LUA EXTENDING 1 References Programming in LUA 2

  • Slides: 19
Download presentation
LUA EXTENDING 1. References: “Programming in LUA, 2 nd ed. ”, Roberto Lerusalmschy Chapters

LUA EXTENDING 1. References: “Programming in LUA, 2 nd ed. ”, Roberto Lerusalmschy Chapters 24 -28 2. “Lua Reference Manual” (included in Lua installation or online)

Overview � � Write a module (in C) that can be run in Lua

Overview � � Write a module (in C) that can be run in Lua “world” C “world” �Lua ○ Makes heavy use of a virtual stack ○ No Lua/C types ○ Lua does all the memory management without our help. �Python: ○ Reference counting (helping Python with memory mgmt) ○ A ton of conversion functions ○ Many Py_xyz/C types. � We’ll explore most of the techniques needed to embed a Lua interpreter in ssuge.

Font / Color conventions -- lua code… print(“Lua code”) -- lua comment // C

Font / Color conventions -- lua code… print(“Lua code”) -- lua comment // C code printf(“%s”, “C-code”); // C comment #define LS lua_State * L int lua_gettop(lua_State * L); int lua_gettop(LS); // short-hand.

Simple Example � We’ll create a module (dll in windows): �A variable �A function

Simple Example � We’ll create a module (dll in windows): �A variable �A function �A simple class � The module itself is useless, but it illustrates �Converting between Lua and C data �Using things in a different “universe” � Simpler than the lab I had planned �Embedding lua in ssuge �I’ll save that for Lab 1 in ETGG 3802

Step 1: Create the project � [Do it together] � Remember to remove the

Step 1: Create the project � [Do it together] � Remember to remove the release and x 64 � In the real lab, I don’t want you to include all lua. c files in the project! � Test program v 1. 0 -- test 01. lua local m = require “test“ -- [discuss search] [Do it!] � What we just did: � � Created a new (empty) module on the Lua Stack and returned it to the lua interpreter (lua_State*)

Step 1, cont. Run it! � Sources of errors: � �Make sure the. dll

Step 1, cont. Run it! � Sources of errors: � �Make sure the. dll is in same folder as. lua �… Visual C++ debugger doesn’t work! � Lua doesn’t really have a debugger � �OK, it sort of does, but… �…it can’t inspect C code. � My (bad) solution: Lots of printf statements!

Lua State object � The environment � When running Lua on the command line

Lua State object � The environment � When running Lua on the command line �There is one lua_State * object �It is passed to all C code run through the command line interpreter. � Later (in ssuge, next semester), we'll create a single state (the "Lua World") lua_State * lua. L_newstate();

Using the documentation � Your best friend in this lab… �https: //www. lua. org/manual/5.

Using the documentation � Your best friend in this lab… �https: //www. lua. org/manual/5. 3/ �(Scroll down a bit to the Index) # items popped from stack # items pushed onto stack One of these: • “-” never raises an error • “m” could raise out-of-mem error • “e” could raise an error • “v” could raise an error on purpose

Lua Stack � The way data is exchanged between C and Lua. � Indices:

Lua Stack � The way data is exchanged between C and Lua. � Indices: � 1 to n: first, second, …, last �-1 to –n: last, next-to-last, …, first �“meta” (virtual) indices – not really on stack. ○ Globals ○ Registry ○…

Step 2: test program, v 2. 0 � Requires us to add (C) function(s)

Step 2: test program, v 2. 0 � Requires us to add (C) function(s) and add them to the module -- test 02. lua local m = require “test" print(m. adder(5, 3)) print(m. adder(5. 2, 3. 1)) print(m. adder(“abc”, 5)) � [Do it!] -- 8. 3 -- error

Functions to manipulate the stack // Gets the top (i. e. the number //

Functions to manipulate the stack // Gets the top (i. e. the number // of things on the stack. ) int lua_gettop(LS); // Removes elements (or add’s nils) // to resize the stack void lua_settop(LS, int num); // Pushes a copy of the indexed value // to the top of the stack void lua_pushvalue(LS, int index);

Functions to manipulate the stack, cont. // Removes the indexed value and // collapses

