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

82
src/Parser/StmtParser.cpp Normal file
View File

@@ -0,0 +1,82 @@
/*!
@file src/Parser/StmtParser.hpp
@brief 语法分析器(Pratt + 手动递归下降) 语句解析实现
@author PuqiAR (im@puqiar.top)
@date 2026-02-19
*/
#include <Parser/Parser.hpp>
namespace Fig
{
Result<VarDecl *, Error> Parser::parseVarDecl(bool isPublic) // 由 parseStatement调用, 当前token为 var
{
state = State::ParsingVarDecl;
SourceLocation location = makeSourceLocation(consumeToken()); // consume `var`
if (currentToken().type != TokenType::Identifier)
{
return std::unexpected(makeUnexpectTokenError("VarDecl", "var name", currentToken()));
}
const String &name = srcManager.GetSub(currentToken().index, currentToken().length);
consumeToken(); // consume name
Expr *typeSpeicifer = nullptr;
if (match(TokenType::Colon)) // `:`
{
const auto &result = parseExpression(0, TokenType::Assign);
if (!result)
{
return std::unexpected(result.error());
}
typeSpeicifer = *result;
}
Expr *initExpr = nullptr;
if (match(TokenType::Assign))
{
const auto &result = parseExpression();
if (!result)
{
return std::unexpected(result.error());
}
initExpr = *result;
}
if (!match(TokenType::Semicolon))
{
makeExpectSemicolonError();
}
VarDecl *varDecl = new VarDecl(isPublic, name, typeSpeicifer, initExpr, location);
return varDecl;
}
Result<Stmt *, Error> Parser::parseStatement()
{
if (currentToken().type == TokenType::Public)
{
consumeToken(); // consume `public`
if (currentToken().type == TokenType::Variable)
{
return parseVarDecl(true);
}
}
else if (currentToken().type == TokenType::Variable)
{
return parseVarDecl(false);
}
else
{
const auto &expr_result = parseExpression(0);
if (!expr_result)
{
return std::unexpected(expr_result.error());
}
ExprStmt *exprStmt = new ExprStmt(*expr_result);
if (!match(TokenType::Semicolon))
{
return std::unexpected(makeExpectSemicolonError());
}
return exprStmt;
}
}
}; // namespace Fig