diff --git a/nautilus-api/include/Interface/function.hpp b/nautilus-api/include/Interface/function.hpp index 38a218e5..d770ca19 100644 --- a/nautilus-api/include/Interface/function.hpp +++ b/nautilus-api/include/Interface/function.hpp @@ -1,11 +1,11 @@ #include #include "DataTypes/Val.hpp" + #pragma once namespace nautilus { - template class CallableNautilusFunction { public: @@ -46,9 +46,7 @@ namespace nautilus { template class CallableRuntimeFunction { public: - CallableRuntimeFunction(R (*fnptr)(FunctionArguments...)) : fnptr(fnptr) { - - }; + explicit CallableRuntimeFunction(R (*fnptr)(FunctionArguments...)) : fnptr(fnptr) {}; template auto transform(Arg argument) { @@ -56,10 +54,18 @@ namespace nautilus { } template + requires (!std::is_void_v) auto operator()(FunctionArgumentsRaw... args) { // function is called from an external context. auto result = fnptr(transform((args))...); - return make_value(result); + return make_value(result); + } + + template + requires std::is_void_v + void operator()(FunctionArgumentsRaw... args) { + // function is called from an external context. + fnptr(transform((args))...); } template @@ -71,13 +77,54 @@ namespace nautilus { R (*fnptr)(FunctionArguments...); }; + template + class MemberFunction { + public: + MemberFunction(TP _Class::* __pm) : __pm(__pm) {} + + template + auto transform(Arg argument) { + return details::getRawValue(argument); + } + + template + val operator()(_Class *mem, FunctionArgumentsRaw... args) { + // we are in the nautilus context + // keep current tracing context and continue tracing + // TODO implement polymorphic inline cache + // TODO pass member as val + auto result = std::invoke(__pm, mem, transform((args))...); + return make_value(result); + } + + TP _Class::* __pm; + }; + - template + template auto invoke(R (*fnptr)(FunctionArguments...), ValueArguments... args) { return CallableRuntimeFunction(fnptr)(args...); } + template + void invoke(void (*fnptr)(FunctionArguments...), ValueArguments... args) { + auto func = CallableRuntimeFunction(fnptr); + func(args...); + } + + template + auto + invoke(TP _Class::* __pm, _Class *mem, ValueArguments... args) { + auto member = MemberFunction(__pm); + return member(mem, args...); + } + + template + auto Function(TP _Class::* __pm) noexcept { + return MemberFunction(__pm); + } + template constexpr bool is_reference_wrapper_v = false; @@ -95,27 +142,6 @@ namespace nautilus { return CallableNautilusFunction(fnptr); } - template - class MemberFunction { - public: - MemberFunction(TP _Class::* __pm) : __pm(__pm) {} - template - auto operator()(_Class *mem, FunctionArgumentsRaw... args) { - // we are in the nautilus context - // keep current tracing context and continue tracing - // TODO implement polymorphic inline cache - return std::invoke(__pm, mem, (args)...); - // return __pm(mem, (args)...); - } - - - TP _Class::* __pm; - }; - - template - auto Function(TP _Class::* __pm) noexcept { - return MemberFunction(__pm); - } } diff --git a/nautilus-api/test/ExecutionTests/Executions.cpp b/nautilus-api/test/ExecutionTests/Executions.cpp index b516348f..c291f329 100644 --- a/nautilus-api/test/ExecutionTests/Executions.cpp +++ b/nautilus-api/test/ExecutionTests/Executions.cpp @@ -133,11 +133,27 @@ namespace nautilus::engine { } void functionCallExecutionTest(engine::NautilusEngine &engine) { - SECTION("sumLoop") { + SECTION("simpleDirectCall") { auto f = engine.registerFunction(simpleDirectCall); REQUIRE(f(10, 10) == 20); REQUIRE(f(0, 1) == 1); + } SECTION("loopDirectCall") { + auto f = engine.registerFunction(loopDirectCall); + REQUIRE(f(10, 10) == 100); + REQUIRE(f(1, 1) == 1); + REQUIRE(f(0, 1) == 0); + }SECTION("voidCall") { + auto f = engine.registerFunction(voidFuncCall); + REQUIRE(f(10, 10) == 10); + REQUIRE(f(0, 1) == 0); + }SECTION("memberFuncCall") { + auto f = engine.registerFunction(memberFuncCall); + REQUIRE(f(10) == 52); + }SECTION("constMemberFuncCall") { + auto f = engine.registerFunction(constMemberFuncCall); + REQUIRE(f(10) == 52); } + } TEMPLATE_TEST_CASE("Engine Test", "[value][template]", int8_t) { diff --git a/nautilus-api/test/ExecutionTests/RunctimeCallFunctions.hpp b/nautilus-api/test/ExecutionTests/RunctimeCallFunctions.hpp index 6d8fa730..c4a2d71c 100644 --- a/nautilus-api/test/ExecutionTests/RunctimeCallFunctions.hpp +++ b/nautilus-api/test/ExecutionTests/RunctimeCallFunctions.hpp @@ -1,7 +1,13 @@ #pragma once + #include + namespace nautilus::engine { + void voidFunc(int32_t x, int32_t y) { + [[maybe_unused]]auto z = x + y; + } + int32_t add(int32_t x, int32_t y) { return x + y; } @@ -10,5 +16,40 @@ namespace nautilus::engine { return invoke<>(add, x, y); } + val loopDirectCall(val c, val x) { + val sum = 0; + for (val i = 0; i < c; i++) { + sum = invoke<>(add, sum, x); + } + return sum; + } + + val voidFuncCall(val x, val y) { + invoke<>(voidFunc, x, y); + return x; + } + + class Clazz { + public: + int32_t add(int32_t x) { + return x + i; + } + + int32_t addConst(int32_t x) const { + return x + i; + } + + int i = 42; + }; + + static auto clazz = Clazz(); + + val memberFuncCall(val x) { + return invoke<>(&Clazz::add, &clazz, x); + } + + val constMemberFuncCall(val x) { + return invoke<>(&Clazz::addConst, &clazz, x); + } }