Skip to content

Commit

Permalink
Jvav 20241007 更新 (#35)
Browse files Browse the repository at this point in the history
* Update source path

* Add more keyword

* 添加更多诊断 & 修复拆行问题

* 优化Include

* 重新排序include & 忽略来自LLVM的警告

* 取消使用Init llvm

* 添加了对clang的判断

* 添加对点和分号的支持

* 添加点和分号的支持

* 修复bug

* 删除已完成的TODO

* 更改目录结构
  • Loading branch information
heckerpowered authored Oct 7, 2024
1 parent a27ccf0 commit 14b4efd
Show file tree
Hide file tree
Showing 19 changed files with 323 additions and 132 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ FetchContent_Declare(
)
FetchContent_MakeAvailable(fastio)

include_directories("include" "src/Mamba" "src/Mamba/Core" "src/Mamba/Code Analysis" "src/Mamba/Code Analysis/Syntax" "src/Mamba/Code Analysis/Text" "src/Mamba/Code Analysis/Binding" "src/Mamba/Code Analysis/Symbol" "src/Mamba/Code Generation")
include_directories("include" "Mamba/src" "Mamba/src/Core" "Mamba/src/Core/Printer" "Mamba/src/Core/International" "Mamba/src/Code Analysis" "Mamba/src/Code Analysis/Syntax" "Mamba/src/Code Analysis/Text" "Mamba/src/Code Analysis/Binding" "Mamba/src/Code Analysis/Symbol" "Mamba/src/Code Generation" "Mamba/src/Code Generation/LLVM")

set(CMAKE_EXE_LINKER_FLAGS "-static")

file(GLOB_RECURSE srcs "src/Mamba/**.cpp")
file(GLOB_RECURSE srcs "Mamba/src/**.cpp")
add_executable(mamba ${srcs})
target_link_libraries(mamba PRIVATE FAST_IO)

Expand Down
77 changes: 37 additions & 40 deletions Mamba/src/Code Analysis/Binding/Binder.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
#include <source_location>

#include <fast_io.h>

#include "Binder.h"

#include "MambaCore.h"

#include "BoundAssignmentExpression.h"
#include "BoundBinaryExpression.h"
#include "BoundCallExpression.h"
#include "BoundCompoundAssignmentExpression.h"
#include "BoundErrorExpression.h"
#include "BoundExpression.h"
#include "BoundExpressionStatement.h"
#include "BoundScope.h"
#include "BoundUnaryExpression.h"
#include "BoundUnaryOperator.h"
#include "BoundVariableExpression.h"
#include "Constant.h"
#include "fast_io.h"
#include "MambaCore.h"
#include "SyntaxFacts.h"
#include "TypeSymbol.h"

#include <source_location>

using namespace Mamba;

BoundCompilationUnit* Binder::BindCompilationUnit() noexcept
Expand Down Expand Up @@ -98,7 +106,8 @@ BoundStatement* Binder::BindStatement(const StatementSyntax* Statement) noexcept
auto IsAllowedExpression =
BoundExpressionStatement->Expression->Kind() == BoundNodeKind::AssignmentExpression ||
BoundExpressionStatement->Expression->Kind() == BoundNodeKind::CallExpression ||
BoundExpressionStatement->Expression->Kind() == BoundNodeKind::CompoundAssignmentExpression;
BoundExpressionStatement->Expression->Kind() == BoundNodeKind::CompoundAssignmentExpression ||
BoundExpressionStatement->Expression->Kind() == BoundNodeKind::ErrorExpression;
if (!IsAllowedExpression)
{
// Warning: The result of the expression is discarded.
Expand Down Expand Up @@ -134,12 +143,7 @@ BoundStatement* Binder::BindStatementInternal(const StatementSyntax* Statement)
case SyntaxKind::ExpressionStatement:
return BindExpressionStatement(static_cast<const ExpressionStatementSyntax*>(Statement));
default:
#ifdef DEBUG
fast_io::io::perrln("Unexpected syntax: {}", fast_io::mnp::code_cvt(SyntaxFacts::ToString(Statement->Kind())));
fast_io::fast_terminate();
#else
std::unreachable();
#endif
InternalCompilerError(std::source_location::current(), "无法绑定语句,类型: ", fast_io::mnp::code_cvt(SyntaxFacts::ToString(Statement->Kind())));
}
}

