Lua Module

BlitzMax Forums/BlitzMax Programming/Lua Module

Ragz(Posted 2006) [#1]
I've searched for a while, I've found loads of threads about it, but I can't find any links to the module, can someone show me where to get it?


N(Posted 2006) [#2]
Go to your bmax/bin folder in a terminal and enter "syncmods -u yourname -p yourpassword axe"


Gabriel(Posted 2006) [#3]
Since we're ( you're ) on the subject, what are the major differences between the two LUA modules? Is one more or less powerful than the other? Are they used for different things? Do they complement each other? Are they just personal preference?

I read a tutorial on the Wiki which I think was on the scriptending module, but I'm curious about the differences/comparisons.


Ragz(Posted 2006) [#4]
Thanks, worked :)

Where would be the best place to find tutorials and such for the lua mod, just so I can get the hang of it?


Gabriel(Posted 2006) [#5]
Well the tutorial I referred to was this one :

http://www.blitzwiki.org/index.php/Lua_Tutorial

Noel wrote one on the other Lua Module ( his own, I guess ) and it's here :

http://www.blitzwiki.org/index.php/Introduction_to_Lua


N(Posted 2006) [#6]
Axe.LuaScript is, simply put, a wrapper on top of Lua. I've gone over the code several times and I have yet to change my mind about its quality. That is, it's extremely poor. If you want a Lua wrapper, you should use this instead of Axe.LuaScript.

Axe.Lua is Lua. It is not a wrapper, it's just the functions that you need to use Lua.

Do not confuse the two. Axe.LuaScript is not Lua, it is a poorly written wrapper that should have been discarded ages ago, but BRL kept it around for some reason.

For a tutorial on how to use Lua and not LuaScript, see my article Introduction to Lua.


popcade(Posted 2006) [#7]
I think there're some issues with Lua module currently

and this was left over 1.20, without fixes.
http://www.blitzbasic.com/Community/posts.php?topic=58735#653478

And thanks Noel for the nice article.


TommyBear(Posted 2006) [#8]
Or more accurately, "poorly" written by me! :) Thanks Noel! :)


N(Posted 2006) [#9]
Any time, Tommy. Remember, kids: don't discriminate.


Ragz(Posted 2006) [#10]
Has anyone got a small example of blitzmax lua in action? It would help me alot more :)


N(Posted 2006) [#11]
I could show you my engine, but then I'd have to kill you.


Ragz(Posted 2006) [#12]
Heh :p
I only want a small example of starting the lua state, defining a function or whatever then running a script (The script would be useful to have too) :)


N(Posted 2006) [#13]
luatest.bmx
SuperStrict

Import Axe.Lua

Function luaPrint%( l@ Ptr )
    For Local i:Int = 1 To lua_gettop( l ) ' The lua stack goes from 1 to lua_gettop( l ) -- it does not start at zero
        Select lua_type( l, i )                                     ' gets the type of the variable
            Case LUA_TBOOLEAN
                Print lua_toboolean( l, i )                         ' true/false
            Case LUA_TNUMBER
                Print lua_tonumber( l, i )                          ' double
            Case LUA_TSTRING
                Print String.FromCString( lua_tostring( l, i ) )    ' print a string - lua_tostring is an auxiliary function
                                                                    ' you should use lua_tolstring in your own code for safety
            Default
                ' other types exist, but for the sake of not writing too much code, they're excluded
        End Select
    Next
    Return 0        ' zero arguments are returned -- if you pushed anything on the stack, you'd specify the
                    ' amount of values you wanted to return
End Function

Local state@ Ptr = luaL_newstate( )         ' Create the state

lua_register( state, "print", luaPrint )    ' Register the function

lua_dofile( state, "luatest.lua" )          ' Execute a script

lua_close( state )                          ' Close the state

Input "Done>"                               ' Pause


luatest.lua
print("foo", false, 5.4321)



Ragz(Posted 2006) [#14]
Ah thanks, that makes it more clear :) I guess I must handle arguments with To lua_gettop( l ) and not fiddle with luaPrint%( l@ Ptr )'s arguments?


N(Posted 2006) [#15]
That is correct.


Ragz(Posted 2006) [#16]
Is there anything at all missing from the blitz lua that is in normal lua? Just checking :)


Ragz(Posted 2006) [#17]
If I 'dofile's that just define functions these functions will stay defined until I end the lua state right? Or can lua scripts not access functions of other lua scripts?


N(Posted 2006) [#18]
They should remain in the global table as they're just pushed onto the stack and executed. Unlike scripting languages like AngelScript, Lua recognizes scripts only as additional code, not a module or section of a larger work.

Think of it as using #include in C, it's just taking the script and adding it to what's already there. Well, that was a bit too much explanation for something so simple.


Ragz(Posted 2006) [#19]
Ah well I understood, I think :), How is it I would handle tables as a function argument it blitz functions? Also how can I return a table?


N(Posted 2006) [#20]
Tables are passed by-reference in Lua, so if you do modify them, the original table will be changed. That's worth noting, first off.

I can't provide a detailed example as I'm going to be heading out for Memorial Day for the next 6-7 hours, so this will have to do:

Strict

Import Axe.Lua

Local st@ Ptr = luaL_newstate( )

' basically, this is how you interact with tables

lua_pushstring( st, "varname" ) ' put the table in varname
lua_newtable( st ) ' create a new table
lua_pushstring( st, "key" ) ' push the key
lua_pushstring( st, "value" ) ' push the new value
lua_settable( st, -3 ) ' set table["key"] to "value"
lua_settable( st, LUA_GLOBALSINDEX ) ' set varname's value as the table

lua_close( st )



Ragz(Posted 2006) [#21]
Hmm, I can work with that for naw thanks :)

...but when when you have time could you explain why the order is that that? It seems to be jumbled and when you set "varname" value as the table you don't actually provide "varname" so how does it know?

And if I passed a table from lua to a blitz function how would I get things from it?

Also, is it possible to run a specific function in a lua file from blitz?


N(Posted 2006) [#22]
...but when when you have time could you explain why the order is that that? It seems to be jumbled and when you set "varname" value as the table you don't actually provide "varname" so how does it know?


"varname" is provided via the lua_pushstring that pushes "varname" (the key into the globals table) onto the stack. Whenever you modify a table, you have to at the least push a key onto the stack (for get and set).

Because all global variables are stored in the globals table, you have to push the variable name and then the value of the variable, then call lua_settable with the globals table constant (LUA_GLOBALSINDEX).

If varname doesn't exist in the globals table, it will be added to the table upon calling lua_settable.

if I passed a table from lua to a blitz function how would I get things from it?


Basically the same process:
' Push the key onto the stack
lua_pushstring( st, "key" )
' Tell lua to get the value from the table and push it onto the stack (it will still be in the table) -- it automatically pops the key
lua_gettable( st, stack index )
' Get the value that was pushed onto the stack
value = lua_tostring/tonumber/toboolean( st, -1 )
' Remove the popped value from the stack
lua_pop( st, 1 )


is it possible to run a specific function in a lua file from blitz?


Yes.
lua_pushstring( st, "function name" )
lua_gettable( st, LUA_GLOBALSINDEX )
' push any arguments onto the stack
' call the function
Local err:Int = lua_pcall( st, numargs, numresults, 0 or an error handler function index )
' get any results -- if err is <> 0 then the pushed result will be an error message (string)



Ragz(Posted 2006) [#23]
Thanks Noel! You've been a great help :) I should be able to figure out the rest form what I have, but I do have one last question: What does 'String.FromCString( )' do to 'lua_tostring( l, -1 )'?


N(Posted 2006) [#24]
Because lua_tolstring (the function that lua_tostring wraps) returns a Byte Ptr (normal 8-bit C string), it's necessary to convert it to a normal BMax string (16-bit unicode). All Lua strings are null-terminated C strings, so using String.FromCString will create a BMax string.

Otherwise, you're stuck working with a pointer to some data.


Ragz(Posted 2006) [#25]
Hmm, how would I call a table's function? I'm guessing I have to push a string and get a table then do what said above or something, but I can't work out how to do it :S

the table is 'test', the function is 'oob'

The Lua.
test = {}

function test.oob()
    print("you tested")
end


The BMax.
lua_pushstring( state, "test.oob" )
lua_gettable( state, LUA_GLOBALSINDEX )
Local err:Int = lua_pcall( state, 0, 0, 0)
If err <> 0 Then Print "Error!"


I tried to figure it out myself and so tried the below code, but PANIC: etc.
lua_pushstring( state, "test" )
lua_gettable( state, LUA_GLOBALSINDEX )
lua_pushstring( state, "oob" )
lua_gettable( state, -1 )
Local err:Int = lua_pcall( state, 0, 0, 0)
If err <> 0 Then Print "Error!"


Also:

Does the module have the 'setmetatable' function or do I have to do blitz version of all the functions like that?

I noticed in the mod folder there are lots of c files like the maths lib etc, but I can't use the function in lua, is there a way to enable any of these?


N(Posted 2006) [#26]
Like this:
' get the table
lua_pushstring( l, "test" )
lua_gettable( l, LUA_GLOBALSINDEX )

' get the function from the table
lua_pushstring( l, "oob" )
' note: -2 is the table, -1 is the key
lua_gettable( l, -2 )

' call the function
lua_pcall( l, 0, 0, 0 )

' pop the 'test' table from the stack since it's no longer needed
lua_pop( 1 )


'oob' is a rather unusual function name.

To use the base/maths/io/debug/string/table libs, use the following functions:
luaopen_base(lua_state:Byte Ptr)
luaopen_table(lua_state:Byte Ptr)
luaopen_io(lua_state:Byte Ptr)
luaopen_string(lua_state:Byte Ptr)
luaopen_math(lua_state:Byte Ptr)
luaopen_debug(lua_state:Byte Ptr)



Ragz(Posted 2006) [#27]
Ah oob is just random, because I was testing :) (short for oobviously)

Again, thanks for the help :)


Ragz(Posted 2006) [#28]
luaopen_debug(lua_state)

What does the add? What can it do? When things fail the only error I get is from the inability to call a function which is generated from another version of this:
Local err:Int = lua_pcall( state, 0, 0, 0)
If err <> 0 Then Print "Error!"
(Yes I have the correct pushes, pop etc, this just demonstrates the only error I get isn't coming from lua.)

Is there any way to output any errors in syntax, like the lua stand alone interp does?

(And is Noel banned? or is that just his signature?)


teamonkey(Posted 2006) [#29]
luaopen_debug(lua_state)

What does the add? What can it do?


Here you go: http://www.lua.org/pil/23.html


Ragz(Posted 2006) [#30]
Ah right, I guess this is not how the Lua stand alone interpreter points out your syntax errors in files? If it is, do you know where the lua script it uses to do this can be found? If not, is the way it debugs enablable in the Lua module for blitz?


Cajun17(Posted 2006) [#31]
Syntax errors don't fall under the debugging category. When lua runs into an error it stops execution and returns to the application if it's embedded.

I use an Ide called LuaEdit and it has a syntax checker if that's all you're looking for. It also has a debugger to help with logic errors.