Merge Lua changes - branch 'class_p1' of github.com:v-for-vandal/swig into v-for-vandal-class_p1
* 'class_p1' of github.com:v-for-vandal/swig: Fixing registerClass. No more wrap: unnecessary attributes Fixed registerMethod to work like registerVariable Switched to Swig_name_* functions Return MIN_OPT_LEVEL for elua add nspace_extend test case updated documentation following comd options renaming Options in alphabetical order Members renaming target_name -> lua_name Fixing cmd options, again Fixing segfault Removed class_parent_nspace Fixes to module options Rename methods to make it clear what 'symbols table' they operate on. Small documenation fixes Updating Lua documentation Eliminating namespaces_hash and using symbols table instead Attempt to catch unreproducable bug from Travis CI build Small bugfixes Bugfixes for eLua. eLua emulation mode Add compatibility option for old-style inheritance Add support for C-style enums in C mode. And tests. Style fixes. Comments fixes. Fixing cmd options. etc Some fixes for elua Attempt to fix unreproducable bug (from Travis CI build) Fixes for examples. Wrapped keywords into guardian in keyword_rename test Remove some typos Remove some obsolete code Manually beautifying luarun.swg Code beautifier Valuewrapper test Removing obsolete debug code Bugfixes A few bugfixes Some class bases iteration improvements Fixes for elua Bugfixes Bugfixes. CMD args handling. Code cleanup Bugfixes Preparations before pull request - part 1 More changes. Mostly to the would-be class library Fixing issuse with v2-compatible static function names Add pointer guard Add runtime test Bugfixes nspace.i example is working Initial implementation - everything compiles but might not work
This commit is contained in:
commit
1be97ed26c
21 changed files with 2692 additions and 953 deletions
|
|
@ -77,7 +77,7 @@ eLua stands for Embedded Lua (can be thought of as a flavor of Lua) and offers t
|
|||
|
||||
|
||||
<p>
|
||||
The current SWIG implementation is designed to work with Lua 5.0.x, 5.1.x and 5.2.x. It should work with later versions of Lua, but certainly not with Lua 4.0 due to substantial API changes. It is possible to either static link or dynamic link a Lua module into the interpreter (normally Lua static links its libraries, as dynamic linking is not available on all platforms). SWIG also supports eLua and works with eLua 0.8. SWIG generated code for eLua has been tested on Stellaris ARM Cortex-M3 LM3S and Infineon TriCore.
|
||||
The current SWIG implementation is designed to work with Lua 5.0.x, 5.1.x and 5.2.x. It should work with later versions of Lua, but certainly not with Lua 4.0 due to substantial API changes. It is possible to either static link or dynamic link a Lua module into the interpreter (normally Lua static links its libraries, as dynamic linking is not available on all platforms). SWIG also has support for eLua starting from eLua 0.8. Due to substantial changes between SWIG 2.x and SWIG 3.0 and unavailability of testing platform, eLua status was downgraded to 'experimental'.
|
||||
</p>
|
||||
|
||||
<H2><a name="Lua_nn3"></a>26.2 Running SWIG</H2>
|
||||
|
|
@ -159,6 +159,14 @@ swig -lua -help
|
|||
<td>Do not register the module name as a global variable but return the module table from calls to require.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>-no-old-metatable-bindings</td>
|
||||
<td>Disable backward compatibility: old-style binding names generations and a few other things. Explanations are included into appropriate sections.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>-squash-bases</td>
|
||||
<td>Squashes symbols from all inheritance tree of a given class into itself. Emulates pre-SWIG3.0 inheritance. Insignificantly speeds things up, but increases memory consumption.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<H3><a name="Lua_nn4"></a>26.2.2 Compiling and Linking and Interpreter</H3>
|
||||
|
|
@ -349,7 +357,8 @@ creates a built-in function <tt>example.fact(n)</tt> that works exactly like you
|
|||
>
|
||||
</pre></div>
|
||||
<p>
|
||||
To avoid name collisions, SWIG create a Lua table which it keeps all the functions and global variables in. It is possible to copy the functions out of this and into the global environment with the following code. This can easily overwrite existing functions, so this must be used with care.
|
||||
To avoid name collisions, SWIG create a Lua table which it keeps all the functions, constants, classes and global variables in. It is possible to copy the functions, constants and classes (but not variables) out of this and into the global environment with the following code. This can easily overwrite existing functions, so this must be used with care.
|
||||
This option is considered deprecated and will be removed in near future.
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
> for k,v in pairs(example) do _G[k]=v end
|
||||
|
|
@ -490,6 +499,52 @@ If you're using eLua and have used <tt>-elua</tt> or <tt>-eluac</tt> to generate
|
|||
> print(example.const.SCONST)
|
||||
Hello World
|
||||
</pre></div>
|
||||
|
||||
<H4>Constants/enums and classes/structures</H4>
|
||||
<p>
|
||||
Unlike previous version of bindings, enums are now exported into class table. For example, given some enums:
|
||||
</p>
|
||||
<div class="code"><pre>%module example
|
||||
enum Days{SUNDAY = 0,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY};
|
||||
class Test {
|
||||
enum { TEST1 = 10, TEST2 = 10 }
|
||||
static const int ICONST = 12;
|
||||
};
|
||||
</pre></div>
|
||||
<p>
|
||||
This is 'effectively' converted into the following Lua code:
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
> print(example.const.SUNDAY)
|
||||
0
|
||||
> print(example.Test.TEST1)
|
||||
10
|
||||
> print(example.Test.ICONST)
|
||||
12
|
||||
</pre></div>
|
||||
<H4>Backward compatibility</H4>
|
||||
<p>
|
||||
If <tt>-no-old-metatable-bindings</tt> option is not given, then in addition to previously described bindings, the old-style ones are generated:
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
> print(example.Test_TEST1)
|
||||
10
|
||||
> print(example.Test_ICONST)
|
||||
12
|
||||
</pre></div>
|
||||
<p>
|
||||
However, in C mode, names of enums are not prefixed with names of structure. This is the due to C Standard.
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
> print(example.TEST1)
|
||||
10
|
||||
> print(example.ICONST)
|
||||
12
|
||||
</pre></div>
|
||||
<p>
|
||||
It worth mentioning, that <tt>example.Test.TEST1</tt> and <tt>example.Test_TEST1</tt> are different entities and changind one wouldn't change another.
|
||||
Given the fact, that these are constantes and they are not supposed to be changed, it is up to you to avoid such issues.
|
||||
</p>
|
||||
<H3><a name="Lua_nn12"></a>26.3.5 Pointers</H3>
|
||||
|
||||
|
||||
|
|
@ -551,7 +606,7 @@ is used as follows:
|
|||
</pre></div>
|
||||
<p>
|
||||
Similar access is provided for unions and the data members of C++ classes.<br>
|
||||
C structures are created using a function <tt>new_Point()</tt>, but for C++ classes are created using just the name <tt>Point()</tt>.
|
||||
C structures can be created using a function <tt>new_Point()</tt>, and both C structures and C++ classes can be created using just the name <tt>Point()</tt>.
|
||||
</p>
|
||||
<p>
|
||||
If you print out the value of p in the above example, you will see something like this:
|
||||
|
|
@ -679,9 +734,9 @@ public:
|
|||
In Lua, the static members can be accessed as follows:
|
||||
</p>
|
||||
<div class="code"><pre>
|
||||
> example.Spam_foo() -- calling Spam::foo()
|
||||
> a=example.Spam_bar -- reading Spam::bar
|
||||
> example.Spam_bar=b -- writing to Spam::bar
|
||||
> example.Spam.foo() -- calling Spam::foo()
|
||||
> a=example.Spam.bar -- reading Spam::bar
|
||||
> example.Spam.bar=b -- writing to Spam::bar
|
||||
</pre></div>
|
||||
<p>
|
||||
It is not (currently) possible to access static members of an instance:
|
||||
|
|
@ -692,6 +747,13 @@ It is not (currently) possible to access static members of an instance:
|
|||
-- does NOT work
|
||||
</pre></div>
|
||||
|
||||
<H4>Backward compatibility</H4>
|
||||
<p> If <tt>-no-old-metatable-bindings</tt> option is not given, then backward compatible names are generated in addition to ordinary ones: </p>
|
||||
<div class="code"><pre>
|
||||
> example.Spam_foo() -- calling Spam::foo()
|
||||
> a=example.Spam_bar -- reading Spam::bar
|
||||
> example.Spam_bar=b -- writing to Spam::bar
|
||||
</pre></div>
|
||||
<H3><a name="Lua_nn15"></a>26.3.8 C++ inheritance</H3>
|
||||
|
||||
|
||||
|
|
@ -1256,6 +1318,143 @@ and the "<a href="Customization.html#Customization_exception">Exception handling
|
|||
add exception specification to functions or globally (respectively).
|
||||
</p>
|
||||
|
||||
<H3><a name ="Lua_nn23_5"></a>26.3.17 Namespaces </H3>
|
||||
<p>
|
||||
Since SWIG 3.0 C++ namespaces are supported. You can enabled handling namespaces with %nspace feature. Everything below is valid only after you enabled %nspace.
|
||||
</p>
|
||||
<p> Namespaces are mapped into lua tables. Each of those tables contains names that were defined within appropriate namespace. Namespaces structure (a.k.a nested namespaces) is preserved. Consider the following C++ code:
|
||||
</p>
|
||||
<div class="code"><pre>%module example
|
||||
%nspace MyWorld::Nested::Dweller;
|
||||
%nspace MyWorld::World;
|
||||
/* and so on */
|
||||
int module_function() { return 7;}
|
||||
int module_variable; // = 9
|
||||
namespace MyWorld {
|
||||
class World {
|
||||
public:
|
||||
int create_world() { return 17;}
|
||||
const int world_max_count = 9;
|
||||
};
|
||||
namespace Nested {
|
||||
class Dweller {
|
||||
enum Gender {MALE, FEMALE;
|
||||
static int populate_cave() { return 19; }
|
||||
int create_cave() { return 13;}
|
||||
int food_count; // = 11
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre></div>
|
||||
Now, in Lua it could be used like this:
|
||||
<div class="targetlang"><pre>
|
||||
> example.module_function()
|
||||
7
|
||||
> print(example.module_variable)
|
||||
8
|
||||
> print(example.MyWorld.World():create_world())
|
||||
17
|
||||
> print(example.MyWorld.World.world_max_count)
|
||||
9
|
||||
> print(example.MyWordl.Nested.Dweller.MALE)
|
||||
0
|
||||
> print(example.MyWordl.Nested.Dweller().food_count)
|
||||
11
|
||||
>
|
||||
</pre></div>
|
||||
<H4> Backward compatibility </H4>
|
||||
<p>
|
||||
If SWIG is running in backward compatible way, i.e. without <tt>-no-old-metatable-bindings</tt> option, then additional old-style names are generated(notice the underscore):
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
9
|
||||
> print(example.MyWorld.Nested.Dweller_MALE)
|
||||
0
|
||||
> print(example.MyWorld.Nested.Dweller_populate_cave())
|
||||
11
|
||||
>
|
||||
</pre></div>
|
||||
<H3> Backward compatibility </H3>
|
||||
<H4> Names </H4>
|
||||
<p> If SWIG is launched without <tt>-no-old-metatable-bindings</tt> option, then it enters backward-compatible mode. While in this mode, it tries
|
||||
to generate additional names for static functions, class static constants and class enums.
|
||||
Those names are in a form <tt>$classname_$symbolname</tt> and are added to the scope surrounding the class.
|
||||
If %nspace is enabled, then class namespace is taken as scope. If there is no namespace, or %nspace is disabled,
|
||||
then module is considered a class namespace.</p>
|
||||
<p> Consider the following C++ code </p>
|
||||
<div class="code"><pre>%module example
|
||||
%nspace MyWorld::Test;
|
||||
namespace MyWorld {
|
||||
class Test {
|
||||
public:
|
||||
enum { TEST1 = 10, TEST2 }
|
||||
static const int ICONST = 12;
|
||||
};
|
||||
class Test2 {
|
||||
public:
|
||||
enum { TEST3 = 20, TEST4 }
|
||||
static const int ICONST2 = 23;
|
||||
}
|
||||
</pre></div>
|
||||
<p> When in backward compatible mode, in addition to usual names, the following ones will be generated (notice the underscore):</p>
|
||||
<div class="targetlang"><pre>
|
||||
9
|
||||
> print(example.MyWorld.Test_TEST1) -- Test has %nspace enabled
|
||||
10
|
||||
> print(example.MyWorld.Test_ICONST) -- Test has %nspace enabled
|
||||
12
|
||||
> print(example.Test2_TEST3) -- Test2 doesn't have %nspace enabled
|
||||
20
|
||||
> print(example.Test2_ICONST2) -- Test2 doesn't have %nspace enabled
|
||||
23
|
||||
>
|
||||
</pre></div>
|
||||
<p> There is a slight difference with enums when in C mode. As per C standard, enums from C structures are exported to
|
||||
surrounding scope without any prefixing. Pretending that Test2 is a struct, not class, that would be:</p>
|
||||
<div class="targetlang"><pre>
|
||||
> print(example.TEST3) -- NOT Test2_TEST3
|
||||
20
|
||||
>
|
||||
</pre></div>
|
||||
|
||||
<H4> Inheritance </H4>
|
||||
<p> The internal organization of inheritance has changed.
|
||||
Consider the following C++ code:</p>
|
||||
<div class="code"><pre>%module example
|
||||
class Base {
|
||||
public:
|
||||
int base_func()
|
||||
};
|
||||
class Derived : public Base {
|
||||
public:
|
||||
int derived_func()
|
||||
}
|
||||
</pre></div>
|
||||
<p>Lets assume for a moment that class member functions are stored in <tt>.fn</tt> table. Previously, when classes
|
||||
were exported to Lua during module initialization, for every derived class all service tables <tt>ST(i.e. ".fn")</tt>
|
||||
were squashed and added to corresponding derived class <tt>ST</tt>: Everything from <tt>.fn</tt> table of class Base
|
||||
was copied to <tt>.fn</tt> table of class Derived and so on. This was a recursive procedure, so in the end the whole
|
||||
inheritance tree of derived class was squashed into derived class. </p>
|
||||
<p> That means that any changes done to class Base after module initialization wouldn't affect class Derived:</p>
|
||||
<div class="targetlang"><pre>
|
||||
base = example.Base()
|
||||
der = example.Derived()
|
||||
> print(base.base_func)
|
||||
function: 0x1367940
|
||||
> getmetatable(base)[".fn"].new_func = function (x) return x -- Adding new function to class Base (to class, not to an instance!)
|
||||
> print(base.new_func) -- Checking this function
|
||||
function
|
||||
> print(der.new_func) -- Wouldn't work. Derived doesn't check Base any more.
|
||||
nil
|
||||
>
|
||||
</pre></div>
|
||||
<p> This behaviour was changed. Now unless -squash-bases option is provided, Derived store a list of it's bases and if some symbol is not found in it's own service tables
|
||||
then its bases are searched for it. Option -squash-bases will effectively return old behaviour.
|
||||
<div class="targetlang"><pre>
|
||||
> print(der.new_func) -- Now it works
|
||||
function
|
||||
>
|
||||
</pre></div>
|
||||
|
||||
<H2><a name="Lua_nn24"></a>26.4 Typemaps</H2>
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ namespace TopLevel
|
|||
%include <std_string.i>
|
||||
|
||||
// nspace feature only supported by these languages
|
||||
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD)
|
||||
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA)
|
||||
%nspace TopLevel::Bar::Foo;
|
||||
%nspace TopLevel::Bar::FooBar;
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ namespace TopLevel
|
|||
%include <std_string.i>
|
||||
|
||||
// nspace feature only supported by these languages
|
||||
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD)
|
||||
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA)
|
||||
%nspace TopLevel::A::Foo;
|
||||
%nspace TopLevel::B::Foo;
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -32,8 +32,10 @@ KW(go, defer)
|
|||
KW(chan, fallthrough)
|
||||
|
||||
/* Lua keywords */
|
||||
#ifdef SWIGLUA
|
||||
KW(end, function)
|
||||
KW(nil,local)
|
||||
#endif
|
||||
|
||||
%}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,4 +19,12 @@ assert(enums.globalinstance3==30)
|
|||
assert(enums.AnonEnum1==0)
|
||||
assert(enums.AnonEnum2==100)
|
||||
|
||||
-- In C enums from struct are exported without prefixing with struct name
|
||||
-- In C++ they are prefixed.
|
||||
-- We are emulating xor :)
|
||||
assert(enums.BAR1 ~= enums.Foo_BAR1) -- It is either C style, or C++ style, but not both
|
||||
assert((enums.BAR1 ~= nil ) or (enums.Foo_BAR1 ~= nil))
|
||||
|
||||
assert(enums.Phoo ~= enums.iFoo_Phoo)
|
||||
assert((enums.Phoo == 50) or (enums.iFoo_Phoo == 50))
|
||||
-- no point in checking fns, C will allow any value
|
||||
|
|
|
|||
|
|
@ -14,4 +14,5 @@ assert(g.test3 == 37)
|
|||
g.test3 = 42
|
||||
assert(g.test3 == 42)
|
||||
|
||||
assert(g.NEGATE ~= nil)
|
||||
assert(g.do_unary(5, g.NEGATE) == -5)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
require("import") -- the import fn
|
||||
import("li_carrays") -- import code
|
||||
|
||||
-- moving to global
|
||||
for k,v in pairs(li_carrays) do _G[k]=v end
|
||||
lc = li_carrays
|
||||
|
||||
-- catch "undefined" global variables
|
||||
local env = _ENV -- Lua 5.2
|
||||
|
|
@ -10,22 +8,22 @@ if not env then env = getfenv () end -- Lua 5.1
|
|||
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
|
||||
|
||||
-- Testing for %array_functions(int,intArray)
|
||||
ary = new_intArray(2)
|
||||
intArray_setitem(ary, 0, 0)
|
||||
intArray_setitem(ary, 1, 1)
|
||||
assert(intArray_getitem(ary, 0)==0)
|
||||
assert(intArray_getitem(ary, 1)==1)
|
||||
delete_intArray(ary)
|
||||
ary = lc.new_intArray(2)
|
||||
lc.intArray_setitem(ary, 0, 0)
|
||||
lc.intArray_setitem(ary, 1, 1)
|
||||
assert(lc.intArray_getitem(ary, 0)==0)
|
||||
assert(lc.intArray_getitem(ary, 1)==1)
|
||||
lc.delete_intArray(ary)
|
||||
|
||||
-- Testing for %array_class(double, doubleArray)
|
||||
d = doubleArray(10)
|
||||
d = lc.doubleArray(10)
|
||||
d[0] = 7
|
||||
d[5] = d[0] + 3
|
||||
assert(d[5] + d[0] == 17)
|
||||
--print(d[5] + d[0])
|
||||
|
||||
ptr = d:cast() -- to ptr
|
||||
d2 = doubleArray_frompointer(ptr) -- and back to array
|
||||
d2 = lc.doubleArray_frompointer(ptr) -- and back to array
|
||||
assert(d2[5] + d2[0] == 17)
|
||||
--print(d2[5] + d2[0])
|
||||
|
||||
|
|
|
|||
|
|
@ -1,43 +1,46 @@
|
|||
--Example using pointers to member functions
|
||||
|
||||
require("import") -- the import fn
|
||||
import("member_pointer") -- import code
|
||||
mp = member_pointer
|
||||
|
||||
for k,v in pairs(member_pointer) do _G[k]=v end
|
||||
-- catching undefined variables
|
||||
local env = _ENV -- Lua 5.2
|
||||
if not env then env = getfenv () end -- Lua 5.1
|
||||
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
|
||||
|
||||
function check(what, expected, actual)
|
||||
assert(expected == actual,"Failed: "..what.." Expected: "..expected.." Actual: "..actual)
|
||||
end
|
||||
|
||||
-- Get the pointers
|
||||
area_pt = areapt()
|
||||
perim_pt = perimeterpt()
|
||||
area_pt = mp.areapt()
|
||||
perim_pt = mp.perimeterpt()
|
||||
|
||||
-- Create some objects
|
||||
s = Square(10)
|
||||
s = mp.Square(10)
|
||||
|
||||
-- Do some calculations
|
||||
check ("Square area ", 100.0, do_op(s,area_pt))
|
||||
check ("Square perim", 40.0, do_op(s,perim_pt))
|
||||
check ("Square area ", 100.0, mp.do_op(s,area_pt))
|
||||
check ("Square perim", 40.0, mp.do_op(s,perim_pt))
|
||||
|
||||
-- Try the variables
|
||||
-- these have to still be part of the 'member_pointer' table
|
||||
memberPtr = member_pointer.areavar
|
||||
memberPtr = member_pointer.perimetervar
|
||||
memberPtr = mp.areavar
|
||||
memberPtr = mp.perimetervar
|
||||
|
||||
check ("Square area ", 100.0, do_op(s,member_pointer.areavar))
|
||||
check ("Square perim", 40.0, do_op(s,member_pointer.perimetervar))
|
||||
check ("Square area ", 100.0, mp.do_op(s,mp.areavar))
|
||||
check ("Square perim", 40.0, mp.do_op(s,mp.perimetervar))
|
||||
|
||||
-- Modify one of the variables
|
||||
member_pointer.areavar = perim_pt
|
||||
mp.areavar = perim_pt
|
||||
|
||||
check ("Square perimeter", 40.0, do_op(s,member_pointer.areavar))
|
||||
check ("Square perimeter", 40.0, mp.do_op(s,mp.areavar))
|
||||
|
||||
-- Try the constants
|
||||
memberPtr = AREAPT
|
||||
memberPtr = PERIMPT
|
||||
memberPtr = NULLPT
|
||||
memberPtr = mp.AREAPT
|
||||
memberPtr = mp.PERIMPT
|
||||
memberPtr = mp.NULLPT
|
||||
|
||||
check ("Square area ", 100.0, do_op(s,AREAPT))
|
||||
check ("Square perim", 40.0, do_op(s,PERIMPT))
|
||||
check ("Square area ", 100.0, mp.do_op(s,mp.AREAPT))
|
||||
check ("Square perim", 40.0, mp.do_op(s,mp.PERIMPT))
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
require("import") -- the import fn
|
||||
import("newobject1") -- import code
|
||||
|
||||
foo1 = newobject1.Foo_makeFoo() -- lua doesnt yet support static fns properly
|
||||
assert(newobject1.Foo_fooCount() == 1) -- lua doesnt yet support static fns properly
|
||||
foo1 = newobject1.Foo_makeFoo()
|
||||
assert(newobject1.Foo_fooCount() == 1)
|
||||
|
||||
foo2 = foo1:makeMore()
|
||||
assert(newobject1.Foo_fooCount() == 2)
|
||||
|
|
|
|||
39
Examples/test-suite/lua/nspace_extend_runme.lua
Normal file
39
Examples/test-suite/lua/nspace_extend_runme.lua
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
require("import") -- the import fn
|
||||
import("nspace_extend") -- import lib
|
||||
|
||||
-- catch "undefined" global variables
|
||||
local env = _ENV -- Lua 5.2
|
||||
if not env then env = getfenv () end -- Lua 5.1
|
||||
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
|
||||
|
||||
ne = nspace_extend
|
||||
|
||||
-- Inner1
|
||||
|
||||
-- Constructors
|
||||
in1_clr1 = ne.Outer.Inner1.Color()
|
||||
in1_clr2 = ne.Outer.Inner1.Color.create()
|
||||
in1_clr3 = ne.Outer.Inner1.Color(in1_clr2)
|
||||
|
||||
-- methods
|
||||
in1_clr1:colorInstanceMethod(1.0)
|
||||
ne.Outer.Inner1.Color.colorStaticMethod(2.0)
|
||||
|
||||
-- Inner2
|
||||
|
||||
-- Constructors
|
||||
in2_clr1 = ne.Outer.Inner2.Color()
|
||||
in2_clr2 = ne.Outer.Inner2.Color.create()
|
||||
in2_clr3 = ne.Outer.Inner2.Color(in2_clr2)
|
||||
|
||||
assert(pcall(ne.Outer.Inner2.Color, in1_clr1) == false)
|
||||
|
||||
-- methods
|
||||
in2_clr1:colorInstanceMethod(1.0)
|
||||
ne.Outer.Inner2.Color.colorStaticMethod(2.0)
|
||||
|
||||
in2_clr3:colors(in1_clr1, in1_clr2, in2_clr2, in2_clr2, in2_clr3)
|
||||
|
||||
assert(pcall(in2_clr3.colors, in2_clr3,
|
||||
in2_clr1, in2_clr2, in1_clr2, in2_clr2, in2_clr3) == false)
|
||||
|
||||
67
Examples/test-suite/lua/nspace_runme.lua
Normal file
67
Examples/test-suite/lua/nspace_runme.lua
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
require("import") -- the import fn
|
||||
import("nspace") -- import lib
|
||||
|
||||
-- catch "undefined" global variables
|
||||
local env = _ENV -- Lua 5.2
|
||||
if not env then env = getfenv () end -- Lua 5.1
|
||||
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
|
||||
|
||||
ns = nspace
|
||||
|
||||
-- Inheritance
|
||||
blue1 = ns.Outer.Inner3.Blue()
|
||||
|
||||
-- blue1:blueInstanceMethod()
|
||||
blue1:colorInstanceMethod(60.0)
|
||||
blue1.instanceMemberVariable = 4
|
||||
assert( blue1.instanceMemberVariable == 4 )
|
||||
|
||||
-- Constructors
|
||||
color1 = ns.Outer.Inner1.Color()
|
||||
color2 = ns.Outer.Inner1.Color.create()
|
||||
color = ns.Outer.Inner1.Color(color1)
|
||||
color3 = ns.Outer.Inner2.Color.create()
|
||||
color4 = ns.Outer.Inner2.Color.create()
|
||||
color5 = ns.Outer.Inner2.Color.create()
|
||||
mwp2 = ns.Outer.MyWorldPart2()
|
||||
gc = ns.GlobalClass()
|
||||
|
||||
nnsp = ns.NoNSpacePlease()
|
||||
|
||||
-- Class methods
|
||||
color:colorInstanceMethod(20.0)
|
||||
ns.Outer.Inner1.Color.colorStaticMethod(30.0)
|
||||
color3:colorInstanceMethod(40.0)
|
||||
ns.Outer.Inner2.Color.colorStaticMethod(50.0)
|
||||
color3:colors(color1, color2, color3, color4, color5)
|
||||
|
||||
gc:gmethod()
|
||||
|
||||
-- Class variables
|
||||
color.instanceMemberVariable = 5
|
||||
color1.instanceMemberVariable = 7
|
||||
assert( color.instanceMemberVariable == 5 )
|
||||
assert( color1.instanceMemberVariable == 7 )
|
||||
assert(ns.Outer.Inner1.Color.staticMemberVariable == 0 )
|
||||
assert(ns.Outer.Inner2.Color.staticMemberVariable == 0 )
|
||||
ns.Outer.Inner1.Color.staticMemberVariable = 9
|
||||
ns.Outer.Inner2.Color.staticMemberVariable = 11
|
||||
assert(ns.Outer.Inner1.Color.staticMemberVariable == 9)
|
||||
assert(ns.Outer.Inner2.Color.staticMemberVariable == 11)
|
||||
|
||||
-- Class constants
|
||||
assert( ns.Outer.Inner1.Color.Specular == 0x20 )
|
||||
assert( ns.Outer.Inner2.Color.Specular == 0x40 )
|
||||
assert( ns.Outer.Inner1.Color.staticConstMemberVariable == 222 )
|
||||
assert( ns.Outer.Inner2.Color.staticConstMemberVariable == 333 )
|
||||
assert( ns.Outer.Inner1.Color.staticConstEnumMemberVariable ~= ns.Outer.Inner2.Color.staticConstEnumMemberVariable )
|
||||
|
||||
|
||||
-- Aggregation
|
||||
sc = ns.Outer.SomeClass()
|
||||
assert( sc:GetInner1ColorChannel() ~= sc:GetInner2Channel() )
|
||||
assert( sc:GetInner1Channel() ~= sc:GetInner2Channel() )
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -3,6 +3,7 @@ import("template_default_arg") -- import code
|
|||
--for k,v in pairs(template_default_arg) do _G[k]=v end -- move to global
|
||||
|
||||
helloInt = template_default_arg.Hello_int()
|
||||
assert(template_default_arg.Hello_int_hi ~= nil)
|
||||
helloInt:foo(template_default_arg.Hello_int_hi)
|
||||
|
||||
x = template_default_arg.X_int()
|
||||
|
|
|
|||
17
Examples/test-suite/lua/valuewrapper_runme.lua
Normal file
17
Examples/test-suite/lua/valuewrapper_runme.lua
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
require("import") -- the import fn
|
||||
import("valuewrapper") -- import code
|
||||
v=valuewrapper -- renaming import
|
||||
|
||||
-- catch "undefined" global variables
|
||||
local env = _ENV -- Lua 5.2
|
||||
if not env then env = getfenv () end -- Lua 5.1
|
||||
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
|
||||
|
||||
assert(v.Xi ~= nil)
|
||||
assert(v.YXi ~= nil)
|
||||
|
||||
x1 = v.Xi(5)
|
||||
|
||||
y1 =v.YXi()
|
||||
assert(y1:spam(x1) == 0)
|
||||
assert(y1:spam() == 0)
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
%module nspace
|
||||
|
||||
// nspace feature only supported by these languages
|
||||
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD)
|
||||
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA)
|
||||
|
||||
#if defined(SWIGJAVA)
|
||||
SWIG_JAVABODY_PROXY(public, public, SWIGTYPE)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
%module nspace_extend
|
||||
|
||||
// nspace feature only supported by these languages
|
||||
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD)
|
||||
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA)
|
||||
|
||||
#if defined(SWIGJAVA)
|
||||
SWIG_JAVABODY_PROXY(public, public, SWIGTYPE)
|
||||
|
|
|
|||
|
|
@ -41,12 +41,12 @@
|
|||
%typemap(consttab) long long, unsigned long long
|
||||
{SWIG_LUA_CONSTTAB_STRING("$symname", "$value")}
|
||||
|
||||
%typemap(consttab) SWIGTYPE *, SWIGTYPE *const, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE []
|
||||
{ SWIG_LUA_POINTER, (char *)"$symname", 0, 0, (void *)$value, &$1_descriptor}
|
||||
%typemap(consttab) SWIGTYPE *, SWIGTYPE *const, SWIGTYPE &, SWIGTYPE []
|
||||
{ SWIG_LUA_CONSTTAB_POINTER("$symname",$value, $1_descriptor) }
|
||||
|
||||
// member function pointers
|
||||
%typemap(consttab) SWIGTYPE (CLASS::*)
|
||||
{ SWIG_LUA_BINARY, (char *)"$symname", sizeof($type), 0, (void *)&$value, &$1_descriptor}
|
||||
{ SWIG_LUA_CONSTTAB_BINARY("$symname", sizeof($type),&$value, $1_descriptor) }
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
|
|
|||
1159
Lib/lua/luarun.swg
1159
Lib/lua/luarun.swg
File diff suppressed because it is too large
Load diff
|
|
@ -36,20 +36,10 @@ SWIGEXPORT int SWIG_init(lua_State* L) /* default Lua action */
|
|||
SWIG_PropagateClientData();
|
||||
#endif
|
||||
|
||||
#if ((SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUA) && (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC))
|
||||
#if ((SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUA) && (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC)) || defined(SWIG_LUA_ELUA_EMULATE)
|
||||
/* add a global fn */
|
||||
SWIG_Lua_add_function(L,"swig_type",SWIG_Lua_type);
|
||||
SWIG_Lua_add_function(L,"swig_equals",SWIG_Lua_equal);
|
||||
/* begin the module (its a table with the same name as the module) */
|
||||
SWIG_Lua_module_begin(L,SWIG_name);
|
||||
/* add commands/functions */
|
||||
for (i = 0; swig_commands[i].name; i++){
|
||||
SWIG_Lua_module_add_function(L,swig_commands[i].name,swig_commands[i].func);
|
||||
}
|
||||
/* add variables */
|
||||
for (i = 0; swig_variables[i].name; i++){
|
||||
SWIG_Lua_module_add_variable(L,swig_variables[i].name,swig_variables[i].get,swig_variables[i].set);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC)
|
||||
|
|
@ -59,17 +49,35 @@ SWIGEXPORT int SWIG_init(lua_State* L) /* default Lua action */
|
|||
SWIG_Lua_init_base_class(L,(swig_lua_class*)(swig_types[i]->clientdata));
|
||||
}
|
||||
}
|
||||
/* additional registration structs & classes in lua */
|
||||
int globalRegister = 0;
|
||||
#ifdef SWIG_LUA_MODULE_GLOBAL
|
||||
globalRegister = 1;
|
||||
#endif
|
||||
|
||||
|
||||
#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_LUA)
|
||||
SWIG_Lua_namespace_register(L,&swig___Module, globalRegister);
|
||||
#endif
|
||||
|
||||
#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) || (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUAC)
|
||||
for (i = 0; swig_types[i]; i++){
|
||||
if (swig_types[i]->clientdata){
|
||||
SWIG_Lua_class_register(L,(swig_lua_class*)(swig_types[i]->clientdata));
|
||||
SWIG_Lua_elua_class_register_instance(L,(swig_lua_class*)(swig_types[i]->clientdata));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ((SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUA) && (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC))
|
||||
/* constants */
|
||||
SWIG_Lua_InstallConstants(L,swig_constants);
|
||||
#if defined(SWIG_LUA_ELUA_EMULATE)
|
||||
lua_newtable(L);
|
||||
SWIG_Lua_elua_emulate_register(L,swig___Module.ns_methods);
|
||||
SWIG_Lua_elua_emulate_register_clear(L);
|
||||
if(globalRegister) {
|
||||
lua_pushstring(L,swig___Module.name);
|
||||
lua_pushvalue(L,-2);
|
||||
lua_rawset(L,-4);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC)
|
||||
|
|
|
|||
|
|
@ -319,8 +319,7 @@ overloading(0),
|
|||
multiinput(0),
|
||||
cplus_runtime(0),
|
||||
directors(0) {
|
||||
Hash *symbols = NewHash();
|
||||
Setattr(symtabs, "", symbols); // create top level/global symbol table scope
|
||||
symbolAddScope(""); // create top level/global symbol table scope
|
||||
argc_template_string = NewString("argc");
|
||||
argv_template_string = NewString("argv[%d]");
|
||||
|
||||
|
|
@ -1490,6 +1489,7 @@ int Language::membervariableHandler(Node *n) {
|
|||
Setattr(n, "type", type);
|
||||
Setattr(n, "name", name);
|
||||
Setattr(n, "sym:name", symname);
|
||||
Delattr(n, "memberset");
|
||||
|
||||
/* Delete all attached typemaps and typemap attributes */
|
||||
Iterator ki;
|
||||
|
|
@ -1507,6 +1507,7 @@ int Language::membervariableHandler(Node *n) {
|
|||
Setattr(n, "sym:name", mrename_get);
|
||||
Setattr(n, "memberget", "1");
|
||||
functionWrapper(n);
|
||||
Delattr(n, "memberget");
|
||||
}
|
||||
Delete(mrename_get);
|
||||
Delete(mrename_set);
|
||||
|
|
@ -2951,11 +2952,14 @@ int Language::constantWrapper(Node *n) {
|
|||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::variableWrapper(Node *n) {
|
||||
Swig_require("variableWrapper", n, "*name", "*sym:name", "*type", "?parms", NIL);
|
||||
Swig_require("variableWrapper", n, "*name", "*sym:name", "*type", "?parms", "?varset", "?varget", NIL);
|
||||
String *symname = Getattr(n, "sym:name");
|
||||
SwigType *type = Getattr(n, "type");
|
||||
String *name = Getattr(n, "name");
|
||||
|
||||
Delattr(n,"varset");
|
||||
Delattr(n,"varget");
|
||||
|
||||
/* If no way to set variables. We simply create functions */
|
||||
int assignable = is_assignable(n);
|
||||
int flags = use_naturalvar_mode(n);
|
||||
|
|
@ -2986,12 +2990,16 @@ int Language::variableWrapper(Node *n) {
|
|||
Delete(pname0);
|
||||
}
|
||||
if (make_set_wrapper) {
|
||||
Setattr(n, "varset", "1");
|
||||
functionWrapper(n);
|
||||
} else {
|
||||
Setattr(n, "feature:immutable", "1");
|
||||
}
|
||||
/* Restore parameters */
|
||||
Setattr(n, "sym:name", symname);
|
||||
Setattr(n, "type", type);
|
||||
Setattr(n, "name", name);
|
||||
Delattr(n, "varset");
|
||||
|
||||
/* Delete all attached typemaps and typemap attributes */
|
||||
Iterator ki;
|
||||
|
|
@ -3005,7 +3013,9 @@ int Language::variableWrapper(Node *n) {
|
|||
String *gname = Swig_name_get(NSpace, symname);
|
||||
Setattr(n, "sym:name", gname);
|
||||
Delete(gname);
|
||||
Setattr(n, "varget", "1");
|
||||
functionWrapper(n);
|
||||
Delattr(n, "varget");
|
||||
Swig_restore(n);
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
|
@ -3049,11 +3059,10 @@ void Language::main(int argc, char *argv[]) {
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
int Language::addSymbol(const String *s, const Node *n, const_String_or_char_ptr scope) {
|
||||
//Printf( stdout, "addSymbol: %s %s\n", s, scope );
|
||||
Hash *symbols = Getattr(symtabs, scope ? scope : "");
|
||||
if (!symbols) {
|
||||
// New scope which has not been added by the target language - lazily created.
|
||||
symbols = NewHash();
|
||||
Setattr(symtabs, scope, symbols);
|
||||
symbols = symbolAddScope(scope);
|
||||
} else {
|
||||
Node *c = Getattr(symbols, s);
|
||||
if (c && (c != n)) {
|
||||
|
|
@ -3069,6 +3078,71 @@ int Language::addSymbol(const String *s, const Node *n, const_String_or_char_ptr
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Lanugage::symbolAddScope( const_String_or_char_ptr scopeName )
|
||||
*
|
||||
* Creates a scope (symbols Hash) for given name. This method is auxilary,
|
||||
* you don't have to call it - addSymbols will lazily create scopes automatically.
|
||||
* If scope with given name already exists, then do nothing.
|
||||
* Returns newly created (or already existing) scope.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
Hash* Language::symbolAddScope(const_String_or_char_ptr scope) {
|
||||
Hash *symbols = symbolScopeLookup(scope);
|
||||
if(!symbols) {
|
||||
// Order in which to following parts are executed is important. In Lanugage
|
||||
// constructor addScope("") is called to create a top level scope itself.
|
||||
// Thus we must first add symbols hash to symtab and only then add pseudo
|
||||
// symbol to top-level scope
|
||||
|
||||
// New scope which has not been added by the target language - lazily created.
|
||||
symbols = NewHash();
|
||||
Setattr(symtabs, scope, symbols);
|
||||
|
||||
// Add the new scope as a symbol in the top level scope.
|
||||
// Alternatively the target language must add it in before attempting to add symbols into the scope.
|
||||
const_String_or_char_ptr top_scope = "";
|
||||
Hash *topscope_symbols = Getattr(symtabs, top_scope);
|
||||
Hash *pseudo_symbol = NewHash();
|
||||
Setattr(pseudo_symbol, "sym:is_scope", "1");
|
||||
Setattr(topscope_symbols, scope, pseudo_symbol);
|
||||
}
|
||||
return symbols;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Lanugage::symbolSscopeLookup( const_String_or_char_ptr scope )
|
||||
*
|
||||
* Lookup and returns a symtable (hash) representing given scope. Hash contains
|
||||
* all symbols in this scope.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
Hash* Language::symbolScopeLookup( const_String_or_char_ptr scope ) {
|
||||
Hash *symbols = Getattr(symtabs, scope ? scope : "");
|
||||
return symbols;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Lanugage::symbolScopeSymbolLookup( const_String_or_char_ptr scope )
|
||||
*
|
||||
* For every scope there is a special pseudo-symbol in the top scope (""). It
|
||||
* exists solely to detect name clashes. This pseudo symbol may contain a few properties,
|
||||
* but you can more if you need to. This is also true fro top level scope ("").
|
||||
* It contains a pseudo symbol with name "" (empty). Pseudo symbol contains the
|
||||
* following properties:
|
||||
* sym:scope = "1" - a flag that this is scope pseudo symbol
|
||||
*
|
||||
* Pseudo symbols are a Hash*, not a Node* (not that there is a difference
|
||||
* in DOH)
|
||||
* There is no difference from symbolLookup() method except for signature
|
||||
* and return type.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
Hash* Language::symbolScopePseudoSymbolLookup( const_String_or_char_ptr scope )
|
||||
{
|
||||
/* Getting top scope */
|
||||
const_String_or_char_ptr top_scope = "";
|
||||
Hash *symbols = Getattr(symtabs, top_scope);
|
||||
return Getattr(symbols, scope);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Language::dumpSymbols()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -215,7 +215,10 @@ public:
|
|||
virtual int validIdentifier(String *s); /* valid identifier? */
|
||||
virtual int addSymbol(const String *s, const Node *n, const_String_or_char_ptr scope = ""); /* Add symbol */
|
||||
virtual void dumpSymbols();
|
||||
virtual Node *symbolLookup(String *s, const_String_or_char_ptr scope = ""); /* Symbol lookup */
|
||||
virtual Node *symbolLookup(String *s, const_String_or_char_ptr scope = ""); /* Symbol lookup */
|
||||
virtual Hash* symbolAddScope(const_String_or_char_ptr scope);
|
||||
virtual Hash* symbolScopeLookup( const_String_or_char_ptr scope );
|
||||
virtual Hash* symbolScopePseudoSymbolLookup( const_String_or_char_ptr scope );
|
||||
virtual Node *classLookup(const SwigType *s) const; /* Class lookup */
|
||||
virtual Node *enumLookup(SwigType *s); /* Enum lookup */
|
||||
virtual int abstractClassTest(Node *n); /* Is class really abstract? */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue