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

ArkScript-lang / Ark / 13591295117

28 Feb 2025 03:30PM UTC coverage: 79.056% (-0.1%) from 79.158%
13591295117

push

github

SuperFola
refactor(vm): mark pointers as const or pointer to const as recommended by cppcheck

25 of 25 new or added lines in 1 file covered. (100.0%)

8 existing lines in 1 file now uncovered.

5862 of 7415 relevant lines covered (79.06%)

70561.35 hits per line

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

47.2
/src/arkreactor/Builtins/IO.cpp
1
#include <Ark/Builtins/Builtins.hpp>
2

3
#include <iostream>
4
#include <filesystem>
5
#include <fmt/core.h>
6

7
#include <Ark/Files.hpp>
8
#include <Ark/VM/VM.hpp>
9
#include <Ark/Exceptions.hpp>
10
#include <Ark/TypeChecker.hpp>
11

12
namespace Ark::internal::Builtins::IO
13
{
14
    /**
15
     * @name print
16
     * @brief Print value(s) in the terminal
17
     * @details No separator is put between the values. Adds a \n at the end
18
     * @param values the values to print
19
     * =begin
20
     * (print "hello")
21
     * =end
22
     * @author https://github.com/SuperFola
23
     */
24
    Value print(std::vector<Value>& n, VM* vm)
175✔
25
    {
175✔
26
        for (auto& value : n)
402✔
27
            fmt::print("{}", value.toString(*vm));
227✔
28
        fmt::println("");
175✔
29

30
        return nil;
175✔
31
    }
×
32

33
    /**
34
     * @name puts
35
     * @brief Print value(s) in the terminal
36
     * @details No separator is put between the values, no \n at the end
37
     * @param values the values to print
38
     * =begin
39
     * (puts "hello")
40
     * =end
41
     * @author https://github.com/SuperFola
42
     */
43
    Value puts_(std::vector<Value>& n, VM* vm)
150✔
44
    {
150✔
45
        for (auto& value : n)
306✔
46
            fmt::print("{}", value.toString(*vm));
156✔
47

48
        return nil;
150✔
49
    }
×
50

51
    /**
52
     * @name input
53
     * @brief Request a value from the user
54
     * @details Return the value as a string
55
     * @param prompt (optional) printed before asking for the user input
56
     * =begin
57
     * (input "put a number> ")
58
     * =end
59
     * @author https://github.com/SuperFola
60
     */
61
    Value input(std::vector<Value>& n, VM* vm [[maybe_unused]])
×
62
    {
×
63
        if (types::check(n, ValueType::String))
×
64
            fmt::print("{}", n[0].string());
×
65
        else if (!n.empty())
×
66
            types::generateError("input", { { types::Contract {}, types::Contract { { types::Typedef("prompt", ValueType::String) } } } }, n);
×
67

68
        std::string line;
×
69
        std::getline(std::cin, line);
×
70

71
        return Value(line);
×
72
    }
×
73

74
    /**
75
     * @name io:writeFile
76
     * @brief Write content to a file. Return nil
77
     * @param filename path to the file to write to (will be overwritten if it exists)
78
     * @param content can be any valid ArkScript value
79
     * =begin
80
     * (io:writeFile "hello.json" "{\"key\": 12}")
81
     * =end
82
     * @author https://github.com/SuperFola
83
     */
84
    Value writeFile(std::vector<Value>& n, VM* vm)
1✔
85
    {
1✔
86
        if (types::check(n, ValueType::String, ValueType::Any))
1✔
87
        {
88
            std::ofstream f(n[0].string());
1✔
89
            if (f.is_open())
1✔
90
            {
91
                f << n[1].toString(*vm);
1✔
92
                f.close();
1✔
93
            }
1✔
94
            else
95
                throw std::runtime_error(fmt::format("io:writeFile: couldn't write to file \"{}\"", n[0].stringRef()));
×
96
        }
1✔
97
        else
98
            types::generateError(
×
99
                "io:writeFile",
×
100
                { { types::Contract { { types::Typedef("filename", ValueType::String), types::Typedef("content", ValueType::Any) } } } },
×
101
                n);
×
102

103
        return nil;
1✔
104
    }
×
105

106
    /**
107
     * @name io:appendToFile
108
     * @brief Append content to a file. Return nil
109
     * @param filename path to the file to append to
110
     * @param content can be any valid ArkScript value
111
     * =begin
112
     * (io:writeFile "hello.json" "{\"key\": 12}")
113
     * =end
114
     * @author https://github.com/SuperFola
115
     */
116
    Value appendToFile(std::vector<Value>& n, VM* vm)
1✔
117
    {
1✔
118
        if (types::check(n, ValueType::String, ValueType::Any))
1✔
119
        {
120
            std::ofstream f(n[0].string(), std::ios::out | std::ios::app);
1✔
121
            if (f.is_open())
1✔
122
            {
123
                f << n[1].toString(*vm);
1✔
124
                f.close();
1✔
125
            }
1✔
126
            else
127
                throw std::runtime_error(fmt::format("io:appendToFile: couldn't write to file \"{}\"", n[0].stringRef()));
×
128
        }
1✔
129
        else
130
            types::generateError(
×
131
                "io:appendToFile",
×
132
                { { types::Contract { { types::Typedef("filename", ValueType::String), types::Typedef("content", ValueType::Any) } } } },
×
133
                n);
×
134

135
        return nil;
1✔
136
    }
×
137

138
    /**
139
     * @name io:readFile
140
     * @brief Read the content from a file as a String
141
     * @param filename the path of the file to read
142
     * =begin
143
     * (io:readFile "hello.json")
144
     * =end
145
     * @author https://github.com/SuperFola
146
     */
147
    Value readFile(std::vector<Value>& n, VM* vm [[maybe_unused]])
3✔
148
    {
3✔
149
        if (!types::check(n, ValueType::String))
3✔
150
            types::generateError(
×
151
                "io:readFile",
×
152
                { { types::Contract { { types::Typedef("filename", ValueType::String) } } } },
×
153
                n);
×
154

155
        std::string filename = n[0].string();
3✔
156
        if (!Utils::fileExists(filename))
3✔
157
            throw std::runtime_error(
×
158
                fmt::format("io:readFile: couldn't read file \"{}\" because it doesn't exist", filename));
×
159

160
        return Value(Utils::readFile(filename));
3✔
161
    }
3✔
162

163
    /**
164
     * @name io:fileExists?
165
     * @brief Check if a file exists, return True or False
166
     * @param filename the path of the file
167
     * =begin
168
     * (io:fileExists? "hello.json")
169
     * =end
170
     * @author https://github.com/SuperFola
171
     */
172
    Value fileExists(std::vector<Value>& n, VM* vm [[maybe_unused]])
4✔
173
    {
4✔
174
        if (!types::check(n, ValueType::String))
4✔
175
            types::generateError(
×
176
                "io:fileExists?",
×
177
                { { types::Contract { { types::Typedef("filename", ValueType::String) } } } },
×
178
                n);
×
179

180
        return Utils::fileExists(n[0].string()) ? trueSym : falseSym;
4✔
181
    }
×
182

183
    /**
184
     * @name io:listFiles
185
     * @brief List files in a folder, as a List of String
186
     * @param path A directory
187
     * =begin
188
     * (io:listFiles "/tmp/hello")
189
     * =end
190
     * @author https://github.com/SuperFola
191
     */
UNCOV
192
    Value listFiles(std::vector<Value>& n, VM* vm [[maybe_unused]])
×
UNCOV
193
    {
×
UNCOV
194
        if (!types::check(n, ValueType::String))
×
195
            types::generateError(
×
196
                "io:listFiles",
×
197
                { { types::Contract { { types::Typedef("path", ValueType::String) } } } },
×
198
                n);
×
199

UNCOV
200
        std::vector<Value> r;
×
UNCOV
201
        for (const auto& entry : std::filesystem::directory_iterator(n[0].string()))
×
202
            // cppcheck-suppress useStlAlgorithm
203
            // We can't use std::transform with a directory_iterator
UNCOV
204
            r.emplace_back(entry.path().string());
×
205

UNCOV
206
        return Value(std::move(r));
×
UNCOV
207
    }
×
208

209
    /**
210
     * @name io:dir?
211
     * @brief Check if a path represents a directory
212
     * @param path A directory
213
     * =begin
214
     * (io:dir? "/tmp/hello")
215
     * =end
216
     * @author https://github.com/SuperFola
217
     */
218
    Value isDirectory(std::vector<Value>& n, VM* vm [[maybe_unused]])
2✔
219
    {
2✔
220
        if (!types::check(n, ValueType::String))
2✔
221
            types::generateError(
×
222
                "io:dir?",
×
223
                { { types::Contract { { types::Typedef("path", ValueType::String) } } } },
×
224
                n);
×
225

226
        return (std::filesystem::is_directory(std::filesystem::path(n[0].string()))) ? trueSym : falseSym;
2✔
227
    }
×
228

229
    /**
230
     * @name io:makeDir
231
     * @brief Create a directory
232
     * @param path A directory
233
     * =begin
234
     * (io:makeDir "/tmp/myDir")
235
     * =end
236
     * @author https://github.com/SuperFola
237
     */
238
    Value makeDir(std::vector<Value>& n, VM* vm [[maybe_unused]])
1✔
239
    {
1✔
240
        if (!types::check(n, ValueType::String))
1✔
241
            types::generateError(
×
242
                "io:makeDir",
×
243
                { { types::Contract { { types::Typedef("path", ValueType::String) } } } },
×
244
                n);
×
245

246
        std::filesystem::create_directories(std::filesystem::path(n[0].string()));
1✔
247
        return nil;
1✔
248
    }
×
249

250
    /**
251
     * @name io:removeFiles
252
     * @brief Delete files
253
     * @details Take multiple arguments, all String, each one representing a path to a file
254
     * @param filenames path to file
255
     * =begin
256
     * (io:removeFiles "/tmp/test.ark" "hello.json")
257
     * =end
258
     * @author https://github.com/SuperFola
259
     */
260
    Value removeFiles(std::vector<Value>& n, VM* vm [[maybe_unused]])
1✔
261
    {
1✔
262
        if (n.empty() || n[0].valueType() != ValueType::String)
1✔
263
            types::generateError(
×
264
                "io:removeFiles",
×
265
                { { types::Contract { { types::Typedef("filename", ValueType::String), types::Typedef("filenames", ValueType::String, /* variadic */ true) } } } },
×
266
                n);
×
267

268
        for (auto it = n.begin(), it_end = n.end(); it != it_end; ++it)
3✔
269
        {
270
            if (it->valueType() != ValueType::String)
2✔
271
                types::generateError(
×
272
                    "io:removeFiles",
×
273
                    { { types::Contract { { types::Typedef("filename", ValueType::String), types::Typedef("filenames", ValueType::String, /* variadic */ true) } } } },
×
274
                    n);
×
275

276
            std::filesystem::remove_all(std::filesystem::path(it->string()));
2✔
277
        }
2✔
278

279
        return nil;
1✔
280
    }
×
281
}
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