|  | /******************************************************************************* | 
|  | * Copyright (c) 2009 Luaj.org. 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. | 
|  | ******************************************************************************/ | 
|  | package org.luaj.vm3; | 
|  |  | 
|  | /** | 
|  | * Class to encapsulate varargs values, either as part of a variable argument list, or multiple return values. | 
|  | * <p> | 
|  | * To construct varargs, use one of the static methods such as | 
|  | * {@code LuaValue.varargsOf(LuaValue,LuaValue)} | 
|  | * <p> | 
|  | * <p> | 
|  | * Any LuaValue can be used as a stand-in for Varargs, for both calls and return values. | 
|  | * When doing so, nargs() will return 1 and arg1() or arg(1) will return this. | 
|  | * This simplifies the case when calling or implementing varargs functions with only | 
|  | * 1 argument or 1 return value. | 
|  | * <p> | 
|  | * Varargs can also be derived from other varargs by appending to the front with a call | 
|  | * such as  {@code LuaValue.varargsOf(LuaValue,Varargs)} | 
|  | * or by taking a portion of the args using {@code Varargs.subargs(int start)} | 
|  | * <p> | 
|  | * @see LuaValue#varargsOf(LuaValue[]) | 
|  | * @see LuaValue#varargsOf(LuaValue, Varargs) | 
|  | * @see LuaValue#varargsOf(LuaValue[], Varargs) | 
|  | * @see LuaValue#varargsOf(LuaValue, LuaValue, Varargs) | 
|  | * @see LuaValue#varargsOf(LuaValue[], int, int) | 
|  | * @see LuaValue#varargsOf(LuaValue[], int, int, Varargs) | 
|  | * @see LuaValue#subargs(int) | 
|  | */ | 
|  | public abstract class Varargs { | 
|  |  | 
|  | /** | 
|  | * Get the n-th argument value (1-based). | 
|  | * @param i the index of the argument to get, 1 is the first argument | 
|  | * @return Value at position i, or LuaValue.NIL if there is none. | 
|  | * @see Varargs#arg1() | 
|  | * @see LuaValue#NIL | 
|  | */ | 
|  | abstract public LuaValue arg( int i ); | 
|  |  | 
|  | /** | 
|  | * Get the number of arguments, or 0 if there are none. | 
|  | * @return number of arguments. | 
|  | */ | 
|  | abstract public int narg(); | 
|  |  | 
|  | /** | 
|  | * Get the first argument in the list. | 
|  | * @return LuaValue which is first in the list, or LuaValue.NIL if there are no values. | 
|  | * @see Varargs#arg(int) | 
|  | * @see LuaValue#NIL | 
|  | */ | 
|  | abstract public LuaValue arg1(); | 
|  |  | 
|  | /** | 
|  | * Evaluate any pending tail call and return result. | 
|  | * @return the evaluated tail call result | 
|  | */ | 
|  | public Varargs eval() { return this; } | 
|  |  | 
|  | /** | 
|  | * Return true if this is a TailcallVarargs | 
|  | * @return true if a tail call, false otherwise | 
|  | */ | 
|  | public boolean isTailcall() { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  | // utilities to get specific arguments and type-check them. | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | /** Gets the type of argument {@code i} | 
|  | * @param i the index of the argument to convert, 1 is the first argument | 
|  | * @return int value corresponding to one of the LuaValue integer type values | 
|  | * @see LuaValue.TNIL | 
|  | * @see LuaValue.TBOOLEAN | 
|  | * @see LuaValue.TNUMBER | 
|  | * @see LuaValue.TSTRING | 
|  | * @see LuaValue.TTABLE | 
|  | * @see LuaValue.TFUNCTION | 
|  | * @see LuaValue.TUSERDATA | 
|  | * @see LuaValue.TTHREAD | 
|  | * */ | 
|  | public int type(int i)             { return arg(i).type(); } | 
|  |  | 
|  | /** Tests if argument i is nil. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return true if the argument is nil or does not exist, false otherwise | 
|  | * @see LuaValue.TNIL | 
|  | * */ | 
|  | public boolean isnil(int i)        { return arg(i).isnil(); } | 
|  |  | 
|  | /** Tests if argument i is a function. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return true if the argument exists and is a function or closure, false otherwise | 
|  | * @see LuaValue.TFUNCTION | 
|  | * */ | 
|  | public boolean isfunction(int i)   { return arg(i).isfunction(); } | 
|  |  | 
|  | /** Tests if argument i is a number. | 
|  | * Since anywhere a number is required, a string can be used that | 
|  | * is a number, this will return true for both numbers and | 
|  | * strings that can be interpreted as numbers. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return true if the argument exists and is a number or | 
|  | * string that can be interpreted as a number, false otherwise | 
|  | * @see LuaValue.TNUMBER | 
|  | * @see LuaValue.TSTRING | 
|  | * */ | 
|  | public boolean isnumber(int i)     { return arg(i).isnumber(); } | 
|  |  | 
|  | /** Tests if argument i is a string. | 
|  | * Since all lua numbers can be used where strings are used, | 
|  | * this will return true for both strings and numbers. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return true if the argument exists and is a string or number, false otherwise | 
|  | * @see LuaValue.TNUMBER | 
|  | * @see LuaValue.TSTRING | 
|  | * */ | 
|  | public boolean isstring(int i)     { return arg(i).isstring(); } | 
|  |  | 
|  | /** Tests if argument i is a table. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return true if the argument exists and is a lua table, false otherwise | 
|  | * @see LuaValue.TTABLE | 
|  | * */ | 
|  | public boolean istable(int i)      { return arg(i).istable(); } | 
|  |  | 
|  | /** Tests if argument i is a thread. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return true if the argument exists and is a lua thread, false otherwise | 
|  | * @see LuaValue.TTHREAD | 
|  | * */ | 
|  | public boolean isthread(int i)     { return arg(i).isthread(); } | 
|  |  | 
|  | /** Tests if argument i is a userdata. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return true if the argument exists and is a userdata, false otherwise | 
|  | * @see LuaValue.TUSERDATA | 
|  | * */ | 
|  | public boolean isuserdata(int i)   { return arg(i).isuserdata(); } | 
|  |  | 
|  | /** Tests if a value exists at argument i. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return true if the argument exists, false otherwise | 
|  | * */ | 
|  | public boolean isvalue(int i)      { return i>0 && i<=narg(); } | 
|  |  | 
|  | /** Return argument i as a boolean value, {@code defval} if nil, or throw a LuaError if any other type. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return true if argument i is boolean true, false if it is false, or defval if not supplied or nil | 
|  | * @exception LuaError if the argument is not a lua boolean | 
|  | * */ | 
|  | public boolean      optboolean(int i, boolean defval)          { return arg(i).optboolean(defval); } | 
|  |  | 
|  | /** Return argument i as a closure, {@code defval} if nil, or throw a LuaError if any other type. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return LuaClosure if argument i is a closure, or defval if not supplied or nil | 
|  | * @exception LuaError if the argument is not a lua closure | 
|  | * */ | 
|  | public LuaClosure   optclosure(int i, LuaClosure defval)       { return arg(i).optclosure(defval); } | 
|  |  | 
|  | /** Return argument i as a double, {@code defval} if nil, or throw a LuaError if it cannot be converted to one. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return java double value if argument i is a number or string that converts to a number, or defval if not supplied or nil | 
|  | * @exception LuaError if the argument is not a number | 
|  | * */ | 
|  | public double       optdouble(int i, double defval)            { return arg(i).optdouble(defval); } | 
|  |  | 
|  | /** Return argument i as a function, {@code defval} if nil, or throw a LuaError  if an incompatible type. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return LuaValue that can be called if argument i is lua function or closure, or defval if not supplied or nil | 
|  | * @exception LuaError if the argument is not a lua function or closure | 
|  | * */ | 
|  | public LuaFunction  optfunction(int i, LuaFunction defval)     { return arg(i).optfunction(defval); } | 
|  |  | 
|  | /** Return argument i as a java int value, discarding any fractional part, {@code defval} if nil, or throw a LuaError  if not a number. | 
|  | * @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, or defval if not supplied or nil | 
|  | * @exception LuaError if the argument is not a number | 
|  | * */ | 
|  | public int          optint(int i, int defval)                  { return arg(i).optint(defval); } | 
|  |  | 
|  | /** Return argument i as a java int value, {@code defval} if nil, or throw a LuaError  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 | 
|  | * @return LuaInteger value that fits in a java int without rounding, or defval if not supplied or nil | 
|  | * @exception LuaError if the argument cannot be represented by a java int value | 
|  | * */ | 
|  | public LuaInteger   optinteger(int i, LuaInteger defval)       { return arg(i).optinteger(defval); } | 
|  |  | 
|  | /** Return argument i as a java long value, discarding any fractional part, {@code defval} if nil, or throw a LuaError  if not a number. | 
|  | * @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, or defval if not supplied or nil | 
|  | * @exception LuaError if the argument is not a number | 
|  | * */ | 
|  | public long         optlong(int i, long defval)                { return arg(i).optlong(defval); } | 
|  |  | 
|  | /** Return argument i as a LuaNumber, {@code defval} if nil, or throw a LuaError  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, or defval if not supplied or nil | 
|  | * @return LuaNumber if argument i is number or can be converted to a number | 
|  | * @exception LuaError if the argument is not a number | 
|  | * */ | 
|  | public LuaNumber    optnumber(int i, LuaNumber defval)         { return arg(i).optnumber(defval); } | 
|  |  | 
|  | /** Return argument i as a java String if a string or number, {@code defval} if nil, or throw a LuaError  if any other type | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return String value if argument i is a string or number, or defval if not supplied or nil | 
|  | * @exception LuaError if the argument is not a string or number | 
|  | * */ | 
|  | public String       optjstring(int i, String defval)           { return arg(i).optjstring(defval); } | 
|  |  | 
|  | /** Return argument i as a LuaString if a string or number, {@code defval} if nil, or throw a LuaError  if any other type | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return LuaString value if argument i is a string or number, or defval if not supplied or nil | 
|  | * @exception LuaError if the argument is not a string or number | 
|  | * */ | 
|  | public LuaString    optstring(int i, LuaString defval)         { return arg(i).optstring(defval); } | 
|  |  | 
|  | /** Return argument i as a LuaTable if a lua table, {@code defval} if nil, or throw a LuaError  if any other type. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return LuaTable value if a table, or defval if not supplied or nil | 
|  | * @exception LuaError if the argument is not a lua table | 
|  | * */ | 
|  | public LuaTable     opttable(int i, LuaTable defval)           { return arg(i).opttable(defval); } | 
|  |  | 
|  | /** Return argument i as a LuaThread if a lua thread, {@code defval} if nil, or throw a LuaError  if any other type. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return LuaThread value if a thread, or defval if not supplied or nil | 
|  | * @exception LuaError if the argument is not a lua thread | 
|  | * */ | 
|  | public LuaThread    optthread(int i, LuaThread defval)         { return arg(i).optthread(defval); } | 
|  |  | 
|  | /** Return argument i as a java Object if a userdata, {@code defval} if nil, or throw a LuaError  if any other type. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return java Object value if argument i is a userdata, or defval if not supplied or nil | 
|  | * @exception LuaError if the argument is not a userdata | 
|  | * */ | 
|  | public Object       optuserdata(int i, Object defval)          { return arg(i).optuserdata(defval); } | 
|  |  | 
|  | /** Return argument i as a java Object if it is a userdata whose instance Class c or a subclass, | 
|  | * {@code defval} if nil, or throw a LuaError  if any other type. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @param c the class to which the userdata instance must be assignable | 
|  | * @return java Object value if argument i is a userdata whose instance Class c or a subclass, or defval if not supplied or nil | 
|  | * @exception LuaError if the argument is not a userdata or from whose instance c is not assignable | 
|  | * */ | 
|  | public Object       optuserdata(int i, Class c, Object defval) { return arg(i).optuserdata(c,defval); } | 
|  |  | 
|  | /** Return argument i as a LuaValue if it exists, or {@code defval}. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return LuaValue value if the argument exists, defval if not | 
|  | * @exception LuaError if the argument does not exist. | 
|  | * */ | 
|  | public LuaValue     optvalue(int i, LuaValue defval)           { return i>0 && i<=narg()? arg(i): defval; } | 
|  |  | 
|  | /** Return argument i as a boolean value, or throw an error if any other type. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return true if argument i is boolean true, false if it is false | 
|  | * @exception LuaError if the argument is not a lua boolean | 
|  | * */ | 
|  | public boolean      checkboolean(int i)          { return arg(i).checkboolean(); } | 
|  |  | 
|  | /** Return argument i as a closure, or throw an error if any other type. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return LuaClosure if argument i is a closure. | 
|  | * @exception LuaError if the argument is not a lua closure | 
|  | * */ | 
|  | public LuaClosure   checkclosure(int i)          { return arg(i).checkclosure(); } | 
|  |  | 
|  | /** Return argument i as a double, 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 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(); } | 
|  |  | 
|  | /** 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 | 
|  | * @return LuaValue that can be called if argument i is lua function or closure | 
|  | * @exception LuaError if the argument is not a lua function or closure | 
|  | * */ | 
|  | 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. | 
|  | * @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 | 
|  | * */ | 
|  | public int          checkint(int i)              { return arg(i).checknumber().toint(); } | 
|  |  | 
|  | /** 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 | 
|  | * @return LuaInteger value that fits in a java int without rounding | 
|  | * @exception LuaError if the argument cannot be represented by a java int value | 
|  | * */ | 
|  | 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. | 
|  | * @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 | 
|  | * */ | 
|  | public long         checklong(int i)             { return arg(i).checknumber().tolong(); } | 
|  |  | 
|  | /** 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 | 
|  | * @return LuaNumber if argument i is number or can be converted to a number | 
|  | * @exception LuaError if the argument is not a number | 
|  | * */ | 
|  | public LuaNumber    checknumber(int i)           { return arg(i).checknumber(); } | 
|  |  | 
|  | /** Return argument i as a java String if a string or number, or throw an error if any other type | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return String value if argument i is a string or number | 
|  | * @exception LuaError if the argument is not a string or number | 
|  | * */ | 
|  | public String       checkjstring(int i)          { return arg(i).checkjstring(); } | 
|  |  | 
|  | /** Return argument i as a LuaString if a string or number, or throw an error if any other type | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return LuaString value if argument i is a string or number | 
|  | * @exception LuaError if the argument is not a string or number | 
|  | * */ | 
|  | public LuaString    checkstring(int i)           { return arg(i).checkstring(); } | 
|  |  | 
|  | /** Return argument i as a LuaTable if a lua table, or throw an error if any other type. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return LuaTable value if a table | 
|  | * @exception LuaError if the argument is not a lua table | 
|  | * */ | 
|  | public LuaTable     checktable(int i)            { return arg(i).checktable(); } | 
|  |  | 
|  | /** Return argument i as a LuaThread if a lua thread, or throw an error if any other type. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return LuaThread value if a thread | 
|  | * @exception LuaError if the argument is not a lua thread | 
|  | * */ | 
|  | public LuaThread    checkthread(int i)           { return arg(i).checkthread(); } | 
|  |  | 
|  | /** Return argument i as a java Object if a userdata, or throw an error if any other type. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return java Object value if argument i is a userdata | 
|  | * @exception LuaError if the argument is not a userdata | 
|  | * */ | 
|  | public Object       checkuserdata(int i)         { return arg(i).checkuserdata(); } | 
|  |  | 
|  | /** Return argument i as a java Object if it is a userdata whose instance Class c or a subclass, | 
|  | * or throw an error if any other type. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @param c the class to which the userdata instance must be assignable | 
|  | * @return java Object value if argument i is a userdata whose instance Class c or a subclass | 
|  | * @exception LuaError if the argument is not a userdata or from whose instance c is not assignable | 
|  | * */ | 
|  | public Object       checkuserdata(int i,Class c) { return arg(i).checkuserdata(c); } | 
|  |  | 
|  | /** Return argument i as a LuaValue if it exists, or throw an error. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return LuaValue value if the argument exists | 
|  | * @exception LuaError if the argument does not exist. | 
|  | * */ | 
|  | public LuaValue     checkvalue(int i)            { return i<=narg()? arg(i): LuaValue.argerror(i,"value expected"); } | 
|  |  | 
|  | /** Return argument i as a LuaValue if it is not nil, or throw an error if it is nil. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return LuaValue value if the argument is not nil | 
|  | * @exception LuaError if the argument doesn't exist or evaluates to nil. | 
|  | * */ | 
|  | public LuaValue     checknotnil(int i)           { return arg(i).checknotnil(); } | 
|  |  | 
|  | /** Return argument i as a LuaValue when a user-supplied assertion passes, or throw an error. | 
|  | * @param test user supplied assertion to test against | 
|  | * @param i the index to report in any error message | 
|  | * @param msg the error message to use when the test fails | 
|  | * @return LuaValue value if the value of {@code test} is {@code true} | 
|  | * @exception LuaError if the the value of {@code test} is {@code false} | 
|  | * */ | 
|  | public void         argcheck(boolean test, int i, String msg) { if (!test) LuaValue.argerror(i,msg); } | 
|  |  | 
|  | /** Return true if there is no argument or nil at argument i. | 
|  | * @param i the index of the argument to test, 1 is the first argument | 
|  | * @return true if argument i contains either no argument or nil | 
|  | * */ | 
|  | public boolean isnoneornil(int i) { | 
|  | return i>narg() || arg(i).isnil(); | 
|  | } | 
|  |  | 
|  | /** Convert argument {@code i} to java boolean based on lua rules for boolean evaluation. | 
|  | * @param i the index of the argument to convert, 1 is the first argument | 
|  | * @return {@code false} if argument i is nil or false, otherwise {@code true} | 
|  | * */ | 
|  | public boolean toboolean(int i)           { return arg(i).toboolean(); } | 
|  |  | 
|  | /** Return argument i as a java byte value, discarding any fractional part and truncating, | 
|  | * or 0 if not a number. | 
|  | * @param i the index of the argument to convert, 1 is the first argument | 
|  | * @return byte value with fraction discarded and truncated if necessary if argument i is number, otherwise 0 | 
|  | * */ | 
|  | public byte    tobyte(int i)              { return arg(i).tobyte(); } | 
|  |  | 
|  | /** Return argument i as a java char value, discarding any fractional part and truncating, | 
|  | * or 0 if not a number. | 
|  | * @param i the index of the argument to convert, 1 is the first argument | 
|  | * @return char value with fraction discarded and truncated if necessary if argument i is number, otherwise 0 | 
|  | * */ | 
|  | public char    tochar(int i)              { return arg(i).tochar(); } | 
|  |  | 
|  | /** Return argument i as a java double value or 0 if not a number. | 
|  | * @param i the index of the argument to convert, 1 is the first argument | 
|  | * @return double value if argument i is number, otherwise 0 | 
|  | * */ | 
|  | public double  todouble(int i)            { return arg(i).todouble(); } | 
|  |  | 
|  | /** Return argument i as a java float value, discarding excess fractional part and truncating, | 
|  | * or 0 if not a number. | 
|  | * @param i the index of the argument to convert, 1 is the first argument | 
|  | * @return float value with excess fraction discarded and truncated if necessary if argument i is number, otherwise 0 | 
|  | * */ | 
|  | public float   tofloat(int i)             { return arg(i).tofloat(); } | 
|  |  | 
|  | /** Return argument i as a java int value, discarding any fractional part and truncating, | 
|  | * or 0 if not a number. | 
|  | * @param i the index of the argument to convert, 1 is the first argument | 
|  | * @return int value with fraction discarded and truncated if necessary if argument i is number, otherwise 0 | 
|  | * */ | 
|  | public int     toint(int i)               { return arg(i).toint(); } | 
|  |  | 
|  | /** Return argument i as a java long value, discarding any fractional part and truncating, | 
|  | * or 0 if not a number. | 
|  | * @param i the index of the argument to convert, 1 is the first argument | 
|  | * @return long value with fraction discarded and truncated if necessary if argument i is number, otherwise 0 | 
|  | * */ | 
|  | public long    tolong(int i)              { return arg(i).tolong(); } | 
|  |  | 
|  | /** Return argument i as a java String based on the type of the argument. | 
|  | * @param i the index of the argument to convert, 1 is the first argument | 
|  | * @return String value representing the type | 
|  | * */ | 
|  | public String  tojstring(int i)           { return arg(i).tojstring(); } | 
|  |  | 
|  | /** Return argument i as a java short value, discarding any fractional part and truncating, | 
|  | * or 0 if not a number. | 
|  | * @param i the index of the argument to convert, 1 is the first argument | 
|  | * @return short value with fraction discarded and truncated if necessary if argument i is number, otherwise 0 | 
|  | * */ | 
|  | public short   toshort(int i)             { return arg(i).toshort(); } | 
|  |  | 
|  | /** Return argument i as a java Object if a userdata, or null. | 
|  | * @param i the index of the argument to convert, 1 is the first argument | 
|  | * @return java Object value if argument i is a userdata, otherwise null | 
|  | * */ | 
|  | public Object  touserdata(int i)          { return arg(i).touserdata(); } | 
|  |  | 
|  | /** Return argument i as a java Object if it is a userdata whose instance Class c or a subclass, or null. | 
|  | * @param i the index of the argument to convert, 1 is the first argument | 
|  | * @param c the class to which the userdata instance must be assignable | 
|  | * @return java Object value if argument i is a userdata whose instance Class c or a subclass, otherwise null | 
|  | * */ | 
|  | public Object  touserdata(int i,Class c)  { return arg(i).touserdata(c); } | 
|  |  | 
|  | /** Convert the list of varargs values to a human readable java String. | 
|  | * @return String value in human readable form such as {1,2}. | 
|  | */ | 
|  | public String tojstring() { | 
|  | Buffer sb = new Buffer(); | 
|  | sb.append( "(" ); | 
|  | for ( int i=1,n=narg(); i<=n; i++ ) { | 
|  | if (i>1) sb.append( "," ); | 
|  | sb.append( arg(i).tojstring() ); | 
|  | } | 
|  | sb.append( ")" ); | 
|  | return sb.tojstring(); | 
|  | } | 
|  |  | 
|  | /** Convert the value or values to a java String using Varargs.tojstring() | 
|  | * @return String value in human readable form. | 
|  | * @see Varargs#tojstring() | 
|  | */ | 
|  | public String toString() { return tojstring(); } | 
|  |  | 
|  | /** | 
|  | * Create a {@code Varargs} instance containing arguments starting at index {@code start} | 
|  | * @param start the index from which to include arguments, where 1 is the first argument. | 
|  | * @return Varargs containing argument { start, start+1,  ... , narg-start-1 } | 
|  | */ | 
|  | abstract public Varargs subargs(final int start); | 
|  |  | 
|  | /** | 
|  | * Implementation of Varargs for use in the Varargs.subargs() function. | 
|  | * @see Varargs#subargs(int) | 
|  | */ | 
|  | static class SubVarargs extends Varargs { | 
|  | private final Varargs v; | 
|  | private final int start; | 
|  | private final int end; | 
|  | public SubVarargs(Varargs varargs, int start, int end) { | 
|  | this.v = varargs; | 
|  | this.start = start; | 
|  | this.end = end; | 
|  | } | 
|  | public LuaValue arg(int i) { | 
|  | i += start-1; | 
|  | return i>=start && i<=end? v.arg(i): LuaValue.NIL; | 
|  | } | 
|  | public LuaValue arg1() { | 
|  | return v.arg(start); | 
|  | } | 
|  | public int narg() { | 
|  | return end+1-start; | 
|  | } | 
|  | public Varargs subargs(final int start) { | 
|  | if (start == 1) | 
|  | return this; | 
|  | final int newstart = this.start + start - 1; | 
|  | if (start > 0) { | 
|  | if (newstart >= this.end) | 
|  | return LuaValue.NONE; | 
|  | if (newstart == this.end) | 
|  | return v.arg(this.end); | 
|  | if (newstart == this.end-1) | 
|  | return new Varargs.PairVarargs(v.arg(this.end-1), v.arg(this.end)); | 
|  | return new SubVarargs(v, newstart, this.end); | 
|  | } | 
|  | return new SubVarargs(v, newstart, this.end); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** Varargs implemenation backed by two values. | 
|  | * <p> | 
|  | * This is an internal class not intended to be used directly. | 
|  | * Instead use the corresponding static method on LuaValue. | 
|  | * | 
|  | * @see LuaValue#varargsOf(LuaValue, Varargs) | 
|  | */ | 
|  | static final class PairVarargs extends Varargs { | 
|  | private final LuaValue v1; | 
|  | private final Varargs v2; | 
|  | /** Construct a Varargs from an two LuaValue. | 
|  | * <p> | 
|  | * This is an internal class not intended to be used directly. | 
|  | * Instead use the corresponding static method on LuaValue. | 
|  | * | 
|  | * @see LuaValue#varargsOf(LuaValue, Varargs) | 
|  | */ | 
|  | PairVarargs(LuaValue v1, Varargs v2) { | 
|  | this.v1 = v1; | 
|  | this.v2 = v2; | 
|  | } | 
|  | public LuaValue arg(int i) { | 
|  | return i==1? v1: v2.arg(i-1); | 
|  | } | 
|  | public int narg() { | 
|  | return 1+v2.narg(); | 
|  | } | 
|  | public LuaValue arg1() { | 
|  | return v1; | 
|  | } | 
|  | public Varargs subargs(final int start) { | 
|  | if (start == 1) | 
|  | return this; | 
|  | if (start == 2) | 
|  | return v2; | 
|  | if (start > 2) | 
|  | return v2.subargs(start - 1); | 
|  | return LuaValue.argerror(1, "start must be > 0"); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** Varargs implemenation backed by an array of LuaValues | 
|  | * <p> | 
|  | * This is an internal class not intended to be used directly. | 
|  | * Instead use the corresponding static methods on LuaValue. | 
|  | * | 
|  | * @see LuaValue#varargsOf(LuaValue[]) | 
|  | * @see LuaValue#varargsOf(LuaValue[], Varargs) | 
|  | */ | 
|  | static final class ArrayVarargs extends Varargs { | 
|  | private final LuaValue[] v; | 
|  | private final Varargs r; | 
|  | /** Construct a Varargs from an array of LuaValue. | 
|  | * <p> | 
|  | * This is an internal class not intended to be used directly. | 
|  | * Instead use the corresponding static methods on LuaValue. | 
|  | * | 
|  | * @see LuaValue#varargsOf(LuaValue[]) | 
|  | * @see LuaValue#varargsOf(LuaValue[], Varargs) | 
|  | */ | 
|  | ArrayVarargs(LuaValue[] v, Varargs r) { | 
|  | this.v = v; | 
|  | this.r = r ; | 
|  | for (int i = 0; i < v.length; ++i) | 
|  | if (v[i] == null) | 
|  | throw new IllegalArgumentException("nulls in array"); | 
|  | } | 
|  | public LuaValue arg(int i) { | 
|  | return i < 1 ? LuaValue.NIL: i <= v.length? v[i - 1]: r.arg(i-v.length); | 
|  | } | 
|  | public int narg() { | 
|  | return v.length+r.narg(); | 
|  | } | 
|  | public LuaValue arg1() { return v.length>0? v[0]: r.arg1(); } | 
|  | public Varargs subargs(int start) { | 
|  | if (start <= 0) | 
|  | LuaValue.argerror(1, "start must be > 0"); | 
|  | if (start == 1) | 
|  | return this; | 
|  | if (start > v.length) | 
|  | return r.subargs(start - v.length); | 
|  | return LuaValue.varargsOf(v, start - 1, v.length - (start - 1), r); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** Varargs implemenation backed by an array of LuaValues | 
|  | * <p> | 
|  | * This is an internal class not intended to be used directly. | 
|  | * Instead use the corresponding static methods on LuaValue. | 
|  | * | 
|  | * @see LuaValue#varargsOf(LuaValue[], int, int) | 
|  | * @see LuaValue#varargsOf(LuaValue[], int, int, Varargs) | 
|  | */ | 
|  | static final class ArrayPartVarargs extends Varargs { | 
|  | private final int offset; | 
|  | private final LuaValue[] v; | 
|  | private final int length; | 
|  | private final Varargs more; | 
|  | /** Construct a Varargs from an array of LuaValue. | 
|  | * <p> | 
|  | * This is an internal class not intended to be used directly. | 
|  | * Instead use the corresponding static methods on LuaValue. | 
|  | * | 
|  | * @see LuaValue#varargsOf(LuaValue[], int, int) | 
|  | */ | 
|  | ArrayPartVarargs(LuaValue[] v, int offset, int length) { | 
|  | this.v = v; | 
|  | this.offset = offset; | 
|  | this.length = length; | 
|  | this.more = LuaValue.NONE; | 
|  | } | 
|  | /** Construct a Varargs from an array of LuaValue and additional arguments. | 
|  | * <p> | 
|  | * This is an internal class not intended to be used directly. | 
|  | * Instead use the corresponding static method on LuaValue. | 
|  | * | 
|  | * @see LuaValue#varargsOf(LuaValue[], int, int, Varargs) | 
|  | */ | 
|  | public ArrayPartVarargs(LuaValue[] v, int offset, int length, Varargs more) { | 
|  | this.v = v; | 
|  | this.offset = offset; | 
|  | this.length = length; | 
|  | this.more = more; | 
|  | } | 
|  | public LuaValue arg(final int i) { | 
|  | return i < 1? LuaValue.NIL: i <= length? v[offset+i-1]: more.arg(i-length); | 
|  | } | 
|  | public int narg() { | 
|  | return length + more.narg(); | 
|  | } | 
|  | public LuaValue arg1() { | 
|  | return length>0? v[offset]: more.arg1(); | 
|  | } | 
|  | public Varargs subargs(int start) { | 
|  | if (start <= 0) | 
|  | LuaValue.argerror(1, "start must be > 0"); | 
|  | if (start == 1) | 
|  | return this; | 
|  | if (start > length) | 
|  | return more.subargs(start - length); | 
|  | return LuaValue.varargsOf(v, offset + start - 1, length - (start - 1), more); | 
|  | } | 
|  | } | 
|  | } |