[Feat] 详细区分左值(LvObject)与右值(RvObject -> ObjectPtr)

[Impl] 重构evaluator.cpp + hpp 全部
[Feat] 增加对于IndexExpr的解析
[Fix][Impl] 现在点运算符不由BinaryExpr负责,增加MemberExpr,单独实现解析
[Impl] 项目目录全部翻修, src/目录下单独文件夹放置每一个模块
This commit is contained in:
2025-12-24 17:51:49 +08:00
parent 3227230aa2
commit fc35368d85
70 changed files with 1558 additions and 1233 deletions

59
src/Core/core.hpp Normal file
View File

@@ -0,0 +1,59 @@
#pragma once
#include <Core/fig_string.hpp>
#include <cstdint>
#include <string_view>
#define __FCORE_VERSION "0.3.2"
#if defined(_WIN32)
#define __FCORE_PLATFORM "Windows"
#elif defined(__APPLE__)
#define __FCORE_PLATFORM "Apple"
#elif defined(__linux__)
#define __FCORE_PLATFORM "Linux"
#elif defined(__unix__)
#define __FCORE_PLATFORM "Unix"
#else
#define __FCORE_PLATFORM "Unknown"
#endif
#if defined(__GNUC__)
#if defined(_WIN32)
#if defined(__clang__)
#define __FCORE_COMPILER "llvm-mingw"
#else
#define __FCORE_COMPILER "MinGW"
#endif
#else
#define __FCORE_COMPILER "GCC"
#endif
#elif defined(__clang__)
#define __FCORE_COMPILER "Clang"
#elif defined(_MSC_VER)
#define __FCORE_COMPILER "MSVC"
#else
#define __FCORE_COMPILER "Unknown"
#endif
#if SIZE_MAX == 18446744073709551615ull
#define __FCORE_ARCH "64"
#else
#define __FCORE_ARCH "86"
#endif
namespace Fig
{
namespace Core
{
inline constexpr std::string_view VERSION = __FCORE_VERSION;
inline constexpr std::string_view LICENSE = "MIT";
inline constexpr std::string_view AUTHOR = "PuqiAR";
inline constexpr std::string_view PLATFORM = __FCORE_PLATFORM;
inline constexpr std::string_view COMPILER = __FCORE_COMPILER;
inline constexpr std::string_view COMPILE_TIME = __FCORE_COMPILE_TIME;
inline constexpr std::string_view ARCH = __FCORE_ARCH;
inline constexpr FString MAIN_FUNCTION = u8"main";
}; // namespace Core
}; // namespace Fig

100
src/Core/fig_string.hpp Normal file
View File

@@ -0,0 +1,100 @@
#pragma once
#include <string>
#include <string_view>
namespace Fig
{
// using String = std::u8string;
// using StringView = std::u8string_view;
class FStringView : public std::u8string_view
{
public:
using std::u8string_view::u8string_view;
static FStringView fromBasicStringView(std::string_view sv)
{
return FStringView(reinterpret_cast<const char8_t*>(sv.data()), sv.size());
}
explicit FStringView(std::string_view sv)
{
*this = fromBasicStringView(sv);
}
explicit FStringView()
{
*this = fromBasicStringView(std::string_view(""));
}
};
class FString : public std::u8string
{
public:
using std::u8string::u8string;
explicit FString(const std::u8string &str)
{
*this = fromU8String(str);
}
explicit FString(std::string str)
{
*this = fromBasicString(str);
}
explicit FString(FStringView sv)
{
*this = fromStringView(sv);
}
std::string toBasicString() const
{
return std::string(this->begin(), this->end());
}
FStringView toStringView() const
{
return FStringView(this->data(), this->size());
}
static FString fromBasicString(const std::string &str)
{
return FString(str.begin(), str.end());
}
static FString fromStringView(FStringView sv)
{
return FString(reinterpret_cast<const char*> (sv.data()));
}
static FString fromU8String(const std::u8string &str)
{
return FString(str.begin(), str.end());
}
size_t length()
{
// get UTF8-String real length
size_t len = 0;
for (auto it = this->begin(); it != this->end(); ++it)
{
if ((*it & 0xC0) != 0x80)
{
++len;
}
}
return len;
}
};
}; // namespace Fig
namespace std
{
template <>
struct hash<Fig::FString>
{
std::size_t operator()(const Fig::FString &s) const
{
return std::hash<std::u8string>{}(static_cast<const std::u8string &>(s));
}
};
}

