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.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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<n; i++, j-- )
|
||||
for ( int i=0, j=n-1; i<n; i++, j-- )
|
||||
b[j] = (byte) s.luaByte(i);
|
||||
vm.setResult( new LString(b) );
|
||||
}
|
||||
@@ -263,27 +269,24 @@ public class StrLib {
|
||||
* returns a suffix of s with length i.
|
||||
*/
|
||||
static void sub( VM vm ) {
|
||||
final int nargs = vm.getArgCount();
|
||||
final LString s = vm.getArgAsLuaString( 0 );
|
||||
final int len = s.length();
|
||||
|
||||
int i = vm.getArgAsInt( 1 );
|
||||
if ( i < 0 ) {
|
||||
// start at -i characters from the end
|
||||
i = Math.max( len + i, 0 );
|
||||
} else if ( 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 );
|
||||
} else {
|
||||
j = Math.min( Math.max( i, j ), len );
|
||||
}
|
||||
if ( i < 1 )
|
||||
i = 1;
|
||||
if ( j > len )
|
||||
j = len;
|
||||
|
||||
LString result = s.substring( i, j );
|
||||
if ( i <= j ) {
|
||||
LString result = s.substring( i - 1 , j );
|
||||
vm.setResult( result );
|
||||
} else {
|
||||
vm.setResult( new LString( "" ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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 = '%';
|
||||
|
||||
@@ -15,8 +15,14 @@ public class LDouble extends LNumber {
|
||||
}
|
||||
|
||||
public LString luaAsString() {
|
||||
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() {
|
||||
// Cast to int and then back to double and see if the value
|
||||
|
||||
@@ -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) )
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user