diff --git a/src/core/org/luaj/vm2/LuaDouble.java b/src/core/org/luaj/vm2/LuaDouble.java index 69e1bafb..85b151ce 100644 --- a/src/core/org/luaj/vm2/LuaDouble.java +++ b/src/core/org/luaj/vm2/LuaDouble.java @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2009 Luaj.org. All rights reserved. +* Copyright (c) 2009-2011 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 @@ -23,15 +23,55 @@ package org.luaj.vm2; import org.luaj.vm2.lib.MathLib; +/** + * Extension of {@link LuaNumber} which can hold a Java double as its value. + *

+ * These instance are not instantiated directly by clients, but indirectly + * via the static functions {@link LuaValue#valueOf(int)} or {@link LuaValue#valueOf(double)} + * functions. This ensures that values which can be represented as int + * are wrapped in {@link LuaInteger} instead of {@link LuaDouble}. + *

+ * Almost all API's implemented in LuaDouble are defined and documented in {@link LuaValue}. + *

+ * However the constants {@link #NAN}, {@link #POSINF}, {@link #NEGINF}, + * {@link #JSTR_NAN}, {@link #JSTR_POSINF}, and {@link #JSTR_NEGINF} may be useful + * when dealing with Nan or Infinite values. + *

+ * LuaDouble also defines functions for handling the unique math rules of lua devision and modulo in + *

+ *

+ * @see LuaValue + * @see LuaNumber + * @see LuaInteger + * @see LuaValue#valueOf(int) + * @see LuaValue#valueOf(double) + */ public class LuaDouble extends LuaNumber { + /** Constant LuaDouble representing NaN (not a number) */ public static final LuaDouble NAN = new LuaDouble( Double.NaN ); + + /** Constant LuaDouble representing positive infinity */ public static final LuaDouble POSINF = new LuaDouble( Double.POSITIVE_INFINITY ); + + /** Constant LuaDouble representing negative infinity */ public static final LuaDouble NEGINF = new LuaDouble( Double.NEGATIVE_INFINITY ); + + /** Constant String representation for NaN (not a number), "nan" */ public static final String JSTR_NAN = "nan"; + + /** Constant String representation for positive infinity, "inf" */ public static final String JSTR_POSINF = "inf"; + + /** Constant String representation for negative infinity, "-inf" */ public static final String JSTR_NEGINF = "-inf"; + /** The value being held by this instance. */ final double v; public static LuaNumber valueOf(double d) { @@ -107,18 +147,46 @@ public class LuaDouble extends LuaNumber { public LuaValue mod( int rhs ) { return LuaDouble.dmod(v,rhs); } public LuaValue modFrom( double lhs ) { return LuaDouble.dmod(lhs,v); } - /** lua division is always double, specific values for singularities */ + + /** Divide two double numbers according to lua math, and return a {@link LuaValue} result. + * @param lhs Left-hand-side of the division. + * @param rhs Right-hand-side of the division. + * @return {@link LuaValue} for the result of the division, + * taking into account positive and negiative infinity, and Nan + * @see #ddiv_d(double, double) + */ public static LuaValue ddiv(double lhs, double rhs) { return rhs!=0? valueOf( lhs / rhs ): lhs>0? POSINF: lhs==0? NAN: NEGINF; } + + /** Divide two double numbers according to lua math, and return a double result. + * @param lhs Left-hand-side of the division. + * @param rhs Right-hand-side of the division. + * @return Value of the division, taking into account positive and negative infinity, and Nan + * @see #ddiv(double, double) + */ public static double ddiv_d(double lhs, double rhs) { return rhs!=0? lhs / rhs: lhs>0? Double.POSITIVE_INFINITY: lhs==0? Double.NaN: Double.NEGATIVE_INFINITY; } - /** lua module is always wrt double. */ + /** Take modulo double numbers according to lua math, and return a {@link LuaValue} result. + * @param lhs Left-hand-side of the modulo. + * @param rhs Right-hand-side of the modulo. + * @return {@link LuaValue} for the result of the modulo, + * using lua's rules for modulo + * @see #dmod_d(double, double) + */ public static LuaValue dmod(double lhs, double rhs) { return rhs!=0? valueOf( lhs-rhs*Math.floor(lhs/rhs) ): NAN; } + + /** Take modulo for double numbers according to lua math, and return a double result. + * @param lhs Left-hand-side of the modulo. + * @param rhs Right-hand-side of the modulo. + * @return double value for the result of the modulo, + * using lua's rules for modulo + * @see #dmod(double, double) + */ public static double dmod_d(double lhs, double rhs) { return rhs!=0? lhs-rhs*Math.floor(lhs/rhs): Double.NaN; } diff --git a/src/core/org/luaj/vm2/LuaFunction.java b/src/core/org/luaj/vm2/LuaFunction.java index 7038a055..4bface62 100644 --- a/src/core/org/luaj/vm2/LuaFunction.java +++ b/src/core/org/luaj/vm2/LuaFunction.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Luaj.org. All rights reserved. + * Copyright (c) 2009-2011 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 @@ -21,9 +21,18 @@ ******************************************************************************/ package org.luaj.vm2; +/** + * Base class for functions implemented in Java. + *

+ * Direct subclass include {@link LibFunction} which is the base class for + * all built-in library functions coded in Java, + * and {@link LuaClosure}, which represents a lua closure + * whose bytecode is interpreted when the function is invoked. + */ abstract public class LuaFunction extends LuaValue { + /** Shared static metatable for all functions and closures. */ public static LuaValue s_metatable; protected LuaValue env; diff --git a/src/core/org/luaj/vm2/LuaInteger.java b/src/core/org/luaj/vm2/LuaInteger.java index 99eb38d3..008efdd4 100644 --- a/src/core/org/luaj/vm2/LuaInteger.java +++ b/src/core/org/luaj/vm2/LuaInteger.java @@ -23,6 +23,23 @@ package org.luaj.vm2; import org.luaj.vm2.lib.MathLib; +/** + * Extension of {@link LuaNumber} which can hold a Java int as its value. + *

+ * These instance are not instantiated directly by clients, but indirectly + * via the static functions {@link LuaValue#valueOf(int)} or {@link LuaValue#valueOf(double)} + * functions. This ensures that policies regarding pooling of instances are + * encapsulated. + *

+ * There are no API's specific to LuaInteger that are useful beyond what is already + * exposed in {@link LuaValue}. + * + * @see LuaValue + * @see LuaNumber + * @see LuaDouble + * @see LuaValue#valueOf(int) + * @see LuaValue#valueOf(double) + */ public class LuaInteger extends LuaNumber { private static final LuaInteger[] intValues = new LuaInteger[512]; @@ -35,6 +52,13 @@ public class LuaInteger extends LuaNumber { return i<=255 && i>=-256? intValues[i+256]: new LuaInteger(i); }; + // TODO consider moving this to LuaValue + /** Return a LuaNumber that represents the value provided + * @param l long value to represent. + * @return LuaNumber that is eithe LuaInteger or LuaDouble representing l + * @see LuaValue#valueOf(int) + * @see LuaValue#valueOf(double) + */ public static LuaNumber valueOf(long l) { int i = (int) l; return l==i? (i<=255 && i>=-256? intValues[i+256]: @@ -42,9 +66,13 @@ public class LuaInteger extends LuaNumber { (LuaNumber) LuaDouble.valueOf(l); } + /** The value being held by this instance. */ public final int v; - /** package protected constructor, @see IntValue.valueOf(int) */ + /** + * Package protected constructor. + * @see LuaValue#valueOf(int) + **/ LuaInteger(int i) { this.v = i; } diff --git a/src/core/org/luaj/vm2/LuaNil.java b/src/core/org/luaj/vm2/LuaNil.java index 5068b43b..78d147b3 100644 --- a/src/core/org/luaj/vm2/LuaNil.java +++ b/src/core/org/luaj/vm2/LuaNil.java @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2009 Luaj.org. All rights reserved. +* Copyright (c) 2009-2011 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 diff --git a/src/core/org/luaj/vm2/LuaNumber.java b/src/core/org/luaj/vm2/LuaNumber.java index d8d19a66..ffc170cd 100644 --- a/src/core/org/luaj/vm2/LuaNumber.java +++ b/src/core/org/luaj/vm2/LuaNumber.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Luaj.org. All rights reserved. + * Copyright (c) 2009-2011 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 @@ -21,9 +21,19 @@ ******************************************************************************/ package org.luaj.vm2; +/** + * Base class for representing numbers as lua values directly. + *

+ * The main subclasses are {@link LuaInteger} which holds values that fit in a java int, + * and {@link LuaDouble} which holds all other number values. + * @see LuaInteger + * @see LuaDouble + * + */ abstract public class LuaNumber extends LuaValue { + /** Shared static metatable for all number values represented in lua. */ public static LuaValue s_metatable; public int type() { diff --git a/src/core/org/luaj/vm2/LuaValue.java b/src/core/org/luaj/vm2/LuaValue.java index 33547b14..ec3fe779 100644 --- a/src/core/org/luaj/vm2/LuaValue.java +++ b/src/core/org/luaj/vm2/LuaValue.java @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2009 Luaj.org. All rights reserved. +* Copyright (c) 2009-2011 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 @@ -22,23 +22,114 @@ package org.luaj.vm2; - +/** + * Base class for all concrete lua type values. + *

+ * Establishes base implementations for all the operations on lua types. + * This allows Java clients to deal essentially with one type for all Java values, namely {@link LuaValue}. + *

+ * Constructors are provided as static methods for common Java types, such as + * {@link LuaValue#valueOf(int)} or {@link LuaValue#valueOf(String)}. + * Primarily this is used to encourage instance pooling for small integers or short strings. + *

+ * Constants are defined for the lua values + * {@link LuaValue#NIL}, {@link LuaValue#TRUE}, and {@link LuaValue#FALSE}. + * A constant {@link LuaValue#NONE} is defined which is a {@link Varargs} list having no values. + * Predefined constants exist for the standard lua type constants + * {@link TNIL}, {@link TBOOLEAN}, {@link TLIGHTUSERDATA}, {@link TNUMBER}, {@link TSTRING}, + * {@link TTABLE}, {@link TFUNCTION}, {@link TUSERDATA}, {@link TTHREAD}, + * extended lua type constants + * {@link TINT}, {@link TNONE}, {@link TVALUE}, + * as well as for the metatags + * {@link INDEX}, {@link NEWINDEX}, {@link CALL}, {@link MODE}, {@link METATABLE}, + * {@link ADD}, {@link SUB}, {@link DIV}, {@link MUL}, {@link POW}, + * {@link MOD}, {@link UNM}, {@link LEN}, {@link EQ}, {@link LT}, + * {@link LE}, {@link TOSTRING}, {@link CONCAT} as well as + *

+ * Operations are performed on values directly via their Java methods. + * For example, the following code divides two numbers: + *

 {@code
+ * LuaValue a = LuaValue.valueOf( 5 );
+ * LuaValue b = LuaValue.valueOf( 4 );
+ * LuaValue c = a.div(b);
+ * } 
+ * Note that in this example, c will be a {@link LuaDouble}, but would be a {@link LuaInteger} + * if the value of a were changed to 8, say. + * In general the value of c in practice will vary depending on both the types and values of a and b + * as well as any metatable/metatag processing that occurs. + *

+ * Field access and function calls are similar, with common overloads to simplify Java usage: + *

 {@code
+ * LuaValue globals = JsePlatform.standardGlobals();
+ * LuaValue sqrt = globals.get("math").get("sqrt");
+ * LuaValue print = globals.get("print");
+ * LuaValue d = sqrt.call( a );
+ * print.call( LuaValue.valueOf("sqrt(5):"), a );
+ * } 
+ *

+ * To supply variable arguments or get multiple return values, use + * {@link invoke(Varargs)} or {@link invokemethod(LuaValue, Varargs)} methods: + *

 {@code
+ * LuaValue modf = globals.get("math").get("modf");
+ * Varargs r = modf.invoke( d );
+ * print.call( r.arg(1), r.arg(2) );
+ * } 
+ *

+ * In general a {@link LuaError} may be thrown on any operation when the + * types supplied to any operation are illegal from a lua perspective. + * Examples could be attempting to concatenate a NIL value, or attempting arithmetic + * on values that are not number. + *

+ * When a {@link LuaTable} is required by an api, a table constructor such as {@link tableOf()} + * can be used, or the type may be coerced via {@link checktable()} or {@link opttable(LuaValue)}. + * Constructors exist to create pre-initialized tables such as {@link LuaValue#tableOf(LuaValue[])} + * for lists, {@link LuaValue#tableOf(LuaValue[], LuaValue[])} for hashtables, + * or {@link LuaValue#tableOf(LuaValue[], LuaValue[], Varargs)} for mixed tables. + */ abstract public class LuaValue extends Varargs { + + /** Type enumeration constant for lua numbers that are ints, for compatibility with lua 5.1 number patch only */ public static final int TINT = (-2); + + /** Type enumeration constant for lua values that have no type, for example weak table entries */ public static final int TNONE = (-1); + + /** Type enumeration constant for lua nil */ public static final int TNIL = 0; + + /** Type enumeration constant for lua booleans */ public static final int TBOOLEAN = 1; + + /** Type enumeration constant for lua light userdata, for compatibility with C-based lua only */ public static final int TLIGHTUSERDATA = 2; + + /** Type enumeration constant for lua numbers */ public static final int TNUMBER = 3; + + /** Type enumeration constant for lua strings */ public static final int TSTRING = 4; + + /** Type enumeration constant for lua tables */ public static final int TTABLE = 5; + + /** Type enumeration constant for lua functions */ public static final int TFUNCTION = 6; + + /** Type enumeration constant for lua userdatas */ public static final int TUSERDATA = 7; + + /** Type enumeration constant for lua threads */ public static final int TTHREAD = 8; + + /** Type enumeration constant for unknown values, for compatibility with C-based lua only */ public static final int TVALUE = 9; + /** String array constant containing names of each of the lua value types + * @see #type() + * @see #typename() + */ public static final String[] TYPE_NAMES = { "nil", "boolean", @@ -52,36 +143,94 @@ public class LuaValue extends Varargs { "value", }; + /** LuaValue constant corresponding to lua {@code nil} */ public static final LuaValue NIL = LuaNil._NIL; + + /** LuaBoolean constant corresponding to lua {@code true} */ public static final LuaBoolean TRUE = LuaBoolean._TRUE; + + /** LuaBoolean constant corresponding to lua {@code false} */ public static final LuaBoolean FALSE = LuaBoolean._FALSE; + + /** LuaValue constant corresponding to a {@link Varargs} list of no values */ public static final LuaValue NONE = None._NONE; + + /** LuaValue number constant equal to 0 */ public static final LuaNumber ZERO = LuaInteger.valueOf(0); + + /** LuaValue number constant equal to 1 */ public static final LuaNumber ONE = LuaInteger.valueOf(1); + + /** LuaValue number constant equal to -1 */ public static final LuaNumber MINUSONE = LuaInteger.valueOf(-1); + + /** LuaValue array constant with no values */ public static final LuaValue[] NOVALS = {}; + + /** LuaString constant with value "__index" for use as metatag */ public static final LuaString INDEX = valueOf("__index"); + + /** LuaString constant with value "__newindex" for use as metatag */ public static final LuaString NEWINDEX = valueOf("__newindex"); + + /** LuaString constant with value "__call" for use as metatag */ public static final LuaString CALL = valueOf("__call"); + + /** LuaString constant with value "__mode" for use as metatag */ public static final LuaString MODE = valueOf("__mode"); + + /** LuaString constant with value "__metatable" for use as metatag */ public static final LuaString METATABLE = valueOf("__metatable"); + + /** LuaString constant with value "__add" for use as metatag */ public static final LuaString ADD = valueOf("__add"); + + /** LuaString constant with value "__sub" for use as metatag */ public static final LuaString SUB = valueOf("__sub"); + + /** LuaString constant with value "__div" for use as metatag */ public static final LuaString DIV = valueOf("__div"); + + /** LuaString constant with value "__mul" for use as metatag */ public static final LuaString MUL = valueOf("__mul"); + + /** LuaString constant with value "__pow" for use as metatag */ public static final LuaString POW = valueOf("__pow"); + + /** LuaString constant with value "__mod" for use as metatag */ public static final LuaString MOD = valueOf("__mod"); + + /** LuaString constant with value "__unm" for use as metatag */ public static final LuaString UNM = valueOf("__unm"); + + /** LuaString constant with value "__len" for use as metatag */ public static final LuaString LEN = valueOf("__len"); + + /** LuaString constant with value "__eq" for use as metatag */ public static final LuaString EQ = valueOf("__eq"); + + /** LuaString constant with value "__lt" for use as metatag */ public static final LuaString LT = valueOf("__lt"); + + /** LuaString constant with value "__le" for use as metatag */ public static final LuaString LE = valueOf("__le"); + + /** LuaString constant with value "__tostring" for use as metatag */ public static final LuaString TOSTRING = valueOf("__tostring"); + + /** LuaString constant with value "__concat" for use as metatag */ public static final LuaString CONCAT = valueOf("__concat"); - public static final LuaString EMPTYSTRING = valueOf(""); + /** LuaString constant with value "" */ + public static final LuaString EMPTYSTRING = valueOf(""); + + /** Limit on lua stack size */ private static int MAXSTACK = 250; + + /** Array of {@link NIL} values to optimize filling stacks using System.arraycopy(). + * Must not be modified. + */ public static final LuaValue[] NILS = new LuaValue[MAXSTACK]; static { for ( int i=0; i + * + * @return name from type name list {@link #TYPE_NAMES} + * corresponding to the type of this value: + * "nil", "boolean", "number", "string", + * "table", "function", "userdata", "thread" + * @see #type() + */ abstract public String typename(); - // type checks + /** Check if {@code this} is a {@code boolean} + * @return true if this is a {@code boolean}, otherwise false + * @see #isboolean() + * @see #toboolean() + * @see #checkboolean() + * @see #optboolean(boolean) + * @see #TOBOLEAN + */ public boolean isboolean() { return false; } + + /** Check if {@code this} is a {@code function} that is a closure, + * meaning interprets lua bytecode for its execution + * @return true if this is a {@code closure}, otherwise false + * @see #isfunction() + * @see #checkclosure() + * @see #optclosure(LuaClosure) + * @see #TFUNCTION + */ public boolean isclosure() { return false; } + + /** Check if {@code this} is a {@code function} + * @return true if this is a {@code function}, otherwise false + * @see #isclosure() + * @see #checkfunction() + * @see #optfunciton(LuaFunction) + * @see #TFUNCTION + */ public boolean isfunction() { return false; } - public boolean isint() { return false; } // may convert from string - public boolean isinttype() { return false; } // will not convert string + + /** Check if {@code this} is a {@code number} and is representable by java int + * without rounding or truncation + * @return true if this is a {@code number} + * meaning derives from {@link LuaNumber} + * or derives from {@link LuaString} and is convertible to a number, + * and can be represented by int, + * otherwise false + * @see #isinttype() + * @see #islong() + * @see #tonumber() + * @see #checkint() + * @see #optint(int) + * @see #TNUMBER + */ + public boolean isint() { return false; } + + /** Check if {@code this} is a {@link LuaInteger} + *

+ * No attempt to convert from string will be made by this call. + * @return true if this is a {@code LuaInteger}, + * otherwise false + * @see #isint() + * @see #isnumber() + * @see #tonumber() + * @see #TNUMBER + */ + public boolean isinttype() { return false; } + + /** Check if {@code this} is a {@code number} and is representable by java long + * without rounding or truncation + * @return true if this is a {@code number} + * meaning derives from {@link LuaNumber} + * or derives from {@link LuaString} and is convertible to a number, + * and can be represented by long, + * otherwise false + * @see #tonumber() + * @see #checklong() + * @see #optlong(long) + * @see #TNUMBER + */ public boolean islong() { return false; } + + /** Check if {@code this} is {@code nil} + * @return true if this is {@code nil}, otherwise false + * @see #NIL + * @see #NONE + * @see #checknotnil() + * @see #optvalue(LuaValue) + * @see Varargs#isnoneornil(int) + * @see #TNIL + * @see #TNONE + */ public boolean isnil() { return false; } + + /** Check if {@code this} is a {@code number} + * @return true if this is a {@code number}, + * meaning derives from {@link LuaNumber} + * or derives from {@link LuaString} and is convertible to a number, + * otherwise false + * @see #tonumber() + * @see #checknumber() + * @see #optnumber(LuaNumber) + * @see #TNUMBER + */ public boolean isnumber() { return false; } // may convert from string + + /** Check if {@code this} is a {@code string} + * @return true if this is a {@code string}, + * meaning derives from {@link LuaString} or {@link LuaNumber}, + * otherwise false + * @see #tostring() + * @see #checkstring() + * @see #optstring(LuaString) + * @see #TSTRING + */ public boolean isstring() { return false; } + + /** Check if {@code this} is a {@code thread} + * @return true if this is a {@code thread}, otherwise false + * @see #checkthread() + * @see #optthread(LuaThread) + * @see #TTHREAD + */ public boolean isthread() { return false; } + + /** Check if {@code this} is a {@code table} + * @return true if this is a {@code table}, otherwise false + * @see #checktable() + * @see #opttable(LuaTable) + * @see #TTABLE + */ public boolean istable() { return false; } + + /** Check if {@code this} is a {@code userdata} + * @return true if this is a {@code userdata}, otherwise false + * @see #isuserdata(Class) + * @see #touserdata() + * @see #checkuserdata() + * @see #optuserdata(Object) + * @see #TUSERDATA + */ public boolean isuserdata() { return false; } + + /** Check if {@code this} is a {@code userdata} of type {@code c} + * @param c Class to test instance against + * @return true if this is a {@code userdata} + * and the instance is assignable to {@code c}, + * otherwise false + * @see #isuserdata() + * @see #touserdata(Class) + * @see #checkuserdata(Class) + * @see #optuserdata(Object,Class) + * @see #TUSERDATA + */ public boolean isuserdata(Class c) { return false; } - // type coercion to java primitives + /** Convert to boolean false if {@link #NIL} or {@link FALSE}, true if anything else + * @return Value cast to byte if number or string convertible to number, otherwise 0 + * @see #optboolean(boolean) + * @see #checkboolean() + * @see #isboolean() + * @see TBOOLEAN + */ public boolean toboolean() { return true; } + + /** Convert to byte if numeric, or 0 if not. + * @return Value cast to byte if number or string convertible to number, otherwise 0 + * @see #toint() + * @see #todouble() + * @see #optbyte(byte) + * @see #checknumber() + * @see #isnumber() + * @see TNUMBER + */ public byte tobyte() { return 0; } + + /** Convert to char if numeric, or 0 if not. + * @return Value cast to char if number or string convertible to number, otherwise 0 + * @see #toint() + * @see #todouble() + * @see #optchar(char) + * @see #checknumber() + * @see #isnumber() + * @see TNUMBER + */ public char tochar() { return 0; } + + /** Convert to double if numeric, or 0 if not. + * @return Value cast to double if number or string convertible to number, otherwise 0 + * @see #toint() + * @see #tobyte() + * @see #tochar() + * @see #toshort() + * @see #tolong() + * @see #tofloat() + * @see #optdouble(double) + * @see #checknumber() + * @see #isnumber() + * @see TNUMBER + */ public double todouble() { return 0; } + + /** Convert to float if numeric, or 0 if not. + * @return Value cast to float if number or string convertible to number, otherwise 0 + * @see #toint() + * @see #todouble() + * @see #optfloat(float) + * @see #checknumber() + * @see #isnumber() + * @see TNUMBER + */ public float tofloat() { return 0; } + + /** Convert to int if numeric, or 0 if not. + * @return Value cast to int if number or string convertible to number, otherwise 0 + * @see #tobyte() + * @see #tochar() + * @see #toshort() + * @see #tolong() + * @see #tofloat() + * @see #todouble() + * @see #optint(int) + * @see #checknumber() + * @see #isnumber() + * @see TNUMBER + */ public int toint() { return 0; } + + /** Convert to long if numeric, or 0 if not. + * @return Value cast to long if number or string convertible to number, otherwise 0 + * @see #isint() + * @see #isinttype() + * @see #toint() + * @see #todouble() + * @see #optlong(long) + * @see #checknumber() + * @see #isnumber() + * @see TNUMBER + */ public long tolong() { return 0; } + + /** Convert to short if numeric, or 0 if not. + * @return Value cast to short if number or string convertible to number, otherwise 0 + * @see #toint() + * @see #todouble() + * @see #optshort(short) + * @see #checknumber() + * @see #isnumber() + * @see TNUMBER + */ public short toshort() { return 0; } + + /** Convert to human readable String for any type. + * @return String for use by human readers based on type. + * @see #tostring() + * @see #optjstring(String) + * @see #checkjstring() + * @see #isstring() + * @see TSTRING + */ public String tojstring() { return typename() + ": " + Integer.toHexString(hashCode()); } + + /** Convert to userdata instance, or null. + * @return userdata instance if userdata, or null if not {@link LuaUserdata} + * @see #optuserdata(Object) + * @see #checkuserdata() + * @see #isuserdata() + * @see #TUSERDATA + */ public Object touserdata() { return null; } + + /** Convert to userdata instance if specific type, or null. + * @return userdata instance if is a userdata whose instance derives from {@code c}, + * or null if not {@link LuaUserdata} + * @see #optuserdata(Class,Object) + * @see #checkuserdata(Class) + * @see #isuserdata(Class) + * @see #TUSERDATA + */ public Object touserdata(Class c) { return null; } - // Object.toString() maps to tojstring() + /** + * Convert the value to a human readable string using {@link #tojstring()} + * @return String value intended to be human readible. + * @see #tostring() + * @see #tojstring() + * @see #optstring(LuaString) + * @see #checkstring() + * @see #toString() + */ public String toString() { return tojstring(); } - // type coercion to lua values - /** @return NIL if not a number or convertible to a number */ + /** Conditionally convert to lua number without throwing errors. + *

+ * In lua all numbers are strings, but not all strings are numbers. + * This function will return + * the {@link LuaValue} {@code this} if it is a number + * or a string convertible to a number, + * and {@link NIL} for all other cases. + *

+ * This allows values to be tested for their "numeric-ness" without + * the penalty of throwing exceptions, + * nor the cost of converting the type and creating storage for it. + * @return {@code this} if it is a {@link LuaNumber} + * or {@link LuaString} that can be converted to a number, + * otherwise {@link #NIL} + * @see #tostring() + * @see #optnumber(LuaNumber) + * @see #checknumber() + * @see #toint() + * @see #todouble() + */ public LuaValue tonumber() { return NIL; } - /** @return NIL if not a string or number */ + /** Conditionally convert to lua string without throwing errors. + *

+ * In lua all numbers are strings, so this function will return + * the {@link LuaValue} {@code this} if it is a string or number, + * and {@link NIL} for all other cases. + *

+ * This allows values to be tested for their "string-ness" without + * the penalty of throwing exceptions. + * @return {@code this} if it is a {@link LuaString} or {@link LuaNumber}, + * otherwise {@link NIL} + * @see #tonumber() + * @see #tojstring() + * @see #optstring(LuaString) + * @see #checkstring() + * @see #toString() + */ public LuaValue tostring() { return NIL; } - // optional argument conversions + /** Check that optional argument is a boolean and return its boolean value + * @param defval boolean value to return if {@code this} is nil or none + * @return {@code this} cast to boolean if a {@LuaBoolean}, + * {@code defval} if nil or none, + * throws {@link LuaError} otherwise + * @throws LuaError if was not a boolean or nil or none. + * @see #checkboolean() + * @see #isboolean() + * @see #TBOOLEAN + */ public boolean optboolean(boolean defval) { argerror("boolean"); return false; } + + /** Check that optional argument is a closure and return as {@link LuaClosure} + *

+ * A {@link LuaClosure} is a {@LuaFunction} that executes lua byteccode. + * @param defval {@link LuaClosure} to return if {@code this} is nil or none + * @return {@code this} cast to {@link LuaClosure} if a function, + * {@code defval} if nil or none, + * throws {@link LuaError} otherwise + * @throws LuaError if was not a closure or nil or none. + * @see #checkclosure() + * @see #isclosure() + * @see #TFUNCTION + */ public LuaClosure optclosure(LuaClosure defval) { argerror("closure"); return null; } + + /** Check that optional argument is a number or string convertible to number and return as double + * @param defval double to return if {@code this} is nil or none + * @return {@code this} cast to double if numeric, + * {@code defval} if nil or none, + * throws {@link LuaError} otherwise + * @throws LuaError if was not numeric or nil or none. + * @see #optint(int) + * @see #optinteger(LuaInteger) + * @see #checkdouble() + * @see #todouble() + * @see #tonumber() + * @see #isnumber() + * @see #TNUMBER + */ public double optdouble(double defval) { argerror("double"); return 0; } + + /** Check that optional argument is a function and return as {@link LuaFunction} + *

+ * A {@link LuaFunction} may either be a Java function that implements + * functionality directly in Java, + * or a {@link LuaClosure} + * which is a {@link LuaFunction} that executes lua bytecode. + * @param defval {@link LuaFunction} to return if {@code this} is nil or none + * @return {@code this} cast to {@link LuaFunction} if a function, + * {@code defval} if nil or none, + * throws {@link LuaError} otherwise + * @throws LuaError if was not a function or nil or none. + * @see #checkfunction() + * @see #isfunction() + * @see #TFUNCTION + */ public LuaFunction optfunction(LuaFunction defval) { argerror("function"); return null; } + + /** Check that optional argument is a number or string convertible to number and return as int + * @param defval int to return if {@code this} is nil or none + * @return {@code this} cast to int if numeric, + * {@code defval} if nil or none, + * throws {@link LuaError} otherwise + * @throws LuaError if was not numeric or nil or none. + * @see #optdouble(double) + * @see #optlong(long) + * @see #optinteger(LuaInteger) + * @see #checkint() + * @see #toint() + * @see #tonumber() + * @see #isnumber() + * @see #TNUMBER + */ public int optint(int defval) { argerror("int"); return 0; } + + /** Check that optional argument is a number or string convertible to number and return as {@link LuaInteger} + * @param defval {@link LuaInteger} to return if {@code this} is nil or none + * @return {@code this} converted and wrapped in {@link LuaInteger} if numeric, + * {@code defval} if nil or none, + * throws {@link LuaError} otherwise + * @throws LuaError if was not numeric or nil or none. + * @see #optdouble(double) + * @see #optint(int) + * @see #checkint() + * @see #toint() + * @see #tonumber() + * @see #isnumber() + * @see #TNUMBER + */ public LuaInteger optinteger(LuaInteger defval) { argerror("integer"); return null; } + + /** Check that optional argument is a number or string convertible to number and return as long + * @param defval long to return if {@code this} is nil or none + * @return {@code this} cast to long if numeric, + * {@code defval} if nil or none, + * throws {@link LuaError} otherwise + * @throws LuaError if was not numeric or nil or none. + * @see #optdouble(double) + * @see #optint(int) + * @see #checkint() + * @see #toint() + * @see #tonumber() + * @see #isnumber() + * @see #TNUMBER + */ public long optlong(long defval) { argerror("long"); return 0; } + + /** Check that optional argument is a number or string convertible to number and return as {@link LuaNumber} + * @param defval {@link LuaNumber} to return if {@code this} is nil or none + * @return {@code this} cast to {@link LuaNumber} if numeric, + * {@code defval} if nil or none, + * throws {@link LuaError} otherwise + * @throws LuaError if was not numeric or nil or none. + * @see #optdouble(double) + * @see #optlong(long) + * @see #optint(int) + * @see #checkint() + * @see #toint() + * @see #tonumber() + * @see #isnumber() + * @see #TNUMBER + */ public LuaNumber optnumber(LuaNumber defval) { argerror("number"); return null; } + + /** Check that optional argument is a string or number and return as Java String + * @param defval {@link LuaString} to return if {@code this} is nil or none + * @return {@code this} converted to String if a string or number, + * {@code defval} if nil or none, + * throws {@link LuaError} if some other type + * @throws LuaError if was not a string or number or nil or none. + * @see #tojstring() + * @see #optstring(LuaString) + * @see #checkjstring() + * @see #toString() + * @see #TSTRING + */ public String optjstring(String defval) { argerror("String"); return null; } + + /** Check that optional argument is a string or number and return as {@link LuaString} + * @param defval {@link LuaString} to return if {@code this} is nil or none + * @return {@code this} converted to {@link LuaString} if a string or number, + * {@code defval} if nil or none, + * throws {@link LuaError} if some other type + * @throws LuaError if was not a string or number or nil or none. + * @see #tojstring() + * @see #optjstring(String) + * @see #checkstring() + * @see #toString() + * @see #TSTRING + */ public LuaString optstring(LuaString defval) { argerror("string"); return null; } + + /** Check that optional argument is a table and return as {@link LuaTable} + * @param defval {@link LuaTable} to return if {@code this} is nil or none + * @return {@code this} cast to {@link LuaTable} if a table, + * {@code defval} if nil or none, + * throws {@link LuaError} if some other type + * @throws LuaError if was not a table or nil or none. + * @see #checktable() + * @see #istable() + * @see #TTABLE + */ public LuaTable opttable(LuaTable defval) { argerror("table"); return null; } + + /** Check that optional argument is a thread and return as {@link LuaThread} + * @param defval {@link LuaThread} to return if {@code this} is nil or none + * @return {@code this} cast to {@link LuaTable} if a thread, + * {@code defval} if nil or none, + * throws {@link LuaError} if some other type + * @throws LuaError if was not a thread or nil or none. + * @see #checkthread() + * @see #isthread() + * @see #TTHREAD + */ public LuaThread optthread(LuaThread defval) { argerror("thread"); return null; } + + /** Check that optional argument is a userdata and return the Object instance + * @param defval Object to return if {@code this} is nil or none + * @return Object instance of the userdata if a {@link LuaUserdata}, + * {@code defval} if nil or none, + * throws {@link LuaError} if some other type + * @throws LuaError if was not a userdata or nil or none. + * @see #checkuserdata() + * @see #isuserdata() + * @see #optuserdata(Class, Object) + * @see #TUSERDATA + */ public Object optuserdata(Object defval) { argerror("object"); return null; } + + /** Check that optional argument is a userdata whose instance is of a type + * and return the Object instance + * @param c Class to test userdata instance against + * @param defval Object to return if {@code this} is nil or none + * @return Object instance of the userdata if a {@link LuaUserdata} and instance is assignable to {@code c}, + * {@code defval} if nil or none, + * throws {@link LuaError} if some other type + * @throws LuaError if was not a userdata whose instance is assignable to {@code c} or nil or none. + * @see #checkuserdata(Class) + * @see #isuserdata(Class) + * @see #optuserdata(Object) + * @see #TUSERDATA + */ public Object optuserdata(Class c, Object defval) { argerror(c.getName()); return null; } + + /** Perform argument check that this is not nil or none. + * @param defval {@link LuaValue} to return if {@code this} is nil or none + * @return {@code this} if not nil or none, else {@code defval} + * @see #NIL + * @see #NONE + * @see #isnil() + * @see Varargs#isnoneornil(int) + * @see #TNIL + * @see #TNONE + */ public LuaValue optvalue(LuaValue defval) { return this; } - // argument type checks + + /** Check that the value is a {@link LuaBoolean}, + * or throw {@link LuaError} if not + * @return boolean value for {@code this} if it is a {@link LuaBoolean} + * @throws LuaError if not a {@link LuaBoolean} + * @see #optboolean(boolean) + * @see #TBOOLEAN + */ public boolean checkboolean() { argerror("boolean"); return false; } + + /** Check that the value is a {@link LuaClosure} , + * or throw {@link LuaError} if not + *

+ * {@link LuaClosure} is a subclass of {@LuaFunction} that interprets lua bytecode. + * @return {@code this} cast as {@link LuaClosure} + * @throws LuaError if not a {@link LuaClosure} + * @see #checkfunction() + * @see #optclosure(LuaClosure) + * @see #isclosure() + * @see #TFUNCTION + */ public LuaClosure checkclosure() { argerror("closure"); return null; } + + /** Check that the value is numeric and return the value as a double, + * or throw {@link LuaError} if not numeric + *

+ * Values that are {@link LuaNumber} and values that are {@link LuaString} + * that can be converted to a number will be converted to double. + * @return value cast to a double if numeric + * @throws LuaError if not a {@link LuaNumber} or is a {@link LuaString} that can't be converted to number + * @see #checkint() + * @see #checkinteger() + * @see #checklong() + * @see #optdouble(double) + * @see #TNUMBER + */ public double checkdouble() { argerror("double"); return 0; } + + /** Check that the value is a function , or throw {@link LuaError} if not + *

+ * A function is considered anything whose {@link type()} returns {@link TFUNCTION}. + * In practice it will be either a built-in Java function, typically deriving from + * {@link LuaFunction} or a {@link LuaClosure} which represents lua source compiled + * into lua bytecode. + * @return {@code this} if if a lua function or closure + * @throws LuaError if not a function + * @see #checkclosure() + */ public LuaValue checkfunction() { argerror("function"); return null; } + + /** Check that the value is numeric, and convert and cast value to int, or throw {@link LuaError} if not numeric + *

+ * Values that are {@link LuaNumber} will be cast to int and may lose precision. + * Values that are {@link LuaString} that can be converted to a number will be converted, + * then cast to int, so may also lose precision. + * @return value cast to a int if numeric + * @throws LuaError if not a {@link LuaNumber} or is a {@link LuaString} that can't be converted to number + * @see #checkinteger() + * @see #checklong() + * @see #checkdouble() + * @see #optint(int) + * @see #TNUMBER + */ public int checkint() { argerror("int"); return 0; } + + /** Check that the value is numeric, and convert and cast value to int, or throw {@link LuaError} if not numeric + *

+ * Values that are {@link LuaNumber} will be cast to int and may lose precision. + * Values that are {@link LuaString} that can be converted to a number will be converted, + * then cast to int, so may also lose precision. + * @return value cast to a int and wrapped in {@link LuaInteger} if numeric + * @throws LuaError if not a {@link LuaNumber} or is a {@link LuaString} that can't be converted to number + * @see #checkint() + * @see #checklong() + * @see #checkdouble() + * @see #optinteger(LuaInteger) + * @see #TNUMBER + */ public LuaInteger checkinteger() { argerror("integer"); return null; } + + /** Check that the value is numeric, and convert and cast value to long, or throw {@link LuaError} if not numeric + *

+ * Values that are {@link LuaNumber} will be cast to long and may lose precision. + * Values that are {@link LuaString} that can be converted to a number will be converted, + * then cast to long, so may also lose precision. + * @return value cast to a long if numeric + * @throws LuaError if not a {@link LuaNumber} or is a {@link LuaString} that can't be converted to number + * @see #checkint() + * @see #checkinteger() + * @see #checkdouble() + * @see #optlong(long) + * @see #TNUMBER + */ public long checklong() { argerror("long"); return 0; } + + /** Check that the value is numeric, and return as a LuaNumber if so, or throw {@link LuaError} + *

+ * Values that are {@link LuaString} that can be converted to a number will be converted and returned. + * @return value as a {@link LuaNumber} if numeric + * @throws LuaError if not a {@link LuaNumber} or is a {@link LuaString} that can't be converted to number + * @see #checkint() + * @see #checkinteger() + * @see #checkdouble() + * @see #checklong() + * @see #optnumber(LuaNumber) + * @see #TNUMBER + */ public LuaNumber checknumber() { argerror("number"); return null; } + + /** Check that the value is numeric, and return as a LuaNumber if so, or throw {@link LuaError} + *

+ * Values that are {@link LuaString} that can be converted to a number will be converted and returned. + * @param msg String message to supply if conversion fails + * @return value as a {@link LuaNumber} if numeric + * @throws LuaError if not a {@link LuaNumber} or is a {@link LuaString} that can't be converted to number + * @see #checkint() + * @see #checkinteger() + * @see #checkdouble() + * @see #checklong() + * @see #optnumber(LuaNumber) + * @see #TNUMBER + */ public LuaNumber checknumber(String msg) { throw new LuaError(msg); } + + /** Convert this value to a Java String. + *

+ * The string representations here will roughly match what is produced by the + * C lua distribution, however hash codes have no relationship, + * and there may be differences in number formatting. + * @return String representation of the value + * @see #checkstring() + * @see #optjstring(String) + * @see #tojstring() + * @see #isstring + * @see #TSTRING + */ public String checkjstring() { argerror("string"); return null; } + + /** Check that this is a lua string, or throw {@link LuaError} if it is not. + *

+ * In lua all numbers are strings, so this will succeed for + * anything that derives from {@link LuaString} or {@link LuaNumber}. + * Numbers will be converted to {@link LuaString}. + * + * @return {@link LuaString} representation of the value if it is a {@link LuaString} or {@link LuaNumber} + * @throws LuaError if {@code this} is not a {@link LuaTable} + * @see #checkjstring() + * @see #optstring(LuaString) + * @see #tostring() + * @see #isstring() + * @see #TSTRING + */ public LuaString checkstring() { argerror("string"); return null; } + + /** Check that this is a {@link LuaTable}, or throw {@link LuaError} if it is not + * @return {@code this} if it is a {@link LuaTable} + * @throws LuaError if {@code this} is not a {@link LuaTable} + * @see #istable() + * @see #opttable(LuaTable) + * @see #TTABLE + */ public LuaTable checktable() { argerror("table"); return null; } + + /** Check that this is a {@link LuaThread}, or throw {@link LuaError} if it is not + * @return {@code this} if it is a {@link LuaThread} + * @throws LuaError if {@code this} is not a {@link LuaThread} + * @see #isthread() + * @see #optthread(LuaThread) + * @see #TTHREAD + */ public LuaThread checkthread() { argerror("thread"); return null; } + + /** Check that this is a {@link LuaUserdata}, or throw {@link LuaError} if it is not + * @return {@code this} if it is a {@link LuaUserdata} + * @throws LuaError if {@code this} is not a {@link LuaUserdata} + * @see #isuserdata() + * @see #optuserdata(Object) + * @see #checkuserdata(Class) + * @see #TUSERDATA + */ public Object checkuserdata() { argerror("userdata"); return null; } + + /** Check that this is a {@link LuaUserdata}, or throw {@link LuaError} if it is not + * @return {@code this} if it is a {@link LuaUserdata} + * @throws LuaError if {@code this} is not a {@link LuaUserdata} + * @see #isuserdata(Class) + * @see #optuserdata(Class, Object) + * @see #checkuserdata() + * @see #TUSERDATA + */ public Object checkuserdata(Class c) { argerror("userdata"); return null; } + + /** Check that this is not the value {@link NIL}, or throw {@link LuaError} if it is + * @return {@code this} if it is not {@link NIL} + * @throws LuaError if {@code this} is {@link NIL} + * @see #optvalue(LuaValue) + */ public LuaValue checknotnil() { return this; } + + /** Check that this is a valid key in a table index operation, or throw {@link LuaError} if not + * @return {@code this} if valid as a table key + * @throws LuaError if not valid as a table key + * @see #isnil() + * @see #isinttype() + */ public LuaValue checkvalidkey() { return this; } - // errors + /** + * Throw a {@link LuaError} with a particular message + * @param message String providing message details + * @throws LuaError in all cases + */ public static LuaValue error(String message) { throw new LuaError(message); } + + /** + * Assert a condition is true, or throw a {@link LuaError} if not + * @param b condition to test + * @return returns no value when b is true, throws error not return if b is false + * @throws LuaError if b is not true + */ public static void assert_(boolean b,String msg) { if(!b) throw new LuaError(msg); } + + /** + * Throw a {@link LuaError} indicating an invalid argument was supplied to a function + * @param expected String naming the type that was expected + * @throws LuaError in all cases + */ protected LuaValue argerror(String expected) { throw new LuaError("bad argument: "+expected+" expected, got "+typename()); } + + /** + * Throw a {@link LuaError} indicating an invalid argument was supplied to a function + * @param iarg index of the argument that was invalid, first index is 1 + * @param msg String providing information about the invalid argument + * @throws LuaError in all cases + */ public static LuaValue argerror(int iarg,String msg) { throw new LuaError("bad argument #"+iarg+": "+msg); } + + /** + * Throw a {@link LuaError} indicating an invalid type was supplied to a function + * @param expected String naming the type that was expected + * @throws LuaError in all cases + */ protected LuaValue typerror(String expected) { throw new LuaError(expected+" expected, got "+typename()); } + + /** + * Throw a {@link LuaError} indicating an operation is not implemented + * @throws LuaError in all cases + */ protected LuaValue unimplemented(String fun) { throw new LuaError("'"+fun+"' not implemented for "+typename()); } + + /** + * Throw a {@link LuaError} indicating an illegal operation occurred, + * typically involved in managing weak references + * @throws LuaError in all cases + */ protected LuaValue illegal(String op,String typename) { throw new LuaError("illegal operation '"+op+"' for "+typename); } + + /** + * Throw a {@link LuaError} based on the len operator, + * typically due to an invalid operand type + * @throws LuaError in all cases + */ protected LuaValue lenerror() { throw new LuaError("attempt to get length of "+typename()); } + + /** + * Throw a {@link LuaError} based on an arithmetic error such as add, or pow, + * typically due to an invalid operand type + * @throws LuaError in all cases + */ protected LuaValue aritherror() { throw new LuaError("attempt to perform arithmetic on "+typename()); } + + /** + * Throw a {@link LuaError} based on an arithmetic error such as add, or pow, + * typically due to an invalid operand type + * @param fun String description of the function that was attempted + * @throws LuaError in all cases + */ protected LuaValue aritherror(String fun) { throw new LuaError("attempt to perform arithmetic '"+fun+"' on "+typename()); } + + /** + * Throw a {@link LuaError} based on a comparison error such as greater-than or less-than, + * typically due to an invalid operand type + * @param rhs String description of what was on the right-hand-side of the comparison that resulted in the error. + * @throws LuaError in all cases + */ protected LuaValue compareerror(String rhs) { throw new LuaError("attempt to compare "+typename()+" with "+rhs); } + + /** + * Throw a {@link LuaError} based on a comparison error such as greater-than or less-than, + * typically due to an invalid operand type + * @param rhs Right-hand-side of the comparison that resulted in the error. + * @throws LuaError in all cases + */ protected LuaValue compareerror(LuaValue rhs) { throw new LuaError("attempt to compare "+typename()+" with "+rhs.typename()); } - // table operations + /** Get a value in a table including metatag processing using {@link INDEX}. + * @param key the key to look up, must not be {@link NIL} or null + * @return {@link LuaValue} for that key, or {@link NIL} if not found and no metatag + * @throws LuaError if {@code this} is not a table, + * or there is no {@link INDEX} metatag, + * or key is {@link NIL} + * @see #get(int) + * @see #get(String) + * @see #rawget(LuaValue) + */ public LuaValue get( LuaValue key ) { return gettable(this,key); } + + /** Get a value in a table including metatag processing using {@link INDEX}. + * @param key the key to look up + * @return {@link LuaValue} for that key, or {@link NIL} if not found + * @throws LuaError if {@code this} is not a table, + * or there is no {@link INDEX} metatag + * @see #get(LuaValue) + * @see #rawget(int) + */ public LuaValue get( int key ) { return get(LuaInteger.valueOf(key)); } + + /** Get a value in a table including metatag processing using {@link INDEX}. + * @param key the key to look up, must not be null + * @return {@link LuaValue} for that key, or {@link NIL} if not found + * @throws LuaError if {@code this} is not a table, + * or there is no {@link INDEX} metatag + * @see #get(LuaValue) + * @see #rawget(String) + */ public LuaValue get( String key ) { return get(valueOf(key)); } + + /** Set a value in a table without metatag processing using {@link NEWINDEX}. + * @param key the key to use, must not be {@link NIL} or null + * @param value the value to use, can be {@link NIL}, must not be null + * @throws LuaError if {@code this} is not a table, + * or key is {@link NIL}, + * or there is no {@link NEWINDEX} metatag + */ public void set( LuaValue key, LuaValue value ) { settable(this, key, value); } + + /** Set a value in a table without metatag processing using {@link NEWINDEX}. + * @param key the key to use + * @param value the value to use, can be {@link NIL}, must not be null + * @throws LuaError if {@code this} is not a table, + * or there is no {@link NEWINDEX} metatag + */ public void set( int key, LuaValue value ) { set(LuaInteger.valueOf(key), value ); } + + /** Set a value in a table without metatag processing using {@link NEWINDEX}. + * @param key the key to use + * @param value the value to use, must not be null + * @throws LuaError if {@code this} is not a table, + * or there is no {@link NEWINDEX} metatag + */ public void set( int key, String value ) { set(key, valueOf(value) ); } + + /** Set a value in a table without metatag processing using {@link NEWINDEX}. + * @param key the key to use, must not be {@link NIL} or null + * @param value the value to use, can be {@link NIL}, must not be null + * @throws LuaError if {@code this} is not a table, + * or there is no {@link NEWINDEX} metatag + */ public void set( String key, LuaValue value ) { set(valueOf(key), value ); } + + /** Set a value in a table without metatag processing using {@link NEWINDEX}. + * @param key the key to use, must not be null + * @param value the value to use + * @throws LuaError if {@code this} is not a table, + * or there is no {@link NEWINDEX} metatag + */ public void set( String key, double value ) { set(valueOf(key), valueOf(value) ); } + + /** Set a value in a table without metatag processing using {@link NEWINDEX}. + * @param key the key to use, must not be null + * @param value the value to use + * @throws LuaError if {@code this} is not a table, + * or there is no {@link NEWINDEX} metatag + */ public void set( String key, int value ) { set(valueOf(key), valueOf(value) ); } + + /** Set a value in a table without metatag processing using {@link NEWINDEX}. + * @param key the key to use, must not be null + * @param value the value to use, must not be null + * @throws LuaError if {@code this} is not a table, + * or there is no {@link NEWINDEX} metatag + */ public void set( String key, String value ) { set(valueOf(key), valueOf(value) ); } + + /** Get a value in a table without metatag processing. + * @param key the key to look up, must not be {@link NIL} or null + * @return {@link LuaValue} for that key, or {@link NIL} if not found + * @throws LuaError if {@code this} is not a table, or key is {@link NIL} + */ public LuaValue rawget( LuaValue key ) { return unimplemented("rawget"); } + + /** Get a value in a table without metatag processing. + * @param key the key to look up + * @return {@link LuaValue} for that key, or {@link NIL} if not found + * @throws LuaError if {@code this} is not a table + */ public LuaValue rawget( int key ) { return rawget(valueOf(key)); } + + /** Get a value in a table without metatag processing. + * @param key the key to look up, must not be null + * @return {@link LuaValue} for that key, or {@link NIL} if not found + * @throws LuaError if {@code this} is not a table + */ public LuaValue rawget( String key ) { return rawget(valueOf(key)); } + + /** Set a value in a table without metatag processing. + * @param key the key to use, must not be {@link NIL} or null + * @param value the value to use, can be {@link NIL}, must not be null + * @throws LuaError if {@code this} is not a table, or key is {@link NIL} + */ public void rawset( LuaValue key, LuaValue value ) { unimplemented("rawset"); } + + /** Set a value in a table without metatag processing. + * @param key the key to use + * @param value the value to use, can be {@link NIL}, must not be null + * @throws LuaError if {@code this} is not a table + */ public void rawset( int key, LuaValue value ) { rawset(valueOf(key),value); } + + /** Set a value in a table without metatag processing. + * @param key the key to use + * @param value the value to use, can be {@link NIL}, must not be null + * @throws LuaError if {@code this} is not a table + */ public void rawset( int key, String value ) { rawset(key,valueOf(value)); } + + /** Set a value in a table without metatag processing. + * @param key the key to use, must not be null + * @param value the value to use, can be {@link NIL}, must not be null + * @throws LuaError if {@code this} is not a table + */ public void rawset( String key, LuaValue value ) { rawset(valueOf(key),value); } + + /** Set a value in a table without metatag processing. + * @param key the key to use, must not be null + * @param value the value to use + * @throws LuaError if {@code this} is not a table + */ public void rawset( String key, double value ) { rawset(valueOf(key),valueOf(value)); } + + /** Set a value in a table without metatag processing. + * @param key the key to use, must not be null + * @param value the value to use + * @throws LuaError if {@code this} is not a table + */ public void rawset( String key, int value ) { rawset(valueOf(key),valueOf(value)); } + + /** Set a value in a table without metatag processing. + * @param key the key to use, must not be null + * @param value the value to use, must not be null + * @throws LuaError if {@code this} is not a table + */ public void rawset( String key, String value ) { rawset(valueOf(key),valueOf(value)); } + + /** Set list values in a table without invoking metatag processing + *

+ * Primarily used internally in response to a SETLIST bytecode. + * @param key0 the first key to set in the table + * @param values the list of values to set + * @throws LuaError if this is not a table. + */ public void rawsetlist( int key0, Varargs values ) { for ( int i=0, n=values.narg(); i + * Primarily used internally in response to a SETLIST bytecode. + * @param i the number of array slots to preallocate in the table. + * @throws LuaError if this is not a table. + */ public void presize( int i) { typerror("table"); } + + /** Find the next key,value pair if {@code this} is a table, + * return {@link NIL} if there are no more, or throw a {@link LuaError} if not a table. + *

+ * To iterate over all key-value pairs in a table you can use + *

 {@code
+	 * LuaValue k = LuaValue.NIL;
+	 * while ( true ) {
+	 *    Varargs n = table.next(k);
+	 *    if ( (k = n.arg1()).isnil() )
+	 *       break;
+	 *    LuaValue v = n.arg(2)
+	 *    process( k, v )
+	 * }
+ * @param index {@link LuaInteger} value identifying a key to start from, + * or {@link NIL} to start at the beginning + * @return {@link Varargs} containing {key,value} for the next entry, + * or {@link NIL} if there are no more. + * @throws LuaError if {@code this} is not a table, or the supplied key is invalid. + * @see LuaTable + * @see #inext() + * @see #valueOf(int) + * @see Varargs#arg1() + * @see Varargs#arg(int) + * @see #isnil() + */ public Varargs next(LuaValue index) { return typerror("table"); } + + /** Find the next integer-key,value pair if {@code this} is a table, + * return {@link NIL} if there are no more, or throw a {@link LuaError} if not a table. + *

+ * To iterate over integer keys in a table you can use + *

 {@code
+	 * LuaValue k = LuaValue.NIL;
+	 * while ( true ) {
+	 *    Varargs n = table.inext(k);
+	 *    if ( (k = n.arg1()).isnil() )
+	 *       break;
+	 *    LuaValue v = n.arg(2)
+	 *    process( k, v )
+	 * }
+ * @param index {@link LuaInteger} value identifying a key to start from, + * or {@link NIL} to start at the beginning + * @return {@link Varargs} containing {key,value} for the next entry, + * or {@link NONE} if there are no more. + * @throws LuaError if {@code this} is not a table, or the supplied key is invalid. + * @see LuaTable + * @see #next() + * @see #valueOf(int) + * @see Varargs#arg1() + * @see Varargs#arg(int) + * @see #isnil() + */ public Varargs inext(LuaValue index) { return typerror("table"); } + + /** + * Load a library instance by setting its environment to {@code this} + * and calling it, which should iniitalize the library instance and + * install itself into this instance. + * @param library The callable {@link LuaValue} to load into {@code this} + * @return {@link LuaValue} containing the result of the initialization call. + */ public LuaValue load(LuaValue library) { library.setfenv(this); return library.call(); } // varargs references @@ -212,93 +1340,1186 @@ public class LuaValue extends Varargs { public int narg() { return 1; }; public LuaValue arg1() { return this; } - // metatable operations + /** + * Get the metatable for this {@link LuaValue} + *

+ * For {@link LuaTable} and {@link LuaUserdata} instances, + * the metatable returned is this instance metatable. + * For all other types, the class metatable value will be returned. + * @return metatable, or null if it there is none + * @see LuaBoolean#s_metatable + * @see LuaNumber#s_metatable + * @see LuaNil#s_metatable + * @see LuaFunction#s_metatable + * @see LuaThread#s_metatable + */ public LuaValue getmetatable() { return null; }; + + /** + * Set the metatable for this {@link LuaValue} + *

+ * For {@link LuaTable} and {@link LuaUserdata} instances, the metatable is per instance. + * For all other types, there is one metatable per type that can be set directly from java + * @param metatable {@link LuaValue} instance to serve as the metatable, or null to reset it. + * @return {@code this} to allow chaining of Java function calls + * @see LuaBoolean#s_metatable + * @see LuaNumber#s_metatable + * @see LuaNil#s_metatable + * @see LuaFunction#s_metatable + * @see LuaThread#s_metatable + */ public LuaValue setmetatable(LuaValue metatable) { return argerror("table"); } + + /** + * Get the environemnt for an instance. + * @return {@link LuaValue} currently set as the instances environent. + */ public LuaValue getfenv() { typerror("function or thread"); return null; } + + /** + * Set the environment on an object. + *

+ * Typically the environment is created once per application via a platform + * helper method such as {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} + * However, any object can serve as an environment if it contains suitable metatag + * values to implement {@link #get(LuaValue)} to provide the environment values. + * @param env {@link LuaValue} (typically a {@link LuaTable}) containing the environment. + * @see org.luaj.vm2.lib.jme.JmePlatform + * @see org.luaj.vm2.lib.jse.JsePlatform + */ public void setfenv(LuaValue env) { typerror("function or thread"); } - // function calls + /** Call {@link this} with 0 arguments, including metatag processing, + * and return only the first return value. + *

+ * If {@code this} is a {@link LuaFunction}, call it, + * and return only its first return value, dropping any others. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * If the return value is a {@link Varargs}, only the 1st value will be returned. + * To get multiple values, use {@link #invoke()} instead. + *

+ * To call {@link this} as a method call, use {@link #method(LuaValue)} instead. + * + * @return First return value {@code (this())}, or {@link NIL} if there were none. + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #call(LuaValue) + * @see #call(LuaValue,LuaValue) + * @see #call(LuaValue, LuaValue, LuaValue) + * @see #invoke() + * @see #method(String) + * @see #method(LuaValue) + */ public LuaValue call() { return callmt().call(this); } + + /** Call {@link this} with 1 argument, including metatag processing, + * and return only the first return value. + *

+ * If {@code this} is a {@link LuaFunction}, call it, + * and return only its first return value, dropping any others. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * If the return value is a {@link Varargs}, only the 1st value will be returned. + * To get multiple values, use {@link #invoke()} instead. + *

+ * To call {@link this} as a method call, use {@link #method(LuaValue)} instead. + * + * @param arg First argument to supply to the called function + * @return First return value {@code (this(arg))}, or {@link NIL} if there were none. + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #call() + * @see #call(LuaValue,LuaValue) + * @see #call(LuaValue, LuaValue, LuaValue) + * @see #invoke(LuaValue) + * @see #method(String,LuaValue) + * @see #method(LuaValue,LuaValue) + */ public LuaValue call(LuaValue arg) { return callmt().call(this,arg); } + + /** Call {@link this} with 2 arguments, including metatag processing, + * and return only the first return value. + *

+ * If {@code this} is a {@link LuaFunction}, call it, + * and return only its first return value, dropping any others. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * If the return value is a {@link Varargs}, only the 1st value will be returned. + * To get multiple values, use {@link #invoke()} instead. + *

+ * To call {@link this} as a method call, use {@link #method(LuaValue)} instead. + * + * @param arg1 First argument to supply to the called function + * @param arg2 Second argument to supply to the called function + * @return First return value {@code (this(arg1,arg2))}, or {@link NIL} if there were none. + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #call() + * @see #call(LuaValue) + * @see #call(LuaValue, LuaValue, LuaValue) + * @see #invoke(LuaValue,LuaValue) + * @see #method(String,LuaValue,LuaValue) + * @see #method(LuaValue,LuaValue,LuaValue) + */ public LuaValue call(LuaValue arg1, LuaValue arg2) { return callmt().call(this,arg1,arg2); } + + /** Call {@link this} with 3 arguments, including metatag processing, + * and return only the first return value. + *

+ * If {@code this} is a {@link LuaFunction}, call it, + * and return only its first return value, dropping any others. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * If the return value is a {@link Varargs}, only the 1st value will be returned. + * To get multiple values, use {@link #invoke()} instead. + *

+ * To call {@link this} as a method call, use {@link #method(LuaValue)} instead. + * + * @param arg1 First argument to supply to the called function + * @param arg2 Second argument to supply to the called function + * @param arg3 Second argument to supply to the called function + * @return First return value {@code (this(arg1,arg2,arg3))}, or {@link NIL} if there were none. + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #call() + * @see #call(LuaValue) + * @see #call(LuaValue, LuaValue) + * @see #invoke(LuaValue,LuaValue, LuaValue) + * @see #invokemethod(String,Varargs) + * @see #invokemethod(LuaValue,Varargs) + */ public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) { return callmt().invoke(new LuaValue[]{this,arg1,arg2,arg3}).arg1(); } + + /** Call named method on {@link this} with 0 arguments, including metatag processing, + * and return only the first return value. + *

+ * Look up {@code this[name]} and if it is a {@link LuaFunction}, + * call it inserting {@link this} as an additional first argument. + * and return only its first return value, dropping any others. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * If the return value is a {@link Varargs}, only the 1st value will be returned. + * To get multiple values, use {@link #invoke()} instead. + *

+ * To call {@link this} as a plain call, use {@link #call()} instead. + * + * @param name Name of the method to look up for invocation + * @return All values returned from {@code this:name()} as a {@link Varargs} instance + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #call() + * @see #invoke() + * @see #method(LuaValue) + * @see #method(String,LuaValue) + * @see #method(String,LuaValue,LuaValue) + */ public LuaValue method(String name) { return this.get(name).call(this); } + + /** Call named method on {@link this} with 0 arguments, including metatag processing, + * and return only the first return value. + *

+ * Look up {@code this[name]} and if it is a {@link LuaFunction}, + * call it inserting {@link this} as an additional first argument, + * and return only its first return value, dropping any others. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * If the return value is a {@link Varargs}, only the 1st value will be returned. + * To get multiple values, use {@link #invoke()} instead. + *

+ * To call {@link this} as a plain call, use {@link #call()} instead. + * + * @param name Name of the method to look up for invocation + * @return All values returned from {@code this:name()} as a {@link Varargs} instance + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #call() + * @see #invoke() + * @see #method(String) + * @see #method(LuaValue,LuaValue) + * @see #method(LuaValue,LuaValue,LuaValue) + */ public LuaValue method(LuaValue name) { return this.get(name).call(this); } + + /** Call named method on {@link this} with 1 argument, including metatag processing, + * and return only the first return value. + *

+ * Look up {@code this[name]} and if it is a {@link LuaFunction}, + * call it inserting {@link this} as an additional first argument, + * and return only its first return value, dropping any others. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * If the return value is a {@link Varargs}, only the 1st value will be returned. + * To get multiple values, use {@link #invoke()} instead. + *

+ * To call {@link this} as a plain call, use {@link #call(LuaValue)} instead. + * + * @param name Name of the method to look up for invocation + * @param arg Argument to supply to the method + * @return All values returned from {@code this:name(arg)} as a {@link Varargs} instance + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #call(LuaValue) + * @see #invoke(LuaValue) + * @see #method(LuaValue,LuaValue) + * @see #method(String) + * @see #method(String,LuaValue,LuaValue) + */ public LuaValue method(String name, LuaValue arg) { return this.get(name).call(this,arg); } + + /** Call named method on {@link this} with 1 argument, including metatag processing, + * and return only the first return value. + *

+ * Look up {@code this[name]} and if it is a {@link LuaFunction}, + * call it inserting {@link this} as an additional first argument, + * and return only its first return value, dropping any others. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * If the return value is a {@link Varargs}, only the 1st value will be returned. + * To get multiple values, use {@link #invoke()} instead. + *

+ * To call {@link this} as a plain call, use {@link #call(LuaValue)} instead. + * + * @param name Name of the method to look up for invocation + * @param arg Argument to supply to the method + * @return All values returned from {@code this:name(arg)} as a {@link Varargs} instance + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #call(LuaValue) + * @see #invoke(LuaValue) + * @see #method(String,LuaValue) + * @see #method(LuaValue) + * @see #method(LuaValue,LuaValue,LuaValue) + */ public LuaValue method(LuaValue name, LuaValue arg) { return this.get(name).call(this,arg); } + + /** Call named method on {@link this} with 2 arguments, including metatag processing, + * and return only the first return value. + *

+ * Look up {@code this[name]} and if it is a {@link LuaFunction}, + * call it inserting {@link this} as an additional first argument, + * and return only its first return value, dropping any others. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * If the return value is a {@link Varargs}, only the 1st value will be returned. + * To get multiple values, use {@link #invoke()} instead. + *

+ * To call {@link this} as a plain call, use {@link #call(LuaValue,LuaValue)} instead. + * + * @param name Name of the method to look up for invocation + * @param arg1 First argument to supply to the method + * @param arg2 Second argument to supply to the method + * @return All values returned from {@code this:name(arg1,arg2)} as a {@link Varargs} instance + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #call(LuaValue,LuaValue) + * @see #invoke(LuaValue,Varargs) + * @see #method(String,LuaValue) + * @see #method(LuaValue,LuaValue,LuaValue) + */ public LuaValue method(String name, LuaValue arg1, LuaValue arg2) { return this.get(name).call(this,arg1,arg2); } + + /** Call named method on {@link this} with 2 arguments, including metatag processing, + * and return only the first return value. + *

+ * Look up {@code this[name]} and if it is a {@link LuaFunction}, + * call it inserting {@link this} as an additional first argument, + * and return only its first return value, dropping any others. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * If the return value is a {@link Varargs}, only the 1st value will be returned. + * To get multiple values, use {@link #invoke()} instead. + *

+ * To call {@link this} as a plain call, use {@link #call(LuaValue,LuaValue)} instead. + * + * @param name Name of the method to look up for invocation + * @param arg1 First argument to supply to the method + * @param arg2 Second argument to supply to the method + * @return All values returned from {@code this:name(arg1,arg2)} as a {@link Varargs} instance + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #call(LuaValue,LuaValue) + * @see #invoke(LuaValue,Varargs) + * @see #method(LuaValue,LuaValue) + * @see #method(String,LuaValue,LuaValue) + */ public LuaValue method(LuaValue name, LuaValue arg1, LuaValue arg2) { return this.get(name).call(this,arg1,arg2); } + + /** Call {@link this} with 0 arguments, including metatag processing, + * and retain all return values in a {@link Varargs}. + *

+ * If {@code this} is a {@link LuaFunction}, call it, and return all values. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * To get a particular return value, us {@link Varargs#arg(int)} + *

+ * To call {@link this} as a method call, use {@link #invokemethod(LuaValue)} instead. + * + * @return All return values as a {@link Varargs} instance. + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #call() + * @see #invoke(Varargs) + * @see #invokemethod(String) + * @see #invokemethod(LuaValue) + */ public Varargs invoke() { return invoke(NONE); } + + /** Call {@link this} with variable arguments, including metatag processing, + * and retain all return values in a {@link Varargs}. + *

+ * If {@code this} is a {@link LuaFunction}, call it, and return all values. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * To get a particular return value, us {@link Varargs#arg(int)} + *

+ * To call {@link this} as a method call, use {@link #invokemethod(LuaValue)} instead. + * + * @param args Varargs containing the arguments to supply to the called function + * @return All return values as a {@link Varargs} instance. + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #varargsOf(LuaValue[]) + * @see #call(LuaValue) + * @see #invoke() + * @see #invoke(LuaValue,Varargs) + * @see #invokemethod(String,Varargs) + * @see #invokemethod(LuaValue,Varargs) + */ public Varargs invoke(Varargs args) { return callmt().invoke(this,args); } + + /** Call {@link this} with variable arguments, including metatag processing, + * and retain all return values in a {@link Varargs}. + *

+ * If {@code this} is a {@link LuaFunction}, call it, and return all values. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * To get a particular return value, us {@link Varargs#arg(int)} + *

+ * To call {@link this} as a method call, use {@link #invokemethod(LuaValue,Varargs)} instead. + * + * @param arg The first argument to supply to the called function + * @param varargs Varargs containing the remaining arguments to supply to the called function + * @return All return values as a {@link Varargs} instance. + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #varargsOf(LuaValue[]) + * @see #call(LuaValue,LuaValue) + * @see #invoke(LuaValue,Varargs) + * @see #invokemethod(String,Varargs) + * @see #invokemethod(LuaValue,Varargs) + */ public Varargs invoke(LuaValue arg,Varargs varargs) { return invoke(varargsOf(arg,varargs)); } + + /** Call {@link this} with variable arguments, including metatag processing, + * and retain all return values in a {@link Varargs}. + *

+ * If {@code this} is a {@link LuaFunction}, call it, and return all values. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * To get a particular return value, us {@link Varargs#arg(int)} + *

+ * To call {@link this} as a method call, use {@link #invokemethod(LuaValue,Varargs)} instead. + * + * @param arg1 The first argument to supply to the called function + * @param arg2 The second argument to supply to the called function + * @param varargs Varargs containing the remaining arguments to supply to the called function + * @return All return values as a {@link Varargs} instance. + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #varargsOf(LuaValue[]) + * @see #call(LuaValue,LuaValue,LuaValue) + * @see #invoke(LuaValue,LuaValue,Varargs) + * @see #invokemethod(String,Varargs) + * @see #invokemethod(LuaValue,Varargs) + */ public Varargs invoke(LuaValue arg1,LuaValue arg2,Varargs varargs) { return invoke(varargsOf(arg1,arg2,varargs)); } + + /** Call {@link this} with variable arguments, including metatag processing, + * and retain all return values in a {@link Varargs}. + *

+ * If {@code this} is a {@link LuaFunction}, call it, and return all values. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * To get a particular return value, us {@link Varargs#arg(int)} + *

+ * To call {@link this} as a method call, use {@link #invokemethod(LuaValue,Varargs)} instead. + * + * @param args Array of arguments to supply to the called function + * @return All return values as a {@link Varargs} instance. + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #varargsOf(LuaValue[]) + * @see #call(LuaValue,LuaValue,LuaValue) + * @see #invoke(LuaValue,LuaValue,Varargs) + * @see #invokemethod(String,LuaValue[]) + * @see #invokemethod(LuaValue,LuaValue[]) + */ public Varargs invoke(LuaValue[] args) { return invoke(varargsOf(args)); } + + /** Call {@link this} with variable arguments, including metatag processing, + * and retain all return values in a {@link Varargs}. + *

+ * If {@code this} is a {@link LuaFunction}, call it, and return all values. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * To get a particular return value, us {@link Varargs#arg(int)} + *

+ * To call {@link this} as a method call, use {@link #invokemethod(LuaValue,Varargs)} instead. + * + * @param args Array of arguments to supply to the called function + * @param varargs Varargs containing additional arguments to supply to the called function + * @return All return values as a {@link Varargs} instance. + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #varargsOf(LuaValue[]) + * @see #call(LuaValue,LuaValue,LuaValue) + * @see #invoke(LuaValue,LuaValue,Varargs) + * @see #invokemethod(String,LuaValue[]) + * @see #invokemethod(LuaValue,LuaValue[]) + * @see #invokemethod(String,Varargs) + * @see #invokemethod(LuaValue,Varargs) + */ public Varargs invoke(LuaValue[] args,Varargs varargs) { return invoke(varargsOf(args,varargs)); } + + /** Call named method on {@link this} with 0 arguments, including metatag processing, + * and retain all return values in a {@link Varargs}. + *

+ * Look up {@code this[name]} and if it is a {@link LuaFunction}, + * call it inserting {@link this} as an additional first argument, + * and return all return values as a {@link Varargs} instance. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * To get a particular return value, us {@link Varargs#arg(int)} + *

+ * To call {@link this} as a plain call, use {@link #invoke()} instead. + * + * @param name Name of the method to look up for invocation + * @return All values returned from {@code this:name()} as a {@link Varargs} instance + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #call() + * @see #invoke() + * @see #method(String) + * @see #invokemethod(LuaValue) + * @see #invokemethod(String,LuaValue) + */ public Varargs invokemethod(String name) { return get(name).invoke(this); } + + /** Call named method on {@link this} with 0 arguments, including metatag processing, + * and retain all return values in a {@link Varargs}. + *

+ * Look up {@code this[name]} and if it is a {@link LuaFunction}, + * call it inserting {@link this} as an additional first argument, + * and return all return values as a {@link Varargs} instance. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * To get a particular return value, us {@link Varargs#arg(int)} + *

+ * To call {@link this} as a plain call, use {@link #invoke()} instead. + * + * @param name Name of the method to look up for invocation + * @return All values returned from {@code this:name()} as a {@link Varargs} instance + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #call() + * @see #invoke() + * @see #method(LuaValue) + * @see #invokemethod(String) + * @see #invokemethod(LuaValue,LuaValue) + */ public Varargs invokemethod(LuaValue name) { return get(name).invoke(this); } + + /** Call named method on {@link this} with 1 argument, including metatag processing, + * and retain all return values in a {@link Varargs}. + *

+ * Look up {@code this[name]} and if it is a {@link LuaFunction}, + * call it inserting {@link this} as an additional first argument, + * and return all return values as a {@link Varargs} instance. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * To get a particular return value, us {@link Varargs#arg(int)} + *

+ * To call {@link this} as a plain call, use {@link #invoke(Varargs)} instead. + * + * @param name Name of the method to look up for invocation + * @param args {@link Varargs} containing arguments to supply to the called function after {@code this} + * @return All values returned from {@code this:name(args)} as a {@link Varargs} instance + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #call() + * @see #invoke(Varargs) + * @see #method(String) + * @see #invokemethod(LuaValue,Varargs) + * @see #invokemethod(String,LuaValue[]) + */ public Varargs invokemethod(String name, Varargs args) { return get(name).invoke(varargsOf(this,args)); } + + /** Call named method on {@link this} with variable arguments, including metatag processing, + * and retain all return values in a {@link Varargs}. + *

+ * Look up {@code this[name]} and if it is a {@link LuaFunction}, + * call it inserting {@link this} as an additional first argument, + * and return all return values as a {@link Varargs} instance. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * To get a particular return value, us {@link Varargs#arg(int)} + *

+ * To call {@link this} as a plain call, use {@link #invoke(Varargs)} instead. + * + * @param name Name of the method to look up for invocation + * @param args {@link Varargs} containing arguments to supply to the called function after {@code this} + * @return All values returned from {@code this:name(args)} as a {@link Varargs} instance + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #call() + * @see #invoke(Varargs) + * @see #method(String) + * @see #invokemethod(String,Varargs) + * @see #invokemethod(LuaValue,LuaValue[]) + */ public Varargs invokemethod(LuaValue name, Varargs args) { return get(name).invoke(varargsOf(this,args)); } + + /** Call named method on {@link this} with 1 argument, including metatag processing, + * and retain all return values in a {@link Varargs}. + *

+ * Look up {@code this[name]} and if it is a {@link LuaFunction}, + * call it inserting {@link this} as an additional first argument, + * and return all return values as a {@link Varargs} instance. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * To get a particular return value, us {@link Varargs#arg(int)} + *

+ * To call {@link this} as a plain call, use {@link #invoke(Varargs)} instead. + * + * @param name Name of the method to look up for invocation + * @param args Array of {@link LuaValue} containing arguments to supply to the called function after {@code this} + * @return All values returned from {@code this:name(args)} as a {@link Varargs} instance + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #call() + * @see #invoke(Varargs) + * @see #method(String) + * @see #invokemethod(LuaValue,LuaValue[]) + * @see #invokemethod(String,Varargs) + * @see LuaValue#varargsOf(LuaValue[]) + */ public Varargs invokemethod(String name, LuaValue[] args) { return get(name).invoke(varargsOf(this,varargsOf(args))); } + + /** Call named method on {@link this} with variable arguments, including metatag processing, + * and retain all return values in a {@link Varargs}. + *

+ * Look up {@code this[name]} and if it is a {@link LuaFunction}, + * call it inserting {@link this} as an additional first argument, + * and return all return values as a {@link Varargs} instance. + * Otherwise, look for the {@link CALL} metatag and call that. + *

+ * To get a particular return value, us {@link Varargs#arg(int)} + *

+ * To call {@link this} as a plain call, use {@link #invoke(Varargs)} instead. + * + * @param name Name of the method to look up for invocation + * @param args Array of {@link LuaValue} containing arguments to supply to the called function after {@code this} + * @return All values returned from {@code this:name(args)} as a {@link Varargs} instance + * @throws LuaError if not a function and {@link CALL} is not defined, + * or the invoked function throws a {@link LuaError} + * or the invoked closure throw a lua {@code error} + * @see #call() + * @see #invoke(Varargs) + * @see #method(String) + * @see #invokemethod(String,LuaValue[]) + * @see #invokemethod(LuaValue,Varargs) + * @see LuaValue#varargsOf(LuaValue[]) + */ public Varargs invokemethod(LuaValue name, LuaValue[] args) { return get(name).invoke(varargsOf(this,varargsOf(args))); } + + /** + * Get the metatag value for the {@link CALL} metatag, if it exists. + * @return {@link LuaValue} value if metatag is defined + * @throws LuaError if {@link CALL} metatag is not defined. + */ protected LuaValue callmt() { return checkmetatag(CALL, "attempt to call "); } - // unary operators + /** Unary not: return inverse boolean value {@code (~this)} as defined by lua not operator + * @return {@link TRUE} if {@link NIL} or {@link FALSE}, otherwise {@link FALSE} + */ public LuaValue not() { return FALSE; } + + /** Unary minus: return negative value {@code (-this)} as defined by lua unary minus operator + * @return boolean inverse as {@link LuaBoolean} if boolean or nil, + * numeric inverse as {@LuaNumber} if numeric, + * or metatag processing result if {@link UNM} metatag is defined + * @throws LuaError if {@code this} is not a table or string, and has no {@link UNM} metatag + */ public LuaValue neg() { return checkmetatag(UNM, "attempt to perform arithmetic on ").call(this); } + + /** Length operator: return lua length of object {@code (#this)} including metatag processing as java int + * @return length as defined by the lua # operator + * or metatag processing result + * @throws LuaError if {@code this} is not a table or string, and has no {@link LEN} metatag + */ public LuaValue len() { return checkmetatag(LEN, "attempt to get length of ").call(this); } + + /** Length operator: return lua length of object {@code (#this)} including metatag processing as java int + * @return length as defined by the lua # operator + * or metatag processing result converted to java int using {@link #toint()} + * @throws LuaError if {@code this} is not a table or string, and has no {@link LEN} metatag + */ public int length() { return len().toint(); } + + /** Implementation of lua 5.0 getn() function. + * @return value of getn() as defined in lua 5.0 spec if {@code this} is a {@link LuaTable} + * @throws LuaError if {@code this} is not a {@link LuaTable} + */ public LuaValue getn() { return typerror("getn"); } // object equality, used for key comparison public boolean equals(Object obj) { return this == obj; } - // arithmetic equality with metatag processing + /** Equals: Perform equality comparison with another value + * including metatag processing using {@link EQ}. + * @param val The value to compare with. + * @return {@link TRUE} if values are comparable and {@code (this == rhs)}, + * {@link FALSE} if comparable but not equal, + * {@link LuaValue} if metatag processing occurs. + * @see #eq_b(LuaValue) + * @see #raweq(LuaValue) + * @see #neq(LuaValue) + * @see #eqmtcall(LuaValue, LuaValue, LuaValue, LuaValue) + * @see #EQ + */ public LuaValue eq( LuaValue val ) { return this == val? TRUE: FALSE; } + + /** Equals: Perform equality comparison with another value + * including metatag processing using {@link EQ}, + * and return java boolean + * @param val The value to compare with. + * @return true if values are comparable and {@code (this == rhs)}, + * false if comparable but not equal, + * result converted to java boolean if metatag processing occurs. + * @see #eq(LuaValue) + * @see #raweq(LuaValue) + * @see #neq_b(LuaValue) + * @see #eqmtcall(LuaValue, LuaValue, LuaValue, LuaValue) + * @see #EQ + */ public boolean eq_b( LuaValue val ) { return this == val; } + + /** Notquals: Perform inequality comparison with another value + * including metatag processing using {@link EQ}. + * @param val The value to compare with. + * @return {@link TRUE} if values are comparable and {@code (this != rhs)}, + * {@link FALSE} if comparable but equal, + * inverse of {@link LuaValue} converted to {@link LuaBoolean} if metatag processing occurs. + * @see #eq(LuaValue) + * @see #raweq(LuaValue) + * @see #eqmtcall(LuaValue, LuaValue, LuaValue, LuaValue) + * @see #EQ + */ public LuaValue neq( LuaValue val ) { return eq_b(val)? FALSE: TRUE; } + + /** Notquals: Perform inequality comparison with another value + * including metatag processing using {@link EQ}. + * @param val The value to compare with. + * @return true if values are comparable and {@code (this != rhs)}, + * false if comparable but equal, + * inverse of result converted to boolean if metatag processing occurs. + * @see #eq_b(LuaValue) + * @see #raweq(LuaValue) + * @see #eqmtcall(LuaValue, LuaValue, LuaValue, LuaValue) + * @see #EQ + */ public boolean neq_b( LuaValue val ) { return !eq_b(val); } - // equality without metatag processing + /** Equals: Perform direct equality comparison with another value + * without metatag processing. + * @param val The value to compare with. + * @return true if {@code (this == rhs)}, false otherwise + * @see #eq(LuaValue) + * @see #raweq(LuaUserdata) + * @see #raweq(LuaString) + * @see #raweq(double) + * @see #raweq(int) + * @see #EQ + */ public boolean raweq( LuaValue val ) { return this == val; } + + /** Equals: Perform direct equality comparison with a {@link LuaUserdata} value + * without metatag processing. + * @param val The {@link LuaUserdata} to compare with. + * @return true if {@code this} is userdata + * and their metatables are the same using == + * and their instances are equal using {@link #equals(Object)}, + * otherwise false + * @see #eq(LuaValue) + * @see #raweq(LuaValue) + */ public boolean raweq( LuaUserdata val ) { return false; } + + /** Equals: Perform direct equality comparison with a {@link LuaString} value + * without metatag processing. + * @param val The {@link LuaString} to compare with. + * @return true if {@code this} is a {@link LuaString} + * and their byte sequences match, + * otherwise false + */ public boolean raweq( LuaString val ) { return false; } + + /** Equals: Perform direct equality comparison with a double value + * without metatag processing. + * @param val The double value to compare with. + * @return true if {@code this} is a {@link LuaNumber} + * whose value equals val, + * otherwise false + */ public boolean raweq( double val ) { return false; } + + /** Equals: Perform direct equality comparison with a int value + * without metatag processing. + * @param val The double value to compare with. + * @return true if {@code this} is a {@link LuaNumber} + * whose value equals val, + * otherwise false + */ public boolean raweq( int val ) { return false; } - // __eq metatag processing + /** Perform equality testing metatag processing + * @param lhs left-hand-side of equality expression + * @param lhsmt metatag value for left-hand-side + * @param rhs right-hand-side of equality expression + * @param rhsmt metatag value for right-hand-side + * @return true if metatag processing result is not {@link NIL} or {@link FALSE} + * @throws LuaError if metatag was not defined for either operand + * @see #equals(Object) + * @see #eq(LuaValue) + * @see #raweq(LuaValue) + * @see #EQ + */ public static final boolean eqmtcall(LuaValue lhs, LuaValue lhsmt, LuaValue rhs, LuaValue rhsmt) { LuaValue h = lhsmt.rawget(EQ); return h.isnil() || h!=rhsmt.rawget(EQ)? false: h.call(lhs,rhs).toboolean(); } - // arithmetic operators + /** Add: Perform numeric add operation with another value + * including metatag processing. + *

+ * Each operand must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + * + * @param rhs The right-hand-side value to perform the add with + * @return value of {@code (this + rhs)} if both are numeric, + * or {@link LuaValue} if metatag processing occurs + * @throws LuaError if either operand is not a number or string convertible to number, + * and neither has the {@link ADD} metatag defined + * @see #arithmt(LuaValue, LuaValue) + */ public LuaValue add( LuaValue rhs ) { return arithmt(ADD,rhs); } + + /** Add: Perform numeric add operation with another value + * of double type without metatag processing + *

+ * {@code this} must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + *

+ * For metatag processing {@link #add(LuaValue)} must be used + * + * @param rhs The right-hand-side value to perform the add with + * @return value of {@code (this + rhs)} if this is numeric + * @throws LuaError if {@code this} is not a number or string convertible to number + * @see #add(LuaValue) + */ public LuaValue add(double rhs) { return aritherror("add"); } + + /** Add: Perform numeric add operation with another value + * of int type without metatag processing + *

+ * {@code this} must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + *

+ * For metatag processing {@link #add(LuaValue)} must be used + * + * @param rhs The right-hand-side value to perform the add with + * @return value of {@code (this + rhs)} if this is numeric + * @throws LuaError if {@code this} is not a number or string convertible to number + * @see #add(LuaValue) + */ public LuaValue add(int rhs) { return add((double)rhs); } + + /** Subtract: Perform numeric subtract operation with another value + * of unknown type, + * including metatag processing. + *

+ * Each operand must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + * + * @param rhs The right-hand-side value to perform the subtract with + * @return value of {@code (this - rhs)} if both are numeric, + * or {@link LuaValue} if metatag processing occurs + * @throws LuaError if either operand is not a number or string convertible to number, + * and neither has the {@link SUB} metatag defined + * @see #arithmt(LuaValue, LuaValue) + */ public LuaValue sub( LuaValue rhs ) { return arithmt(SUB,rhs); } + + /** Subtract: Perform numeric subtract operation with another value + * of double type without metatag processing + *

+ * {@code this} must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + *

+ * For metatag processing {@link #sub(LuaValue)} must be used + * + * @param rhs The right-hand-side value to perform the subtract with + * @return value of {@code (this - rhs)} if this is numeric + * @throws LuaError if {@code this} is not a number or string convertible to number + * @see #sub(LuaValue) + */ public LuaValue sub( double rhs ) { return aritherror("sub"); } + + /** Subtract: Perform numeric subtract operation with another value + * of int type without metatag processing + *

+ * {@code this} must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + *

+ * For metatag processing {@link #sub(LuaValue)} must be used + * + * @param rhs The right-hand-side value to perform the subtract with + * @return value of {@code (this - rhs)} if this is numeric + * @throws LuaError if {@code this} is not a number or string convertible to number + * @see #sub(LuaValue) + */ public LuaValue sub( int rhs ) { return aritherror("sub"); } + + /** Reverse-subtract: Perform numeric subtract operation from an int value + * without metatag processing + *

+ * {@code this} must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + *

+ * For metatag processing {@link #sub(LuaValue)} must be used + * + * @param lhs The left-hand-side value from which to perform the subtraction + * @return value of {@code (lhs - this)} if this is numeric + * @throws LuaError if {@code this} is not a number or string convertible to number + * @see #sub(LuaValue) + * @see #sub(double) + * @see #sub(int) + */ public LuaValue subFrom(double lhs) { return aritherror("sub"); } + + /** Reverse-subtract: Perform numeric subtract operation from a double value + * without metatag processing + *

+ * {@code this} must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + *

+ * For metatag processing {@link #sub(LuaValue)} must be used + * + * @param lhs The left-hand-side value from which to perform the subtraction + * @return value of {@code (lhs - this)} if this is numeric + * @throws LuaError if {@code this} is not a number or string convertible to number + * @see #sub(LuaValue) + * @see #sub(double) + * @see #sub(int) + */ public LuaValue subFrom(int lhs) { return subFrom((double)lhs); } + + /** Multiply: Perform numeric multiply operation with another value + * of unknown type, + * including metatag processing. + *

+ * Each operand must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + * + * @param rhs The right-hand-side value to perform the multiply with + * @return value of {@code (this * rhs)} if both are numeric, + * or {@link LuaValue} if metatag processing occurs + * @throws LuaError if either operand is not a number or string convertible to number, + * and neither has the {@link MUL} metatag defined + * @see #arithmt(LuaValue, LuaValue) + */ public LuaValue mul( LuaValue rhs ) { return arithmt(MUL,rhs); } + + /** Multiply: Perform numeric multiply operation with another value + * of double type without metatag processing + *

+ * {@code this} must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + *

+ * For metatag processing {@link #mul(LuaValue)} must be used + * + * @param rhs The right-hand-side value to perform the multiply with + * @return value of {@code (this * rhs)} if this is numeric + * @throws LuaError if {@code this} is not a number or string convertible to number + * @see #mul(LuaValue) + */ public LuaValue mul(double rhs) { return aritherror("mul"); } + + /** Multiply: Perform numeric multiply operation with another value + * of int type without metatag processing + *

+ * {@code this} must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + *

+ * For metatag processing {@link #mul(LuaValue)} must be used + * + * @param rhs The right-hand-side value to perform the multiply with + * @return value of {@code (this * rhs)} if this is numeric + * @throws LuaError if {@code this} is not a number or string convertible to number + * @see #mul(LuaValue) + */ public LuaValue mul(int rhs) { return mul((double)rhs); } + + /** Raise to power: Raise this value to a power + * including metatag processing. + *

+ * Each operand must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + * + * @param rhs The power to raise this value to + * @return value of {@code (this ^ rhs)} if both are numeric, + * or {@link LuaValue} if metatag processing occurs + * @throws LuaError if either operand is not a number or string convertible to number, + * and neither has the {@link POW} metatag defined + * @see #arithmt(LuaValue, LuaValue) + */ public LuaValue pow( LuaValue rhs ) { return arithmt(POW,rhs); } + + /** Raise to power: Raise this value to a power + * of double type without metatag processing + *

+ * {@code this} must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + *

+ * For metatag processing {@link #pow(LuaValue)} must be used + * + * @param rhs The power to raise this value to + * @return value of {@code (this ^ rhs)} if this is numeric + * @throws LuaError if {@code this} is not a number or string convertible to number + * @see #pow(LuaValue) + */ public LuaValue pow( double rhs ) { return aritherror("pow"); } + + /** Raise to power: Raise this value to a power + * of int type without metatag processing + *

+ * {@code this} must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + *

+ * For metatag processing {@link #pow(LuaValue)} must be used + * + * @param rhs The power to raise this value to + * @return value of {@code (this ^ rhs)} if this is numeric + * @throws LuaError if {@code this} is not a number or string convertible to number + * @see #pow(LuaValue) + */ public LuaValue pow( int rhs ) { return aritherror("pow"); } + + /** Reverse-raise to power: Raise another value of double type to this power + * without metatag processing + *

+ * {@code this} must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + *

+ * For metatag processing {@link #pow(LuaValue)} must be used + * + * @param lhs The left-hand-side value which will be raised to this power + * @return value of {@code (lhs ^ this)} if this is numeric + * @throws LuaError if {@code this} is not a number or string convertible to number + * @see #pow(LuaValue) + * @see #pow(double) + * @see #pow(int) + */ public LuaValue powWith(double lhs) { return aritherror("mul"); } + + /** Reverse-raise to power: Raise another value of double type to this power + * without metatag processing + *

+ * {@code this} must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + *

+ * For metatag processing {@link #pow(LuaValue)} must be used + * + * @param lhs The left-hand-side value which will be raised to this power + * @return value of {@code (lhs ^ this)} if this is numeric + * @throws LuaError if {@code this} is not a number or string convertible to number + * @see #pow(LuaValue) + * @see #pow(double) + * @see #pow(int) + */ public LuaValue powWith(int lhs) { return powWith((double)lhs); } + + /** Divide: Perform numeric divide operation by another value + * of unknown type, + * including metatag processing. + *

+ * Each operand must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + * + * @param rhs The right-hand-side value to perform the divulo with + * @return value of {@code (this / rhs)} if both are numeric, + * or {@link LuaValue} if metatag processing occurs + * @throws LuaError if either operand is not a number or string convertible to number, + * and neither has the {@link DIV} metatag defined + * @see #arithmt(LuaValue, LuaValue) + */ public LuaValue div( LuaValue rhs ) { return arithmt(DIV,rhs); } + + /** Divide: Perform numeric divide operation by another value + * of double type without metatag processing + *

+ * {@code this} must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + *

+ * For metatag processing {@link #div(LuaValue)} must be used + * + * @param rhs The right-hand-side value to perform the divulo with + * @return value of {@code (this / rhs)} if this is numeric + * @throws LuaError if {@code this} is not a number or string convertible to number + * @see #div(LuaValue) + */ public LuaValue div( double rhs ) { return aritherror("div"); } + + /** Divide: Perform numeric divide operation by another value + * of int type without metatag processing + *

+ * {@code this} must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + *

+ * For metatag processing {@link #div(LuaValue)} must be used + * + * @param rhs The right-hand-side value to perform the divulo with + * @return value of {@code (this / rhs)} if this is numeric + * @throws LuaError if {@code this} is not a number or string convertible to number + * @see #div(LuaValue) + */ public LuaValue div( int rhs ) { return aritherror("div"); } + + /** Reverse-divide: Perform numeric divide operation into another value + * without metatag processing + *

+ * {@code this} must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + *

+ * For metatag processing {@link #div(LuaValue)} must be used + * + * @param lhs The left-hand-side value which will be divided by this + * @return value of {@code (lhs / this)} if this is numeric + * @throws LuaError if {@code this} is not a number or string convertible to number + * @see #div(LuaValue) + * @see #div(double) + * @see #div(int) + */ public LuaValue divInto(double lhs) { return aritherror("divInto"); } + + /** Modulo: Perform numeric modulo operation with another value + * of unknown type, + * including metatag processing. + *

+ * Each operand must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + * + * @param rhs The right-hand-side value to perform the modulo with + * @return value of {@code (this % rhs)} if both are numeric, + * or {@link LuaValue} if metatag processing occurs + * @throws LuaError if either operand is not a number or string convertible to number, + * and neither has the {@link MOD} metatag defined + * @see #arithmt(LuaValue, LuaValue) + */ public LuaValue mod( LuaValue rhs ) { return arithmt(MOD,rhs); } + + /** Modulo: Perform numeric modulo operation with another value + * of double type without metatag processing + *

+ * {@code this} must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + *

+ * For metatag processing {@link #mod(LuaValue)} must be used + * + * @param rhs The right-hand-side value to perform the modulo with + * @return value of {@code (this % rhs)} if this is numeric + * @throws LuaError if {@code this} is not a number or string convertible to number + * @see #mod(LuaValue) + */ public LuaValue mod( double rhs ) { return aritherror("mod"); } + + /** Modulo: Perform numeric modulo operation with another value + * of int type without metatag processing + *

+ * {@code this} must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + *

+ * For metatag processing {@link #mod(LuaValue)} must be used + * + * @param rhs The right-hand-side value to perform the modulo with + * @return value of {@code (this % rhs)} if this is numeric + * @throws LuaError if {@code this} is not a number or string convertible to number + * @see #mod(LuaValue) + */ public LuaValue mod( int rhs ) { return aritherror("mod"); } + + /** Reverse-modulo: Perform numeric modulo operation from another value + * without metatag processing + *

+ * {@code this} must derive from {@link LuaNumber} + * or derive from {@link LuaString} and be convertible to a number + *

+ * For metatag processing {@link #mod(LuaValue)} must be used + * + * @param lhs The left-hand-side value which will be modulo'ed by this + * @return value of {@code (lhs % this)} if this is numeric + * @throws LuaError if {@code this} is not a number or string convertible to number + * @see #mod(LuaValue) + * @see #mod(double) + * @see #mod(int) + */ public LuaValue modFrom(double lhs) { return aritherror("modFrom"); } + + /** Perform metatag processing for arithmetic operations. + *

+ * Finds the supplied metatag value for {@code this} or {@code op2} and invokes it, + * or throws {@link LuaError} if neither is defined. + * @param tag The metatag to look up + * @param op2 The other operand value to perform the operation with + * @return {@link LuaValue} resulting from metatag processing + * @throws LuaError if metatag was not defined for either operand + * @see #add(LuaValue) + * @see #sub(LuaValue) + * @see #mul(LuaValue) + * @see #pow(LuaValue) + * @see #div(LuaValue) + * @see #mod(LuaValue) + * @see #ADD + * @see #SUB + * @see #MUL + * @see #POW + * @see #DIV + * @see #MOD + */ protected LuaValue arithmt(LuaValue tag, LuaValue op2) { LuaValue h = this.metatag(tag); if ( h.isnil() ) { @@ -309,31 +2530,421 @@ public class LuaValue extends Varargs { return h.call( this, op2 ); } - // relational operators + /** Less than: Perform numeric or string comparison with another value + * of unknown type, + * including metatag processing, and returning {@link LuaValue}. + *

+ * To be comparable, both operands must derive from {@link LuaString} + * or both must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return {@link TRUE} if {@code (this < rhs)}, {@link FALSE} if not, + * or {@link LuaValue} if metatag processing occurs + * @throws LuaError if either both operands are not a strings or both are not numbers + * and no {@link LT} metatag is defined. + * @see #gteq_b(LuaValue) + * @see #comparemt(LuaValue, LuaValue) + */ public LuaValue lt( LuaValue rhs ) { return comparemt(LT,rhs); } + + /** Less than: Perform numeric comparison with another value + * of double type, + * including metatag processing, and returning {@link LuaValue}. + *

+ * To be comparable, this must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return {@link TRUE} if {@code (this < rhs)}, {@link FALSE} if not, + * or {@link LuaValue} if metatag processing occurs + * @throws LuaError if this is not a number + * and no {@link LT} metatag is defined. + * @see #gteq_b(double) + * @see #comparemt(LuaValue, LuaValue) + */ public LuaValue lt( double rhs ) { return compareerror("number"); } + + /** Less than: Perform numeric comparison with another value + * of int type, + * including metatag processing, and returning {@link LuaValue}. + *

+ * To be comparable, this must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return {@link TRUE} if {@code (this < rhs)}, {@link FALSE} if not, + * or {@link LuaValue} if metatag processing occurs + * @throws LuaError if this is not a number + * and no {@link LT} metatag is defined. + * @see #gteq_b(int) + * @see #comparemt(LuaValue, LuaValue) + */ public LuaValue lt( int rhs ) { return compareerror("number"); } + + /** Less than: Perform numeric or string comparison with another value + * of unknown type, including metatag processing, + * and returning java boolean. + *

+ * To be comparable, both operands must derive from {@link LuaString} + * or both must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return true if {@code (this < rhs)}, false if not, + * and boolean interpreation of result if metatag processing occurs. + * @throws LuaError if either both operands are not a strings or both are not numbers + * and no {@link LT} metatag is defined. + * @see #gteq(LuaValue) + * @see #comparemt(LuaValue, LuaValue) + */ public boolean lt_b( LuaValue rhs ) { return comparemt(LT,rhs).toboolean(); } + + /** Less than: Perform numeric comparison with another value + * of int type, + * including metatag processing, + * and returning java boolean. + *

+ * To be comparable, this must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return true if {@code (this < rhs)}, false if not, + * and boolean interpreation of result if metatag processing occurs. + * @throws LuaError if this is not a number + * and no {@link LT} metatag is defined. + * @see #gteq(int) + * @see #comparemt(LuaValue, LuaValue) + */ public boolean lt_b( int rhs ) { compareerror("number"); return false; } + + /** Less than: Perform numeric or string comparison with another value + * of unknown type, including metatag processing, + * and returning java boolean. + *

+ * To be comparable, both operands must derive from {@link LuaString} + * or both must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return true if {@code (this < rhs)}, false if not, + * and boolean interpreation of result if metatag processing occurs. + * @throws LuaError if either both operands are not a strings or both are not numbers + * and no {@link LT} metatag is defined. + * @see #gteq(LuaValue) + * @see #comparemt(LuaValue, LuaValue) + */ public boolean lt_b( double rhs ) { compareerror("number"); return false; } + + /** Less than or equals: Perform numeric or string comparison with another value + * of unknown type, + * including metatag processing, and returning {@link LuaValue}. + *

+ * To be comparable, both operands must derive from {@link LuaString} + * or both must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return {@link TRUE} if {@code (this <= rhs)}, {@link FALSE} if not, + * or {@link LuaValue} if metatag processing occurs + * @throws LuaError if either both operands are not a strings or both are not numbers + * and no {@link LE} metatag is defined. + * @see #gteq_b(LuaValue) + * @see #comparemt(LuaValue, LuaValue) + */ public LuaValue lteq( LuaValue rhs ) { return comparemt(LE,rhs); } + + /** Less than or equals: Perform numeric comparison with another value + * of double type, + * including metatag processing, and returning {@link LuaValue}. + *

+ * To be comparable, this must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return {@link TRUE} if {@code (this <= rhs)}, {@link FALSE} if not, + * or {@link LuaValue} if metatag processing occurs + * @throws LuaError if this is not a number + * and no {@link LE} metatag is defined. + * @see #gteq_b(double) + * @see #comparemt(LuaValue, LuaValue) + */ public LuaValue lteq( double rhs ) { return compareerror("number"); } + + /** Less than or equals: Perform numeric comparison with another value + * of int type, + * including metatag processing, and returning {@link LuaValue}. + *

+ * To be comparable, this must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return {@link TRUE} if {@code (this <= rhs)}, {@link FALSE} if not, + * or {@link LuaValue} if metatag processing occurs + * @throws LuaError if this is not a number + * and no {@link LE} metatag is defined. + * @see #gteq_b(int) + * @see #comparemt(LuaValue, LuaValue) + */ public LuaValue lteq( int rhs ) { return compareerror("number"); } + + /** Less than or equals: Perform numeric or string comparison with another value + * of unknown type, including metatag processing, + * and returning java boolean. + *

+ * To be comparable, both operands must derive from {@link LuaString} + * or both must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return true if {@code (this <= rhs)}, false if not, + * and boolean interpreation of result if metatag processing occurs. + * @throws LuaError if either both operands are not a strings or both are not numbers + * and no {@link LE} metatag is defined. + * @see #gteq(LuaValue) + * @see #comparemt(LuaValue, LuaValue) + */ public boolean lteq_b( LuaValue rhs ) { return comparemt(LE,rhs).toboolean(); } + + /** Less than or equals: Perform numeric comparison with another value + * of int type, + * including metatag processing, + * and returning java boolean. + *

+ * To be comparable, this must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return true if {@code (this <= rhs)}, false if not, + * and boolean interpreation of result if metatag processing occurs. + * @throws LuaError if this is not a number + * and no {@link LE} metatag is defined. + * @see #gteq(int) + * @see #comparemt(LuaValue, LuaValue) + */ public boolean lteq_b( int rhs ) { compareerror("number"); return false; } + + /** Less than or equals: Perform numeric comparison with another value + * of double type, + * including metatag processing, + * and returning java boolean. + *

+ * To be comparable, this must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return true if {@code (this <= rhs)}, false if not, + * and boolean interpreation of result if metatag processing occurs. + * @throws LuaError if this is not a number + * and no {@link LE} metatag is defined. + * @see #gteq(double) + * @see #comparemt(LuaValue, LuaValue) + */ public boolean lteq_b( double rhs ) { compareerror("number"); return false; } + + /** Greater than: Perform numeric or string comparison with another value + * of unknown type, + * including metatag processing, and returning {@link LuaValue}. + *

+ * To be comparable, both operands must derive from {@link LuaString} + * or both must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return {@link TRUE} if {@code (this > rhs)}, {@link FALSE} if not, + * or {@link LuaValue} if metatag processing occurs + * @throws LuaError if either both operands are not a strings or both are not numbers + * and no {@link LE} metatag is defined. + * @see #gteq_b(LuaValue) + * @see #comparemt(LuaValue, LuaValue) + */ public LuaValue gt( LuaValue rhs ) { return rhs.comparemt(LE,this); } + + /** Greater than: Perform numeric comparison with another value + * of double type, + * including metatag processing, and returning {@link LuaValue}. + *

+ * To be comparable, this must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return {@link TRUE} if {@code (this > rhs)}, {@link FALSE} if not, + * or {@link LuaValue} if metatag processing occurs + * @throws LuaError if this is not a number + * and no {@link LE} metatag is defined. + * @see #gteq_b(double) + * @see #comparemt(LuaValue, LuaValue) + */ public LuaValue gt( double rhs ) { return compareerror("number"); } + + /** Greater than: Perform numeric comparison with another value + * of int type, + * including metatag processing, and returning {@link LuaValue}. + *

+ * To be comparable, this must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return {@link TRUE} if {@code (this > rhs)}, {@link FALSE} if not, + * or {@link LuaValue} if metatag processing occurs + * @throws LuaError if this is not a number + * and no {@link LE} metatag is defined. + * @see #gteq_b(int) + * @see #comparemt(LuaValue, LuaValue) + */ public LuaValue gt( int rhs ) { return compareerror("number"); } + + /** Greater than: Perform numeric or string comparison with another value + * of unknown type, including metatag processing, + * and returning java boolean. + *

+ * To be comparable, both operands must derive from {@link LuaString} + * or both must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return true if {@code (this > rhs)}, false if not, + * and boolean interpreation of result if metatag processing occurs. + * @throws LuaError if either both operands are not a strings or both are not numbers + * and no {@link LE} metatag is defined. + * @see #gteq(LuaValue) + * @see #comparemt(LuaValue, LuaValue) + */ public boolean gt_b( LuaValue rhs ) { return rhs.comparemt(LE,this).toboolean(); } + + /** Greater than: Perform numeric comparison with another value + * of int type, + * including metatag processing, + * and returning java boolean. + *

+ * To be comparable, this must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return true if {@code (this > rhs)}, false if not, + * and boolean interpreation of result if metatag processing occurs. + * @throws LuaError if this is not a number + * and no {@link LE} metatag is defined. + * @see #gteq(int) + * @see #comparemt(LuaValue, LuaValue) + */ public boolean gt_b( int rhs ) { compareerror("number"); return false; } + + /** Greater than: Perform numeric or string comparison with another value + * of unknown type, including metatag processing, + * and returning java boolean. + *

+ * To be comparable, both operands must derive from {@link LuaString} + * or both must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return true if {@code (this > rhs)}, false if not, + * and boolean interpreation of result if metatag processing occurs. + * @throws LuaError if either both operands are not a strings or both are not numbers + * and no {@link LE} metatag is defined. + * @see #gteq(LuaValue) + * @see #comparemt(LuaValue, LuaValue) + */ public boolean gt_b( double rhs ) { compareerror("number"); return false; } + + /** Greater than or equals: Perform numeric or string comparison with another value + * of unknown type, + * including metatag processing, and returning {@link LuaValue}. + *

+ * To be comparable, both operands must derive from {@link LuaString} + * or both must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return {@link TRUE} if {@code (this >= rhs)}, {@link FALSE} if not, + * or {@link LuaValue} if metatag processing occurs + * @throws LuaError if either both operands are not a strings or both are not numbers + * and no {@link LT} metatag is defined. + * @see #gteq_b(LuaValue) + * @see #comparemt(LuaValue, LuaValue) + */ public LuaValue gteq( LuaValue rhs ) { return rhs.comparemt(LT,this); } + + /** Greater than or equals: Perform numeric comparison with another value + * of double type, + * including metatag processing, and returning {@link LuaValue}. + *

+ * To be comparable, this must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return {@link TRUE} if {@code (this >= rhs)}, {@link FALSE} if not, + * or {@link LuaValue} if metatag processing occurs + * @throws LuaError if this is not a number + * and no {@link LT} metatag is defined. + * @see #gteq_b(double) + * @see #comparemt(LuaValue, LuaValue) + */ public LuaValue gteq( double rhs ) { return compareerror("number"); } + + /** Greater than or equals: Perform numeric comparison with another value + * of int type, + * including metatag processing, and returning {@link LuaValue}. + *

+ * To be comparable, this must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return {@link TRUE} if {@code (this >= rhs)}, {@link FALSE} if not, + * or {@link LuaValue} if metatag processing occurs + * @throws LuaError if this is not a number + * and no {@link LT} metatag is defined. + * @see #gteq_b(int) + * @see #comparemt(LuaValue, LuaValue) + */ public LuaValue gteq( int rhs ) { return valueOf(todouble() >= rhs); } + + /** Greater than or equals: Perform numeric or string comparison with another value + * of unknown type, including metatag processing, + * and returning java boolean. + *

+ * To be comparable, both operands must derive from {@link LuaString} + * or both must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return true if {@code (this >= rhs)}, false if not, + * and boolean interpreation of result if metatag processing occurs. + * @throws LuaError if either both operands are not a strings or both are not numbers + * and no {@link LT} metatag is defined. + * @see #gteq(LuaValue) + * @see #comparemt(LuaValue, LuaValue) + */ public boolean gteq_b( LuaValue rhs ) { return rhs.comparemt(LT,this).toboolean(); } + + /** Greater than or equals: Perform numeric comparison with another value + * of int type, + * including metatag processing, + * and returning java boolean. + *

+ * To be comparable, this must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return true if {@code (this >= rhs)}, false if not, + * and boolean interpreation of result if metatag processing occurs. + * @throws LuaError if this is not a number + * and no {@link LT} metatag is defined. + * @see #gteq(int) + * @see #comparemt(LuaValue, LuaValue) + */ public boolean gteq_b( int rhs ) { compareerror("number"); return false; } + + /** Greater than or equals: Perform numeric comparison with another value + * of double type, + * including metatag processing, + * and returning java boolean. + *

+ * To be comparable, this must derive from {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @return true if {@code (this >= rhs)}, false if not, + * and boolean interpreation of result if metatag processing occurs. + * @throws LuaError if this is not a number + * and no {@link LT} metatag is defined. + * @see #gteq(double) + * @see #comparemt(LuaValue, LuaValue) + */ public boolean gteq_b( double rhs ) { compareerror("number"); return false; } + + /** Perform metatag processing for comparison operations. + *

+ * Finds the supplied metatag value and invokes it, + * or throws {@link LuaError} if none applies. + * @param tag The metatag to look up + * @param rhs The right-hand-side value to perform the operation with + * @return {@link LuaValue} resulting from metatag processing + * @throws LuaError if metatag was not defined for either operand, + * or if the operands are not the same type, + * or the metatag values for the two operands are different. + * @see #gt(LuaValue) + * @see #gteq(LuaValue) + * @see #lt(LuaValue) + * @see #lteq(LuaValue) + */ public LuaValue comparemt( LuaValue tag, LuaValue op1 ) { if ( type() == op1.type() ) { LuaValue h = metatag(tag); @@ -343,18 +2954,120 @@ public class LuaValue extends Varargs { return error("attempt to compare "+tag+" on "+typename()+" and "+op1.typename()); } - - // string comparison + /** Perform string comparison with another value + * of any type + * using string comparison based on byte values. + *

+ * Only strings can be compared, meaning + * each operand must derive from {@link LuaString}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @returns int < 0 for {@code (this < rhs)}, int > 0 for {@code (this > rhs)}, or 0 when same string. + * @throws LuaError if either operand is not a string + */ public int strcmp( LuaValue rhs ) { error("attempt to compare "+typename()); return 0; } + + /** Perform string comparison with another value + * known to be a {@link LuaString} + * using string comparison based on byte values. + *

+ * Only strings can be compared, meaning + * each operand must derive from {@link LuaString}. + * + * @param rhs The right-hand-side value to perform the comparison with + * @returns int < 0 for {@code (this < rhs)}, int > 0 for {@code (this > rhs)}, or 0 when same string. + * @throws LuaError if this is not a string + */ public int strcmp( LuaString rhs ) { error("attempt to compare "+typename()); return 0; } - // concatenation + /** Concatenate another value onto this value and return the result + * using rules of lua string concatenation including metatag processing. + *

+ * Only strings and numbers as represented can be concatenated, meaning + * each operand must derive from {@link LuaString} or {@link LuaNumber}. + * + * @param rhs The right-hand-side value to perform the operation with + * @returns {@link LuaValue} resulting from concatenation of {@code (this .. rhs)} + * @throws LuaError if either operand is not of an appropriate type, + * such as nil or a table + */ public LuaValue concat(LuaValue rhs) { return this.concatmt(rhs); } + + /** Reverse-concatenation: concatenate this value onto another value + * whose type is unknwon + * and return the result using rules of lua string concatenation including + * metatag processing. + *

+ * Only strings and numbers as represented can be concatenated, meaning + * each operand must derive from {@link LuaString} or {@link LuaNumber}. + * + * @param lhs The left-hand-side value onto which this will be concatenated + * @returns {@link LuaValue} resulting from concatenation of {@code (lhs .. this)} + * @throws LuaError if either operand is not of an appropriate type, + * such as nil or a table + * @see #concat(LuaValue) + */ public LuaValue concatTo(LuaValue lhs) { return lhs.concatmt(this); } + + /** Reverse-concatenation: concatenate this value onto another value + * known to be a {@link LuaNumber} + * and return the result using rules of lua string concatenation including + * metatag processing. + *

+ * Only strings and numbers as represented can be concatenated, meaning + * each operand must derive from {@link LuaString} or {@link LuaNumber}. + * + * @param lhs The left-hand-side value onto which this will be concatenated + * @returns {@link LuaValue} resulting from concatenation of {@code (lhs .. this)} + * @throws LuaError if either operand is not of an appropriate type, + * such as nil or a table + * @see #concat(LuaValue) + */ public LuaValue concatTo(LuaNumber lhs) { return lhs.concatmt(this); } + + /** Reverse-concatenation: concatenate this value onto another value + * known to be a {@link LuaString} + * and return the result using rules of lua string concatenation including + * metatag processing. + *

+ * Only strings and numbers as represented can be concatenated, meaning + * each operand must derive from {@link LuaString} or {@link LuaNumber}. + * + * @param lhs The left-hand-side value onto which this will be concatenated + * @returns {@link LuaValue} resulting from concatenation of {@code (lhs .. this)} + * @throws LuaError if either operand is not of an appropriate type, + * such as nil or a table + * @see #concat(LuaValue) + */ public LuaValue concatTo(LuaString lhs) { return lhs.concatmt(this); } + + /** Convert the value to a {@link Buffer} for more efficient concatenation of + * multiple strings. + * @return Buffer instance containing the string or number + */ public Buffer buffer() { return new Buffer(this); } + + /** Concatenate a {@link Buffer} onto this value and return the result + * using rules of lua string concatenation including metatag processing. + *

+ * Only strings and numbers as represented can be concatenated, meaning + * each operand must derive from {@link LuaString} or {@link LuaNumber}. + * + * @param rhs The right-hand-side {@link Buffer} to perform the operation with + * @return LuaString resulting from concatenation of {@code (this .. rhs)} + * @throws LuaError if either operand is not of an appropriate type, + * such as nil or a table + */ public Buffer concat(Buffer rhs) { return rhs.concatTo(this); } + + /** Perform metatag processing for concatenation operations. + *

+ * Finds the {@link CONCAT} metatag value and invokes it, + * or throws {@link LuaError} if it doesn't exist. + * @param rhs The right-hand-side value to perform the operation with + * @return {@link LuaValue} resulting from metatag processing for {@link CONCAT} metatag. + * @throws LuaError if metatag was not defined for either operand + */ public LuaValue concatmt(LuaValue rhs) { LuaValue h=metatag(CONCAT); if ( h.isnil() && (h=rhs.metatag(CONCAT)).isnil()) @@ -362,47 +3075,195 @@ public class LuaValue extends Varargs { return h.call(this,rhs); } - // boolean operators + /** Perform boolean {@code and} with another operand, based on lua rules for boolean evaluation. + * This returns either {@code this} or {@code rhs} depending on the boolean value for {@code this}. + * + * @param rhs The right-hand-side value to perform the operation with + * @return {@code this} if {@code this.toboolean()} is false, {@code rhs} otherwise. + */ public LuaValue and( LuaValue rhs ) { return this.toboolean()? rhs: this; } + + /** Perform boolean {@code or} with another operand, based on lua rules for boolean evaluation. + * This returns either {@code this} or {@code rhs} depending on the boolean value for {@code this}. + * + * @param rhs The right-hand-side value to perform the operation with + * @return {@code this} if {@code this.toboolean()} is true, {@code rhs} otherwise. + */ public LuaValue or( LuaValue rhs ) { return this.toboolean()? this: rhs; } - // for loop helpers - /** used in for loop only */ + /** Perform end-condition test in for-loop processing. + *

+ * Used in lua-bytecode to Java-bytecode conversion. + * + * @param limit the numerical limit to complete the for loop + * @param step the numberical step size to use. + * @return true if limit has not been reached, false otherwise. + */ public boolean testfor_b(LuaValue limit, LuaValue step) { return step.gt_b(0)? lteq_b(limit): gteq_b(limit); } - // lua number/string conversion + /** + * Convert this value to a string if it is a {@link LuaString} or {@link LuaNumber}, + * or throw a {@link LuaError} if it is not + * @return {@link LuaString} corresponding to the value if a string or number + * @throws LuaError if not a string or number + */ public LuaString strvalue() { typerror("strValue"); return null; } + + /** Return the key part of this value if it is a weak table entry, or {@link NIL} if it was weak and is no longer referenced. + * @return {@link LuaValue} key, or {@link NIL} if it was weak and is no longer referenced. + * @see WeakTable + */ public LuaValue strongkey() { return strongvalue(); } + + /** Return this value as a strong reference, or {@link NIL} if it was weak and is no longer referenced. + * @return {@link LuaValue} referred to, or {@link NIL} if it was weak and is no longer referenced. + * @see WeakTable + */ public LuaValue strongvalue() { return this; } + + /** Test if this is a weak reference and its value no longer is referenced. + * @return true if this is a weak reference whose value no longer is referenced + * @see WeakTable + */ public boolean isweaknil() { return false; } - // conversion from java values + /** Convert java boolean to a {@link LuaValue}. + * + * @param b boolean value to convert + * @return {@link TRUE} if not or {@link FALSE} if false + */ public static LuaBoolean valueOf(boolean b) { return b? LuaValue.TRUE: FALSE; }; + + /** Convert java int to a {@link LuaValue}. + * + * @param i int value to convert + * @return {@link LuaInteger} instance, possibly pooled, whose value is i + */ public static LuaInteger valueOf(int i) { return LuaInteger.valueOf(i); } + + /** Convert java double to a {@link LuaValue}. + * This may return a {@link LuaInteger} or {@link LuaDouble} depending + * on the value supplied. + * + * @param d double value to convert + * @return {@link LuaNumber} instance, possibly pooled, whose value is d + */ public static LuaNumber valueOf(double d) { return LuaDouble.valueOf(d); }; + + /** Convert java string to a {@link LuaValue}. + * + * @param s String value to convert + * @return {@link LuaString} instance, possibly pooled, whose value is s + */ public static LuaString valueOf(String s) { return LuaString.valueOf(s); } + + /** Convert bytes in an array to a {@link LuaValue}. + * + * @param bytes byte array to convert + * @return {@link LuaString} instance, possibly pooled, whose bytes are those in the supplied array + */ public static LuaString valueOf(byte[] bytes) { return LuaString.valueOf(bytes); } + + /** Convert bytes in an array to a {@link LuaValue}. + * + * @param bytes byte array to convert + * @param off offset into the byte array, starting at 0 + * @param len number of bytes to include in the {@link LuaString} + * @return {@link LuaString} instance, possibly pooled, whose bytes are those in the supplied array + */ public static LuaString valueOf(byte[] bytes, int off, int len) { return LuaString.valueOf(bytes,off,len); } - // table initializers + /** Construct an empty {@link LuaTable}. + * @return new {@link LuaTable} instance with no values and no metatable. + */ public static LuaTable tableOf() { return new LuaTable(); } + + /** Construct a {@link LuaTable} initialized with supplied array values. + * @param varargs {@link Varargs} containing the values to use in initialization + * @param firstarg the index of the first argument to use from the varargs, 1 being the first. + * @return new {@link LuaTable} instance with sequential elements coming from the varargs. + */ public static LuaTable tableOf(Varargs varargs, int firstarg) { return new LuaTable(varargs,firstarg); } + + /** Construct an empty {@link LuaTable} preallocated to hold array and hashed elements + * @param narray Number of array elements to preallocate + * @param nhash Number of hash elements to preallocate + * @return new {@link LuaTable} instance with no values and no metatable, but preallocated for array and hashed elements. + */ public static LuaTable tableOf(int narray, int nhash) { return new LuaTable(narray, nhash); } + + /** Construct a {@link LuaTable} initialized with supplied array values. + * @param unnamedValues array of {@link LuaValue} containing the values to use in initialization + * @return new {@link LuaTable} instance with sequential elements coming from the array. + */ public static LuaTable listOf(LuaValue[] unnamedValues) { return new LuaTable(null,unnamedValues,null); } + + /** Construct a {@link LuaTable} initialized with supplied array values. + * @param unnamedValues array of {@link LuaValue} containing the first values to use in initialization + * @param lastarg {@link Varargs} containing additional values to use in initialization + * to be put after the last unnamedValues element + * @return new {@link LuaTable} instance with sequential elements coming from the array and varargs. + */ public static LuaTable listOf(LuaValue[] unnamedValues,Varargs lastarg) { return new LuaTable(null,unnamedValues,lastarg); } + + /** Construct a {@link LuaTable} initialized with supplied named values. + * @param namedValues array of {@link LuaValue} containing the keys and values to use in initialization + * in order {@code {key-a, value-a, key-b, value-b, ...} } + * @return new {@link LuaTable} instance with non-sequential keys coming from the supplied array. + */ public static LuaTable tableOf(LuaValue[] namedValues) { return new LuaTable(namedValues,null,null); } + + /** Construct a {@link LuaTable} initialized with supplied named values and sequential elements. + * The named values will be assigned first, and the sequential elements will be assigned later, + * possibly overwriting named values at the same slot if there are conflicts. + * @param namedValues array of {@link LuaValue} containing the keys and values to use in initialization + * in order {@code {key-a, value-a, key-b, value-b, ...} } + * @param unnamedValues array of {@link LuaValue} containing the sequenctial elements to use in initialization + * in order {@code {value-1, value-2, ...} }, or null if there are none + * @return new {@link LuaTable} instance with named and sequential values supplied. + */ public static LuaTable tableOf(LuaValue[] namedValues, LuaValue[] unnamedValues) {return new LuaTable(namedValues,unnamedValues,null); } + + /** Construct a {@link LuaTable} initialized with supplied named values and sequential elements in an array part and as varargs. + * The named values will be assigned first, and the sequential elements will be assigned later, + * possibly overwriting named values at the same slot if there are conflicts. + * @param namedValues array of {@link LuaValue} containing the keys and values to use in initialization + * in order {@code {key-a, value-a, key-b, value-b, ...} } + * @param unnamedValues array of {@link LuaValue} containing the first sequenctial elements to use in initialization + * in order {@code {value-1, value-2, ...} }, or null if there are none + * @param lastarg {@link Varargs} containing additional values to use in the sequential part of the initialization, + * to be put after the last unnamedValues element + * @return new {@link LuaTable} instance with named and sequential values supplied. + */ public static LuaTable tableOf(LuaValue[] namedValues, LuaValue[] unnamedValues, Varargs lastarg) {return new LuaTable(namedValues,unnamedValues,lastarg); } - // userdata intializers + /** Construct a LuaUserdata for an object. + * + * @param o The java instance to be wrapped as userdata + * @return {@link LuaUserdata} value wrapping the java instance. + */ public static LuaUserdata userdataOf(Object o) { return new LuaUserdata(o); } + + /** Construct a LuaUserdata for an object with a user supplied metatable. + * + * @param o The java instance to be wrapped as userdata + * @param metatable The metatble to associate with the userdata instance. + * @return {@link LuaUserdata} value wrapping the java instance. + */ public static LuaUserdata userdataOf(Object o,LuaValue metatable) { return new LuaUserdata(o,metatable); } + /** Constant limiting metatag loop processing */ private static final int MAXTAGLOOP = 100; - // metatable processing + /** + * Return value for field reference including metatag processing, or {@link LuaValue#NIL} if it doesn't exist. + * @param t {@link LuaValue} on which field is being referenced, typically a table or something with the metatag {@link LuaValue#INDEX} defined + * @param key {@link LuaValue} naming the field to reference + * @return {@link LuaValue} for the {@code key} if it exists, or {@link LuaValue#NIL} + * @throws LuaError if there is a loop in metatag processing + */ /** get value from metatable operations, or NIL if not defined by metatables */ protected static LuaValue gettable(LuaValue t, LuaValue key) { LuaValue tm; @@ -423,20 +3284,27 @@ public class LuaValue extends Varargs { return NIL; } - /** returns true if value was set via metatable processing, false otherwise */ - protected static boolean settable(LuaValue t, LuaValue key, LuaValue val) { + /** + * Perform field assignment including metatag processing. + * @param t {@link LuaValue} on which value is being set, typically a table or something with the metatag {@link LuaValue#NEWINDEX} defined + * @param key {@link LuaValue} naming the field to assign + * @param value {@link LuaValue} the new value to assign to {@code key} + * @throws LuaError if there is a loop in metatag processing + * @return true if assignment or metatag processing succeeded, false otherwise + */ + protected static boolean settable(LuaValue t, LuaValue key, LuaValue value) { LuaValue tm; int loop = 0; do { if (t.istable()) { if ((!t.rawget(key).isnil()) || (tm = t.metatag(NEWINDEX)).isnil()) { - t.rawset(key, val); + t.rawset(key, value); return true; } } else if ((tm = t.metatag(NEWINDEX)).isnil()) t.typerror("index"); if (tm.isfunction()) { - tm.call(t, key, val); + tm.call(t, key, value); return true; } t = tm; @@ -446,25 +3314,50 @@ public class LuaValue extends Varargs { return false; } + /** + * Get particular metatag, or return {@link LuaValue#NIL} if it doesn't exist + * @param tag Metatag name to look up, typically a string such as + * {@link LuaValue#INDEX} or {@link LuaValue#NEWINDEX} + * @param reason Description of error when tag lookup fails. + * @return {@link LuaValue} for tag {@code reason}, or {@link LuaValue#NIL} + */ public LuaValue metatag(LuaValue tag) { LuaValue mt = getmetatable(); if ( mt == null ) return NIL; return mt.rawget(tag); } - + + /** + * Get particular metatag, or throw {@link LuaError} if it doesn't exist + * @param tag Metatag name to look up, typically a string such as + * {@link LuaValue#INDEX} or {@link LuaValue#NEWINDEX} + * @param reason Description of error when tag lookup fails. + * @return {@link LuaValue} that can be called + * @throws LuaError when the lookup fails. + */ protected LuaValue checkmetatag(LuaValue tag, String reason) { LuaValue h = this.metatag(tag); if ( h.isnil() ) throw new LuaError(reason+typename()); return h; } - + + /** Throw {@link LuaError} indicating index was attempted on illegal type + * @throws LuaError when called. + */ private void indexerror() { error( "attempt to index ? (a "+typename()+" value)" ); } - // common varargs constructors + /** Construct a {@link Varargs} around an array of {@link LuaValue}s. + * + * @param v The array of {@link LuaValue}s + * @param more {@link Varargs} contain values to include at the end + * @return {@link Varargs} wrapping the supplied values. + * @see LuaValue#varargsOf(LuaValue, Varargs) + * @see LuaValue#varargsOf(LuaValue[], int, int) + */ public static Varargs varargsOf(final LuaValue[] v) { switch ( v.length ) { case 0: return NONE; @@ -473,6 +3366,15 @@ public class LuaValue extends Varargs { default: return new ArrayVarargs(v,NONE); } } + + /** Construct a {@link Varargs} around an array of {@link LuaValue}s. + * + * @param v The array of {@link LuaValue}s + * @param more {@link Varargs} contain values to include at the end + * @return {@link Varargs} wrapping the supplied values. + * @see LuaValue#varargsOf(LuaValue[]) + * @see LuaValue#varargsOf(LuaValue[], int, int, Varargs) + */ public static Varargs varargsOf(final LuaValue[] v,Varargs r) { switch ( v.length ) { case 0: return r; @@ -480,6 +3382,16 @@ public class LuaValue extends Varargs { default: return new ArrayVarargs(v,r); } } + + /** Construct a {@link Varargs} around an array of {@link LuaValue}s. + * + * @param v The array of {@link LuaValue}s + * @param offset number of initial values to skip in the array + * @param length number of values to include from the array + * @return {@link Varargs} wrapping the supplied values. + * @see LuaValue#varargsOf(LuaValue[]) + * @see LuaValue#varargsOf(LuaValue[], int, int, Varargs) + */ public static Varargs varargsOf(final LuaValue[] v, final int offset, final int length) { switch ( length ) { case 0: return NONE; @@ -488,6 +3400,17 @@ public class LuaValue extends Varargs { default: return new ArrayPartVarargs(v,offset,length); } } + + /** Construct a {@link Varargs} around an array of {@link LuaValue}s. + * + * @param v The array of {@link LuaValue}s + * @param offset number of initial values to skip in the array + * @param length number of values to include from the array + * @param more {@link Varargs} contain values to include at the end + * @return {@link Varargs} wrapping the supplied values. + * @see LuaValue#varargsOf(LuaValue[], Varargs) + * @see LuaValue#varargsOf(LuaValue[], int, int) + */ public static Varargs varargsOf(final LuaValue[] v, final int offset, final int length,Varargs more) { switch ( length ) { case 0: return more; @@ -495,12 +3418,35 @@ public class LuaValue extends Varargs { default: return new ArrayPartVarargs(v,offset,length,more); } } + + /** Construct a {@link Varargs} around a set of 2 or more {@link LuaValue}s. + *

+ * This can be used to wrap exactly 2 values, or a list consisting of 1 initial value + * followed by another variable list of remaining values. + * + * @param v1 First {@link LuaValue} in the {@link Varargs} + * @param v2 {@link LuaValue} supplying the 2rd value, + * or {@link Varargs}s supplying all values beyond the first + * @return {@link Varargs} wrapping the supplied values. + */ public static Varargs varargsOf(LuaValue v, Varargs r) { switch ( r.narg() ) { case 0: return v; default: return new PairVarargs(v,r); } } + + /** Construct a {@link Varargs} around a set of 3 or more {@link LuaValue}s. + *

+ * This can be used to wrap exactly 3 values, or a list consisting of 2 initial values + * followed by another variable list of remaining values. + * + * @param v1 First {@link LuaValue} in the {@link Varargs} + * @param v2 Second {@link LuaValue} in the {@link Varargs} + * @param v3 {@link LuaValue} supplying the 3rd value, + * or {@link Varargs}s supplying all values beyond the second + * @return {@link Varargs} wrapping the supplied values. + */ public static Varargs varargsOf(LuaValue v1,LuaValue v2,Varargs v3) { switch ( v3.narg() ) { case 0: return new PairVarargs(v1,v2); @@ -508,18 +3454,51 @@ public class LuaValue extends Varargs { } } - // tail call support + /** Construct a {@link TailcallVarargs} around a function and arguments. + *

+ * The tail call is not yet called or processing until the client invokes + * {@link TailcallVarargs#eval()} which performs the tail call processing. + *

+ * This method is typically not used directly by client code. + * Instead use one of the function invocation methods. + * + * @param func {@link LuaValue} to be called as a tail call + * @param args {@link Varargs} containing the arguments to the call + * @return {@link TailcallVarargs} to be used in tailcall oprocessing. + * @see LuaValue#call() + * @see LuaValue#invoke() + * @see LuaValue#method(LuaValue) + * @see LuaValue#invokemethod(LuaValue) + */ public static Varargs tailcallOf(LuaValue func, Varargs args) { return new TailcallVarargs(func, args); } - // called by TailcallVarargs to invoke the function once. - // may return TailcallVarargs to be evaluated by the caller. + /** + * Callback used during tail call processing to invoke the function once. + *

+ * This may return a {@link TailcallVarargs} to be evaluated by the client. + *

+ * This should not be called directly, instead use on of the call invocation functions. + * + * @param args the arguments to the call invocation. + * @return Varargs the return values, possible a TailcallVarargs. + * @see LuaValue#call() + * @see LuaValue#invoke() + * @see LuaValue#method(LuaValue) + * @see LuaValue#invokemethod(LuaValue) + */ public Varargs onInvoke(Varargs args) { return invoke(args); } - // empty varargs + /** Varargs implemenation with no values. + *

+ * This is an internal class not intended to be used directly. + * Instead use the predefined constant {@link LuaValue#NONE} + * + * @see LuaValue#NONE + */ private static final class None extends LuaNil { static None _NONE = new None(); public LuaValue arg(int i) { return NIL; } @@ -528,10 +3507,25 @@ public class LuaValue extends Varargs { public String tojstring() { return "none"; } } - // varargs from array + /** Varargs implemenation backed by an array of LuaValues + *

+ * 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. + *

+ * 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 ; @@ -545,18 +3539,39 @@ public class LuaValue extends Varargs { public LuaValue arg1() { return v.length>0? v[0]: r.arg1(); } } - // varargs from array part + /** Varargs implemenation backed by an array of LuaValues + *

+ * 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. + *

+ * 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 = NONE; } + /** Construct a Varargs from an array of LuaValue and additional arguments. + *

+ * 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; @@ -574,10 +3589,23 @@ public class LuaValue extends Varargs { } } - // varargs from two values + /** Varargs implemenation backed by two values. + *

+ * 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. + *

+ * 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;