From fc8c790b0d2342e8762d73d5d4dbc0ed4ef9b494 Mon Sep 17 00:00:00 2001 From: Ian Farmer Date: Wed, 19 Sep 2007 04:44:31 +0000 Subject: [PATCH] Fixes for string.rep, string.byte, string.lower, and string.upper. Also factor out negative index handling to separate function, posrelat (to match C Lua). When converting numbers to strings, see if the double value can be represented exactly as a long, and if so format the string as an integer. With these changes the standard test case "strings.lua" runs to line 104 (over half way through!), where it uses string.format. --- .../java/lua/addon/luacompat/LuaCompat.java | 2 +- .../java/lua/addon/luacompat/StrLib.java | 61 ++++++++++-------- src/main/java/lua/value/LDouble.java | 8 ++- src/test/res/strlib.lua | 6 ++ src/test/res/strlib.luac | Bin 982 -> 1226 bytes 5 files changed, 48 insertions(+), 29 deletions(-) diff --git a/src/addon/java/lua/addon/luacompat/LuaCompat.java b/src/addon/java/lua/addon/luacompat/LuaCompat.java index b90b10fb..ed808808 100644 --- a/src/addon/java/lua/addon/luacompat/LuaCompat.java +++ b/src/addon/java/lua/addon/luacompat/LuaCompat.java @@ -127,7 +127,7 @@ public class LuaCompat extends LFunction { private static final int LEN = STRING_BASE + 7; private static final int LOWER = STRING_BASE + 8; private static final int MATCH = STRING_BASE + 9; - private static final int REP = STRING_BASE + 20; + private static final int REP = STRING_BASE + 10; private static final int REVERSE = STRING_BASE + 11; private static final int SUB = STRING_BASE + 12; private static final int UPPER = STRING_BASE + 13; diff --git a/src/addon/java/lua/addon/luacompat/StrLib.java b/src/addon/java/lua/addon/luacompat/StrLib.java index d8055db8..46f798b5 100644 --- a/src/addon/java/lua/addon/luacompat/StrLib.java +++ b/src/addon/java/lua/addon/luacompat/StrLib.java @@ -19,14 +19,20 @@ public class StrLib { */ static void byte_( VM vm ) { LString ls = vm.getArgAsLuaString(0); - int i = vm.getArgAsInt(1); - int j = vm.getArgAsInt(2); - int n = ls.length(); - i = Math.max(1, i); - j = Math.min(n, (j==0? i: j)); + int l = ls.length(); + final int nargs = vm.getArgCount(); + int i = posrelat( ( nargs > 1 ) ? vm.getArgAsInt(1) : 1, l ); + int j = posrelat( ( nargs > 2 ) ? vm.getArgAsInt(2) : i, l ); vm.setResult(); - for ( int k=i; k<=j; k++ ) - vm.push( new LInteger( ls.luaByte(k-1) ) ); + if ( i <= 0 ) + i = 1; + if ( j > l ) + j = l; + if ( i > j ) + return; + int n = j - i + 1; + for ( int k=0; k < n; k++ ) + vm.push( new LInteger( ls.luaByte(k+i-1) ) ); } /** @@ -200,7 +206,7 @@ public class StrLib { * The definition of what an uppercase letter is depends on the current locale. */ static void lower( VM vm ) { - vm.setResult( new LString( vm.getArgAsString(1).toLowerCase() ) ); + vm.setResult( new LString( vm.getArgAsString(0).toLowerCase() ) ); } /** @@ -243,10 +249,10 @@ public class StrLib { * Returns a string that is the string s reversed. */ static void reverse( VM vm ) { - LString s = vm.getArgAsLuaString(1); + LString s = vm.getArgAsLuaString(0); int n = s.length(); byte[] b = new byte[n]; - for ( int i=0, j=n; i 0 ) { - // start at character i - 1 - i = i - 1; - } + int i = posrelat( nargs > 1 ? vm.getArgAsInt( 1 ) : 1, len ); + int j = posrelat( nargs > 2 ? vm.getArgAsInt( 2 ) : -1, len ); - int j = ( vm.getArgCount() > 2 ) ? vm.getArgAsInt( 2 ): -1; - if ( j < 0 ) { - j = Math.max( i, len + j + 1 ); + if ( i < 1 ) + i = 1; + if ( j > len ) + j = len; + + if ( i <= j ) { + LString result = s.substring( i - 1 , j ); + vm.setResult( result ); } else { - j = Math.min( Math.max( i, j ), len ); + vm.setResult( new LString( "" ) ); } - - LString result = s.substring( i, j ); - vm.setResult( result ); } /** @@ -294,7 +297,7 @@ public class StrLib { * The definition of what a lowercase letter is depends on the current locale. */ static void upper( VM vm ) { - vm.setResult( new LString( vm.getArgAsString(1).toUpperCase() ) ); + vm.setResult( new LString( vm.getArgAsString(0).toUpperCase() ) ); } /** @@ -351,6 +354,10 @@ public class StrLib { vm.setResult( LNil.NIL ); } + private static int posrelat( int pos, int len ) { + return ( pos >= 0 ) ? pos : len + pos + 1; + } + // Pattern matching implementation private static final int L_ESC = '%'; diff --git a/src/main/java/lua/value/LDouble.java b/src/main/java/lua/value/LDouble.java index 453d1272..78909248 100644 --- a/src/main/java/lua/value/LDouble.java +++ b/src/main/java/lua/value/LDouble.java @@ -15,7 +15,13 @@ public class LDouble extends LNumber { } public LString luaAsString() { - return LString.valueOf( m_value ); + long l = (long) m_value; + if ( m_value == (double) l ) { + // TODO: is this a good idea? + return new LString( Long.toString( l ) ); + } else { + return LString.valueOf( m_value ); + } } public boolean isInteger() { diff --git a/src/test/res/strlib.lua b/src/test/res/strlib.lua index f3a97509..54ca5876 100644 --- a/src/test/res/strlib.lua +++ b/src/test/res/strlib.lua @@ -13,3 +13,9 @@ print( string.match( "abbaaababaabaaabaa", "b(a*)()b" ) ) print( string.match( "abbaaababaabaaabaa", "b(a*)()b", 3 ) ) print( string.match( "abbaaababaabaaabaa", "b(a*)()b", 8 ) ) print( string.match( "abbaaababaabaaabaa", "b(a*)()b", 12 ) ) + +print( string.byte("hi", -3) ) + +print( tostring(1234567890123) ) +print( tostring(1234567890124) ) +print( tostring(1234567890125) ) diff --git a/src/test/res/strlib.luac b/src/test/res/strlib.luac index 3ec427f378bc8caed8ebc15c69e5b7378684ae32..4f219cc9d8b5a5b79713e5f9af42867b0eb92ee2 100644 GIT binary patch delta 290 zcmcb{eu{H~24mqy&1}Y4Rt5$JR|f_LH-{q(jSVae2M@3?#4t24$^gZ{azL`tffXpm zfGXC2MeG1VOpc*}L1OYu#)F4I1RMugIDu42esM`rW?ni_ zc!SRd`R|2J%nS!$j0+G3NO|Grc&2Q|6hR;p7ZwJ}p<@xC7&;aOiebY*VK4vyv85=u delta 50 xcmX@bd5wL724nO_&1^