From 4d4517dd586359ceadce51be8149d8bdeac81792 Mon Sep 17 00:00:00 2001 From: James Roseborough Date: Wed, 18 Aug 2010 21:14:13 +0000 Subject: [PATCH] Add __unm and __len metatags. --- src/core/org/luaj/vm2/LuaClosure.java | 2 -- src/core/org/luaj/vm2/LuaString.java | 2 +- src/core/org/luaj/vm2/LuaValue.java | 22 +++++++------ test/lua/metatags.lua | 47 +++++++++++++++++++-------- 4 files changed, 47 insertions(+), 26 deletions(-) diff --git a/src/core/org/luaj/vm2/LuaClosure.java b/src/core/org/luaj/vm2/LuaClosure.java index 31d93bed..a25f6fa2 100644 --- a/src/core/org/luaj/vm2/LuaClosure.java +++ b/src/core/org/luaj/vm2/LuaClosure.java @@ -26,8 +26,6 @@ import org.luaj.vm2.lib.DebugLib; public class LuaClosure extends LuaFunction { private static final UpValue[] NOUPVALUES = new UpValue[0]; - public LuaValue s_metatable; - public final Prototype p; public final UpValue[] upValues; diff --git a/src/core/org/luaj/vm2/LuaString.java b/src/core/org/luaj/vm2/LuaString.java index d4460ade..aa11270d 100644 --- a/src/core/org/luaj/vm2/LuaString.java +++ b/src/core/org/luaj/vm2/LuaString.java @@ -109,7 +109,7 @@ public class LuaString extends LuaValue { } // unary operators - public LuaValue neg() { return valueOf(-checkarith()); } + public LuaValue neg() { double d = scannumber(10); return Double.isNaN(d)? super.neg(): valueOf(-d); } // basic binary arithmetic public LuaValue add( LuaValue rhs ) { double d = scannumber(10); return Double.isNaN(d)? arithmt(ADD,rhs): rhs.add(d); } diff --git a/src/core/org/luaj/vm2/LuaValue.java b/src/core/org/luaj/vm2/LuaValue.java index 3df3ef88..86908888 100644 --- a/src/core/org/luaj/vm2/LuaValue.java +++ b/src/core/org/luaj/vm2/LuaValue.java @@ -64,14 +64,16 @@ public class LuaValue extends Varargs { public static final LuaString INDEX = valueOf("__index"); public static final LuaString NEWINDEX = valueOf("__newindex"); public static final LuaString CALL = valueOf("__call"); - public static final LuaString MODE = valueOf("__mode"); + public static final LuaString MODE = valueOf("__mode"); public static final LuaString METATABLE = valueOf("__metatable"); - public static final LuaString ADD = valueOf("__add"); - public static final LuaString SUB = valueOf("__sub"); - public static final LuaString DIV = valueOf("__div"); - public static final LuaString MUL = valueOf("__mul"); - public static final LuaString POW = valueOf("__pow"); - public static final LuaString MOD = valueOf("__mod"); + public static final LuaString ADD = valueOf("__add"); + public static final LuaString SUB = valueOf("__sub"); + public static final LuaString DIV = valueOf("__div"); + public static final LuaString MUL = valueOf("__mul"); + public static final LuaString POW = valueOf("__pow"); + public static final LuaString MOD = valueOf("__mod"); + public static final LuaString UNM = valueOf("__unm"); + public static final LuaString LEN = valueOf("__len"); public static final LuaString EMPTYSTRING = valueOf(""); private static int MAXSTACK = 250; @@ -247,9 +249,9 @@ public class LuaValue extends Varargs { // unary operators public LuaValue not() { return FALSE; } - public LuaValue neg() { return aritherror("neg"); } - public LuaValue len() { return lenerror(); } - public int length() { error("attempt to get length of "+typename()); return 0; } + public LuaValue neg() { return checkmetatag(UNM, "attempt to perform arithmetic on ").call(this); } + public LuaValue len() { return checkmetatag(LEN, "attempt to get length of ").call(this); } + public int length() { return len().toint(); } public LuaValue getn() { return typerror("getn"); } // object equality, used for key comparison diff --git a/test/lua/metatags.lua b/test/lua/metatags.lua index 130a3fa8..ac151612 100644 --- a/test/lua/metatags.lua +++ b/test/lua/metatags.lua @@ -3,7 +3,7 @@ local anumber = 111 local aboolean = false local afunction = function() end local athread = coroutine.create( afunction ) -local values = { athread, aboolean, afunction, athread } +local values = { anumber, aboolean, afunction, athread } for i=1,#values do print( debug.getmetatable( values[i] ) ) end @@ -13,7 +13,14 @@ tostring = function(o) return (t=='thread' or t=='function') and t or ts(o) end -local buildbin = function(name) +local buildunop = function(name) + return function(a) + print( 'mt.__'..name..'()', type(a), a ) + return '__'..name..'-result' + end +end + +local buildbinop = function(name) return function(a,b) print( 'mt.__'..name..'()', type(a), type(b), a, b ) return '__'..name..'-result' @@ -25,12 +32,14 @@ local mt = { print( 'mt.__call()', type(a), type(b), type(c), b, c ) return '__call-result' end, - __add=buildbin('add'), - __sub=buildbin('sub'), - __mul=buildbin('mul'), - __div=buildbin('div'), - __pow=buildbin('pow'), - __mod=buildbin('mod'), + __add=buildbinop('add'), + __sub=buildbinop('sub'), + __mul=buildbinop('mul'), + __div=buildbinop('div'), + __pow=buildbinop('pow'), + __mod=buildbinop('mod'), + __unm=buildunop('unm'), + __len=buildunop('neg'), } -- pcall a function and check for a pattern in the error string @@ -80,10 +89,22 @@ for i=1,#groups do print( debug.setmetatable( a, nil ) ) end - - -print( '---- final metatables' ) -for i=1,#values do - print( debug.getmetatable( values[i] ) ) +print( '---- __len' ) +values = { aboolean, afunction, athread } +for i=1,#values do + print( type(values[i]), 'before', ecall( 'attempt to get length of ', function() return #values[i] end ) ) + print( debug.setmetatable( values[i], mt ) ) + print( type(values[i]), 'after', pcall( function() return #values[i] end ) ) + print( debug.setmetatable( values[i], nil ) ) end + +print( '---- __neg' ) +values = { aboolean, afunction, athread, "abcd" } +for i=1,#values do + print( type(values[i]), 'before', ecall( 'attempt to get length of ', function() return #values[i] end ) ) + print( debug.setmetatable( values[i], mt ) ) + print( type(values[i]), 'after', pcall( function() return #values[i] end ) ) + print( debug.setmetatable( values[i], nil ) ) +end + \ No newline at end of file