Skip to content

Commit

Permalink
Merge pull request #28 from heckerpowered/heckerpowered/dev
Browse files Browse the repository at this point in the history
支持基于LLVM的代码生成
  • Loading branch information
heckerpowered authored Sep 26, 2024
2 parents fb7ccb0 + dfe7d91 commit 71af38b
Show file tree
Hide file tree
Showing 27 changed files with 439 additions and 143 deletions.
41 changes: 26 additions & 15 deletions src/Mamba/Code Analysis/Binding/Binder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "BoundExpressionStatement.h"
#include "MambaCore.h"
#include "SyntaxFacts.h"
#include "TypeSymbol.h"
#include <source_location>

using namespace Mamba;
Expand Down Expand Up @@ -65,9 +66,9 @@ std::vector<const ParameterSymbol*> Binder::BindParameter(
Parameters |
std::views::transform([](auto&& Node) { return dynamic_cast<const ParameterSyntax*>(Node); }) | std::views::enumerate)
{
const auto Name = Parameter->Identifier->Text();
const auto Type = new TypeSymbol(Parameter->Type->Identifier->Text());
const auto ParameterSymbol = new class ParameterSymbol(Name, Type, Index);
auto Name = Parameter->Identifier->Text();
auto Type = new TypeSymbol(Parameter->Type->Identifier->Text());
auto ParameterSymbol = new class ParameterSymbol(Name, Type, Index);
Scope->Declare(ParameterSymbol);
}
#else
Expand All @@ -77,9 +78,9 @@ std::vector<const ParameterSymbol*> Binder::BindParameter(
{
++Index;

const auto Name = Parameter->Identifier->Text();
const auto Type = new TypeSymbol(Parameter->Type->Identifier->Text());
const auto ParameterSymbol = new class ParameterSymbol(Name, Type, Index);
auto Name = Parameter->Identifier->Text();
auto Type = new TypeSymbol(Parameter->Type->Identifier->Text());
auto ParameterSymbol = new class ParameterSymbol(Name, Type, Index);
Scope->Declare(ParameterSymbol);
}

Expand Down Expand Up @@ -298,7 +299,7 @@ BoundStatement* Binder::BindContinueStatement(const ContinueStatementSyntax* Con
BoundReturnStatement* Binder::BindReturnStatement(const ReturnStatementSyntax* ReturnStatement) noexcept
{
// TODO: Diagnostics
const auto Expression = BindExpression(ReturnStatement->Expression);
auto Expression = BindExpression(ReturnStatement->Expression);
return new BoundReturnStatement(ReturnStatement, Expression);
}

Expand Down Expand Up @@ -354,12 +355,12 @@ BoundUnaryExpression* Binder::BindUnaryExpression(const UnaryExpressionSyntax* U

BoundBinaryExpression* Binder::BindBinaryExpression(const BinaryExpressionSyntax* BinaryExpression) noexcept
{
const auto BoundLeft = BindExpression(BinaryExpression->Left);
const auto BoundRight = BindExpression(BinaryExpression->Right);
auto BoundLeft = BindExpression(BinaryExpression->Left);
auto BoundRight = BindExpression(BinaryExpression->Right);

// TODO: Check operand types

const auto BoundOperator = BoundBinaryOperator::Bind(
auto BoundOperator = BoundBinaryOperator::Bind(
BinaryExpression->OperatorToken->Kind(),
BoundLeft->Type(),
BoundRight->Type()
Expand Down Expand Up @@ -422,7 +423,7 @@ BoundCallExpression* Binder::BindCallExpression(const CallExpressionSyntax* Call
for (auto&& Argument : CallExpression->Arguments.Nodes())
{
// Argument is guaranteed to be a expression by the parser.
const auto BoundArgument = BindExpression(static_cast<const ExpressionSyntax*>(Argument));
auto BoundArgument = BindExpression(static_cast<const ExpressionSyntax*>(Argument));

// TODO: Use hatcher to avoid copy
BoundArguments.emplace_back(BoundArgument);
Expand All @@ -431,7 +432,7 @@ BoundCallExpression* Binder::BindCallExpression(const CallExpressionSyntax* Call
// TODO: Refinement Jvav standard
// [basic.lookup]/? : If the declarations found by name lookup all denote functions,
// the declarations are said to form an overload set.
const auto FunctionSet = Scope->LookupFunction(CallExpression->Identifier->Text());
auto FunctionSet = Scope->LookupFunction(CallExpression->Identifier->Text());
if (FunctionSet.empty())
{
// TODO: Diagnostics - undeclaraed function
Expand All @@ -440,7 +441,7 @@ BoundCallExpression* Binder::BindCallExpression(const CallExpressionSyntax* Call
}

// TODO: Overload resolution. Before overload resolution is avaiable, function override is not permitted.
const auto Function = FunctionSet.front();
auto Function = FunctionSet.front();

if (CallExpression->Arguments.Count() != Function->Parameters.size())
{
Expand All @@ -461,10 +462,10 @@ NullablePointer<const TypeSymbol> Binder::BindTypeClause(NullablePointer<const T
return {};
}

const auto Types = Scope->LookupType(TypeClause->Identifier->Text());
auto Types = Scope->LookupType(TypeClause->Identifier->Text());
if (Types.empty())
{
// TODO: Diagnostics - undeclaraed type
Diagnostics.ReportUndeclaredIdentifier(TypeClause->Identifier->Location(), TypeClause->Identifier->Text());
return {};
}

Expand All @@ -480,7 +481,17 @@ void Binder::DeclareBuiltinFunctions() noexcept
{
}

void Binder::DeclareBuiltinTypes() noexcept
{
Scope->Declare(&TypeSymbol::Int);
Scope->Declare(&TypeSymbol::Bool);
Scope->Declare(&TypeSymbol::String);
Scope->Declare(&TypeSymbol::Void);
Scope->Declare(&TypeSymbol::Double);
}

Binder::Binder(const class SyntaxTree* SyntaxTree) noexcept :
Scope(new BoundScope(nullptr)), SyntaxTree(SyntaxTree)
{
DeclareBuiltinTypes();
}
3 changes: 2 additions & 1 deletion src/Mamba/Code Analysis/Binding/Binder.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ namespace Mamba
ScopeGuard EnterScope() noexcept;

void DeclareBuiltinFunctions() noexcept;
void DeclareBuiltinFunction();
void DeclareBuiltinFunction() noexcept;
void DeclareBuiltinTypes() noexcept;

public:
DiagnosticBag Diagnostics;
Expand Down
12 changes: 6 additions & 6 deletions src/Mamba/Code Analysis/Binding/BoundBinaryOperator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@

using namespace Mamba;

BoundBinaryOperator::BoundBinaryOperator(SyntaxKind Kind, BoundBinaryOperatorKind BoundKind, const TypeSymbol* Type) noexcept :
BoundBinaryOperator(Kind, BoundKind, Type, Type, Type)
BoundBinaryOperator::BoundBinaryOperator(SyntaxKind Kind, BoundBinaryOperatorKind OperatorKind, const TypeSymbol* Type) noexcept :
BoundBinaryOperator(Kind, OperatorKind, Type, Type, Type)
{
}

BoundBinaryOperator::BoundBinaryOperator(SyntaxKind Kind, BoundBinaryOperatorKind BoundKind, const TypeSymbol* OperandType, const TypeSymbol* ResultType) noexcept :
BoundBinaryOperator(Kind, BoundKind, OperandType, OperandType, ResultType)
BoundBinaryOperator::BoundBinaryOperator(SyntaxKind Kind, BoundBinaryOperatorKind OperatorKind, const TypeSymbol* OperandType, const TypeSymbol* ResultType) noexcept :
BoundBinaryOperator(Kind, OperatorKind, OperandType, OperandType, ResultType)
{
}

BoundBinaryOperator::BoundBinaryOperator(SyntaxKind Kind, BoundBinaryOperatorKind BoundKind, const TypeSymbol* LeftType, const TypeSymbol* RightType, const TypeSymbol* ResultType) noexcept :
Kind(Kind), BoundKind(BoundKind), LeftType(LeftType), RightType(RightType), Type(ResultType)
BoundBinaryOperator::BoundBinaryOperator(SyntaxKind Kind, BoundBinaryOperatorKind OperatorKind, const TypeSymbol* LeftType, const TypeSymbol* RightType, const TypeSymbol* ResultType) noexcept :
Kind(Kind), OperatorKind(OperatorKind), LeftType(LeftType), RightType(RightType), Type(ResultType)
{
}

Expand Down
10 changes: 5 additions & 5 deletions src/Mamba/Code Analysis/Binding/BoundBinaryOperator.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ namespace Mamba
{
class BoundBinaryOperator
{
[[nodiscard]] BoundBinaryOperator(SyntaxKind SyntaxKind, BoundBinaryOperatorKind Kind, const TypeSymbol* Type) noexcept;
[[nodiscard]] BoundBinaryOperator(SyntaxKind SyntaxKind, BoundBinaryOperatorKind Kind, const TypeSymbol* OperandType, const TypeSymbol* ResultType) noexcept;
[[nodiscard]] BoundBinaryOperator(SyntaxKind SyntaxKind, BoundBinaryOperatorKind Kind, const TypeSymbol* LeftType, const TypeSymbol* RightType, const TypeSymbol* ResultType) noexcept;
[[nodiscard]] BoundBinaryOperator(SyntaxKind Kind, BoundBinaryOperatorKind OperatorKind, const TypeSymbol* Type) noexcept;
[[nodiscard]] BoundBinaryOperator(SyntaxKind Kind, BoundBinaryOperatorKind OperatorKind, const TypeSymbol* OperandType, const TypeSymbol* ResultType) noexcept;
[[nodiscard]] BoundBinaryOperator(SyntaxKind Kind, BoundBinaryOperatorKind OperatorKind, const TypeSymbol* LeftType, const TypeSymbol* RightType, const TypeSymbol* ResultType) noexcept;

BoundBinaryOperator(const BoundBinaryOperator&) = delete;
BoundBinaryOperator(BoundBinaryOperator&&) = delete;
Expand All @@ -21,8 +21,8 @@ namespace Mamba
BoundBinaryOperator& operator=(BoundBinaryOperator&&) = delete;

public:
enum SyntaxKind Kind;
BoundBinaryOperatorKind BoundKind;
SyntaxKind Kind;
BoundBinaryOperatorKind OperatorKind;
const TypeSymbol* LeftType;
const TypeSymbol* RightType;
const TypeSymbol* Type;
Expand Down
17 changes: 16 additions & 1 deletion src/Mamba/Code Analysis/Binding/BoundLiteralExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
#include "MambaCore.h"
#include "TypeSymbol.h"

#include <cstdint>
#include <fast_io.h>
#include <limits>
#include <source_location>
#include <utility>

Expand Down Expand Up @@ -55,5 +57,18 @@ const TypeSymbol* BoundLiteralExpression::Type() const noexcept

Constant BoundLiteralExpression::ConstantValue() const noexcept
{
return std::visit([](auto Value) -> Constant { return Value; }, Value.Value);
return std::visit(
[]<typename T>(T&& Value) -> Constant {
if constexpr (std::is_same_v<std::decay_t<T>, LiteralType::Number>)
{
if (Value <= static_cast<std::uint64_t>(std::numeric_limits<std::int32_t>::max()))
{
return static_cast<std::int32_t>(Value);
}
}

return Value;
},
Value.Value
);
}
15 changes: 13 additions & 2 deletions src/Mamba/Code Analysis/Binding/BoundScope.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "BoundScope.h"
#include "TypeSymbol.h"

using namespace Mamba;

Expand All @@ -7,6 +8,16 @@ BoundScope::BoundScope(NullablePointer<const BoundScope> Parent) noexcept :

BoundScope::~BoundScope() noexcept
{
for (auto Symbol : DeclaredSymbols())
{
if (TypeSymbol::IsBuiltInType(static_cast<const TypeSymbol*>(Symbol)))
{
continue;
}

delete Symbol;
}

for (auto Child : Children)
{
delete Child;
Expand All @@ -20,7 +31,7 @@ void BoundScope::Declare(const Symbol* Symbol) noexcept

BoundScope* BoundScope::DeclareScope() noexcept
{
const auto ChildScope = new BoundScope(this);
auto ChildScope = new BoundScope(this);
Children.emplace_back(ChildScope);
return ChildScope;
}
Expand Down Expand Up @@ -59,7 +70,7 @@ std::vector<const ParameterSymbol*> BoundScope::LookupParameter(StringView Name)

std::vector<const Symbol*> BoundScope::Lookup(StringView Name) const noexcept
{
const auto Result = Symbols.find(Name);
auto Result = Symbols.find(Name);
if (Result != Symbols.end()) [[unlikely]]
{
return Result->second;
Expand Down
10 changes: 5 additions & 5 deletions src/Mamba/Code Analysis/Binding/ConstantFolding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ Constant ConstantFolding::Fold(
const BoundExpression* Right
) noexcept
{
const auto LeftConstant = Left->ConstantValue();
const auto RightConstant = Right->ConstantValue();
auto LeftConstant = Left->ConstantValue();
auto RightConstant = Right->ConstantValue();

// Special case && and || because there are cases where only one
// side needs to be known.

if (Operator.BoundKind == BoundBinaryOperatorKind::LogicalAnd)
if (Operator.OperatorKind == BoundBinaryOperatorKind::LogicalAnd)
{
if ((LeftConstant.IsValid() && !LeftConstant.Get<bool>()) ||
(RightConstant.IsValid() && !RightConstant.Get<bool>()))
Expand All @@ -48,7 +48,7 @@ Constant ConstantFolding::Fold(
}
}

if (Operator.BoundKind == BoundBinaryOperatorKind::LogicalOr)
if (Operator.OperatorKind == BoundBinaryOperatorKind::LogicalOr)
{
if ((LeftConstant.IsValid() && LeftConstant.Get<bool>()) ||
(RightConstant.IsValid() && RightConstant.Get<bool>()))
Expand All @@ -62,7 +62,7 @@ Constant ConstantFolding::Fold(
return {};
}

switch (Operator.BoundKind)
switch (Operator.OperatorKind)
{
case BoundBinaryOperatorKind::Addition:
return LeftConstant + RightConstant;
Expand Down
8 changes: 4 additions & 4 deletions src/Mamba/Code Analysis/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ void Compiler::PrivateAddSourceFile(const std::string_view FileName) noexcept
{
try
{
const auto FileLoader = fast_io::native_file_loader(FileName);
auto FileLoader = fast_io::native_file_loader(FileName);

const auto Info = SourceTextInfo{
auto Info = SourceTextInfo{
.FileName = Concat(fast_io::mnp::code_cvt(FileName)),
.Text = String(FileLoader.begin(), FileLoader.end())
};
Expand Down Expand Up @@ -107,10 +107,10 @@ void Compiler::Compile() noexcept
PrintDiagnostics(Binder.Diagnostics);
}

LLVMBackend::GenerateCode(BoundCompilationUnits, "Main");

for (auto&& BoundCompilationUnit : BoundCompilationUnits)
{
delete BoundCompilationUnit;
}

LLVMBackend::GenerateCode(BoundCompilationUnits, "Main");
}
35 changes: 9 additions & 26 deletions src/Mamba/Code Analysis/DiagnosticBag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include "BreakStatementSyntax.h"
#include "CallExpressionSyntax.h"
#include "ContinueStatementSyntax.h"
#include "Diagnostic.h"
#include "DoWhileStatementSyntax.h"
#include "ExpressionStatementSyntax.h"
#include "ForStatementSyntax.h"
Expand All @@ -22,53 +21,37 @@

namespace Mamba
{
void DiagnosticBag::AddRange(const std::vector<Diagnostic>& Diagnostics) noexcept
{
#if __cpp_lib_containers_ranges == 202202L
append_range(Diagnostics);
#else
for (auto&& Diagnostic : Diagnostics)
{
emplace_back(std::forward<decltype(Diagnostic)>(Diagnostic));
}
#endif
}

void DiagnosticBag::ReportInvalidCharacter(const TextLocation Location, const Char Character) noexcept
void DiagnosticBag::ReportInvalidCharacter(TextLocation Location, Char Character) noexcept
{
ReportError(Location, TEXT("无效字符 '"), fast_io::mnp::chvw(Character), TEXT("'."));
}

void DiagnosticBag::ReportUnterminatedString(const TextLocation Location) noexcept
void DiagnosticBag::ReportUnterminatedString(TextLocation Location) noexcept
{
ReportError(Location, TEXT("未结束的字符串字面量"));
}

void DiagnosticBag::ReportInvalidDecimal(const TextLocation Location, const StringView Literal) noexcept
void DiagnosticBag::ReportInvalidDecimal(TextLocation Location, StringView Literal) noexcept
{
ReportError(Location, Concat(TEXT("无效十进制字面量 '"), Literal, TEXT("'.")));
}

void DiagnosticBag::ReportInvalidHexadecimal(const TextLocation Location, const StringView Literal) noexcept
void DiagnosticBag::ReportInvalidHexadecimal(TextLocation Location, StringView Literal) noexcept
{
ReportError(Location, Concat(TEXT("无效十六进制字面量 '"), Literal, TEXT("'.")));
}

void DiagnosticBag::ReportInvalidBinary(const TextLocation Location, const StringView Literal) noexcept
void DiagnosticBag::ReportInvalidBinary(TextLocation Location, StringView Literal) noexcept
{
ReportError(Location, Concat(TEXT("无效二进制字面量 '"), Literal, TEXT("'.")));
}

void DiagnosticBag::ReportInvalidOctal(const TextLocation Location, const StringView Literal) noexcept
void DiagnosticBag::ReportInvalidOctal(TextLocation Location, StringView Literal) noexcept
{
ReportError(Location, Concat(TEXT("无效八进制字面量 '"), Literal, TEXT("'.")));
}

void DiagnosticBag::ReportUnexpectedToken(
const TextLocation Location,
const SyntaxKind Kind,
const SyntaxKind ExpectedKind
) noexcept
void DiagnosticBag::ReportUnexpectedToken(TextLocation Location, SyntaxKind Kind, SyntaxKind ExpectedKind) noexcept
{
// Unexpected token 'Kind', Expected: 'ExpectedKind'.
if (ExpectedKind == SyntaxKind::IdentifierToken)
Expand All @@ -89,12 +72,12 @@ namespace Mamba
}
}

void DiagnosticBag::ReportDiscardExpressionValue(const TextLocation Location) noexcept
void DiagnosticBag::ReportDiscardExpressionValue(TextLocation Location) noexcept
{
ReportWarning(Location, TEXT("表达式的结果被忽略"));
}

void DiagnosticBag::ReportVariableAlreadyDeclared(const TextLocation Location, StringView Name) noexcept
void DiagnosticBag::ReportVariableAlreadyDeclared(TextLocation Location, StringView Name) noexcept
{
// Variable 'Name' is already declared, previous declaration at FileName:StartLine:StartCharacter.
ReportError(
Expand Down
Loading

0 comments on commit 71af38b

Please sign in to comment.