From 7d60cb87acae0c4db071d377bffcf6835b35baeb Mon Sep 17 00:00:00 2001 From: Jeremy Woertink Date: Sun, 29 Aug 2021 16:20:39 -0700 Subject: [PATCH] Adding new register_function for creating a function from Crystal space that's available in Lua space. Fixes #15 --- spec/lua/stack_spec.cr | 22 ++++++++++++++++++++++ src/lua/stack.cr | 1 + src/lua/stack/register_function.cr | 26 ++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 src/lua/stack/register_function.cr diff --git a/spec/lua/stack_spec.cr b/spec/lua/stack_spec.cr index 38dae99..6356fc3 100644 --- a/spec/lua/stack_spec.cr +++ b/spec/lua/stack_spec.cr @@ -184,6 +184,28 @@ module Lua stack.size.should eq 1 end end + + describe "#register_function" do + it "creates a new Lua function" do + stack = Stack.new + Stack.register_function stack, "crystal_debug", ->(value : String) do + value + end + + result = stack.run %(return crystal_debug("hello")) + result.should eq("hello") + end + + it "creates a new Lua function with two args" do + stack = Stack.new + Stack.register_function stack, "crystal_add", ->(x : Float64, y : Float64) do + x + y + end + + result = stack.run "return crystal_add(1, 2)" + result.should eq(3) + end + end end private class LuaReporter diff --git a/src/lua/stack.cr b/src/lua/stack.cr index 31e4380..c1eea6f 100644 --- a/src/lua/stack.cr +++ b/src/lua/stack.cr @@ -11,6 +11,7 @@ module Lua include StackMixin::CoroutineSupport include StackMixin::StandardLibraries include StackMixin::ClassSupport + include StackMixin::RegisterFunction getter state getter libs = Set(Symbol).new diff --git a/src/lua/stack/register_function.cr b/src/lua/stack/register_function.cr new file mode 100644 index 0000000..7161786 --- /dev/null +++ b/src/lua/stack/register_function.cr @@ -0,0 +1,26 @@ +module Lua + module StackMixin::RegisterFunction + macro included + macro register_function(stack, name, proc) + {% verbatim do %} + proc = ->(state : LibLua::State) { + {% for arg, index in proc.args %} + {{ arg.name }} = LibLua.tonumberx(state, {{ index + 1 }}, nil) + {% end %} + + # push result to stack + LibLua.pushnumber(state, {{ proc.body }}) + + 1 # number of results + } + + # push crystal proc onto the stack + LibLua.pushcclosure({{ stack.id }}.state, proc, 0) + + # give it a name + LibLua.setglobal({{ stack.id }}.state, {{ name }}) + {% end %} + end + end + end +end