From d6f553a794efa8fda5b530e096fe89d223531477 Mon Sep 17 00:00:00 2001 From: Alexander McCord Date: Sun, 26 May 2024 13:11:38 -0700 Subject: [PATCH] Sketch out Language a little bit. Still WIP. --- EqSat/include/Luau/EGraph.h | 2 +- EqSat/include/Luau/Language.h | 63 +++++++++++++++++++++++++++++++++-- Sources.cmake | 2 ++ tests/EqSat.language.test.cpp | 26 +++++++++++++++ 4 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 tests/EqSat.language.test.cpp diff --git a/EqSat/include/Luau/EGraph.h b/EqSat/include/Luau/EGraph.h index 48f3a32a..21932f9d 100644 --- a/EqSat/include/Luau/EGraph.h +++ b/EqSat/include/Luau/EGraph.h @@ -57,7 +57,7 @@ private: std::unordered_map> classes; /// The hashcons 𝐻 is a map from e-nodes to e-class ids. - std::unordered_map hashcons; + std::unordered_map hashcons; }; } // namespace Luau::EqSat diff --git a/EqSat/include/Luau/Language.h b/EqSat/include/Luau/Language.h index e36b7611..bd4bd9d9 100644 --- a/EqSat/include/Luau/Language.h +++ b/EqSat/include/Luau/Language.h @@ -1,12 +1,71 @@ // This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details #pragma once +#include +#include +#include + namespace Luau::EqSat { -struct Language -{ +#define LUAU_EQSAT_ATOM(name, value) LUAU_EQSAT_ATOM_CUSTOM(name, #name, value) +#define LUAU_EQSAT_ATOM_CUSTOM(name, custom, value) \ + struct name : public ::Luau::EqSat::Atom \ + { \ + static constexpr const char* tag = custom; \ + } +template +struct Atom +{ + T value; +}; + +// `Language` is very similar to `Luau::Variant` with enough differences warranting a different type altogether. +// +// Firstly, where `Luau::Variant` uses an `int` to decide which type the variant currently holds, we use +// a `const char*` instead. We use the pointer address for tag checking, and the string buffer for stringification. +// +// Secondly, we need `Language` to have additional methods such as: +// - `children()` to get child operands, +// - `operator==` to decide equality, and +// - `hash()` function. +// +// And finally, each `T` in `Ts` have additional requirements which `Luau::Variant` doesn't need. +template +class Language +{ + const char* tag; + char buffer[std::max({sizeof(Ts)...})]; + +public: + template + Language(T&& t) + { + using TT = std::decay_t; + static_assert(std::disjunction_v...>); + + tag = T::tag; + new (&buffer) TT(std::forward(t)); + } + + template + const T* get() const + { + static_assert(std::disjunction_v, Ts>...>); + + return tag == T::tag ? reinterpret_cast(&buffer) : nullptr; + } + +public: + struct Hash + { + size_t operator()(const Language& lang) + { + // TODO. Currently here so I can build and test this project. + return 0; + } + }; }; } // namespace Luau::EqSat diff --git a/Sources.cmake b/Sources.cmake index 8601fa28..89da27ca 100644 --- a/Sources.cmake +++ b/Sources.cmake @@ -429,6 +429,8 @@ if(TARGET Luau.UnitTest) tests/DiffAsserts.cpp tests/DiffAsserts.h tests/Differ.test.cpp + tests/EqSat.language.test.cpp + tests/EqSat.propositional.test.cpp tests/Error.test.cpp tests/Fixture.cpp tests/Fixture.h diff --git a/tests/EqSat.language.test.cpp b/tests/EqSat.language.test.cpp new file mode 100644 index 00000000..6977d50b --- /dev/null +++ b/tests/EqSat.language.test.cpp @@ -0,0 +1,26 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#include + +#include "Luau/Language.h" + +LUAU_EQSAT_ATOM(Atom1, bool); +LUAU_EQSAT_ATOM(Atom2, bool); + +using namespace Luau; + +using Mini = EqSat::Language; + +TEST_SUITE_BEGIN("EqSatLanguage"); + +TEST_CASE("language_get_works") +{ + Mini m{Atom1{true}}; + + const Atom1* atom = m.get(); + REQUIRE(atom); + CHECK(atom->value); + + CHECK(!m.get()); +} + +TEST_SUITE_END();