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 LEN = STRING_BASE + 7;
|
||||||
private static final int LOWER = STRING_BASE + 8;
|
private static final int LOWER = STRING_BASE + 8;
|
||||||
private static final int MATCH = STRING_BASE + 9;
|
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 REVERSE = STRING_BASE + 11;
|
||||||
private static final int SUB = STRING_BASE + 12;
|
private static final int SUB = STRING_BASE + 12;
|
||||||
private static final int UPPER = STRING_BASE + 13;
|
private static final int UPPER = STRING_BASE + 13;
|
||||||
|
|||||||
@@ -19,14 +19,20 @@ public class StrLib {
|
|||||||
*/
|
*/
|
||||||
static void byte_( VM vm ) {
|
static void byte_( VM vm ) {
|
||||||
LString ls = vm.getArgAsLuaString(0);
|
LString ls = vm.getArgAsLuaString(0);
|
||||||
int i = vm.getArgAsInt(1);
|
int l = ls.length();
|
||||||
int j = vm.getArgAsInt(2);
|
final int nargs = vm.getArgCount();
|
||||||
int n = ls.length();
|
int i = posrelat( ( nargs > 1 ) ? vm.getArgAsInt(1) : 1, l );
|
||||||
i = Math.max(1, i);
|
int j = posrelat( ( nargs > 2 ) ? vm.getArgAsInt(2) : i, l );
|
||||||
j = Math.min(n, (j==0? i: j));
|
|
||||||
vm.setResult();
|
vm.setResult();
|
||||||
for ( int k=i; k<=j; k++ )
|
if ( i <= 0 )
|
||||||
vm.push( new LInteger( ls.luaByte(k-1) ) );
|
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.
|
* The definition of what an uppercase letter is depends on the current locale.
|
||||||
*/
|
*/
|
||||||
static void lower( VM vm ) {
|
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.
|
* Returns a string that is the string s reversed.
|
||||||
*/
|
*/
|
||||||
static void reverse( VM vm ) {
|
static void reverse( VM vm ) {
|
||||||
LString s = vm.getArgAsLuaString(1);
|
LString s = vm.getArgAsLuaString(0);
|
||||||
int n = s.length();
|
int n = s.length();
|
||||||
byte[] b = new byte[n];
|
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);
|
b[j] = (byte) s.luaByte(i);
|
||||||
vm.setResult( new LString(b) );
|
vm.setResult( new LString(b) );
|
||||||
}
|
}
|
||||||
@@ -263,27 +269,24 @@ public class StrLib {
|
|||||||
* returns a suffix of s with length i.
|
* returns a suffix of s with length i.
|
||||||
*/
|
*/
|
||||||
static void sub( VM vm ) {
|
static void sub( VM vm ) {
|
||||||
|
final int nargs = vm.getArgCount();
|
||||||
final LString s = vm.getArgAsLuaString( 0 );
|
final LString s = vm.getArgAsLuaString( 0 );
|
||||||
final int len = s.length();
|
final int len = s.length();
|
||||||
|
|
||||||
int i = vm.getArgAsInt( 1 );
|
int i = posrelat( nargs > 1 ? vm.getArgAsInt( 1 ) : 1, len );
|
||||||
if ( i < 0 ) {
|
int j = posrelat( nargs > 2 ? vm.getArgAsInt( 2 ) : -1, len );
|
||||||
// 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 j = ( vm.getArgCount() > 2 ) ? vm.getArgAsInt( 2 ): -1;
|
if ( i < 1 )
|
||||||
if ( j < 0 ) {
|
i = 1;
|
||||||
j = Math.max( i, len + j + 1 );
|
if ( j > len )
|
||||||
} else {
|
j = len;
|
||||||
j = Math.min( Math.max( i, j ), len );
|
|
||||||
}
|
|
||||||
|
|
||||||
LString result = s.substring( i, j );
|
if ( i <= j ) {
|
||||||
|
LString result = s.substring( i - 1 , j );
|
||||||
vm.setResult( result );
|
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.
|
* The definition of what a lowercase letter is depends on the current locale.
|
||||||
*/
|
*/
|
||||||
static void upper( VM vm ) {
|
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 );
|
vm.setResult( LNil.NIL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int posrelat( int pos, int len ) {
|
||||||
|
return ( pos >= 0 ) ? pos : len + pos + 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Pattern matching implementation
|
// Pattern matching implementation
|
||||||
|
|
||||||
private static final int L_ESC = '%';
|
private static final int L_ESC = '%';
|
||||||
|
|||||||
@@ -15,8 +15,14 @@ public class LDouble extends LNumber {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public LString luaAsString() {
|
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 );
|
return LString.valueOf( m_value );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isInteger() {
|
public boolean isInteger() {
|
||||||
// Cast to int and then back to double and see if the value
|
// 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", 3 ) )
|
||||||
print( string.match( "abbaaababaabaaabaa", "b(a*)()b", 8 ) )
|
print( string.match( "abbaaababaabaaabaa", "b(a*)()b", 8 ) )
|
||||||
print( string.match( "abbaaababaabaaabaa", "b(a*)()b", 12 ) )
|
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