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:
Ian Farmer
2007-09-19 04:44:31 +00:00
parent 32e1fedba5
commit fc8c790b0d
5 changed files with 48 additions and 29 deletions

View File

@@ -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;

View File

@@ -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 = '%';

View File

@@ -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

View File

@@ -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.