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

ArkScript-lang / Ark / 20009525215

07 Dec 2025 07:57PM UTC coverage: 90.367% (-0.2%) from 90.556%
20009525215

Pull #613

github

web-flow
Merge 84d909ba4 into 0bb785969
Pull Request #613: Adding argument attributes 'mut' and 'ref'

45 of 62 new or added lines in 8 files covered. (72.58%)

5 existing lines in 1 file now uncovered.

8011 of 8865 relevant lines covered (90.37%)

180002.24 hits per line

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

92.81
/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) :
167,630✔
12
        m_type(node_type), m_value(value), m_pos()
83,815✔
13
    {}
83,815✔
14

15
    Node::Node(const NodeType node_type) :
314,824✔
16
        m_type(node_type), m_pos()
629,648✔
17
    {
314,824✔
18
        if (m_type == NodeType::List || m_type == NodeType::Macro || m_type == NodeType::Field)
314,824✔
19
            m_value = std::vector<Node>();
314,395✔
20
    }
314,824✔
21

22
    Node::Node(double value) :
75,910✔
23
        m_type(NodeType::Number), m_value(value), m_pos()
151,820✔
24
    {}
151,820✔
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) :
16,772✔
31
        m_type(NodeType::Keyword), m_value(value), m_pos()
33,544✔
32
    {}
33,544✔
33

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

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

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

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

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

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

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

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

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

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

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

88
    bool Node::isFunction() const noexcept
8,101✔
89
    {
8,101✔
90
        return m_type == NodeType::List &&
14,149✔
91
            !constList().empty() &&
6,048✔
92
            constList()[0].nodeType() == NodeType::Keyword &&
8,845✔
93
            constList()[0].keyword() == Keyword::Fun;
2,797✔
94
    }
95

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

188
            case NodeType::MutArg:
NEW
189
                data += "(mut " + string() + ")";
×
NEW
190
                break;
×
191

192
            case NodeType::RefArg:
NEW
193
                data += "(ref " + string() + ")";
×
NEW
194
                break;
×
195

196
            case NodeType::Capture:
197
                data += "&" + string();
×
198
                break;
92✔
199

200
            case NodeType::Keyword:
201
                data += keywords[static_cast<std::size_t>(keyword())];
92✔
202
                break;
597✔
203

204
            case NodeType::String:
205
                data += "\"" + string() + "\"";
505✔
206
                break;
1,745✔
207

208
            case NodeType::Number:
209
                data += fmt::format("{}", number());
1,240✔
210
                break;
2,517✔
211

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

224
                    data += open;
282✔
225
                    for (std::size_t i = 1, end = constList().size(); i < end; ++i)
865✔
226
                    {
227
                        data += constList()[i].repr();
583✔
228
                        if (i < end - 1)
583✔
229
                            data += " ";
372✔
230
                    }
583✔
231

232
                    if (open == '{')
282✔
233
                        data += "}";
5✔
234
                    else if (open == '[')
277✔
235
                        data += "]";
277✔
236
                }
282✔
237
                else
238
                {
239
                    data += "(";
995✔
240
                    for (std::size_t i = 0, end = constList().size(); i < end; ++i)
3,575✔
241
                    {
242
                        data += constList()[i].repr();
2,580✔
243
                        if (i < end - 1)
2,580✔
244
                            data += " ";
493,170✔
245
                    }
2,580✔
246
                    data += ")";
995✔
247
                }
248
                break;
1,414✔
249

250
            case NodeType::Field:
491,566✔
251
                for (std::size_t i = 0, end = constList().size(); i < end; ++i)
491,991✔
252
                {
253
                    data += constList()[i].repr();
288✔
254
                    if (i < end - 1)
288✔
255
                        data += ".";
151✔
256
                }
288✔
257
                break;
153✔
258

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

270
            case NodeType::Spread:
271
                data += "..." + string();
1✔
272
                break;
1✔
273

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

281
            case NodeType::Unused:
282
                break;
×
283
        }
20,521✔
284
        return data;
20,521✔
285
    }
20,521✔
286

287
    std::ostream& Node::debugPrint(std::ostream& os) const noexcept
