diff --git a/.clang-format b/.clang-format index deb0b18..f9f2c5e 100644 --- a/.clang-format +++ b/.clang-format @@ -33,8 +33,8 @@ ContinuationIndentWidth: 2 AlignAfterOpenBracket: AlwaysBreak AlignConsecutiveDeclarations: Enabled: true - AcrossEmptyLines: true - AcrossComments: true + AcrossEmptyLines: false + AcrossComments: false AlignCompound: true PadOperators: true AlignConsecutiveMacros: diff --git a/compiler/ast/ast.cpp b/compiler/ast/ast.cpp index 41559cf..610689c 100644 --- a/compiler/ast/ast.cpp +++ b/compiler/ast/ast.cpp @@ -80,8 +80,8 @@ namespace swallow::compiler::type Manager typeManager; Environment typeEnvironment; - auto intType = Type::Ptr(new Base("Int")); - auto binopType = + auto intType = Type::Ptr(new Base("Int")); + auto binopType = Type::Ptr(new Arrow(intType, Type::Ptr(new type::Arrow(intType, intType)))); typeEnvironment.Bind("+", binopType); diff --git a/compiler/ast/ast.hpp b/compiler/ast/ast.hpp index 1cb01a0..d63d1fd 100644 --- a/compiler/ast/ast.hpp +++ b/compiler/ast/ast.hpp @@ -44,29 +44,37 @@ namespace swallow::compiler::ast { + + /** The base class of expressions */ class AST { + public: + using Ptr = std::unique_ptr; + + /** The location of the current expression in the source file. + * (generated by Bison, passed in parser.y) */ const yy::location Location; - type::Type::Ptr NodeType; - using Ptr = std::unique_ptr; + type::Type::Ptr NodeType; explicit AST(const yy::location Location) : Location(Location) {} virtual ~AST() = default; + /** This function calls TypeCheck, + * stores the result in NodeType and returns NodeType */ auto CommonTypeCheck( - type::Manager &typeManager, const type::Environment &typeEnvironment) noexcept - -> type::Type::Ptr; + type::Manager &typeManager, + const type::Environment &typeEnvironment) noexcept -> type::Type::Ptr; - void CommonResolve(const type::Manager &typeManager) noexcept; + void CommonResolve(const type::Manager &typeManager) noexcept; virtual void Resolve(const type::Manager &typeManager) noexcept = 0; - virtual auto TypeCheck( - type::Manager &typeManager, const type::Environment &typeEnvironment) const noexcept - -> utils::Result = 0; + virtual auto + TypeCheck(type::Manager &typeManager, const type::Environment &typeEnvironment) + const noexcept -> utils::Result = 0; virtual void Dump(uint8_t indent, std::ostream &to) const noexcept = 0; @@ -322,8 +330,8 @@ namespace swallow::compiler::ast const AST::Ptr Body; std::vector Instructions; - std::vector ParamTypes; - type::Type::Ptr ReturnType; + std::vector ParamTypes; + type::Type::Ptr ReturnType; Fn( const yy::location Location, diff --git a/compiler/ast/g-machine.cpp b/compiler/ast/g-machine.cpp index d4e7471..d59a901 100644 --- a/compiler/ast/g-machine.cpp +++ b/compiler/ast/g-machine.cpp @@ -57,7 +57,7 @@ namespace swallow::compiler::ast into.push_back(Instruction::Ptr( machineEnvironment->HasVariable(ID) ? dynamic_cast( - new instruction::Push(machineEnvironment->GetOffset(ID).value())) + new instruction::Push(machineEnvironment->GetOffset(ID).value())) : dynamic_cast(new instruction::PushGlobal(ID)))); } @@ -129,7 +129,7 @@ namespace swallow::compiler::ast constructorPattern->Params.rend(), [&](const auto ¶m) { newEnvironment = Environment::Ptr(new Variable(param, newEnvironment)); - }); + }); branchInstructions.push_back(Instruction::Ptr(new instruction::Split())); branch->Expr->Compile(newEnvironment, branchInstructions); diff --git a/compiler/ast/type.cpp b/compiler/ast/type.cpp index 751ce85..88bdc49 100644 --- a/compiler/ast/type.cpp +++ b/compiler/ast/type.cpp @@ -43,16 +43,14 @@ using namespace swallow::compiler::utils; namespace swallow::compiler::ast { - auto Int::TypeCheck( - type::Manager &typeManager, const type::Environment &typeEnvironment) const noexcept - -> Result + auto Int::TypeCheck(type::Manager &typeManager, const type::Environment &typeEnvironment) + const noexcept -> Result { return Ok(type::Type::Ptr(new type::Base("Int"))); } - auto LID::TypeCheck( - type::Manager &typeManager, const type::Environment &typeEnvironment) const noexcept - -> Result + auto LID::TypeCheck(type::Manager &typeManager, const type::Environment &typeEnvironment) + const noexcept -> Result { return typeEnvironment.Lookup(ID).or_else([&](const auto &err) { return diagnostics::Reporter::REPORTER->normal( @@ -64,9 +62,8 @@ namespace swallow::compiler::ast }); } - auto UID::TypeCheck( - type::Manager &typeManager, const type::Environment &typeEnvironment) const noexcept - -> Result + auto UID::TypeCheck(type::Manager &typeManager, const type::Environment &typeEnvironment) + const noexcept -> Result { return typeEnvironment.Lookup(ID).or_else([&](const auto &err) { return diagnostics::Reporter::REPORTER->normal( @@ -78,27 +75,25 @@ namespace swallow::compiler::ast }); } - auto Binop::TypeCheck( - type::Manager &typeManager, const type::Environment &typeEnvironment) const noexcept - -> Result + auto + Binop::TypeCheck(type::Manager &typeManager, const type::Environment &typeEnvironment) + const noexcept -> Result { const std::string operatorName = OperatorToString(Operator); - type::Type::Ptr leftType = Left->CommonTypeCheck(typeManager, typeEnvironment); - type::Type::Ptr rightType = Right->CommonTypeCheck(typeManager, typeEnvironment); + type::Type::Ptr leftType = Left->CommonTypeCheck(typeManager, typeEnvironment); + type::Type::Ptr rightType = Right->CommonTypeCheck(typeManager, typeEnvironment); - type::Type::Ptr functionType = - typeEnvironment.Lookup(operatorName) - .or_else([&](const auto &err) { - return diagnostics::Reporter::REPORTER->normal( - Location, - std::format("'{}' was not declared", operatorName), - "The definition of this operator cannot be found in the " - "context", - "Operator is undefined", - diagnostics::BINOP_NOT_DECLARED); - }) - .unwrap(); + type::Type::Ptr functionType = typeEnvironment.Lookup(operatorName) + .or_else([&](const auto &err) { + return diagnostics::Reporter::REPORTER->normal( + Location, + std::format("'{}' was not declared", operatorName), + "The definition of this operator cannot be found in the " + "context", + "Operator is undefined", + diagnostics::BINOP_NOT_DECLARED); + }).unwrap(); type::Type::Ptr returnType = typeManager.NewType(); type::Type::Ptr arrowOne = type::Type::Ptr(new type::Arrow(rightType, returnType)); @@ -106,25 +101,24 @@ namespace swallow::compiler::ast typeManager.Unify(arrowTwo, functionType) .or_else([&](const auto &err) { - std::stringstream expected; - std::stringstream actual; + std::stringstream expected; + std::stringstream actual; - functionType->Dump(typeManager, expected); - arrowOne->Dump(typeManager, actual); + functionType->Dump(typeManager, expected); + arrowOne->Dump(typeManager, actual); - return diagnostics::Reporter::REPORTER->normal( - Location, - std::format("Type checking failed for '{}'", operatorName), - std::format( - "The operator '{}' has type '{}', but here may need a " - "'{}'", - operatorName, - expected.str(), - actual.str()), - std::format("'{}' conflicts with '{}'", expected.str(), actual.str()), - diagnostics::BINOP_TYPE_MISMATCH); - }) - .ignore(); + return diagnostics::Reporter::REPORTER->normal( + Location, + std::format("Type checking failed for '{}'", operatorName), + std::format( + "The operator '{}' has type '{}', but here may need a " + "'{}'", + operatorName, + expected.str(), + actual.str()), + std::format("'{}' conflicts with '{}'", expected.str(), actual.str()), + diagnostics::BINOP_TYPE_MISMATCH); + }).ignore(); return Ok(returnType); } @@ -141,30 +135,29 @@ namespace swallow::compiler::ast typeManager.Unify(arrowType, leftType) .or_else([&](const auto &err) { - std::stringstream expected; - std::stringstream actual; + std::stringstream expected; + std::stringstream actual; - arrowType->Dump(typeManager, expected); - leftType->Dump(typeManager, actual); + arrowType->Dump(typeManager, expected); + leftType->Dump(typeManager, actual); - return diagnostics::Reporter::REPORTER->normal( - Location, - std::format("Type checking failed for function application"), - std::format( - "This expression has type '{}', but here may need a '{}'", - actual.str(), - expected.str()), - std::format("'{}' conflicts with '{}'", expected.str(), actual.str()), - diagnostics::APPLICATION_TYPE_MISMATCH); - }) - .ignore(); + return diagnostics::Reporter::REPORTER->normal( + Location, + std::format("Type checking failed for function application"), + std::format( + "This expression has type '{}', but here may need a '{}'", + actual.str(), + expected.str()), + std::format("'{}' conflicts with '{}'", expected.str(), actual.str()), + diagnostics::APPLICATION_TYPE_MISMATCH); + }).ignore(); return Ok(returnType); } - auto Match::TypeCheck( - type::Manager &typeManager, const type::Environment &typeEnvironment) const noexcept - -> Result + auto + Match::TypeCheck(type::Manager &typeManager, const type::Environment &typeEnvironment) + const noexcept -> Result { type::Variable *var = nullptr; type::Type::Ptr matchType = @@ -181,23 +174,22 @@ namespace swallow::compiler::ast typeManager.Unify(branchType, currentBranchType) .or_else([&](const auto &err) { - std::stringstream expected; - std::stringstream actual; - - branchType->Dump(typeManager, expected); - currentBranchType->Dump(typeManager, actual); - - return diagnostics::Reporter::REPORTER->normal( - branch->Location, - "Type checking failed for Match expression's branch", - std::format( - "This branch has type '{}', but here may need a '{}'", - actual.str(), - expected.str()), - std::format("'{}' conflicts with '{}'", expected.str(), actual.str()), - diagnostics::MATCH_EXPR_BRANCHE_TYPE_CONFLICTS); - }) - .ignore(); + std::stringstream expected; + std::stringstream actual; + + branchType->Dump(typeManager, expected); + currentBranchType->Dump(typeManager, actual); + + return diagnostics::Reporter::REPORTER->normal( + branch->Location, + "Type checking failed for Match expression's branch", + std::format( + "This branch has type '{}', but here may need a '{}'", + actual.str(), + expected.str()), + std::format("'{}' conflicts with '{}'", expected.str(), actual.str()), + diagnostics::MATCH_EXPR_BRANCHE_TYPE_CONFLICTS); + }).ignore(); } matchType = typeManager.Resolve(matchType, var); @@ -227,18 +219,16 @@ namespace swallow::compiler::ast type::Manager &typeManager, type::Environment &typeEnvironment) const noexcept { - type::Type::Ptr constructorType = - typeEnvironment.Lookup(ConstructorName) - .or_else([&](const auto &err) { - return diagnostics::Reporter::REPORTER->normal( - Location, - std::format("'{}' was not declared", ConstructorName), - "The definition of this constructor cannot be found in the " - "context", - "Constructor is undefined", - diagnostics::CONSTRUCTOR_NOT_DECLARED); - }) - .unwrap(); + type::Type::Ptr constructorType = typeEnvironment.Lookup(ConstructorName) + .or_else([&](const auto &err) { + return diagnostics::Reporter::REPORTER->normal( + Location, + std::format("'{}' was not declared", ConstructorName), + "The definition of this constructor cannot be found in the " + "context", + "Constructor is undefined", + diagnostics::CONSTRUCTOR_NOT_DECLARED); + }).unwrap(); std::for_each(Params.begin(), Params.end(), [&](const std::string ¶m) { auto *arrow = dynamic_cast(constructorType.get()); @@ -259,23 +249,22 @@ namespace swallow::compiler::ast typeManager.Unify(type, constructorType) .or_else([&](const auto &err) { - std::stringstream expected; - std::stringstream actual; + std::stringstream expected; + std::stringstream actual; - type->Dump(typeManager, expected); - constructorType->Dump(typeManager, actual); + type->Dump(typeManager, expected); + constructorType->Dump(typeManager, actual); - return diagnostics::Reporter::REPORTER->normal( - Location, - "Type checking failed for pattern", - std::format( - "This pattern has type '{}', but here may need a '{}'", - actual.str(), - expected.str()), - std::format("'{}' conflicts with '{}'", expected.str(), actual.str()), - diagnostics::PATTERN_MISMATCH); - }) - .ignore(); + return diagnostics::Reporter::REPORTER->normal( + Location, + "Type checking failed for pattern", + std::format( + "This pattern has type '{}', but here may need a '{}'", + actual.str(), + expected.str()), + std::format("'{}' conflicts with '{}'", expected.str(), actual.str()), + diagnostics::PATTERN_MISMATCH); + }).ignore(); } void Fn::PreScanTypes( @@ -298,8 +287,8 @@ namespace swallow::compiler::ast { type::Environment newEnvironment = typeEnvironment.Scope(); - auto paramIterator = Params.begin(); - auto typeIterator = ParamTypes.rbegin(); + auto paramIterator = Params.begin(); + auto typeIterator = ParamTypes.rbegin(); while (paramIterator != Params.end() && typeIterator != ParamTypes.rend()) { newEnvironment.Bind(*paramIterator, *typeIterator); @@ -311,23 +300,22 @@ namespace swallow::compiler::ast typeManager.Unify(ReturnType, bodyType) .or_else([&](const auto &err) { - std::stringstream expected; - std::stringstream actual; + std::stringstream expected; + std::stringstream actual; - ReturnType->Dump(typeManager, expected); - bodyType->Dump(typeManager, actual); + ReturnType->Dump(typeManager, expected); + bodyType->Dump(typeManager, actual); - return diagnostics::Reporter::REPORTER->normal( - Location, - "Type checking failed for function", - std::format( - "This function has type '{}', but the body has type '{}'", - expected.str(), - actual.str()), - std::format("'{}' conflicts with '{}'", expected.str(), actual.str()), - diagnostics::MATCH_EXPR_BRANCHE_TYPE_CONFLICTS); - }) - .ignore(); + return diagnostics::Reporter::REPORTER->normal( + Location, + "Type checking failed for function", + std::format( + "This function has type '{}', but the body has type '{}'", + expected.str(), + actual.str()), + std::format("'{}' conflicts with '{}'", expected.str(), actual.str()), + diagnostics::MATCH_EXPR_BRANCHE_TYPE_CONFLICTS); + }).ignore(); } void Data::PreScanTypes( @@ -349,7 +337,7 @@ namespace swallow::compiler::ast [&](const auto &typeName) { fullType = type::Type::Ptr( new type::Arrow(type::Type::Ptr(new type::Base(typeName)), fullType)); - }); + }); typeEnvironment.Bind(constructor->Name, fullType); } @@ -360,19 +348,18 @@ namespace swallow::compiler::ast {} auto AST::CommonTypeCheck( - type::Manager &typeManager, const type::Environment &typeEnvironment) noexcept - -> type::Type::Ptr + type::Manager &typeManager, + const type::Environment &typeEnvironment) noexcept -> type::Type::Ptr { NodeType = TypeCheck(typeManager, typeEnvironment) .or_else([&](const auto &err) { - return diagnostics::Reporter::REPORTER->normal( - Location, - "Type checking failed", - "Wrong type here", - std::format("No more information"), - diagnostics::EXPR_TYPE_CHECKING_FAILED); - }) - .unwrap(); + return diagnostics::Reporter::REPORTER->normal( + Location, + "Type checking failed", + "Wrong type here", + std::format("No more information"), + diagnostics::EXPR_TYPE_CHECKING_FAILED); + }).unwrap(); ; return NodeType; } diff --git a/compiler/compiler.h b/compiler/compiler.h index a457fb8..5dc2d87 100644 --- a/compiler/compiler.h +++ b/compiler/compiler.h @@ -39,8 +39,8 @@ namespace swallow::compiler class CompileUnit { public: - const std::string FileValue; - const std::string FilePath; + const std::string FileValue; + const std::string FilePath; inline static CompileUnit *FILE = nullptr; diff --git a/compiler/diagnostics/diagnostics.cpp b/compiler/diagnostics/diagnostics.cpp index 0a8aed5..e557d30 100644 --- a/compiler/diagnostics/diagnostics.cpp +++ b/compiler/diagnostics/diagnostics.cpp @@ -329,7 +329,7 @@ namespace swallow::compiler::diagnostics { const auto &line_span = this->details_->get_line_spans()[line_index]; - auto line_number = line_index + 1; + auto line_number = line_index + 1; output << " " << COLOR_RGB( std::setw(spaces_prefix.length() - 3) @@ -368,7 +368,7 @@ namespace swallow::compiler::diagnostics } } - const auto ¤t_labels = level_labels.at(current_level); + const auto ¤t_labels = level_labels.at(current_level); std::map current_label_startings; for (const auto &label : current_labels) @@ -475,7 +475,7 @@ namespace swallow::compiler::diagnostics void LabelGroup::print_colored_source_line( std::ostream &output, const Span &label_span, const Labels &labels) const { - const auto source = this->details_->get_line_source(label_span); + const auto source = this->details_->get_line_source(label_span); std::map mapped_labels; for (const auto &label : labels) @@ -529,7 +529,7 @@ namespace swallow::compiler::diagnostics std::vector level_labels; - auto current_labels = descending_labels; + auto current_labels = descending_labels; while (true) { auto overlapping_labels = find_remove_overlapping_labels(current_labels); @@ -549,7 +549,7 @@ namespace swallow::compiler::diagnostics if (labels.empty()) return {}; - Labels overlapping_labels; + Labels overlapping_labels; const auto *current_label = labels.front(); for (auto iterator = labels.begin() + 1; iterator < labels.end(); iterator++) @@ -572,7 +572,7 @@ namespace swallow::compiler::diagnostics auto LabelGroup::find_labels_in_line(size_t line_index) const -> Labels { - Labels result; + Labels result; const auto &line_span = this->details_->get_line_spans().at(line_index); for (const auto &label : this->labels_) @@ -600,7 +600,7 @@ namespace swallow::compiler::diagnostics std::vector labels_collection; auto *current_labels = &labels_collection.emplace_back(); - auto ascending_labels(labels); + auto ascending_labels(labels); std::sort(ascending_labels.begin(), ascending_labels.end(), AscendingLabels()); auto last_line = labels.front()->get_line(); diff --git a/compiler/diagnostics/diagnostics.h b/compiler/diagnostics/diagnostics.h index a5dd4f8..05e1de1 100644 --- a/compiler/diagnostics/diagnostics.h +++ b/compiler/diagnostics/diagnostics.h @@ -65,7 +65,7 @@ namespace swallow::compiler::diagnostics [[nodiscard]] auto get_end_index() const -> size_t; - void set_end_index(size_t end_index); + void set_end_index(size_t end_index); [[nodiscard]] auto get_width() const -> size_t; @@ -133,8 +133,8 @@ namespace swallow::compiler::diagnostics [[nodiscard]] auto get_label_line(const Label &label) const -> size_t; - [[nodiscard]] auto get_line_spans() const - -> const std::vector> &; + [[nodiscard]] auto + get_line_spans() const -> const std::vector> &; [[nodiscard]] auto get_source() const -> const std::string &; @@ -165,20 +165,20 @@ namespace swallow::compiler::diagnostics auto print_colored_source_line( std::ostream &output, const Span &label_span, const Labels &labels) const -> void; - [[nodiscard]] static auto find_label_levels(const Labels &labels) - -> std::vector; + [[nodiscard]] static auto + find_label_levels(const Labels &labels) -> std::vector; [[nodiscard]] static auto find_remove_overlapping_labels(Labels &labels) -> Labels; - [[nodiscard]] auto find_labels_in_line(size_t line_index) const -> Labels; + [[nodiscard]] auto find_labels_in_line(size_t line_index) const -> Labels; - [[nodiscard]] auto get_first_label() const -> const Label *; + [[nodiscard]] auto get_first_label() const -> const Label *; - [[nodiscard]] auto get_labels() const -> const Labels &; + [[nodiscard]] auto get_labels() const -> const Labels &; - [[nodiscard]] auto get_details() const -> Details *; + [[nodiscard]] auto get_details() const -> Details *; - [[nodiscard]] auto get_last_label() const -> const Label *; + [[nodiscard]] auto get_last_label() const -> const Label *; private: const Label *first_label_; @@ -215,7 +215,7 @@ namespace swallow::compiler::diagnostics std::vector