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

View File

@@ -14,4 +14,5 @@
#include <Ast/Expr/LiteralExpr.hpp>
#include <Ast/Expr/PrefixExpr.hpp>
#include <Ast/Stmt/ExprStmt.hpp>
#include <Ast/Stmt/VarDecl.hpp>

View File

@@ -16,29 +16,33 @@ namespace Fig
enum class AstType : std::uint8_t
{
AstNode, // 基类
Program, // 程序
Expr, // 表达式
Stmt, // 语句
/* Expressions */
IdentiExpr, // 标识符表达式
LiteralExpr, // 字面量表达式
PrefixExpr, // 一元 前缀表达式
InfixExpr, // 二元 中缀表达式
IndexExpr, // 后缀表达式,索引
CallExpr, // 后缀表达式,函数调用
PrefixExpr, // 一元 前缀表达式
InfixExpr, // 二元 中缀表达式
IndexExpr, // 后缀表达式,索引
CallExpr, // 后缀表达式,函数调用
/* Statements */
VarDecl,
ExprStmt, // 表达式语句,如 println(1)
VarDecl, // 变量声明
};
struct AstNode
{
AstType type = AstType::AstNode;
AstType type = AstType::AstNode;
SourceLocation location;
virtual String toString() const = 0;
};
struct Program;
struct Expr : public AstNode
{
Expr()
@@ -55,6 +59,31 @@ namespace Fig
type = AstType::Stmt;
}
};
struct Program final : public AstNode
{
DynArray<Stmt *> nodes;
Program()
{
type = AstType::Program;
}
Program(DynArray<Stmt *> _nodes)
{
type = AstType::Program;
nodes = std::move(_nodes);
if (!_nodes.empty())
{
location = std::move(_nodes.back()->location);
}
}
virtual String toString() const override
{
return "Program";
}
};
}; // namespace Fig
namespace std
@@ -73,4 +102,4 @@ namespace std
return std::format_to(ctx.out(), "{}", _node->toString().toStdString());
}
};
};
}; // namespace std

View File

@@ -20,6 +20,8 @@ namespace Fig
Negate, // 取反 -
Not, // 逻辑非 ! / not
AddressOf, // 取引用 &
Count // 哨兵,(int) Count 获得运算符数量注意enum必须从 0 开始且不中断)
};
enum class BinaryOperator : std::uint8_t
{
@@ -43,13 +45,13 @@ namespace Fig
Power, // 幂运算 **
Assign, // 赋值(修改) =
AddAssign, // +=
SubAssign, // -=
Assign, // 赋值(修改) =
AddAssign, // +=
SubAssign, // -=
MultiplyAssign, // *=
DivideAssign, // /=
ModuloAssign, // %=
BitXorAssign, // ^=
DivideAssign, // /=
ModuloAssign, // %=
BitXorAssign, // ^=
// 位运算
BitAnd, // 按位与 &
@@ -60,14 +62,22 @@ namespace Fig
// 成员访问
MemberAccess, // .
Count // 哨兵,(int) Count 获得运算符数量注意enum必须从 0 开始且不中断)
};
constexpr unsigned int GetOperatorsSize()
{
// 获取全部运算符的数量
return static_cast<std::uint8_t>(UnaryOperator::Count) + static_cast<std::uint8_t>(BinaryOperator::Count);
}
using BindingPower = unsigned int;
HashMap<TokenType, UnaryOperator> &GetUnaryOpMap();
HashMap<TokenType, UnaryOperator> &GetUnaryOpMap();
HashMap<TokenType, BinaryOperator> &GetBinaryOpMap();
HashMap<UnaryOperator, BindingPower> &GetUnaryOpBindingPowerMap();
HashMap<UnaryOperator, BindingPower> &GetUnaryOpBindingPowerMap();
HashMap<BinaryOperator, BindingPower> &GetBinaryOpBindingPowerMap();
BindingPower GetUnaryOpRBp(UnaryOperator);
@@ -77,6 +87,6 @@ namespace Fig
bool IsTokenOp(TokenType type, bool binary = true);
UnaryOperator TokenToUnaryOp(const Token &);
UnaryOperator TokenToUnaryOp(const Token &);
BinaryOperator TokenToBinaryOp(const Token &);
}; // namespace Fig

35
src/Ast/Stmt/ExprStmt.hpp Normal file
View File

@@ -0,0 +1,35 @@
/*!
@file src/Ast/Stmt/ExprStmt.hpp
@brief ExprStmt定义
@author PuqiAR (im@puqiar.top)
@date 2026-02-19
*/
#pragma once
#include <Ast/Base.hpp>
namespace Fig
{
struct ExprStmt final : public Stmt
{
Expr *expr;
ExprStmt()
{
type = AstType::ExprStmt;
}
ExprStmt(Expr *_expr) :
expr(_expr)
{
type = AstType::ExprStmt;
location = _expr->location;
}
virtual String toString() const override
{
return std::format("<ExprStmt: {}>", expr->toString());
}
};
}

View File

@@ -23,12 +23,13 @@ namespace Fig
type = AstType::VarDecl;
}
VarDecl(String _name, Expr *_typeSpecifier, Expr *_initExpr, SourceLocation _location) :
VarDecl(bool _isPublic, String _name, Expr *_typeSpecifier, Expr *_initExpr, SourceLocation _location) :
name(std::move(_name)),
typeSpecifier(_typeSpecifier),
initExpr(_initExpr) // location 指向关键字 var/const位置
{
type = AstType::VarDecl;
isPublic = _isPublic;
location = std::move(_location);
}