Lua Module
BlitzMax Forums/BlitzMax Programming/Lua Module
| ||
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? |
| ||
Go to your bmax/bin folder in a terminal and enter "syncmods -u yourname -p yourpassword axe" |
| ||
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. |
| ||
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? |
| ||
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 |
| ||
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. |
| ||
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. |
| ||
Or more accurately, "poorly" written by me! :) Thanks Noel! :) |
| ||
Any time, Tommy. Remember, kids: don't discriminate. |
| ||
Has anyone got a small example of blitzmax lua in action? It would help me alot more :) |
| ||
I could show you my engine, but then I'd have to kill you. |
| ||
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) :) |
| ||
luatest.bmxSuperStrict 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) |
| ||
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? |
| ||
That is correct. |
| ||
Is there anything at all missing from the blitz lua that is in normal lua? Just checking :) |
| ||
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? |
| ||
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. |
| ||
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? |
| ||
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 ) |
| ||
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? |
| ||
...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) |
| ||
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 )'? |
| ||
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. |
| ||
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? |
| ||
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) |
| ||
Ah oob is just random, because I was testing :) (short for oobviously) Again, thanks for the help :) |
| ||
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?) |
| ||
luaopen_debug(lua_state) What does the add? What can it do? Here you go: http://www.lua.org/pil/23.html |
| ||
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? |
| ||
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. |