537✔
288
    {
537✔
289
        switch (m_type)
537✔
290
        {
155✔
291
            case NodeType::Symbol:
292
                os << "Symbol:" << string();
155✔
293
                break;
161✔
294

295
            case NodeType::MutArg:
296
                os << "MutArg:" << string();
6✔
297
                break;
12✔
298

299
            case NodeType::RefArg:
300
                os << "RefArg:" << string();
6✔
301
                break;
16✔
302

303
            case NodeType::Capture:
304
                os << "Capture:" << string();
10✔
305
                break;
102✔
306

307
            case NodeType::Keyword:
308
                os << "Keyword:";
92✔
309
                switch (keyword())
92✔
310
                {
24✔
311
                    case Keyword::Fun: os << "Fun"; break;
44✔
312
                    case Keyword::Let: os << "Let"; break;
23✔
313
                    case Keyword::Mut: os << "Mut"; break;
4✔
314
                    case Keyword::Set: os << "Set"; break;
16✔
315
                    case Keyword::If: os << "If"; break;
21✔
316
                    case Keyword::While: os << "While"; break;
17✔
317
                    case Keyword::Begin: os << "Begin"; break;
19✔
318
                    case Keyword::Import: os << "Import"; break;
12✔
319
                    case Keyword::Del: os << "Del"; break;
4✔
320
                }
92✔
321
                break;
100✔
322

323
            case NodeType::String:
324
                os << "String:" << string();
8✔
325
                break;
85✔
326

327
            case NodeType::Number:
328
                os << "Number:" << number();
77✔
329
                break;
241✔
330

331
            case NodeType::List:
332
                os << "( ";
164✔
333
                for (const auto& i : constList())
564✔
334
                    i.debugPrint(os) << " ";
400✔
335
                os << ")";
164✔
336
                break;
173✔
337

338
            case NodeType::Field:
339
                os << "( Field ";
9✔
340
                for (const auto& i : constList())
30✔
341
                    i.debugPrint(os) << " ";
21✔
342
                os << ")";
9✔
343
                break;
17✔
344

345
            case NodeType::Macro:
346
                os << "( Macro ";
8✔
347
                for (const auto& i : constList())
31✔
348
                    i.debugPrint(os) << " ";
23✔
349
                os << ")";
8✔
350
                break;
10✔
351

352
            case NodeType::Spread:
353
                os << "Spread:" << string();
2✔
354
                break;
2✔
355

356
            case NodeType::Namespace:
357
            {
358
                const auto details = constArkNamespace();
×
359
                os << "( Namespace:" << details.name << " ";
×
360
                details.ast->debugPrint(os) << " )";
×
361
                break;
362
            }
×
363

364
            case NodeType::Unused:
365
                break;
×
366
        }
537✔
367
        return os;
537✔
368
    }
369

370
    const Node& getTrueNode()
77✔
371
    {
77✔
372
        static const Node TrueNode(NodeType::Symbol, "true");
77✔
373
        return TrueNode;
77✔
374
    }
×
375

376
    const Node& getFalseNode()
60✔
377
    {
60✔
378
        static const Node FalseNode(NodeType::Symbol, "false");
60✔
379
        return FalseNode;
60✔
380
    }
×
381

382
    const Node& getNilNode()
55✔
383
    {
55✔
384
        static const Node NilNode(NodeType::Symbol, "nil");
55✔
385
        return NilNode;
55✔
386
    }
×
387

388
    const Node& getListNode()
1,185✔
389
    {
1,185✔
390
        static const Node ListNode(NodeType::Symbol, "list");
1,185✔
391
        return ListNode;
1,185✔
392
    }
×
393

394
    bool operator==(const Node& A, const Node& B)
382✔
395
    {
382✔
396
        if (A.m_type != B.m_type)  // should have the same types
382✔
397
            return false;
31✔
398

399
        if (A.m_type != NodeType::List)
351✔
400
            return A.m_value == B.m_value;
351✔
401
        return false;
×
402
    }
382✔
403

404
    bool operator<(const Node& A, const Node& B)
58✔
405
    {
58✔
406
        if (A.nodeType() != B.nodeType())
58✔
407
            return (static_cast<int>(A.nodeType()) - static_cast<int>(B.nodeType())) < 0;
18✔
408

409
        switch (A.nodeType())
40✔
410
        {
40✔
411
            case NodeType::Number:
412
                [[fallthrough]];
413
            case NodeType::Symbol:
414
                [[fallthrough]];
415
            case NodeType::String:
416
                return A.m_value < B.m_value;
40✔
417

418
            default:
419
                return false;
×
420
        }
421
    }
58✔
422
}
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