Skip to content

Commit

Permalink
feat: equals for hashes and arrays (#102)
Browse files Browse the repository at this point in the history
  • Loading branch information
hrzlgnm authored Dec 14, 2024
1 parent d020ad4 commit 2d0464e
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 8 deletions.
5 changes: 5 additions & 0 deletions source/eval/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ auto builtin_object::inspect() const -> std::string
return fmt::format("builtin {}(){{...}}", builtin->name);
}

auto function_object::inspect() const -> std::string
{
return callable->string();
}

namespace
{
const boolean_object false_obj {/*val=*/false};
Expand Down
28 changes: 23 additions & 5 deletions source/eval/object.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <algorithm>
#include <cstdint>
#include <string>
#include <unordered_map>
Expand Down Expand Up @@ -208,8 +209,15 @@ struct array_object : object

[[nodiscard]] auto equals_to(const object* other) const -> bool override
{
// FIXME:
return other->is(type()) && other->as<array_object>()->elements.size() == elements.size();
if (!other->is(type()) || other->as<array_object>()->elements.size() != elements.size()) {
return false;
}
const auto& other_elements = other->as<array_object>()->elements;
return std::equal(elements.cbegin(),
elements.cend(),
other_elements.cbegin(),
other_elements.cend(),
[](const object* a, const object* b) { return a->equals_to(b); });
}

array elements;
Expand All @@ -230,8 +238,18 @@ struct hash_object : object

[[nodiscard]] auto equals_to(const object* other) const -> bool override
{
// FIXME:
return other->is(type()) && other->as<hash_object>()->pairs.size() == pairs.size();
if (!other->is(type()) || other->as<hash_object>()->pairs.size() != pairs.size()) {
return false;
}
const auto& other_pairs = other->as<hash_object>()->pairs;
return std::all_of(pairs.cbegin(),
pairs.cend(),
[other_pairs](const auto& pair)
{
const auto& [key, value] = pair;
auto it = other_pairs.find(key);
return it != other_pairs.cend() && it->second->equals_to(value);
});
}

hash pairs;
Expand All @@ -249,7 +267,7 @@ struct function_object : object

[[nodiscard]] auto type() const -> object_type override { return object_type::function; }

[[nodiscard]] auto inspect() const -> std::string override { return "todo"; }
[[nodiscard]] auto inspect() const -> std::string override;

const callable_expression* callable {};
environment* closure_env {};
Expand Down
11 changes: 8 additions & 3 deletions source/vm/vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ auto vm::run() -> void
case opcodes::jump_not_truthy: {
auto pos = read_uint16_big_endian(code, instr_ptr + 1UL);
current_frame().ip += 2;
auto condition = pop();
const auto* condition = pop();
if (!condition->is_truthy()) {
current_frame().ip = pos - 1;
}
Expand All @@ -88,7 +88,7 @@ auto vm::run() -> void
case opcodes::array: {
auto num_elements = read_uint16_big_endian(code, instr_ptr + 1UL);
current_frame().ip += 2;
auto arr = build_array(m_sp - num_elements, m_sp);
auto* arr = build_array(m_sp - num_elements, m_sp);
m_sp -= num_elements;
push(arr);
} break;
Expand Down Expand Up @@ -583,7 +583,7 @@ auto run(std::array<vt<Expecteds...>, N> tests)
auto mchn = vm::create(std::move(byte_code));
mchn.run();

auto top = mchn.last_popped();
const auto* top = mchn.last_popped();
require_eq(expected, top, input);
}
}
Expand Down Expand Up @@ -652,7 +652,12 @@ TEST_CASE("booleanExpressions")
vt<bool> {R"(!!false)", false},
vt<bool> {R"(!!5)", true},
vt<bool> {R"(!(if (false) { 5; }))", true},
vt<bool> {R"(["a", 1] == ["b", 1])", false},
vt<bool> {R"({"a": 1} == {"b": 1})", false},
vt<bool> {R"(["a", 1] == ["a", 1])", true},
vt<bool> {R"({"a": 1} == {"a": 1})", true},
};

run(tests);
}

Expand Down

0 comments on commit 2d0464e

Please sign in to comment.