commonMain.org.luaj.vm2.LuaValue.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of luak Show documentation
Show all versions of luak Show documentation
Multiplatform Kotlin LuaJ port (LUA interpreter)
/*******************************************************************************
* 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
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.luaj.vm2
import org.luaj.vm2.internal.*
import kotlin.jvm.*
import kotlin.reflect.*
/**
* 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 [LuaValue].
*
*
* Constructors are provided as static methods for common Java types, such as
* [LuaValue.valueOf] or [LuaValue.valueOf]
* to allow for instance pooling.
*
*
* Constants are defined for the lua values
* [.NIL], [.TRUE], and [.FALSE].
* A constant [.NONE] is defined which is a [Varargs] list having no values.
*
*
* Operations are performed on values directly via their Java methods.
* For example, the following code divides two numbers:
* `LuaValue a = LuaValue.valueOf( 5 );
* LuaValue b = LuaValue.valueOf( 4 );
* LuaValue c = a.div(b);
` *
* Note that in this example, c will be a [LuaDouble], but would be a [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:
* `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
* [.invoke] or [.invokemethod] methods:
* `LuaValue modf = globals.get("math").get("modf");
* Varargs r = modf.invoke( d );
* print.call( r.arg(1), r.arg(2) );
` *
*
*
* To load and run a script, [LoadState] is used:
* `LoadState.load( new FileInputStream("main.lua"), "main.lua", globals ).call();
` *
*
*
* although `require` could also be used:
* `globals.get("require").call(LuaValue.valueOf("main"));
` *
* For this to work the file must be in the current directory, or in the class path,
* dependening on the platform.
* See [org.luaj.vm2.lib.jse.JsePlatform] and [org.luaj.vm2.lib.jme.JmePlatform] for details.
*
*
* In general a [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.
*
*
* There are several methods for preinitializing tables, such as:
*
* * [.listOf] for unnamed elements
* * [.tableOf] for named elements
* * [.tableOf] for mixtures
*
*
*
* Predefined constants exist for the standard lua type constants
* [.TNIL], [.TBOOLEAN], [.TLIGHTUSERDATA], [.TNUMBER], [.TSTRING],
* [.TTABLE], [.TFUNCTION], [.TUSERDATA], [.TTHREAD],
* and extended lua type constants
* [.TINT], [.TNONE], [.TVALUE]
*
*
* Predefined constants exist for all strings used as metatags:
* [.INDEX], [.NEWINDEX], [.CALL], [.MODE], [.METATABLE],
* [.ADD], [.SUB], [.DIV], [.MUL], [.POW],
* [.MOD], [.UNM], [.LEN], [.EQ], [.LT],
* [.LE], [.TOSTRING], and [.CONCAT].
*
* @see org.luaj.vm2.lib.jse.JsePlatform
*
* @see org.luaj.vm2.lib.jme.JmePlatform
*
* @see LoadState
*
* @see Varargs
*/
abstract class LuaValue : Varargs() {
// type
/** Get the enumeration value for the type of this value.
* @return value for this type, one of
* [.TNIL],
* [.TBOOLEAN],
* [.TNUMBER],
* [.TSTRING],
* [.TTABLE],
* [.TFUNCTION],
* [.TUSERDATA],
* [.TTHREAD]
* @see .typename
*/
abstract fun type(): Int
/** Get the String name of the type of this value.
*
*
*
* @return name from type name list [.TYPE_NAMES]
* corresponding to the type of this value:
* "nil", "boolean", "number", "string",
* "table", "function", "userdata", "thread"
* @see .type
*/
abstract fun typename(): String
/** Check if `this` is a `boolean`
* @return true if this is a `boolean`, otherwise false
* @see .isboolean
* @see .toboolean
* @see .checkboolean
* @see .optboolean
* @see .TBOOLEAN
*/
open fun isboolean(): Boolean {
return false
}
/** Check if `this` is a `function` that is a closure,
* meaning interprets lua bytecode for its execution
* @return true if this is a `closure`, otherwise false
* @see .isfunction
* @see .checkclosure
* @see .optclosure
* @see .TFUNCTION
*/
open fun isclosure(): Boolean {
return false
}
/** Check if `this` is a `function`
* @return true if this is a `function`, otherwise false
* @see .isclosure
* @see .checkfunction
* @see .optfunction
* @see .TFUNCTION
*/
open fun isfunction(): Boolean {
return false
}
/** Check if `this` is a `number` and is representable by java int
* without rounding or truncation
* @return true if this is a `number`
* meaning derives from [LuaNumber]
* or derives from [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
* @see .TNUMBER
*/
open fun isint(): Boolean {
return false
}
/** Check if `this` is a [LuaInteger]
*
*
* No attempt to convert from string will be made by this call.
* @return true if this is a `LuaInteger`,
* otherwise false
* @see .isint
* @see .isnumber
* @see .tonumber
* @see .TNUMBER
*/
open fun isinttype(): Boolean {
return false
}
/** Check if `this` is a `number` and is representable by java long
* without rounding or truncation
* @return true if this is a `number`
* meaning derives from [LuaNumber]
* or derives from [LuaString] and is convertible to a number,
* and can be represented by long,
* otherwise false
* @see .tonumber
* @see .checklong
* @see .optlong
* @see .TNUMBER
*/
open fun islong(): Boolean {
return false
}
/** Check if `this` is `#NIL`
* @return true if this is `#NIL`, otherwise false
* @see .NIL
*
* @see .NONE
*
* @see .checknotnil
* @see .optvalue
* @see Varargs.isnoneornil
* @see .TNIL
*
* @see .TNONE
*/
open fun isnil(): Boolean {
return false
}
/** Check if `this` is a `number`
* @return true if this is a `number`,
* meaning derives from [LuaNumber]
* or derives from [LuaString] and is convertible to a number,
* otherwise false
* @see .tonumber
* @see .checknumber
* @see .optnumber
* @see .TNUMBER
*/
open fun isnumber(): Boolean {
return false
} // may convert from string
/** Check if `this` is a `string`
* @return true if this is a `string`,
* meaning derives from [LuaString] or [LuaNumber],
* otherwise false
* @see .tostring
* @see .checkstring
* @see .optstring
* @see .TSTRING
*/
open fun isstring(): Boolean {
return false
}
/** Check if `this` is a `thread`
* @return true if this is a `thread`, otherwise false
* @see .checkthread
* @see .optthread
* @see .TTHREAD
*/
open fun isthread(): Boolean {
return false
}
/** Check if `this` is a `table`
* @return true if this is a `table`, otherwise false
* @see .checktable
* @see .opttable
* @see .TTABLE
*/
open fun istable(): Boolean {
return false
}
/** Check if `this` is a `userdata`
* @return true if this is a `userdata`, otherwise false
* @see .isuserdata
* @see .touserdata
* @see .checkuserdata
* @see .optuserdata
* @see .TUSERDATA
*/
open fun isuserdata(): Boolean {
return false
}
/** Check if `this` is a `userdata` of type `c`
* @param c Class to test instance against
* @return true if this is a `userdata`
* and the instance is assignable to `c`,
* otherwise false
* @see .isuserdata
* @see .touserdata
* @see .checkuserdata
* @see .optuserdata
* @see .TUSERDATA
*/
open fun isuserdata(c: KClass<*>): Boolean {
return false
}
/** Convert to boolean false if [.NIL] or [.FALSE], true if anything else
* @return Value cast to byte if number or string convertible to number, otherwise 0
* @see .optboolean
* @see .checkboolean
* @see .isboolean
* @see .TBOOLEAN
*/
open fun toboolean(): Boolean {
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 .checknumber
* @see .isnumber
* @see .TNUMBER
*/
open fun tobyte(): Byte {
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 .checknumber
* @see .isnumber
* @see .TNUMBER
*/
open fun tochar(): Char {
return 0.toChar()
}
/** 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
* @see .checknumber
* @see .isnumber
* @see .TNUMBER
*/
open fun todouble(): Double {
return 0.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 .checknumber
* @see .isnumber
* @see .TNUMBER
*/
open fun tofloat(): Float {
return 0f
}
/** 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
* @see .checknumber
* @see .isnumber
* @see .TNUMBER
*/
open fun toint(): Int {
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
* @see .checknumber
* @see .isnumber
* @see .TNUMBER
*/
open fun tolong(): Long {
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 .checknumber
* @see .isnumber
* @see .TNUMBER
*/
open fun toshort(): Short {
return 0
}
/** Convert to human readable String for any type.
* @return String for use by human readers based on type.
* @see .tostring
* @see .optjstring
* @see .checkjstring
* @see .isstring
* @see .TSTRING
*/
override fun tojstring(): String {
return typename() + ": " + hashCode().toHexString()
}
/** Convert to userdata instance, or null.
* @return userdata instance if userdata, or null if not [LuaUserdata]
* @see .optuserdata
* @see .checkuserdata
* @see .isuserdata
* @see .TUSERDATA
*/
open fun touserdata(): Any? {
return null
}
/** Convert to userdata instance if specific type, or null.
* @return userdata instance if is a userdata whose instance derives from `c`,
* or null if not [LuaUserdata]
* @see .optuserdata
* @see .checkuserdata
* @see .isuserdata
* @see .TUSERDATA
*/
open fun touserdata(c: KClass<*>): Any? {
return null
}
/**
* Convert the value to a human readable string using [.tojstring]
* @return String value intended to be human readible.
* @see .tostring
* @see .tojstring
* @see .optstring
* @see .checkstring
* @see .toString
*/
override fun toString(): String {
return tojstring()
}
/** 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 [LuaValue] `this` if it is a number
* or a string convertible to a number,
* and [.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 `this` if it is a [LuaNumber]
* or [LuaString] that can be converted to a number,
* otherwise [.NIL]
* @see .tostring
* @see .optnumber
* @see .checknumber
* @see .toint
* @see .todouble
*/
open fun tonumber(): LuaValue {
return NIL
}
/** Conditionally convert to lua string without throwing errors.
*
*
* In lua all numbers are strings, so this function will return
* the [LuaValue] `this` if it is a string or number,
* and [.NIL] for all other cases.
*
*
* This allows values to be tested for their "string-ness" without
* the penalty of throwing exceptions.
* @return `this` if it is a [LuaString] or [LuaNumber],
* otherwise [.NIL]
* @see .tonumber
* @see .tojstring
* @see .optstring
* @see .checkstring
* @see .toString
*/
open fun tostring(): LuaValue {
return NIL
}
/** Check that optional argument is a boolean and return its boolean value
* @param defval boolean value to return if `this` is nil or none
* @return `this` cast to boolean if a [LuaBoolean],
* `defval` if nil or none,
* throws [LuaError] otherwise
* @com.soywiz.luak.compat.java.Throws LuaError if was not a boolean or nil or none.
* @see .checkboolean
* @see .isboolean
* @see .TBOOLEAN
*/
open fun optboolean(defval: Boolean): Boolean {
argerror("boolean")
}
/** Check that optional argument is a closure and return as [LuaClosure]
*
*
* A [LuaClosure] is a [LuaFunction] that executes lua byteccode.
* @param defval [LuaClosure] to return if `this` is nil or none
* @return `this` cast to [LuaClosure] if a function,
* `defval` if nil or none,
* throws [LuaError] otherwise
* @com.soywiz.luak.compat.java.Throws LuaError if was not a closure or nil or none.
* @see .checkclosure
* @see .isclosure
* @see .TFUNCTION
*/
open fun optclosure(defval: LuaClosure?): LuaClosure? {
argerror("closure")
}
/** Check that optional argument is a number or string convertible to number and return as double
* @param defval double to return if `this` is nil or none
* @return `this` cast to double if numeric,
* `defval` if nil or none,
* throws [LuaError] otherwise
* @com.soywiz.luak.compat.java.Throws LuaError if was not numeric or nil or none.
* @see .optint
* @see .optinteger
* @see .checkdouble
* @see .todouble
* @see .tonumber
* @see .isnumber
* @see .TNUMBER
*/
open fun optdouble(defval: Double): Double {
argerror("double")
}
/** Check that optional argument is a function and return as [LuaFunction]
*
*
* A [LuaFunction] may either be a Java function that implements
* functionality directly in Java, or a [LuaClosure]
* which is a [LuaFunction] that executes lua bytecode.
* @param defval [LuaFunction] to return if `this` is nil or none
* @return `this` cast to [LuaFunction] if a function,
* `defval` if nil or none,
* throws [LuaError] otherwise
* @com.soywiz.luak.compat.java.Throws LuaError if was not a function or nil or none.
* @see .checkfunction
* @see .isfunction
* @see .TFUNCTION
*/
open fun optfunction(defval: LuaFunction?): LuaFunction? {
argerror("function")
}
/** Check that optional argument is a number or string convertible to number and return as int
* @param defval int to return if `this` is nil or none
* @return `this` cast to int if numeric,
* `defval` if nil or none,
* throws [LuaError] otherwise
* @com.soywiz.luak.compat.java.Throws LuaError if was not numeric or nil or none.
* @see .optdouble
* @see .optlong
* @see .optinteger
* @see .checkint
* @see .toint
* @see .tonumber
* @see .isnumber
* @see .TNUMBER
*/
open fun optint(defval: Int): Int {
argerror("int")
}
/** Check that optional argument is a number or string convertible to number and return as [LuaInteger]
* @param defval [LuaInteger] to return if `this` is nil or none
* @return `this` converted and wrapped in [LuaInteger] if numeric,
* `defval` if nil or none,
* throws [LuaError] otherwise
* @com.soywiz.luak.compat.java.Throws LuaError if was not numeric or nil or none.
* @see .optdouble
* @see .optint
* @see .checkint
* @see .toint
* @see .tonumber
* @see .isnumber
* @see .TNUMBER
*/
open fun optinteger(defval: LuaInteger?): LuaInteger? {
argerror("integer")
}
/** Check that optional argument is a number or string convertible to number and return as long
* @param defval long to return if `this` is nil or none
* @return `this` cast to long if numeric,
* `defval` if nil or none,
* throws [LuaError] otherwise
* @com.soywiz.luak.compat.java.Throws LuaError if was not numeric or nil or none.
* @see .optdouble
* @see .optint
* @see .checkint
* @see .toint
* @see .tonumber
* @see .isnumber
* @see .TNUMBER
*/
open fun optlong(defval: Long): Long {
argerror("long")
}
/** Check that optional argument is a number or string convertible to number and return as [LuaNumber]
* @param defval [LuaNumber] to return if `this` is nil or none
* @return `this` cast to [LuaNumber] if numeric,
* `defval` if nil or none,
* throws [LuaError] otherwise
* @com.soywiz.luak.compat.java.Throws LuaError if was not numeric or nil or none.
* @see .optdouble
* @see .optlong
* @see .optint
* @see .checkint
* @see .toint
* @see .tonumber
* @see .isnumber
* @see .TNUMBER
*/
open fun optnumber(defval: LuaNumber?): LuaNumber? {
argerror("number")
}
/** Check that optional argument is a string or number and return as Java String
* @param defval [LuaString] to return if `this` is nil or none
* @return `this` converted to String if a string or number,
* `defval` if nil or none,
* throws [LuaError] if some other type
* @com.soywiz.luak.compat.java.Throws LuaError if was not a string or number or nil or none.
* @see .tojstring
* @see .optstring
* @see .checkjstring
* @see .toString
* @see .TSTRING
*/
open fun optjstring(defval: String?): String? {
argerror("String")
}
/** Check that optional argument is a string or number and return as [LuaString]
* @param defval [LuaString] to return if `this` is nil or none
* @return `this` converted to [LuaString] if a string or number,
* `defval` if nil or none,
* throws [LuaError] if some other type
* @com.soywiz.luak.compat.java.Throws LuaError if was not a string or number or nil or none.
* @see .tojstring
* @see .optjstring
* @see .checkstring
* @see .toString
* @see .TSTRING
*/
open fun optstring(defval: LuaString?): LuaString? {
argerror("string")
}
/** Check that optional argument is a table and return as [LuaTable]
* @param defval [LuaTable] to return if `this` is nil or none
* @return `this` cast to [LuaTable] if a table,
* `defval` if nil or none,
* throws [LuaError] if some other type
* @com.soywiz.luak.compat.java.Throws LuaError if was not a table or nil or none.
* @see .checktable
* @see .istable
* @see .TTABLE
*/
open fun opttable(defval: LuaTable?): LuaTable? {
argerror("table")
}
/** Check that optional argument is a thread and return as [LuaThread]
* @param defval [LuaThread] to return if `this` is nil or none
* @return `this` cast to [LuaTable] if a thread,
* `defval` if nil or none,
* throws [LuaError] if some other type
* @com.soywiz.luak.compat.java.Throws LuaError if was not a thread or nil or none.
* @see .checkthread
* @see .isthread
* @see .TTHREAD
*/
open fun optthread(defval: LuaThread?): LuaThread? {
argerror("thread")
}
/** Check that optional argument is a userdata and return the Object instance
* @param defval Object to return if `this` is nil or none
* @return Object instance of the userdata if a [LuaUserdata],
* `defval` if nil or none,
* throws [LuaError] if some other type
* @com.soywiz.luak.compat.java.Throws LuaError if was not a userdata or nil or none.
* @see .checkuserdata
* @see .isuserdata
* @see .optuserdata
* @see .TUSERDATA
*/
open fun optuserdata(defval: Any?): Any? {
argerror("object")
}
/** 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 `this` is nil or none
* @return Object instance of the userdata if a [LuaUserdata] and instance is assignable to `c`,
* `defval` if nil or none,
* throws [LuaError] if some other type
* @com.soywiz.luak.compat.java.Throws LuaError if was not a userdata whose instance is assignable to `c` or nil or none.
* @see .checkuserdata
* @see .isuserdata
* @see .optuserdata
* @see .TUSERDATA
*/
open fun optuserdata(c: KClass<*>, defval: Any?): Any? {
argerror(c.portableName)
}
/** Perform argument check that this is not nil or none.
* @param defval [LuaValue] to return if `this` is nil or none
* @return `this` if not nil or none, else `defval`
* @see .NIL
*
* @see .NONE
*
* @see .isnil
* @see Varargs.isnoneornil
* @see .TNIL
*
* @see .TNONE
*/
open fun optvalue(defval: LuaValue): LuaValue {
return this
}
/** Check that the value is a [LuaBoolean],
* or throw [LuaError] if not
* @return boolean value for `this` if it is a [LuaBoolean]
* @com.soywiz.luak.compat.java.Throws LuaError if not a [LuaBoolean]
* @see .optboolean
* @see .TBOOLEAN
*/
open fun checkboolean(): Boolean {
argerror("boolean")
}
/** Check that the value is a [LuaClosure] ,
* or throw [LuaError] if not
*
*
* [LuaClosure] is a subclass of [LuaFunction] that interprets lua bytecode.
* @return `this` cast as [LuaClosure]
* @com.soywiz.luak.compat.java.Throws LuaError if not a [LuaClosure]
* @see .checkfunction
* @see .optclosure
* @see .isclosure
* @see .TFUNCTION
*/
open fun checkclosure(): LuaClosure? {
argerror("closure")
}
/** Check that the value is numeric and return the value as a double,
* or throw [LuaError] if not numeric
*
*
* Values that are [LuaNumber] and values that are [LuaString]
* that can be converted to a number will be converted to double.
* @return value cast to a double if numeric
* @com.soywiz.luak.compat.java.Throws LuaError if not a [LuaNumber] or is a [LuaString] that can't be converted to number
* @see .checkint
* @see .checkinteger
* @see .checklong
* @see .optdouble
* @see .TNUMBER
*/
open fun checkdouble(): Double {
argerror("double")
}
/** Check that the value is a function , or throw [LuaError] if not
*
*
* A [LuaFunction] may either be a Java function that implements
* functionality directly in Java, or a [LuaClosure]
* which is a [LuaFunction] that executes lua bytecode.
* @return `this` if it is a lua function or closure
* @com.soywiz.luak.compat.java.Throws LuaError if not a function
* @see .checkclosure
*/
open fun checkfunction(): LuaFunction? {
argerror("function")
}
/** Check that the value is a Globals instance, or throw [LuaError] if not
*
*
* [Globals] are a special [LuaTable] that establish the default global environment.
* @return `this` if if an instance fof [Globals]
* @com.soywiz.luak.compat.java.Throws LuaError if not a [Globals] instance.
*/
open fun checkglobals(): Globals {
argerror("globals")
}
/** Check that the value is numeric, and convert and cast value to int, or throw [LuaError] if not numeric
*
*
* Values that are [LuaNumber] will be cast to int and may lose precision.
* Values that are [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
* @com.soywiz.luak.compat.java.Throws LuaError if not a [LuaNumber] or is a [LuaString] that can't be converted to number
* @see .checkinteger
* @see .checklong
* @see .checkdouble
* @see .optint
* @see .TNUMBER
*/
open fun checkint(): Int {
argerror("int")
}
/** Check that the value is numeric, and convert and cast value to int, or throw [LuaError] if not numeric
*
*
* Values that are [LuaNumber] will be cast to int and may lose precision.
* Values that are [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 [LuaInteger] if numeric
* @com.soywiz.luak.compat.java.Throws LuaError if not a [LuaNumber] or is a [LuaString] that can't be converted to number
* @see .checkint
* @see .checklong
* @see .checkdouble
* @see .optinteger
* @see .TNUMBER
*/
open fun checkinteger(): LuaInteger? {
argerror("integer")
}
/** Check that the value is numeric, and convert and cast value to long, or throw [LuaError] if not numeric
*
*
* Values that are [LuaNumber] will be cast to long and may lose precision.
* Values that are [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
* @com.soywiz.luak.compat.java.Throws LuaError if not a [LuaNumber] or is a [LuaString] that can't be converted to number
* @see .checkint
* @see .checkinteger
* @see .checkdouble
* @see .optlong
* @see .TNUMBER
*/
open fun checklong(): Long {
argerror("long")
}
/** Check that the value is numeric, and return as a LuaNumber if so, or throw [LuaError]
*
*
* Values that are [LuaString] that can be converted to a number will be converted and returned.
* @return value as a [LuaNumber] if numeric
* @com.soywiz.luak.compat.java.Throws LuaError if not a [LuaNumber] or is a [LuaString] that can't be converted to number
* @see .checkint
* @see .checkinteger
* @see .checkdouble
* @see .checklong
* @see .optnumber
* @see .TNUMBER
*/
open fun checknumber(): LuaNumber? {
argerror("number")
}
/** Check that the value is numeric, and return as a LuaNumber if so, or throw [LuaError]
*
*
* Values that are [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 [LuaNumber] if numeric
* @com.soywiz.luak.compat.java.Throws LuaError if not a [LuaNumber] or is a [LuaString] that can't be converted to number
* @see .checkint
* @see .checkinteger
* @see .checkdouble
* @see .checklong
* @see .optnumber
* @see .TNUMBER
*/
open fun checknumber(msg: String): LuaNumber {
throw 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
* @see .tojstring
* @see .isstring
*
* @see .TSTRING
*/
open fun checkjstring(): String? {
argerror("string")
}
/** Check that this is a lua string, or throw [LuaError] if it is not.
*
*
* In lua all numbers are strings, so this will succeed for
* anything that derives from [LuaString] or [LuaNumber].
* Numbers will be converted to [LuaString].
*
* @return [LuaString] representation of the value if it is a [LuaString] or [LuaNumber]
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a [LuaTable]
* @see .checkjstring
* @see .optstring
* @see .tostring
* @see .isstring
* @see .TSTRING
*/
open fun checkstring(): LuaString {
argerror("string")
}
/** Check that this is a [LuaTable], or throw [LuaError] if it is not
* @return `this` if it is a [LuaTable]
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a [LuaTable]
* @see .istable
* @see .opttable
* @see .TTABLE
*/
open fun checktable(): LuaTable? {
argerror("table")
}
/** Check that this is a [LuaThread], or throw [LuaError] if it is not
* @return `this` if it is a [LuaThread]
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a [LuaThread]
* @see .isthread
* @see .optthread
* @see .TTHREAD
*/
open fun checkthread(): LuaThread? {
argerror("thread")
}
/** Check that this is a [LuaUserdata], or throw [LuaError] if it is not
* @return `this` if it is a [LuaUserdata]
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a [LuaUserdata]
* @see .isuserdata
* @see .optuserdata
* @see .checkuserdata
* @see .TUSERDATA
*/
open fun checkuserdata(): Any? {
argerror("userdata")
}
/** Check that this is a [LuaUserdata], or throw [LuaError] if it is not
* @return `this` if it is a [LuaUserdata]
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a [LuaUserdata]
* @see .isuserdata
* @see .optuserdata
* @see .checkuserdata
* @see .TUSERDATA
*/
open fun checkuserdata(c: KClass<*>): Any? {
argerror("userdata")
}
/** Check that this is not the value [.NIL], or throw [LuaError] if it is
* @return `this` if it is not [.NIL]
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is [.NIL]
* @see .optvalue
*/
open fun checknotnil(): LuaValue {
return this
}
/** Return true if this is a valid key in a table index operation.
* @return true if valid as a table key, otherwise false
* @see .isnil
* @see .isinttype
*/
open fun isvalidkey(): Boolean {
return true
}
/**
* Throw a [LuaError] indicating an invalid argument was supplied to a function
* @param expected String naming the type that was expected
* @com.soywiz.luak.compat.java.Throws LuaError in all cases
*/
protected fun argerror(expected: String): Nothing {
throw LuaError("bad argument: " + expected + " expected, got " + typename())
}
/**
* Throw a [LuaError] indicating an invalid type was supplied to a function
* @param expected String naming the type that was expected
* @com.soywiz.luak.compat.java.Throws LuaError in all cases
*/
protected fun typerror(expected: String): Nothing {
throw LuaError("$expected expected, got ${typename()}")
}
/**
* Throw a [LuaError] indicating an operation is not implemented
* @com.soywiz.luak.compat.java.Throws LuaError in all cases
*/
protected fun unimplemented(`fun`: String): Nothing {
throw LuaError("'$`fun`' not implemented for ${typename()}")
}
/**
* Throw a [LuaError] indicating an illegal operation occurred,
* typically involved in managing weak references
* @com.soywiz.luak.compat.java.Throws LuaError in all cases
*/
protected fun illegal(op: String, typename: String): Nothing {
throw LuaError("illegal operation '$op' for $typename")
}
/**
* Throw a [LuaError] based on the len operator,
* typically due to an invalid operand type
* @com.soywiz.luak.compat.java.Throws LuaError in all cases
*/
protected fun lenerror(): Nothing {
throw LuaError("attempt to get length of " + typename())
}
/**
* Throw a [LuaError] based on an arithmetic error such as add, or pow,
* typically due to an invalid operand type
* @com.soywiz.luak.compat.java.Throws LuaError in all cases
*/
protected fun aritherror(): Nothing {
throw LuaError("attempt to perform arithmetic on " + typename())
}
/**
* Throw a [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
* @com.soywiz.luak.compat.java.Throws LuaError in all cases
*/
protected fun aritherror(`fun`: String): Nothing {
throw LuaError("attempt to perform arithmetic '" + `fun` + "' on " + typename())
}
/**
* Throw a [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.
* @com.soywiz.luak.compat.java.Throws LuaError in all cases
*/
protected fun compareerror(rhs: String): Nothing {
throw LuaError("attempt to compare " + typename() + " with " + rhs)
}
/**
* Throw a [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.
* @com.soywiz.luak.compat.java.Throws LuaError in all cases
*/
protected fun compareerror(rhs: LuaValue): Nothing {
throw LuaError("attempt to compare " + typename() + " with " + rhs.typename())
}
/** Get a value in a table including metatag processing using [.INDEX].
* @param key the key to look up, must not be [.NIL] or null
* @return [LuaValue] for that key, or [.NIL] if not found and no metatag
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table,
* or there is no [.INDEX] metatag,
* or key is [.NIL]
* @see .get
* @see .get
* @see .rawget
*/
open operator fun get(key: LuaValue): LuaValue {
return gettable(this, key)
}
/** Get a value in a table including metatag processing using [.INDEX].
* @param key the key to look up
* @return [LuaValue] for that key, or [.NIL] if not found
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table,
* or there is no [.INDEX] metatag
* @see .get
* @see .rawget
*/
open operator fun get(key: Int): LuaValue {
return get(LuaInteger.valueOf(key))
}
/** Get a value in a table including metatag processing using [.INDEX].
* @param key the key to look up, must not be null
* @return [LuaValue] for that key, or [.NIL] if not found
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table,
* or there is no [.INDEX] metatag
* @see .get
* @see .rawget
*/
operator fun get(key: String): LuaValue {
return get(valueOf(key))
}
/** Set a value in a table without metatag processing using [.NEWINDEX].
* @param key the key to use, must not be [.NIL] or null
* @param value the value to use, can be [.NIL], must not be null
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table,
* or key is [.NIL],
* or there is no [.NEWINDEX] metatag
*/
open operator fun set(key: LuaValue, value: LuaValue) {
settable(this, key, value)
}
/** Set a value in a table without metatag processing using [.NEWINDEX].
* @param key the key to use
* @param value the value to use, can be [.NIL], must not be null
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table,
* or there is no [.NEWINDEX] metatag
*/
open operator fun set(key: Int, value: LuaValue) {
set(LuaInteger.valueOf(key), value)
}
/** Set a value in a table without metatag processing using [.NEWINDEX].
* @param key the key to use
* @param value the value to use, must not be null
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table,
* or there is no [.NEWINDEX] metatag
*/
operator fun set(key: Int, value: String) {
set(key, valueOf(value))
}
/** Set a value in a table without metatag processing using [.NEWINDEX].
* @param key the key to use, must not be [.NIL] or null
* @param value the value to use, can be [.NIL], must not be null
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table,
* or there is no [.NEWINDEX] metatag
*/
operator fun set(key: String, value: LuaValue) {
set(valueOf(key), value)
}
/** Set a value in a table without metatag processing using [.NEWINDEX].
* @param key the key to use, must not be null
* @param value the value to use
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table,
* or there is no [.NEWINDEX] metatag
*/
operator fun set(key: String, value: Double) {
set(valueOf(key), valueOf(value))
}
/** Set a value in a table without metatag processing using [.NEWINDEX].
* @param key the key to use, must not be null
* @param value the value to use
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table,
* or there is no [.NEWINDEX] metatag
*/
operator fun set(key: String, value: Int) {
set(valueOf(key), valueOf(value))
}
/** Set a value in a table without metatag processing using [.NEWINDEX].
* @param key the key to use, must not be null
* @param value the value to use, must not be null
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table,
* or there is no [.NEWINDEX] metatag
*/
operator fun set(key: String, value: String) {
set(valueOf(key), valueOf(value))
}
/** Get a value in a table without metatag processing.
* @param key the key to look up, must not be [.NIL] or null
* @return [LuaValue] for that key, or [.NIL] if not found
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table, or key is [.NIL]
*/
open fun rawget(key: LuaValue): LuaValue {
return unimplemented("rawget")
}
/** Get a value in a table without metatag processing.
* @param key the key to look up
* @return [LuaValue] for that key, or [.NIL] if not found
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table
*/
open fun rawget(key: Int): LuaValue {
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 [LuaValue] for that key, or [.NIL] if not found
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table
*/
fun rawget(key: String): LuaValue {
return rawget(valueOf(key))
}
/** Set a value in a table without metatag processing.
* @param key the key to use, must not be [.NIL] or null
* @param value the value to use, can be [.NIL], must not be null
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table, or key is [.NIL]
*/
open fun rawset(key: LuaValue, value: LuaValue) {
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 [.NIL], must not be null
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table
*/
open fun rawset(key: Int, value: LuaValue) {
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 [.NIL], must not be null
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table
*/
fun rawset(key: Int, value: String) {
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 [.NIL], must not be null
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table
*/
fun rawset(key: String, value: LuaValue) {
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
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table
*/
fun rawset(key: String, value: Double) {
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
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table
*/
fun rawset(key: String, value: Int) {
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
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table
*/
fun rawset(key: String, value: String) {
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
* @com.soywiz.luak.compat.java.Throws LuaError if this is not a table.
*/
fun rawsetlist(key0: Int, values: Varargs) {
var i = 0
val n = values.narg()
while (i < n) {
rawset(key0 + i, values.arg(i + 1))
i++
}
}
/** Preallocate the array part of a table to be a certain size,
*
*
* Primarily used internally in response to a SETLIST bytecode.
* @param i the number of array slots to preallocate in the table.
* @com.soywiz.luak.compat.java.Throws LuaError if this is not a table.
*/
open fun presize(i: Int) {
typerror("table")
}
/** Find the next key,value pair if `this` is a table,
* return [.NIL] if there are no more, or throw a [LuaError] if not a table.
*
*
* To iterate over all key-value pairs in a table you can use
* `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 [LuaInteger] value identifying a key to start from,
* or [.NIL] to start at the beginning
* @return [Varargs] containing {key,value} for the next entry,
* or [.NIL] if there are no more.
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table, or the supplied key is invalid.
* @see LuaTable
*
* @see .inext
* @see .valueOf
* @see Varargs.arg1
* @see Varargs.arg
* @see .isnil
*/
open fun next(index: LuaValue): Varargs {
return typerror("table")
}
/** Find the next integer-key,value pair if `this` is a table,
* return [.NIL] if there are no more, or throw a [LuaError] if not a table.
*
*
* To iterate over integer keys in a table you can use
* `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 [LuaInteger] value identifying a key to start from,
* or [.NIL] to start at the beginning
* @return [Varargs] containing `(key,value)` for the next entry,
* or [.NONE] if there are no more.
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table, or the supplied key is invalid.
* @see LuaTable
*
* @see .next
* @see .valueOf
* @see Varargs.arg1
* @see Varargs.arg
* @see .isnil
*/
open fun inext(index: LuaValue): Varargs {
return typerror("table")
}
/**
* Load a library instance by calling it with and empty string as the modname,
* and this Globals as the environment. This is normally used to iniitalize the
* library instance and which may install itself into these globals.
* @param library The callable [LuaValue] to load into `this`
* @return [LuaValue] returned by the initialization call.
*/
fun load(library: LuaValue): LuaValue {
return library.call(EMPTYSTRING, this)
}
// varargs references
override fun arg(index: Int): LuaValue {
return if (index == 1) this else NIL
}
override fun narg(): Int {
return 1
}
override fun arg1(): LuaValue {
return this
}
/**
* Get the metatable for this [LuaValue]
*
*
* For [LuaTable] and [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
*/
open fun getmetatable(): LuaValue? {
return null
}
/**
* Set the metatable for this [LuaValue]
*
*
* For [LuaTable] and [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 [LuaValue] instance to serve as the metatable, or null to reset it.
* @return `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
*/
open fun setmetatable(metatable: LuaValue?): LuaValue {
return argerror("table")
}
/** Call `this` with 0 arguments, including metatag processing,
* and return only the first return value.
*
*
* If `this` is a [LuaFunction], call it,
* and return only its first return value, dropping any others.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* If the return value is a [Varargs], only the 1st value will be returned.
* To get multiple values, use [.invoke] instead.
*
*
* To call `this` as a method call, use [.method] instead.
*
* @return First return value `(this())`, or [.NIL] if there were none.
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .call
* @see .call
* @see .call
* @see .invoke
* @see .method
* @see .method
*/
open fun call(): LuaValue {
return callmt().call(this)
}
/** Call `this` with 1 argument, including metatag processing,
* and return only the first return value.
*
*
* If `this` is a [LuaFunction], call it,
* and return only its first return value, dropping any others.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* If the return value is a [Varargs], only the 1st value will be returned.
* To get multiple values, use [.invoke] instead.
*
*
* To call `this` as a method call, use [.method] instead.
*
* @param arg First argument to supply to the called function
* @return First return value `(this(arg))`, or [.NIL] if there were none.
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .call
* @see .call
* @see .call
* @see .invoke
* @see .method
* @see .method
*/
open fun call(arg: LuaValue): LuaValue {
return callmt().call(this, arg)
}
/** Convenience function which calls a luavalue with a single, string argument.
* @param arg String argument to the function. This will be converted to a LuaString.
* @return return value of the invocation.
* @see .call
*/
fun call(arg: String): LuaValue {
return call(valueOf(arg))
}
/** Call `this` with 2 arguments, including metatag processing,
* and return only the first return value.
*
*
* If `this` is a [LuaFunction], call it,
* and return only its first return value, dropping any others.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* If the return value is a [Varargs], only the 1st value will be returned.
* To get multiple values, use [.invoke] instead.
*
*
* To call `this` as a method call, use [.method] 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 `(this(arg1,arg2))`, or [.NIL] if there were none.
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .call
* @see .call
* @see .call
* @see .invoke
* @see .method
* @see .method
*/
open fun call(arg1: LuaValue, arg2: LuaValue): LuaValue {
return callmt().call(this, arg1, arg2)
}
/** Call `this` with 3 arguments, including metatag processing,
* and return only the first return value.
*
*
* If `this` is a [LuaFunction], call it,
* and return only its first return value, dropping any others.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* If the return value is a [Varargs], only the 1st value will be returned.
* To get multiple values, use [.invoke] instead.
*
*
* To call `this` as a method call, use [.method] 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 `(this(arg1,arg2,arg3))`, or [.NIL] if there were none.
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .call
* @see .call
* @see .call
* @see .invoke
* @see .invokemethod
* @see .invokemethod
*/
open fun call(arg1: LuaValue, arg2: LuaValue, arg3: LuaValue): LuaValue {
return callmt().invoke(arrayOf(this, arg1, arg2, arg3)).arg1()
}
/** Call named method on `this` with 0 arguments, including metatag processing,
* and return only the first return value.
*
*
* Look up `this[name]` and if it is a [LuaFunction],
* call it inserting `this` as an additional first argument.
* and return only its first return value, dropping any others.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* If the return value is a [Varargs], only the 1st value will be returned.
* To get multiple values, use [.invoke] instead.
*
*
* To call `this` as a plain call, use [.call] instead.
*
* @param name Name of the method to look up for invocation
* @return All values returned from `this:name()` as a [Varargs] instance
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .call
* @see .invoke
* @see .method
* @see .method
* @see .method
*/
fun method(name: String): LuaValue {
return this[name].call(this)
}
/** Call named method on `this` with 0 arguments, including metatag processing,
* and return only the first return value.
*
*
* Look up `this[name]` and if it is a [LuaFunction],
* call it inserting `this` as an additional first argument,
* and return only its first return value, dropping any others.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* If the return value is a [Varargs], only the 1st value will be returned.
* To get multiple values, use [.invoke] instead.
*
*
* To call `this` as a plain call, use [.call] instead.
*
* @param name Name of the method to look up for invocation
* @return All values returned from `this:name()` as a [Varargs] instance
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .call
* @see .invoke
* @see .method
* @see .method
* @see .method
*/
fun method(name: LuaValue): LuaValue {
return this[name].call(this)
}
/** Call named method on `this` with 1 argument, including metatag processing,
* and return only the first return value.
*
*
* Look up `this[name]` and if it is a [LuaFunction],
* call it inserting `this` as an additional first argument,
* and return only its first return value, dropping any others.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* If the return value is a [Varargs], only the 1st value will be returned.
* To get multiple values, use [.invoke] instead.
*
*
* To call `this` as a plain call, use [.call] 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 `this:name(arg)` as a [Varargs] instance
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .call
* @see .invoke
* @see .method
* @see .method
* @see .method
*/
fun method(name: String, arg: LuaValue): LuaValue {
return this[name].call(this, arg)
}
/** Call named method on `this` with 1 argument, including metatag processing,
* and return only the first return value.
*
*
* Look up `this[name]` and if it is a [LuaFunction],
* call it inserting `this` as an additional first argument,
* and return only its first return value, dropping any others.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* If the return value is a [Varargs], only the 1st value will be returned.
* To get multiple values, use [.invoke] instead.
*
*
* To call `this` as a plain call, use [.call] 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 `this:name(arg)` as a [Varargs] instance
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .call
* @see .invoke
* @see .method
* @see .method
* @see .method
*/
fun method(name: LuaValue, arg: LuaValue): LuaValue {
return this[name].call(this, arg)
}
/** Call named method on `this` with 2 arguments, including metatag processing,
* and return only the first return value.
*
*
* Look up `this[name]` and if it is a [LuaFunction],
* call it inserting `this` as an additional first argument,
* and return only its first return value, dropping any others.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* If the return value is a [Varargs], only the 1st value will be returned.
* To get multiple values, use [.invoke] instead.
*
*
* To call `this` as a plain call, use [.call] 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 `this:name(arg1,arg2)` as a [Varargs] instance
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .call
* @see .invoke
* @see .method
* @see .method
*/
fun method(name: String, arg1: LuaValue, arg2: LuaValue): LuaValue {
return this[name].call(this, arg1, arg2)
}
/** Call named method on `this` with 2 arguments, including metatag processing,
* and return only the first return value.
*
*
* Look up `this[name]` and if it is a [LuaFunction],
* call it inserting `this` as an additional first argument,
* and return only its first return value, dropping any others.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* If the return value is a [Varargs], only the 1st value will be returned.
* To get multiple values, use [.invoke] instead.
*
*
* To call `this` as a plain call, use [.call] 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 `this:name(arg1,arg2)` as a [Varargs] instance
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .call
* @see .invoke
* @see .method
* @see .method
*/
fun method(name: LuaValue, arg1: LuaValue, arg2: LuaValue): LuaValue {
return this[name].call(this, arg1, arg2)
}
/** Call `this` with 0 arguments, including metatag processing,
* and retain all return values in a [Varargs].
*
*
* If `this` is a [LuaFunction], call it, and return all values.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* To get a particular return value, us [Varargs.arg]
*
*
* To call `this` as a method call, use [.invokemethod] instead.
*
* @return All return values as a [Varargs] instance.
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .call
* @see .invoke
* @see .invokemethod
* @see .invokemethod
*/
operator fun invoke(): Varargs {
return invoke(NONE)
}
/** Call `this` with variable arguments, including metatag processing,
* and retain all return values in a [Varargs].
*
*
* If `this` is a [LuaFunction], call it, and return all values.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* To get a particular return value, us [Varargs.arg]
*
*
* To call `this` as a method call, use [.invokemethod] instead.
*
* @param args Varargs containing the arguments to supply to the called function
* @return All return values as a [Varargs] instance.
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .varargsOf
* @see .call
* @see .invoke
* @see .invoke
* @see .invokemethod
* @see .invokemethod
*/
open operator fun invoke(args: Varargs): Varargs {
return callmt().invoke(this, args)
}
/** Call `this` with variable arguments, including metatag processing,
* and retain all return values in a [Varargs].
*
*
* If `this` is a [LuaFunction], call it, and return all values.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* To get a particular return value, us [Varargs.arg]
*
*
* To call `this` as a method call, use [.invokemethod] 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 [Varargs] instance.
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .varargsOf
* @see .call
* @see .invoke
* @see .invokemethod
* @see .invokemethod
*/
operator fun invoke(arg: LuaValue, varargs: Varargs): Varargs {
return invoke(varargsOf(arg, varargs))
}
/** Call `this` with variable arguments, including metatag processing,
* and retain all return values in a [Varargs].
*
*
* If `this` is a [LuaFunction], call it, and return all values.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* To get a particular return value, us [Varargs.arg]
*
*
* To call `this` as a method call, use [.invokemethod] 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 [Varargs] instance.
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .varargsOf
* @see .call
* @see .invoke
* @see .invokemethod
* @see .invokemethod
*/
operator fun invoke(arg1: LuaValue, arg2: LuaValue, varargs: Varargs): Varargs {
return invoke(varargsOf(arg1, arg2, varargs))
}
/** Call `this` with variable arguments, including metatag processing,
* and retain all return values in a [Varargs].
*
*
* If `this` is a [LuaFunction], call it, and return all values.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* To get a particular return value, us [Varargs.arg]
*
*
* To call `this` as a method call, use [.invokemethod] instead.
*
* @param args Array of arguments to supply to the called function
* @return All return values as a [Varargs] instance.
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .varargsOf
* @see .call
* @see .invoke
* @see .invokemethod
* @see .invokemethod
*/
operator fun invoke(args: Array): Varargs {
return invoke(varargsOf(args))
}
/** Call `this` with variable arguments, including metatag processing,
* and retain all return values in a [Varargs].
*
*
* If `this` is a [LuaFunction], call it, and return all values.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* To get a particular return value, us [Varargs.arg]
*
*
* To call `this` as a method call, use [.invokemethod] 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 [Varargs] instance.
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .varargsOf
* @see .call
* @see .invoke
* @see .invokemethod
* @see .invokemethod
* @see .invokemethod
* @see .invokemethod
*/
operator fun invoke(args: Array, varargs: Varargs): Varargs {
return invoke(varargsOf(args, varargs))
}
/** Call named method on `this` with 0 arguments, including metatag processing,
* and retain all return values in a [Varargs].
*
*
* Look up `this[name]` and if it is a [LuaFunction],
* call it inserting `this` as an additional first argument,
* and return all return values as a [Varargs] instance.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* To get a particular return value, us [Varargs.arg]
*
*
* To call `this` as a plain call, use [.invoke] instead.
*
* @param name Name of the method to look up for invocation
* @return All values returned from `this:name()` as a [Varargs] instance
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .call
* @see .invoke
* @see .method
* @see .invokemethod
* @see .invokemethod
* @see .invokemethod
* @see .invokemethod
* @see .invokemethod
*/
fun invokemethod(name: String): Varargs {
return get(name).invoke(this)
}
/** Call named method on `this` with 0 arguments, including metatag processing,
* and retain all return values in a [Varargs].
*
*
* Look up `this[name]` and if it is a [LuaFunction],
* call it inserting `this` as an additional first argument,
* and return all return values as a [Varargs] instance.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* To get a particular return value, us [Varargs.arg]
*
*
* To call `this` as a plain call, use [.invoke] instead.
*
* @param name Name of the method to look up for invocation
* @return All values returned from `this:name()` as a [Varargs] instance
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .call
* @see .invoke
* @see .method
* @see .invokemethod
* @see .invokemethod
* @see .invokemethod
* @see .invokemethod
* @see .invokemethod
*/
fun invokemethod(name: LuaValue): Varargs {
return get(name).invoke(this)
}
/** Call named method on `this` with 1 argument, including metatag processing,
* and retain all return values in a [Varargs].
*
*
* Look up `this[name]` and if it is a [LuaFunction],
* call it inserting `this` as an additional first argument,
* and return all return values as a [Varargs] instance.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* To get a particular return value, us [Varargs.arg]
*
*
* To call `this` as a plain call, use [.invoke] instead.
*
* @param name Name of the method to look up for invocation
* @param args [Varargs] containing arguments to supply to the called function after `this`
* @return All values returned from `this:name(args)` as a [Varargs] instance
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .call
* @see .invoke
* @see .method
* @see .invokemethod
* @see .invokemethod
* @see .invokemethod
* @see .invokemethod
* @see .invokemethod
*/
fun invokemethod(name: String, args: Varargs): Varargs {
return get(name).invoke(varargsOf(this, args))
}
/** Call named method on `this` with variable arguments, including metatag processing,
* and retain all return values in a [Varargs].
*
*
* Look up `this[name]` and if it is a [LuaFunction],
* call it inserting `this` as an additional first argument,
* and return all return values as a [Varargs] instance.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* To get a particular return value, us [Varargs.arg]
*
*
* To call `this` as a plain call, use [.invoke] instead.
*
* @param name Name of the method to look up for invocation
* @param args [Varargs] containing arguments to supply to the called function after `this`
* @return All values returned from `this:name(args)` as a [Varargs] instance
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .call
* @see .invoke
* @see .method
* @see .invokemethod
* @see .invokemethod
* @see .invokemethod
* @see .invokemethod
* @see .invokemethod
*/
fun invokemethod(name: LuaValue, args: Varargs): Varargs {
return get(name).invoke(varargsOf(this, args))
}
/** Call named method on `this` with 1 argument, including metatag processing,
* and retain all return values in a [Varargs].
*
*
* Look up `this[name]` and if it is a [LuaFunction],
* call it inserting `this` as an additional first argument,
* and return all return values as a [Varargs] instance.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* To get a particular return value, us [Varargs.arg]
*
*
* To call `this` as a plain call, use [.invoke] instead.
*
* @param name Name of the method to look up for invocation
* @param args Array of [LuaValue] containing arguments to supply to the called function after `this`
* @return All values returned from `this:name(args)` as a [Varargs] instance
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .call
* @see .invoke
* @see .method
* @see .invokemethod
* @see .invokemethod
* @see .invokemethod
* @see .invokemethod
* @see .invokemethod
* @see LuaValue.varargsOf
*/
fun invokemethod(name: String, args: Array): Varargs {
return get(name).invoke(varargsOf(this, varargsOf(args)))
}
/** Call named method on `this` with variable arguments, including metatag processing,
* and retain all return values in a [Varargs].
*
*
* Look up `this[name]` and if it is a [LuaFunction],
* call it inserting `this` as an additional first argument,
* and return all return values as a [Varargs] instance.
* Otherwise, look for the [.CALL] metatag and call that.
*
*
* To get a particular return value, us [Varargs.arg]
*
*
* To call `this` as a plain call, use [.invoke] instead.
*
* @param name Name of the method to look up for invocation
* @param args Array of [LuaValue] containing arguments to supply to the called function after `this`
* @return All values returned from `this:name(args)` as a [Varargs] instance
* @com.soywiz.luak.compat.java.Throws LuaError if not a function and [.CALL] is not defined,
* or the invoked function throws a [LuaError]
* or the invoked closure throw a lua `error`
* @see .call
* @see .invoke
* @see .method
* @see .invokemethod
* @see .invokemethod
* @see .invokemethod
* @see .invokemethod
* @see .invokemethod
* @see LuaValue.varargsOf
*/
fun invokemethod(name: LuaValue, args: Array): Varargs {
return get(name).invoke(varargsOf(this, varargsOf(args)))
}
/**
* Get the metatag value for the [.CALL] metatag, if it exists.
* @return [LuaValue] value if metatag is defined
* @com.soywiz.luak.compat.java.Throws LuaError if [.CALL] metatag is not defined.
*/
protected fun callmt(): LuaValue {
return checkmetatag(CALL, "attempt to call ")
}
/** Unary not: return inverse boolean value `(~this)` as defined by lua not operator
* @return [.TRUE] if [.NIL] or [.FALSE], otherwise [.FALSE]
*/
open operator fun not(): LuaValue {
return FALSE
}
/** Unary minus: return negative value `(-this)` as defined by lua unary minus operator
* @return boolean inverse as [LuaBoolean] if boolean or nil,
* numeric inverse as [LuaNumber] if numeric,
* or metatag processing result if [.UNM] metatag is defined
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table or string, and has no [.UNM] metatag
*/
open fun neg(): LuaValue {
return checkmetatag(UNM, "attempt to perform arithmetic on ").call(this)
}
/** Length operator: return lua length of object `(#this)` including metatag processing as java int
* @return length as defined by the lua # operator
* or metatag processing result
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table or string, and has no [.LEN] metatag
*/
open fun len(): LuaValue {
return checkmetatag(LEN, "attempt to get length of ").call(this)
}
/** Length operator: return lua length of object `(#this)` including metatag processing as java int
* @return length as defined by the lua # operator
* or metatag processing result converted to java int using [.toint]
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table or string, and has no [.LEN] metatag
*/
open fun length(): Int {
return len().toint()
}
/** Get raw length of table or string without metatag processing.
* @return the length of the table or string.
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a table or string.
*/
open fun rawlen(): Int {
typerror("table or string")
return 0
}
// object equality, used for key comparison
override fun equals(obj: Any?): Boolean {
return this === obj
}
/** Equals: Perform equality comparison with another value
* including metatag processing using [.EQ].
* @param val The value to compare with.
* @return [.TRUE] if values are comparable and `(this == rhs)`,
* [.FALSE] if comparable but not equal,
* [LuaValue] if metatag processing occurs.
* @see .eq_b
* @see .raweq
* @see .neq
* @see .eqmtcall
* @see .EQ
*/
open fun eq(`val`: LuaValue): LuaValue {
return if (this === `val`) TRUE else FALSE
}
/** Equals: Perform equality comparison with another value
* including metatag processing using [.EQ],
* and return java boolean
* @param val The value to compare with.
* @return true if values are comparable and `(this == rhs)`,
* false if comparable but not equal,
* result converted to java boolean if metatag processing occurs.
* @see .eq
* @see .raweq
* @see .neq_b
* @see .eqmtcall
* @see .EQ
*/
open fun eq_b(`val`: LuaValue): Boolean = this === `val`
/** Notquals: Perform inequality comparison with another value
* including metatag processing using [.EQ].
* @param val The value to compare with.
* @return [.TRUE] if values are comparable and `(this != rhs)`,
* [.FALSE] if comparable but equal,
* inverse of [LuaValue] converted to [LuaBoolean] if metatag processing occurs.
* @see .eq
* @see .raweq
* @see .eqmtcall
* @see .EQ
*/
fun neq(`val`: LuaValue): LuaValue = if (eq_b(`val`)) FALSE else TRUE
/** Notquals: Perform inequality comparison with another value
* including metatag processing using [.EQ].
* @param val The value to compare with.
* @return true if values are comparable and `(this != rhs)`,
* false if comparable but equal,
* inverse of result converted to boolean if metatag processing occurs.
* @see .eq_b
* @see .raweq
* @see .eqmtcall
* @see .EQ
*/
fun neq_b(`val`: LuaValue): Boolean {
return !eq_b(`val`)
}
/** Equals: Perform direct equality comparison with another value
* without metatag processing.
* @param val The value to compare with.
* @return true if `(this == rhs)`, false otherwise
* @see .eq
* @see .raweq
* @see .raweq
* @see .raweq
* @see .raweq
* @see .EQ
*/
open fun raweq(`val`: LuaValue): Boolean {
return this === `val`
}
/** Equals: Perform direct equality comparison with a [LuaUserdata] value
* without metatag processing.
* @param val The [LuaUserdata] to compare with.
* @return true if `this` is userdata
* and their metatables are the same using ==
* and their instances are equal using [.equals],
* otherwise false
* @see .eq
* @see .raweq
*/
open fun raweq(`val`: LuaUserdata): Boolean {
return false
}
/** Equals: Perform direct equality comparison with a [LuaString] value
* without metatag processing.
* @param val The [LuaString] to compare with.
* @return true if `this` is a [LuaString]
* and their byte sequences match,
* otherwise false
*/
open fun raweq(`val`: LuaString): Boolean {
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 `this` is a [LuaNumber]
* whose value equals val,
* otherwise false
*/
open fun raweq(`val`: Double): Boolean {
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 `this` is a [LuaNumber]
* whose value equals val,
* otherwise false
*/
open fun raweq(`val`: Int): Boolean {
return false
}
/** Add: Perform numeric add operation with another value
* including metatag processing.
*
*
* Each operand must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
* @param rhs The right-hand-side value to perform the add with
* @return value of `(this + rhs)` if both are numeric,
* or [LuaValue] if metatag processing occurs
* @com.soywiz.luak.compat.java.Throws LuaError if either operand is not a number or string convertible to number,
* and neither has the [.ADD] metatag defined
* @see .arithmt
*/
open fun add(rhs: LuaValue): LuaValue {
return arithmt(ADD, rhs)
}
/** Add: Perform numeric add operation with another value
* of double type with metatag processing
*
*
* `this` must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
* @param rhs The right-hand-side value to perform the add with
* @return value of `(this + rhs)` if this is numeric
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a number or string convertible to number
* @see .add
*/
open fun add(rhs: Double): LuaValue {
return arithmtwith(ADD, rhs)
}
/** Add: Perform numeric add operation with another value
* of int type with metatag processing
*
*
* `this` must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
* @param rhs The right-hand-side value to perform the add with
* @return value of `(this + rhs)` if this is numeric
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a number or string convertible to number
* @see .add
*/
open fun add(rhs: Int): LuaValue {
return add(rhs.toDouble())
}
/** Subtract: Perform numeric subtract operation with another value
* of unknown type,
* including metatag processing.
*
*
* Each operand must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
* @param rhs The right-hand-side value to perform the subtract with
* @return value of `(this - rhs)` if both are numeric,
* or [LuaValue] if metatag processing occurs
* @com.soywiz.luak.compat.java.Throws LuaError if either operand is not a number or string convertible to number,
* and neither has the [.SUB] metatag defined
* @see .arithmt
*/
open fun sub(rhs: LuaValue): LuaValue {
return arithmt(SUB, rhs)
}
/** Subtract: Perform numeric subtract operation with another value
* of double type with metatag processing
*
*
* `this` must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
* @param rhs The right-hand-side value to perform the subtract with
* @return value of `(this - rhs)` if this is numeric
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a number or string convertible to number
* @see .sub
*/
open fun sub(rhs: Double): LuaValue {
return aritherror("sub")
}
/** Subtract: Perform numeric subtract operation with another value
* of int type with metatag processing
*
*
* `this` must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
* @param rhs The right-hand-side value to perform the subtract with
* @return value of `(this - rhs)` if this is numeric
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a number or string convertible to number
* @see .sub
*/
open fun sub(rhs: Int): LuaValue {
return aritherror("sub")
}
/** Reverse-subtract: Perform numeric subtract operation from an int value
* with metatag processing
*
*
* `this` must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
* @param lhs The left-hand-side value from which to perform the subtraction
* @return value of `(lhs - this)` if this is numeric
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a number or string convertible to number
* @see .sub
* @see .sub
* @see .sub
*/
open fun subFrom(lhs: Double): LuaValue {
return arithmtwith(SUB, lhs)
}
/** Reverse-subtract: Perform numeric subtract operation from a double value
* without metatag processing
*
*
* `this` must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
*
* For metatag processing [.sub] must be used
*
* @param lhs The left-hand-side value from which to perform the subtraction
* @return value of `(lhs - this)` if this is numeric
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a number or string convertible to number
* @see .sub
* @see .sub
* @see .sub
*/
open fun subFrom(lhs: Int): LuaValue {
return subFrom(lhs.toDouble())
}
/** Multiply: Perform numeric multiply operation with another value
* of unknown type,
* including metatag processing.
*
*
* Each operand must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
* @param rhs The right-hand-side value to perform the multiply with
* @return value of `(this * rhs)` if both are numeric,
* or [LuaValue] if metatag processing occurs
* @com.soywiz.luak.compat.java.Throws LuaError if either operand is not a number or string convertible to number,
* and neither has the [.MUL] metatag defined
* @see .arithmt
*/
open fun mul(rhs: LuaValue): LuaValue {
return arithmt(MUL, rhs)
}
/** Multiply: Perform numeric multiply operation with another value
* of double type with metatag processing
*
*
* `this` must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
* @param rhs The right-hand-side value to perform the multiply with
* @return value of `(this * rhs)` if this is numeric
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a number or string convertible to number
* @see .mul
*/
open fun mul(rhs: Double): LuaValue {
return arithmtwith(MUL, rhs)
}
/** Multiply: Perform numeric multiply operation with another value
* of int type with metatag processing
*
*
* `this` must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
* @param rhs The right-hand-side value to perform the multiply with
* @return value of `(this * rhs)` if this is numeric
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a number or string convertible to number
* @see .mul
*/
open fun mul(rhs: Int): LuaValue {
return mul(rhs.toDouble())
}
/** Raise to power: Raise this value to a power
* including metatag processing.
*
*
* Each operand must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
* @param rhs The power to raise this value to
* @return value of `(this ^ rhs)` if both are numeric,
* or [LuaValue] if metatag processing occurs
* @com.soywiz.luak.compat.java.Throws LuaError if either operand is not a number or string convertible to number,
* and neither has the [.POW] metatag defined
* @see .arithmt
*/
open fun pow(rhs: LuaValue): LuaValue {
return arithmt(POW, rhs)
}
/** Raise to power: Raise this value to a power
* of double type with metatag processing
*
*
* `this` must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
* @param rhs The power to raise this value to
* @return value of `(this ^ rhs)` if this is numeric
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a number or string convertible to number
* @see .pow
*/
open fun pow(rhs: Double): LuaValue {
return aritherror("pow")
}
/** Raise to power: Raise this value to a power
* of int type with metatag processing
*
*
* `this` must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
* @param rhs The power to raise this value to
* @return value of `(this ^ rhs)` if this is numeric
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a number or string convertible to number
* @see .pow
*/
open fun pow(rhs: Int): LuaValue {
return aritherror("pow")
}
/** Reverse-raise to power: Raise another value of double type to this power
* with metatag processing
*
*
* `this` must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
* @param lhs The left-hand-side value which will be raised to this power
* @return value of `(lhs ^ this)` if this is numeric
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a number or string convertible to number
* @see .pow
* @see .pow
* @see .pow
*/
open fun powWith(lhs: Double): LuaValue {
return arithmtwith(POW, lhs)
}
/** Reverse-raise to power: Raise another value of double type to this power
* with metatag processing
*
*
* `this` must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
* @param lhs The left-hand-side value which will be raised to this power
* @return value of `(lhs ^ this)` if this is numeric
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a number or string convertible to number
* @see .pow
* @see .pow
* @see .pow
*/
open fun powWith(lhs: Int): LuaValue {
return powWith(lhs.toDouble())
}
/** Divide: Perform numeric divide operation by another value
* of unknown type,
* including metatag processing.
*
*
* Each operand must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
* @param rhs The right-hand-side value to perform the divulo with
* @return value of `(this / rhs)` if both are numeric,
* or [LuaValue] if metatag processing occurs
* @com.soywiz.luak.compat.java.Throws LuaError if either operand is not a number or string convertible to number,
* and neither has the [.DIV] metatag defined
* @see .arithmt
*/
open operator fun div(rhs: LuaValue): LuaValue {
return arithmt(DIV, rhs)
}
/** Divide: Perform numeric divide operation by another value
* of double type without metatag processing
*
*
* `this` must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
*
* For metatag processing [.div] must be used
*
* @param rhs The right-hand-side value to perform the divulo with
* @return value of `(this / rhs)` if this is numeric
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a number or string convertible to number
* @see .div
*/
open operator fun div(rhs: Double): LuaValue {
return aritherror("div")
}
/** Divide: Perform numeric divide operation by another value
* of int type without metatag processing
*
*
* `this` must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
*
* For metatag processing [.div] must be used
*
* @param rhs The right-hand-side value to perform the divulo with
* @return value of `(this / rhs)` if this is numeric
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a number or string convertible to number
* @see .div
*/
open operator fun div(rhs: Int): LuaValue {
return aritherror("div")
}
/** Reverse-divide: Perform numeric divide operation into another value
* with metatag processing
*
*
* `this` must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
* @param lhs The left-hand-side value which will be divided by this
* @return value of `(lhs / this)` if this is numeric
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a number or string convertible to number
* @see .div
* @see .div
* @see .div
*/
open fun divInto(lhs: Double): LuaValue {
return arithmtwith(DIV, lhs)
}
/** Modulo: Perform numeric modulo operation with another value
* of unknown type,
* including metatag processing.
*
*
* Each operand must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
* @param rhs The right-hand-side value to perform the modulo with
* @return value of `(this % rhs)` if both are numeric,
* or [LuaValue] if metatag processing occurs
* @com.soywiz.luak.compat.java.Throws LuaError if either operand is not a number or string convertible to number,
* and neither has the [.MOD] metatag defined
* @see .arithmt
*/
open fun mod(rhs: LuaValue): LuaValue {
return arithmt(MOD, rhs)
}
/** Modulo: Perform numeric modulo operation with another value
* of double type without metatag processing
*
*
* `this` must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
*
* For metatag processing [.mod] must be used
*
* @param rhs The right-hand-side value to perform the modulo with
* @return value of `(this % rhs)` if this is numeric
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a number or string convertible to number
* @see .mod
*/
open fun mod(rhs: Double): LuaValue {
return aritherror("mod")
}
/** Modulo: Perform numeric modulo operation with another value
* of int type without metatag processing
*
*
* `this` must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
*
* For metatag processing [.mod] must be used
*
* @param rhs The right-hand-side value to perform the modulo with
* @return value of `(this % rhs)` if this is numeric
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a number or string convertible to number
* @see .mod
*/
open fun mod(rhs: Int): LuaValue {
return aritherror("mod")
}
/** Reverse-modulo: Perform numeric modulo operation from another value
* with metatag processing
*
*
* `this` must derive from [LuaNumber]
* or derive from [LuaString] and be convertible to a number
*
* @param lhs The left-hand-side value which will be modulo'ed by this
* @return value of `(lhs % this)` if this is numeric
* @com.soywiz.luak.compat.java.Throws LuaError if `this` is not a number or string convertible to number
* @see .mod
* @see .mod
* @see .mod
*/
open fun modFrom(lhs: Double): LuaValue {
return arithmtwith(MOD, lhs)
}
/** Perform metatag processing for arithmetic operations.
*
*
* Finds the supplied metatag value for `this` or `op2` and invokes it,
* or throws [LuaError] if neither is defined.
* @param tag The metatag to look up
* @param op2 The other operand value to perform the operation with
* @return [LuaValue] resulting from metatag processing
* @com.soywiz.luak.compat.java.Throws LuaError if metatag was not defined for either operand
* @see .add
* @see .sub
* @see .mul
* @see .pow
* @see .div
* @see .mod
* @see .ADD
*
* @see .SUB
*
* @see .MUL
*
* @see .POW
*
* @see .DIV
*
* @see .MOD
*/
protected fun arithmt(tag: LuaValue, op2: LuaValue): LuaValue {
var h = this.metatag(tag)
if (h.isnil()) {
h = op2.metatag(tag)
if (h.isnil())
error("attempt to perform arithmetic " + tag + " on " + typename() + " and " + op2.typename())
}
return h.call(this, op2)
}
/** Perform metatag processing for arithmetic operations when the left-hand-side is a number.
*
*
* Finds the supplied metatag value for `this` and invokes it,
* or throws [LuaError] if neither is defined.
* @param tag The metatag to look up
* @param op1 The value of the left-hand-side to perform the operation with
* @return [LuaValue] resulting from metatag processing
* @com.soywiz.luak.compat.java.Throws LuaError if metatag was not defined for either operand
* @see .add
* @see .sub
* @see .mul
* @see .pow
* @see .div
* @see .mod
* @see .ADD
*
* @see .SUB
*
* @see .MUL
*
* @see .POW
*
* @see .DIV
*
* @see .MOD
*/
protected fun arithmtwith(tag: LuaValue, op1: Double): LuaValue {
val h = metatag(tag)
if (h.isnil())
error("attempt to perform arithmetic " + tag + " on number and " + typename())
return h.call(LuaValue.valueOf(op1), this)
}
/** Less than: Perform numeric or string comparison with another value
* of unknown type,
* including metatag processing, and returning [LuaValue].
*
*
* To be comparable, both operands must derive from [LuaString]
* or both must derive from [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return [.TRUE] if `(this < rhs)`, [.FALSE] if not,
* or [LuaValue] if metatag processing occurs
* @com.soywiz.luak.compat.java.Throws LuaError if either both operands are not a strings or both are not numbers
* and no [.LT] metatag is defined.
* @see .gteq_b
* @see .comparemt
*/
open fun lt(rhs: LuaValue): LuaValue {
return comparemt(LT, rhs)
}
/** Less than: Perform numeric comparison with another value
* of double type,
* including metatag processing, and returning [LuaValue].
*
*
* To be comparable, this must derive from [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return [.TRUE] if `(this < rhs)`, [.FALSE] if not,
* or [LuaValue] if metatag processing occurs
* @com.soywiz.luak.compat.java.Throws LuaError if this is not a number
* and no [.LT] metatag is defined.
* @see .gteq_b
* @see .comparemt
*/
open fun lt(rhs: Double): LuaValue {
return compareerror("number")
}
/** Less than: Perform numeric comparison with another value
* of int type,
* including metatag processing, and returning [LuaValue].
*
*
* To be comparable, this must derive from [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return [.TRUE] if `(this < rhs)`, [.FALSE] if not,
* or [LuaValue] if metatag processing occurs
* @com.soywiz.luak.compat.java.Throws LuaError if this is not a number
* and no [.LT] metatag is defined.
* @see .gteq_b
* @see .comparemt
*/
open fun lt(rhs: Int): LuaValue {
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 [LuaString]
* or both must derive from [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return true if `(this < rhs)`, false if not,
* and boolean interpreation of result if metatag processing occurs.
* @com.soywiz.luak.compat.java.Throws LuaError if either both operands are not a strings or both are not numbers
* and no [.LT] metatag is defined.
* @see .gteq
* @see .comparemt
*/
open fun lt_b(rhs: LuaValue): Boolean {
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 [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return true if `(this < rhs)`, false if not,
* and boolean interpreation of result if metatag processing occurs.
* @com.soywiz.luak.compat.java.Throws LuaError if this is not a number
* and no [.LT] metatag is defined.
* @see .gteq
* @see .comparemt
*/
open fun lt_b(rhs: Int): Boolean {
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 [LuaString]
* or both must derive from [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return true if `(this < rhs)`, false if not,
* and boolean interpreation of result if metatag processing occurs.
* @com.soywiz.luak.compat.java.Throws LuaError if either both operands are not a strings or both are not numbers
* and no [.LT] metatag is defined.
* @see .gteq
* @see .comparemt
*/
open fun lt_b(rhs: Double): Boolean {
compareerror("number")
return false
}
/** Less than or equals: Perform numeric or string comparison with another value
* of unknown type,
* including metatag processing, and returning [LuaValue].
*
*
* To be comparable, both operands must derive from [LuaString]
* or both must derive from [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return [.TRUE] if `(this <= rhs)`, [.FALSE] if not,
* or [LuaValue] if metatag processing occurs
* @com.soywiz.luak.compat.java.Throws LuaError if either both operands are not a strings or both are not numbers
* and no [.LE] metatag is defined.
* @see .gteq_b
* @see .comparemt
*/
open fun lteq(rhs: LuaValue): LuaValue {
return comparemt(LE, rhs)
}
/** Less than or equals: Perform numeric comparison with another value
* of double type,
* including metatag processing, and returning [LuaValue].
*
*
* To be comparable, this must derive from [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return [.TRUE] if `(this <= rhs)`, [.FALSE] if not,
* or [LuaValue] if metatag processing occurs
* @com.soywiz.luak.compat.java.Throws LuaError if this is not a number
* and no [.LE] metatag is defined.
* @see .gteq_b
* @see .comparemt
*/
open fun lteq(rhs: Double): LuaValue {
return compareerror("number")
}
/** Less than or equals: Perform numeric comparison with another value
* of int type,
* including metatag processing, and returning [LuaValue].
*
*
* To be comparable, this must derive from [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return [.TRUE] if `(this <= rhs)`, [.FALSE] if not,
* or [LuaValue] if metatag processing occurs
* @com.soywiz.luak.compat.java.Throws LuaError if this is not a number
* and no [.LE] metatag is defined.
* @see .gteq_b
* @see .comparemt
*/
open fun lteq(rhs: Int): LuaValue {
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 [LuaString]
* or both must derive from [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return true if `(this <= rhs)`, false if not,
* and boolean interpreation of result if metatag processing occurs.
* @com.soywiz.luak.compat.java.Throws LuaError if either both operands are not a strings or both are not numbers
* and no [.LE] metatag is defined.
* @see .gteq
* @see .comparemt
*/
open fun lteq_b(rhs: LuaValue): Boolean {
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 [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return true if `(this <= rhs)`, false if not,
* and boolean interpreation of result if metatag processing occurs.
* @com.soywiz.luak.compat.java.Throws LuaError if this is not a number
* and no [.LE] metatag is defined.
* @see .gteq
* @see .comparemt
*/
open fun lteq_b(rhs: Int): Boolean {
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 [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return true if `(this <= rhs)`, false if not,
* and boolean interpreation of result if metatag processing occurs.
* @com.soywiz.luak.compat.java.Throws LuaError if this is not a number
* and no [.LE] metatag is defined.
* @see .gteq
* @see .comparemt
*/
open fun lteq_b(rhs: Double): Boolean {
compareerror("number")
return false
}
/** Greater than: Perform numeric or string comparison with another value
* of unknown type,
* including metatag processing, and returning [LuaValue].
*
*
* To be comparable, both operands must derive from [LuaString]
* or both must derive from [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return [.TRUE] if `(this > rhs)`, [.FALSE] if not,
* or [LuaValue] if metatag processing occurs
* @com.soywiz.luak.compat.java.Throws LuaError if either both operands are not a strings or both are not numbers
* and no [.LE] metatag is defined.
* @see .gteq_b
* @see .comparemt
*/
open fun gt(rhs: LuaValue): LuaValue {
return rhs.comparemt(LE, this)
}
/** Greater than: Perform numeric comparison with another value
* of double type,
* including metatag processing, and returning [LuaValue].
*
*
* To be comparable, this must derive from [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return [.TRUE] if `(this > rhs)`, [.FALSE] if not,
* or [LuaValue] if metatag processing occurs
* @com.soywiz.luak.compat.java.Throws LuaError if this is not a number
* and no [.LE] metatag is defined.
* @see .gteq_b
* @see .comparemt
*/
open fun gt(rhs: Double): LuaValue {
return compareerror("number")
}
/** Greater than: Perform numeric comparison with another value
* of int type,
* including metatag processing, and returning [LuaValue].
*
*
* To be comparable, this must derive from [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return [.TRUE] if `(this > rhs)`, [.FALSE] if not,
* or [LuaValue] if metatag processing occurs
* @com.soywiz.luak.compat.java.Throws LuaError if this is not a number
* and no [.LE] metatag is defined.
* @see .gteq_b
* @see .comparemt
*/
open fun gt(rhs: Int): LuaValue {
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 [LuaString]
* or both must derive from [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return true if `(this > rhs)`, false if not,
* and boolean interpreation of result if metatag processing occurs.
* @com.soywiz.luak.compat.java.Throws LuaError if either both operands are not a strings or both are not numbers
* and no [.LE] metatag is defined.
* @see .gteq
* @see .comparemt
*/
open fun gt_b(rhs: LuaValue): Boolean {
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 [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return true if `(this > rhs)`, false if not,
* and boolean interpreation of result if metatag processing occurs.
* @com.soywiz.luak.compat.java.Throws LuaError if this is not a number
* and no [.LE] metatag is defined.
* @see .gteq
* @see .comparemt
*/
open fun gt_b(rhs: Int): Boolean {
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 [LuaString]
* or both must derive from [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return true if `(this > rhs)`, false if not,
* and boolean interpreation of result if metatag processing occurs.
* @com.soywiz.luak.compat.java.Throws LuaError if either both operands are not a strings or both are not numbers
* and no [.LE] metatag is defined.
* @see .gteq
* @see .comparemt
*/
open fun gt_b(rhs: Double): Boolean {
compareerror("number")
}
/** Greater than or equals: Perform numeric or string comparison with another value
* of unknown type,
* including metatag processing, and returning [LuaValue].
*
*
* To be comparable, both operands must derive from [LuaString]
* or both must derive from [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return [.TRUE] if `(this >= rhs)`, [.FALSE] if not,
* or [LuaValue] if metatag processing occurs
* @com.soywiz.luak.compat.java.Throws LuaError if either both operands are not a strings or both are not numbers
* and no [.LT] metatag is defined.
* @see .gteq_b
* @see .comparemt
*/
open fun gteq(rhs: LuaValue): LuaValue {
return rhs.comparemt(LT, this)
}
/** Greater than or equals: Perform numeric comparison with another value
* of double type,
* including metatag processing, and returning [LuaValue].
*
*
* To be comparable, this must derive from [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return [.TRUE] if `(this >= rhs)`, [.FALSE] if not,
* or [LuaValue] if metatag processing occurs
* @com.soywiz.luak.compat.java.Throws LuaError if this is not a number
* and no [.LT] metatag is defined.
* @see .gteq_b
* @see .comparemt
*/
open fun gteq(rhs: Double): LuaValue {
return compareerror("number")
}
/** Greater than or equals: Perform numeric comparison with another value
* of int type,
* including metatag processing, and returning [LuaValue].
*
*
* To be comparable, this must derive from [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return [.TRUE] if `(this >= rhs)`, [.FALSE] if not,
* or [LuaValue] if metatag processing occurs
* @com.soywiz.luak.compat.java.Throws LuaError if this is not a number
* and no [.LT] metatag is defined.
* @see .gteq_b
* @see .comparemt
*/
open fun gteq(rhs: Int): LuaValue {
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 [LuaString]
* or both must derive from [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return true if `(this >= rhs)`, false if not,
* and boolean interpreation of result if metatag processing occurs.
* @com.soywiz.luak.compat.java.Throws LuaError if either both operands are not a strings or both are not numbers
* and no [.LT] metatag is defined.
* @see .gteq
* @see .comparemt
*/
open fun gteq_b(rhs: LuaValue): Boolean {
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 [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return true if `(this >= rhs)`, false if not,
* and boolean interpreation of result if metatag processing occurs.
* @com.soywiz.luak.compat.java.Throws LuaError if this is not a number
* and no [.LT] metatag is defined.
* @see .gteq
* @see .comparemt
*/
open fun gteq_b(rhs: Int): Boolean {
compareerror("number")
}
/** 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 [LuaNumber].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return true if `(this >= rhs)`, false if not,
* and boolean interpreation of result if metatag processing occurs.
* @com.soywiz.luak.compat.java.Throws LuaError if this is not a number
* and no [.LT] metatag is defined.
* @see .gteq
* @see .comparemt
*/
open fun gteq_b(rhs: Double): Boolean {
compareerror("number")
}
/** Perform metatag processing for comparison operations.
*
*
* Finds the supplied metatag value and invokes it,
* or throws [LuaError] if none applies.
* @param tag The metatag to look up
* @param op1 The operand with which to to perform the operation
* @return [LuaValue] resulting from metatag processing
* @com.soywiz.luak.compat.java.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
* @see .gteq
* @see .lt
* @see .lteq
*/
fun comparemt(tag: LuaValue, op1: LuaValue): LuaValue {
lateinit var h: LuaValue
if (!(run { h = metatag(tag); h }).isnil() || !((run { h = op1.metatag(tag); h }).isnil()))
return h.call(this, op1)
return if (LuaValue.LE.raweq(tag) && (!(run { h = metatag(LT); h }).isnil() || !(run {
h = op1.metatag(LT); h
}).isnil())) h.call(op1, this).not() else error(
"attempt to compare " + tag + " on " + typename() + " and " + op1.typename()
)
}
/** 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 [LuaString].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return int < 0 for `(this < rhs)`, int > 0 for `(this > rhs)`, or 0 when same string.
* @com.soywiz.luak.compat.java.Throws LuaError if either operand is not a string
*/
open fun strcmp(rhs: LuaValue): Int {
error("attempt to compare " + typename())
return 0
}
/** Perform string comparison with another value
* known to be a [LuaString]
* using string comparison based on byte values.
*
*
* Only strings can be compared, meaning
* each operand must derive from [LuaString].
*
* @param rhs The right-hand-side value to perform the comparison with
* @return int < 0 for `(this < rhs)`, int > 0 for `(this > rhs)`, or 0 when same string.
* @com.soywiz.luak.compat.java.Throws LuaError if this is not a string
*/
open fun strcmp(rhs: LuaString): Int {
error("attempt to compare " + typename())
return 0
}
/** 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 [LuaString] or [LuaNumber].
*
* @param rhs The right-hand-side value to perform the operation with
* @return [LuaValue] resulting from concatenation of `(this .. rhs)`
* @com.soywiz.luak.compat.java.Throws LuaError if either operand is not of an appropriate type,
* such as nil or a table
*/
open fun concat(rhs: LuaValue): LuaValue {
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 [LuaString] or [LuaNumber].
*
* @param lhs The left-hand-side value onto which this will be concatenated
* @return [LuaValue] resulting from concatenation of `(lhs .. this)`
* @com.soywiz.luak.compat.java.Throws LuaError if either operand is not of an appropriate type,
* such as nil or a table
* @see .concat
*/
fun concatTo(lhs: LuaValue): LuaValue {
return lhs.concatmt(this)
}
/** Reverse-concatenation: concatenate this value onto another value
* known to be a [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 [LuaString] or [LuaNumber].
*
* @param lhs The left-hand-side value onto which this will be concatenated
* @return [LuaValue] resulting from concatenation of `(lhs .. this)`
* @com.soywiz.luak.compat.java.Throws LuaError if either operand is not of an appropriate type,
* such as nil or a table
* @see .concat
*/
open fun concatTo(lhs: LuaNumber): LuaValue {
return lhs.concatmt(this)
}
/** Reverse-concatenation: concatenate this value onto another value
* known to be a [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 [LuaString] or [LuaNumber].
*
* @param lhs The left-hand-side value onto which this will be concatenated
* @return [LuaValue] resulting from concatenation of `(lhs .. this)`
* @com.soywiz.luak.compat.java.Throws LuaError if either operand is not of an appropriate type,
* such as nil or a table
* @see .concat
*/
open fun concatTo(lhs: LuaString): LuaValue {
return lhs.concatmt(this)
}
/** Convert the value to a [Buffer] for more efficient concatenation of
* multiple strings.
* @return Buffer instance containing the string or number
*/
fun buffer(): Buffer {
return Buffer(this)
}
/** Concatenate a [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 [LuaString] or [LuaNumber].
*
* @param rhs The right-hand-side [Buffer] to perform the operation with
* @return LuaString resulting from concatenation of `(this .. rhs)`
* @com.soywiz.luak.compat.java.Throws LuaError if either operand is not of an appropriate type,
* such as nil or a table
*/
open fun concat(rhs: Buffer): Buffer {
return rhs.concatTo(this)
}
/** Perform metatag processing for concatenation operations.
*
*
* Finds the [.CONCAT] metatag value and invokes it,
* or throws [LuaError] if it doesn't exist.
* @param rhs The right-hand-side value to perform the operation with
* @return [LuaValue] resulting from metatag processing for [.CONCAT] metatag.
* @com.soywiz.luak.compat.java.Throws LuaError if metatag was not defined for either operand
*/
fun concatmt(rhs: LuaValue): LuaValue {
var h = metatag(CONCAT)
if (h.isnil() && (run { h = rhs.metatag(CONCAT); h }).isnil())
error("attempt to concatenate " + typename() + " and " + rhs.typename())
return h.call(this, rhs)
}
/** Perform boolean `and` with another operand, based on lua rules for boolean evaluation.
* This returns either `this` or `rhs` depending on the boolean value for `this`.
*
* @param rhs The right-hand-side value to perform the operation with
* @return `this` if `this.toboolean()` is false, `rhs` otherwise.
*/
fun and(rhs: LuaValue): LuaValue {
return if (this.toboolean()) rhs else this
}
/** Perform boolean `or` with another operand, based on lua rules for boolean evaluation.
* This returns either `this` or `rhs` depending on the boolean value for `this`.
*
* @param rhs The right-hand-side value to perform the operation with
* @return `this` if `this.toboolean()` is true, `rhs` otherwise.
*/
fun or(rhs: LuaValue): LuaValue {
return if (this.toboolean()) this else rhs
}
/** 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.
*/
fun testfor_b(limit: LuaValue, step: LuaValue): Boolean {
return if (step.gt_b(0)) lteq_b(limit) else gteq_b(limit)
}
/**
* Convert this value to a string if it is a [LuaString] or [LuaNumber],
* or throw a [LuaError] if it is not
* @return [LuaString] corresponding to the value if a string or number
* @com.soywiz.luak.compat.java.Throws LuaError if not a string or number
*/
open fun strvalue(): LuaString? {
typerror("strValue")
}
/** Return this value as a strong reference, or null if it was weak and is no longer referenced.
* @return [LuaValue] referred to, or null if it was weak and is no longer referenced.
* @see WeakTable
*/
open fun strongvalue(): LuaValue? {
return this
}
/**
* Get particular metatag, or return [LuaValue.NIL] if it doesn't exist
* @param tag Metatag name to look up, typically a string such as
* [LuaValue.INDEX] or [LuaValue.NEWINDEX]
* @return [LuaValue] for tag `reason`, or [LuaValue.NIL]
*/
fun metatag(tag: LuaValue): LuaValue {
val mt = getmetatable() ?: return NIL
return mt.rawget(tag)
}
/**
* Get particular metatag, or throw [LuaError] if it doesn't exist
* @param tag Metatag name to look up, typically a string such as
* [LuaValue.INDEX] or [LuaValue.NEWINDEX]
* @param reason Description of error when tag lookup fails.
* @return [LuaValue] that can be called
* @com.soywiz.luak.compat.java.Throws LuaError when the lookup fails.
*/
protected fun checkmetatag(tag: LuaValue, reason: String): LuaValue {
val h = this.metatag(tag)
if (h.isnil())
throw LuaError(reason + typename())
return h
}
/** Throw [LuaError] indicating index was attempted on illegal type
* @com.soywiz.luak.compat.java.Throws LuaError when called.
*/
private fun indexerror() {
error("attempt to index ? (a " + typename() + " value)")
}
/**
* Callback used during tail call processing to invoke the function once.
*
*
* This may return a [TailcallVarargs] to be evaluated by the client.
*
*
* This should not be called directly, instead use one 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
* @see LuaValue.invokemethod
*/
open fun onInvoke(args: Varargs): Varargs {
return invoke(args)
}
/** Hook for implementations such as LuaJC to load the environment of the main chunk
* into the first upvalue location. If the function has no upvalues or is not a main chunk,
* calling this will be no effect.
* @param env The environment to load into the first upvalue, if there is one.
*/
fun initupvalue1(env: LuaValue) {}
/** Varargs implemenation with no values.
*
*
* This is an internal class not intended to be used directly.
* Instead use the predefined constant [LuaValue.NONE]
*
* @see LuaValue.NONE
*/
class None2 : LuaNil() {
override fun arg(i: Int): LuaValue {
return NIL
}
override fun narg(): Int {
return 0
}
override fun arg1(): LuaValue {
return NIL
}
override fun tojstring(): String {
return "none"
}
override fun subargs(start: Int): Varargs {
return if (start > 0) this else argerror(1, "start must be > 0")
}
override fun copyto(dest: Array, offset: Int, length: Int) {
var offset = offset
var length = length
while (length > 0) {
dest[offset++] = NIL
length--
}
}
companion object {
var _NONE = None2()
}
}
/**
* Create a `Varargs` instance containing arguments starting at index `start`
* @param start the index from which to include arguments, where 1 is the first argument.
* @return Varargs containing argument { start, start+1, ... , narg-start-1 }
*/
override fun subargs(start: Int): Varargs {
if (start == 1)
return this
return if (start > 1) NONE else argerror(1, "start must be > 0")
}
companion object {
/** Type enumeration constant for lua numbers that are ints, for compatibility with lua 5.1 number patch only */
const val TINT = -2
/** Type enumeration constant for lua values that have no type, for example weak table entries */
const val TNONE = -1
/** Type enumeration constant for lua nil */
const val TNIL = 0
/** Type enumeration constant for lua booleans */
const val TBOOLEAN = 1
/** Type enumeration constant for lua light userdata, for compatibility with C-based lua only */
const val TLIGHTUSERDATA = 2
/** Type enumeration constant for lua numbers */
const val TNUMBER = 3
/** Type enumeration constant for lua strings */
const val TSTRING = 4
/** Type enumeration constant for lua tables */
const val TTABLE = 5
/** Type enumeration constant for lua functions */
const val TFUNCTION = 6
/** Type enumeration constant for lua userdatas */
const val TUSERDATA = 7
/** Type enumeration constant for lua threads */
const val TTHREAD = 8
/** Type enumeration constant for unknown values, for compatibility with C-based lua only */
const val TVALUE = 9
/** String array constant containing names of each of the lua value types
* @see .type
* @see .typename
*/
val TYPE_NAMES = arrayOf(
"nil",
"boolean",
"lightuserdata",
"number",
"string",
"table",
"function",
"userdata",
"thread",
"value"
)
/** LuaValue constant corresponding to lua `#NIL` */
val NIL: LuaValue = LuaNil._NIL
/** LuaBoolean constant corresponding to lua `true` */
val TRUE = LuaBoolean._TRUE
/** LuaBoolean constant corresponding to lua `false` */
val FALSE = LuaBoolean._FALSE
/** LuaValue constant corresponding to a [Varargs] list of no values */
val NONE: LuaValue = None2._NONE
/** LuaValue number constant equal to 0 */
val ZERO: LuaNumber = LuaInteger.valueOf(0)
/** LuaValue number constant equal to 1 */
val ONE: LuaNumber = LuaInteger.valueOf(1)
/** LuaValue number constant equal to -1 */
val MINUSONE: LuaNumber = LuaInteger.valueOf(-1)
/** LuaValue array constant with no values */
val NOVALS = arrayOf()
/** The variable name of the environment. */
val ENV: LuaString by lazy { LuaString.valueOf("_ENV") }
/** LuaString constant with value "__index" for use as metatag */
val INDEX by lazy { LuaString.valueOf("__index") }
/** LuaString constant with value "__newindex" for use as metatag */
val NEWINDEX by lazy { LuaString.valueOf("__newindex") }
/** LuaString constant with value "__call" for use as metatag */
val CALL by lazy { LuaString.valueOf("__call") }
/** LuaString constant with value "__mode" for use as metatag */
val MODE by lazy { LuaString.valueOf("__mode") }
/** LuaString constant with value "__metatable" for use as metatag */
val METATABLE by lazy { LuaString.valueOf("__metatable") }
/** LuaString constant with value "__add" for use as metatag */
val ADD by lazy { LuaString.valueOf("__add") }
/** LuaString constant with value "__sub" for use as metatag */
val SUB by lazy { LuaString.valueOf("__sub") }
/** LuaString constant with value "__div" for use as metatag */
val DIV by lazy { LuaString.valueOf("__div") }
/** LuaString constant with value "__mul" for use as metatag */
val MUL by lazy { LuaString.valueOf("__mul") }
/** LuaString constant with value "__pow" for use as metatag */
val POW by lazy { LuaString.valueOf("__pow") }
/** LuaString constant with value "__mod" for use as metatag */
val MOD by lazy { LuaString.valueOf("__mod") }
/** LuaString constant with value "__unm" for use as metatag */
val UNM by lazy { LuaString.valueOf("__unm") }
/** LuaString constant with value "__len" for use as metatag */
val LEN by lazy { LuaString.valueOf("__len") }
/** LuaString constant with value "__eq" for use as metatag */
val EQ by lazy { LuaString.valueOf("__eq") }
/** LuaString constant with value "__lt" for use as metatag */
val LT by lazy { LuaString.valueOf("__lt") }
/** LuaString constant with value "__le" for use as metatag */
val LE by lazy { LuaString.valueOf("__le") }
/** LuaString constant with value "__tostring" for use as metatag */
val TOSTRING by lazy { LuaString.valueOf("__tostring") }
/** LuaString constant with value "__concat" for use as metatag */
val CONCAT by lazy { LuaString.valueOf("__concat") }
/** LuaString constant with value "" */
val EMPTYSTRING by lazy { LuaString.valueOf("") }
/** Limit on lua stack size */
private val MAXSTACK = 250
/** Array of [.NIL] values to optimize filling stacks using System.arraycopy().
* Must not be modified.
*/
val NILS by lazy { Array(MAXSTACK) { NIL } }
/**
* Throw a [LuaError] with a particular message
* @param message String providing message details
* @com.soywiz.luak.compat.java.Throws LuaError in all cases
*/
fun error(message: String): LuaValue {
throw LuaError(message)
}
/**
* Assert a condition is true, or throw a [LuaError] if not
* Returns no value when b is true, throws [.error] with `msg` as argument
* and does not return if b is false.
* @param b condition to test
* @param msg String message to produce on failure
* @com.soywiz.luak.compat.java.Throws LuaError if b is not true
*/
fun assert_(b: Boolean, msg: String) {
if (!b) throw LuaError(msg)
}
/**
* Throw a [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
* @com.soywiz.luak.compat.java.Throws LuaError in all cases
*/
fun argerror(iarg: Int, msg: String): Nothing {
throw LuaError("bad argument #$iarg: $msg")
}
/** 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 [.NIL] or [.FALSE]
* @com.soywiz.luak.compat.java.Throws LuaError if metatag was not defined for either operand
* @see .equals
* @see .eq
* @see .raweq
* @see .EQ
*/
fun eqmtcall(lhs: LuaValue, lhsmt: LuaValue, rhs: LuaValue, rhsmt: LuaValue): Boolean {
val h = lhsmt.rawget(EQ)
return if (h.isnil() || h !== rhsmt.rawget(EQ)) false else h.call(lhs, rhs).toboolean()
}
/** Convert java boolean to a [LuaValue].
*
* @param b boolean value to convert
* @return [.TRUE] if not or [.FALSE] if false
*/
fun valueOf(b: Boolean): LuaBoolean {
return if (b) LuaValue.TRUE else FALSE
}
/** Convert java int to a [LuaValue].
*
* @param i int value to convert
* @return [LuaInteger] instance, possibly pooled, whose value is i
*/
@JvmStatic
fun valueOf(i: Int): LuaInteger {
return LuaInteger.valueOf(i)
}
/** Convert java double to a [LuaValue].
* This may return a [LuaInteger] or [LuaDouble] depending
* on the value supplied.
*
* @param d double value to convert
* @return [LuaNumber] instance, possibly pooled, whose value is d
*/
fun valueOf(d: Double): LuaNumber {
return LuaDouble.valueOf(d)
}
/** Convert java string to a [LuaValue].
*
* @param s String value to convert
* @return [LuaString] instance, possibly pooled, whose value is s
*/
fun valueOf(s: String): LuaString {
return LuaString.valueOf(s)
}
/** Convert bytes in an array to a [LuaValue].
*
* @param bytes byte array to convert
* @return [LuaString] instance, possibly pooled, whose bytes are those in the supplied array
*/
fun valueOf(bytes: ByteArray): LuaString {
return LuaString.valueOf(bytes)
}
/** Convert bytes in an array to a [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 [LuaString]
* @return [LuaString] instance, possibly pooled, whose bytes are those in the supplied array
*/
fun valueOf(bytes: ByteArray, off: Int, len: Int): LuaString {
return LuaString.valueOf(bytes, off, len)
}
/** Construct an empty [LuaTable].
* @return new [LuaTable] instance with no values and no metatable.
*/
fun tableOf(): LuaTable {
return LuaTable()
}
/** Construct a [LuaTable] initialized with supplied array values.
* @param varargs [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 [LuaTable] instance with sequential elements coming from the varargs.
*/
fun tableOf(varargs: Varargs, firstarg: Int): LuaTable {
return LuaTable(varargs, firstarg)
}
/** Construct an empty [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 [LuaTable] instance with no values and no metatable, but preallocated for array and hashed elements.
*/
fun tableOf(narray: Int, nhash: Int): LuaTable {
return LuaTable(narray, nhash)
}
/** Construct a [LuaTable] initialized with supplied array values.
* @param unnamedValues array of [LuaValue] containing the values to use in initialization
* @return new [LuaTable] instance with sequential elements coming from the array.
*/
fun listOf(unnamedValues: Array): LuaTable {
return LuaTable(null, unnamedValues, null)
}
/** Construct a [LuaTable] initialized with supplied array values.
* @param unnamedValues array of [LuaValue] containing the first values to use in initialization
* @param lastarg [Varargs] containing additional values to use in initialization
* to be put after the last unnamedValues element
* @return new [LuaTable] instance with sequential elements coming from the array and varargs.
*/
fun listOf(unnamedValues: Array, lastarg: Varargs): LuaTable {
return LuaTable(null, unnamedValues, lastarg)
}
/** Construct a [LuaTable] initialized with supplied named values.
* @param namedValues array of [LuaValue] containing the keys and values to use in initialization
* in order `{key-a, value-a, key-b, value-b, ...} `
* @return new [LuaTable] instance with non-sequential keys coming from the supplied array.
*/
fun tableOf(namedValues: Array): LuaTable {
return LuaTable(namedValues, null, null)
}
/** Construct a [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 [LuaValue] containing the keys and values to use in initialization
* in order `{key-a, value-a, key-b, value-b, ...} `
* @param unnamedValues array of [LuaValue] containing the sequenctial elements to use in initialization
* in order `{value-1, value-2, ...} `, or null if there are none
* @return new [LuaTable] instance with named and sequential values supplied.
*/
fun tableOf(namedValues: Array, unnamedValues: Array): LuaTable {
return LuaTable(namedValues, unnamedValues, null)
}
/** Construct a [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 [LuaValue] containing the keys and values to use in initialization
* in order `{key-a, value-a, key-b, value-b, ...} `
* @param unnamedValues array of [LuaValue] containing the first sequenctial elements to use in initialization
* in order `{value-1, value-2, ...} `, or null if there are none
* @param lastarg [Varargs] containing additional values to use in the sequential part of the initialization,
* to be put after the last unnamedValues element
* @return new [LuaTable] instance with named and sequential values supplied.
*/
fun tableOf(namedValues: Array, unnamedValues: Array, lastarg: Varargs): LuaTable {
return LuaTable(namedValues, unnamedValues, lastarg)
}
/** Construct a LuaUserdata for an object.
*
* @param o The java instance to be wrapped as userdata
* @return [LuaUserdata] value wrapping the java instance.
*/
fun userdataOf(o: Any): LuaUserdata {
return 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 [LuaUserdata] value wrapping the java instance.
*/
fun userdataOf(o: Any, metatable: LuaValue?): LuaUserdata {
return LuaUserdata(o, metatable)
}
/** Constant limiting metatag loop processing */
private const val MAXTAGLOOP = 100
/**
* Return value for field reference including metatag processing, or [LuaValue.NIL] if it doesn't exist.
* @param t [LuaValue] on which field is being referenced, typically a table or something with the metatag [LuaValue.INDEX] defined
* @param key [LuaValue] naming the field to reference
* @return [LuaValue] for the `key` if it exists, or [LuaValue.NIL]
* @com.soywiz.luak.compat.java.Throws LuaError if there is a loop in metatag processing
*/
/** get value from metatable operations, or NIL if not defined by metatables */
@JvmStatic
protected fun gettable(t: LuaValue, key: LuaValue): LuaValue {
var t = t
lateinit var tm: LuaValue
var loop = 0
do {
if (t.istable()) {
val res = t.rawget(key)
if (!res.isnil() || (run { tm = t.metatag(INDEX); tm }).isnil())
return res
} else if ((run { tm = t.metatag(INDEX); tm }).isnil())
t.indexerror()
if (tm.isfunction())
return tm.call(t, key)
t = tm
} while (++loop < MAXTAGLOOP)
error("loop in gettable")
return NIL
}
/**
* Perform field assignment including metatag processing.
* @param t [LuaValue] on which value is being set, typically a table or something with the metatag [LuaValue.NEWINDEX] defined
* @param key [LuaValue] naming the field to assign
* @param value [LuaValue] the new value to assign to `key`
* @com.soywiz.luak.compat.java.Throws LuaError if there is a loop in metatag processing
* @return true if assignment or metatag processing succeeded, false otherwise
*/
fun settable(t: LuaValue, key: LuaValue, value: LuaValue): Boolean {
var t = t
lateinit var tm: LuaValue
var loop = 0
do {
if (t.istable()) {
if (!t.rawget(key).isnil() || (run { tm = t.metatag(NEWINDEX); tm }).isnil()) {
t.rawset(key, value)
return true
}
} else if ((run { tm = t.metatag(NEWINDEX); tm }).isnil())
t.typerror("index")
if (tm.isfunction()) {
tm.call(t, key, value)
return true
}
t = tm
} while (++loop < MAXTAGLOOP)
error("loop in settable")
return false
}
/** Construct a Metatable instance from the given LuaValue */
@JvmStatic
protected fun metatableOf(mt: LuaValue?): Metatable? {
if (mt != null && mt.istable()) {
val mode = mt.rawget(MODE)
if (mode.isstring()) {
val m = mode.tojstring()
val weakkeys = m.indexOf('k') >= 0
val weakvalues = m.indexOf('v') >= 0
if (weakkeys || weakvalues) {
return WeakTable(weakkeys, weakvalues, mt)
}
}
return mt as LuaTable?
} else return if (mt != null) {
NonTableMetatable(mt)
} else {
null
}
}
/** Construct a [Varargs] around an array of [LuaValue]s.
*
* @param v The array of [LuaValue]s
* @return [Varargs] wrapping the supplied values.
* @see LuaValue.varargsOf
* @see LuaValue.varargsOf
*/
fun varargsOf(v: Array): Varargs {
when (v.size) {
0 -> return NONE
1 -> return v[0]
2 -> return Varargs.PairVarargs(v[0], v[1])
else -> return Varargs.ArrayVarargs(v, NONE)
}
}
/** Construct a [Varargs] around an array of [LuaValue]s.
*
* @param v The array of [LuaValue]s
* @param r [Varargs] contain values to include at the end
* @return [Varargs] wrapping the supplied values.
* @see LuaValue.varargsOf
* @see LuaValue.varargsOf
*/
fun varargsOf(v: Array, r: Varargs): Varargs {
when (v.size) {
0 -> return r
1 -> return if (r.narg() > 0)
Varargs.PairVarargs(v[0], r)
else
v[0]
2 -> return if (r.narg() > 0)
Varargs.ArrayVarargs(v, r)
else
Varargs.PairVarargs(v[0], v[1])
else -> return Varargs.ArrayVarargs(v, r)
}
}
/** Construct a [Varargs] around an array of [LuaValue]s.
*
* @param v The array of [LuaValue]s
* @param offset number of initial values to skip in the array
* @param length number of values to include from the array
* @return [Varargs] wrapping the supplied values.
* @see LuaValue.varargsOf
* @see LuaValue.varargsOf
*/
fun varargsOf(v: Array, offset: Int, length: Int): Varargs {
when (length) {
0 -> return NONE
1 -> return v[offset]
2 -> return Varargs.PairVarargs(v[offset + 0], v[offset + 1])
else -> return Varargs.ArrayPartVarargs(v, offset, length, NONE)
}
}
/** Construct a [Varargs] around an array of [LuaValue]s.
*
* Caller must ensure that array contents are not mutated after this call
* or undefined behavior will result.
*
* @param v The array of [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 [Varargs] contain values to include at the end
* @return [Varargs] wrapping the supplied values.
* @see LuaValue.varargsOf
* @see LuaValue.varargsOf
*/
fun varargsOf(v: Array, offset: Int, length: Int, more: Varargs): Varargs {
when (length) {
0 -> return more
1 -> return if (more.narg() > 0)
Varargs.PairVarargs(v[offset], more)
else
v[offset]
2 -> return if (more.narg() > 0)
Varargs.ArrayPartVarargs(v, offset, length, more)
else
Varargs.PairVarargs(v[offset], v[offset + 1])
else -> return Varargs.ArrayPartVarargs(v, offset, length, more)
}
}
/** Construct a [Varargs] around a set of 2 or more [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 v First [LuaValue] in the [Varargs]
* @param r [LuaValue] supplying the 2rd value,
* or [Varargs]s supplying all values beyond the first
* @return [Varargs] wrapping the supplied values.
*/
fun varargsOf(v: LuaValue, r: Varargs): Varargs {
when (r.narg()) {
0 -> return v
else -> return Varargs.PairVarargs(v, r)
}
}
/** Construct a [Varargs] around a set of 3 or more [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 [LuaValue] in the [Varargs]
* @param v2 Second [LuaValue] in the [Varargs]
* @param v3 [LuaValue] supplying the 3rd value,
* or [Varargs]s supplying all values beyond the second
* @return [Varargs] wrapping the supplied values.
*/
fun varargsOf(v1: LuaValue, v2: LuaValue, v3: Varargs): Varargs {
when (v3.narg()) {
0 -> return Varargs.PairVarargs(v1, v2)
else -> return Varargs.ArrayPartVarargs(arrayOf(v1, v2), 0, 2, v3)
}
}
/** Construct a [TailcallVarargs] around a function and arguments.
*
*
* The tail call is not yet called or processing until the client invokes
* [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 [LuaValue] to be called as a tail call
* @param args [Varargs] containing the arguments to the call
* @return [TailcallVarargs] to be used in tailcall oprocessing.
* @see LuaValue.call
* @see LuaValue.invoke
* @see LuaValue.method
* @see LuaValue.invokemethod
*/
fun tailcallOf(func: LuaValue, args: Varargs): Varargs {
return TailcallVarargs(func, args)
}
}
}