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:
@@ -14,4 +14,5 @@
|
||||
#include <Ast/Expr/LiteralExpr.hpp>
|
||||
#include <Ast/Expr/PrefixExpr.hpp>
|
||||
|
||||
#include <Ast/Stmt/ExprStmt.hpp>
|
||||
#include <Ast/Stmt/VarDecl.hpp>
|
||||
@@ -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
|
||||
@@ -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
35
src/Ast/Stmt/ExprStmt.hpp
Normal 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());
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user