Skip to content

Commit

Permalink
token: make tokens comparable with literals
Browse files Browse the repository at this point in the history
  • Loading branch information
jumanji144 committed Nov 12, 2023
1 parent 13c07e7 commit e341c26
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 27 deletions.
20 changes: 11 additions & 9 deletions lib/include/pl/core/token.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <variant>
#include <vector>
#include <map>
#include <limits>
#include <utility>

#include <pl/helpers/types.hpp>
#include "location.hpp"
Expand Down Expand Up @@ -171,7 +171,7 @@ namespace pl::core {
constexpr bool operator==(const DocComment &) const = default;
};

struct Literal : public std::variant<char, bool, u128, i128, double, std::string, std::shared_ptr<ptrn::Pattern>> {
struct Literal : std::variant<char, bool, u128, i128, double, std::string, std::shared_ptr<ptrn::Pattern>> {
using variant::variant;

[[nodiscard]] std::shared_ptr<ptrn::Pattern> toPattern() const;
Expand All @@ -192,33 +192,35 @@ namespace pl::core {
[[nodiscard]] bool isString() const;

[[nodiscard]] ValueType getType() const;

[[nodiscard]] bool operator==(const Literal &other) const;
};

using ValueTypes = std::variant<Keyword, Identifier, Operator, Literal, ValueType, Separator, DocComment>;

constexpr Token(Type type, auto value, Location location) : type(type), value(std::move(value)), location(location) {}
constexpr Token(const Type type, auto value, const Location location) : type(type), value(std::move(value)), location(location) {}

[[nodiscard]] constexpr static inline bool isInteger(const ValueType &type) {
[[nodiscard]] constexpr static bool isInteger(const ValueType &type) {
return isUnsigned(type) || isSigned(type);
}

[[nodiscard]] constexpr static inline bool isUnsigned(const ValueType &type) {
[[nodiscard]] constexpr static bool isUnsigned(const ValueType &type) {
return (static_cast<u32>(type) & 0x0F) == 0x00;
}

[[nodiscard]] constexpr static inline bool isSigned(const ValueType &type) {
[[nodiscard]] constexpr static bool isSigned(const ValueType &type) {
return (static_cast<u32>(type) & 0x0F) == 0x01;
}

[[nodiscard]] constexpr static inline bool isFloatingPoint(const ValueType &type) {
[[nodiscard]] constexpr static bool isFloatingPoint(const ValueType &type) {
return (static_cast<u32>(type) & 0x0F) == 0x02;
}

[[nodiscard]] constexpr static inline u32 getTypeSize(const ValueType &type) {
[[nodiscard]] constexpr static u32 getTypeSize(const ValueType &type) {
return static_cast<u32>(type) >> 4;
}

[[nodiscard]] static const char* getTypeName(core::Token::ValueType type);
[[nodiscard]] static const char* getTypeName(ValueType type);

[[nodiscard]] std::string getFormattedType() const;
[[nodiscard]] std::string getFormattedValue() const;
Expand Down
61 changes: 43 additions & 18 deletions lib/source/pl/core/token.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,31 @@ namespace pl::core {
return std::holds_alternative<std::shared_ptr<ptrn::Pattern>>(*this);
}

bool Token::Literal::operator==(const Literal &other) const {
return std::visit(wolv::util::overloaded {
[]<typename T>(T lhs, T rhs) {
return lhs == rhs;
},
[](integral auto lhs, pl::integral auto rhs) {
if constexpr (std::same_as<decltype(lhs), char> || std::same_as<decltype(rhs), char>)
return char(lhs) == char(rhs);
else if constexpr (std::same_as<decltype(lhs), bool> || std::same_as<decltype(rhs), bool>)
return bool(lhs) == bool(rhs);
else
return std::cmp_equal(lhs, rhs);
},
[](integral auto lhs, floating_point auto rhs) {
return lhs == rhs;
},
[](floating_point auto lhs, integral auto rhs) {
return lhs == rhs;
},
[](auto, auto) {
return false;
}
}, *this, other);
}

Token::ValueType Token::Literal::getType() const {
return std::visit(wolv::util::overloaded {
[](char) { return Token::ValueType::Character; },
Expand Down Expand Up @@ -196,9 +221,9 @@ namespace pl::core {

[[nodiscard]] std::string Token::getFormattedValue() const {
return std::visit(wolv::util::overloaded {
[](Token::Keyword keyword) -> std::string {
[](const Keyword keyword) -> std::string {
switch (keyword) {
using enum Token::Keyword;
using enum Keyword;
case Struct: return "struct";
case Union: return "union";
case Using: return "using";
Expand Down Expand Up @@ -235,9 +260,9 @@ namespace pl::core {

return "";
},
[](Token::Separator separator) -> std::string {
[](const Separator separator) -> std::string {
switch(separator) {
using enum Token::Separator;
using enum Separator;

case LeftParenthesis: return "(";
case RightParenthesis: return ")";
Expand All @@ -253,9 +278,9 @@ namespace pl::core {

return "";
},
[](Token::Operator op) -> std::string {
[](const Operator op) -> std::string {
switch (op) {
using enum Token::Operator;
using enum Operator;

case At: return "@";
case Assign: return "=";
Expand Down Expand Up @@ -291,16 +316,16 @@ namespace pl::core {

return "";
},
[](const Token::Identifier &identifier) -> std::string {
[](const Identifier &identifier) -> std::string {
return fmt::format("'{}'", identifier.get());
},
[](const Token::Literal &literal) -> std::string {
[](const Literal &literal) -> std::string {
return fmt::format("'{}'", literal.toString(true));
},
[](Token::ValueType valueType) -> std::string {
[](const ValueType valueType) -> std::string {
return getTypeName(valueType);
},
[](const Token::DocComment &docComment) -> std::string {
[](const DocComment &docComment) -> std::string {
if (docComment.global)
return fmt::format("/*! {} */", docComment.comment);
else
Expand All @@ -312,24 +337,24 @@ namespace pl::core {
bool Token::operator==(const ValueTypes &other) const {
if (this->type == Type::Integer || this->type == Type::Identifier || this->type == Type::String || this->type == Type::DocComment)
return true;
else if (this->type == Type::ValueType) {
auto otherValueType = std::get_if<ValueType>(&other);
auto valueType = std::get_if<ValueType>(&this->value);
if (this->type == Type::ValueType) {
const auto otherValueType = std::get_if<ValueType>(&other);
const auto valueType = std::get_if<ValueType>(&this->value);

if (otherValueType == nullptr) return false;
if (valueType == nullptr) return false;

if (*otherValueType == *valueType)
return true;
else if (*otherValueType == ValueType::Any)
if (*otherValueType == ValueType::Any)
return *valueType != ValueType::CustomType && *valueType != ValueType::Padding;
else if (*otherValueType == ValueType::Unsigned)
if (*otherValueType == ValueType::Unsigned)
return isUnsigned(*valueType);
else if (*otherValueType == ValueType::Signed)
if (*otherValueType == ValueType::Signed)
return isSigned(*valueType);
else if (*otherValueType == ValueType::FloatingPoint)
if (*otherValueType == ValueType::FloatingPoint)
return isFloatingPoint(*valueType);
else if (*otherValueType == ValueType::Integer)
if (*otherValueType == ValueType::Integer)
return isUnsigned(*valueType) || isSigned(*valueType);
} else
return other == this->value;
Expand Down

0 comments on commit e341c26

Please sign in to comment.