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

ArkScript-lang / Ark / 17273628689

27 Aug 2025 05:09PM UTC coverage: 89.465% (+0.8%) from 88.656%
17273628689

push

github

SuperFola
fix(ci): update ci workflow to remove unused exclusion pattern for coverage and update setup-emsdk action

7745 of 8657 relevant lines covered (89.47%)

145446.32 hits per line

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

94.12
/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) :
142,812✔
12
        m_type(node_type), m_value(value), m_pos()
71,406✔
13
    {}
71,406✔
14

15
    Node::Node(const NodeType node_type) :
268,931✔
16
        m_type(node_type), m_pos()
537,862✔
17
    {
268,931✔
18
        if (m_type == NodeType::List || m_type == NodeType::Macro || m_type == NodeType::Field)
268,931✔
19
            m_value = std::vector<Node>();
268,600✔
20
    }
268,931✔
21

22
    Node::Node(double value) :
71,087✔
23
        m_type(NodeType::Number), m_value(value), m_pos()
142,174✔
24
    {}
142,174✔
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) :
14,378✔
31
        m_type(NodeType::Keyword), m_value(value), m_pos()
28,756✔
32
    {}
28,756✔
33

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

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

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

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

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

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

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

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

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

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

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

88
    bool Node::isFunction() const noexcept
6,902✔
89
    {
6,902✔
90
        return m_type == NodeType::List &&
12,103✔
91
            !constList().empty() &&
5,201✔
92
            constList()[0].nodeType() == NodeType::Keyword &&
7,621✔
93
            constList()[0].keyword() == Keyword::Fun;
2,420✔
94
    }
95

96
    const std::optional<std::string>& Node::getUnqualifiedName() const noexcept
900✔
97
    {
900✔
98
        return m_unqualified_name;
900✔
99
    }
100

101
    void Node::updateValueAndType(const Node& source) noexcept
23,678✔
102
    {
23,678✔
103
        m_type = source.m_type;
23,678✔
104
        m_value = source.m_value;
23,678✔
105
    }
23,678✔
106

107
    void Node::setNodeType(const NodeType type) noexcept
296✔
108
    {
296✔
109
        m_type = type;
296✔
110
    }
296✔
111

112
    void Node::setUnqualifiedName(const std::string& name) noexcept
224✔
113
    {
224✔
114
        m_unqualified_name = name;
224✔
115
    }
224✔
116

117
    void Node::setString(const std::string& value) noexcept
107,786✔
118
    {
107,786✔
119
        m_value = value;
107,786✔
120
    }
107,786✔
121

122
    void Node::setPositionFrom(const Node& source) noexcept
170✔
123
    {
170✔
124
        m_filename = source.m_filename;
170✔
125
        m_pos = source.m_pos;
170✔
126
    }
170✔
127

128
    Node& Node::attachNearestCommentBefore(const std::string& comment)
170,675✔
129
    {
170,675✔
130
        m_comment = comment;
170,675✔
131
        return *this;
170,675✔
132
    }
133

134
    Node& Node::attachCommentAfter(const std::string& comment)
43,675✔
135
    {
43,675✔
136
        if (!m_after_comment.empty())
43,675✔
137
            m_after_comment += "\n";
37✔
138
        m_after_comment += comment;
43,675✔
139
        if (!m_after_comment.empty() && m_after_comment.back() == '\n')
43,675✔
140
            m_after_comment.pop_back();
107✔
141
        return *this;
43,675✔
142
    }
143

144
    void Node::setAltSyntax(const bool toggle)
3,120✔
145
    {
3,120✔
146
        m_alt_syntax = toggle;
3,120✔
147
    }
3,120✔
148

149
    void Node::setFunctionKind(const bool anonymous)
2,394✔
150
    {
2,394✔
151
        m_is_anonymous_function = anonymous;
2,394✔
152
    }
2,394✔
153

154
    bool Node::isAnonymousFunction() const noexcept
5,335✔
155
    {
5,335✔
156
        return m_is_anonymous_function;
5,335✔
157
    }
158

159
    FileSpan Node::position() const noexcept
119,590✔
160
    {
119,590✔
161
        return m_pos;
119,590✔
162
    }