260
src/Core/utf8_iterator.hpp Normal file
View File

@@ -0,0 +1,260 @@
#include <corecrt.h>
#include <string>
#include <iterator>
#include <string>
#include <cwctype>
// fuckyou C++
// i don't know how to deal with unicode string in cpp
// fuck
// generate by Qwen3-Coder:
namespace Fig
{
class UTF8Char
{
private:
std::u8string char_data_;
public:
UTF8Char(const std::u8string &data) :
char_data_(data) {}
// 获取UTF-8字符的字节长度
static size_t getUTF8CharLength(char8_t first_byte)
{
if ((first_byte & 0x80) == 0x00) return 1;
if ((first_byte & 0xE0) == 0xC0) return 2;
if ((first_byte & 0xF0) == 0xE0) return 3;
if ((first_byte & 0xF8) == 0xF0) return 4;
return 1;
}
// 转换为Unicode码点
char32_t toCodePoint() const
{
if (char_data_.empty()) return 0;
size_t len = getUTF8CharLength(char_data_[0]);
if (len > char_data_.length()) return 0;
char32_t code_point = 0;
switch (len)
{
case 1:
code_point = char_data_[0];
break;
case 2:
code_point = ((char_data_[0] & 0x1F) << 6) | (char_data_[1] & 0x3F);
break;
case 3:
code_point = ((char_data_[0] & 0x0F) << 12) | ((char_data_[1] & 0x3F) << 6) | (char_data_[2] & 0x3F);
break;
case 4:
code_point = ((char_data_[0] & 0x07) << 18) | ((char_data_[1] & 0x3F) << 12) | ((char_data_[2] & 0x3F) << 6) | (char_data_[3] & 0x3F);
break;
}
return code_point;
}
inline bool operator==(char32_t ch)
{
return this->toCodePoint() == ch;
}
// 字符分类函数
bool isAlpha() const
{
char32_t cp = toCodePoint();
return std::iswalpha(static_cast<wint_t>(cp));
}
bool isDigit() const
{
char32_t cp = toCodePoint();
return std::iswdigit(static_cast<wint_t>(cp));
}
bool isAlnum() const
{
char32_t cp = toCodePoint();
return std::iswalnum(static_cast<wint_t>(cp));
}
bool isSpace() const
{
char32_t cp = toCodePoint();
return std::iswspace(static_cast<wint_t>(cp));
}
bool isUpper() const
{
char32_t cp = toCodePoint();
return std::iswupper(static_cast<wint_t>(cp));
}
bool isLower() const
{
char32_t cp = toCodePoint();
return std::iswlower(static_cast<wint_t>(cp));
}
bool isPunct() const
{
char32_t cp = toCodePoint();
return std::iswpunct(static_cast<wint_t>(cp));
}
// 获取底层数据
const std::u8string &getString() const { return char_data_; }
// 获取字符长度(字节数)
size_t length() const { return char_data_.length(); }
// 是否为空
bool empty() const { return char_data_.empty(); }
};
class UTF8Iterator
{
private:
const std::u8string *str_;
size_t pos_;
// 获取UTF-8字符的字节长度
static size_t getUTF8CharLength(char8_t first_byte)
{
if ((first_byte & 0x80) == 0x00) return 1;
if ((first_byte & 0xE0) == 0xC0) return 2;
if ((first_byte & 0xF0) == 0xE0) return 3;
if ((first_byte & 0xF8) == 0xF0) return 4;
return 1;
}
// 获取下一个字符的起始位置
size_t getNextCharPos(size_t current_pos) const
{
if (current_pos >= str_->length()) return current_pos;
size_t char_len = getUTF8CharLength((*str_)[current_pos]);
return current_pos + char_len;
}
// 获取前一个字符的起始位置
size_t getPrevCharPos(size_t current_pos) const
{
if (current_pos == 0) return 0;
size_t pos = current_pos - 1;
while (pos > 0 && (str_->at(pos) & 0xC0) == 0x80)
{
--pos;
}
return pos;
}
public:
using iterator_category = std::bidirectional_iterator_tag;
using value_type = UTF8Char;
using difference_type = std::ptrdiff_t;
using pointer = const UTF8Char *;
using reference = const UTF8Char &;
// 构造函数
UTF8Iterator(const std::u8string &str, size_t pos = 0) :
str_(&str), pos_(pos)
{
if (pos_ > str_->length()) pos_ = str_->length();
}
// 前置递增
UTF8Iterator &operator++()
{
pos_ = getNextCharPos(pos_);
return *this;
}
// 后置递增
UTF8Iterator operator++(int)
{
UTF8Iterator temp = *this;
pos_ = getNextCharPos(pos_);
return temp;
}
// 前置递减
UTF8Iterator &operator--()
{
pos_ = getPrevCharPos(pos_);
return *this;
}
// 后置递减
UTF8Iterator operator--(int)
{
UTF8Iterator temp = *this;
pos_ = getPrevCharPos(pos_);
return temp;
}
// 解引用操作符 - 返回当前字符
UTF8Char operator*() const
{
if (pos_ >= str_->length())
{
return UTF8Char(std::u8string());
}
size_t char_len = getUTF8CharLength((*str_)[pos_]);
size_t end_pos = pos_ + char_len;
if (end_pos > str_->length())
{
end_pos = str_->length();
}
return UTF8Char(str_->substr(pos_, end_pos - pos_));
}
UTF8Char peek() const
{
if (pos_ >= str_->length())
{
return UTF8Char(std::u8string());
}
size_t next_pos = getNextCharPos(pos_);
if (next_pos >= str_->length())
{
return UTF8Char(std::u8string());
}
size_t char_len = getUTF8CharLength((*str_)[next_pos]);
size_t end_pos = next_pos + char_len;
if (end_pos > str_->length())
{
end_pos = str_->length();
}
return UTF8Char(str_->substr(next_pos, end_pos - next_pos));
}
// 窥探前一个字符
UTF8Char peekPrev() const
{
if (pos_ == 0)
{
return UTF8Char(std::u8string());
}
size_t prev_pos = getPrevCharPos(pos_);
size_t char_len = getUTF8CharLength((*str_)[prev_pos]);
size_t end_pos = prev_pos + char_len;
if (end_pos > str_->length())
{
end_pos = str_->length();
}
return UTF8Char(str_->substr(prev_pos, end_pos - prev_pos));
}
// 获取当前位置
size_t position() const { return pos_; }
size_t column() const { return pos_ + 1; }
// 检查是否到达末尾
bool isEnd() const { return pos_ >= str_->length(); }
};
} // namespace Fig

9
src/Core/warning.cpp Normal file
View File

@@ -0,0 +1,9 @@
#include <Core/warning.hpp>
namespace Fig
{
const std::unordered_map<std::size_t, FString> Warning::standardWarnings = {
{1, FString(u8"Identifier is too similar to a keyword or a primitive type")},
{2, FString(u8"The identifier is too abstract")}
};
};

55
src/Core/warning.hpp Normal file
View File

@@ -0,0 +1,55 @@
#pragma once
#include <Core/fig_string.hpp>
#include <Utils/magic_enum/magic_enum.hpp>
#include <unordered_map>
namespace Fig
{
class Warning
{
private:
size_t id; // the id (standard) of warning
FString msg;
size_t line, column;
public:
static const std::unordered_map<size_t, FString> standardWarnings;
Warning(size_t _id, FString _msg)
{
id = _id;
msg = std::move(_msg);
}
Warning(size_t _id, FString _msg, size_t _line, size_t _column)
{
id = _id;
msg = std::move(_msg);
line = _line;
column = _column;
}
auto getIDName()
{
return standardWarnings.at(id);
}
auto getID()
{
return id;
}
auto getMsg()
{
return msg;
}
auto getLine()
{
return line;
}
auto getColumn()
{
return column;
}
};
};