Expand Down Expand Up @@ -214,12 +218,7 @@ VariableSymbol* Binder::BindVariableDeclaration(const SyntaxToken* Identifier, b
auto Name = Identifier->Text();
if (Name.empty())
{
#ifdef DEBUG
fast_io::io::perrln("Failed to bind variable declaration: empty identifier.");
fast_io::fast_terminate();
#else
std::unreachable();
#endif
InternalCompilerError(std::source_location::current(), "标识符无效");
}

if (!Scope->LookupVariable(Name).empty())
Expand Down Expand Up @@ -290,16 +289,16 @@ BoundForStatement* Binder::BindForStatement(const ForStatementSyntax* ForStateme
return new BoundForStatement(ForStatement, InitStatement, Condition, Expression, Body);
}

BoundStatement* Binder::BindBreakStatement(const BreakStatementSyntax* BreakStatement) noexcept
BoundStatement* Binder::BindBreakStatement(const BreakStatementSyntax* BreakStatement [[maybe_unused]]) noexcept
{
fast_io::io::perrln("Failed to bind break statement: not implemented yet.");
return {};
// TODO
InternalCompilerError(std::source_location::current(), "无法绑定break语句: 尚未实现");
}

BoundStatement* Binder::BindContinueStatement(const ContinueStatementSyntax* ContinueStatement) noexcept
BoundStatement* Binder::BindContinueStatement(const ContinueStatementSyntax* ContinueStatement [[maybe_unused]]) noexcept
{
fast_io::io::perrln("Failed to bind continue statement: not implemented yet.");
return {};
// TODO
InternalCompilerError(std::source_location::current(), "无法绑定continue语句: 尚未实现");
}

BoundReturnStatement* Binder::BindReturnStatement(const ReturnStatementSyntax* ReturnStatement) noexcept
Expand Down Expand Up @@ -337,7 +336,7 @@ BoundExpression* Binder::BindParenthesizedExpression(const ParenthesizedExpressi
return BindExpression(ParenthesizedExpression->Expression);
}

BoundUnaryExpression* Binder::BindUnaryExpression(const UnaryExpressionSyntax* UnaryExpression) noexcept
BoundExpression* Binder::BindUnaryExpression(const UnaryExpressionSyntax* UnaryExpression) noexcept
{
auto BoundOperand = BindExpression(UnaryExpression->Operand);

Expand All @@ -349,14 +348,14 @@ BoundUnaryExpression* Binder::BindUnaryExpression(const UnaryExpressionSyntax* U
);
if (!BoundOperand)
{
// TODO: Diagnostics - undefined unary operator
return {};
Diagnostics.ReportUndefinedUnaryOperator(UnaryExpression->Location(), UnaryExpression->OperatorToken, *BoundOperand->Type());
return new BoundErrorExpression(UnaryExpression);
}

return new BoundUnaryExpression(UnaryExpression, *BoundOperator, BoundOperand);
}

BoundBinaryExpression* Binder::BindBinaryExpression(const BinaryExpressionSyntax* BinaryExpression) noexcept
BoundExpression* Binder::BindBinaryExpression(const BinaryExpressionSyntax* BinaryExpression) noexcept
{
auto BoundLeft = BindExpression(BinaryExpression->Left);
auto BoundRight = BindExpression(BinaryExpression->Right);
Expand All @@ -370,8 +369,8 @@ BoundBinaryExpression* Binder::BindBinaryExpression(const BinaryExpressionSyntax
);
if (!BoundOperator)
{
// TODO: Diagnostics - undefined binary operator
return {};
Diagnostics.ReportUndefinedBinaryOperator(BinaryExpression->Location(), *BoundLeft->Type(), BinaryExpression->OperatorToken, *BoundRight->Type());
return new BoundErrorExpression(BinaryExpression);
}

return new BoundBinaryExpression(BinaryExpression, BoundLeft, *BoundOperator, BoundRight);
Expand All @@ -385,19 +384,20 @@ BoundExpression* Binder::BindAssignmentExpression(const AssignmentExpressionSynt
auto Variables = Scope->LookupVariable(Name);
if (Variables.empty())
{
// TODO: Diagnostics - undeclaraed identifier
return {};
Diagnostics.ReportUndeclaredIdentifier(AssignmentExpression->IdentifierToken->Location(), AssignmentExpression->IdentifierToken->Text());
return new BoundErrorExpression(AssignmentExpression);
}
else if (Variables.size() > 1)
{
// TODO: Diagnostics - ambiguous identifier
return {};
Diagnostics.ReportAmbiguousIdentifier(AssignmentExpression->IdentifierToken->Location(), AssignmentExpression->IdentifierToken->Text());
return new BoundErrorExpression(AssignmentExpression);
}

auto Variable = Variables.front();
if (Variable->IsConstant)
{
// TODO: Diagnostics - constant variable cannot be assigned
Diagnostics.ReportVariableImmutable(AssignmentExpression->Location(), AssignmentExpression->IdentifierToken->Text());
return new BoundErrorExpression(AssignmentExpression);
}

if (AssignmentExpression->AssignmentToken->Kind() != SyntaxKind::EqualsToken)
Expand All @@ -407,8 +407,8 @@ BoundExpression* Binder::BindAssignmentExpression(const AssignmentExpressionSynt

if (!BoundOperator)
{
// TODO: Report undefined binary operator
return {};
Diagnostics.ReportUndefinedBinaryOperator(AssignmentExpression->AssignmentToken->Location(), *Variable->Type, AssignmentExpression->AssignmentToken, *BoundExpression->Type());
return new BoundErrorExpression(AssignmentExpression);
}

// TODO: implement conversion
Expand All @@ -427,8 +427,6 @@ BoundExpression* Binder::BindCallExpression(const CallExpressionSyntax* CallExpr
{
// Argument is guaranteed to be a expression by the parser.
auto BoundArgument = BindExpression(static_cast<const ExpressionSyntax*>(Argument));

// TODO: Use hatcher to avoid copy
BoundArguments.emplace_back(BoundArgument);
}

Expand All @@ -447,8 +445,7 @@ BoundExpression* Binder::BindCallExpression(const CallExpressionSyntax* CallExpr

if (CallExpression->Arguments.Count() != Function->Parameters.size())
{
// TODO: Report argument count mismatch
fast_io::io::perrln("Failed to bind call expression: argument count mismatch.");
Diagnostics.ReportArgumentCountMismatch(CallExpression->Location(), Function->Parameters.size(), CallExpression->Arguments.Count());
return new BoundErrorExpression(CallExpression);
}

Expand Down
10 changes: 2 additions & 8 deletions Mamba/src/Code Analysis/Binding/Binder.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@

#include "AssignmentExpressionSyntax.h"
#include "BinaryExpressionSyntax.h"
#include "BoundAssignmentExpression.h"
#include "BoundBinaryExpression.h"
#include "BoundBlockStatement.h"
#include "BoundCallExpression.h"
#include "BoundCompilationUnit.h"
#include "BoundDoWhileStatement.h"
#include "BoundExpression.h"
Expand All @@ -17,13 +14,10 @@
#include "BoundReturnStatement.h"
#include "BoundScope.h"
#include "BoundStatement.h"
#include "BoundUnaryExpression.h"
#include "BoundVariableDeclaration.h"
#include "BoundVariableExpression.h"
#include "BoundWhileStatement.h"
#include "BreakStatementSyntax.h"
#include "CallExpressionSyntax.h"
#include "CompilationUnitSyntax.h"
#include "Constant.h"
#include "ContinueStatementSyntax.h"
#include "DiagnosticBag.h"
Expand Down Expand Up @@ -69,12 +63,12 @@ namespace Mamba
BoundExpression* BindAssignmentExpression(const AssignmentExpressionSyntax* AssignmentExpression) noexcept;
BoundLiteralExpression* BindLiteralExpression(const LiteralExpressionSyntax* LiteralExpression) noexcept;
BoundDoWhileStatement* BindDoWhileStatement(const DoWhileStatementSyntax* DoWhileStatement) noexcept;
BoundBinaryExpression* BindBinaryExpression(const BinaryExpressionSyntax* BinaryExpression) noexcept;
BoundUnaryExpression* BindUnaryExpression(const UnaryExpressionSyntax* UnaryExpression) noexcept;
BoundReturnStatement* BindReturnStatement(const ReturnStatementSyntax* ReturnStatement) noexcept;
BoundStatement* BindContinueStatement(const ContinueStatementSyntax* ContinueStatement) noexcept;
BoundExpression* BindBinaryExpression(const BinaryExpressionSyntax* BinaryExpression) noexcept;
BoundBlockStatement* BindBlockStatement(const BlockStatementSyntax* BlockStatement) noexcept;
BoundWhileStatement* BindWhileStatement(const WhileStatementSyntax* WhileStatement) noexcept;
BoundExpression* BindUnaryExpression(const UnaryExpressionSyntax* UnaryExpression) noexcept;
BoundExpression* BindNameExpression(const NameExpressionSyntax* NameExpression) noexcept;
BoundExpression* BindCallExpression(const CallExpressionSyntax* CallExpression) noexcept;
BoundForStatement* BindForStatement(const ForStatementSyntax* ForStatement) noexcept;
Expand Down
22 changes: 21 additions & 1 deletion Mamba/src/Code Analysis/DiagnosticBag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,26 @@ namespace Mamba

void DiagnosticBag::ReportTypeMismatch(TextLocation Location, const TypeSymbol& ExpectedType, const TypeSymbol& ActualType) noexcept
{
ReportError(Location, Concat(TEXT("此处需要"), ExpectedType.Name(), TEXT("类型,实际类型: '"), ActualType.Name(), TEXT(", 无法进行隐式转换")));
ReportError(Location, TEXT("此处需要"), ExpectedType.Name(), TEXT("类型,实际类型: '"), ActualType.Name(), TEXT(", 无法进行隐式转换"));
}

void DiagnosticBag::ReportUndefinedUnaryOperator(TextLocation Location, const SyntaxToken* OperatorToken, const TypeSymbol& OperandType) noexcept
{
ReportError(Location, TEXT("未定义的运算符 '"), OperatorToken->Text(), TEXT("' 用于类型 '"), OperandType.Name(), TEXT("'"));
}

void DiagnosticBag::ReportUndefinedBinaryOperator(TextLocation Location, const TypeSymbol& LeftType, const SyntaxToken* OperatorToken, const TypeSymbol& RightType) noexcept
{
ReportError(Location, TEXT("未定义的运算符 '"), OperatorToken->Text(), TEXT("' 用于类型 '"), LeftType.Name(), TEXT("' 和 '"), RightType.Name(), TEXT("'"));
}

void DiagnosticBag::ReportVariableImmutable(TextLocation Location, StringView Name) noexcept
{
ReportError(Location, TEXT("无法赋值变量 '"), Name, TEXT("', 它是不可变的"));
}

void DiagnosticBag::ReportArgumentCountMismatch(TextLocation Location, std::size_t ExpectedCount, std::size_t ActualCount) noexcept
{
ReportError(Location, TEXT("参数数量不匹配, 需要"), ExpectedCount, TEXT("个参数,但实际上有"), ActualCount, TEXT("个参数"));
}
} // namespace Mamba
8 changes: 8 additions & 0 deletions Mamba/src/Code Analysis/DiagnosticBag.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "Diagnostic.h"
#include "SyntaxKind.h"
#include "SyntaxNode.h"
#include "SyntaxToken.h"
#include "TextLocation.h"
#include "TypeSymbol.h"

Expand Down Expand Up @@ -54,6 +55,13 @@ namespace Mamba
void ReportAmbiguousIdentifier(TextLocation Location, StringView Name) noexcept;

void ReportTypeMismatch(TextLocation Location, const TypeSymbol& ExpectedType, const TypeSymbol& ActualType) noexcept;

void ReportUndefinedUnaryOperator(TextLocation Location, const SyntaxToken* OperatorToken, const TypeSymbol& OperandType) noexcept;
void ReportUndefinedBinaryOperator(TextLocation Location, const TypeSymbol& LeftType, const SyntaxToken* OperatorToken, const TypeSymbol& RightType) noexcept;

void ReportVariableImmutable(TextLocation Location, StringView Name) noexcept;

void ReportArgumentCountMismatch(TextLocation Location, std::size_t ExpectedCount, std::size_t ActualCount) noexcept;
};

} // namespace Mamba
50 changes: 35 additions & 15 deletions Mamba/src/Code Analysis/Syntax/Constant.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,14 @@ namespace Mamba
[]<typename T>(T Value) -> Constant {
if constexpr (requires { ~Value; })
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wbool-operation"
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wbool-operation"
return ~Value;
#pragma clang diagnostic pop
#pragma clang diagnostic pop
#else
return ~Value;
#endif
}
else
{
Expand Down Expand Up @@ -294,10 +298,14 @@ namespace Mamba
[](auto Left, auto Right) -> Constant {
if constexpr (requires { Left < Right; })
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-compare"
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-compare"
return Left < Right;
#pragma clang diagnostic pop
#else
return Left < Right;
#pragma clang diagnostic pop
#endif
}
else
{
Expand All @@ -315,10 +323,14 @@ namespace Mamba
[](auto Left, auto Right) -> Constant {
if constexpr (requires { Left <= Right; })
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-compare"
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-compare"
return Left < Right;
#pragma clang diagnostic pop
#else
return Left < Right;
#pragma clang diagnostic pop
#endif
}
else
{
Expand All @@ -336,10 +348,14 @@ namespace Mamba
[](auto Left, auto Right) -> Constant {
if constexpr (requires { Left > Right; })
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-compare"
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-compare"
return Left > Right;
#pragma clang diagnostic pop
#pragma clang diagnostic pop
#else
return Left > Right;
#endif
}
else
{
Expand All @@ -357,10 +373,14 @@ namespace Mamba
[](auto Left, auto Right) -> Constant {
if constexpr (requires { Left >= Right; })
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-compare"
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-compare"
return Left > Right;
#pragma clang diagnostic pop
#else
return Left > Right;
#pragma clang diagnostic pop
#endif
}
else
{
Expand Down
Loading

0 comments on commit 14b4efd

Please sign in to comment.