163

164
    const std::string& Node::filename() const noexcept
54,542✔
165
    {
54,542✔
166
        return m_filename;
54,542✔
167
    }
168

169
    const std::string& Node::comment() const noexcept
17,176✔
170
    {
17,176✔
171
        return m_comment;
17,176✔
172
    }
173

174
    const std::string& Node::commentAfter() const noexcept
2,266✔
175
    {
2,266✔
176
        return m_after_comment;
2,266✔
177
    }
178

179
    std::string Node::repr() const noexcept
17,607✔
180
    {
17,607✔
181
        std::string data;
17,607✔
182
        switch (m_type)
17,607✔
183
        {
14,693✔
184
            case NodeType::Symbol:
185
                data += string();
14,693✔
186
                break;
14,693✔
187

188
            case NodeType::Capture:
189
                data += "&" + string();
×
190
                break;
60✔
191

192
            case NodeType::Keyword:
193
                data += keywords[static_cast<std::size_t>(keyword())];
60✔
194
                break;
491✔
195

196
            case NodeType::String:
197
                data += "\"" + string() + "\"";
431✔
198
                break;
1,596✔
199

200
            case NodeType::Number:
201
                data += fmt::format("{}", number());
1,165✔
202
                break;
2,269✔
203

204
            case NodeType::List:
205
                if (m_alt_syntax)
1,104✔
206
                {
207
                    const auto first = constList().front();
265✔
208
                    char open = 0;
265✔
209
                    if (first.nodeType() == NodeType::Keyword && first.keyword() == Keyword::Begin)
265✔
210
                        open = '{';
3✔
211
                    else if (first.nodeType() == NodeType::Symbol && first.string() == "list")
262✔
212
                        open = '[';
262✔
213
                    else
214
                        assert(false && "Alt syntax nodes can only be begin or list");
×
215

216
                    data += open;
265✔
217
                    for (std::size_t i = 1, end = constList().size(); i < end; ++i)
818✔
218
                    {
219
                        data += constList()[i].repr();
553✔
220
                        if (i < end - 1)
553✔
221
                            data += " ";
355✔
222
                    }
553✔
223

224
                    if (open == '{')
265✔
225
                        data += "}";
3✔
226
                    else if (open == '[')
262✔
227
                        data += "]";
262✔
228
                }
265✔
229
                else
230
                {
231
                    data += "(";
839✔
232
                    for (std::size_t i = 0, end = constList().size(); i < end; ++i)
3,053✔
233
                    {
234
                        data += constList()[i].repr();
2,214✔
235
                        if (i < end - 1)
2,214✔
236
                            data += " ";
1,379✔
237
                    }
2,214✔
238
                    data += ")";
839✔
239
                }
240
                break;
1,241✔
241

242
            case NodeType::Field:
243
                for (std::size_t i = 0, end = constList().size(); i < end; ++i)
425✔
244
                {
426,042✔
245
                    data += constList()[i].repr();
288✔
246
                    if (i < end - 1)
288✔
247
                        data += ".";
151✔
248
                }
288✔
249
                break;
153✔
250

426,042✔
251
            case NodeType::Macro:
426,042✔
252
                data += "(macro ";
16✔
253
                for (std::size_t i = 0, end = constList().size(); i < end; ++i)
76✔
254
                {
255
                    data += constList()[i].repr();
60✔
256
                    if (i < end - 1)
60✔
257
                        data += " ";
44✔
258
                }
60✔
259
                data += ")";
16✔
260
                break;
17✔
261

262
            case NodeType::Spread:
263
                data += "..." + string();
1✔
264
                break;
1✔
265

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

273
            case NodeType::Unused:
274
                break;
×
275
        }
17,607✔
276
        return data;
17,607✔
277
    }
17,607✔
278

279
    std::ostream& Node::debugPrint(std::ostream& os) const noexcept
