添加了标准库 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/Statements/ControlSt.hpp>
|
||||||
#include <Ast/astBase.hpp>
|
#include <Ast/astBase.hpp>
|
||||||
#include <Ast/functionParameters.hpp>
|
#include <Ast/functionParameters.hpp>
|
||||||
#include <Evaluator/Context/context.hpp>
|
|
||||||
#include <Core/fig_string.hpp>
|
|
||||||
#include <Ast/AccessModifier.hpp>
|
#include <Ast/AccessModifier.hpp>
|
||||||
|
|
||||||
#include <Evaluator/Value/structType.hpp>
|
#include <Evaluator/Value/structType.hpp>
|
||||||
#include <Evaluator/Value/value.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 <memory>
|
||||||
#include <print>
|
#include <print>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -132,9 +138,18 @@ namespace Fig::Builtins
|
|||||||
{u8"__fmath_tan", 1},
|
{u8"__fmath_tan", 1},
|
||||||
{u8"__fmath_tanh", 1},
|
{u8"__fmath_tanh", 1},
|
||||||
{u8"__fmath_trunc", 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;
|
return builtinFunctionArgCounts;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::unordered_map<FString, BuiltinFunction> &getBuiltinFunctions()
|
const std::unordered_map<FString, BuiltinFunction> &getBuiltinFunctions()
|
||||||
{
|
{
|
||||||
static const std::unordered_map<FString, BuiltinFunction> builtinFunctions{
|
static const std::unordered_map<FString, BuiltinFunction> builtinFunctions{
|
||||||
@@ -421,6 +436,47 @@ namespace Fig::Builtins
|
|||||||
ValueType::DoubleClass d = val->getNumericValue();
|
ValueType::DoubleClass d = val->getNumericValue();
|
||||||
return std::make_shared<Object>(trunc(d));
|
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;
|
return builtinFunctions;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
namespace Fig
|
namespace Fig
|
||||||
{
|
{
|
||||||
@@ -44,7 +45,20 @@ namespace Fig
|
|||||||
using BuiltinFunction = std::function<ObjectPtr(const std::vector<ObjectPtr> &)>;
|
using BuiltinFunction = std::function<ObjectPtr(const std::vector<ObjectPtr> &)>;
|
||||||
|
|
||||||
const std::unordered_map<FString, int> &getBuiltinFunctionArgCounts();
|
const std::unordered_map<FString, int> &getBuiltinFunctionArgCounts();
|
||||||
const std::unordered_map<FString, BuiltinFunction> &getBuiltinFunctions();
|
|
||||||
|
/*
|
||||||
|
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)
|
inline bool isBuiltinFunction(const FString &name)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user