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

ArkScript-lang / Ark / 14823373998

04 May 2025 05:03PM UTC coverage: 86.442% (+0.03%) from 86.409%
14823373998

push

github

SuperFola
fix: change the color of the function name inside runtime typechecking errors from blue to cyan to be easier to read inside dark terminals

0 of 1 new or added line in 1 file covered. (0.0%)

195 existing lines in 22 files now uncovered.

6835 of 7907 relevant lines covered (86.44%)

79668.53 hits per line

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

85.6
/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
    // cppcheck-suppress constParameterReference
25
    Value print(std::vector<Value>& n, VM* vm)
175✔
26
    {
175✔
27
        for (const auto& value : n)
402✔
28
            fmt::print("{}", value.toString(*vm));
227✔
29
        fmt::println("");
175✔
30

31
        return nil;
175✔
UNCOV
32
    }
×
33

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

50
        return nil;
150✔
UNCOV
51
    }
×
52

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

71
        std::string line;
×
72
        std::getline(std::cin, line);
×
73

UNCOV
74
        return Value(line);
×
UNCOV
75
    }
×
76

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

106
        return nil;
2✔
107
    }
1✔
108

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

138
        return nil;
1✔
139
    }
1✔
140

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

159
        std::string filename = n[0].string();
4✔
160
        if (!Utils::fileExists(filename))
4✔
161
            throw std::runtime_error(
1✔
162
                fmt::format("io:readFile: couldn't read file \"{}\" because it doesn't exist", filename));
1✔
163

164
        return Value(Utils::readFile(filename));
3✔
165
    }
6✔
166

167
    /**
168
     * @name io:fileExists?
169
     * @brief Check if a file exists, return True or False
170
     * @param filename the path of the file
171
     * =begin
172
     * (io:fileExists? "hello.json")
173
     * =end
174
     * @author https://github.com/SuperFola
175
     */
176
    // cppcheck-suppress constParameterReference
177
    Value fileExists(std::vector<Value>& n, VM* vm [[maybe_unused]])
5✔
178
    {
5✔
179
        if (!types::check(n, ValueType::String))
5✔
180
            throw types::TypeCheckingError(
2✔
181
                "io:fileExists?",
1✔
182
                { { types::Contract { { types::Typedef("filename", ValueType::String) } } } },
1✔
183
                n);
1✔
184

185
        return Utils::fileExists(n[0].string()) ? trueSym : falseSym;
4✔
186
    }
1✔
187

188
    /**
189
     * @name io:listFiles
190
     * @brief List files in a folder, as a List of String
191
     * @param path A directory
192
     * =begin
193
     * (io:listFiles "/tmp/hello")
194
     * =end
195
     * @author https://github.com/SuperFola
196
     */
197
    // cppcheck-suppress constParameterReference
198
    Value listFiles(std::vector<Value>& n, VM* vm [[maybe_unused]])
1✔
199
    {
1✔
200
        if (!types::check(n, ValueType::String))
1✔
201
            throw types::TypeCheckingError(
2✔
202
                "io:listFiles",
1✔
203
                { { types::Contract { { types::Typedef("path", ValueType::String) } } } },
1✔
204
                n);
1✔
205

206
        std::vector<Value> r;
×
UNCOV
207
        for (const auto& entry : std::filesystem::directory_iterator(n[0].string()))
×
208
            // cppcheck-suppress useStlAlgorithm
209
            // We can't use std::transform with a directory_iterator
UNCOV
210
            r.emplace_back(entry.path().string());
×
211

UNCOV
212
        return Value(std::move(r));
×
213
    }
1✔
214

215
    /**
216
     * @name io:dir?
217
     * @brief Check if a path represents a directory
218
     * @param path A directory
219
     * =begin
220
     * (io:dir? "/tmp/hello")
221
     * =end
222
     * @author https://github.com/SuperFola
223
     */
224
    // cppcheck-suppress constParameterReference
225
    Value isDirectory(std::vector<Value>& n, VM* vm [[maybe_unused]])
3✔
226
    {
3✔
227
        if (!types::check(n, ValueType::String))
3✔
228
            throw types::TypeCheckingError(
2✔
229
                "io:dir?",
1✔
230
                { { types::Contract { { types::Typedef("path", ValueType::String) } } } },
1✔
231
                n);
1✔
232

233
        return (std::filesystem::is_directory(std::filesystem::path(n[0].string()))) ? trueSym : falseSym;
2✔
234
    }
1✔
235

236
    /**
237
     * @name io:makeDir
238
     * @brief Create a directory
239
     * @param path A directory
240
     * =begin
241
     * (io:makeDir "/tmp/myDir")
242
     * =end
243
     * @author https://github.com/SuperFola
244
     */
245
    // cppcheck-suppress constParameterReference
246
    Value makeDir(std::vector<Value>& n, VM* vm [[maybe_unused]])
2✔
247
    {
2✔
248
        if (!types::check(n, ValueType::String))
2✔
249
            throw types::TypeCheckingError(
2✔
250
                "io:makeDir",
1✔
251
                { { types::Contract { { types::Typedef("path", ValueType::String) } } } },
1✔
252
                n);
1✔
253

254
        std::filesystem::create_directories(std::filesystem::path(n[0].string()));
1✔
255
        return nil;
1✔
256
    }
1✔
257

258
    /**
259
     * @name io:removeFiles
260
     * @brief Delete files
261
     * @details Take multiple arguments, all String, each one representing a path to a file
262
     * @param filenames path to file
263
     * =begin
264
     * (io:removeFiles "/tmp/test.ark" "hello.json")
265
     * =end
266
     * @author https://github.com/SuperFola
267
     */
268
    // cppcheck-suppress constParameterReference
269
    Value removeFiles(std::vector<Value>& n, VM* vm [[maybe_unused]])
3✔
270
    {
3✔
271
        if (n.empty() || n[0].valueType() != ValueType::String)
3✔
272
            throw types::TypeCheckingError(
3✔
273
                "io:removeFiles",
1✔
274
                { { types::Contract { { types::Typedef("filename", ValueType::String, /* is_variadic= */ true) } } } },
1✔
275
                n);
1✔
276

277
        for (auto it = n.begin(), it_end = n.end(); it != it_end; ++it)
6✔
278
        {
279
            if (it->valueType() != ValueType::String)
4✔
280
                throw types::TypeCheckingError(
2✔
281
                    "io:removeFiles",
1✔
282
                    { { types::Contract { { types::Typedef("filename", ValueType::String), types::Typedef("filenames", ValueType::String, /* variadic */ true) } } } },
1✔
283
                    n);
1✔
284

285
            std::filesystem::remove_all(std::filesystem::path(it->string()));
3✔
286
        }
3✔
287

288
        return nil;
1✔
289
    }
2✔
290
}
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