feat: 在解析器中实现 Lambda 和 new 表达式
- 增加了对 Lambda 表达式的初步解析支持,包括参数处理和返回类型。Lambda闭包尚未支持。 - 引入了用于对象初始化的新的表达式,支持可选的命名参数。 - 改进了表达式语法错误的错误报告。 - 更新了解析器和分析器以处理新的表达式类型并验证其语义。 - 修改了现有测试以涵盖新功能并确保其正确性。 - 改进了各种解析和语义错误的诊断。
This commit is contained in:
@@ -11,13 +11,19 @@
|
||||
#include <Ast/Expr/IdentiExpr.hpp>
|
||||
#include <Ast/Expr/IndexExpr.hpp>
|
||||
#include <Ast/Expr/InfixExpr.hpp>
|
||||
#include <Ast/Expr/LambdaExpr.hpp>
|
||||
#include <Ast/Expr/LiteralExpr.hpp>
|
||||
#include <Ast/Expr/MemberExpr.hpp>
|
||||
#include <Ast/Expr/NewExpr.hpp>
|
||||
#include <Ast/Expr/PrefixExpr.hpp>
|
||||
|
||||
#include <Ast/Stmt/ControlFlowStmts.hpp>
|
||||
#include <Ast/Stmt/ExprStmt.hpp>
|
||||
#include <Ast/Stmt/FnDefStmt.hpp>
|
||||
#include <Ast/Stmt/IfStmt.hpp>
|
||||
#include <Ast/Stmt/ImplStmt.hpp>
|
||||
#include <Ast/Stmt/InterfaceDefStmt.hpp>
|
||||
#include <Ast/Stmt/StructDefStmt.hpp>
|
||||
#include <Ast/Stmt/VarDecl.hpp>
|
||||
#include <Ast/Stmt/WhileStmt.hpp>
|
||||
#include <Ast/TypeExpr.hpp>
|
||||
@@ -29,7 +29,8 @@ namespace Fig
|
||||
IndexExpr,
|
||||
CallExpr,
|
||||
MemberExpr, // obj.prop
|
||||
ObjectInitExpr, // new Point{}
|
||||
NewExpr, // new Point{}
|
||||
LambdaExpr,
|
||||
|
||||
/* Statements */
|
||||
ExprStmt,
|
||||
|
||||
@@ -47,9 +47,10 @@ namespace Fig
|
||||
type = AstType::CallExpr;
|
||||
}
|
||||
|
||||
CallExpr(Expr *_callee, FnCallArgs _args) : callee(_callee), args(std::move(_args))
|
||||
CallExpr(Expr *_callee, FnCallArgs _args, SourceLocation _location) : callee(_callee), args(std::move(_args))
|
||||
{
|
||||
type = AstType::CallExpr;
|
||||
location = std::move(_location);
|
||||
}
|
||||
|
||||
virtual String toString() const override
|
||||
|
||||
70
src/Ast/Expr/LambdaExpr.hpp
Normal file
70
src/Ast/Expr/LambdaExpr.hpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/*!
|
||||
@file src/Ast/Expr/LambdaExpr.hpp
|
||||
@brief Lambda表达式定义
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Ast/Base.hpp>
|
||||
#include <Ast/Stmt/FnDefStmt.hpp>
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
struct LambdaExpr final : public Expr
|
||||
{
|
||||
// func (params) [-> return type] ([=> expr] / [ {stmt} ])
|
||||
|
||||
DynArray<Param *> params;
|
||||
TypeExpr *returnType;
|
||||
AstNode *body; // expr/blockstmt
|
||||
bool isExprBody;
|
||||
|
||||
DynArray<UpvalueInfo> upvalues;
|
||||
|
||||
LambdaExpr()
|
||||
{
|
||||
type = AstType::LambdaExpr;
|
||||
}
|
||||
|
||||
LambdaExpr(
|
||||
DynArray<Param *> _params,
|
||||
TypeExpr *_returnType,
|
||||
AstNode *_body,
|
||||
bool _isExprBody,
|
||||
SourceLocation _location) :
|
||||
params(std::move(_params)),
|
||||
returnType(_returnType),
|
||||
body(_body),
|
||||
isExprBody(_isExprBody)
|
||||
{
|
||||
type = AstType::LambdaExpr;
|
||||
location = std::move(_location);
|
||||
}
|
||||
|
||||
virtual String toString() const override
|
||||
{
|
||||
String specifying = "<LambdaExpr 'func (";
|
||||
for (auto &p : params)
|
||||
{
|
||||
if (p != params.front())
|
||||
{
|
||||
specifying += ", ";
|
||||
}
|
||||
specifying += p->toString();
|
||||
}
|
||||
if (isExprBody)
|
||||
{
|
||||
specifying += ") => ";
|
||||
specifying += body->toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
specifying += ") {";
|
||||
specifying += body->toString();
|
||||
specifying.push_back(U'}');
|
||||
}
|
||||
specifying += "'>";
|
||||
return specifying;
|
||||
}
|
||||
};
|
||||
}; // namespace Fig
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
struct ObjectInitExpr final : public Expr
|
||||
struct NewExpr final : public Expr
|
||||
{
|
||||
struct Arg
|
||||
{
|
||||
@@ -21,20 +21,20 @@ namespace Fig
|
||||
TypeExpr *typeExpr;
|
||||
DynArray<Arg> args;
|
||||
|
||||
ObjectInitExpr()
|
||||
NewExpr()
|
||||
{
|
||||
type = AstType::ObjectInitExpr;
|
||||
type = AstType::NewExpr;
|
||||
}
|
||||
ObjectInitExpr(TypeExpr *_te, DynArray<Arg> _args, SourceLocation _loc) :
|
||||
NewExpr(TypeExpr *_te, DynArray<Arg> _args, SourceLocation _loc) :
|
||||
typeExpr(_te), args(std::move(_args))
|
||||
{
|
||||
type = AstType::ObjectInitExpr;
|
||||
type = AstType::NewExpr;
|
||||
location = std::move(_loc);
|
||||
}
|
||||
|
||||
virtual String toString() const override
|
||||
{
|
||||
String res = "<ObjectInitExpr 'new " + typeExpr->toString() + "{";
|
||||
String res = "<NewExpr 'new " + typeExpr->toString() + "{";
|
||||
for (size_t i = 0; i < args.size(); ++i)
|
||||
{
|
||||
if (!args[i].name.empty())
|
||||
@@ -13,9 +13,12 @@ namespace Fig
|
||||
{
|
||||
struct Field
|
||||
{
|
||||
bool isPublic;
|
||||
bool typeInfer;
|
||||
|
||||
String name;
|
||||
TypeExpr *type;
|
||||
bool isPublic;
|
||||
Expr *initExpr;
|
||||
};
|
||||
bool isPublic;
|
||||
String name;
|
||||
|
||||
Reference in New Issue
Block a user