添加了标准库 std.file。支持简单的文件读写

This commit is contained in:
2026-02-12 14:29:26 +08:00
parent a00be02359
commit ca0396568b
5 changed files with 252 additions and 4 deletions

View File

@@ -0,0 +1,3 @@
#pragma once
#include "File/File.hpp"

View 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

View 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
};
}

View File

@@ -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;
}

View File

@@ -10,6 +10,7 @@
#include <unordered_map>
#include <functional>
#include <vector>
#include <fstream>
namespace Fig
{
@@ -44,7 +45,20 @@ namespace Fig
using BuiltinFunction = std::function<ObjectPtr(const std::vector<ObjectPtr> &)>;
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)
{