Skip to content

Commit

Permalink
Switch to uintwide_t for 128-bit integers
Browse files Browse the repository at this point in the history
  • Loading branch information
mrexodia committed Jan 20, 2025
1 parent 947b99c commit 4b98a8d
Show file tree
Hide file tree
Showing 35 changed files with 256 additions and 154 deletions.
2 changes: 1 addition & 1 deletion generators/include/pl/formatters/formatter_json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ namespace pl::gen::fmt {
auto literal = pattern->getValue();

addLine(pattern->getVariableName(), std::visit(wolv::util::overloaded {
[&](std::integral auto value) -> std::string { return ::fmt::format("{}", value); },
[&](integral auto value) -> std::string { return ::fmt::format("{}", value); },
[&](std::floating_point auto value) -> std::string { return ::fmt::format("{}", value); },
[&](const std::string &value) -> std::string { return ::fmt::format("\"{}\"", value); },
[&](bool value) -> std::string { return value ? "true" : "false"; },
Expand Down
2 changes: 2 additions & 0 deletions lib/include/pl/core/ast/ast_node_literal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ namespace pl::core::ast {
class ASTNodeLiteral : public ASTNode {
public:
explicit ASTNodeLiteral(Token::Literal literal);
explicit ASTNodeLiteral(int value)
: ASTNodeLiteral(i128(value)) { }
ASTNodeLiteral(const ASTNodeLiteral &) = default;

[[nodiscard]] std::unique_ptr<ASTNode> clone() const override {
Expand Down
30 changes: 24 additions & 6 deletions lib/include/pl/core/ast/ast_node_mathematical_expression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,38 @@ namespace pl::core::ast {
class ASTNodeMathematicalExpression : public ASTNode {

FLOAT_BIT_OPERATION(shiftLeft) {
return left << right;
if constexpr (is_signed<decltype(left)>::value && is_signed<decltype(right)>::value)
return i128(left) << u64(right);
else
return u128(left) << u64(right);
}

FLOAT_BIT_OPERATION(shiftRight) {
return left >> right;
if constexpr (is_signed<decltype(left)>::value)
return i128(left) >> u64(right);
else
return u128(left) >> u64(right);
}

FLOAT_BIT_OPERATION(bitAnd) {
return left & right;
if constexpr (is_signed<decltype(left)>::value && is_signed<decltype(right)>::value)
return i128(left) & i128(right);
else
return u128(left) & u128(right);
}

FLOAT_BIT_OPERATION(bitOr) {
return left | right;
if constexpr (is_signed<decltype(left)>::value && is_signed<decltype(right)>::value)
return i128(left) | i128(right);
else
return u128(left) | u128(right);
}

FLOAT_BIT_OPERATION(bitXor) {
return left ^ right;
if constexpr (is_signed<decltype(left)>::value && is_signed<decltype(right)>::value)
return i128(left) ^ i128(right);
else
return u128(left) ^ u128(right);
}

FLOAT_BIT_OPERATION(bitNot) {
Expand All @@ -62,7 +77,10 @@ namespace pl::core::ast {
}

FLOAT_BIT_OPERATION(modulus) {
return left % right;
if constexpr (is_signed<decltype(left)>::value && is_signed<decltype(right)>::value)
return i128(left) % i128(right);
else
return u128(left) % u128(right);
}

#undef FLOAT_BIT_OPERATION
Expand Down
4 changes: 2 additions & 2 deletions lib/include/pl/core/tokens.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
namespace pl::core::tkn {

static const inline std::map<std::string_view, Token::Literal> constants = {
{ "true", Token::Literal(1) },
{ "false", Token::Literal(0) },
{ "true", Token::Literal(true) },
{ "false", Token::Literal(false) },
{ "nan", Token::Literal(std::numeric_limits<double>::quiet_NaN()) },
{ "inf", Token::Literal(std::numeric_limits<double>::infinity()) },
};
Expand Down
42 changes: 39 additions & 3 deletions lib/include/pl/helpers/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@

#include <cstddef>
#include <cstdint>
#include <wolv/types/uintwide_t.h>

namespace pl {

using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;
using u128 = __uint128_t;
using u128 = ::math::wide_integer::uint128_t;

using i8 = std::int8_t;
using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;
using i128 = ::math::wide_integer::int128_t;;

struct Region {
u64 address;
Expand All @@ -29,4 +30,39 @@ namespace pl {
Return
};

}
namespace hlp
{
[[nodiscard]] std::string to_string(u128 value);
[[nodiscard]] std::string to_string(i128 value);
[[nodiscard]] std::string to_hex_string(u128 value);
[[nodiscard]] std::string to_hex_string(i128 value);
}

}


#include <fmt/format.h>

template<>
struct fmt::formatter<pl::u128>
{
constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
return fmt::formatter<uint64_t>().parse(ctx);
}

auto format(const pl::u128& v, format_context& ctx) const {
return format_to(ctx.out(), "u128({})", pl::hlp::to_string(v));
}
};

template<>
struct fmt::formatter<pl::i128>
{
constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
return fmt::formatter<int64_t>().parse(ctx);
}

auto format(const pl::i128& v, format_context& ctx) const {
return format_to(ctx.out(), "i128({})", pl::hlp::to_string(v));
}
};
4 changes: 3 additions & 1 deletion lib/include/pl/helpers/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ namespace pl::hlp {

[[nodiscard]] std::string to_string(u128 value);
[[nodiscard]] std::string to_string(i128 value);
[[nodiscard]] std::string to_hex_string(u128 value);
[[nodiscard]] std::string to_hex_string(i128 value);

[[nodiscard]] std::vector<u8> toMinimalBytes(const auto &value) {
auto bytesArray = wolv::util::toBytes(value);
Expand Down Expand Up @@ -53,7 +55,7 @@ namespace pl::hlp {
u32 stringCrc32(const std::string &str);

[[nodiscard]] constexpr inline i128 signExtend(size_t numBits, i128 value) {
i128 mask = u128(1) << u128(numBits - 1);
i128 mask = u128(1) << (numBits - 1);
return (value ^ mask) - mask;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/include/pl/lib/std/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace pl::lib::libstd::types {

struct Endian {
Endian(u128 value) {
switch (value) {
switch (u64(value)) {
case 0: this->m_endian = std::endian::native; break;
case 1: this->m_endian = std::endian::big; break;
case 2: this->m_endian = std::endian::little; break;
Expand Down
26 changes: 14 additions & 12 deletions lib/include/pl/patterns/pattern_bitfield.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ namespace pl::ptrn {

std::string formatDisplayValue() override {
auto rawValue = this->readValue();
auto value = hlp::signExtend(this->getBitSize(), rawValue);
auto value = hlp::signExtend(this->getBitSize(), i128(rawValue));
return Pattern::callUserFormatFunc(value).value_or(fmt::format("{}", value));
}

Expand All @@ -205,11 +205,13 @@ namespace pl::ptrn {
}

std::string formatDisplayValue() override {
switch (this->getValue().toUnsigned()) {
case 0: return "false";
case 1: return "true";
default: return "true*";
}
auto value = this->getValue().toUnsigned();
if (value == 0)
return "false";
else if (value == 1)
return "true";
else
return "true*";
}

[[nodiscard]] std::string toString() const override {
Expand Down Expand Up @@ -273,7 +275,7 @@ namespace pl::ptrn {
public IIndexable {
public:
PatternBitfieldArray(core::Evaluator *evaluator, u64 offset, u8 firstBitOffset, u128 totalBitSize, u32 line)
: PatternBitfieldMember(evaluator, offset, (totalBitSize + 7) / 8, line), m_firstBitOffset(firstBitOffset), m_totalBitSize(totalBitSize) { }
: PatternBitfieldMember(evaluator, offset, size_t((totalBitSize + 7) / 8), line), m_firstBitOffset(firstBitOffset), m_totalBitSize(totalBitSize) { }

PatternBitfieldArray(const PatternBitfieldArray &other) : PatternBitfieldMember(other) {
std::vector<std::shared_ptr<Pattern>> entries;
Expand Down Expand Up @@ -308,11 +310,11 @@ namespace pl::ptrn {

void setBitSize(u128 bitSize) {
this->m_totalBitSize = bitSize;
this->setSize((bitSize + 7) / 8);
this->setSize(size_t((bitSize + 7) / 8));
}

[[nodiscard]] u64 getBitSize() const override {
return this->m_totalBitSize;
return u64(this->m_totalBitSize);
}

[[nodiscard]] bool isReversed() const {
Expand Down Expand Up @@ -557,7 +559,7 @@ namespace pl::ptrn {
public IIterable {
public:
PatternBitfield(core::Evaluator *evaluator, u64 offset, u8 firstBitOffset, u128 totalBitSize, u32 line)
: PatternBitfieldMember(evaluator, offset, (totalBitSize + 7) / 8, line), m_firstBitOffset(firstBitOffset), m_totalBitSize(totalBitSize) { }
: PatternBitfieldMember(evaluator, offset, size_t((totalBitSize + 7) / 8), line), m_firstBitOffset(firstBitOffset), m_totalBitSize(totalBitSize) { }

PatternBitfield(const PatternBitfield &other) : PatternBitfieldMember(other) {
for (auto &field : other.m_fields)
Expand Down Expand Up @@ -589,8 +591,8 @@ namespace pl::ptrn {
}

void setBitSize(u128 bitSize) {
this->m_totalBitSize = bitSize;
this->setSize((bitSize + 7) / 8);
this->m_totalBitSize = u64(bitSize);
this->setSize(size_t((bitSize + 7) / 8));
}

[[nodiscard]] u64 getBitSize() const override {
Expand Down
11 changes: 6 additions & 5 deletions lib/include/pl/patterns/pattern_boolean.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ namespace pl::ptrn {
}

std::string formatDisplayValue() override {
switch (this->getValue().toUnsigned()) {
case 0: return "false";
case 1: return "true";
default: return "true*";
}
auto value = this->getValue().toUnsigned();
if (value == 0)
return "false";
if (value == 1)
return "true";
return "true*";
}

[[nodiscard]] bool operator==(const Pattern &other) const override { return compareCommonProperties<decltype(*this)>(other); }
Expand Down
8 changes: 4 additions & 4 deletions lib/include/pl/patterns/pattern_pointer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ namespace pl::ptrn {
void setPointedAtPattern(std::shared_ptr<Pattern> &&pattern) {
this->m_pointedAt = std::move(pattern);
this->m_pointedAt->setVariableName(fmt::format("*({})", this->getVariableName()));
this->m_pointedAt->setOffset(this->m_pointedAtAddress);
this->m_pointedAt->setOffset(u64(this->m_pointedAtAddress));

if (this->hasOverriddenColor())
this->m_pointedAt->setColor(this->getColor());
Expand Down Expand Up @@ -129,7 +129,7 @@ namespace pl::ptrn {
this->m_pointerBase = base;

if (this->m_pointedAt != nullptr) {
this->m_pointedAt->setOffset(this->m_pointedAtAddress);
this->m_pointedAt->setOffset(u64(this->m_pointedAtAddress));
}
}

Expand All @@ -148,8 +148,8 @@ namespace pl::ptrn {
}

std::string formatDisplayValue() override {
auto data = this->getValue().toSigned();
return Pattern::callUserFormatFunc(this->getValue()).value_or(fmt::format("*(0x{0:X})", data));
auto value = this->getValue();
return Pattern::callUserFormatFunc(value).value_or(hlp::to_hex_string(value.toSigned()));
}

[[nodiscard]] std::string toString() const override {
Expand Down
2 changes: 1 addition & 1 deletion lib/include/pl/patterns/pattern_wide_character.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace pl::ptrn {

[[nodiscard]] std::string toString() const override {
auto value = this->getValue();
char16_t character = value.toUnsigned();
char16_t character = char16_t(value.toUnsigned());
character = hlp::changeEndianess(character, this->getEndian());

auto result = wolv::util::utf16ToUtf8(std::u16string(&character, 1));
Expand Down
20 changes: 10 additions & 10 deletions lib/source/pl/core/ast/ast_node_array_variable_decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ namespace pl::core::ast {
if (id == nullptr)
err::E0010.throwError("Cannot use void expression as section identifier.", {}, this->getLocation());

evaluator->pushSectionId(id->getValue().toUnsigned());
evaluator->pushSectionId(u64(id->getValue().toUnsigned()));
} else {
scopeGuard.release();
}
Expand All @@ -69,7 +69,7 @@ namespace pl::core::ast {
evaluator->setReadOffset(std::visit(wolv::util::overloaded {
[this](const std::string &) -> u64 { err::E0005.throwError("Cannot use string as placement offset.", "Try using a integral value instead.", this->getLocation()); },
[this](const std::shared_ptr<ptrn::Pattern>&) -> u64 { err::E0005.throwError("Cannot use string as placement offset.", "Try using a integral value instead.", this->getLocation()); },
[](auto &&offset) -> u64 { return offset; }
[](auto &&offset) -> u64 { return u64(offset); }
}, offset->getValue()));
}

Expand Down Expand Up @@ -122,7 +122,7 @@ namespace pl::core::ast {
auto entryCount = std::visit(wolv::util::overloaded {
[this](const std::string &) -> i128 { err::E0006.throwError("Cannot use string to index array.", "Try using an integral type instead.", this->getLocation()); },
[this](const std::shared_ptr<ptrn::Pattern> &pattern) -> i128 {err::E0006.throwError(fmt::format("Cannot use custom type '{}' to index array.", pattern->getTypeName()), "Try using an integral type instead.", this->getLocation()); },
[](auto &&size) -> i128 { return size; }
[](auto &&size) -> i128 { return i128(size); }
}, sizeLiteral->getValue());

u64 section = 0;
Expand All @@ -132,20 +132,20 @@ namespace pl::core::ast {
if (sectionLiteral == nullptr)
err::E0002.throwError("Cannot use void expression as section identifier.", {}, this->getLocation());

section = sectionLiteral->getValue().toUnsigned();
section = u64(sectionLiteral->getValue().toUnsigned());
} else {
section = evaluator->getSectionId();
}

evaluator->createArrayVariable(this->m_name, this->m_type.get(), entryCount, section, this->m_constant);
evaluator->createArrayVariable(this->m_name, this->m_type.get(), size_t(entryCount), section, this->m_constant);

if (this->m_placementOffset != nullptr) {
const auto placementNode = this->m_placementOffset->evaluate(evaluator);
const auto offsetLiteral = dynamic_cast<ASTNodeLiteral *>(placementNode.get());
if (offsetLiteral == nullptr)
err::E0002.throwError("Void expression used in placement expression.", { }, this->getLocation());

evaluator->setVariableAddress(this->getName(), offsetLiteral->getValue().toUnsigned(), section);
evaluator->setVariableAddress(this->getName(), u64(offsetLiteral->getValue().toUnsigned()), section);
}

return std::nullopt;
Expand Down Expand Up @@ -176,7 +176,7 @@ namespace pl::core::ast {
entryCount = std::visit(wolv::util::overloaded {
[this](const std::string &) -> i128 { err::E0006.throwError("Cannot use string to index array.", "Try using an integral type instead.", this->getLocation()); },
[this](const std::shared_ptr<ptrn::Pattern> &pattern) -> i128 {err::E0006.throwError(fmt::format("Cannot use custom type '{}' to index array.", pattern->getTypeName()), "Try using an integral type instead.", this->getLocation()); },
[](auto &&size) -> i128 { return size; }
[](auto &&size) -> i128 { return i128(size); }
}, literal->getValue());
} else if (auto whileStatement = dynamic_cast<ASTNodeWhileStatement *>(sizeNode.get())) {
while (whileStatement->evaluateCondition(evaluator)) {
Expand Down Expand Up @@ -225,7 +225,7 @@ namespace pl::core::ast {
outputPattern = std::make_unique<ptrn::PatternWideString>(evaluator, startOffset, 0, getLocation().line);
} else {
auto arrayPattern = std::make_unique<ptrn::PatternArrayStatic>(evaluator, startOffset, 0, getLocation().line);
arrayPattern->setEntries(templatePattern->clone(), entryCount);
arrayPattern->setEntries(templatePattern->clone(), size_t(entryCount));
arrayPattern->setSection(templatePattern->getSection());
outputPattern = std::move(arrayPattern);
}
Expand All @@ -234,7 +234,7 @@ namespace pl::core::ast {
if (templatePattern->hasOverriddenEndian())
outputPattern->setEndian(templatePattern->getEndian());
outputPattern->setTypeName(templatePattern->getTypeName());
outputPattern->setSize(templatePattern->getSize() * entryCount);
outputPattern->setSize(size_t(templatePattern->getSize() * entryCount));
if (evaluator->isReadOrderReversed())
outputPattern->setAbsoluteOffset(evaluator->getReadOffset());
outputPattern->setSection(templatePattern->getSection());
Expand Down Expand Up @@ -305,7 +305,7 @@ namespace pl::core::ast {
auto entryCount = std::visit(wolv::util::overloaded {
[this](const std::string &) -> u128 { err::E0006.throwError("Cannot use string to index array.", "Try using an integral type instead.", this->getLocation()); },
[this](const std::shared_ptr<ptrn::Pattern> &pattern) -> u128 {err::E0006.throwError(fmt::format("Cannot use custom type '{}' to index array.", pattern->getTypeName()), "Try using an integral type instead.", this->getLocation()); },
[](auto &&size) -> u128 { return size; }
[](auto &&size) -> u128 { return u128(size); }
}, literal->getValue());

auto limit = evaluator->getArrayLimit();
Expand Down
Loading

0 comments on commit 4b98a8d

Please sign in to comment.