diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index ddbfb52b..c17963f7 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -87,6 +87,7 @@ add_library(compiler_lib ast/ForIter.cpp ast/While.cpp ast/AssignationOperator.cpp + ast/AbstractType.cpp # === Environment === environment/Environment.cpp environment/Name.cpp diff --git a/src/lib/ast/AST.h b/src/lib/ast/AST.h index 83cb75cd..2e466209 100644 --- a/src/lib/ast/AST.h +++ b/src/lib/ast/AST.h @@ -200,16 +200,18 @@ namespace filc::ast { AbstractType(AbstractType &&other) = default; - auto operator=(const AbstractType &other) -> AbstractType & = default; + auto operator=(const AbstractType &other) -> AbstractType & = delete; - auto operator=(AbstractType &&other) -> AbstractType & = default; + auto operator=(AbstractType &&other) -> AbstractType & = delete; [[nodiscard]] virtual auto dump() const -> std::string = 0; [[nodiscard]] virtual auto getInnerType() const -> AbstractType * = 0; + [[nodiscard]] virtual auto equals(const AbstractType &other) const -> bool = 0; + protected: - AbstractType() = default; + explicit AbstractType() = default; }; class Type : public AbstractType { @@ -224,6 +226,8 @@ namespace filc::ast { [[nodiscard]] auto getInnerType() const -> AbstractType * override; + [[nodiscard]] auto equals(const AbstractType &other) const -> bool override; + private: Identifier *_name; }; @@ -240,6 +244,8 @@ namespace filc::ast { [[nodiscard]] auto dump() const -> std::string override; + auto equals(const AbstractType &other) const -> bool override; + private: AbstractType *_inner_type; unsigned int _size; @@ -255,6 +261,8 @@ namespace filc::ast { [[nodiscard]] auto dump() const -> std::string override; + auto equals(const AbstractType &other) const -> bool override; + private: AbstractType *_inner_type; }; @@ -276,6 +284,8 @@ namespace filc::ast { [[nodiscard]] auto getCalledOn() const -> AbstractType *; + auto equals(const AbstractType &other) const -> bool override; + private: std::vector _argument_types; AbstractType *_return_type; @@ -632,4 +642,8 @@ namespace filc::ast { }; } +auto operator==(const filc::ast::AbstractType &type1, const filc::ast::AbstractType &type2) -> bool; + +auto operator!=(const filc::ast::AbstractType &type1, const filc::ast::AbstractType &type2) -> bool; + #endif //FILC_AST_H diff --git a/src/lib/ast/AbstractType.cpp b/src/lib/ast/AbstractType.cpp new file mode 100644 index 00000000..e18cb6a4 --- /dev/null +++ b/src/lib/ast/AbstractType.cpp @@ -0,0 +1,32 @@ +/** + * MIT License + * + * Copyright (c) 2023-Present Kevin Traini + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "AST.h" + +auto operator==(const filc::ast::AbstractType &type1, const filc::ast::AbstractType &type2) -> bool { + return type1.equals(type2); +} + +auto operator!=(const filc::ast::AbstractType &type1, const filc::ast::AbstractType &type2) -> bool { + return !(type1 == type2); +} \ No newline at end of file diff --git a/src/lib/ast/ArrayType.cpp b/src/lib/ast/ArrayType.cpp index 12a6d855..30e4e621 100644 --- a/src/lib/ast/ArrayType.cpp +++ b/src/lib/ast/ArrayType.cpp @@ -40,6 +40,19 @@ namespace filc::ast { } ArrayType::~ArrayType() { - delete _inner_type; +// delete _inner_type; + } + + auto ArrayType::equals(const AbstractType &other) const -> bool { + if (dynamic_cast(&other) == nullptr) { + return false; + } + auto other_type = dynamic_cast(other); + + if (_size != other_type._size) { + return false; + } + + return *_inner_type == *other_type._inner_type; } } diff --git a/src/lib/ast/ClassicOperator.cpp b/src/lib/ast/ClassicOperator.cpp index 9672fe34..11a935c1 100644 --- a/src/lib/ast/ClassicOperator.cpp +++ b/src/lib/ast/ClassicOperator.cpp @@ -80,7 +80,7 @@ namespace filc::ast { filc::ast::AbstractType *called_on, filc::environment::Environment *environment, filc::message::MessageCollector *collector) const -> LambdaType * { - return new LambdaType({}, return_type); + return new LambdaType({}, return_type, called_on); } auto ClassicOperator::dumpPostLambdaType(filc::ast::AbstractType *return_type, diff --git a/src/lib/ast/LambdaType.cpp b/src/lib/ast/LambdaType.cpp index 13b6fe49..e7ae0417 100644 --- a/src/lib/ast/LambdaType.cpp +++ b/src/lib/ast/LambdaType.cpp @@ -54,10 +54,10 @@ namespace filc::ast { } LambdaType::~LambdaType() { - for (const auto &argument_type: _argument_types) { - delete argument_type; - } - delete _return_type; +// for (const auto &argument_type: _argument_types) { +// delete argument_type; +// } +// delete _return_type; } auto LambdaType::getInnerType() const -> AbstractType * { @@ -67,4 +67,23 @@ namespace filc::ast { auto LambdaType::getCalledOn() const -> AbstractType * { return _called_on; } + + auto LambdaType::equals(const AbstractType &other) const -> bool { + if (dynamic_cast(&other) == nullptr) { + return false; + } + auto other_type = dynamic_cast(other); + + if (_argument_types.size() != other_type._argument_types.size()) { + return false; + } + + for (unsigned int i = 0; i < _argument_types.size(); i++) { + if (*_argument_types[i] != *other_type._argument_types[i]) { + return false; + } + } + + return *_return_type == *other_type._return_type && *_called_on == *other_type._called_on; + } } diff --git a/src/lib/ast/PointerType.cpp b/src/lib/ast/PointerType.cpp index 90161e71..c6c49b23 100644 --- a/src/lib/ast/PointerType.cpp +++ b/src/lib/ast/PointerType.cpp @@ -36,6 +36,15 @@ namespace filc::ast { } PointerType::~PointerType() { - delete _inner_type; +// delete _inner_type; + } + + auto PointerType::equals(const AbstractType &other) const -> bool { + if (dynamic_cast(&other) == nullptr) { + return false; + } + auto other_type = dynamic_cast(other); + + return *_inner_type == *other_type._inner_type; } } diff --git a/src/lib/ast/Type.cpp b/src/lib/ast/Type.cpp index 6608a0d7..4e314954 100644 --- a/src/lib/ast/Type.cpp +++ b/src/lib/ast/Type.cpp @@ -28,7 +28,7 @@ namespace filc::ast { : _name(name) {} Type::~Type() { - delete _name; +// delete _name; } auto Type::getName() const -> Identifier * { @@ -42,4 +42,13 @@ namespace filc::ast { auto Type::getInnerType() const -> AbstractType * { return (AbstractType *) this; } + + auto Type::equals(const AbstractType &other) const -> bool { + if (dynamic_cast(&other) == nullptr) { + return false; + } + auto other_type = dynamic_cast(other); + + return _name->getName() == other_type._name->getName(); + } } \ No newline at end of file diff --git a/src/lib/ast/VariableDeclaration.cpp b/src/lib/ast/VariableDeclaration.cpp index 8bd7642e..3a815f6c 100644 --- a/src/lib/ast/VariableDeclaration.cpp +++ b/src/lib/ast/VariableDeclaration.cpp @@ -71,7 +71,8 @@ namespace filc::ast { return; } - if (environment->getName("operator=", new filc::ast::LambdaType({_type, assignation_type}, _type)) == nullptr) { + if (!environment->hasName("operator=", new filc::ast::LambdaType({_type, assignation_type}, + environment->getType("void")))) { collector->addError( new filc::message::Error(filc::message::ERROR, "Cannot assign " + assignation_type->dump() + " to " + _type->dump(), diff --git a/src/lib/environment/Environment.cpp b/src/lib/environment/Environment.cpp index f4c2ffbe..095a2452 100644 --- a/src/lib/environment/Environment.cpp +++ b/src/lib/environment/Environment.cpp @@ -35,7 +35,7 @@ namespace filc::environment { auto Environment::hasName(const std::string &name, filc::ast::AbstractType *type) const -> bool { return std::any_of(_names.begin(), _names.end(), [name, type](auto *item) -> bool { - return item->getName() == name && (type == nullptr || item->getType()->dump() == type->dump()); + return item->getName() == name && (type == nullptr || *item->getType() == *type); }) || (_parent != nullptr && _parent->hasName(name)); } @@ -52,7 +52,7 @@ namespace filc::environment { auto Environment::getName(const std::string &name, filc::ast::AbstractType *type) const -> Name * { if (hasName(name, type)) { auto result = std::find_if(_names.begin(), _names.end(), [name, type](auto *item) -> bool { - return item->getName() == name && (type == nullptr || item->getType()->dump() == type->dump()); + return item->getName() == name && (type == nullptr || *item->getType() == *type); }); if (result == _names.end()) {