A simple scripting language in C++
Ferenc Szontágh
2025-04-19 26263ab9055d2ce4f6b1ec934949bcea240b1f29
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// FileModule.hpp
#ifndef MODULES_FILEMODULE_HPP
#define MODULES_FILEMODULE_HPP
 
#include <filesystem>
#include <fstream>
#include <iterator>
#include <stdexcept>
#include <vector>
#include <string>
#include "Modules/BaseModule.hpp"
#include "Modules/ModuleManager.hpp"
#include "Symbols/Value.hpp"
 
namespace Modules {
 
/**
 * @brief Module providing simple file I/O functions:
 *  file_get_contents(filename) -> string content
 *  file_put_contents(filename, content, overwrite) -> undefined, throws on error
 *  file_exists(filename) -> bool
 */
class FileModule : public BaseModule {
  public:
    void registerModule() override {
        auto &mgr = ModuleManager::instance();
        // Read entire file content
        mgr.registerFunction("file_get_contents", [](const std::vector<Symbols::Value> &args) {
            using namespace Symbols;
            if (args.size() != 1) {
                throw std::runtime_error("file_get_contents expects 1 argument");
            }
            if (args[0].getType() != Variables::Type::STRING) {
                throw std::runtime_error("file_get_contents expects string filename");
            }
            const std::string filename = args[0].get<std::string>();
            if (!std::filesystem::exists(filename)) {
                throw std::runtime_error("File does not exist: " + filename);
            }
            std::ifstream input(filename, std::ios::in | std::ios::binary);
            if (!input.is_open()) {
                throw std::runtime_error("Could not open file: " + filename);
            }
            std::string content((std::istreambuf_iterator<char>(input)), std::istreambuf_iterator<char>());
            input.close();
            return Value(content);
        });
        // Write content to file, with optional overwrite
        mgr.registerFunction("file_put_contents", [](const std::vector<Symbols::Value> &args) {
            using namespace Symbols;
            if (args.size() != 3) {
                throw std::runtime_error("file_put_contents expects 3 arguments");
            }
            if (args[0].getType() != Variables::Type::STRING ||
                args[1].getType() != Variables::Type::STRING ||
                args[2].getType() != Variables::Type::BOOLEAN) {
                throw std::runtime_error("file_put_contents expects (string, string, bool)");
            }
            const std::string filename = args[0].get<std::string>();
            const std::string content = args[1].get<std::string>();
            const bool overwrite = args[2].get<bool>();
            if (!overwrite && std::filesystem::exists(filename)) {
                throw std::runtime_error("File already exists: " + filename);
            }
            std::ofstream output(filename, std::ios::out | std::ios::binary | std::ios::trunc);
            if (!output.is_open()) {
                throw std::runtime_error("Could not open file for writing: " + filename);
            }
            output << content;
            if (!output) {
                throw std::runtime_error("Failed to write to file: " + filename);
            }
            output.close();
            return Value();
        });
        // Check if file exists
        mgr.registerFunction("file_exists", [](const std::vector<Symbols::Value> &args) {
            using namespace Symbols;
            if (args.size() != 1) {
                throw std::runtime_error("file_exists expects 1 argument");
            }
            if (args[0].getType() != Variables::Type::STRING) {
                throw std::runtime_error("file_exists expects string filename");
            }
            const std::string filename = args[0].get<std::string>();
            bool exists = std::filesystem::exists(filename);
            return Value(exists);
        });
    }
};
 
} // namespace Modules
#endif // MODULES_FILEMODULE_HPP