[NOTHING CHANGED] Assorted fixes #48
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,7 +1,6 @@
|
||||
bin/
|
||||
target/
|
||||
build/
|
||||
lib/
|
||||
jit/
|
||||
*.ser
|
||||
*.gz
|
||||
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2007 LuaJ. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -18,7 +18,7 @@ James Roseborough, Ian Farmer, Version 3.0.2
|
||||
<small>
|
||||
Copyright © 2009-2014 Luaj.org.
|
||||
Freely available under the terms of the
|
||||
<a href="http://sourceforge.net/dbimage.php?id=196142">Luaj license</a>.
|
||||
<a href="LICENSE">Luaj license</a>.
|
||||
</small>
|
||||
<hr>
|
||||
<p>
|
||||
@@ -412,7 +412,7 @@ and the math operations include all those supported by Java SE.
|
||||
Android applications should use the JsePlatform, and can include the <a href="#luajava">Luajava</a> library
|
||||
to simplify access to underlying Android APIs.
|
||||
A specialized Globals.finder should be provided to find scripts and data for loading.
|
||||
See <a href="examples/android/src/android/LuajView">examples/android/src/android/LuajView</a>
|
||||
See <a href="examples/android/src/android/LuajView.java">examples/android/src/android/LuajView.java</a>
|
||||
for an example that loads from the "res" Android project directory.
|
||||
The ant build script is <a href="examples/android/build.xml">examples/android/build.xml</a>.
|
||||
|
||||
|
||||
@@ -155,7 +155,6 @@ public class LoadState {
|
||||
private static final LuaValue[] NOVALUES = {};
|
||||
private static final Prototype[] NOPROTOS = {};
|
||||
private static final LocVars[] NOLOCVARS = {};
|
||||
private static final LuaString[] NOSTRVALUES = {};
|
||||
private static final Upvaldesc[] NOUPVALDESCS = {};
|
||||
private static final int[] NOINTS = {};
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2;
|
||||
|
||||
import org.luaj.vm2.lib.DebugLib.CallFrame;
|
||||
|
||||
/**
|
||||
* Extension of {@link LuaFunction} which executes lua bytecode.
|
||||
* <p>
|
||||
@@ -415,7 +417,7 @@ public class LuaClosure extends LuaFunction {
|
||||
{
|
||||
LuaValue limit = stack[a + 1];
|
||||
LuaValue step = stack[a + 2];
|
||||
LuaValue idx = step.add(stack[a]);
|
||||
LuaValue idx = stack[a].add(step);
|
||||
if (step.gt_b(0)? idx.lteq_b(limit): idx.gteq_b(limit)) {
|
||||
stack[a] = idx;
|
||||
stack[a + 3] = idx;
|
||||
@@ -547,8 +549,24 @@ public class LuaClosure extends LuaFunction {
|
||||
}
|
||||
|
||||
private void processErrorHooks(LuaError le, Prototype p, int pc) {
|
||||
le.fileline = (p.source != null? p.source.tojstring(): "?") + ":"
|
||||
+ (p.lineinfo != null && pc >= 0 && pc < p.lineinfo.length? String.valueOf(p.lineinfo[pc]): "?") + ": ";
|
||||
String file = "?";
|
||||
int line = -1;
|
||||
{
|
||||
CallFrame frame = null;
|
||||
if (globals != null && globals.debuglib != null) {
|
||||
frame = globals.debuglib.getCallFrame(le.level);
|
||||
if (frame != null) {
|
||||
String src = frame.shortsource();
|
||||
file = src != null ? src : "?";
|
||||
line = frame.currentline();
|
||||
}
|
||||
}
|
||||
if (frame == null) {
|
||||
file = p.source != null? p.source.tojstring(): "?";
|
||||
line = p.lineinfo != null && pc >= 0 && pc < p.lineinfo.length ? p.lineinfo[pc] : -1;
|
||||
}
|
||||
}
|
||||
le.fileline = file + ": " + line;
|
||||
le.traceback = errorHook(le.getMessage(), le.level);
|
||||
}
|
||||
|
||||
|
||||
@@ -213,28 +213,28 @@ public class LuaDouble extends LuaNumber {
|
||||
}
|
||||
|
||||
// relational operators
|
||||
public LuaValue lt( LuaValue rhs ) { return rhs.gt_b(v)? LuaValue.TRUE: FALSE; }
|
||||
public LuaValue lt( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.gt_b(v)? TRUE: FALSE) : super.lt(rhs); }
|
||||
public LuaValue lt( double rhs ) { return v < rhs? TRUE: FALSE; }
|
||||
public LuaValue lt( int rhs ) { return v < rhs? TRUE: FALSE; }
|
||||
public boolean lt_b( LuaValue rhs ) { return rhs.gt_b(v); }
|
||||
public boolean lt_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.gt_b(v) : super.lt_b(rhs); }
|
||||
public boolean lt_b( int rhs ) { return v < rhs; }
|
||||
public boolean lt_b( double rhs ) { return v < rhs; }
|
||||
public LuaValue lteq( LuaValue rhs ) { return rhs.gteq_b(v)? LuaValue.TRUE: FALSE; }
|
||||
public LuaValue lteq( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.gteq_b(v)? TRUE: FALSE) : super.lteq(rhs); }
|
||||
public LuaValue lteq( double rhs ) { return v <= rhs? TRUE: FALSE; }
|
||||
public LuaValue lteq( int rhs ) { return v <= rhs? TRUE: FALSE; }
|
||||
public boolean lteq_b( LuaValue rhs ) { return rhs.gteq_b(v); }
|
||||
public boolean lteq_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.gteq_b(v) : super.lteq_b(rhs); }
|
||||
public boolean lteq_b( int rhs ) { return v <= rhs; }
|
||||
public boolean lteq_b( double rhs ) { return v <= rhs; }
|
||||
public LuaValue gt( LuaValue rhs ) { return rhs.lt_b(v)? LuaValue.TRUE: FALSE; }
|
||||
public LuaValue gt( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.lt_b(v)? TRUE: FALSE) : super.gt(rhs); }
|
||||
public LuaValue gt( double rhs ) { return v > rhs? TRUE: FALSE; }
|
||||
public LuaValue gt( int rhs ) { return v > rhs? TRUE: FALSE; }
|
||||
public boolean gt_b( LuaValue rhs ) { return rhs.lt_b(v); }
|
||||
public boolean gt_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.lt_b(v) : super.gt_b(rhs); }
|
||||
public boolean gt_b( int rhs ) { return v > rhs; }
|
||||
public boolean gt_b( double rhs ) { return v > rhs; }
|
||||
public LuaValue gteq( LuaValue rhs ) { return rhs.lteq_b(v)? LuaValue.TRUE: FALSE; }
|
||||
public LuaValue gteq( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.lteq_b(v)? TRUE: FALSE) : super.gteq(rhs); }
|
||||
public LuaValue gteq( double rhs ) { return v >= rhs? TRUE: FALSE; }
|
||||
public LuaValue gteq( int rhs ) { return v >= rhs? TRUE: FALSE; }
|
||||
public boolean gteq_b( LuaValue rhs ) { return rhs.lteq_b(v); }
|
||||
public boolean gteq_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.lteq_b(v) : super.gteq_b(rhs); }
|
||||
public boolean gteq_b( int rhs ) { return v >= rhs; }
|
||||
public boolean gteq_b( double rhs ) { return v >= rhs; }
|
||||
|
||||
|
||||
@@ -74,10 +74,13 @@ public class LuaFunction extends LuaValue {
|
||||
|
||||
/** Return the last part of the class name, to be used as a function name in tojstring and elsewhere.
|
||||
* @return String naming the last part of the class name after the last dot (.) or dollar sign ($).
|
||||
* If the first character is '_', it is skipped.
|
||||
*/
|
||||
public String classnamestub() {
|
||||
String s = getClass().getName();
|
||||
return s.substring(Math.max(s.lastIndexOf('.'),s.lastIndexOf('$'))+1);
|
||||
int offset = Math.max(s.lastIndexOf('.'), s.lastIndexOf('$')) + 1;
|
||||
if (s.charAt(offset) == '_') offset++;
|
||||
return s.substring(offset);
|
||||
}
|
||||
|
||||
/** Return a human-readable name for this function. Returns the last part of the class name by default.
|
||||
|
||||
@@ -172,28 +172,28 @@ public class LuaInteger extends LuaNumber {
|
||||
public LuaValue modFrom( double lhs ) { return LuaDouble.dmod(lhs,v); }
|
||||
|
||||
// relational operators
|
||||
public LuaValue lt( LuaValue rhs ) { return rhs.gt_b(v)? TRUE: FALSE; }
|
||||
public LuaValue lt( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.gt_b(v)? TRUE: FALSE) : super.lt(rhs); }
|
||||
public LuaValue lt( double rhs ) { return v < rhs? TRUE: FALSE; }
|
||||
public LuaValue lt( int rhs ) { return v < rhs? TRUE: FALSE; }
|
||||
public boolean lt_b( LuaValue rhs ) { return rhs.gt_b(v); }
|
||||
public boolean lt_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.gt_b(v) : super.lt_b(rhs); }
|
||||
public boolean lt_b( int rhs ) { return v < rhs; }
|
||||
public boolean lt_b( double rhs ) { return v < rhs; }
|
||||
public LuaValue lteq( LuaValue rhs ) { return rhs.gteq_b(v)? TRUE: FALSE; }
|
||||
public LuaValue lteq( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.gteq_b(v)? TRUE: FALSE) : super.lteq(rhs); }
|
||||
public LuaValue lteq( double rhs ) { return v <= rhs? TRUE: FALSE; }
|
||||
public LuaValue lteq( int rhs ) { return v <= rhs? TRUE: FALSE; }
|
||||
public boolean lteq_b( LuaValue rhs ) { return rhs.gteq_b(v); }
|
||||
public boolean lteq_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.gteq_b(v) : super.lteq_b(rhs); }
|
||||
public boolean lteq_b( int rhs ) { return v <= rhs; }
|
||||
public boolean lteq_b( double rhs ) { return v <= rhs; }
|
||||
public LuaValue gt( LuaValue rhs ) { return rhs.lt_b(v)? TRUE: FALSE; }
|
||||
public LuaValue gt( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.lt_b(v)? TRUE: FALSE) : super.gt(rhs); }
|
||||
public LuaValue gt( double rhs ) { return v > rhs? TRUE: FALSE; }
|
||||
public LuaValue gt( int rhs ) { return v > rhs? TRUE: FALSE; }
|
||||
public boolean gt_b( LuaValue rhs ) { return rhs.lt_b(v); }
|
||||
public boolean gt_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.lt_b(v) : super.gt_b(rhs); }
|
||||
public boolean gt_b( int rhs ) { return v > rhs; }
|
||||
public boolean gt_b( double rhs ) { return v > rhs; }
|
||||
public LuaValue gteq( LuaValue rhs ) { return rhs.lteq_b(v)? TRUE: FALSE; }
|
||||
public LuaValue gteq( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.lteq_b(v)? TRUE: FALSE) : super.gteq(rhs); }
|
||||
public LuaValue gteq( double rhs ) { return v >= rhs? TRUE: FALSE; }
|
||||
public LuaValue gteq( int rhs ) { return v >= rhs? TRUE: FALSE; }
|
||||
public boolean gteq_b( LuaValue rhs ) { return rhs.lteq_b(v); }
|
||||
public boolean gteq_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.lteq_b(v) : super.gteq_b(rhs); }
|
||||
public boolean gteq_b( int rhs ) { return v >= rhs; }
|
||||
public boolean gteq_b( double rhs ) { return v >= rhs; }
|
||||
|
||||
|
||||
@@ -289,20 +289,20 @@ public class LuaString extends LuaValue {
|
||||
public LuaValue modFrom( double lhs ) { return LuaDouble.dmod(lhs, checkarith()); }
|
||||
|
||||
// relational operators, these only work with other strings
|
||||
public LuaValue lt( LuaValue rhs ) { return rhs.strcmp(this)>0? LuaValue.TRUE: FALSE; }
|
||||
public boolean lt_b( LuaValue rhs ) { return rhs.strcmp(this)>0; }
|
||||
public LuaValue lt( LuaValue rhs ) { return rhs.isstring() ? (rhs.strcmp(this)>0? LuaValue.TRUE: FALSE) : super.lt(rhs); }
|
||||
public boolean lt_b( LuaValue rhs ) { return rhs.isstring() ? rhs.strcmp(this)>0 : super.lt_b(rhs); }
|
||||
public boolean lt_b( int rhs ) { typerror("attempt to compare string with number"); return false; }
|
||||
public boolean lt_b( double rhs ) { typerror("attempt to compare string with number"); return false; }
|
||||
public LuaValue lteq( LuaValue rhs ) { return rhs.strcmp(this)>=0? LuaValue.TRUE: FALSE; }
|
||||
public boolean lteq_b( LuaValue rhs ) { return rhs.strcmp(this)>=0; }
|
||||
public LuaValue lteq( LuaValue rhs ) { return rhs.isstring() ? (rhs.strcmp(this)>=0? LuaValue.TRUE: FALSE) : super.lteq(rhs); }
|
||||
public boolean lteq_b( LuaValue rhs ) { return rhs.isstring() ? rhs.strcmp(this)>=0 : super.lteq_b(rhs); }
|
||||
public boolean lteq_b( int rhs ) { typerror("attempt to compare string with number"); return false; }
|
||||
public boolean lteq_b( double rhs ) { typerror("attempt to compare string with number"); return false; }
|
||||
public LuaValue gt( LuaValue rhs ) { return rhs.strcmp(this)<0? LuaValue.TRUE: FALSE; }
|
||||
public boolean gt_b( LuaValue rhs ) { return rhs.strcmp(this)<0; }
|
||||
public LuaValue gt( LuaValue rhs ) { return rhs.isstring() ? (rhs.strcmp(this)<0? LuaValue.TRUE: FALSE) : super.gt(rhs); }
|
||||
public boolean gt_b( LuaValue rhs ) { return rhs.isstring() ? rhs.strcmp(this)<0 : super.gt_b(rhs); }
|
||||
public boolean gt_b( int rhs ) { typerror("attempt to compare string with number"); return false; }
|
||||
public boolean gt_b( double rhs ) { typerror("attempt to compare string with number"); return false; }
|
||||
public LuaValue gteq( LuaValue rhs ) { return rhs.strcmp(this)<=0? LuaValue.TRUE: FALSE; }
|
||||
public boolean gteq_b( LuaValue rhs ) { return rhs.strcmp(this)<=0; }
|
||||
public LuaValue gteq( LuaValue rhs ) { return rhs.isstring() ? (rhs.strcmp(this)<=0? LuaValue.TRUE: FALSE) : super.gteq(rhs); }
|
||||
public boolean gteq_b( LuaValue rhs ) { return rhs.isstring() ? rhs.strcmp(this)<=0 : super.gteq_b(rhs); }
|
||||
public boolean gteq_b( int rhs ) { typerror("attempt to compare string with number"); return false; }
|
||||
public boolean gteq_b( double rhs ) { typerror("attempt to compare string with number"); return false; }
|
||||
|
||||
|
||||
@@ -299,15 +299,15 @@ public class LuaTable extends LuaValue implements Metatable {
|
||||
* @return The removed item, or {@link #NONE} if not removed
|
||||
*/
|
||||
public LuaValue remove(int pos) {
|
||||
int n = rawlen();
|
||||
int n = length();
|
||||
if ( pos == 0 )
|
||||
pos = n;
|
||||
else if (pos > n)
|
||||
return NONE;
|
||||
LuaValue v = rawget(pos);
|
||||
LuaValue v = get(pos);
|
||||
for ( LuaValue r=v; !r.isnil(); ) {
|
||||
r = rawget(pos+1);
|
||||
rawset(pos++, r);
|
||||
r = get(pos+1);
|
||||
set(pos++, r);
|
||||
}
|
||||
return v.isnil()? NONE: v;
|
||||
}
|
||||
@@ -319,10 +319,10 @@ public class LuaTable extends LuaValue implements Metatable {
|
||||
*/
|
||||
public void insert(int pos, LuaValue value) {
|
||||
if ( pos == 0 )
|
||||
pos = rawlen()+1;
|
||||
pos = length()+1;
|
||||
while ( ! value.isnil() ) {
|
||||
LuaValue v = rawget( pos );
|
||||
rawset(pos++, value);
|
||||
LuaValue v = get( pos );
|
||||
set(pos++, value);
|
||||
value = v;
|
||||
}
|
||||
}
|
||||
@@ -472,7 +472,8 @@ public class LuaTable extends LuaValue implements Metatable {
|
||||
}
|
||||
}
|
||||
if ( checkLoadFactor() ) {
|
||||
if ( key.isinttype() && key.toint() > 0 ) {
|
||||
if ( (m_metatable == null || !m_metatable.useWeakValues())
|
||||
&& key.isinttype() && key.toint() > 0 ) {
|
||||
// a rehash might make room in the array portion for this key.
|
||||
rehash( key.toint() );
|
||||
if ( arrayset(key.toint(), value) )
|
||||
@@ -719,7 +720,7 @@ public class LuaTable extends LuaValue implements Metatable {
|
||||
StrongSlot entry = slot.first();
|
||||
if (entry != null)
|
||||
newArray[ k - 1 ] = entry.value();
|
||||
} else {
|
||||
} else if ( !(slot instanceof DeadSlot) ) {
|
||||
int j = slot.keyindex( newHashMask );
|
||||
newHash[j] = slot.relink( newHash[j] );
|
||||
}
|
||||
@@ -789,33 +790,35 @@ public class LuaTable extends LuaValue implements Metatable {
|
||||
if (m_metatable != null && m_metatable.useWeakValues()) {
|
||||
dropWeakArrayValues();
|
||||
}
|
||||
int n = array.length;
|
||||
while ( n > 0 && array[n-1] == null )
|
||||
--n;
|
||||
int n = length();
|
||||
if ( n > 1 )
|
||||
heapSort(n, comparator);
|
||||
heapSort(n, comparator.isnil() ? null : comparator);
|
||||
}
|
||||
|
||||
private void heapSort(int count, LuaValue cmpfunc) {
|
||||
heapify(count, cmpfunc);
|
||||
for ( int end=count-1; end>0; ) {
|
||||
swap(end, 0);
|
||||
siftDown(0, --end, cmpfunc);
|
||||
for ( int end=count; end>1; ) {
|
||||
LuaValue a = get(end); // swap(end, 1)
|
||||
set(end, get(1));
|
||||
set(1, a);
|
||||
siftDown(1, --end, cmpfunc);
|
||||
}
|
||||
}
|
||||
|
||||
private void heapify(int count, LuaValue cmpfunc) {
|
||||
for ( int start=count/2-1; start>=0; --start )
|
||||
siftDown(start, count - 1, cmpfunc);
|
||||
for ( int start=count/2; start>0; --start )
|
||||
siftDown(start, count, cmpfunc);
|
||||
}
|
||||
|
||||
private void siftDown(int start, int end, LuaValue cmpfunc) {
|
||||
for ( int root=start; root*2+1 <= end; ) {
|
||||
int child = root*2+1;
|
||||
for ( int root=start; root*2 <= end; ) {
|
||||
int child = root*2;
|
||||
if (child < end && compare(child, child + 1, cmpfunc))
|
||||
++child;
|
||||
if (compare(root, child, cmpfunc)) {
|
||||
swap(root, child);
|
||||
LuaValue a = get(root); // swap(root, child)
|
||||
set(root, get(child));
|
||||
set(child, a);
|
||||
root = child;
|
||||
} else
|
||||
return;
|
||||
@@ -823,29 +826,16 @@ public class LuaTable extends LuaValue implements Metatable {
|
||||
}
|
||||
|
||||
private boolean compare(int i, int j, LuaValue cmpfunc) {
|
||||
LuaValue a, b;
|
||||
if (m_metatable == null) {
|
||||
a = array[i];
|
||||
b = array[j];
|
||||
} else {
|
||||
a = m_metatable.arrayget(array, i);
|
||||
b = m_metatable.arrayget(array, j);
|
||||
}
|
||||
LuaValue a = get(i), b = get(j);
|
||||
if ( a == null || b == null )
|
||||
return false;
|
||||
if ( ! cmpfunc.isnil() ) {
|
||||
if ( cmpfunc != null ) {
|
||||
return cmpfunc.call(a,b).toboolean();
|
||||
} else {
|
||||
return a.lt_b(b);
|
||||
}
|
||||
}
|
||||
|
||||
private void swap(int i, int j) {
|
||||
LuaValue a = array[i];
|
||||
array[i] = array[j];
|
||||
array[j] = a;
|
||||
}
|
||||
|
||||
/** This may be deprecated in a future release.
|
||||
* It is recommended to count via iteration over next() instead
|
||||
* @return count of keys in the table
|
||||
|
||||
@@ -291,7 +291,7 @@ public abstract class Varargs {
|
||||
* @return java double value if argument i is a number or string that converts to a number
|
||||
* @exception LuaError if the argument is not a number
|
||||
* */
|
||||
public double checkdouble(int i) { return arg(i).checknumber().todouble(); }
|
||||
public double checkdouble(int i) { return arg(i).checkdouble(); }
|
||||
|
||||
/** Return argument i as a function, or throw an error if an incompatible type.
|
||||
* @param i the index of the argument to test, 1 is the first argument
|
||||
@@ -300,12 +300,12 @@ public abstract class Varargs {
|
||||
* */
|
||||
public LuaFunction checkfunction(int i) { return arg(i).checkfunction(); }
|
||||
|
||||
/** Return argument i as a java int value, discarding any fractional part, or throw an error if not a number.
|
||||
/** Return argument i as a java int value, or throw an error if it cannot be converted to one.
|
||||
* @param i the index of the argument to test, 1 is the first argument
|
||||
* @return int value with fraction discarded and truncated if necessary if argument i is number
|
||||
* @exception LuaError if the argument is not a number
|
||||
* @return int value if argument i is a number or string that converts to a number
|
||||
* @exception LuaError if the argument cannot be represented by a java int value
|
||||
* */
|
||||
public int checkint(int i) { return arg(i).checknumber().toint(); }
|
||||
public int checkint(int i) { return arg(i).checkint(); }
|
||||
|
||||
/** Return argument i as a java int value, or throw an error if not a number or is not representable by a java int.
|
||||
* @param i the index of the argument to test, 1 is the first argument
|
||||
@@ -314,12 +314,12 @@ public abstract class Varargs {
|
||||
* */
|
||||
public LuaInteger checkinteger(int i) { return arg(i).checkinteger(); }
|
||||
|
||||
/** Return argument i as a java long value, discarding any fractional part, or throw an error if not a number.
|
||||
/** Return argument i as a java long value, or throw an error if it cannot be converted to one.
|
||||
* @param i the index of the argument to test, 1 is the first argument
|
||||
* @return long value with fraction discarded and truncated if necessary if argument i is number
|
||||
* @exception LuaError if the argument is not a number
|
||||
* @return long value if argument i is a number or string that converts to a number
|
||||
* @exception LuaError if the argument cannot be represented by a java long value
|
||||
* */
|
||||
public long checklong(int i) { return arg(i).checknumber().tolong(); }
|
||||
public long checklong(int i) { return arg(i).checklong(); }
|
||||
|
||||
/** Return argument i as a LuaNumber, or throw an error if not a number or string that can be converted to a number.
|
||||
* @param i the index of the argument to test, 1 is the first argument
|
||||
@@ -707,8 +707,10 @@ public abstract class Varargs {
|
||||
/** Return Varargs that cannot be using a shared array for the storage, and is flattened.
|
||||
* Internal utility method not intended to be called directly from user code.
|
||||
* @return Varargs containing same values, but flattened and with a new array if needed.
|
||||
* @exclude
|
||||
* @hide
|
||||
*/
|
||||
Varargs dealias() {
|
||||
public Varargs dealias() {
|
||||
int n = narg();
|
||||
switch (n) {
|
||||
case 0: return LuaValue.NONE;
|
||||
|
||||
@@ -28,9 +28,9 @@ import java.io.OutputStream;
|
||||
import org.luaj.vm2.Globals;
|
||||
import org.luaj.vm2.LoadState;
|
||||
import org.luaj.vm2.LocVars;
|
||||
import org.luaj.vm2.Prototype;
|
||||
import org.luaj.vm2.LuaString;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.Prototype;
|
||||
|
||||
|
||||
/** Class to dump a {@link Prototype} into an output stream, as part of compiling.
|
||||
@@ -85,7 +85,7 @@ public class DumpState {
|
||||
public static final int NUMBER_FORMAT_DEFAULT = NUMBER_FORMAT_FLOATS_OR_DOUBLES;
|
||||
|
||||
// header fields
|
||||
private boolean IS_LITTLE_ENDIAN = false;
|
||||
private boolean IS_LITTLE_ENDIAN = true;
|
||||
private int NUMBER_FORMAT = NUMBER_FORMAT_DEFAULT;
|
||||
private int SIZEOF_LUA_NUMBER = 8;
|
||||
private static final int SIZEOF_INT = 4;
|
||||
|
||||
@@ -198,7 +198,7 @@ public class LexState extends Constants {
|
||||
}
|
||||
|
||||
private boolean isspace(int c) {
|
||||
return (c <= ' ');
|
||||
return (c >= 0 && c <= ' ');
|
||||
}
|
||||
|
||||
|
||||
@@ -388,8 +388,13 @@ public class LexState extends Constants {
|
||||
seminfo.r = LuaValue.ZERO;
|
||||
else if (str.indexOf('x')>=0 || str.indexOf('X')>=0)
|
||||
seminfo.r = strx2number(str, seminfo);
|
||||
else
|
||||
seminfo.r = LuaValue.valueOf(Double.parseDouble(str.trim()));
|
||||
else {
|
||||
try {
|
||||
seminfo.r = LuaValue.valueOf(Double.parseDouble(str.trim()));
|
||||
} catch (NumberFormatException e) {
|
||||
lexerror("malformed number (" + e.getMessage() + ")", TK_NUMBER);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -408,7 +413,6 @@ public class LexState extends Constants {
|
||||
else
|
||||
break;
|
||||
}
|
||||
save('\0');
|
||||
String str = new String(buff, 0, nbuff);
|
||||
str2d(str, seminfo);
|
||||
}
|
||||
@@ -585,6 +589,13 @@ public class LexState extends Constants {
|
||||
inclinenumber();
|
||||
continue;
|
||||
}
|
||||
case ' ':
|
||||
case '\f':
|
||||
case '\t':
|
||||
case 0x0B: /* \v */ {
|
||||
nextChar();
|
||||
continue;
|
||||
}
|
||||
case '-': {
|
||||
nextChar();
|
||||
if (current != '-')
|
||||
@@ -688,19 +699,12 @@ public class LexState extends Constants {
|
||||
return TK_EOF;
|
||||
}
|
||||
default: {
|
||||
if (isspace(current)) {
|
||||
_assert (!currIsNewline());
|
||||
nextChar();
|
||||
continue;
|
||||
} else if (isdigit(current)) {
|
||||
read_numeral(seminfo);
|
||||
return TK_NUMBER;
|
||||
} else if (isalpha(current) || current == '_') {
|
||||
if (isalpha(current) || current == '_') {
|
||||
/* identifier or reserved word */
|
||||
LuaString ts;
|
||||
do {
|
||||
save_and_next();
|
||||
} while (isalnum(current) || current == '_');
|
||||
} while (isalnum(current));
|
||||
ts = newstring(buff, 0, nbuff);
|
||||
if ( RESERVED.containsKey(ts) )
|
||||
return ((Integer)RESERVED.get(ts)).intValue();
|
||||
@@ -1744,7 +1748,7 @@ public class LexState extends Constants {
|
||||
fs.checkrepeated(dyd.label, dyd.n_label, label); /* check for repeated labels */
|
||||
checknext(TK_DBCOLON); /* skip double colon */
|
||||
/* create new entry for this label */
|
||||
l = newlabelentry(dyd.label=grow(dyd.label, dyd.n_label+1), dyd.n_label++, label, line, fs.pc);
|
||||
l = newlabelentry(dyd.label=grow(dyd.label, dyd.n_label+1), dyd.n_label++, label, line, fs.getlabel());
|
||||
skipnoopstat(); /* skip other no-op statements */
|
||||
if (block_follow(false)) { /* label is last no-op statement in the block? */
|
||||
/* assume that locals are already out of scope */
|
||||
|
||||
@@ -151,7 +151,7 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
||||
System.gc();
|
||||
return LuaValue.TRUE;
|
||||
} else {
|
||||
this.argerror("gc op");
|
||||
argerror(1, "invalid option '" + s + "'");
|
||||
}
|
||||
return NIL;
|
||||
}
|
||||
@@ -172,16 +172,16 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
||||
// "error", // ( message [,level] ) -> ERR
|
||||
static final class error extends TwoArgFunction {
|
||||
public LuaValue call(LuaValue arg1, LuaValue arg2) {
|
||||
throw arg1.isnil()? new LuaError(null, arg2.optint(1)):
|
||||
arg1.isstring()? new LuaError(arg1.tojstring(), arg2.optint(1)):
|
||||
new LuaError(arg1);
|
||||
if (arg1.isnil()) throw new LuaError(NIL);
|
||||
if (!arg1.isstring() || arg2.optint(1) == 0) throw new LuaError(arg1);
|
||||
throw new LuaError(arg1.tojstring(), arg2.optint(1));
|
||||
}
|
||||
}
|
||||
|
||||
// "getmetatable", // ( object ) -> table
|
||||
static final class getmetatable extends LibFunction {
|
||||
public LuaValue call() {
|
||||
return argerror(1, "value");
|
||||
return argerror(1, "value expected");
|
||||
}
|
||||
public LuaValue call(LuaValue arg) {
|
||||
LuaValue mt = arg.getmetatable();
|
||||
@@ -192,7 +192,9 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
||||
final class load extends VarArgFunction {
|
||||
public Varargs invoke(Varargs args) {
|
||||
LuaValue ld = args.arg1();
|
||||
args.argcheck(ld.isstring() || ld.isfunction(), 1, "ld must be string or function");
|
||||
if (!ld.isstring() && !ld.isfunction()) {
|
||||
throw new LuaError("bad argument #1 to 'load' (string or function expected, got " + ld.typename() + ")");
|
||||
}
|
||||
String source = args.optjstring(2, ld.isstring()? ld.tojstring(): "=(load)");
|
||||
String mode = args.optjstring(3, "bt");
|
||||
LuaValue env = args.optvalue(4, globals);
|
||||
@@ -257,10 +259,10 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
||||
// "rawequal", // (v1, v2) -> boolean
|
||||
static final class rawequal extends LibFunction {
|
||||
public LuaValue call() {
|
||||
return argerror(1, "value");
|
||||
return argerror(1, "value expected");
|
||||
}
|
||||
public LuaValue call(LuaValue arg) {
|
||||
return argerror(2, "value");
|
||||
return argerror(2, "value expected");
|
||||
}
|
||||
public LuaValue call(LuaValue arg1, LuaValue arg2) {
|
||||
return valueOf(arg1.raweq(arg2));
|
||||
@@ -268,12 +270,12 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
||||
}
|
||||
|
||||
// "rawget", // (table, index) -> value
|
||||
static final class rawget extends LibFunction {
|
||||
static final class rawget extends TableLibFunction {
|
||||
public LuaValue call() {
|
||||
return argerror(1, "value");
|
||||
return argerror(1, "value expected");
|
||||
}
|
||||
public LuaValue call(LuaValue arg) {
|
||||
return argerror(2, "value");
|
||||
return argerror(2, "value expected");
|
||||
}
|
||||
public LuaValue call(LuaValue arg1, LuaValue arg2) {
|
||||
return arg1.checktable().rawget(arg2);
|
||||
@@ -289,16 +291,16 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
||||
}
|
||||
|
||||
// "rawset", // (table, index, value) -> table
|
||||
static final class rawset extends LibFunction {
|
||||
static final class rawset extends TableLibFunction {
|
||||
public LuaValue call(LuaValue table) {
|
||||
return argerror(2,"value");
|
||||
return argerror(2,"value expected");
|
||||
}
|
||||
public LuaValue call(LuaValue table, LuaValue index) {
|
||||
return argerror(3,"value");
|
||||
return argerror(3,"value expected");
|
||||
}
|
||||
public LuaValue call(LuaValue table, LuaValue index, LuaValue value) {
|
||||
LuaTable t = table.checktable();
|
||||
if (!index.isvalidkey()) argerror(2, "value");
|
||||
if (!index.isvalidkey()) argerror(2, "table index is nil");
|
||||
t.rawset(index, value);
|
||||
return t;
|
||||
}
|
||||
@@ -318,9 +320,9 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
||||
}
|
||||
|
||||
// "setmetatable", // (table, metatable) -> table
|
||||
static final class setmetatable extends LibFunction {
|
||||
static final class setmetatable extends TableLibFunction {
|
||||
public LuaValue call(LuaValue table) {
|
||||
return argerror(2,"value");
|
||||
return argerror(2,"nil or table expected");
|
||||
}
|
||||
public LuaValue call(LuaValue table, LuaValue metatable) {
|
||||
final LuaValue mt0 = table.checktable().getmetatable();
|
||||
@@ -471,10 +473,12 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
||||
this.func = func;
|
||||
}
|
||||
public int read() throws IOException {
|
||||
if ( remaining <= 0 ) {
|
||||
if ( remaining < 0 )
|
||||
return -1;
|
||||
if ( remaining == 0 ) {
|
||||
LuaValue s = func.call();
|
||||
if ( s.isnil() )
|
||||
return -1;
|
||||
return remaining = -1;
|
||||
LuaString ls = s.strvalue();
|
||||
bytes = ls.m_bytes;
|
||||
offset = ls.m_offset;
|
||||
|
||||
@@ -442,6 +442,10 @@ public class DebugLib extends TwoArgFunction {
|
||||
return callstack().traceback(level);
|
||||
}
|
||||
|
||||
public CallFrame getCallFrame(int level) {
|
||||
return callstack().getCallFrame(level);
|
||||
}
|
||||
|
||||
void callHook(LuaThread.State s, LuaValue type, LuaValue arg) {
|
||||
if (s.inhook || s.hookfunc == null) return;
|
||||
s.inhook = true;
|
||||
@@ -645,7 +649,7 @@ public class DebugLib extends TwoArgFunction {
|
||||
|
||||
}
|
||||
|
||||
static class CallFrame {
|
||||
public static class CallFrame {
|
||||
LuaFunction f;
|
||||
int pc;
|
||||
int top;
|
||||
@@ -691,7 +695,7 @@ public class DebugLib extends TwoArgFunction {
|
||||
return NIL;
|
||||
}
|
||||
}
|
||||
int currentline() {
|
||||
public int currentline() {
|
||||
if ( !f.isclosure() ) return -1;
|
||||
int[] li = f.checkclosure().p.lineinfo;
|
||||
return li==null || pc<0 || pc>=li.length? -1: li[pc];
|
||||
@@ -796,13 +800,13 @@ public class DebugLib extends TwoArgFunction {
|
||||
LuaString vn = (Lua.GET_OPCODE(i) == Lua.OP_GETTABLE) /* name of indexed variable */
|
||||
? p.getlocalname(t + 1, pc)
|
||||
: (t < p.upvalues.length ? p.upvalues[t].name : QMARK);
|
||||
name = kname(p, k);
|
||||
return new NameWhat( name.tojstring(), vn != null && vn.eq_b(ENV)? "global": "field" );
|
||||
String jname = kname(p, pc, k);
|
||||
return new NameWhat( jname, vn != null && vn.eq_b(ENV)? "global": "field" );
|
||||
}
|
||||
case Lua.OP_GETUPVAL: {
|
||||
int u = Lua.GETARG_B(i); /* upvalue index */
|
||||
name = u < p.upvalues.length ? p.upvalues[u].name : QMARK;
|
||||
return new NameWhat( name.tojstring(), "upvalue" );
|
||||
return name == null ? null : new NameWhat( name.tojstring(), "upvalue" );
|
||||
}
|
||||
case Lua.OP_LOADK:
|
||||
case Lua.OP_LOADKX: {
|
||||
@@ -816,8 +820,8 @@ public class DebugLib extends TwoArgFunction {
|
||||
}
|
||||
case Lua.OP_SELF: {
|
||||
int k = Lua.GETARG_C(i); /* key index */
|
||||
name = kname(p, k);
|
||||
return new NameWhat( name.tojstring(), "method" );
|
||||
String jname = kname(p, pc, k);
|
||||
return new NameWhat( jname, "method" );
|
||||
}
|
||||
default:
|
||||
break;
|
||||
@@ -826,11 +830,20 @@ public class DebugLib extends TwoArgFunction {
|
||||
return null; /* no useful name found */
|
||||
}
|
||||
|
||||
static LuaString kname(Prototype p, int c) {
|
||||
if (Lua.ISK(c) && p.k[Lua.INDEXK(c)].isstring())
|
||||
return p.k[Lua.INDEXK(c)].strvalue();
|
||||
else
|
||||
return QMARK;
|
||||
static String kname(Prototype p, int pc, int c) {
|
||||
if (Lua.ISK(c)) { /* is 'c' a constant? */
|
||||
LuaValue k = p.k[Lua.INDEXK(c)];
|
||||
if (k.isstring()) { /* literal constant? */
|
||||
return k.tojstring(); /* it is its own name */
|
||||
} /* else no reasonable name found */
|
||||
} else { /* 'c' is a register */
|
||||
NameWhat what = getobjname(p, pc, c); /* search for 'c' */
|
||||
if (what != null && "constant".equals(what.namewhat)) { /* found a constant name? */
|
||||
return what.name; /* 'name' already filled */
|
||||
}
|
||||
/* else no reasonable name found */
|
||||
}
|
||||
return "?"; /* no reasonable name found */
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -95,6 +95,12 @@ public class IoLib extends TwoArgFunction {
|
||||
// return number of bytes read if positive, false if eof, throw IOException on other exception
|
||||
abstract public int read(byte[] bytes, int offset, int length) throws IOException;
|
||||
|
||||
public boolean eof() throws IOException {
|
||||
try {
|
||||
return peek() < 0;
|
||||
} catch (EOFException e) { return true; }
|
||||
}
|
||||
|
||||
// delegate method access to file methods table
|
||||
public LuaValue get( LuaValue key ) {
|
||||
return filemethods.get(key);
|
||||
@@ -112,6 +118,14 @@ public class IoLib extends TwoArgFunction {
|
||||
public String tojstring() {
|
||||
return "file: " + Integer.toHexString(hashCode());
|
||||
}
|
||||
|
||||
public void finalize() {
|
||||
if (!isclosed()) {
|
||||
try {
|
||||
close();
|
||||
} catch (IOException ignore) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Enumerated value representing stdin */
|
||||
@@ -269,8 +283,15 @@ public class IoLib extends TwoArgFunction {
|
||||
static final class IoLibV extends VarArgFunction {
|
||||
private File f;
|
||||
public IoLib iolib;
|
||||
private boolean toclose;
|
||||
private Varargs args;
|
||||
public IoLibV() {
|
||||
}
|
||||
public IoLibV(File f, String name, int opcode, IoLib iolib, boolean toclose, Varargs args) {
|
||||
this(f, name, opcode, iolib);
|
||||
this.toclose = toclose;
|
||||
this.args = args.dealias();
|
||||
}
|
||||
public IoLibV(File f, String name, int opcode, IoLib iolib) {
|
||||
super();
|
||||
this.f = f;
|
||||
@@ -290,22 +311,26 @@ public class IoLib extends TwoArgFunction {
|
||||
case IO_TYPE: return iolib._io_type(args.arg1());
|
||||
case IO_POPEN: return iolib._io_popen(args.checkjstring(1),args.optjstring(2,"r"));
|
||||
case IO_OPEN: return iolib._io_open(args.checkjstring(1), args.optjstring(2,"r"));
|
||||
case IO_LINES: return iolib._io_lines(args.isvalue(1)? args.checkjstring(1): null);
|
||||
case IO_LINES: return iolib._io_lines(args);
|
||||
case IO_READ: return iolib._io_read(args);
|
||||
case IO_WRITE: return iolib._io_write(args);
|
||||
|
||||
case FILE_CLOSE: return iolib._file_close(args.arg1());
|
||||
case FILE_FLUSH: return iolib._file_flush(args.arg1());
|
||||
case FILE_SETVBUF: return iolib._file_setvbuf(args.arg1(),args.checkjstring(2),args.optint(3,1024));
|
||||
case FILE_LINES: return iolib._file_lines(args.arg1());
|
||||
case FILE_SETVBUF: return iolib._file_setvbuf(args.arg1(),args.checkjstring(2),args.optint(3,8192));
|
||||
case FILE_LINES: return iolib._file_lines(args);
|
||||
case FILE_READ: return iolib._file_read(args.arg1(),args.subargs(2));
|
||||
case FILE_SEEK: return iolib._file_seek(args.arg1(),args.optjstring(2,"cur"),args.optint(3,0));
|
||||
case FILE_WRITE: return iolib._file_write(args.arg1(),args.subargs(2));
|
||||
|
||||
case IO_INDEX: return iolib._io_index(args.arg(2));
|
||||
case LINES_ITER: return iolib._lines_iter(f);
|
||||
case LINES_ITER: return iolib._lines_iter(f, toclose, this.args);
|
||||
}
|
||||
} catch ( IOException ioe ) {
|
||||
if (opcode == LINES_ITER) {
|
||||
String s = ioe.getMessage();
|
||||
error(s != null ? s : ioe.toString());
|
||||
}
|
||||
return errorresult(ioe);
|
||||
}
|
||||
return NONE;
|
||||
@@ -361,6 +386,7 @@ public class IoLib extends TwoArgFunction {
|
||||
|
||||
// io.popen(prog, [mode]) -> file
|
||||
public Varargs _io_popen(String prog, String mode) throws IOException {
|
||||
if (!"r".equals(mode) && !"w".equals(mode)) argerror(2, "invalid value: '" + mode + "'; must be one of 'r' or 'w'");
|
||||
return openProgram(prog, mode);
|
||||
}
|
||||
|
||||
@@ -369,11 +395,12 @@ public class IoLib extends TwoArgFunction {
|
||||
return rawopenfile(FTYPE_NAMED, filename, mode);
|
||||
}
|
||||
|
||||
// io.lines(filename) -> iterator
|
||||
public Varargs _io_lines(String filename) {
|
||||
infile = filename==null? input(): ioopenfile(FTYPE_NAMED, filename,"r");
|
||||
// io.lines(filename, ...) -> iterator
|
||||
public Varargs _io_lines(Varargs args) {
|
||||
String filename = args.optjstring(1, null);
|
||||
File infile = filename==null? input(): ioopenfile(FTYPE_NAMED, filename,"r");
|
||||
checkopen(infile);
|
||||
return lines(infile);
|
||||
return lines(infile, filename != null, args.subargs(2));
|
||||
}
|
||||
|
||||
// io.read(...) -> (...)
|
||||
@@ -401,13 +428,19 @@ public class IoLib extends TwoArgFunction {
|
||||
|
||||
// file:setvbuf(mode,[size]) -> void
|
||||
public Varargs _file_setvbuf(LuaValue file, String mode, int size) {
|
||||
if ("no".equals(mode)) {
|
||||
} else if ("full".equals(mode)) {
|
||||
} else if ("line".equals(mode)) {
|
||||
} else {
|
||||
argerror(1, "invalid value: '" + mode + "'; must be one of 'no', 'full' or 'line'");
|
||||
}
|
||||
checkfile(file).setvbuf(mode,size);
|
||||
return LuaValue.TRUE;
|
||||
}
|
||||
|
||||
// file:lines() -> iterator
|
||||
public Varargs _file_lines(LuaValue file) {
|
||||
return lines(checkfile(file));
|
||||
// file:lines(...) -> iterator
|
||||
public Varargs _file_lines(Varargs args) {
|
||||
return lines(checkfile(args.arg1()), false, args.subargs(2));
|
||||
}
|
||||
|
||||
// file:read(...) -> (...)
|
||||
@@ -417,6 +450,12 @@ public class IoLib extends TwoArgFunction {
|
||||
|
||||
// file:seek([whence][,offset]) -> pos | nil,error
|
||||
public Varargs _file_seek(LuaValue file, String whence, int offset) throws IOException {
|
||||
if ("set".equals(whence)) {
|
||||
} else if ("end".equals(whence)) {
|
||||
} else if ("cur".equals(whence)) {
|
||||
} else {
|
||||
argerror(1, "invalid value: '" + whence + "'; must be one of 'set', 'cur' or 'end'");
|
||||
}
|
||||
return valueOf( checkfile(file).seek(whence,offset) );
|
||||
}
|
||||
|
||||
@@ -433,8 +472,13 @@ public class IoLib extends TwoArgFunction {
|
||||
}
|
||||
|
||||
// lines iterator(s,var) -> var'
|
||||
public Varargs _lines_iter(LuaValue file) throws IOException {
|
||||
return freadline(checkfile(file));
|
||||
public Varargs _lines_iter(LuaValue file, boolean toclose, Varargs args) throws IOException {
|
||||
File f = optfile(file);
|
||||
if ( f == null ) argerror(1, "not a file: " + file);
|
||||
if ( f.isclosed() ) error("file is already closed");
|
||||
Varargs ret = ioread(f, args);
|
||||
if (toclose && ret.isnil(1) && f.eof()) f.close();
|
||||
return ret;
|
||||
}
|
||||
|
||||
private File output() {
|
||||
@@ -476,9 +520,9 @@ public class IoLib extends TwoArgFunction {
|
||||
return varargsOf(NIL, valueOf(errortext));
|
||||
}
|
||||
|
||||
private Varargs lines(final File f) {
|
||||
private Varargs lines(final File f, boolean toclose, Varargs args) {
|
||||
try {
|
||||
return new IoLibV(f,"lnext",LINES_ITER,this);
|
||||
return new IoLibV(f,"lnext",LINES_ITER,this,toclose,args);
|
||||
} catch ( Exception e ) {
|
||||
return error("lines: "+e);
|
||||
}
|
||||
@@ -492,6 +536,7 @@ public class IoLib extends TwoArgFunction {
|
||||
|
||||
private Varargs ioread(File f, Varargs args) throws IOException {
|
||||
int i,n=args.narg();
|
||||
if (n == 0) return freadline(f,false);
|
||||
LuaValue[] v = new LuaValue[n];
|
||||
LuaValue ai,vi;
|
||||
LuaString fmt;
|
||||
@@ -502,10 +547,11 @@ public class IoLib extends TwoArgFunction {
|
||||
break item;
|
||||
case LuaValue.TSTRING:
|
||||
fmt = ai.checkstring();
|
||||
if ( fmt.m_length == 2 && fmt.m_bytes[fmt.m_offset] == '*' ) {
|
||||
if ( fmt.m_length >= 2 && fmt.m_bytes[fmt.m_offset] == '*' ) {
|
||||
switch ( fmt.m_bytes[fmt.m_offset+1] ) {
|
||||
case 'n': vi = freadnumber(f); break item;
|
||||
case 'l': vi = freadline(f); break item;
|
||||
case 'l': vi = freadline(f,false); break item;
|
||||
case 'L': vi = freadline(f,true); break item;
|
||||
case 'a': vi = freadall(f); break item;
|
||||
}
|
||||
}
|
||||
@@ -537,6 +583,17 @@ public class IoLib extends TwoArgFunction {
|
||||
}
|
||||
|
||||
private File rawopenfile(int filetype, String filename, String mode) throws IOException {
|
||||
int len = mode.length();
|
||||
for (int i = 0; i < len; i++) { // [rwa][+]?b*
|
||||
char ch = mode.charAt(i);
|
||||
if (i == 0 && "rwa".indexOf(ch) >= 0) continue;
|
||||
if (i == 1 && ch == '+') continue;
|
||||
if (i >= 1 && ch == 'b') continue;
|
||||
len = -1;
|
||||
break;
|
||||
}
|
||||
if (len <= 0) argerror(2, "invalid mode: '" + mode + "'");
|
||||
|
||||
switch (filetype) {
|
||||
case FTYPE_STDIN: return wrapStdin();
|
||||
case FTYPE_STDOUT: return wrapStdout();
|
||||
@@ -553,26 +610,27 @@ public class IoLib extends TwoArgFunction {
|
||||
// ------------- file reading utilitied ------------------
|
||||
|
||||
public static LuaValue freadbytes(File f, int count) throws IOException {
|
||||
if (count == 0) return f.eof() ? NIL : EMPTYSTRING;
|
||||
byte[] b = new byte[count];
|
||||
int r;
|
||||
if ( ( r = f.read(b,0,b.length) ) < 0 )
|
||||
return NIL;
|
||||
return LuaString.valueUsing(b, 0, r);
|
||||
}
|
||||
public static LuaValue freaduntil(File f,boolean lineonly) throws IOException {
|
||||
public static LuaValue freaduntil(File f,boolean lineonly,boolean withend) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
int c;
|
||||
try {
|
||||
if ( lineonly ) {
|
||||
loop: while ( (c = f.read()) > 0 ) {
|
||||
loop: while ( (c = f.read()) >= 0 ) {
|
||||
switch ( c ) {
|
||||
case '\r': break;
|
||||
case '\n': break loop;
|
||||
case '\r': if (withend) baos.write(c); break;
|
||||
case '\n': if (withend) baos.write(c); break loop;
|
||||
default: baos.write(c); break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while ( (c = f.read()) > 0 )
|
||||
while ( (c = f.read()) >= 0 )
|
||||
baos.write(c);
|
||||
}
|
||||
} catch ( EOFException e ) {
|
||||
@@ -582,15 +640,15 @@ public class IoLib extends TwoArgFunction {
|
||||
(LuaValue) NIL:
|
||||
(LuaValue) LuaString.valueUsing(baos.toByteArray());
|
||||
}
|
||||
public static LuaValue freadline(File f) throws IOException {
|
||||
return freaduntil(f,true);
|
||||
public static LuaValue freadline(File f,boolean withend) throws IOException {
|
||||
return freaduntil(f,true,withend);
|
||||
}
|
||||
public static LuaValue freadall(File f) throws IOException {
|
||||
int n = f.remaining();
|
||||
if ( n >= 0 ) {
|
||||
return freadbytes(f, n);
|
||||
return n == 0 ? EMPTYSTRING : freadbytes(f, n);
|
||||
} else {
|
||||
return freaduntil(f,false);
|
||||
return freaduntil(f,false,false);
|
||||
}
|
||||
}
|
||||
public static LuaValue freadnumber(File f) throws IOException {
|
||||
|
||||
@@ -144,6 +144,7 @@ public class PackageLib extends TwoArgFunction {
|
||||
searchers.set(2, lua_searcher = new lua_searcher());
|
||||
searchers.set(3, java_searcher = new java_searcher());
|
||||
package_.set(_SEARCHERS, searchers);
|
||||
package_.set("config", FILE_SEP + "\n;\n?\n!\n-\n");
|
||||
package_.get(_LOADED).set("package", package_);
|
||||
env.set("package", package_);
|
||||
globals.package_ = this;
|
||||
|
||||
@@ -79,8 +79,8 @@ public class StringLib extends TwoArgFunction {
|
||||
*/
|
||||
public LuaValue call(LuaValue modname, LuaValue env) {
|
||||
LuaTable string = new LuaTable();
|
||||
string.set("byte", new byte_());
|
||||
string.set("char", new char_());
|
||||
string.set("byte", new _byte());
|
||||
string.set("char", new _char());
|
||||
string.set("dump", new dump());
|
||||
string.set("find", new find());
|
||||
string.set("format", new format());
|
||||
@@ -113,7 +113,7 @@ public class StringLib extends TwoArgFunction {
|
||||
*
|
||||
* @param args the calling args
|
||||
*/
|
||||
static final class byte_ extends VarArgFunction {
|
||||
static final class _byte extends VarArgFunction {
|
||||
public Varargs invoke(Varargs args) {
|
||||
LuaString s = args.checkstring(1);
|
||||
int l = s.m_length;
|
||||
@@ -144,7 +144,7 @@ public class StringLib extends TwoArgFunction {
|
||||
*
|
||||
* @param args the calling VM
|
||||
*/
|
||||
static final class char_ extends VarArgFunction {
|
||||
static final class _char extends VarArgFunction {
|
||||
public Varargs invoke(Varargs args) {
|
||||
int n = args.narg();
|
||||
byte[] bytes = new byte[n];
|
||||
@@ -624,19 +624,20 @@ public class StringLib extends TwoArgFunction {
|
||||
private final int srclen;
|
||||
private final MatchState ms;
|
||||
private int soffset;
|
||||
private int lastmatch;
|
||||
public GMatchAux(Varargs args, LuaString src, LuaString pat) {
|
||||
this.srclen = src.length();
|
||||
this.ms = new MatchState(args, src, pat);
|
||||
this.soffset = 0;
|
||||
this.lastmatch = -1;
|
||||
}
|
||||
public Varargs invoke(Varargs args) {
|
||||
for ( ; soffset<=srclen; soffset++ ) {
|
||||
ms.reset();
|
||||
int res = ms.match(soffset, 0);
|
||||
if ( res >=0 ) {
|
||||
if ( res >=0 && res != lastmatch ) {
|
||||
int soff = soffset;
|
||||
soffset = res;
|
||||
if (soff == res) soffset++; /* empty match? go at least one position */
|
||||
lastmatch = soffset = res;
|
||||
return ms.push_captures( true, soff, res );
|
||||
}
|
||||
}
|
||||
@@ -695,6 +696,7 @@ public class StringLib extends TwoArgFunction {
|
||||
LuaString src = args.checkstring( 1 );
|
||||
final int srclen = src.length();
|
||||
LuaString p = args.checkstring( 2 );
|
||||
int lastmatch = -1; /* end of last match */
|
||||
LuaValue repl = args.arg( 3 );
|
||||
int max_s = args.optint( 4, srclen + 1 );
|
||||
final boolean anchor = p.length() > 0 && p.charAt( 0 ) == '^';
|
||||
@@ -707,18 +709,15 @@ public class StringLib extends TwoArgFunction {
|
||||
while ( n < max_s ) {
|
||||
ms.reset();
|
||||
int res = ms.match( soffset, anchor ? 1 : 0 );
|
||||
if ( res != -1 ) {
|
||||
if ( res != -1 && res != lastmatch ) { /* match? */
|
||||
n++;
|
||||
ms.add_value( lbuf, soffset, res, repl );
|
||||
ms.add_value( lbuf, soffset, res, repl ); /* add replacement to buffer */
|
||||
soffset = lastmatch = res;
|
||||
}
|
||||
if ( res != -1 && res > soffset )
|
||||
soffset = res;
|
||||
else if ( soffset < srclen )
|
||||
else if ( soffset < srclen ) /* otherwise, skip one character */
|
||||
lbuf.append( (byte) src.luaByte( soffset++ ) );
|
||||
else
|
||||
break;
|
||||
if ( anchor )
|
||||
break;
|
||||
else break; /* end of subject */
|
||||
if ( anchor ) break;
|
||||
}
|
||||
lbuf.append( src.substring( soffset, srclen ) );
|
||||
return varargsOf(lbuf.tostring(), valueOf(n));
|
||||
@@ -914,6 +913,8 @@ public class StringLib extends TwoArgFunction {
|
||||
private static final LuaString SPECIALS = valueOf("^$*+?.([%-");
|
||||
private static final int MAX_CAPTURES = 32;
|
||||
|
||||
private static final int MAXCCALLS = 200;
|
||||
|
||||
private static final int CAP_UNFINISHED = -1;
|
||||
private static final int CAP_POSITION = -2;
|
||||
|
||||
@@ -931,7 +932,7 @@ public class StringLib extends TwoArgFunction {
|
||||
static {
|
||||
CHAR_TABLE = new byte[256];
|
||||
|
||||
for ( int i = 0; i < 256; ++i ) {
|
||||
for ( int i = 0; i < 128; ++i ) {
|
||||
final char c = (char) i;
|
||||
CHAR_TABLE[i] = (byte)( ( Character.isDigit( c ) ? MASK_DIGIT : 0 ) |
|
||||
( Character.isLowerCase( c ) ? MASK_LOWERCASE : 0 ) |
|
||||
@@ -940,7 +941,7 @@ public class StringLib extends TwoArgFunction {
|
||||
if ( ( c >= 'a' && c <= 'f' ) || ( c >= 'A' && c <= 'F' ) || ( c >= '0' && c <= '9' ) ) {
|
||||
CHAR_TABLE[i] |= MASK_HEXDIGIT;
|
||||
}
|
||||
if ( ( c >= '!' && c <= '/' ) || ( c >= ':' && c <= '@' ) ) {
|
||||
if ( ( c >= '!' && c <= '/' ) || ( c >= ':' && c <= '@' ) || ( c >= '[' && c <= '`' ) || ( c >= '{' && c <= '~' ) ) {
|
||||
CHAR_TABLE[i] |= MASK_PUNCT;
|
||||
}
|
||||
if ( ( CHAR_TABLE[i] & ( MASK_LOWERCASE | MASK_UPPERCASE ) ) != 0 ) {
|
||||
@@ -952,11 +953,12 @@ public class StringLib extends TwoArgFunction {
|
||||
CHAR_TABLE['\r'] |= MASK_SPACE;
|
||||
CHAR_TABLE['\n'] |= MASK_SPACE;
|
||||
CHAR_TABLE['\t'] |= MASK_SPACE;
|
||||
CHAR_TABLE[0x0C /* '\v' */ ] |= MASK_SPACE;
|
||||
CHAR_TABLE[0x0B /* '\v' */ ] |= MASK_SPACE;
|
||||
CHAR_TABLE['\f'] |= MASK_SPACE;
|
||||
};
|
||||
|
||||
static class MatchState {
|
||||
int matchdepth; /* control for recursive depth (to avoid C stack overflow) */
|
||||
final LuaString s;
|
||||
final LuaString p;
|
||||
final Varargs args;
|
||||
@@ -971,10 +973,12 @@ public class StringLib extends TwoArgFunction {
|
||||
this.level = 0;
|
||||
this.cinit = new int[ MAX_CAPTURES ];
|
||||
this.clen = new int[ MAX_CAPTURES ];
|
||||
this.matchdepth = MAXCCALLS;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
level = 0;
|
||||
this.matchdepth = MAXCCALLS;
|
||||
}
|
||||
|
||||
private void add_s( Buffer lbuf, LuaString news, int soff, int e ) {
|
||||
@@ -1049,7 +1053,7 @@ public class StringLib extends TwoArgFunction {
|
||||
if ( i == 0 ) {
|
||||
return s.substring( soff, end );
|
||||
} else {
|
||||
return error( "invalid capture index" );
|
||||
return error( "invalid capture index %" + (i + 1) );
|
||||
}
|
||||
} else {
|
||||
int l = clen[i];
|
||||
@@ -1068,7 +1072,7 @@ public class StringLib extends TwoArgFunction {
|
||||
private int check_capture( int l ) {
|
||||
l -= '1';
|
||||
if ( l < 0 || l >= level || this.clen[l] == CAP_UNFINISHED ) {
|
||||
error("invalid capture index");
|
||||
error("invalid capture index %" + (l + 1));
|
||||
}
|
||||
return l;
|
||||
}
|
||||
@@ -1118,9 +1122,10 @@ public class StringLib extends TwoArgFunction {
|
||||
case 'c': res = ( cdata & MASK_CONTROL ) != 0; break;
|
||||
case 'p': res = ( cdata & MASK_PUNCT ) != 0; break;
|
||||
case 's': res = ( cdata & MASK_SPACE ) != 0; break;
|
||||
case 'g': res = ( cdata & ( MASK_ALPHA | MASK_DIGIT | MASK_PUNCT ) ) != 0; break;
|
||||
case 'w': res = ( cdata & ( MASK_ALPHA | MASK_DIGIT ) ) != 0; break;
|
||||
case 'x': res = ( cdata & MASK_HEXDIGIT ) != 0; break;
|
||||
case 'z': res = ( c == 0 ); break;
|
||||
case 'z': res = ( c == 0 ); break; /* deprecated option */
|
||||
default: return cl == c;
|
||||
}
|
||||
return ( lcl == cl ) ? res : !res;
|
||||
@@ -1162,81 +1167,86 @@ public class StringLib extends TwoArgFunction {
|
||||
* where match ends, otherwise returns -1.
|
||||
*/
|
||||
int match( int soffset, int poffset ) {
|
||||
while ( true ) {
|
||||
// Check if we are at the end of the pattern -
|
||||
// equivalent to the '\0' case in the C version, but our pattern
|
||||
// string is not NUL-terminated.
|
||||
if ( poffset == p.length() )
|
||||
return soffset;
|
||||
switch ( p.luaByte( poffset ) ) {
|
||||
case '(':
|
||||
if ( ++poffset < p.length() && p.luaByte( poffset ) == ')' )
|
||||
return start_capture( soffset, poffset + 1, CAP_POSITION );
|
||||
else
|
||||
return start_capture( soffset, poffset, CAP_UNFINISHED );
|
||||
case ')':
|
||||
return end_capture( soffset, poffset + 1 );
|
||||
case L_ESC:
|
||||
if ( poffset + 1 == p.length() )
|
||||
error("malformed pattern (ends with '%')");
|
||||
switch ( p.luaByte( poffset + 1 ) ) {
|
||||
case 'b':
|
||||
soffset = matchbalance( soffset, poffset + 2 );
|
||||
if ( soffset == -1 ) return -1;
|
||||
poffset += 4;
|
||||
continue;
|
||||
case 'f': {
|
||||
poffset += 2;
|
||||
if ( poffset == p.length() || p.luaByte( poffset ) != '[' ) {
|
||||
error("Missing '[' after '%f' in pattern");
|
||||
if (matchdepth-- == 0) error("pattern too complex");
|
||||
try {
|
||||
while ( true ) {
|
||||
// Check if we are at the end of the pattern -
|
||||
// equivalent to the '\0' case in the C version, but our pattern
|
||||
// string is not NUL-terminated.
|
||||
if ( poffset == p.length() )
|
||||
return soffset;
|
||||
switch ( p.luaByte( poffset ) ) {
|
||||
case '(':
|
||||
if ( ++poffset < p.length() && p.luaByte( poffset ) == ')' )
|
||||
return start_capture( soffset, poffset + 1, CAP_POSITION );
|
||||
else
|
||||
return start_capture( soffset, poffset, CAP_UNFINISHED );
|
||||
case ')':
|
||||
return end_capture( soffset, poffset + 1 );
|
||||
case L_ESC:
|
||||
if ( poffset + 1 == p.length() )
|
||||
error("malformed pattern (ends with '%')");
|
||||
switch ( p.luaByte( poffset + 1 ) ) {
|
||||
case 'b':
|
||||
soffset = matchbalance( soffset, poffset + 2 );
|
||||
if ( soffset == -1 ) return -1;
|
||||
poffset += 4;
|
||||
continue;
|
||||
case 'f': {
|
||||
poffset += 2;
|
||||
if ( poffset == p.length() || p.luaByte( poffset ) != '[' ) {
|
||||
error("missing '[' after '%f' in pattern");
|
||||
}
|
||||
int ep = classend( poffset );
|
||||
int previous = ( soffset == 0 ) ? '\0' : s.luaByte( soffset - 1 );
|
||||
int next = ( soffset == s.length() ) ? '\0' : s.luaByte( soffset );
|
||||
if ( matchbracketclass( previous, poffset, ep - 1 ) ||
|
||||
!matchbracketclass( next, poffset, ep - 1 ) )
|
||||
return -1;
|
||||
poffset = ep;
|
||||
continue;
|
||||
}
|
||||
int ep = classend( poffset );
|
||||
int previous = ( soffset == 0 ) ? '\0' : s.luaByte( soffset - 1 );
|
||||
int next = ( soffset == s.length() ) ? '\0' : s.luaByte( soffset );
|
||||
if ( matchbracketclass( previous, poffset, ep - 1 ) ||
|
||||
!matchbracketclass( next, poffset, ep - 1 ) )
|
||||
default: {
|
||||
int c = p.luaByte( poffset + 1 );
|
||||
if ( Character.isDigit( (char) c ) ) {
|
||||
soffset = match_capture( soffset, c );
|
||||
if ( soffset == -1 )
|
||||
return -1;
|
||||
return match( soffset, poffset + 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
case '$':
|
||||
if ( poffset + 1 == p.length() )
|
||||
return ( soffset == s.length() ) ? soffset : -1;
|
||||
}
|
||||
int ep = classend( poffset );
|
||||
boolean m = soffset < s.length() && singlematch( s.luaByte( soffset ), poffset, ep );
|
||||
int pc = ( ep < p.length() ) ? p.luaByte( ep ) : '\0';
|
||||
|
||||
switch ( pc ) {
|
||||
case '?':
|
||||
int res;
|
||||
if ( m && ( ( res = match( soffset + 1, ep + 1 ) ) != -1 ) )
|
||||
return res;
|
||||
poffset = ep + 1;
|
||||
continue;
|
||||
case '*':
|
||||
return max_expand( soffset, poffset, ep );
|
||||
case '+':
|
||||
return ( m ? max_expand( soffset + 1, poffset, ep ) : -1 );
|
||||
case '-':
|
||||
return min_expand( soffset, poffset, ep );
|
||||
default:
|
||||
if ( !m )
|
||||
return -1;
|
||||
soffset++;
|
||||
poffset = ep;
|
||||
continue;
|
||||
}
|
||||
default: {
|
||||
int c = p.luaByte( poffset + 1 );
|
||||
if ( Character.isDigit( (char) c ) ) {
|
||||
soffset = match_capture( soffset, c );
|
||||
if ( soffset == -1 )
|
||||
return -1;
|
||||
return match( soffset, poffset + 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
case '$':
|
||||
if ( poffset + 1 == p.length() )
|
||||
return ( soffset == s.length() ) ? soffset : -1;
|
||||
}
|
||||
int ep = classend( poffset );
|
||||
boolean m = soffset < s.length() && singlematch( s.luaByte( soffset ), poffset, ep );
|
||||
int pc = ( ep < p.length() ) ? p.luaByte( ep ) : '\0';
|
||||
|
||||
switch ( pc ) {
|
||||
case '?':
|
||||
int res;
|
||||
if ( m && ( ( res = match( soffset + 1, ep + 1 ) ) != -1 ) )
|
||||
return res;
|
||||
poffset = ep + 1;
|
||||
continue;
|
||||
case '*':
|
||||
return max_expand( soffset, poffset, ep );
|
||||
case '+':
|
||||
return ( m ? max_expand( soffset + 1, poffset, ep ) : -1 );
|
||||
case '-':
|
||||
return min_expand( soffset, poffset, ep );
|
||||
default:
|
||||
if ( !m )
|
||||
return -1;
|
||||
soffset++;
|
||||
poffset = ep;
|
||||
continue;
|
||||
}
|
||||
} finally {
|
||||
matchdepth++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1301,7 +1311,7 @@ public class StringLib extends TwoArgFunction {
|
||||
int matchbalance( int soff, int poff ) {
|
||||
final int plen = p.length();
|
||||
if ( poff == plen || poff + 1 == plen ) {
|
||||
error( "unbalanced pattern" );
|
||||
error( "malformed pattern (missing arguments to '%b')" );
|
||||
}
|
||||
final int slen = s.length();
|
||||
if ( soff >= slen )
|
||||
|
||||
@@ -74,12 +74,6 @@ public class TableLib extends TwoArgFunction {
|
||||
return NIL;
|
||||
}
|
||||
|
||||
static class TableLibFunction extends LibFunction {
|
||||
public LuaValue call() {
|
||||
return argerror(1, "table expected, got no value");
|
||||
}
|
||||
}
|
||||
|
||||
// "concat" (table [, sep [, i [, j]]]) -> string
|
||||
static class concat extends TableLibFunction {
|
||||
public LuaValue call(LuaValue list) {
|
||||
@@ -100,18 +94,22 @@ public class TableLib extends TwoArgFunction {
|
||||
static class insert extends VarArgFunction {
|
||||
public Varargs invoke(Varargs args) {
|
||||
switch (args.narg()) {
|
||||
case 0: case 1: {
|
||||
return argerror(2, "value expected");
|
||||
}
|
||||
case 2: {
|
||||
LuaTable table = args.arg1().checktable();
|
||||
LuaTable table = args.checktable(1);
|
||||
table.insert(table.length()+1,args.arg(2));
|
||||
return NONE;
|
||||
}
|
||||
default: {
|
||||
args.arg1().checktable().insert(args.checkint(2),args.arg(3));
|
||||
case 3: {
|
||||
LuaTable table = args.checktable(1);
|
||||
int pos = args.checkint(2);
|
||||
int max = table.length() + 1;
|
||||
if (pos < 1 || pos > max) argerror(2, "position out of bounds: " + pos + " not between 1 and " + max);
|
||||
table.insert(pos, args.arg(3));
|
||||
return NONE;
|
||||
}
|
||||
default: {
|
||||
return error("wrong number of arguments to 'table.insert': " + args.narg() + " (must be 2 or 3)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,15 +126,21 @@ public class TableLib extends TwoArgFunction {
|
||||
// "remove" (table [, pos]) -> removed-ele
|
||||
static class remove extends VarArgFunction {
|
||||
public Varargs invoke(Varargs args) {
|
||||
return args.arg1().checktable().remove(args.optint(2, 0));
|
||||
LuaTable table = args.checktable(1);
|
||||
int size = table.length();
|
||||
int pos = args.optint(2, size);
|
||||
if (pos != size && (pos < 1 || pos > size + 1)) {
|
||||
argerror(2, "position out of bounds: " + pos + " not between 1 and " + (size + 1));
|
||||
}
|
||||
return table.remove(pos);
|
||||
}
|
||||
}
|
||||
|
||||
// "sort" (table [, comp])
|
||||
static class sort extends VarArgFunction {
|
||||
public Varargs invoke(Varargs args) {
|
||||
args.arg1().checktable().sort(
|
||||
args.arg(2).isnil()? NIL: args.arg(2).checkfunction());
|
||||
args.checktable(1).sort(
|
||||
args.isnil(2)? NIL: args.checkfunction(2));
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
@@ -146,11 +150,9 @@ public class TableLib extends TwoArgFunction {
|
||||
static class unpack extends VarArgFunction {
|
||||
public Varargs invoke(Varargs args) {
|
||||
LuaTable t = args.checktable(1);
|
||||
switch (args.narg()) {
|
||||
case 1: return t.unpack();
|
||||
case 2: return t.unpack(args.checkint(2));
|
||||
default: return t.unpack(args.checkint(2), args.checkint(3));
|
||||
}
|
||||
// do not waste resource for calc rawlen if arg3 is not nil
|
||||
int len = args.arg(3).isnil() ? t.length() : 0;
|
||||
return t.unpack(args.optint(2, 1), args.optint(3, len));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
9
src/core/org/luaj/vm2/lib/TableLibFunction.java
Normal file
9
src/core/org/luaj/vm2/lib/TableLibFunction.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package org.luaj.vm2.lib;
|
||||
|
||||
import org.luaj.vm2.LuaValue;
|
||||
|
||||
class TableLibFunction extends LibFunction {
|
||||
public LuaValue call() {
|
||||
return argerror(1, "table expected, got no value");
|
||||
}
|
||||
}
|
||||
@@ -133,7 +133,7 @@ public class JseIoLib extends IoLib {
|
||||
this( null, null, o );
|
||||
}
|
||||
public String tojstring() {
|
||||
return "file ("+this.hashCode()+")";
|
||||
return "file (" + (this.closed ? "closed" : String.valueOf(this.hashCode())) + ")";
|
||||
}
|
||||
public boolean isstdfile() {
|
||||
return file == null;
|
||||
@@ -321,7 +321,7 @@ public class JseIoLib extends IoLib {
|
||||
}
|
||||
|
||||
public int remaining() throws IOException {
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int peek() throws IOException, EOFException {
|
||||
|
||||
@@ -126,7 +126,7 @@ public class JseOsLib extends org.luaj.vm2.lib.OsLib {
|
||||
protected String tmpname() {
|
||||
try {
|
||||
java.io.File f = java.io.File.createTempFile(TMP_PREFIX ,TMP_SUFFIX);
|
||||
return f.getName();
|
||||
return f.getAbsolutePath();
|
||||
} catch ( IOException ioe ) {
|
||||
return super.tmpname();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user