添加了标准库 std.file。支持简单的文件读写
This commit is contained in:
3
src/Module/CppLibrary/CppLibrary.hpp
Normal file
3
src/Module/CppLibrary/CppLibrary.hpp
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#include "File/File.hpp"
|
||||
74
src/Module/CppLibrary/File/File.hpp
Normal file
74
src/Module/CppLibrary/File/File.hpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <fstream>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
namespace Fig::CppLibrary
|
||||
{
|
||||
using FileIDType = uint16_t;
|
||||
struct File
|
||||
{
|
||||
FileIDType id;
|
||||
std::fstream *fs;
|
||||
};
|
||||
class FileManager
|
||||
{
|
||||
private:
|
||||
std::vector<File *> handlers;
|
||||
std::vector<FileIDType> free_handlers;
|
||||
|
||||
FileIDType allocated = 0;
|
||||
|
||||
public:
|
||||
static constexpr FileIDType MAX_HANDLERS = std::numeric_limits<FileIDType>::max();
|
||||
static constexpr unsigned int MAX_FILE_BUF = 961200; // bytes
|
||||
|
||||
FileIDType AllocFile(std::fstream *fs)
|
||||
{
|
||||
FileIDType id = allocated++;
|
||||
File *f = new File{.id = id, .fs = fs};
|
||||
handlers.push_back(f);
|
||||
return id;
|
||||
}
|
||||
|
||||
void CloseFile(FileIDType id)
|
||||
{
|
||||
assert(id < allocated && "CloseHandler: id out of range");
|
||||
File *f = handlers[id];
|
||||
if (f == nullptr) { return; }
|
||||
f->fs->close();
|
||||
delete f->fs;
|
||||
delete f;
|
||||
free_handlers.push_back(id);
|
||||
handlers[id] = nullptr;
|
||||
}
|
||||
|
||||
File *GetNextFreeFile()
|
||||
{
|
||||
// if there is no free handler, create a new one
|
||||
if (free_handlers.size() > 0)
|
||||
{
|
||||
FileIDType id = *free_handlers.begin();
|
||||
handlers[id] = new File{.id = id, .fs = new std::fstream};
|
||||
free_handlers.erase(free_handlers.begin());
|
||||
return handlers[id];
|
||||
}
|
||||
return handlers[AllocFile(new std::fstream)];
|
||||
}
|
||||
|
||||
File *GetFile(FileIDType id)
|
||||
{
|
||||
assert(id < allocated && "GetFile: id out of range");
|
||||
return handlers[id];
|
||||
}
|
||||
|
||||
static FileManager &getInstance()
|
||||
{
|
||||
static FileManager fm;
|
||||
return fm;
|
||||
}
|
||||
};
|
||||
}; // namespace Fig::CppLibrary
|
||||
101
src/Module/Library/std/file/file.fig
Normal file
101
src/Module/Library/std/file/file.fig
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
Official Module `std.file`
|
||||
Library/std/file/file.fig
|
||||
|
||||
Copyright © 2026 PuqiAR. All rights reserved.
|
||||
*/
|
||||
|
||||
import _builtins;
|
||||
import std.io;
|
||||
|
||||
|
||||
public struct __OpenMode
|
||||
{
|
||||
public App: Int = 1;
|
||||
public Ate: Int = 2;
|
||||
public Bin: Int = 4;
|
||||
public In: Int = 8;
|
||||
public Out: Int = 16;
|
||||
public Trunc: Int = 32;
|
||||
|
||||
public __openmode_to_string: Map =
|
||||
{
|
||||
1 : "App",
|
||||
2 : "Ate",
|
||||
4 : "Bin",
|
||||
8 : "In",
|
||||
16 : "Out",
|
||||
32 : "Trunc"
|
||||
};
|
||||
}
|
||||
public const OpenMode := new __OpenMode{};
|
||||
|
||||
public func repr_mode(mode: Int) -> String
|
||||
{
|
||||
return OpenMode.__openmode_to_string[mode];
|
||||
}
|
||||
|
||||
|
||||
|
||||
public struct FileError
|
||||
{
|
||||
msg: String;
|
||||
}
|
||||
|
||||
impl Error for FileError
|
||||
{
|
||||
getErrorClass()
|
||||
{
|
||||
return "FileError";
|
||||
}
|
||||
getErrorMessage()
|
||||
{
|
||||
return msg;
|
||||
}
|
||||
toString()
|
||||
{
|
||||
return getErrorClass() + ": " + msg;
|
||||
}
|
||||
}
|
||||
|
||||
public struct File
|
||||
{
|
||||
path: String;
|
||||
mode: Int;
|
||||
|
||||
id: Int;
|
||||
|
||||
public func read() -> Any
|
||||
{
|
||||
return __fstdfile_read(id);
|
||||
}
|
||||
|
||||
public func write(object: String) -> Null
|
||||
{
|
||||
__fstdfile_write(id, object);
|
||||
}
|
||||
|
||||
public func close() -> Null
|
||||
{
|
||||
__fstdfile_close(id);
|
||||
}
|
||||
|
||||
public func getID() -> Int
|
||||
{
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
public func open(path: String, mode: Int)
|
||||
{
|
||||
const id := __fstdfile_open(path, mode);
|
||||
if not __fstdfile_is_open(id)
|
||||
{
|
||||
throw new FileError{"File " + path + " open failed"};
|
||||
}
|
||||
return new File{
|
||||
path: path,
|
||||
mode: mode,
|
||||
id: id
|
||||
};
|
||||
}
|
||||
@@ -5,13 +5,19 @@
|
||||
#include <Ast/Statements/ControlSt.hpp>
|
||||
#include <Ast/astBase.hpp>
|
||||
#include <Ast/functionParameters.hpp>
|
||||
#include <Evaluator/Context/context.hpp>
|
||||
#include <Core/fig_string.hpp>
|
||||
#include <Ast/AccessModifier.hpp>
|
||||
|
||||
#include <Evaluator/Value/structType.hpp>
|
||||
#include <Evaluator/Value/value.hpp>
|
||||
#include <Module/builtins.hpp>
|
||||
#include <Evaluator/Value/Type.hpp>
|
||||
#include <Evaluator/Context/context.hpp>
|
||||
|
||||
#include <Module/CppLibrary/CppLibrary.hpp>
|
||||
|
||||
#include <Module/builtins.hpp>
|
||||
#include <Core/fig_string.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <print>
|
||||
#include <iostream>
|
||||
@@ -132,9 +138,18 @@ namespace Fig::Builtins
|
||||
{u8"__fmath_tan", 1},
|
||||
{u8"__fmath_tanh", 1},
|
||||
{u8"__fmath_trunc", 1},
|
||||
|
||||
/* file start */
|
||||
{u8"__fstdfile_open", 2},
|
||||
{u8"__fstdfile_close", 1},
|
||||
{u8"__fstdfile_is_open", 1},
|
||||
|
||||
{u8"__fstdfile_read", 1},
|
||||
{u8"__fstdfile_write", 2},
|
||||
};
|
||||
return builtinFunctionArgCounts;
|
||||
}
|
||||
|
||||
const std::unordered_map<FString, BuiltinFunction> &getBuiltinFunctions()
|
||||
{
|
||||
static const std::unordered_map<FString, BuiltinFunction> builtinFunctions{
|
||||
@@ -421,6 +436,47 @@ namespace Fig::Builtins
|
||||
ValueType::DoubleClass d = val->getNumericValue();
|
||||
return std::make_shared<Object>(trunc(d));
|
||||
}},
|
||||
/* file start */
|
||||
{u8"__fstdfile_open",
|
||||
[](const std::vector<ObjectPtr> &args) -> ObjectPtr {
|
||||
const FString &path = args[0]->as<ValueType::StringClass>();
|
||||
const ValueType::IntClass &mode = args[1]->as<ValueType::IntClass>();
|
||||
|
||||
CppLibrary::File *f = CppLibrary::FileManager::getInstance().GetNextFreeFile();
|
||||
f->fs->open(path.toBasicString(), static_cast<unsigned int>(mode));
|
||||
return std::make_shared<Object>(static_cast<ValueType::IntClass>(f->id));
|
||||
}},
|
||||
{u8"__fstdfile_close",
|
||||
[](const std::vector<ObjectPtr> &args) -> ObjectPtr {
|
||||
const ValueType::IntClass &id = args[0]->as<ValueType::IntClass>();
|
||||
CppLibrary::FileManager::getInstance().CloseFile(id);
|
||||
return Object::getNullInstance();
|
||||
}},
|
||||
{u8"__fstdfile_is_open",
|
||||
[](const std::vector<ObjectPtr> &args) -> ObjectPtr {
|
||||
const ValueType::IntClass &id = args[0]->as<ValueType::IntClass>();
|
||||
return std::make_shared<Object>(CppLibrary::FileManager::getInstance().GetFile(id)->fs->is_open());
|
||||
}},
|
||||
{u8"__fstdfile_read",
|
||||
[](const std::vector<ObjectPtr> &args) -> ObjectPtr {
|
||||
const ValueType::IntClass &id = args[0]->as<ValueType::IntClass>();
|
||||
CppLibrary::File *f = CppLibrary::FileManager::getInstance().GetFile(id);
|
||||
|
||||
char *buf = new char[CppLibrary::FileManager::MAX_FILE_BUF];
|
||||
f->fs->read(buf, CppLibrary::FileManager::MAX_FILE_BUF);
|
||||
return std::make_shared<Object>(ValueType::StringClass(reinterpret_cast<const char8_t *>(buf)));
|
||||
}},
|
||||
{u8"__fstdfile_write",
|
||||
[](const std::vector<ObjectPtr> &args) -> ObjectPtr {
|
||||
const ValueType::IntClass &id = args[0]->as<ValueType::IntClass>();
|
||||
const ValueType::StringClass &str = args[1]->as<ValueType::StringClass>();
|
||||
|
||||
CppLibrary::File *f = CppLibrary::FileManager::getInstance().GetFile(id);
|
||||
const char *data = reinterpret_cast<const char *>(str.c_str());
|
||||
f->fs->write(data, str.size());
|
||||
return std::make_shared<Object>(static_cast<ValueType::IntClass>(str.length()));
|
||||
// bytes wrote
|
||||
}},
|
||||
};
|
||||
return builtinFunctions;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
@@ -44,6 +45,19 @@ namespace Fig
|
||||
using BuiltinFunction = std::function<ObjectPtr(const std::vector<ObjectPtr> &)>;
|
||||
|
||||
const std::unordered_map<FString, int> &getBuiltinFunctionArgCounts();
|
||||
|
||||
/*
|
||||
File
|
||||
*/
|
||||
|
||||
struct FileHandler
|
||||
{
|
||||
int64_t id;
|
||||
std::fstream *fs;
|
||||
};
|
||||
|
||||
std::vector<FileHandler *> &getFileHandlers(); // global
|
||||
|
||||
const std::unordered_map<FString, BuiltinFunction> &getBuiltinFunctions();
|
||||
|
||||
inline bool isBuiltinFunction(const FString &name)
|
||||
|
||||
Reference in New Issue
Block a user