-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Crystal callback #15
Comments
Currently it is possible to do the following: stack = Lua::Stack.new
proc = ->(state : LibLua::State) {
puts LibLua.tonumberx(state, 1, nil)
return 0
}
# push crystal proc onto the stack
LibLua.pushcclosure(stack.state, proc, 0)
# give it a name
LibLua.setglobal(stack.state, "crystal")
# call crystal function with an argument.
stack.run "crystal(10)" #=> 10.0
stack.close
|
Bump |
@zatherz sorry, I don't have so much time for this now. Will try to work on it during coming weeks. If you are able to prepare PR I would love to review/merge it ;) Any other help also appreciated... |
I was going to write a PR, but I'm not decided on the API. Should the proc receive a low level state like above or should it get an Array? Array of what? How should assigning it to a global work? |
Well, the example above is low level. For convenience lua = Lua.load
# define a new crystal callback/function
lua.function "crystal_add" do |x, y|
x + y
end
# use it in Lua
lua.eval %q{
return 100 * crystal_add(3, 4)
} #=> 700.0 Here is the same that is written in a low-level manner: lua = Lua.load
proc = ->(state : LibLua::State) {
x = LibLua.tonumberx(state, 1, nil)
y = LibLua.tonumberx(state, 2, nil)
# push result to stack
LibLua.pushnumber(state, x + y)
1 # number of results
}
# push crystal proc onto the stack
LibLua.pushcclosure(lua.state, proc, 0)
# give it a name
LibLua.setglobal(lua.state, "crystal_add")
# call crystal function with arguments.
pp lua.run %q{
return 100 * crystal_add(3.0, 4.0)
} #=> 700.0
lua.close So, basically, to achieve this, you need to create new method
|
You can try to start and create PR on early stage, so we can discuss it if needed. PS: I was highly inspired by ruby's version of this: rufus-lua. That may help you a lot. Thanks for being interested in this project ;) |
What is the type of
? |
Hm, that has to be |
That should be an alias, but with what name? lua.function "crystal_add", Float64, Float64 do |x, y|
x + y
end ? |
Yes, there is an alias for this, Regarding |
Maybe using the lua.function "crystal_add", ->(x : Float64, y : Float64) do
x + y
end This would easily allow passing arbitrary procs like: def foo(x)
x + 1
end
lua.function "cr_foo", ->foo(Int32)
int = 42
lua.function "increment_int_from_lua", ->int.succ
lua.eval "increment_int_from_lua()"
puts int # => 43 |
@bew good suggestion. I have to return to this and implement it ;) But if you are willing to work on it, do not hesitate to open a PR 😼 |
looks like I need to use a macro to properly find arguments names & types of the passed proc, and properly generate the Lua proc (taking a Lua state, and working with that). Maybe the API could look like: def foo(x)
x + 1
end
lua.function "cr_foo", Lua.make_function ->foo(Int32)
int = 42
lua_function_proc = Lua.make_function ->int.succ
lua.function "increment_int_from_lua", lua_function_proc
lua.eval "increment_int_from_lua()"
puts int # => 43 What do you think? Edit: we'll need crystal-lang/crystal#5206 to be merged, to be able to inspect the |
Sorry, I might need to look at it closer, but does it make sense to create lua.function "cr_foo", ->foo(Int32) I am talking about it abstractly, so may be wrong. BTW, why do you interested in this? I abandoned it a bit because haven't seen practical examples/usage... |
While you can use macros inside a function, you cannot access its arguments as AST nodes, and inspect the properties of these AST nodes, for example, here we need to get the Given this simplified implementation: def function(name, proc)
lua_proc = ->(state : LibLua::State) do
# /!\ --------> Not possible, as `proc` is nothing here in macro world
{% for arg in proc.args %}
# extract the argument from the stack, based on the type of `arg`
{% end %}
# call `proc` with the fetched arguments from the stack
# put back the result in the stack
1
end
# associate the lua_proc with a global name
# etc..
end That's why I think the macro is necessary. BTW reply: nothing special, I just really like Lua, and found this project interesting for scripting inside a crystal app, and I think Lua deserve a cool library to run Lua scripts in Crystal 🌟 |
That's correct. But I was just saying that |
Ah that's not possible with current Crystal, as macros cannot be called on instances (for good IMO), so |
Was any progress made on this? I've got a pretty important use for it, and the Proc stuffs a bit goofy |
@shayneoneill no progress. And I can't promise you it will be done in the nearest future. |
…ce that's available in Lua space. Fixes veelenga#15
I just pushed up a WIP PR for this. I don't really know what I'm doing, but if anyone wants to take a look and give a little guidance, I'll fix it up. 😄 |
Would be nice to be able to write function callback in Crystal.
The text was updated successfully, but these errors were encountered: