diff --git a/nautilus/include/nautilus/val_concepts.hpp b/nautilus/include/nautilus/val_concepts.hpp index b987d600..c4195715 100644 --- a/nautilus/include/nautilus/val_concepts.hpp +++ b/nautilus/include/nautilus/val_concepts.hpp @@ -20,11 +20,11 @@ concept convertible_to_integral = (std::is_convertible_v || std::is_conv template concept is_fundamental_val = requires { typename std::remove_reference_t::basic_type; // Ensure T has a member type 'basic_type' - requires std::is_fundamental_v::basic_type>; // Ensure 'basic_type' is integral + requires !std::is_enum_v::basic_type> && std::is_fundamental_v::basic_type>; // Ensure 'basic_type' is integral }; template -concept convertible_to_fundamental = !is_fundamental_val && (convertible_to_integral || std::is_convertible_v || std::is_convertible_v || std::is_convertible_v); +concept convertible_to_fundamental = !std::is_enum_v && !is_fundamental_val && (convertible_to_integral || std::is_convertible_v || std::is_convertible_v || std::is_convertible_v); template concept is_arithmetic = std::is_arithmetic_v; diff --git a/nautilus/include/nautilus/val_enum.hpp b/nautilus/include/nautilus/val_enum.hpp index 03cfdb25..020ee8f6 100644 --- a/nautilus/include/nautilus/val_enum.hpp +++ b/nautilus/include/nautilus/val_enum.hpp @@ -3,6 +3,7 @@ #include "nautilus/val_concepts.hpp" #include #include +#include #ifdef ENABLE_TRACING @@ -20,21 +21,80 @@ class val { using raw_type = underlying_type_t; using basic_type = raw_type; - val() : value() {} - #ifdef ENABLE_TRACING - val(val t) : state(t.state), value((T) details::getRawValue(t)) {} - val(val& t) : state(tracing::traceCopy(t.state)), value(t.value) {} - val(val&& t) : state(t.state), value(t.value) {} - val(T val) : state(tracing::traceConstant((underlying_type_t) val)), value(val) {} + template + requires std::is_enum_v && (!std::is_convertible_v>) + val(T val) : state(tracing::traceConstant(static_cast>(val))), value(static_cast>(val)) { + } + + template + requires std::is_enum_v && (!std::is_convertible_v>) + val(val& val) : state(tracing::traceConstant(static_cast>(val))), value(static_cast>(val)) { + } + val(val t) : state(t.state), value((T) details::getRawValue(t)) { + } + val(val& t) : state(tracing::traceCopy(t.state)), value(t.value) { + } + val(val&& t) : state(t.state), value(t.value) { + } + val(T val) : state(tracing::traceConstant(static_cast>(val))), value(val) { + } #else - val(val t) : value((T) details::getRawValue(t)) {} - val(val& t) : value(t.value) {} - val(T val) : value(val) {} + template + requires std::is_enum_v && (!std::is_convertible_v>) + val(T val) : value(static_cast>(val)) { + } + + template + requires std::is_enum_v && (!std::is_convertible_v>) + val(val& val) : value(static_cast>(val)) { + } + + val(val t) : value((T) details::getRawValue(t)) { + } + val(val& t) : value(t.value) { + } + val(T val) : value(val) { + } #endif + + val operator==(val& other) const { +#ifdef ENABLE_TRACING + if (tracing::inTracer()) { + auto tc = tracing::traceBinaryOp(tracing::EQ, Type::b, state, other.state); + return val(tc); + } +#endif + return value == other.value; + } + + val operator==(const T& other) const { + auto res = val(other); + return *this == res; + } + + val operator!=(val& other) const { +#ifdef ENABLE_TRACING + if (tracing::inTracer()) { + auto tc = tracing::traceBinaryOp(tracing::NEQ, Type::b, state, other.state); + return val(tc); + } +#endif + return value != other.value; + } + + val operator!=(const T& other) const { + return *this == val(other); + } + operator val() const { - return value; +#ifdef ENABLE_TRACING + if (tracing::inTracer()) { + return val(state); + } +#endif + return val(static_cast>(value)); } val& operator=(const val& other) { @@ -56,4 +116,10 @@ class val { const T value; }; +template +requires std::is_enum_v +auto inline make_value(const Type& value) { + return val(value); +} + } // namespace nautilus diff --git a/nautilus/test/common/EnumFunction.hpp b/nautilus/test/common/EnumFunction.hpp index c37e9bdb..1349b7fa 100644 --- a/nautilus/test/common/EnumFunction.hpp +++ b/nautilus/test/common/EnumFunction.hpp @@ -1,15 +1,22 @@ #pragma once #include +#include namespace nautilus { enum Color { BLUE, GREEN }; +enum class LogLevel : uint8_t { LOG_NONE = 1, LOG_FATAL_ERROR = 2, LOG_ERROR = 3, LOG_WARNING = 4, LOG_INFO = 5, LOG_DEBUG = 6, LOG_TRACE = 7 }; + val handleEnum(val enumVal) { return enumVal == Color::BLUE; } +val handleEnumLogLevel(val enumVal) { + return enumVal == LogLevel::LOG_DEBUG || enumVal == LogLevel::LOG_INFO; +} + val isEnum(val enumVal) { if (enumVal == Color::BLUE) { return 1; @@ -33,7 +40,32 @@ int32_t enumFunction(Color value) { } } +auto enumClassFunction(LogLevel level) { + switch (level) { + case LogLevel::LOG_NONE: + return 1; + case LogLevel::LOG_FATAL_ERROR: + return 2; + case LogLevel::LOG_ERROR: + return 3; + case LogLevel::LOG_WARNING: + return 4; + case LogLevel::LOG_INFO: + return 5; + case LogLevel::LOG_DEBUG: + return 6; + case LogLevel::LOG_TRACE: + return 7; + } + + return 43; +} + val callEnumFunction(val enumVal) { return invoke(enumFunction, enumVal); } -} // namespace nautilus \ No newline at end of file + +val callEnumClassFunction(val enumClassVal) { + return invoke(enumClassFunction, enumClassVal); +} +} // namespace nautilus diff --git a/nautilus/test/data/enum-tests/after_ssa/callEnumFunction.trace b/nautilus/test/data/enum-tests/after_ssa/callEnumFunction.trace deleted file mode 100644 index 584e7ea8..00000000 --- a/nautilus/test/data/enum-tests/after_ssa/callEnumFunction.trace +++ /dev/null @@ -1,3 +0,0 @@ -B0($1:ui32) - CALL $2 nautilus::enumFunction(nautilus::Color)($1) :i32 - RETURN $2 :i32 diff --git a/nautilus/test/data/enum-tests/after_ssa/getEnum.trace b/nautilus/test/data/enum-tests/after_ssa/getEnum.trace deleted file mode 100644 index c6d74556..00000000 --- a/nautilus/test/data/enum-tests/after_ssa/getEnum.trace +++ /dev/null @@ -1,3 +0,0 @@ -B0() - CONST $1 0 :ui32 - RETURN $1 :ui32 diff --git a/nautilus/test/data/enum-tests/after_ssa/handleEnum.trace b/nautilus/test/data/enum-tests/after_ssa/handleEnum.trace deleted file mode 100644 index cdf4dd64..00000000 --- a/nautilus/test/data/enum-tests/after_ssa/handleEnum.trace +++ /dev/null @@ -1,4 +0,0 @@ -B0($1:ui32) - CONST $2 0 :ui32 - EQ $3 $1 $2 :bool - RETURN $3 :bool diff --git a/nautilus/test/data/enum-tests/after_ssa/isEnum.trace b/nautilus/test/data/enum-tests/after_ssa/isEnum.trace deleted file mode 100644 index adc272c5..00000000 --- a/nautilus/test/data/enum-tests/after_ssa/isEnum.trace +++ /dev/null @@ -1,19 +0,0 @@ -B0($1:ui32) - CONST $2 0 :ui32 - EQ $3 $1 $2 :bool - CMP $4 $3 B1() B2($1) :void -B1() - CONST $5 1 :i32 - JMP $0 B5($5) :void -B2($1:ui32) - CONST $7 1 :ui32 - EQ $8 $1 $7 :bool - CMP $9 $8 B3() B4() :void -B3() - CONST $10 2 :i32 - JMP $0 B5($10) :void -B4() - CONST $12 42 :i32 - JMP $0 B5($12) :void -B5($5:i32) - RETURN $5 :i32 diff --git a/nautilus/test/data/enum-tests/ir/callEnumFunction.trace b/nautilus/test/data/enum-tests/ir/callEnumFunction.trace deleted file mode 100644 index e093ded3..00000000 --- a/nautilus/test/data/enum-tests/ir/callEnumFunction.trace +++ /dev/null @@ -1,7 +0,0 @@ -NautilusIr { -execute() { -Block_0($1:ui32): - $2 = nautilus::enumFunction(nautilus::Color)($1) :i32 - return ($2) :i32 -} -} //NESIR \ No newline at end of file diff --git a/nautilus/test/data/enum-tests/ir/getEnum.trace b/nautilus/test/data/enum-tests/ir/getEnum.trace deleted file mode 100644 index c8bab973..00000000 --- a/nautilus/test/data/enum-tests/ir/getEnum.trace +++ /dev/null @@ -1,7 +0,0 @@ -NautilusIr { -execute() { -Block_0(): - $1 = 0 :ui32 - return ($1) :ui32 -} -} //NESIR \ No newline at end of file diff --git a/nautilus/test/data/enum-tests/ir/handleEnum.trace b/nautilus/test/data/enum-tests/ir/handleEnum.trace deleted file mode 100644 index e33aad62..00000000 --- a/nautilus/test/data/enum-tests/ir/handleEnum.trace +++ /dev/null @@ -1,8 +0,0 @@ -NautilusIr { -execute() { -Block_0($1:ui32): - $2 = 0 :ui32 - $3 = $1 == $2 :bool - return ($3) :bool -} -} //NESIR \ No newline at end of file diff --git a/nautilus/test/data/enum-tests/ir/isEnum.trace b/nautilus/test/data/enum-tests/ir/isEnum.trace deleted file mode 100644 index 3c024daf..00000000 --- a/nautilus/test/data/enum-tests/ir/isEnum.trace +++ /dev/null @@ -1,28 +0,0 @@ -NautilusIr { -execute() { -Block_0($1:ui32): - $2 = 0 :ui32 - $3 = $1 == $2 :bool - if $3 ? Block_1() : Block_2($1) :void - -Block_1(): - $5 = 1 :i32 - br Block_5($5) :void - -Block_5($5:i32): - return ($5) :i32 - -Block_2($1:ui32): - $7 = 1 :ui32 - $8 = $1 == $7 :bool - if $8 ? Block_3() : Block_4() :void - -Block_3(): - $10 = 2 :i32 - br Block_5($10) :void - -Block_4(): - $12 = 42 :i32 - br Block_5($12) :void -} -} //NESIR \ No newline at end of file diff --git a/nautilus/test/data/enum-tests/tracing/callEnumFunction.trace b/nautilus/test/data/enum-tests/tracing/callEnumFunction.trace deleted file mode 100644 index 584e7ea8..00000000 --- a/nautilus/test/data/enum-tests/tracing/callEnumFunction.trace +++ /dev/null @@ -1,3 +0,0 @@ -B0($1:ui32) - CALL $2 nautilus::enumFunction(nautilus::Color)($1) :i32 - RETURN $2 :i32 diff --git a/nautilus/test/data/enum-tests/tracing/getEnum.trace b/nautilus/test/data/enum-tests/tracing/getEnum.trace deleted file mode 100644 index c6d74556..00000000 --- a/nautilus/test/data/enum-tests/tracing/getEnum.trace +++ /dev/null @@ -1,3 +0,0 @@ -B0() - CONST $1 0 :ui32 - RETURN $1 :ui32 diff --git a/nautilus/test/data/enum-tests/tracing/handleEnum.trace b/nautilus/test/data/enum-tests/tracing/handleEnum.trace deleted file mode 100644 index cdf4dd64..00000000 --- a/nautilus/test/data/enum-tests/tracing/handleEnum.trace +++ /dev/null @@ -1,4 +0,0 @@ -B0($1:ui32) - CONST $2 0 :ui32 - EQ $3 $1 $2 :bool - RETURN $3 :bool diff --git a/nautilus/test/data/enum-tests/tracing/isEnum.trace b/nautilus/test/data/enum-tests/tracing/isEnum.trace deleted file mode 100644 index 3f4ff1ad..00000000 --- a/nautilus/test/data/enum-tests/tracing/isEnum.trace +++ /dev/null @@ -1,17 +0,0 @@ -B0($1:ui32) - CONST $2 0 :ui32 - EQ $3 $1 $2 :bool - CMP $4 $3 B1() B2() :void -B1() - CONST $5 1 :i32 - RETURN $5 :i32 -B2() - CONST $7 1 :ui32 - EQ $8 $1 $7 :bool - CMP $9 $8 B3() B4() :void -B3() - CONST $10 2 :i32 - RETURN $10 :i32 -B4() - CONST $12 42 :i32 - RETURN $12 :i32 diff --git a/nautilus/test/execution-tests/ExecutionTest.cpp b/nautilus/test/execution-tests/ExecutionTest.cpp index 984d554c..9cb7a037 100644 --- a/nautilus/test/execution-tests/ExecutionTest.cpp +++ b/nautilus/test/execution-tests/ExecutionTest.cpp @@ -86,6 +86,19 @@ void expressionTests(engine::NautilusEngine& engine) { REQUIRE(f((char) CHAR_MIN) == (char) CHAR_MAX); } + SECTION("callEnumClassFunction") { + auto f = engine.registerFunction(callEnumClassFunction); + REQUIRE(f(LogLevel::LOG_DEBUG) == 6); + REQUIRE(f(LogLevel::LOG_NONE) == 1); + } + + SECTION("handleEnumLogLevel") { + auto f = engine.registerFunction(handleEnumLogLevel); + REQUIRE(f(LogLevel::LOG_INFO)); + REQUIRE(f(LogLevel::LOG_DEBUG)); + REQUIRE(!f(LogLevel::LOG_NONE)); + } + SECTION("callEnumFunction") { auto f = engine.registerFunction(callEnumFunction); REQUIRE(f(Color::BLUE) == 42); diff --git a/nautilus/test/execution-tests/TracingTest.cpp b/nautilus/test/execution-tests/TracingTest.cpp index 0c1ac692..cc95b102 100644 --- a/nautilus/test/execution-tests/TracingTest.cpp +++ b/nautilus/test/execution-tests/TracingTest.cpp @@ -135,8 +135,8 @@ void runTraceTests(const std::string& category, std::vector(test); auto name = std::get<0>(test); - auto executionTrace = tracing::TraceContext::trace(func); DYNAMIC_SECTION(name) { + auto executionTrace = tracing::TraceContext::trace(func); DYNAMIC_SECTION("tracing") { REQUIRE(checkTestFile(executionTrace.get(), category, "tracing", name)); } @@ -276,6 +276,8 @@ TEST_CASE("Enum Trace Test") { {"isEnum", details::createFunctionWrapper(isEnum)}, {"getEnum", details::createFunctionWrapper(getEnum)}, {"callEnumFunction", details::createFunctionWrapper(callEnumFunction)}, + {"callEnumClassFunction", details::createFunctionWrapper(callEnumClassFunction)}, + {"handleEnumLogLevel", details::createFunctionWrapper(handleEnumLogLevel)}, }; runTraceTests("enum-tests", tests); }