feat: Implement compiler and virtual machine for Fig language

- Added Compiler class with methods for compiling programs, statements, and expressions.
- Introduced Proto structure to hold compiled bytecode and constants.
- Implemented expression compilation including literals, identifiers, and infix expressions.
- Developed statement compilation for variable declarations and expression statements.
- Created a VM class to execute compiled bytecode with support for arithmetic and comparison operations.
- Added Object and Value classes for handling different data types and memory management.
- Implemented String and Struct objects for enhanced data representation.
- Established a parser for parsing variable declarations and statements.
- Included tests for the VM and object representations.
This commit is contained in:
2026-02-20 14:05:56 +08:00
parent f2e899c7a7
commit 2631f76da1
31 changed files with 1722 additions and 94 deletions

237
src/Object/ObjectBase.hpp Normal file
View File

@@ -0,0 +1,237 @@
/*!
@file src/Object/ObjectBase.hpp
@brief 值表示定义 (NaN Boxing) uint64
@author PuqiAR (im@puqiar.top)
@date 2026-02-19
*/
#pragma once
#include <bit>
#include <cstdint>
#include <Deps/Deps.hpp>
namespace Fig
{
struct Object; // 前置声明
/*
正常来说直接 Value = std::uint64_t会更快
但是这样会带来隐式转换的问题
因此我们封装成一个类,这样速度不会损失很多。
(release模式编译器会直接优化, 速度和uint64_t直接表示一样快)
*/
class Value
{
private:
std::uint64_t v_; // 唯一的物理成员 sizeof(Value) 永远是 8 字节。
// --- 私有掩码常量 ---
static constexpr std::uint64_t QNAN_MASK = 0x7ffc000000000000;
static constexpr std::uint64_t SIGN_BIT = 0x8000000000000000;
// 专门给 Int32 预留的高位 Tag
static constexpr std::uint32_t INT_TAG_HIGH = 0x7FFD0000;
// 基础原语 Tag
static constexpr std::uint64_t TAG_NULL = 1;
static constexpr std::uint64_t TAG_FALSE = 2;
static constexpr std::uint64_t TAG_TRUE = 3;
// 私有底层构造:仅供内部组装使用
constexpr explicit Value(uint64_t raw) : v_(raw) {}
public:
// 默认构造为 Null保证未初始化变量也是安全的
constexpr Value()
{
*this = GetNullInstance();
}
[[nodiscard]] static constexpr Value FromDouble(double d)
{
uint64_t raw = std::bit_cast<uint64_t>(d);
// 清洗非法的 NaN
if ((raw & QNAN_MASK) == QNAN_MASK)
return Value(QNAN_MASK);
return Value(raw);
}
[[nodiscard]] static constexpr Value FromInt(std::int32_t i)
{
// 移位构造,彻底阻断符号扩展漏洞
return Value((static_cast<uint64_t>(INT_TAG_HIGH) << 32) | static_cast<uint32_t>(i));
}
[[nodiscard]] static constexpr Value &GetTrueInstance()
{
static Value trueInstance(QNAN_MASK | TAG_TRUE);
return trueInstance;
}
[[nodiscard]] static constexpr Value &GetFalseInstance()
{
static Value falseInstance(QNAN_MASK | TAG_FALSE);
return falseInstance;
}
[[nodiscard]] static constexpr Value &FromBool(bool b)
{
return (b ? GetTrueInstance() : GetFalseInstance());
}
[[nodiscard]] static constexpr Value &GetNullInstance()
{
static Value nullInstance(QNAN_MASK | TAG_NULL);
return nullInstance;
}
[[nodiscard]] static Value FromObject(Object *ptr)
{
return Value(reinterpret_cast<uint64_t>(ptr) | SIGN_BIT | QNAN_MASK);
}
// 类型检查 (Is)
[[nodiscard]] constexpr bool IsDouble() const
{
return (v_ & QNAN_MASK) != QNAN_MASK;
}
[[nodiscard]] constexpr bool IsInt() const
{
// 安全的高 32 位移位判定
return static_cast<uint32_t>(v_ >> 32) == INT_TAG_HIGH;
}
[[nodiscard]] constexpr bool IsNumber() const
{
return IsDouble() || IsInt();
}
[[nodiscard]] constexpr bool IsObject() const
{
return (v_ & (SIGN_BIT | QNAN_MASK)) == (SIGN_BIT | QNAN_MASK);
}
[[nodiscard]] constexpr bool IsNull() const
{
return v_ == (QNAN_MASK | TAG_NULL);
}
[[nodiscard]] constexpr bool IsBool() const
{
return (v_ | 1) == (QNAN_MASK | TAG_TRUE);
}
// 提取数据 (Unbox / As)
[[nodiscard]] constexpr double AsDouble() const
{
return std::bit_cast<double>(v_);
}
[[nodiscard]] constexpr int32_t AsInt() const
{
return static_cast<int32_t>(v_);
}
// 核心辅助:泛型数字提取。算术指令可以直接用这个,免去手写 if 分支
// 若不是 int/double 会导致非常恐怖的问题
[[nodiscard]] constexpr double CastToDouble() const
{
return IsInt() ? static_cast<double>(AsInt()) : AsDouble();
}
[[nodiscard]] constexpr bool AsBool() const
{
return v_ == (QNAN_MASK | TAG_TRUE);
}
[[nodiscard]] struct Object *AsObject() const
{
return reinterpret_cast<struct Object *>(v_ & ~(SIGN_BIT | QNAN_MASK));
}
// 重载
// 暴露原生值用于硬核位运算或 Hash 计算
[[nodiscard]] constexpr uint64_t Raw() const
{
return v_;
}
// 让 VM 的 OP_EQ 指令极简:`if (RA == RB)`
[[nodiscard]] constexpr bool operator==(const Value &other) const
{
// IEEE 754 规定浮点数有 +0.0 == -0.0 的特殊规则
if (IsDouble() && other.IsDouble())
{
return AsDouble() == other.AsDouble();
}
// 直接比较 64 位整数内存
return v_ == other.v_;
}
[[nodiscard]] constexpr bool operator!=(const Value &other) const
{
return !(*this == other);
}
// 类函数
[[nodiscard]]
constexpr String ToString() const
{
if (IsNull())
{
return "null";
}
else if (IsInt())
{
return std::to_string(AsInt());
}
else if (IsDouble())
{
return std::format("{}", AsDouble());
}
else if (IsBool())
{
return (AsBool() ? "true" : "false");
}
else if (IsObject())
{
return "Object"; // TODO: 分派
}
else
{
return "Unknow";
}
}
};
/*
C风格继承 + 手动分发
禁止任何 virtual 达到最高效率
*/
enum class ObjectType : uint8_t
{
String,
Function,
Struct,
Instance,
};
struct Struct /* : public Object */; // 结构体基类的定义,前向声明
// Total 24 bytes size
struct Object
{
Object *next; // 8 bytes: gc链表
Struct *klass; // 8 bytes: 一切皆对象,父类指针
ObjectType type; // 1 byte : 类型
bool isMarked = false; // 1 byte : gc标记
// + 6 bytes padding
};
} // namespace Fig