487✔
280
    {
487✔
281
        switch (m_type)
487✔
282
        {
145✔
283
            case NodeType::Symbol:
284
                os << "Symbol:" << string();
145✔
285
                break;
151✔
286

287
            case NodeType::Capture:
288
                os << "Capture:" << string();
6✔
289
                break;
90✔
290

291
            case NodeType::Keyword:
292
                os << "Keyword:";
84✔
293
                switch (keyword())
84✔
294
                {
16✔
295
                    case Keyword::Fun: os << "Fun"; break;
36✔
296
                    case Keyword::Let: os << "Let"; break;
23✔
297
                    case Keyword::Mut: os << "Mut"; break;
4✔
298
                    case Keyword::Set: os << "Set"; break;
16✔
299
                    case Keyword::If: os << "If"; break;
21✔
300
                    case Keyword::While: os << "While"; break;
17✔
301
                    case Keyword::Begin: os << "Begin"; break;
19✔
302
                    case Keyword::Import: os << "Import"; break;
12✔
303
                    case Keyword::Del: os << "Del"; break;
4✔
304
                }
84✔
305
                break;
92✔
306

307
            case NodeType::String:
308
                os << "String:" << string();
8✔
309
                break;
85✔
310

311
            case NodeType::Number:
312
                os << "Number:" << number();
77✔
313
                break;
225✔
314

315
            case NodeType::List:
316
                os << "( ";
148✔
317
                for (const auto& i : constList())
506✔
318
                    i.debugPrint(os) << " ";
358✔
319
                os << ")";
148✔
320
                break;
157✔
321

322
            case NodeType::Field:
323
                os << "( Field ";
9✔
324
                for (const auto& i : constList())
30✔
325
                    i.debugPrint(os) << " ";
21✔
326
                os << ")";
9✔
327
                break;
17✔
328

329
            case NodeType::Macro:
330
                os << "( Macro ";
8✔
331
                for (const auto& i : constList())
31✔
332
                    i.debugPrint(os) << " ";
23✔
333
                os << ")";
8✔
334
                break;
10✔
335

336
            case NodeType::Spread:
337
                os << "Spread:" << string();
2✔
338
                break;
2✔
339

340
            case NodeType::Namespace:
341
            {
342
                const auto details = constArkNamespace();
×
343
                os << "( Namespace:" << details.name << " ";
×
344
                details.ast->debugPrint(os) << " )";
×
345
                break;
346
            }
×
347

348
            case NodeType::Unused:
349
                break;
×
350
        }
487✔
351
        return os;
487✔
352
    }
353

354
    const Node& getTrueNode()
77✔
355
    {
77✔
356
        static const Node TrueNode(NodeType::Symbol, "true");
77✔
357
        return TrueNode;
77✔
358
    }
×
359

360
    const Node& getFalseNode()
59✔
361
    {
59✔
362
        static const Node FalseNode(NodeType::Symbol, "false");
59✔
363
        return FalseNode;
59✔
364
    }
×
365

366
    const Node& getNilNode()
51✔
367
    {
51✔
368
        static const Node NilNode(NodeType::Symbol, "nil");
51✔
369
        return NilNode;
51✔
370
    }
×
371

372
    const Node& getListNode()
1,141✔
373
    {
1,141✔
374
        static const Node ListNode(NodeType::Symbol, "list");
1,141✔
375
        return ListNode;
1,141✔
376
    }
×
377

378
    bool operator==(const Node& A, const Node& B)
414✔
379
    {
414✔
380
        if (A.m_type != B.m_type)  // should have the same types
414✔
381
            return false;
30✔
382

383
        if (A.m_type != NodeType::List)
384✔
384
            return A.m_value == B.m_value;
384✔
385
        return false;
×
386
    }
414✔
387

388
    bool operator<(const Node& A, const Node& B)
58✔
389
    {
58✔
390
        if (A.nodeType() != B.nodeType())
58✔
391
            return (static_cast<int>(A.nodeType()) - static_cast<int>(B.nodeType())) < 0;
18✔
392

393
        switch (A.nodeType())
40✔
394
        {
40✔
395
            case NodeType::Number:
396
                [[fallthrough]];
397
            case NodeType::Symbol:
398
                [[fallthrough]];
399
            case NodeType::String:
400
                return A.m_value < B.m_value;
40✔
401

402
            default:
403
                return false;
×
404
        }
405
    }
58✔
406
}
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