diff --git a/CMakeLists.txt b/CMakeLists.txt index 46880c8..dda03d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/Mamba/src/Code Analysis/Binding/Binder.cpp b/Mamba/src/Code Analysis/Binding/Binder.cpp index 1e455c3..5802f7a 100644 --- a/Mamba/src/Code Analysis/Binding/Binder.cpp +++ b/Mamba/src/Code Analysis/Binding/Binder.cpp @@ -1,18 +1,26 @@ +#include + +#include + #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 - using namespace Mamba; BoundCompilationUnit* Binder::BindCompilationUnit() noexcept @@ -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. @@ -134,12 +143,7 @@ BoundStatement* Binder::BindStatementInternal(const StatementSyntax* Statement) case SyntaxKind::ExpressionStatement: return BindExpressionStatement(static_cast(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()))); } } @@ -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()) @@ -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 @@ -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); @@ -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); @@ -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); @@ -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) @@ -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 @@ -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(Argument)); - - // TODO: Use hatcher to avoid copy BoundArguments.emplace_back(BoundArgument); } @@ -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); } diff --git a/Mamba/src/Code Analysis/Binding/Binder.h b/Mamba/src/Code Analysis/Binding/Binder.h index 836d299..8cbf6ba 100644 --- a/Mamba/src/Code Analysis/Binding/Binder.h +++ b/Mamba/src/Code Analysis/Binding/Binder.h @@ -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" @@ -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" @@ -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; diff --git a/Mamba/src/Code Analysis/DiagnosticBag.cpp b/Mamba/src/Code Analysis/DiagnosticBag.cpp index 82dcc66..e4b6c98 100644 --- a/Mamba/src/Code Analysis/DiagnosticBag.cpp +++ b/Mamba/src/Code Analysis/DiagnosticBag.cpp @@ -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 diff --git a/Mamba/src/Code Analysis/DiagnosticBag.h b/Mamba/src/Code Analysis/DiagnosticBag.h index 5c285e3..6b27e87 100644 --- a/Mamba/src/Code Analysis/DiagnosticBag.h +++ b/Mamba/src/Code Analysis/DiagnosticBag.h @@ -5,6 +5,7 @@ #include "Diagnostic.h" #include "SyntaxKind.h" #include "SyntaxNode.h" +#include "SyntaxToken.h" #include "TextLocation.h" #include "TypeSymbol.h" @@ -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 \ No newline at end of file diff --git a/Mamba/src/Code Analysis/Syntax/Constant.h b/Mamba/src/Code Analysis/Syntax/Constant.h index 2f46695..b92433e 100644 --- a/Mamba/src/Code Analysis/Syntax/Constant.h +++ b/Mamba/src/Code Analysis/Syntax/Constant.h @@ -102,10 +102,14 @@ namespace Mamba [](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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { diff --git a/Mamba/src/Code Analysis/Syntax/Lexer.cpp b/Mamba/src/Code Analysis/Syntax/Lexer.cpp index 4ea5770..facacc2 100644 --- a/Mamba/src/Code Analysis/Syntax/Lexer.cpp +++ b/Mamba/src/Code Analysis/Syntax/Lexer.cpp @@ -1,7 +1,6 @@ #include "Lexer.h" #include "DiagnosticBag.h" -#include "fast_io.h" #include "Literal.h" #include "SourceText.h" #include "SyntaxFacts.h" @@ -237,6 +236,14 @@ namespace Mamba ++Position; } break; + case TEXT('.'): + ++Position; + Kind = SyntaxKind::DotToken; + break; + case TEXT(';'): + Kind = SyntaxKind::SemicolonToken; + ++Position; + break; case TEXT('"'): ReadString(); break; diff --git a/Mamba/src/Code Analysis/Syntax/Parser.cpp b/Mamba/src/Code Analysis/Syntax/Parser.cpp index dff0ac3..46c39d9 100644 --- a/Mamba/src/Code Analysis/Syntax/Parser.cpp +++ b/Mamba/src/Code Analysis/Syntax/Parser.cpp @@ -1,7 +1,11 @@ #include "Parser.h" +#include "AssignmentExpressionSyntax.h" +#include "BinaryExpressionSyntax.h" +#include "GlobalStatementSyntax.h" #include "MambaCore.h" #include "SyntaxFacts.h" +#include "SyntaxKind.h" #include "SyntaxTree.h" #include "UnaryExpressionSyntax.h" @@ -10,13 +14,9 @@ using namespace Mamba; Parser::Parser(const class SyntaxTree* SyntaxTree, std::vector&& Tokens) noexcept : SyntaxTree(SyntaxTree), Tokens(std::move(Tokens)), Position(0) { - if (this->Tokens.empty()) + if (this->Tokens.empty() || this->Tokens.back().Kind() != SyntaxKind::EndOfFileToken) { - InternalCompilerError(std::source_location::current(), "No tokens provided to parser."); - } - else if (this->Tokens.back().Kind() != SyntaxKind::EndOfFileToken) - { - InternalCompilerError(std::source_location::current(), "Tokens do not end with EndOfFileToken."); + InternalCompilerError(std::source_location::current(), "不正常的结尾标记"); } } @@ -91,6 +91,11 @@ MemberSyntax* Parser::ParseMember() noexcept { Result = ParseFunctionDeclaration(); } + else if (Current()->Kind() == SyntaxKind::SemicolonToken) + { + // Discard semi-colon + NextToken(); + } else { Result = ParseGlobalStatement(); diff --git a/Mamba/src/Code Analysis/Syntax/Parser.h b/Mamba/src/Code Analysis/Syntax/Parser.h index 46fb8ae..d2ddeae 100644 --- a/Mamba/src/Code Analysis/Syntax/Parser.h +++ b/Mamba/src/Code Analysis/Syntax/Parser.h @@ -2,8 +2,6 @@ #include -#include "AssignmentExpressionSyntax.h" -#include "BinaryExpressionSyntax.h" #include "BreakStatementSyntax.h" #include "CallExpressionSyntax.h" #include "CompilationUnitSyntax.h" @@ -14,7 +12,6 @@ #include "ExpressionStatementSyntax.h" #include "ForStatementSyntax.h" #include "FunctionDeclarationSyntax.h" -#include "GlobalStatementSyntax.h" #include "IfStatementSyntax.h" #include "LiteralExpressionSyntax.h" #include "NameExpressionSyntax.h" diff --git a/Mamba/src/Code Analysis/Syntax/SeperatedSyntaxList.h b/Mamba/src/Code Analysis/Syntax/SeperatedSyntaxList.h index 2688e95..f28756d 100644 --- a/Mamba/src/Code Analysis/Syntax/SeperatedSyntaxList.h +++ b/Mamba/src/Code Analysis/Syntax/SeperatedSyntaxList.h @@ -11,8 +11,8 @@ namespace Mamba { template typename Container = std::vector> requires requires { - std::is_pointer_v; - std::derived_from::element_type, SyntaxNode>; + requires std::is_pointer_v; + requires std::derived_from::element_type, SyntaxNode>; } class SeperatedSyntaxList : public Container { @@ -65,7 +65,6 @@ namespace Mamba // TODO: use ranges instead [[nodiscard]] constexpr T GetSeparator(const std::size_t Index) const noexcept - { return (*this)[Index * 2 + 1]; } diff --git a/Mamba/src/Code Analysis/Syntax/SyntaxFacts.cpp b/Mamba/src/Code Analysis/Syntax/SyntaxFacts.cpp index 9b4739e..145a909 100644 --- a/Mamba/src/Code Analysis/Syntax/SyntaxFacts.cpp +++ b/Mamba/src/Code Analysis/Syntax/SyntaxFacts.cpp @@ -1,6 +1,7 @@ #include "SyntaxFacts.h" #include "fast_io.h" #include "MambaCore.h" +#include "SyntaxKind.h" #include #include @@ -77,6 +78,10 @@ namespace Mamba std::make_pair(TEXT("continue"), SyntaxKind::ContinueKeyword), std::make_pair(TEXT("return"), SyntaxKind::ReturnKeyword), + + std::make_pair(TEXT("mut"), SyntaxKind::MutKeyword), + std::make_pair(TEXT("pure"), SyntaxKind::PureKeyword), + std::make_pair(TEXT("const"), SyntaxKind::ConstKeyword) }; auto Iterator = KeywordsMap.find(Text); diff --git a/Mamba/src/Code Analysis/Syntax/SyntaxKind.h b/Mamba/src/Code Analysis/Syntax/SyntaxKind.h index 2b4880d..30464c6 100644 --- a/Mamba/src/Code Analysis/Syntax/SyntaxKind.h +++ b/Mamba/src/Code Analysis/Syntax/SyntaxKind.h @@ -43,6 +43,8 @@ namespace Mamba CommaToken, IdentifierToken, WhitespaceToken, + DotToken, + SemicolonToken, // Keywords BreakKeyword, @@ -60,6 +62,11 @@ namespace Mamba WhileKeyword, DoKeyword, + // Function access modifiers + PureKeyword, + ConstKeyword, + MutKeyword, + // Nodes CompilationUnit, FunctionDeclaration, diff --git a/Mamba/src/Code Analysis/Text/SourceText.cpp b/Mamba/src/Code Analysis/Text/SourceText.cpp index aa4453d..08ac72a 100644 --- a/Mamba/src/Code Analysis/Text/SourceText.cpp +++ b/Mamba/src/Code Analysis/Text/SourceText.cpp @@ -1,6 +1,5 @@ #include "SourceText.h" -#include "fast_io_core_impl/integers/impl.h" #include "TextLine.h" #include @@ -17,7 +16,7 @@ using namespace Mamba; return 2; } - if (Character == TEXT('\r') || LineBreakCharacter == TEXT('\n')) + if (Character == TEXT('\r') || Character == TEXT('\n')) { return 1; } @@ -112,9 +111,10 @@ std::vector SourceText::SplitLines(const SourceTextInfo& Info) while (Position < Text.length()) { - auto LineBreakWidth = GetLineBreakWidth(Text, Position++); + auto LineBreakWidth = GetLineBreakWidth(Text, Position); if (LineBreakWidth == 0) { + ++Position; continue; } diff --git a/Mamba/src/Code Generation/LLVM/LLVMBackend.cpp b/Mamba/src/Code Generation/LLVM/LLVMBackend.cpp index dedff4e..6558620 100644 --- a/Mamba/src/Code Generation/LLVM/LLVMBackend.cpp +++ b/Mamba/src/Code Generation/LLVM/LLVMBackend.cpp @@ -1,33 +1,39 @@ -#include "LLVMBackend.h" - #include #include #include #include -#include "BoundExpressionStatement.h" -#include "BoundIfStatement.h" -#include "BoundWhileStatement.h" -#include "fast_io.h" - -#include "LLVM/GenerationContext.h" -#include "llvm/IR/BasicBlock.h" -#include "llvm/IR/DerivedTypes.h" -#include "llvm/IR/Function.h" -#include "llvm/IR/Instructions.h" -#include "llvm/IR/IRBuilder.h" -#include "llvm/IR/LegacyPassManager.h" -#include "llvm/IR/LLVMContext.h" -#include "llvm/IR/Module.h" -#include "llvm/IR/Type.h" -#include "llvm/IR/Verifier.h" -#include "llvm/MC/TargetRegistry.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/TargetSelect.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" -#include "llvm/TargetParser/Host.h" +#include + +#ifdef __clang__ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Weverything" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __clang__ + #pragma clang diagnostic pop +#endif + +#include "LLVMBackend.h" #include "MambaCore.h" @@ -35,12 +41,15 @@ #include "BoundBinaryOperatorKind.h" #include "BoundBlockStatement.h" #include "BoundExpression.h" +#include "BoundExpressionStatement.h" #include "BoundFunctionDeclaration.h" +#include "BoundIfStatement.h" #include "BoundLiteralExpression.h" #include "BoundNodeKind.h" #include "BoundReturnStatement.h" #include "BoundStatement.h" #include "BoundVariableDeclaration.h" +#include "BoundWhileStatement.h" #include "Constant.h" #include "FunctionSymbol.h" #include "TypeSymbol.h" @@ -162,26 +171,29 @@ Value* GenerateBinaryExpression(GenerationContext& Context, const BoundBinaryExp Value* GenerateLiteralExpression(GenerationContext& Context, const BoundLiteralExpression& Expression) noexcept { - return Expression.ConstantValue().GetValue().visit([&](T&& Value) -> ConstantData* { - if constexpr (std::is_same_v, ConstantType::Int>) - { - return ConstantInt::get(Type::getInt32Ty(Context.Context), Value); - } - else if constexpr (std::is_same_v, ConstantType::ULong>) - { - return ConstantInt::get(Type::getInt64Ty(Context.Context), Value); - } - else if constexpr (std::is_same_v, ConstantType::Boolean>) - { - return ConstantInt::get(Type::getInt1Ty(Context.Context), Value); - } - else if constexpr (std::is_same_v, ConstantType::Double>) - { - return ConstantFP::get(Context.Context, APFloat(Value)); - } - - return nullptr; - }); + return std::visit( + [&](T&& Value) -> ConstantData* { + if constexpr (std::is_same_v, ConstantType::Int>) + { + return ConstantInt::get(Type::getInt32Ty(Context.Context), Value); + } + else if constexpr (std::is_same_v, ConstantType::ULong>) + { + return ConstantInt::get(Type::getInt64Ty(Context.Context), Value); + } + else if constexpr (std::is_same_v, ConstantType::Boolean>) + { + return ConstantInt::get(Type::getInt1Ty(Context.Context), Value); + } + else if constexpr (std::is_same_v, ConstantType::Double>) + { + return ConstantFP::get(Context.Context, APFloat(Value)); + } + + return nullptr; + }, + Expression.ConstantValue().GetValue() + ); } Value* GenerateExpression(GenerationContext& Context, const BoundExpression& Statement) noexcept @@ -259,8 +271,9 @@ void GenerateIfStatement(GenerationContext& Context, const BoundIfStatement& Sta Context.Builder.SetInsertPoint(MergeBlock); } -void GenerateWhileStatement(GenerationContext& Context, const BoundWhileStatement& Statement) noexcept +void GenerateWhileStatement(GenerationContext& Context [[maybe_unused]], const BoundWhileStatement& Statement [[maybe_unused]]) noexcept { + // TODO } void GenerateStatement(GenerationContext& Context, const BoundStatement& Statement) noexcept diff --git a/Mamba/src/Core/DiagnosticPrinter.h b/Mamba/src/Core/Printer/DiagnosticPrinter.h similarity index 99% rename from Mamba/src/Core/DiagnosticPrinter.h rename to Mamba/src/Core/Printer/DiagnosticPrinter.h index 1c10c65..9774807 100644 --- a/Mamba/src/Core/DiagnosticPrinter.h +++ b/Mamba/src/Core/Printer/DiagnosticPrinter.h @@ -2,7 +2,6 @@ #include #include -#include #include "Colors.h" #include "Diagnostic.h" diff --git a/Mamba/src/Mamba.cpp b/Mamba/src/Mamba.cpp index ce9945c..b7d197f 100644 --- a/Mamba/src/Mamba.cpp +++ b/Mamba/src/Mamba.cpp @@ -2,15 +2,12 @@ #include "Compiler.h" #include "MambaSignalHandler.h" -#include "llvm/Support/InitLLVM.h" - using namespace std::string_literals; using namespace Mamba; std::int32_t Mamba::InitMamba(int ArgumentCount, [[maybe_unused]] char* Arguments[]) noexcept { InitSignalHandler(); - llvm::InitLLVM(ArgumentCount, Arguments); auto Begin = Arguments + 1; auto End = Arguments + ArgumentCount; diff --git a/docs/draft/Jvav 25.pdf b/docs/draft/Jvav 25.pdf new file mode 100644 index 0000000..c1a448f Binary files /dev/null and b/docs/draft/Jvav 25.pdf differ diff --git a/docs/draft/Jvav 25.typ b/docs/draft/Jvav 25.typ new file mode 100644 index 0000000..59b8489 --- /dev/null +++ b/docs/draft/Jvav 25.typ @@ -0,0 +1,121 @@ +#set text(font: "SimSun", lang: "zh") +#set text(font: "PT Sans") + +#set heading(numbering: "1.") +#set page(footer: context [ + #h(1fr) + #counter(page).display( + "1" + ) +]) + +#let keyword-color = eastern +#let since-color = green +#let user-color = blue +#let bracket-color = orange + +#align(center, text(24pt)[ + 编程语言Jvav标准工作草案 +]) + +#table( + columns: 2, + stroke: none +)[#text(12pt)[日期:]][#text(12pt)[2024-8-20] +][#text(12pt)[回复:]][#text(12pt)[heckerpowered (#text(12pt, user-color)[heckerpowered\@icloud.com])]] + +#align(bottom)[ + 这是一份草案,有很多不完整和错误的地方 +] + +#pagebreak() + +#show outline.entry.where( + level: 1 +): it => { + v(12pt, weak: true) + strong(it) +} +#outline( + indent: auto +) + +#pagebreak() + += 基础 +== 序言 + +_#text(user-color)[实体]_ 是 _#text(user-color)[值]_, _#text(user-color)[对象]_, _#text(user-color)[函数]_, _#text(user-color)[类成员]_。 + +名字是#text(user-color)[标识符]。 + +名字由声明引入,可能是: +- #text(user-color)[函数声明] +- #text(user-color)[参数声明] +- #text(user-color)[变量声明] + +== 编译单元 + +编译单元是最小可被编译的代码单元。 + +在编译单元中,最外层的作用域被称为#text(user-color)[全局作用域]。 + +#pagebreak() + += 作用域 +== 序言 + +最外围的作用域被称为#text(user-color)[全局作用域],由其他方式引入的作用域称为#text(user-color)[全局作用域]。 + +使用大括号将语句包裹起来,可创建一个局部作用域。 + += 表达式 +== 序言 + +#text(user-color)[表达式]是#text(user-color)[运算符]与#text(user-color)[操作数]的序列,它指定一项计算。 + +#text(user-color)[表达式]的求值可以产生一个结果,比如 2 + 2 的求值产生结果 4,也可能产生副作用。 + +表达式具有两种性质:#text(user-color)[类型]和#text(user-color)[值类别]。 + +表达式的类型是其结果的类型。 + +== 值类别 + +表达式有3种值类别,是:左值、亡值、纯右值。 + +=== 左值 + +左值是求值可确定某个对象的标识的表达式。 + +下列表达式是左值表达式: +- 由任何变量的名字构成的表达式,不论类型。 +- 返回类型是引用的函数调用表达式 +- 到引用类型的转换 +- 所有内建的赋值表达式 +- 前置自增或自减表达式 +- 内建的下标表达式a[n],当a是左值时。 +- 成员表达式a.m,其中a是左值,m是非静态成员变量的名字。 +- 三元条件表达式 a ? b : c,其中b和c是同类型的左值表达式 +- 字符串字面量 + +==== 性质 + +- 可以取地址 +- 可以用于初始化引用 + +=== 亡值 + +亡值是代表它的资源能够被重新使用的对象或位域的泛左值 + +#pagebreak() + += 声明 +== 序言 +== 说明符 + +=== 访问加宽说明符 + +访问加宽说明符是widen,只能在类型内部出现,例如成员函数的访问限制说明符中。 + +访问加宽说明符修饰成员函数时,允许通过不可变的对象调用此成员函数,但当通过可变对象调用此成员函数时,此说明符也允许成员函数修改此对象。 \ No newline at end of file diff --git a/xmake.lua b/xmake.lua index 13c9b83..a76d38e 100644 --- a/xmake.lua +++ b/xmake.lua @@ -4,6 +4,8 @@ add_rules("plugin.compile_commands.autoupdate") local includedirs = { "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",