Functions to manipulate the stack, cont. // Removes the indexed value and // collapses the “hole”. int lua_remove(LS, int index); // Moves the top element to the given // index. void lua_insert(LS, int index); // Pops the top value and replaces the // value at the given index with it void lua_replace(LS, int index);

Functions to get values � int lua_isnumber(LS, int index); � int lua_tointeger(LS, int index);

Functions to get values � int lua_isnumber(LS, int index); � int lua_tointeger(LS, int index); � double lua_tonumber(LS, int index); � int lua_isstring(LS, int index) � char * lua_tostring(LS, int index); � Another method: �int lua. L_checkint(LS, int index); // error-check �char * lua. L_checkstring(LS, int index)

Functions to add values to the stack � lua_pushinteger(LS, int val); � lua_pushnumber(LS, double

Functions to add values to the stack � lua_pushinteger(LS, int val); � lua_pushnumber(LS, double val); � lua_pushstring(LS, char * val); �…

A handy debugging tool void stack_dump(lua_State * L) { int i; char type_str[256], value_str[256];

A handy debugging tool void stack_dump(lua_State * L) { int i; char type_str[256], value_str[256]; printf("======n|STACK DUMPn======n"); for (i=1; i<=lua_gettop(L); i++) { value_str[0] = ''; if (lua_isboolean(L, i)) { sprintf_s(type_str, 255, "boolean"); if (lua_toboolean(L, i))sprintf_s(value_str, 255, "true"); else sprintf_s(value_str, 255, "false"); } else if (lua_iscfunction(L, i))sprintf_s(type_str, 255, "cfunction"); else if (lua_isfunction(L, i))sprintf_s(type_str, 255, "lua-function"); else if (lua_islightuserdata(L, i))sprintf_s(type_str, 255, "lt-user-data"); else if (lua_isnil(L, i))sprintf_s(type_str, 255, "nil"); else if (lua_isnone(L, i))sprintf_s(type_str, 255, "<none>");

A handy debugging tool, cont. else if (lua_isnumber(L, i)) { sprintf_s(type_str, 255, "number"); sprintf_s(value_str,

A handy debugging tool, cont. else if (lua_isnumber(L, i)) { sprintf_s(type_str, 255, "number"); sprintf_s(value_str, 255, "%f", lua_tonumber(L, i)); } else if (lua_isstring(L, i)) { sprintf_s(type_str, 255, "string"); sprintf_s(value_str, 255, "%s", lua_tostring(L, i)); } else if (lua_istable(L, i))sprintf_s(type_str, 255, "table"); else if (lua_isuserdata(L, i))sprintf_s(type_str, 255, "user-data"); printf("|t[%d]: type='%s', value='%s'n", i, type_str, value_str); } // end the for loop printf("======n|END STACK DUMPn======n"); }

Step 3: test program, v 3. 0 local m = require("lua_extending") --print(m. adder(5, 3))

Step 3: test program, v 3. 0 local m = require("lua_extending") --print(m. adder(5, 3)) --print(m. adder(5. 2, 3. 1)) --print(m. adder("abc", 5)) --for k, v in pairs(m) do -print(k. . " ". . tostring(v)) --end x y z q = = m. Complex. new(4. 2, 3. 7) m. Complex. new(1. 9, -0. 2) m. Complex. new("surprise-me") print(z) z = nil print(x) print(q) print(x + y) print(x: magnitude()) ------- <0. 0, 0. 0 i> Triggers g. c. on z <4. 2, 3. 7 i> A random complex with values 0. 0. . . 1. 0 <6. 1, 3. 5 i> 5. 5973205566406

Review: metatables Any table (call it A) can optionally have a metatable (call it

Review: metatables Any table (call it A) can optionally have a metatable (call it MT) � A metatable can hold special meta-methods � � __index(table, key): called if we try to use a non- existent field in A � __newindex(table, key, value): similarly if we try to modify a non-existent field in A � __tostring(table): convert to a string � __add(lhs, rhs): used when using + � __gc(table): called when the table is “destroyed”. �… � � lua-users. org/wiki/Metatable. Events For OOP, we set the metatable of instances to the class table.

Step 5: Create the Complex “class" backend � 3 sub-steps �Create the C structure

Step 5: Create the Complex “class" backend � 3 sub-steps �Create the C structure �Create methods �Associate this new class with the module � [Do it!]