forked from PuqiAR/Fig-TreeWalker
[Feat] 详细区分左值(LvObject)与右值(RvObject -> ObjectPtr)
[Impl] 重构evaluator.cpp + hpp 全部 [Feat] 增加对于IndexExpr的解析 [Fix][Impl] 现在点运算符不由BinaryExpr负责,增加MemberExpr,单独实现解析 [Impl] 项目目录全部翻修, src/目录下单独文件夹放置每一个模块
This commit is contained in:
59
src/Core/core.hpp
Normal file
59
src/Core/core.hpp
Normal 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
100
src/Core/fig_string.hpp
Normal 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
260
src/Core/utf8_iterator.hpp
Normal 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
9
src/Core/warning.cpp
Normal 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
55
src/Core/warning.hpp
Normal 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;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user