wrenpp/test/unit/main.cpp

125 lines
3.4 KiB
C++

#include "wrenpp/vm_fun.hpp"
#include "wrenpp/def_configuration.hpp"
#include <iostream>
#include <string_view>
#include <map>
#include <string>
#include <functional>
namespace {
const constexpr char g_script[] = ""
R"script(class Maths {
foreign static mul(a,b)
foreign static div(a,b)
foreign static sum(a,b)
foreign static sub(a,b)
}
var my_mul = Maths.mul(Maths.mul(2, 2), Maths.mul(3, 2)) - 4
System.print("my_mul = %(my_mul) (expected: 20)")
var my_sum = Maths.sum(Maths.sum(3, 4), Maths.sum(5, -1)) + 8
System.print("my_sum = %(my_sum) (expected: 19)")
var my_sub = Maths.sub(Maths.sub(8, 5), Maths.sub(20, 19)) + 1
System.print("my_sub = %(my_sub) (expected: 3)")
)script";
const constexpr char g_script_2[] = ""
R"script(class Maths {
foreign static mul(a,b)
foreign static div(a,b)
foreign static sum(a,b)
foreign static sub(a,b)
}
var my_mul_2 = Maths.mul(Maths.mul(2, 2), Maths.mul(3, 2)) - 4
System.print("my_mul_2 = %(my_mul_2) (expected: 20)")
var my_sum_2 = Maths.sum(Maths.sum(3, 4), Maths.sum(5, -1)) + 8
System.print("my_sum_2 = %(my_sum_2) (expected: 19)")
var my_sub_2 = Maths.sub(Maths.sub(8, 5), Maths.sub(20, 19)) + 1
System.print("my_sub_2 = %(my_sub_2) (expected: 3)")
)script";
class MyConfig : public wren::DefConfiguration {
typedef std::map<std::string, wren::foreign_method_t> MethodMap;
public:
wren::foreign_method_t foreign_method_fn(
wren::VM* vm,
const char* module_ptr,
const char* class_name_ptr,
bool is_static,
const char* signature_ptr
) {
auto key = to_map_key(module_ptr, class_name_ptr, signature_ptr);
auto it_found = m_foreign_methods.find(key);
if (m_foreign_methods.end() != it_found)
return it_found->second;
else
return nullptr;
}
void register_foreign_method (
std::string_view module_name,
std::string_view class_name,
std::string_view func_name,
wren::foreign_method_t fn
) {
m_foreign_methods[to_map_key(module_name, class_name, func_name)] = fn;
}
private:
static std::string to_map_key(
std::string_view module_name,
std::string_view class_name,
std::string_view func_name
) {
std::string key;
key.reserve(module_name.size() + class_name.size() + func_name.size() + 4);
key.append(module_name);
key += "::";
key.append(class_name);
key += "::";
key.append(func_name);
return key;
}
MethodMap m_foreign_methods;
};
template <typename Op>
void do_op(wren::VM& vm) {
using wren::get;
set(vm, 0, Op()(get<int>(vm, 1), get<int>(vm, 2)));
}
} //unnamed namespace
int main() {
MyConfig config;
config.register_foreign_method("main", "Maths", "sum(_,_)", &do_op<std::plus<int>>);
config.register_foreign_method("main", "Maths", "sub(_,_)", &do_op<std::minus<int>>);
config.register_foreign_method("main", "Maths", "mul(_,_)", &do_op<std::multiplies<int>>);
config.register_foreign_method("main", "Maths", "div(_,_)", &do_op<std::divides<int>>);
wren::VM vm(&config, nullptr);
vm.interpret("main", g_script);
wren::variable_ensure_slot(vm, {"main", "my_mul"}, 0);
std::cout << "Dynafunc mem usage: " << vm.dynafunc_byte_size() << " bytes\n";
vm.reset(&config);
std::cout << "Dynafunc mem usage after reset: " << vm.dynafunc_byte_size() << " bytes\n";
vm.interpret("main", g_script_2);
{
auto [var] = wren::variables<int>(vm, wren::ModuleAndName{"main", "my_mul_2"});
std::cout << "main::my_mul2 == " << var << " (expected: 20)\n";
}
std::cout << "Dynafunc mem usage: " << vm.dynafunc_byte_size() << " bytes\n";
return 0;
}