diff --git a/.clang-format b/.clang-format index 1d87988..d088eeb 100644 --- a/.clang-format +++ b/.clang-format @@ -22,7 +22,7 @@ BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: true AllowAllArgumentsOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: true -ColumnLimit: 80 +ColumnLimit: 120 CommentPragmas: '^ IWYU pragma:' ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerIndentWidth: 2 @@ -47,11 +47,11 @@ MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 1 NamespaceIndentation: All -PenaltyBreakComment: 80 -PenaltyBreakFirstLessLess: 80 -PenaltyBreakString: 80 -PenaltyExcessCharacter: 80 -PenaltyReturnTypeOnItsOwnLine: 80 +PenaltyBreakComment: 120 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 120 +PenaltyExcessCharacter: 120 +PenaltyReturnTypeOnItsOwnLine: 120 PointerAlignment: Middle ReflowComments: true SortIncludes: "Never" diff --git a/.gitignore b/.gitignore index 101dd4e..eb11a97 100644 --- a/.gitignore +++ b/.gitignore @@ -12,11 +12,6 @@ build/ compile_commands.json -compiler/lexer/flex_lexer.cpp -compiler/parser/bison_parser.cpp -compiler/parser/bison_parser.hpp -compiler/parser/location.hh - .ninja_deps .ninja_log diff --git a/CMakeLists.txt b/CMakeLists.txt index a4388bf..2154eb4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,23 +8,24 @@ cmake_policy(SET CMP0091 NEW) project(swallow VERSION 0.0.1 LANGUAGES CXX) # target -set(CMAKE_C_COMPILER "/usr/bin/clang") -set(CMAKE_CXX_COMPILER "/usr/bin/clang++") add_library(base SHARED "") set_target_properties(base PROPERTIES OUTPUT_NAME "base") -set_target_properties(base PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/linux/x86_64/release") +set_target_properties(base PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/linux/x86_64/debug") target_compile_options(base PRIVATE $<$:-m64> $<$:-m64> - $<$:-DNDEBUG> - $<$:-DNDEBUG> ) set_target_properties(base PROPERTIES CXX_EXTENSIONS OFF) target_compile_features(base PRIVATE cxx_std_20) if(MSVC) - target_compile_options(base PRIVATE $<$:-Ox -fp:fast>) + target_compile_options(base PRIVATE $<$:-Od>) else() - target_compile_options(base PRIVATE -O3) + target_compile_options(base PRIVATE -O0) +endif() +if(MSVC) + target_compile_options(base PRIVATE -Zi) +else() + target_compile_options(base PRIVATE -g) endif() if(MSVC) set_property(TARGET base PROPERTY @@ -38,11 +39,9 @@ target_sources(base PRIVATE ) # target -set(CMAKE_C_COMPILER "/usr/bin/clang") -set(CMAKE_CXX_COMPILER "/usr/bin/clang++") add_executable(swc "") set_target_properties(swc PROPERTIES OUTPUT_NAME "swc") -set_target_properties(swc PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/linux/x86_64/release") +set_target_properties(swc PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/linux/x86_64/debug") add_dependencies(swc base) target_include_directories(swc PRIVATE compiler @@ -56,20 +55,18 @@ target_include_directories(swc PRIVATE target_compile_options(swc PRIVATE $<$:-m64> $<$:-m64> - $<$:-DNDEBUG> - $<$:-DNDEBUG> - $<$:-stdlib=libc++> ) set_target_properties(swc PROPERTIES CXX_EXTENSIONS OFF) target_compile_features(swc PRIVATE cxx_std_20) if(MSVC) - target_compile_options(swc PRIVATE $<$:-Ox -fp:fast>) + target_compile_options(swc PRIVATE $<$:-Od>) else() - target_compile_options(swc PRIVATE -O3) + target_compile_options(swc PRIVATE -O0) endif() if(MSVC) + target_compile_options(swc PRIVATE -Zi) else() - target_compile_options(swc PRIVATE -fvisibility=hidden) + target_compile_options(swc PRIVATE -g) endif() if(MSVC) set_property(TARGET swc PROPERTY @@ -79,55 +76,52 @@ target_link_libraries(swc PRIVATE base ) target_link_directories(swc PRIVATE - build/linux/x86_64/release + build/linux/x86_64/debug ) target_link_options(swc PRIVATE -m64 ) target_sources(swc PRIVATE compiler/compiler.cpp - compiler/ast/g-machine.cpp - compiler/ast/dump.cpp compiler/ast/ast.cpp + compiler/ast/dump.cpp + compiler/ast/g-machine.cpp compiler/ast/type.cpp compiler/diagnostics/utils.cpp - compiler/diagnostics/reporter.cpp compiler/diagnostics/diagnostics.cpp - compiler/g-machine/instruction.cpp + compiler/diagnostics/reporter.cpp compiler/g-machine/binop.cpp compiler/g-machine/environment.cpp + compiler/g-machine/instruction.cpp compiler/lexer/lexer.cpp compiler/lexer/flex_lexer.cpp compiler/parser/parser.cpp compiler/parser/bison_parser.cpp - compiler/type/type.cpp compiler/type/dump.cpp compiler/type/environment.cpp + compiler/type/type.cpp ) # target -set(CMAKE_C_COMPILER "/usr/bin/clang") -set(CMAKE_CXX_COMPILER "/usr/bin/clang++") add_executable(swi "") set_target_properties(swi PROPERTIES OUTPUT_NAME "swi") -set_target_properties(swi PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/linux/x86_64/release") +set_target_properties(swi PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/linux/x86_64/debug") add_dependencies(swi swc) target_compile_options(swi PRIVATE $<$:-m64> $<$:-m64> - $<$:-DNDEBUG> - $<$:-DNDEBUG> ) set_target_properties(swi PROPERTIES CXX_EXTENSIONS OFF) target_compile_features(swi PRIVATE cxx_std_20) if(MSVC) - target_compile_options(swi PRIVATE $<$:-Ox -fp:fast>) + target_compile_options(swi PRIVATE $<$:-Od>) else() - target_compile_options(swi PRIVATE -O3) + target_compile_options(swi PRIVATE -O0) endif() if(MSVC) + target_compile_options(swi PRIVATE -Zi) else() - target_compile_options(swi PRIVATE -fvisibility=hidden) + target_compile_options(swi PRIVATE -g) endif() if(MSVC) set_property(TARGET swi PROPERTY @@ -137,7 +131,7 @@ target_link_libraries(swi PRIVATE base ) target_link_directories(swi PRIVATE - build/linux/x86_64/release + build/linux/x86_64/debug ) target_link_options(swi PRIVATE -m64 diff --git a/compiler/ast/ast.cpp b/compiler/ast/ast.cpp index d47333f..c316e1f 100644 --- a/compiler/ast/ast.cpp +++ b/compiler/ast/ast.cpp @@ -81,8 +81,7 @@ namespace swallow::compiler::type Environment typeEnvironment; auto intType = Type::Ptr(new Base("Int")); - auto binopType = Type::Ptr( - new Arrow(intType, Type::Ptr(new type::Arrow(intType, intType)))); + auto binopType = Type::Ptr(new Arrow(intType, Type::Ptr(new type::Arrow(intType, intType)))); typeEnvironment.Bind("+", binopType); typeEnvironment.Bind("-", binopType); diff --git a/compiler/ast/ast.hpp b/compiler/ast/ast.hpp index a0d4020..c754ac8 100644 --- a/compiler/ast/ast.hpp +++ b/compiler/ast/ast.hpp @@ -56,22 +56,19 @@ namespace swallow::compiler::ast virtual ~AST() = default; auto CommonTypeCheck(type::Manager &typeManager, - const type::Environment &typeEnvironment) noexcept - -> type::Type::Ptr; + const type::Environment &typeEnvironment) noexcept -> type::Type::Ptr; void CommonResolve(const type::Manager &typeManager) noexcept; virtual void Resolve(const type::Manager &typeManager) const 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; virtual void Compile(const gmachine::Environment::Ptr &machineEnvironment, - std::vector - &into) const noexcept = 0; + std::vector &into) const noexcept = 0; }; class Pattern @@ -114,8 +111,7 @@ namespace swallow::compiler::ast const yy::location Location; uint8_t Tag{}; - Constructor(const yy::location Location, std::string Name, - std::vector Types) + Constructor(const yy::location Location, std::string Name, std::vector Types) : Name(std::move(Name)), Types(std::move(Types)), Location(Location) {} }; @@ -130,14 +126,11 @@ namespace swallow::compiler::ast explicit Definition(const yy::location Location) : Location(Location) {} virtual ~Definition() = default; - virtual void PreScanTypes(type::Manager &typeManager, - type::Environment &typeEnvironment) noexcept = 0; + virtual void PreScanTypes(type::Manager &typeManager, type::Environment &typeEnvironment) noexcept = 0; virtual void Resolve(const type::Manager &typeManager) const noexcept = 0; - virtual void - TypeCheck(type::Manager &typeManager, - const type::Environment &typeEnvironment) const noexcept = 0; + virtual void TypeCheck(type::Manager &typeManager, const type::Environment &typeEnvironment) const noexcept = 0; }; class Int final : public AST @@ -145,19 +138,17 @@ namespace swallow::compiler::ast const int Value; public: - explicit Int(const yy::location Location, const int V) - : Value(V), AST(Location) - {} + explicit Int(const yy::location Location, const int V) : Value(V), AST(Location) {} - auto TypeCheck(type::Manager &typeManager, - const type::Environment &typeEnvironment) const noexcept + auto TypeCheck(type::Manager &typeManager, const type::Environment &typeEnvironment) const noexcept -> utils::Result override; void Dump(uint8_t indent, std::ostream &to) const noexcept override; void Compile(const gmachine::Environment::Ptr &machineEnvironment, - std::vector &into) - const noexcept override; + std::vector &into) const noexcept override; + + virtual void Resolve(const type::Manager &typeManager) const noexcept override; }; class LID final : public AST @@ -165,19 +156,16 @@ namespace swallow::compiler::ast const std::string ID; public: - explicit LID(const yy::location Location, std::string ID) - : ID(std::move(ID)), AST(Location) - {} + explicit LID(const yy::location Location, std::string ID) : ID(std::move(ID)), AST(Location) {} - auto TypeCheck(type::Manager &typeManager, - const type::Environment &typeEnvironment) const noexcept + auto TypeCheck(type::Manager &typeManager, const type::Environment &typeEnvironment) const noexcept -> utils::Result override; void Dump(uint8_t indent, std::ostream &to) const noexcept override; void Compile(const gmachine::Environment::Ptr &machineEnvironment, - std::vector &into) - const noexcept override; + std::vector &into) const noexcept override; + virtual void Resolve(const type::Manager &typeManager) const noexcept override; }; class UID final : public AST @@ -185,19 +173,16 @@ namespace swallow::compiler::ast const std::string ID; public: - explicit UID(const yy::location Location, std::string ID) - : ID(std::move(ID)), AST(Location) - {} + explicit UID(const yy::location Location, std::string ID) : ID(std::move(ID)), AST(Location) {} - auto TypeCheck(type::Manager &typeManager, - const type::Environment &typeEnvironment) const noexcept + auto TypeCheck(type::Manager &typeManager, const type::Environment &typeEnvironment) const noexcept -> utils::Result override; void Dump(uint8_t indent, std::ostream &to) const noexcept override; void Compile(const gmachine::Environment::Ptr &machineEnvironment, - std::vector &into) - const noexcept override; + std::vector &into) const noexcept override; + virtual void Resolve(const type::Manager &typeManager) const noexcept override; }; class Binop final : public AST @@ -207,27 +192,21 @@ namespace swallow::compiler::ast const Ptr Left; const Ptr Right; - Binop(const yy::location Location, utils::Binop Operator, Ptr Left, - Ptr Right) - : Operator(Operator) - , Left(std::move(Left)) - , Right(std::move(Right)) - , AST(Location) + Binop(const yy::location Location, utils::Binop Operator, Ptr Left, Ptr Right) + : Operator(Operator), Left(std::move(Left)), Right(std::move(Right)), AST(Location) {} static auto OperatorToString(utils::Binop op) noexcept -> std::string; - auto TypeCheck(type::Manager &typeManager, - const type::Environment &typeEnvironment) const noexcept + auto TypeCheck(type::Manager &typeManager, const type::Environment &typeEnvironment) const noexcept -> utils::Result override; void Dump(uint8_t indent, std::ostream &to) const noexcept override; void Compile(const gmachine::Environment::Ptr &machineEnvironment, - std::vector &into) - const noexcept override; + std::vector &into) const noexcept override; - virtual void Resolve(const type::Manager &typeManager) const noexcept; + virtual void Resolve(const type::Manager &typeManager) const noexcept override; }; class Application final : public AST @@ -240,15 +219,14 @@ namespace swallow::compiler::ast : Left(std::move(Left)), Right(std::move(Right)), AST(Location) {} - auto TypeCheck(type::Manager &typeManager, - const type::Environment &typeEnvironment) const noexcept + auto TypeCheck(type::Manager &typeManager, const type::Environment &typeEnvironment) const noexcept -> utils::Result override; void Dump(uint8_t indent, std::ostream &to) const noexcept override; void Compile(const gmachine::Environment::Ptr &machineEnvironment, - std::vector &into) - const noexcept override; + std::vector &into) const noexcept override; + virtual void Resolve(const type::Manager &typeManager) const noexcept override; }; class Match final : public AST @@ -261,15 +239,14 @@ namespace swallow::compiler::ast : With(std::move(o)), Branches(std::move(b)), AST(Location) {} - auto TypeCheck(type::Manager &typeManager, - const type::Environment &typeEnvironment) const noexcept + auto TypeCheck(type::Manager &typeManager, const type::Environment &typeEnvironment) const noexcept -> utils::Result override; void Dump(uint8_t indent, std::ostream &to) const noexcept override; void Compile(const gmachine::Environment::Ptr &machineEnvironment, - std::vector &into) - const noexcept override; + std::vector &into) const noexcept override; + virtual void Resolve(const type::Manager &typeManager) const noexcept override; }; class VariablePattern final : public Pattern @@ -293,11 +270,8 @@ namespace swallow::compiler::ast const std::string ConstructorName; const std::vector Params; - ConstructorPattern(const yy::location Location, std::string Constructor, - std::vector Params) - : ConstructorName(std::move(Constructor)) - , Params(std::move(Params)) - , Pattern(Location) + ConstructorPattern(const yy::location Location, std::string Constructor, std::vector Params) + : ConstructorName(std::move(Constructor)), Params(std::move(Params)), Pattern(Location) {} void Match(type::Type::Ptr type, type::Manager &typeManager, @@ -316,20 +290,14 @@ namespace swallow::compiler::ast std::vector ParamTypes; type::Type::Ptr ReturnType; - Fn(const yy::location Location, std::string Name, - std::vector Params, AST::Ptr Body) - : Name(std::move(Name)) - , Params(std::move(Params)) - , Body(std::move(Body)) - , Definition(Location) + Fn(const yy::location Location, std::string Name, std::vector Params, AST::Ptr Body) + : Name(std::move(Name)), Params(std::move(Params)), Body(std::move(Body)), Definition(Location) {} - void PreScanTypes(type::Manager &typeManager, - type::Environment &typeEnvironment) noexcept override; + void PreScanTypes(type::Manager &typeManager, type::Environment &typeEnvironment) noexcept override; - void TypeCheck( - type::Manager &typeManager, - const type::Environment &typeEnvironment) const noexcept override; + void TypeCheck(type::Manager &typeManager, const type::Environment &typeEnvironment) const noexcept override; + virtual void Resolve(const type::Manager &typeManager) const noexcept override; }; class Data final : public Definition @@ -338,19 +306,13 @@ namespace swallow::compiler::ast const std::string Name; const std::vector Constructors; - Data(const yy::location Location, std::string Name, - std::vector Constructors) - : Name(std::move(Name)) - , Constructors(std::move(Constructors)) - , Definition(Location) + Data(const yy::location Location, std::string Name, std::vector Constructors) + : Name(std::move(Name)), Constructors(std::move(Constructors)), Definition(Location) {} - void PreScanTypes(type::Manager &typeManager, - type::Environment &typeEnvironment) noexcept override; - - void TypeCheck( - type::Manager &typeManager, - const type::Environment &typeEnvironment) const noexcept override; + void PreScanTypes(type::Manager &typeManager, type::Environment &typeEnvironment) noexcept override; + void TypeCheck(type::Manager &typeManager, const type::Environment &typeEnvironment) const noexcept override; + virtual void Resolve(const type::Manager &typeManager) const noexcept override; }; void Dump(const std::vector &Program) noexcept; diff --git a/compiler/ast/dump.cpp b/compiler/ast/dump.cpp index 897ac98..6eda6d2 100644 --- a/compiler/ast/dump.cpp +++ b/compiler/ast/dump.cpp @@ -97,10 +97,7 @@ namespace swallow::compiler::ast to << ">" << '\n'; } - void VariablePattern::Dump(std::ostream &to) const noexcept - { - to << Variable; - } + void VariablePattern::Dump(std::ostream &to) const noexcept { to << Variable; } void ConstructorPattern::Dump(std::ostream &to) const noexcept { diff --git a/compiler/ast/g-machine.cpp b/compiler/ast/g-machine.cpp index 8301be8..2e5d519 100644 --- a/compiler/ast/g-machine.cpp +++ b/compiler/ast/g-machine.cpp @@ -33,6 +33,7 @@ #include "g-machine/binop.hpp" #include "g-machine/instruction.hpp" #include +#include "panic/panic.hpp" using swallow::compiler::gmachine::instruction::Instruction; using namespace swallow::compiler::gmachine; @@ -49,12 +50,11 @@ namespace swallow::compiler::ast void LID::Compile(const gmachine::Environment::Ptr &machineEnvironment, std::vector &into) const noexcept { - into.push_back(Instruction::Ptr( - machineEnvironment->HasVariable(ID) - ? dynamic_cast( - new instruction::Push(machineEnvironment->GetOffset(ID).value())) + into.push_back( + Instruction::Ptr(machineEnvironment->HasVariable(ID) + ? dynamic_cast(new instruction::Push(machineEnvironment->GetOffset(ID).value())) - : dynamic_cast(new instruction::PushGlobal(ID)))); + : dynamic_cast(new instruction::PushGlobal(ID)))); } void UID::Compile(const gmachine::Environment::Ptr &machineEnvironment, @@ -77,16 +77,96 @@ namespace swallow::compiler::ast Right->Compile(machineEnvironment, into); Left->Compile(machineEnvironment, into); - into.push_back(Instruction::Ptr( - new instruction::PushGlobal(gmachine::Binop::Action(Operator)))); + into.push_back(Instruction::Ptr(new instruction::PushGlobal(gmachine::Binop::Action(Operator)))); into.push_back(Instruction::Ptr(new instruction::MakeApplication())); into.push_back(Instruction::Ptr(new instruction::MakeApplication())); } + static auto CompileVariablePattern(instruction::Jump *jump, + const type::Data *type, + const Branch::Ptr &branch, + const Environment::Ptr &machineEnvironment) noexcept + -> std::vector + { + std::vector branchInstructions; + + branch->Expr->Compile(Environment::Ptr(new Offset(1, machineEnvironment)), branchInstructions); + + for (const auto &constructorPair : type->Constructors) + { + if (jump->TagMappings.find(constructorPair.second.Tag) != jump->TagMappings.end()) + break; + + jump->TagMappings[constructorPair.second.Tag] = jump->Branches.size(); + } + jump->Branches.push_back(std::move(branchInstructions)); + return branchInstructions; + } + + static auto CompileConstructorPattern(instruction::Jump *jump, + type::Data *type, + const Branch::Ptr &branch, + const Environment::Ptr &machineEnvironment, + const ConstructorPattern *constructorPattern, + const yy::location &Location) noexcept -> std::vector + { + auto newEnvironment = machineEnvironment; + std::vector branchInstructions; + + std::for_each(constructorPattern->Params.rbegin(), 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); + branchInstructions.push_back(Instruction::Ptr(new instruction::Slide(constructorPattern->Params.size()))); + + uint8_t newTag = type->Constructors[constructorPattern->ConstructorName].Tag; + if (jump->TagMappings.find(newTag) != jump->TagMappings.end()) + { + diagnostics::Reporter::REPORTER->normal( + Location, + std::format("Duplicate pattern {}", constructorPattern->ConstructorName), + "This constructor already exists in context", + "Consider remove this pattern", + diagnostics::PATTERN_CONSTRUCTOR_IS_DUPLICATED); + } + + jump->TagMappings[newTag] = jump->Branches.size(); + jump->Branches.push_back(std::move(branchInstructions)); + return branchInstructions; + } + + static void CheckCompileResult(const instruction::Jump *jump, const type::Data *type, const yy::location &Location) + { + for (const auto &constructorPair : type->Constructors) + { + if (jump->TagMappings.find(constructorPair.second.Tag) == jump->TagMappings.end()) + diagnostics::Reporter::REPORTER->normal(Location, "This pattern-matching is not exhaustive", + "There may be other patterns", "Please try to match all cases", + diagnostics::MATCH_EXPR_IS_NON_EXHAUSTIVE); + } + } + + static void CompileBranch(const Branch::Ptr &branch, instruction::Jump *jump, const AST::Ptr &With, + const Environment::Ptr &machineEnvironment, const yy::location &Location) noexcept + { + auto *type = dynamic_cast(With->NodeType.get()); + auto *variablePattern = dynamic_cast(branch->Patt.get()); + auto *constructorPattern = dynamic_cast(branch->Patt.get()); + + if (nullptr != variablePattern) + CompileVariablePattern(jump, type, branch, machineEnvironment); + else if (nullptr != constructorPattern) + CompileConstructorPattern(jump, type, branch, machineEnvironment, constructorPattern, Location); + else + utils::Panic("WTF"); + + CheckCompileResult(jump, type, Location); + } + void Match::Compile(const gmachine::Environment::Ptr &machineEnvironment, std::vector &into) const noexcept { - auto *type = dynamic_cast(With->NodeType.get()); auto *jump = new instruction::Jump(); With->Compile(machineEnvironment, into); @@ -94,73 +174,6 @@ namespace swallow::compiler::ast into.push_back(Instruction::Ptr(jump)); for (const auto &branch : Branches) - { - std::vector branchInstructions; - auto *variablePattern = - dynamic_cast(branch->Patt.get()); - auto *constructorPattern = - dynamic_cast(branch->Patt.get()); - - if (nullptr != variablePattern) - { - branch->Expr->Compile( - Environment::Ptr(new Offset(1, machineEnvironment)), - branchInstructions); - - for (const auto &constructorPair : type->Constructors) - { - if (jump->TagMappings.find(constructorPair.second.Tag) - != jump->TagMappings.end()) - break; - - jump->TagMappings[constructorPair.second.Tag] = - jump->Branches.size(); - } - jump->Branches.push_back(std::move(branchInstructions)); - } - else if (nullptr != constructorPattern) - { - auto newEnvironment = machineEnvironment; - - std::for_each( - constructorPattern->Params.rbegin(), - 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); - branchInstructions.push_back(Instruction::Ptr( - new instruction::Slide(constructorPattern->Params.size()))); - - uint8_t newTag = - type->Constructors[constructorPattern->ConstructorName].Tag; - if (jump->TagMappings.find(newTag) != jump->TagMappings.end()) - { - diagnostics::Reporter::REPORTER->normal( - Location, - std::format("Duplicate pattern {}", - constructorPattern->ConstructorName), - "This constructor already exists in context", - "Consider remove this pattern", - diagnostics::PATTERN_CONSTRUCTOR_IS_DUPLICATED); - } - - jump->TagMappings[newTag] = jump->Branches.size(); - jump->Branches.push_back(std::move(branchInstructions)); - } - - for (const auto &constructorPair : type->Constructors) - { - if (jump->TagMappings.find(constructorPair.second.Tag) - == jump->TagMappings.end()) - diagnostics::Reporter::REPORTER->normal( - Location, "This pattern-matching is not exhaustive", - "There may be other patterns", "Please try to match all cases", - diagnostics::MATCH_EXPR_IS_NON_EXHAUSTIVE); - } - } + CompileBranch(branch, jump, this->With, machineEnvironment, this->Location); } } // namespace swallow::compiler::ast diff --git a/compiler/ast/type.cpp b/compiler/ast/type.cpp index 7ddbe1f..18237fe 100644 --- a/compiler/ast/type.cpp +++ b/compiler/ast/type.cpp @@ -43,79 +43,67 @@ namespace swallow::compiler::ast { auto Int::TypeCheck(type::Manager &typeManager, - const type::Environment &typeEnvironment) const noexcept - -> Result + 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 + const type::Environment &typeEnvironment) const noexcept -> Result { return typeEnvironment.Lookup(ID).or_else([&](const auto &err) { - return diagnostics::Reporter::REPORTER->normal( - Location, std::format("'{}' was not declared", ID), - "The definition of this identifier cannot be found in the context", - "Function or Variable is undefined", - diagnostics::Code::LID_NOT_DECLARED); + return diagnostics::Reporter::REPORTER->normal(Location, std::format("'{}' was not declared", ID), + "The definition of this identifier cannot be found in the context", + "Function or Variable is undefined", + diagnostics::Code::LID_NOT_DECLARED); }); } auto UID::TypeCheck(type::Manager &typeManager, - const type::Environment &typeEnvironment) const noexcept - -> Result + const type::Environment &typeEnvironment) const noexcept -> Result { return typeEnvironment.Lookup(ID).or_else([&](const auto &err) { - return diagnostics::Reporter::REPORTER->normal( - Location, std::format("'{}' was not declared", ID), - "The definition of this identifier cannot be found in the context", - "Type or ConstructorName is undefined", diagnostics::UID_NOT_DECLARED); + return diagnostics::Reporter::REPORTER->normal(Location, std::format("'{}' was not declared", ID), + "The definition of this identifier cannot be found in the context", + "Type or ConstructorName is undefined", + diagnostics::UID_NOT_DECLARED); }); } auto Binop::TypeCheck(type::Manager &typeManager, - const type::Environment &typeEnvironment) const noexcept - -> Result + const type::Environment &typeEnvironment) const noexcept -> Result { const std::string operatorName = OperatorToString(Operator); - type::Type::Ptr leftType = - Left->TypeCheck(typeManager, typeEnvironment) - .or_else([&](const auto &err) { - return diagnostics::Reporter::REPORTER->normal( - Left->Location, "Type checking failed", "Wrong type here", - std::format("No more information"), - diagnostics::EXPR_TYPE_CHECKING_FAILED); - }) - .unwrap(); - - type::Type::Ptr rightType = - Right->TypeCheck(typeManager, typeEnvironment) - .or_else([&](const auto &err) { - return diagnostics::Reporter::REPORTER->normal( - Left->Location, "Type checking failed", "Wrong type here", - std::format("No more information"), - diagnostics::EXPR_TYPE_CHECKING_FAILED); - }) - .unwrap(); + type::Type::Ptr leftType = Left->TypeCheck(typeManager, typeEnvironment) + .or_else([&](const auto &err) { + return diagnostics::Reporter::REPORTER->normal( + Left->Location, "Type checking failed", "Wrong type here", + std::format("No more information"), diagnostics::EXPR_TYPE_CHECKING_FAILED); + }) + .unwrap(); + + type::Type::Ptr rightType = Right->TypeCheck(typeManager, typeEnvironment) + .or_else([&](const auto &err) { + return diagnostics::Reporter::REPORTER->normal( + Left->Location, "Type checking failed", "Wrong type here", + std::format("No more information"), diagnostics::EXPR_TYPE_CHECKING_FAILED); + }) + .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); + 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)); - type::Type::Ptr arrowTwo = - type::Type::Ptr(new type::Arrow(leftType, arrowOne)); + type::Type::Ptr arrowOne = type::Type::Ptr(new type::Arrow(rightType, returnType)); + type::Type::Ptr arrowTwo = type::Type::Ptr(new type::Arrow(leftType, arrowOne)); typeManager.Unify(arrowTwo, functionType) .or_else([&](const auto &err) { @@ -140,32 +128,26 @@ namespace swallow::compiler::ast } auto Application::TypeCheck(type::Manager &typeManager, - const type::Environment &typeEnvironment) - const noexcept -> Result + const type::Environment &typeEnvironment) const noexcept -> Result { - type::Type::Ptr leftType = - Left->TypeCheck(typeManager, typeEnvironment) - .or_else([&](const auto &err) { - return diagnostics::Reporter::REPORTER->normal( - Left->Location, "Type checking failed", "Wrong type here", - std::format("No more information"), - diagnostics::EXPR_TYPE_CHECKING_FAILED); - }) - .unwrap(); - - type::Type::Ptr rightType = - Right->TypeCheck(typeManager, typeEnvironment) - .or_else([&](const auto &err) { - return diagnostics::Reporter::REPORTER->normal( - Left->Location, "Type checking failed", "Wrong type here", - std::format("No more information"), - diagnostics::EXPR_TYPE_CHECKING_FAILED); - }) - .unwrap(); + type::Type::Ptr leftType = Left->TypeCheck(typeManager, typeEnvironment) + .or_else([&](const auto &err) { + return diagnostics::Reporter::REPORTER->normal( + Left->Location, "Type checking failed", "Wrong type here", + std::format("No more information"), diagnostics::EXPR_TYPE_CHECKING_FAILED); + }) + .unwrap(); + + type::Type::Ptr rightType = Right->TypeCheck(typeManager, typeEnvironment) + .or_else([&](const auto &err) { + return diagnostics::Reporter::REPORTER->normal( + Left->Location, "Type checking failed", "Wrong type here", + std::format("No more information"), diagnostics::EXPR_TYPE_CHECKING_FAILED); + }) + .unwrap(); type::Type::Ptr returnType = typeManager.NewType(); - type::Type::Ptr arrowType = - type::Type::Ptr(new type::Arrow(rightType, returnType)); + type::Type::Ptr arrowType = type::Type::Ptr(new type::Arrow(rightType, returnType)); typeManager.Unify(arrowType, leftType) .or_else([&](const auto &err) { @@ -178,8 +160,7 @@ namespace swallow::compiler::ast 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("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); }) @@ -189,20 +170,18 @@ namespace swallow::compiler::ast } auto Match::TypeCheck(type::Manager &typeManager, - const type::Environment &typeEnvironment) const noexcept - -> Result + const type::Environment &typeEnvironment) const noexcept -> Result { type::Variable *var = nullptr; - type::Type::Ptr matchType = typeManager.Resolve( - With->TypeCheck(typeManager, typeEnvironment) - .or_else([&](const auto &err) { - return diagnostics::Reporter::REPORTER->normal( - With->Location, "Type checking failed", "Wrong type here", - std::format("No more information"), - diagnostics::MATCH_EXPR_TYPE_CHECKING_FAILED); - }) - .unwrap(), - var); + type::Type::Ptr matchType = + typeManager.Resolve(With->TypeCheck(typeManager, typeEnvironment) + .or_else([&](const auto &err) { + return diagnostics::Reporter::REPORTER->normal( + With->Location, "Type checking failed", "Wrong type here", + std::format("No more information"), diagnostics::MATCH_EXPR_TYPE_CHECKING_FAILED); + }) + .unwrap(), + var); type::Type::Ptr branchType = typeManager.NewType(); @@ -215,8 +194,7 @@ namespace swallow::compiler::ast branch->Expr->TypeCheck(typeManager, newEnvironment) .or_else([&](const auto &err) { return diagnostics::Reporter::REPORTER->normal( - branch->Location, "Type checking failed", "Wrong type here", - "No more information", + branch->Location, "Type checking failed", "Wrong type here", "No more information", diagnostics::MATCH_EXPR_CURRENT_BRANCHE_TYPE_CHECKING_FAILED); }) .unwrap(); @@ -232,10 +210,8 @@ namespace swallow::compiler::ast 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()), + 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(); @@ -244,10 +220,9 @@ namespace swallow::compiler::ast matchType = typeManager.Resolve(matchType, var); if (nullptr == dynamic_cast(matchType.get())) { - return diagnostics::Reporter::REPORTER->normal( - Location, "Type checking failed for Match expression", - "This is not a data type", "No more information", - diagnostics::MATCH_NON_DATA_TYPE); + return diagnostics::Reporter::REPORTER->normal(Location, "Type checking failed for Match expression", + "This is not a data type", "No more information", + diagnostics::MATCH_NON_DATA_TYPE); } return Ok(branchType); @@ -259,31 +234,27 @@ namespace swallow::compiler::ast typeManager.Bind(Variable, type); } - void - ConstructorPattern::Match(type::Type::Ptr type, type::Manager &typeManager, - type::Environment &typeEnvironment) const noexcept + void ConstructorPattern::Match(type::Type::Ptr type, 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", - "ConstructorName 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", + "ConstructorName is undefined", diagnostics::CONSTRUCTOR_NOT_DECLARED); + }) + .unwrap(); std::for_each(Params.begin(), Params.end(), [&](const std::string ¶m) { auto *arrow = dynamic_cast(constructorType.get()); if (arrow == nullptr) { - diagnostics::Reporter::REPORTER->normal( - Location, "Illegal Pattern", "This identifier is not a constructor", - "ConstructorName must be a function type", - diagnostics::PATTERN_CONSTRUCTOR_IS_NOT_FUNCTION); + diagnostics::Reporter::REPORTER->normal(Location, "Illegal Pattern", "This identifier is not a constructor", + "ConstructorName must be a function type", + diagnostics::PATTERN_CONSTRUCTOR_IS_NOT_FUNCTION); } typeEnvironment.Bind(param, arrow->Left); @@ -300,41 +271,33 @@ namespace swallow::compiler::ast 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); + 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(); - if (auto *const resultType = - dynamic_cast(constructorType.get()); - resultType == nullptr) + if (auto *const resultType = dynamic_cast(constructorType.get()); resultType == nullptr) { - diagnostics::Reporter::REPORTER->normal( - Location, "Illegal return type", "Unable to return this value", - "No more information", diagnostics::UNKNOWN); + diagnostics::Reporter::REPORTER->normal(Location, "Illegal return type", "Unable to return this value", + "No more information", diagnostics::UNKNOWN); } } - void Fn::PreScanTypes(type::Manager &typeManager, - type::Environment &typeEnvironment) noexcept + void Fn::PreScanTypes(type::Manager &typeManager, type::Environment &typeEnvironment) noexcept { ReturnType = typeManager.NewType(); type::Type::Ptr fullType = ReturnType; - std::for_each( - Params.rbegin(), Params.rend(), [&](const std::string ¶m) { - type::Type::Ptr paramType = typeManager.NewType(); - fullType = type::Type::Ptr(new type::Arrow(paramType, fullType)); - ParamTypes.push_back(paramType); - }); + std::for_each(Params.rbegin(), Params.rend(), [&](const std::string ¶m) { + type::Type::Ptr paramType = typeManager.NewType(); + fullType = type::Type::Ptr(new type::Arrow(paramType, fullType)); + ParamTypes.push_back(paramType); + }); typeEnvironment.Bind(Name, fullType); } - void Fn::TypeCheck(type::Manager &typeManager, - const type::Environment &typeEnvironment) const noexcept + void Fn::TypeCheck(type::Manager &typeManager, const type::Environment &typeEnvironment) const noexcept { type::Environment newEnvironment = typeEnvironment.Scope(); @@ -350,8 +313,7 @@ namespace swallow::compiler::ast auto bodyType = Body->TypeCheck(typeManager, newEnvironment) .or_else([&](const auto &err) { return diagnostics::Reporter::REPORTER->normal( - Location, "Type checking failed for function body", - "Wrong type here", "No more information", + Location, "Type checking failed for function body", "Wrong type here", "No more information", diagnostics::FUNCTION_BODY_TYPE_CHECKING_FAILED); }) .unwrap(); @@ -366,16 +328,14 @@ namespace swallow::compiler::ast 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("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(type::Manager &typeManager, - type::Environment &typeEnvironment) noexcept + void Data::PreScanTypes(type::Manager &typeManager, type::Environment &typeEnvironment) noexcept { auto *thisType = new type::Data(Name); auto returnType = type::Type::Ptr(thisType); @@ -387,23 +347,18 @@ namespace swallow::compiler::ast thisType->Constructors[constructor->Name] = {nextTag++}; auto fullType = returnType; - std::for_each(constructor->Types.rbegin(), constructor->Types.rend(), - [&](const auto &typeName) { - fullType = type::Type::Ptr(new type::Arrow( - type::Type::Ptr(new type::Base(typeName)), fullType)); - }); + std::for_each(constructor->Types.rbegin(), constructor->Types.rend(), [&](const auto &typeName) { + fullType = type::Type::Ptr(new type::Arrow(type::Type::Ptr(new type::Base(typeName)), fullType)); + }); typeEnvironment.Bind(constructor->Name, fullType); } } - void Data::TypeCheck(type::Manager &typeManager, - const type::Environment &typeEnvironment) const noexcept - {} + void Data::TypeCheck(type::Manager &typeManager, const type::Environment &typeEnvironment) const noexcept {} auto AST::CommonTypeCheck(type::Manager &typeManager, - const type::Environment &typeEnvironment) noexcept - -> type::Type::Ptr + const type::Environment &typeEnvironment) noexcept -> type::Type::Ptr { NodeType = TypeCheck(typeManager, typeEnvironment).unwrap(); return NodeType; @@ -415,9 +370,8 @@ namespace swallow::compiler::ast type::Type::Ptr resolveType = typeManager.Resolve(NodeType, variable); if (nullptr == variable) - diagnostics::Reporter::REPORTER->normal( - Location, "Ambiguously type here", "Ambiguously typed program", - "No more information", diagnostics::AMBIGUOUSLY_TYPE); + diagnostics::Reporter::REPORTER->normal(Location, "Ambiguously type here", "Ambiguously typed program", + "No more information", diagnostics::AMBIGUOUSLY_TYPE); Resolve(typeManager); NodeType = std::move(resolveType); @@ -429,4 +383,12 @@ namespace swallow::compiler::ast Right->CommonResolve(typeManager); } + void Application::Resolve(const type::Manager &typeManager) const noexcept {} + void Match::Resolve(const type::Manager &typeManager) const noexcept {} + void Data::Resolve(const type::Manager &typeManager) const noexcept {} + void Fn::Resolve(const type::Manager &typeManager) const noexcept {} + void UID::Resolve(const type::Manager &typeManager) const noexcept {} + void LID::Resolve(const type::Manager &typeManager) const noexcept {} + void Int::Resolve(const type::Manager &typeManager) const noexcept {} + } // namespace swallow::compiler::ast diff --git a/compiler/compiler.h b/compiler/compiler.h index b13f1fe..9a626be 100644 --- a/compiler/compiler.h +++ b/compiler/compiler.h @@ -44,9 +44,7 @@ namespace swallow::compiler inline static CompileUnit *FILE = nullptr; - explicit CompileUnit(const std::string &FilePath) - : FilePath(FilePath), FileValue(ReadEntireFile(FilePath)) - {} + explicit CompileUnit(const std::string &FilePath) : FilePath(FilePath), FileValue(ReadEntireFile(FilePath)) {} private: static auto ReadEntireFile(const std::string &FilePath) -> std::string diff --git a/compiler/diagnostics/diagnostics.cpp b/compiler/diagnostics/diagnostics.cpp index 5c9f476..f2d2835 100644 --- a/compiler/diagnostics/diagnostics.cpp +++ b/compiler/diagnostics/diagnostics.cpp @@ -56,8 +56,7 @@ namespace swallow::compiler::diagnostics } } - auto color_by_type(std::ostream &stream, - const ColorType type) -> std::ostream & + auto color_by_type(std::ostream &stream, const ColorType type) -> std::ostream & { switch (type) { @@ -142,26 +141,20 @@ namespace swallow::compiler::diagnostics } } - auto AscendingLabels::operator()(const Label *first, - const Label *second) const -> bool + auto AscendingLabels::operator()(const Label *first, const Label *second) const -> bool { - auto difference = (int) first->get_span().get_start_index() - - (int) second->get_span().get_start_index(); + auto difference = (int) first->get_span().get_start_index() - (int) second->get_span().get_start_index(); if (difference == 0) - return first->get_span().get_end_index() - < second->get_span().get_end_index(); + return first->get_span().get_end_index() < second->get_span().get_end_index(); return difference < 0; } - auto DescendingLabels::operator()(const Label *first, - const Label *second) const -> bool + auto DescendingLabels::operator()(const Label *first, const Label *second) const -> bool { - auto difference = (int) first->get_span().get_start_index() - - (int) second->get_span().get_start_index(); + auto difference = (int) first->get_span().get_start_index() - (int) second->get_span().get_start_index(); if (difference == 0) - return first->get_span().get_end_index() - < second->get_span().get_end_index(); + return first->get_span().get_end_index() < second->get_span().get_end_index(); return difference > 0; } @@ -174,14 +167,12 @@ namespace swallow::compiler::diagnostics auto Span::relative_to(const Span &span) const -> Span { - return {span.get_details(), this->start_index_ - span.start_index_, - this->end_index_ - span.start_index_}; + return {span.get_details(), this->start_index_ - span.start_index_, this->end_index_ - span.start_index_}; } auto Span::is_inside_span(const Span &span) const -> bool { - return (this->start_index_ <= span.start_index_) - && (this->end_index_ >= span.end_index_); + return (this->start_index_ <= span.start_index_) && (this->end_index_ >= span.end_index_); } auto Span::get_start_index() const -> size_t { return this->start_index_; } @@ -192,22 +183,15 @@ namespace swallow::compiler::diagnostics void Span::set_end_index(size_t end_index) { this->end_index_ = end_index; } - auto Span::get_width() const -> size_t - { - return this->end_index_ - this->start_index_; - } + auto Span::get_width() const -> size_t { return this->end_index_ - this->start_index_; } - Label::Label(std::optional message, const Span &span, - ColorType color_type) + Label::Label(std::optional message, const Span &span, ColorType color_type) : message_(std::move(message)), color_(color_type), span_(span) { this->line_ = this->span_.get_details()->get_label_line(*this); } - auto Label::get_message() const -> const std::optional & - { - return this->message_; - } + auto Label::get_message() const -> const std::optional & { return this->message_; } auto Label::get_span() const -> const Span & { return this->span_; } @@ -246,8 +230,7 @@ namespace swallow::compiler::diagnostics return {this->message_, this->span_.value(), color}; } - Details::Details(std::string source, std::string path) - : source_(std::move(source)), path_(std::move(path)) + Details::Details(std::string source, std::string path) : source_(std::move(source)), path_(std::move(path)) { Span *current_span = nullptr; for (auto index = 0U; index < this->source_.size(); index++) @@ -275,8 +258,7 @@ namespace swallow::compiler::diagnostics auto Details::get_line_source(const Span &span) const -> std::string { - auto result = - this->source_.substr(span.get_start_index(), span.get_width()); + auto result = this->source_.substr(span.get_start_index(), span.get_width()); result = std::regex_replace(result, std::regex("\t"), " "); return result; } @@ -293,39 +275,25 @@ namespace swallow::compiler::diagnostics utils::Panic("Couldn't find the associated line for this span."); } - auto Details::get_line_spans() const - -> const std::vector> & - { - return this->line_spans_; - } + auto Details::get_line_spans() const -> const std::vector> & { return this->line_spans_; } - auto Details::get_source() const -> const std::string & - { - return this->source_; - } + auto Details::get_source() const -> const std::string & { return this->source_; } auto Details::get_path() const -> const std::string & { return this->path_; } - LabelGroup::LabelGroup( - Details *general_details_, std::vector labels) - : first_label_() - , last_label_() - , details_(general_details_) - , labels_(std::move(labels)) + LabelGroup::LabelGroup(Details *general_details_, std::vector labels) + : first_label_(), last_label_(), details_(general_details_), labels_(std::move(labels)) { - assertm(!this->labels_.empty(), - "Couldn't find the last labels as there are no labels."); + assertm(!this->labels_.empty(), "Couldn't find the last labels as there are no labels."); auto ascending_labels(this->labels_); - std::sort(ascending_labels.begin(), ascending_labels.end(), - AscendingLabels()); + std::sort(ascending_labels.begin(), ascending_labels.end(), AscendingLabels()); this->first_label_ = ascending_labels.front(); this->last_label_ = ascending_labels.back(); } - void LabelGroup::print(std::ostream &output, - const std::string &spaces_prefix) const + void LabelGroup::print(std::ostream &output, const std::string &spaces_prefix) const { auto first_line = this->first_label_->get_line(); auto last_line = this->last_label_->get_line(); @@ -338,15 +306,13 @@ namespace swallow::compiler::diagnostics if (ending_line >= this->details_->get_line_spans().size()) ending_line = last_line; - for (auto line_index = beginning_line; line_index <= ending_line; - line_index++) + for (auto line_index = beginning_line; line_index <= ending_line; line_index++) { const auto &line_span = this->details_->get_line_spans()[line_index]; auto line_number = line_index + 1; output << " " - << COLOR_RGB(std::setw(spaces_prefix.length() - 3) - << std::setfill(' ') << line_number << " | ", + << COLOR_RGB(std::setw(spaces_prefix.length() - 3) << std::setfill(' ') << line_number << " | ", COLOR_GREY); auto labels = this->find_labels_in_line(line_index); @@ -357,8 +323,7 @@ namespace swallow::compiler::diagnostics auto label_levels = find_label_levels(labels); for (auto index = 0U; index < label_levels.size(); index++) - print_labels_level(label_levels, index, *line_span, output, - spaces_prefix); + print_labels_level(label_levels, index, *line_span, output, spaces_prefix); } } @@ -489,17 +454,14 @@ namespace swallow::compiler::diagnostics } } - void LabelGroup::print_colored_source_line(std::ostream &output, - const Span &label_span, - const Labels &labels) const + 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); std::map mapped_labels; for (const auto &label : labels) { - const auto &line_span = - this->details_->get_line_spans()[label->get_line()]; + const auto &line_span = this->details_->get_line_spans()[label->get_line()]; auto relative_span = label->get_span().relative_to(*line_span); mapped_labels[relative_span.get_start_index()] = label; } @@ -520,9 +482,7 @@ namespace swallow::compiler::diagnostics output << current_char; auto starting_index = char_index; - for (char_index++; - char_index < starting_index + label->get_span().get_width() + 1; - char_index++) + for (char_index++; char_index < starting_index + label->get_span().get_width() + 1; char_index++) { if (mapped_labels.contains(char_index)) break; @@ -544,16 +504,14 @@ namespace swallow::compiler::diagnostics auto LabelGroup::find_label_levels(const Labels &labels) -> std::vector { auto descending_labels(labels); - std::sort(descending_labels.begin(), descending_labels.end(), - DescendingLabels()); + std::sort(descending_labels.begin(), descending_labels.end(), DescendingLabels()); std::vector level_labels; auto current_labels = descending_labels; while (true) { - auto overlapping_labels = - find_remove_overlapping_labels(current_labels); + auto overlapping_labels = find_remove_overlapping_labels(current_labels); level_labels.push_back(current_labels); if (overlapping_labels.empty()) @@ -573,13 +531,11 @@ namespace swallow::compiler::diagnostics Labels overlapping_labels; const auto *current_label = labels.front(); - for (auto iterator = labels.begin() + 1; iterator < labels.end(); - iterator++) + for (auto iterator = labels.begin() + 1; iterator < labels.end(); iterator++) { const auto *next_label = *iterator; - if (next_label->get_span().get_end_index() - < current_label->get_span().get_start_index()) + if (next_label->get_span().get_end_index() < current_label->get_span().get_start_index()) current_label = next_label; else { @@ -605,20 +561,11 @@ namespace swallow::compiler::diagnostics return result; } - auto LabelGroup::get_labels() const -> const Labels & - { - return this->labels_; - } + auto LabelGroup::get_labels() const -> const Labels & { return this->labels_; } - auto LabelGroup::get_first_label() const -> const Label * - { - return this->first_label_; - } + auto LabelGroup::get_first_label() const -> const Label * { return this->first_label_; } - auto LabelGroup::get_last_label() const -> const Label * - { - return this->last_label_; - } + auto LabelGroup::get_last_label() const -> const Label * { return this->last_label_; } auto LabelGroup::get_details() const -> Details * { return this->details_; } @@ -631,8 +578,7 @@ namespace swallow::compiler::diagnostics auto *current_labels = &labels_collection.emplace_back(); auto ascending_labels(labels); - std::sort(ascending_labels.begin(), ascending_labels.end(), - AscendingLabels()); + std::sort(ascending_labels.begin(), ascending_labels.end(), AscendingLabels()); auto last_line = labels.front()->get_line(); for (const auto &label : ascending_labels) @@ -651,11 +597,9 @@ namespace swallow::compiler::diagnostics this->label_groups_.emplace_back(details, collected_labels); } - void FileGroup::print(std::ostream &output, - const std::string &spaces_prefix) const + void FileGroup::print(std::ostream &output, const std::string &spaces_prefix) const { - output << COLOR_RGB("-[", COLOR_GREY) - << COLOR_RGB(this->details_->get_path(), COLOR_WHITE) + output << COLOR_RGB("-[", COLOR_GREY) << COLOR_RGB(this->details_->get_path(), COLOR_WHITE) << COLOR_RGB("]", COLOR_GREY); output << "\n"; @@ -694,28 +638,19 @@ namespace swallow::compiler::diagnostics return biggest_number; } - auto FileGroup::get_label_groups() const -> const std::vector & - { - return this->label_groups_; - } + auto FileGroup::get_label_groups() const -> const std::vector & { return this->label_groups_; } auto FileGroup::get_details() const -> Details * { return this->details_; } - Report::Report(ReportType type, std::string message, size_t code, - std::vector