diff --git a/.classpath b/.classpath deleted file mode 100644 index eded28b8..00000000 --- a/.classpath +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..ab1f4164 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 00000000..85067693 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/discord.xml b/.idea/discord.xml new file mode 100644 index 00000000..d8e95616 --- /dev/null +++ b/.idea/discord.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 00000000..a72ee6d0 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 00000000..50664c82 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/luaj.iml b/.idea/luaj.iml new file mode 100644 index 00000000..d6ebd480 --- /dev/null +++ b/.idea/luaj.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..a8069d15 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,18 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..35eb1ddf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.project b/.project deleted file mode 100644 index 15180d11..00000000 --- a/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - luaj-vm - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/README.md b/README.md index 75363ae9..86848e6c 100644 --- a/README.md +++ b/README.md @@ -317,10 +317,6 @@ A simple example may be found in You must include the library luaj-jme-3.0.2.jar in your midlet jar.

-An ant script to build and run the midlet is in -

-	build-midlet.xml
-

You must install the wireless toolkit and define WTK_HOME for this script to work. @@ -428,7 +424,6 @@ Applets in browsers should use the JsePlatform. The permissions model in applet highly restrictive, so a specialization of the Luajava library must be used that uses default class loading. This is illustrated in the sample Applet examples/jse/SampleApplet.java, -which can be built using build-applet.xml.

JmePlatform

@@ -447,7 +442,6 @@ In particular Globals.finder is overridden to load as resources, so scripts shou colocated with class files in the MIDlet jar file. Luajava cannot be used. Camples code is in examples/jme/SampleMIDlet.java, -which can be built using build-midlet.xml.

Thread Safety

@@ -889,10 +883,6 @@ Unit test scripts can be found in these locations

Code coverage

-A build script for running unit tests and producing code coverage statistics is in -

-	build-coverage.xml
-
It relies on the cobertura code coverage library. @@ -951,7 +941,6 @@ and at http://luaj.sour
  • Add explicit Globals object to manage global state, especially to imrpove thread safety
  • Drop support for lua source to java surce (lua2java) in favor of direct java bytecode output (luajc)
  • Remove compatibility functions like table.getn(), table.maxn(), table.foreach(), and math.log10()
  • -
  • Add ability to create runnable jar file from lua script with sample build file build-app.xml
  • Supply environment as second argument to LibFunction when loading via require()
  • Fix bug 3597515 memory leak due to string caching by simplifying caching logic.
  • Fix bug 3565008 so that short substrings are backed by short arrays.
  • diff --git a/build-app.xml b/build-app.xml deleted file mode 100644 index a3985c9d..00000000 --- a/build-app.xml +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - - - - - - - - - - - - - - ------ @{cmd} - - - - - - - - - - - - - =========== @{srcdir}/@{luaprog} ============= - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build-applet.xml b/build-applet.xml deleted file mode 100644 index d27b4420..00000000 --- a/build-applet.xml +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -injars ${build.dir}/${script.name}-unobfuscated.jar - -outjars ${build.dir}/${script.name}.jar - -libraryjars ${java.home}/lib/rt.jar - -overloadaggressively - -repackageclasses '' - -allowaccessmodification - -printmapping ${build.dir}/mapping.txt - - -keep public class * extends java.applet.Applet - - -target 1.4 - - - - - - - - - - - Luaj Sample Applet - -

    Luaj Sample Applet

    - Requires browser that supports applets. - ${script.name} - - - - - - -
    -
    - - - - - - - - - - - - -
    diff --git a/build-coverage.xml b/build-coverage.xml deleted file mode 100644 index 8a491f8c..00000000 --- a/build-coverage.xml +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build-libs.xml b/build-libs.xml deleted file mode 100644 index 872c5bb8..00000000 --- a/build-libs.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build-maven.xml b/build-maven.xml deleted file mode 100644 index 33e2211d..00000000 --- a/build-maven.xml +++ /dev/null @@ -1,176 +0,0 @@ - - - - - - - - - - - 4.0.0 - org.luaj - luaj-]]>@{platform} - ]]>${version}@{snapshot} - jar - luaj-]]>@{platform} - Luaj ]]>${version}@{platform} - http://sourceforge.net/projects/luaj/ - - - MIT License - http://luaj.sourceforge.net/license.txt - repo - - - - - jrosebor - James Roseborough - jim.roseborough@luaj.org - -8 - - - - ifarmer - Ian Farmer - ian.farmer@luaj.org - -8 - - - - - http://luaj.cvs.sourceforge.net/viewvc/luaj/luaj-vm/ - - -]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Luaj API]]> - Copyright © 2007-2015 Luaj.org. All Rights Reserved.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Usage: ant [-Dversion=${version}] -f build-maven.xml [install | shapshot | deploy] - - diff --git a/build-midlet.xml b/build-midlet.xml deleted file mode 100644 index 89457961..00000000 --- a/build-midlet.xml +++ /dev/null @@ -1,113 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -injars build/sample-plain.jar - -outjars build/sample.jar - -libraryjars lib/midpapi20.jar - -libraryjars lib/cldcapi11.jar - -overloadaggressively - -repackageclasses '' - -microedition - - -keep public class SampleMIDlet - -keep public class * extends org.luaj.vm2.LuaValue - - - - - - Jar file length is ${sample.jar.length} - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build-perf.xml b/build-perf.xml deleted file mode 100644 index 63007823..00000000 --- a/build-perf.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ------ @{program} @{luaprog} - - - - - - - - - - - - =========== @{luaprog} ============= - - - - - - - - - - - - - - - - diff --git a/build.xml b/build.xml deleted file mode 100644 index e0ea7f0d..00000000 --- a/build.xml +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Luaj API]]> - Copyright © 2007-2015 Luaj.org. All Rights Reserved.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/core/pom.xml b/core/pom.xml new file mode 100644 index 00000000..ba62cddd --- /dev/null +++ b/core/pom.xml @@ -0,0 +1,36 @@ + + + 4.0.0 + + + org.openautonomousconnection.luaj + parent + 3.0.2 + + + core + jar + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + jar + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 21 + 21 + + + + + \ No newline at end of file diff --git a/src/core/org/luaj/vm2/Buffer.java b/core/src/main/java/org/luaj/vm2/Buffer.java similarity index 100% rename from src/core/org/luaj/vm2/Buffer.java rename to core/src/main/java/org/luaj/vm2/Buffer.java diff --git a/src/core/org/luaj/vm2/Globals.java b/core/src/main/java/org/luaj/vm2/Globals.java similarity index 100% rename from src/core/org/luaj/vm2/Globals.java rename to core/src/main/java/org/luaj/vm2/Globals.java diff --git a/src/core/org/luaj/vm2/LoadState.java b/core/src/main/java/org/luaj/vm2/LoadState.java similarity index 100% rename from src/core/org/luaj/vm2/LoadState.java rename to core/src/main/java/org/luaj/vm2/LoadState.java diff --git a/src/core/org/luaj/vm2/LocVars.java b/core/src/main/java/org/luaj/vm2/LocVars.java similarity index 100% rename from src/core/org/luaj/vm2/LocVars.java rename to core/src/main/java/org/luaj/vm2/LocVars.java diff --git a/src/core/org/luaj/vm2/Lua.java b/core/src/main/java/org/luaj/vm2/Lua.java similarity index 100% rename from src/core/org/luaj/vm2/Lua.java rename to core/src/main/java/org/luaj/vm2/Lua.java diff --git a/src/core/org/luaj/vm2/LuaBoolean.java b/core/src/main/java/org/luaj/vm2/LuaBoolean.java similarity index 100% rename from src/core/org/luaj/vm2/LuaBoolean.java rename to core/src/main/java/org/luaj/vm2/LuaBoolean.java diff --git a/src/core/org/luaj/vm2/LuaClosure.java b/core/src/main/java/org/luaj/vm2/LuaClosure.java similarity index 99% rename from src/core/org/luaj/vm2/LuaClosure.java rename to core/src/main/java/org/luaj/vm2/LuaClosure.java index 46a3556f..a1c1c078 100644 --- a/src/core/org/luaj/vm2/LuaClosure.java +++ b/core/src/main/java/org/luaj/vm2/LuaClosure.java @@ -502,10 +502,10 @@ public class LuaClosure extends LuaFunction { continue; case Lua.OP_EXTRAARG: - throw new java.lang.IllegalArgumentException("Uexecutable opcode: OP_EXTRAARG"); + throw new IllegalArgumentException("Uexecutable opcode: OP_EXTRAARG"); default: - throw new java.lang.IllegalArgumentException("Illegal opcode: " + (i & 0x3f)); + throw new IllegalArgumentException("Illegal opcode: " + (i & 0x3f)); } } } catch ( LuaError le ) { diff --git a/src/core/org/luaj/vm2/LuaDouble.java b/core/src/main/java/org/luaj/vm2/LuaDouble.java similarity index 100% rename from src/core/org/luaj/vm2/LuaDouble.java rename to core/src/main/java/org/luaj/vm2/LuaDouble.java diff --git a/src/core/org/luaj/vm2/LuaError.java b/core/src/main/java/org/luaj/vm2/LuaError.java similarity index 100% rename from src/core/org/luaj/vm2/LuaError.java rename to core/src/main/java/org/luaj/vm2/LuaError.java diff --git a/src/core/org/luaj/vm2/LuaFunction.java b/core/src/main/java/org/luaj/vm2/LuaFunction.java similarity index 100% rename from src/core/org/luaj/vm2/LuaFunction.java rename to core/src/main/java/org/luaj/vm2/LuaFunction.java diff --git a/src/core/org/luaj/vm2/LuaInteger.java b/core/src/main/java/org/luaj/vm2/LuaInteger.java similarity index 100% rename from src/core/org/luaj/vm2/LuaInteger.java rename to core/src/main/java/org/luaj/vm2/LuaInteger.java diff --git a/src/core/org/luaj/vm2/LuaNil.java b/core/src/main/java/org/luaj/vm2/LuaNil.java similarity index 100% rename from src/core/org/luaj/vm2/LuaNil.java rename to core/src/main/java/org/luaj/vm2/LuaNil.java diff --git a/src/core/org/luaj/vm2/LuaNumber.java b/core/src/main/java/org/luaj/vm2/LuaNumber.java similarity index 100% rename from src/core/org/luaj/vm2/LuaNumber.java rename to core/src/main/java/org/luaj/vm2/LuaNumber.java diff --git a/src/core/org/luaj/vm2/LuaString.java b/core/src/main/java/org/luaj/vm2/LuaString.java similarity index 100% rename from src/core/org/luaj/vm2/LuaString.java rename to core/src/main/java/org/luaj/vm2/LuaString.java diff --git a/src/core/org/luaj/vm2/LuaTable.java b/core/src/main/java/org/luaj/vm2/LuaTable.java similarity index 100% rename from src/core/org/luaj/vm2/LuaTable.java rename to core/src/main/java/org/luaj/vm2/LuaTable.java diff --git a/core/src/main/java/org/luaj/vm2/LuaThread.java b/core/src/main/java/org/luaj/vm2/LuaThread.java new file mode 100644 index 00000000..a210d4c7 --- /dev/null +++ b/core/src/main/java/org/luaj/vm2/LuaThread.java @@ -0,0 +1,309 @@ +/******************************************************************************* + * Copyright (c) 2007-2012 LuaJ. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ +package org.luaj.vm2; + + +import java.lang.ref.WeakReference; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Subclass of {@link LuaValue} that implements + * a lua coroutine thread using Java Threads. + *

    + * A LuaThread is typically created in response to a scripted call to + * {@code coroutine.create()} + *

    + * The threads must be initialized with the globals, so that + * the global environment may be passed along according to rules of lua. + * This is done via the constructor arguments {@link #LuaThread(Globals)} or + * {@link #LuaThread(Globals, LuaValue)}. + *

    + * The utility classes {@link org.luaj.vm2.lib.jse.JsePlatform} and + * {@link org.luaj.vm2.lib.jme.JmePlatform} + * see to it that this {@link Globals} are initialized properly. + *

    + * The behavior of coroutine threads matches closely the behavior + * of C coroutine library. However, because of the use of Java threads + * to manage call state, it is possible to yield from anywhere in luaj. + *

    + * Each Java thread wakes up at regular intervals and checks a weak reference + * to determine if it can ever be resumed. If not, it throws + * {@link OrphanedThread} which is an {@link java.lang.Error}. + * Applications should not catch {@link OrphanedThread}, because it can break + * the thread safety of luaj. The value controlling the polling interval + * is {@link #thread_orphan_check_interval} and may be set by the user. + *

    + * There are two main ways to abandon a coroutine. The first is to call + * {@code yield()} from lua, or equivalently {@link Globals#yield(Varargs)}, + * and arrange to have it never resumed possibly by values passed to yield. + * The second is to throw {@link OrphanedThread}, which should put the thread + * in a dead state. In either case all references to the thread must be + * dropped, and the garbage collector must run for the thread to be + * garbage collected. + * + * + * @see LuaValue + * @see org.luaj.vm2.lib.jse.JsePlatform + * @see org.luaj.vm2.lib.jme.JmePlatform + * @see org.luaj.vm2.lib.CoroutineLib + */ +public class LuaThread extends LuaValue { + + /** Shared metatable for lua threads. */ + public static LuaValue s_metatable; + + /** The current number of coroutines. Should not be set. */ + public static int coroutine_count = 0; + + /** Polling interval, in milliseconds, which each thread uses while waiting to + * return from a yielded state to check if the lua threads is no longer + * referenced and therefore should be garbage collected. + * A short polling interval for many threads will consume server resources. + * Orphaned threads cannot be detected and collected unless garbage + * collection is run. This can be changed by Java startup code if desired. + */ + public static long thread_orphan_check_interval = 5000; + + public static final String USE_PLATFORM_THREAD = "USE_PLATFORM_THREAD"; + + private static boolean SUPPORT_VIRTUAL_THREAD = false; + + static { + try { + Thread.class.getMethod("ofVirtual"); + SUPPORT_VIRTUAL_THREAD = true; + } catch (Exception e) { + //e.printStackTrace(); + } + } + + public static final int STATUS_INITIAL = 0; + public static final int STATUS_SUSPENDED = 1; + public static final int STATUS_RUNNING = 2; + public static final int STATUS_NORMAL = 3; + public static final int STATUS_DEAD = 4; + public static final String[] STATUS_NAMES = { + "suspended", + "suspended", + "running", + "normal", + "dead",}; + + public final State state; + + public static final int MAX_CALLSTACK = 256; + + /** Thread-local used by DebugLib to store debugging state. + * This is an opaque value that should not be modified by applications. */ + public Object callstack; + + public final Globals globals; + + /** Error message handler for this thread, if any. */ + public LuaValue errorfunc; + + /** Private constructor for main thread only */ + public LuaThread(Globals globals) { + state = new State(globals, this, null); + state.status = STATUS_RUNNING; + this.globals = globals; + } + + /** + * Create a LuaThread around a function and environment + * @param func The function to execute + */ + public LuaThread(Globals globals, LuaValue func) { + LuaValue.assert_(func != null, "function cannot be null"); + state = new State(globals, this, func); + this.globals = globals; + } + + public int type() { + return LuaValue.TTHREAD; + } + + public String typename() { + return "thread"; + } + + public boolean isthread() { + return true; + } + + public LuaThread optthread(LuaThread defval) { + return this; + } + + public LuaThread checkthread() { + return this; + } + + public LuaValue getmetatable() { + return s_metatable; + } + + public String getStatus() { + return STATUS_NAMES[state.status]; + } + + public boolean isMainThread() { + return this.state.function == null; + } + + public Varargs resume(Varargs args) { + final LuaThread.State s = this.state; + if (s.status > LuaThread.STATUS_SUSPENDED) + return LuaValue.varargsOf(LuaValue.FALSE, + LuaValue.valueOf("cannot resume "+(s.status==LuaThread.STATUS_DEAD? "dead": "non-suspended")+" coroutine")); + return s.lua_resume(this, args); + } + + public static class State implements Runnable { + private final Globals globals; + final WeakReference lua_thread; + public final LuaValue function; + Varargs args = LuaValue.NONE; + Varargs result = LuaValue.NONE; + String error = null; + + /** Hook function control state used by debug lib. */ + public LuaValue hookfunc; + + public boolean hookline; + public boolean hookcall; + public boolean hookrtrn; + public int hookcount; + public boolean inhook; + public int lastline; + public int bytecodes; + + public int status = LuaThread.STATUS_INITIAL; + private Lock locker = new ReentrantLock(); + private Condition cond = locker.newCondition(); + + State(Globals globals, LuaThread lua_thread, LuaValue function) { + this.globals = globals; + this.lua_thread = new WeakReference(lua_thread); + this.function = function; + } + + public void run() { + locker.lock(); + try { + try { + Varargs a = this.args; + this.args = LuaValue.NONE; + this.result = function.invoke(a); + } catch (Throwable t) { + this.error = t.getMessage(); + } finally { + this.status = LuaThread.STATUS_DEAD; + cond.signal(); + } + } finally { + locker.unlock(); + } + } + + public Varargs lua_resume(LuaThread new_thread, Varargs args) { + locker.lock(); + try { + LuaThread previous_thread = globals.running; + try { + globals.running = new_thread; + this.args = args; + if (this.status == STATUS_INITIAL) { + this.status = STATUS_RUNNING; + Thread t = null; + if(SUPPORT_VIRTUAL_THREAD) { + LuaValue setting = globals.get(USE_PLATFORM_THREAD); + if(setting.isnil()) {//default + if(Thread.currentThread().isVirtual()) { + t = Thread.ofVirtual().name("Coroutine-"+(++coroutine_count)).start(this); + } + } else { + if(!setting.toboolean()) { + t = Thread.ofVirtual().name("Coroutine-"+(++coroutine_count)).start(this); + } + } + } + if (t == null){ + new Thread(this, "Coroutine-"+(++coroutine_count)).start(); + } + } else { + cond.signal(); + } + if (previous_thread != null) + previous_thread.state.status = STATUS_NORMAL; + this.status = STATUS_RUNNING; + cond.await(); + return (this.error != null? + LuaValue.varargsOf(LuaValue.FALSE, LuaValue.valueOf(this.error)): + LuaValue.varargsOf(LuaValue.TRUE, this.result)); + } catch (InterruptedException ie) { + throw new OrphanedThread(); + } finally { + this.args = LuaValue.NONE; + this.result = LuaValue.NONE; + this.error = null; + globals.running = previous_thread; + if (previous_thread != null) + globals.running.state.status =STATUS_RUNNING; + } + } finally { + locker.unlock(); + } + } + + public Varargs lua_yield(Varargs args) { + locker.lock(); + try { + try { + this.result = args; + this.status = STATUS_SUSPENDED; + cond.signal(); + do { + cond.await(thread_orphan_check_interval,TimeUnit.MILLISECONDS); + if (this.lua_thread.get() == null) { + this.status = STATUS_DEAD; + throw new OrphanedThread(); + } + } while (this.status == STATUS_SUSPENDED); + return this.args; + } catch (InterruptedException ie) { + this.status = STATUS_DEAD; + throw new OrphanedThread(); + } finally { + this.args = LuaValue.NONE; + this.result = LuaValue.NONE; + } + } finally { + locker.unlock(); + } + } + } + +} \ No newline at end of file diff --git a/src/core/org/luaj/vm2/LuaUserdata.java b/core/src/main/java/org/luaj/vm2/LuaUserdata.java similarity index 100% rename from src/core/org/luaj/vm2/LuaUserdata.java rename to core/src/main/java/org/luaj/vm2/LuaUserdata.java diff --git a/src/core/org/luaj/vm2/LuaValue.java b/core/src/main/java/org/luaj/vm2/LuaValue.java similarity index 99% rename from src/core/org/luaj/vm2/LuaValue.java rename to core/src/main/java/org/luaj/vm2/LuaValue.java index 9d3af18d..34913cb3 100644 --- a/src/core/org/luaj/vm2/LuaValue.java +++ b/core/src/main/java/org/luaj/vm2/LuaValue.java @@ -3402,8 +3402,8 @@ public class LuaValue extends Varargs { switch ( v.length ) { case 0: return NONE; case 1: return v[0]; - case 2: return new Varargs.PairVarargs(v[0],v[1]); - default: return new Varargs.ArrayVarargs(v,NONE); + case 2: return new PairVarargs(v[0],v[1]); + default: return new ArrayVarargs(v,NONE); } } @@ -3419,12 +3419,12 @@ public class LuaValue extends Varargs { switch ( v.length ) { case 0: return r; case 1: return r.narg()>0? - (Varargs) new Varargs.PairVarargs(v[0],r): + (Varargs) new PairVarargs(v[0],r): (Varargs) v[0]; case 2: return r.narg()>0? - (Varargs) new Varargs.ArrayVarargs(v,r): - (Varargs) new Varargs.PairVarargs(v[0],v[1]); - default: return new Varargs.ArrayVarargs(v,r); + (Varargs) new ArrayVarargs(v,r): + (Varargs) new PairVarargs(v[0],v[1]); + default: return new ArrayVarargs(v,r); } } @@ -3441,8 +3441,8 @@ public class LuaValue extends Varargs { switch ( length ) { case 0: return NONE; case 1: return v[offset]; - case 2: return new Varargs.PairVarargs(v[offset+0],v[offset+1]); - default: return new Varargs.ArrayPartVarargs(v, offset, length, NONE); + case 2: return new PairVarargs(v[offset+0],v[offset+1]); + default: return new ArrayPartVarargs(v, offset, length, NONE); } } @@ -3463,12 +3463,12 @@ public class LuaValue extends Varargs { switch ( length ) { case 0: return more; case 1: return more.narg()>0? - (Varargs) new Varargs.PairVarargs(v[offset],more): + (Varargs) new PairVarargs(v[offset],more): (Varargs) v[offset]; case 2: return more.narg()>0? - (Varargs) new Varargs.ArrayPartVarargs(v,offset,length,more): - (Varargs) new Varargs.PairVarargs(v[offset],v[offset+1]); - default: return new Varargs.ArrayPartVarargs(v,offset,length,more); + (Varargs) new ArrayPartVarargs(v,offset,length,more): + (Varargs) new PairVarargs(v[offset],v[offset+1]); + default: return new ArrayPartVarargs(v,offset,length,more); } } @@ -3485,7 +3485,7 @@ public class LuaValue extends Varargs { public static Varargs varargsOf(LuaValue v, Varargs r) { switch ( r.narg() ) { case 0: return v; - default: return new Varargs.PairVarargs(v,r); + default: return new PairVarargs(v,r); } } @@ -3502,8 +3502,8 @@ public class LuaValue extends Varargs { */ public static Varargs varargsOf(LuaValue v1,LuaValue v2,Varargs v3) { switch ( v3.narg() ) { - case 0: return new Varargs.PairVarargs(v1,v2); - default: return new Varargs.ArrayPartVarargs(new LuaValue[]{v1,v2}, 0, 2, v3); + case 0: return new PairVarargs(v1,v2); + default: return new ArrayPartVarargs(new LuaValue[]{v1,v2}, 0, 2, v3); } } diff --git a/src/core/org/luaj/vm2/Metatable.java b/core/src/main/java/org/luaj/vm2/Metatable.java similarity index 100% rename from src/core/org/luaj/vm2/Metatable.java rename to core/src/main/java/org/luaj/vm2/Metatable.java diff --git a/src/core/org/luaj/vm2/NonTableMetatable.java b/core/src/main/java/org/luaj/vm2/NonTableMetatable.java similarity index 100% rename from src/core/org/luaj/vm2/NonTableMetatable.java rename to core/src/main/java/org/luaj/vm2/NonTableMetatable.java diff --git a/src/core/org/luaj/vm2/OrphanedThread.java b/core/src/main/java/org/luaj/vm2/OrphanedThread.java similarity index 96% rename from src/core/org/luaj/vm2/OrphanedThread.java rename to core/src/main/java/org/luaj/vm2/OrphanedThread.java index b3c931f1..5e2eba8d 100644 --- a/src/core/org/luaj/vm2/OrphanedThread.java +++ b/core/src/main/java/org/luaj/vm2/OrphanedThread.java @@ -22,7 +22,7 @@ package org.luaj.vm2; /** - * {@link java.lang.Error} sublcass that indicates a lua thread that is no + * {@link Error} sublcass that indicates a lua thread that is no * longer referenced has been detected. *

    * The java thread in which this is thrown should correspond to a diff --git a/src/core/org/luaj/vm2/Print.java b/core/src/main/java/org/luaj/vm2/Print.java similarity index 100% rename from src/core/org/luaj/vm2/Print.java rename to core/src/main/java/org/luaj/vm2/Print.java diff --git a/src/core/org/luaj/vm2/Prototype.java b/core/src/main/java/org/luaj/vm2/Prototype.java similarity index 100% rename from src/core/org/luaj/vm2/Prototype.java rename to core/src/main/java/org/luaj/vm2/Prototype.java diff --git a/src/core/org/luaj/vm2/TailcallVarargs.java b/core/src/main/java/org/luaj/vm2/TailcallVarargs.java similarity index 100% rename from src/core/org/luaj/vm2/TailcallVarargs.java rename to core/src/main/java/org/luaj/vm2/TailcallVarargs.java diff --git a/src/core/org/luaj/vm2/UpValue.java b/core/src/main/java/org/luaj/vm2/UpValue.java similarity index 100% rename from src/core/org/luaj/vm2/UpValue.java rename to core/src/main/java/org/luaj/vm2/UpValue.java diff --git a/src/core/org/luaj/vm2/Upvaldesc.java b/core/src/main/java/org/luaj/vm2/Upvaldesc.java similarity index 100% rename from src/core/org/luaj/vm2/Upvaldesc.java rename to core/src/main/java/org/luaj/vm2/Upvaldesc.java diff --git a/src/core/org/luaj/vm2/Varargs.java b/core/src/main/java/org/luaj/vm2/Varargs.java similarity index 99% rename from src/core/org/luaj/vm2/Varargs.java rename to core/src/main/java/org/luaj/vm2/Varargs.java index e56d8dcf..04cf60d8 100644 --- a/src/core/org/luaj/vm2/Varargs.java +++ b/core/src/main/java/org/luaj/vm2/Varargs.java @@ -537,7 +537,7 @@ public abstract class Varargs { if (newstart == this.end) return v.arg(this.end); if (newstart == this.end-1) - return new Varargs.PairVarargs(v.arg(this.end-1), v.arg(this.end)); + return new PairVarargs(v.arg(this.end-1), v.arg(this.end)); return new SubVarargs(v, newstart, this.end); } return new SubVarargs(v, newstart, this.end); diff --git a/src/core/org/luaj/vm2/WeakTable.java b/core/src/main/java/org/luaj/vm2/WeakTable.java similarity index 100% rename from src/core/org/luaj/vm2/WeakTable.java rename to core/src/main/java/org/luaj/vm2/WeakTable.java diff --git a/src/core/org/luaj/vm2/compiler/Constants.java b/core/src/main/java/org/luaj/vm2/compiler/Constants.java similarity index 100% rename from src/core/org/luaj/vm2/compiler/Constants.java rename to core/src/main/java/org/luaj/vm2/compiler/Constants.java diff --git a/src/core/org/luaj/vm2/compiler/DumpState.java b/core/src/main/java/org/luaj/vm2/compiler/DumpState.java similarity index 99% rename from src/core/org/luaj/vm2/compiler/DumpState.java rename to core/src/main/java/org/luaj/vm2/compiler/DumpState.java index 3f92ba63..f53a3ea2 100644 --- a/src/core/org/luaj/vm2/compiler/DumpState.java +++ b/core/src/main/java/org/luaj/vm2/compiler/DumpState.java @@ -168,7 +168,7 @@ public class DumpState { break; case NUMBER_FORMAT_INTS_ONLY: if ( ! ALLOW_INTEGER_CASTING && ! o.isint() ) - throw new java.lang.IllegalArgumentException("not an integer: "+o); + throw new IllegalArgumentException("not an integer: "+o); writer.write(LuaValue.TNUMBER); dumpInt(o.toint()); break; diff --git a/src/core/org/luaj/vm2/compiler/FuncState.java b/core/src/main/java/org/luaj/vm2/compiler/FuncState.java similarity index 66% rename from src/core/org/luaj/vm2/compiler/FuncState.java rename to core/src/main/java/org/luaj/vm2/compiler/FuncState.java index 70e0f885..4c56a206 100644 --- a/src/core/org/luaj/vm2/compiler/FuncState.java +++ b/core/src/main/java/org/luaj/vm2/compiler/FuncState.java @@ -1,24 +1,24 @@ /******************************************************************************* -* Copyright (c) 2009 Luaj.org. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ + * Copyright (c) 2009 Luaj.org. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ package org.luaj.vm2.compiler; import java.util.Hashtable; @@ -45,7 +45,7 @@ public class FuncState extends Constants { boolean upval; /* true if some variable in the block is an upvalue */ boolean isloop; /* true if `block' is a loop */ }; - + Prototype f; /* current function header */ Hashtable h; /* table to find (and reuse) elements in `k' */ FuncState prev; /* enclosing function */ @@ -64,8 +64,8 @@ public class FuncState extends Constants { FuncState() { } - - + + // ============================================================= // from lcode.h // ============================================================= @@ -86,7 +86,7 @@ public class FuncState extends Constants { setreturns(e, LUA_MULTRET); } - + // ============================================================= // from lparser.c // ============================================================= @@ -97,7 +97,7 @@ public class FuncState extends Constants { for (i = bl.firstlabel; i < ll_n; i++) { if (label.eq_b(ll[i].name)) { String msg = ls.L.pushfstring( - "label '" + label + " already defined on line " + ll[i].line); + "label '" + label + " already defined on line " + ll[i].line); ls.semerror(msg); } } @@ -108,13 +108,13 @@ public class FuncState extends Constants { if ( v > l ) errorlimit( l, msg ); } - + void errorlimit (int limit, String what) { // TODO: report message logic. - String msg = (f.linedefined == 0) ? - ls.L.pushfstring("main function has more than "+limit+" "+what) : - ls.L.pushfstring("function at line "+f.linedefined+" has more than "+limit+" "+what); - ls.lexerror(msg, 0); + String msg = (f.linedefined == 0) ? + ls.L.pushfstring("main function has more than "+limit+" "+what) : + ls.L.pushfstring("function at line "+f.linedefined+" has more than "+limit+" "+what); + ls.lexerror(msg, 0); } LocVars getlocvar(int i) { @@ -124,19 +124,19 @@ public class FuncState extends Constants { } void removevars (int tolevel) { - ls.dyd.n_actvar -= (nactvar - tolevel); - while (nactvar > tolevel) - getlocvar(--nactvar).endpc = pc; + ls.dyd.n_actvar -= (nactvar - tolevel); + while (nactvar > tolevel) + getlocvar(--nactvar).endpc = pc; } int searchupvalue (LuaString name) { - int i; - Upvaldesc[] up = f.upvalues; - for (i = 0; i < nups; i++) - if (up[i].name.eq_b(name)) - return i; - return -1; /* not found */ + int i; + Upvaldesc[] up = f.upvalues; + for (i = 0; i < nups; i++) + if (up[i].name.eq_b(name)) + return i; + return -1; /* not found */ } int newupvalue (LuaString name, expdesc v) { @@ -144,9 +144,9 @@ public class FuncState extends Constants { if (f.upvalues == null || nups + 1 > f.upvalues.length) f.upvalues = realloc( f.upvalues, nups > 0 ? nups*2 : 1 ); f.upvalues[nups] = new Upvaldesc(name, v.k == LexState.VLOCAL, v.u.info); - return nups++; + return nups++; } - + int searchvar(LuaString n) { int i; for (i = nactvar - 1; i >= 0; i--) { @@ -155,14 +155,14 @@ public class FuncState extends Constants { } return -1; /* not found */ } - + void markupval(int level) { BlockCnt bl = this.bl; while (bl.nactvar > level) bl = bl.previous; bl.upval = true; } - + static int singlevaraux(FuncState fs, LuaString n, expdesc var, int base) { if (fs == null) /* no more levels? */ return LexState.VVOID; /* default is global */ @@ -173,24 +173,24 @@ public class FuncState extends Constants { fs.markupval(v); /* local will be used as an upval */ return LexState.VLOCAL; } else { /* not found at current level; try upvalues */ - int idx = fs.searchupvalue(n); /* try existing upvalues */ - if (idx < 0) { /* not found? */ - if (singlevaraux(fs.prev, n, var, 0) == LexState.VVOID) /* try upper levels */ - return LexState.VVOID; /* not found; is a global */ - /* else was LOCAL or UPVAL */ - idx = fs.newupvalue(n, var); /* will be a new upvalue */ - } - var.init(LexState.VUPVAL, idx); - return LexState.VUPVAL; + int idx = fs.searchupvalue(n); /* try existing upvalues */ + if (idx < 0) { /* not found? */ + if (singlevaraux(fs.prev, n, var, 0) == LexState.VVOID) /* try upper levels */ + return LexState.VVOID; /* not found; is a global */ + /* else was LOCAL or UPVAL */ + idx = fs.newupvalue(n, var); /* will be a new upvalue */ + } + var.init(LexState.VUPVAL, idx); + return LexState.VUPVAL; } } /* - ** "export" pending gotos to outer level, to check them against - ** outer labels; if the block being exited has upvalues, and - ** the goto exits the scope of any variable (which can be the - ** upvalue), close those variables being exited. - */ + ** "export" pending gotos to outer level, to check them against + ** outer labels; if the block being exited has upvalues, and + ** the goto exits the scope of any variable (which can be the + ** upvalue), close those variables being exited. + */ void movegotosout(BlockCnt bl) { int i = bl.firstgoto; final LexState.Labeldesc[] gl = ls.dyd.gt; @@ -207,37 +207,37 @@ public class FuncState extends Constants { i++; /* move to next one */ } } - + void enterblock (BlockCnt bl, boolean isloop) { - bl.isloop = isloop; - bl.nactvar = nactvar; - bl.firstlabel = (short) ls.dyd.n_label; - bl.firstgoto = (short) ls.dyd.n_gt; - bl.upval = false; - bl.previous = this.bl; - this.bl = bl; - _assert(this.freereg == this.nactvar); + bl.isloop = isloop; + bl.nactvar = nactvar; + bl.firstlabel = (short) ls.dyd.n_label; + bl.firstgoto = (short) ls.dyd.n_gt; + bl.upval = false; + bl.previous = this.bl; + this.bl = bl; + _assert(this.freereg == this.nactvar); } void leaveblock() { BlockCnt bl = this.bl; if (bl.previous != null && bl.upval) { - /* create a 'jump to here' to close upvalues */ - int j = this.jump(); - this.patchclose(j, bl.nactvar); - this.patchtohere(j); + /* create a 'jump to here' to close upvalues */ + int j = this.jump(); + this.patchclose(j, bl.nactvar); + this.patchtohere(j); } if (bl.isloop) - ls.breaklabel(); /* close pending breaks */ + ls.breaklabel(); /* close pending breaks */ this.bl = bl.previous; this.removevars(bl.nactvar); _assert(bl.nactvar == this.nactvar); this.freereg = this.nactvar; /* free registers */ ls.dyd.n_label = bl.firstlabel; /* remove local labels */ if (bl.previous != null) /* inner block? */ - this.movegotosout(bl); /* update pending gotos to outer block */ + this.movegotosout(bl); /* update pending gotos to outer block */ else if (bl.firstgoto < ls.dyd.n_gt) /* pending gotos in outer block? */ - ls.undefgoto(ls.dyd.gt[bl.firstgoto]); /* error */ + ls.undefgoto(ls.dyd.gt[bl.firstgoto]); /* error */ } void closelistfield(ConsControl cc) { @@ -258,19 +258,19 @@ public class FuncState extends Constants { void lastlistfield (ConsControl cc) { if (cc.tostore == 0) return; if (hasmultret(cc.v.k)) { - this.setmultret(cc.v); - this.setlist(cc.t.u.info, cc.na, LUA_MULTRET); - cc.na--; /** do not count last expression (unknown number of elements) */ + this.setmultret(cc.v); + this.setlist(cc.t.u.info, cc.na, LUA_MULTRET); + cc.na--; /** do not count last expression (unknown number of elements) */ } else { - if (cc.v.k != LexState.VVOID) - this.exp2nextreg(cc.v); - this.setlist(cc.t.u.info, cc.na, cc.tostore); + if (cc.v.k != LexState.VVOID) + this.exp2nextreg(cc.v); + this.setlist(cc.t.u.info, cc.na, cc.tostore); } } - - - + + + // ============================================================= // from lcode.c // ============================================================= @@ -479,7 +479,7 @@ public class FuncState extends Constants { return ((Integer) h.get(v)).intValue(); } final int idx = this.nk; - this.h.put(v, new Integer(idx)); + this.h.put(v, idx); final Prototype f = this.f; if (f.k == null || nk + 1 >= f.k.length) f.k = realloc( f.k, nk*2 + 1 ); @@ -531,33 +531,33 @@ public class FuncState extends Constants { void dischargevars(expdesc e) { switch (e.k) { - case LexState.VLOCAL: { - e.k = LexState.VNONRELOC; - break; - } - case LexState.VUPVAL: { - e.u.info = this.codeABC(OP_GETUPVAL, 0, e.u.info, 0); - e.k = LexState.VRELOCABLE; - break; - } - case LexState.VINDEXED: { - int op = OP_GETTABUP; /* assume 't' is in an upvalue */ - this.freereg(e.u.ind_idx); - if (e.u.ind_vt == LexState.VLOCAL) { /* 't' is in a register? */ - this.freereg(e.u.ind_t); - op = OP_GETTABLE; + case LexState.VLOCAL: { + e.k = LexState.VNONRELOC; + break; } - e.u.info = this.codeABC(op, 0, e.u.ind_t, e.u.ind_idx); - e.k = LexState.VRELOCABLE; - break; - } - case LexState.VVARARG: - case LexState.VCALL: { - this.setoneret(e); - break; - } - default: - break; /* there is one value available (somewhere) */ + case LexState.VUPVAL: { + e.u.info = this.codeABC(OP_GETUPVAL, 0, e.u.info, 0); + e.k = LexState.VRELOCABLE; + break; + } + case LexState.VINDEXED: { + int op = OP_GETTABUP; /* assume 't' is in an upvalue */ + this.freereg(e.u.ind_idx); + if (e.u.ind_vt == LexState.VLOCAL) { /* 't' is in a register? */ + this.freereg(e.u.ind_t); + op = OP_GETTABLE; + } + e.u.info = this.codeABC(op, 0, e.u.ind_t, e.u.ind_idx); + e.k = LexState.VRELOCABLE; + break; + } + case LexState.VVARARG: + case LexState.VCALL: { + this.setoneret(e); + break; + } + default: + break; /* there is one value available (somewhere) */ } } @@ -569,38 +569,38 @@ public class FuncState extends Constants { void discharge2reg(expdesc e, int reg) { this.dischargevars(e); switch (e.k) { - case LexState.VNIL: { - this.nil(reg, 1); - break; - } - case LexState.VFALSE: - case LexState.VTRUE: { - this.codeABC(OP_LOADBOOL, reg, (e.k == LexState.VTRUE ? 1 : 0), - 0); - break; - } - case LexState.VK: { - this.codeK(reg, e.u.info); - break; - } - case LexState.VKNUM: { - this.codeK(reg, this.numberK(e.u.nval())); - break; - } - case LexState.VRELOCABLE: { - InstructionPtr pc = this.getcodePtr(e); - SETARG_A(pc, reg); - break; - } - case LexState.VNONRELOC: { - if (reg != e.u.info) - this.codeABC(OP_MOVE, reg, e.u.info, 0); - break; - } - default: { - _assert (e.k == LexState.VVOID || e.k == LexState.VJMP); - return; /* nothing to do... */ - } + case LexState.VNIL: { + this.nil(reg, 1); + break; + } + case LexState.VFALSE: + case LexState.VTRUE: { + this.codeABC(OP_LOADBOOL, reg, (e.k == LexState.VTRUE ? 1 : 0), + 0); + break; + } + case LexState.VK: { + this.codeK(reg, e.u.info); + break; + } + case LexState.VKNUM: { + this.codeK(reg, this.numberK(e.u.nval())); + break; + } + case LexState.VRELOCABLE: { + InstructionPtr pc = this.getcodePtr(e); + SETARG_A(pc, reg); + break; + } + case LexState.VNONRELOC: { + if (reg != e.u.info) + this.codeABC(OP_MOVE, reg, e.u.info, 0); + break; + } + default: { + _assert (e.k == LexState.VVOID || e.k == LexState.VJMP); + return; /* nothing to do... */ + } } e.u.info = reg; e.k = LexState.VNONRELOC; @@ -673,57 +673,57 @@ public class FuncState extends Constants { int exp2RK(expdesc e) { this.exp2val(e); switch (e.k) { - case LexState.VTRUE: - case LexState.VFALSE: - case LexState.VNIL: { - if (this.nk <= MAXINDEXRK) { /* constant fit in RK operand? */ - e.u.info = (e.k == LexState.VNIL) ? this.nilK() - : this.boolK((e.k == LexState.VTRUE)); + case LexState.VTRUE: + case LexState.VFALSE: + case LexState.VNIL: { + if (this.nk <= MAXINDEXRK) { /* constant fit in RK operand? */ + e.u.info = (e.k == LexState.VNIL) ? this.nilK() + : this.boolK((e.k == LexState.VTRUE)); + e.k = LexState.VK; + return RKASK(e.u.info); + } else + break; + } + case LexState.VKNUM: { + e.u.info = this.numberK(e.u.nval()); e.k = LexState.VK; - return RKASK(e.u.info); - } else + /* go through */ + } + case LexState.VK: { + if (e.u.info <= MAXINDEXRK) /* constant fit in argC? */ + return RKASK(e.u.info); + else + break; + } + default: break; } - case LexState.VKNUM: { - e.u.info = this.numberK(e.u.nval()); - e.k = LexState.VK; - /* go through */ - } - case LexState.VK: { - if (e.u.info <= MAXINDEXRK) /* constant fit in argC? */ - return RKASK(e.u.info); - else - break; - } - default: - break; - } /* not a constant in the right range: put it in a register */ return this.exp2anyreg(e); } void storevar(expdesc var, expdesc ex) { switch (var.k) { - case LexState.VLOCAL: { - this.freeexp(ex); - this.exp2reg(ex, var.u.info); - return; - } - case LexState.VUPVAL: { - int e = this.exp2anyreg(ex); - this.codeABC(OP_SETUPVAL, e, var.u.info, 0); - break; - } - case LexState.VINDEXED: { - int op = (var.u.ind_vt == LexState.VLOCAL) ? OP_SETTABLE : OP_SETTABUP; - int e = this.exp2RK(ex); - this.codeABC(op, var.u.ind_t, var.u.ind_idx, e); - break; - } - default: { - _assert (false); /* invalid var kind to store */ - break; - } + case LexState.VLOCAL: { + this.freeexp(ex); + this.exp2reg(ex, var.u.info); + return; + } + case LexState.VUPVAL: { + int e = this.exp2anyreg(ex); + this.codeABC(OP_SETUPVAL, e, var.u.info, 0); + break; + } + case LexState.VINDEXED: { + int op = (var.u.ind_vt == LexState.VLOCAL) ? OP_SETTABLE : OP_SETTABUP; + int e = this.exp2RK(ex); + this.codeABC(op, var.u.ind_t, var.u.ind_idx, e); + break; + } + default: { + _assert (false); /* invalid var kind to store */ + break; + } } this.freeexp(ex); } @@ -769,21 +769,21 @@ public class FuncState extends Constants { int pc; /* pc of last jump */ this.dischargevars(e); switch (e.k) { - case LexState.VJMP: { - this.invertjump(e); - pc = e.u.info; - break; - } - case LexState.VK: - case LexState.VKNUM: - case LexState.VTRUE: { - pc = LexState.NO_JUMP; /* always true; do nothing */ - break; - } - default: { - pc = this.jumponcond(e, 0); - break; - } + case LexState.VJMP: { + this.invertjump(e); + pc = e.u.info; + break; + } + case LexState.VK: + case LexState.VKNUM: + case LexState.VTRUE: { + pc = LexState.NO_JUMP; /* always true; do nothing */ + break; + } + default: { + pc = this.jumponcond(e, 0); + break; + } } this.concat(e.f, pc); /* insert last jump in `f' list */ this.patchtohere(e.t.i); @@ -794,19 +794,19 @@ public class FuncState extends Constants { int pc; /* pc of last jump */ this.dischargevars(e); switch (e.k) { - case LexState.VJMP: { - pc = e.u.info; - break; - } - case LexState.VNIL: - case LexState.VFALSE: { - pc = LexState.NO_JUMP; /* always false; do nothing */ - break; - } - default: { - pc = this.jumponcond(e, 1); - break; - } + case LexState.VJMP: { + pc = e.u.info; + break; + } + case LexState.VNIL: + case LexState.VFALSE: { + pc = LexState.NO_JUMP; /* always false; do nothing */ + break; + } + default: { + pc = this.jumponcond(e, 1); + break; + } } this.concat(e.t, pc); /* insert last jump in `t' list */ this.patchtohere(e.f.i); @@ -816,33 +816,33 @@ public class FuncState extends Constants { void codenot(expdesc e) { this.dischargevars(e); switch (e.k) { - case LexState.VNIL: - case LexState.VFALSE: { - e.k = LexState.VTRUE; - break; - } - case LexState.VK: - case LexState.VKNUM: - case LexState.VTRUE: { - e.k = LexState.VFALSE; - break; - } - case LexState.VJMP: { - this.invertjump(e); - break; - } - case LexState.VRELOCABLE: - case LexState.VNONRELOC: { - this.discharge2anyreg(e); - this.freeexp(e); - e.u.info = this.codeABC(OP_NOT, 0, e.u.info, 0); - e.k = LexState.VRELOCABLE; - break; - } - default: { - _assert (false); /* cannot happen */ - break; - } + case LexState.VNIL: + case LexState.VFALSE: { + e.k = LexState.VTRUE; + break; + } + case LexState.VK: + case LexState.VKNUM: + case LexState.VTRUE: { + e.k = LexState.VFALSE; + break; + } + case LexState.VJMP: { + this.invertjump(e); + break; + } + case LexState.VRELOCABLE: + case LexState.VNONRELOC: { + this.discharge2anyreg(e); + this.freeexp(e); + e.u.info = this.codeABC(OP_NOT, 0, e.u.info, 0); + e.k = LexState.VRELOCABLE; + break; + } + default: { + _assert (false); /* cannot happen */ + break; + } } /* interchange true and false lists */ { @@ -871,39 +871,39 @@ public class FuncState extends Constants { if (!e1.isnumeral() || !e2.isnumeral()) return false; if ((op == OP_DIV || op == OP_MOD) && e2.u.nval().eq_b(LuaValue.ZERO)) - return false; /* do not attempt to divide by 0 */ + return false; /* do not attempt to divide by 0 */ v1 = e1.u.nval(); v2 = e2.u.nval(); switch (op) { - case OP_ADD: - r = v1.add(v2); - break; - case OP_SUB: - r = v1.sub(v2); - break; - case OP_MUL: - r = v1.mul(v2); - break; - case OP_DIV: - r = v1.div(v2); - break; - case OP_MOD: - r = v1.mod(v2); - break; - case OP_POW: - r = v1.pow(v2); - break; - case OP_UNM: - r = v1.neg(); - break; - case OP_LEN: - // r = v1.len(); - // break; - return false; /* no constant folding for 'len' */ - default: - _assert (false); - r = null; - break; + case OP_ADD: + r = v1.add(v2); + break; + case OP_SUB: + r = v1.sub(v2); + break; + case OP_MUL: + r = v1.mul(v2); + break; + case OP_DIV: + r = v1.div(v2); + break; + case OP_MOD: + r = v1.mod(v2); + break; + case OP_POW: + r = v1.pow(v2); + break; + case OP_UNM: + r = v1.neg(); + break; + case OP_LEN: + // r = v1.len(); + // break; + return false; /* no constant folding for 'len' */ + default: + _assert (false); + r = null; + break; } if ( Double.isNaN(r.todouble()) ) return false; /* do not attempt to produce NaN */ @@ -951,131 +951,131 @@ public class FuncState extends Constants { expdesc e2 = new expdesc(); e2.init(LexState.VKNUM, 0); switch (op) { - case LexState.OPR_MINUS: { - if (e.isnumeral()) /* minus constant? */ - e.u.setNval(e.u.nval().neg()); /* fold it */ - else { - this.exp2anyreg(e); - this.codearith(OP_UNM, e, e2, line); - } - break; - } - case LexState.OPR_NOT: - this.codenot(e); - break; - case LexState.OPR_LEN: { - this.exp2anyreg(e); /* cannot operate on constants */ - this.codearith(OP_LEN, e, e2, line); - break; - } - default: - _assert (false); + case LexState.OPR_MINUS: { + if (e.isnumeral()) /* minus constant? */ + e.u.setNval(e.u.nval().neg()); /* fold it */ + else { + this.exp2anyreg(e); + this.codearith(OP_UNM, e, e2, line); + } + break; + } + case LexState.OPR_NOT: + this.codenot(e); + break; + case LexState.OPR_LEN: { + this.exp2anyreg(e); /* cannot operate on constants */ + this.codearith(OP_LEN, e, e2, line); + break; + } + default: + _assert (false); } } void infix(int /* BinOpr */op, expdesc v) { switch (op) { - case LexState.OPR_AND: { - this.goiftrue(v); - break; - } - case LexState.OPR_OR: { - this.goiffalse(v); - break; - } - case LexState.OPR_CONCAT: { - this.exp2nextreg(v); /* operand must be on the `stack' */ - break; - } - case LexState.OPR_ADD: - case LexState.OPR_SUB: - case LexState.OPR_MUL: - case LexState.OPR_DIV: - case LexState.OPR_MOD: - case LexState.OPR_POW: { - if (!v.isnumeral()) + case LexState.OPR_AND: { + this.goiftrue(v); + break; + } + case LexState.OPR_OR: { + this.goiffalse(v); + break; + } + case LexState.OPR_CONCAT: { + this.exp2nextreg(v); /* operand must be on the `stack' */ + break; + } + case LexState.OPR_ADD: + case LexState.OPR_SUB: + case LexState.OPR_MUL: + case LexState.OPR_DIV: + case LexState.OPR_MOD: + case LexState.OPR_POW: { + if (!v.isnumeral()) + this.exp2RK(v); + break; + } + default: { this.exp2RK(v); - break; - } - default: { - this.exp2RK(v); - break; - } + break; + } } } void posfix(int op, expdesc e1, expdesc e2, int line) { switch (op) { - case LexState.OPR_AND: { - _assert (e1.t.i == LexState.NO_JUMP); /* list must be closed */ - this.dischargevars(e2); - this.concat(e2.f, e1.f.i); - // *e1 = *e2; - e1.setvalue(e2); - break; - } - case LexState.OPR_OR: { - _assert (e1.f.i == LexState.NO_JUMP); /* list must be closed */ - this.dischargevars(e2); - this.concat(e2.t, e1.t.i); - // *e1 = *e2; - e1.setvalue(e2); - break; - } - case LexState.OPR_CONCAT: { - this.exp2val(e2); - if (e2.k == LexState.VRELOCABLE - && GET_OPCODE(this.getcode(e2)) == OP_CONCAT) { - _assert (e1.u.info == GETARG_B(this.getcode(e2)) - 1); - this.freeexp(e1); - SETARG_B(this.getcodePtr(e2), e1.u.info); - e1.k = LexState.VRELOCABLE; - e1.u.info = e2.u.info; - } else { - this.exp2nextreg(e2); /* operand must be on the 'stack' */ - this.codearith(OP_CONCAT, e1, e2, line); + case LexState.OPR_AND: { + _assert (e1.t.i == LexState.NO_JUMP); /* list must be closed */ + this.dischargevars(e2); + this.concat(e2.f, e1.f.i); + // *e1 = *e2; + e1.setvalue(e2); + break; } - break; - } - case LexState.OPR_ADD: - this.codearith(OP_ADD, e1, e2, line); - break; - case LexState.OPR_SUB: - this.codearith(OP_SUB, e1, e2, line); - break; - case LexState.OPR_MUL: - this.codearith(OP_MUL, e1, e2, line); - break; - case LexState.OPR_DIV: - this.codearith(OP_DIV, e1, e2, line); - break; - case LexState.OPR_MOD: - this.codearith(OP_MOD, e1, e2, line); - break; - case LexState.OPR_POW: - this.codearith(OP_POW, e1, e2, line); - break; - case LexState.OPR_EQ: - this.codecomp(OP_EQ, 1, e1, e2); - break; - case LexState.OPR_NE: - this.codecomp(OP_EQ, 0, e1, e2); - break; - case LexState.OPR_LT: - this.codecomp(OP_LT, 1, e1, e2); - break; - case LexState.OPR_LE: - this.codecomp(OP_LE, 1, e1, e2); - break; - case LexState.OPR_GT: - this.codecomp(OP_LT, 0, e1, e2); - break; - case LexState.OPR_GE: - this.codecomp(OP_LE, 0, e1, e2); - break; - default: - _assert (false); + case LexState.OPR_OR: { + _assert (e1.f.i == LexState.NO_JUMP); /* list must be closed */ + this.dischargevars(e2); + this.concat(e2.t, e1.t.i); + // *e1 = *e2; + e1.setvalue(e2); + break; + } + case LexState.OPR_CONCAT: { + this.exp2val(e2); + if (e2.k == LexState.VRELOCABLE + && GET_OPCODE(this.getcode(e2)) == OP_CONCAT) { + _assert (e1.u.info == GETARG_B(this.getcode(e2)) - 1); + this.freeexp(e1); + SETARG_B(this.getcodePtr(e2), e1.u.info); + e1.k = LexState.VRELOCABLE; + e1.u.info = e2.u.info; + } else { + this.exp2nextreg(e2); /* operand must be on the 'stack' */ + this.codearith(OP_CONCAT, e1, e2, line); + } + break; + } + case LexState.OPR_ADD: + this.codearith(OP_ADD, e1, e2, line); + break; + case LexState.OPR_SUB: + this.codearith(OP_SUB, e1, e2, line); + break; + case LexState.OPR_MUL: + this.codearith(OP_MUL, e1, e2, line); + break; + case LexState.OPR_DIV: + this.codearith(OP_DIV, e1, e2, line); + break; + case LexState.OPR_MOD: + this.codearith(OP_MOD, e1, e2, line); + break; + case LexState.OPR_POW: + this.codearith(OP_POW, e1, e2, line); + break; + case LexState.OPR_EQ: + this.codecomp(OP_EQ, 1, e1, e2); + break; + case LexState.OPR_NE: + this.codecomp(OP_EQ, 0, e1, e2); + break; + case LexState.OPR_LT: + this.codecomp(OP_LT, 1, e1, e2); + break; + case LexState.OPR_LE: + this.codecomp(OP_LE, 1, e1, e2); + break; + case LexState.OPR_GT: + this.codecomp(OP_LT, 0, e1, e2); + break; + case LexState.OPR_GE: + this.codecomp(OP_LE, 0, e1, e2); + break; + default: + _assert (false); } } @@ -1143,5 +1143,5 @@ public class FuncState extends Constants { } this.freereg = (short) (base + 1); /* free registers with list values */ } - -} + +} \ No newline at end of file diff --git a/src/core/org/luaj/vm2/compiler/InstructionPtr.java b/core/src/main/java/org/luaj/vm2/compiler/InstructionPtr.java similarity index 100% rename from src/core/org/luaj/vm2/compiler/InstructionPtr.java rename to core/src/main/java/org/luaj/vm2/compiler/InstructionPtr.java diff --git a/src/core/org/luaj/vm2/compiler/IntPtr.java b/core/src/main/java/org/luaj/vm2/compiler/IntPtr.java similarity index 100% rename from src/core/org/luaj/vm2/compiler/IntPtr.java rename to core/src/main/java/org/luaj/vm2/compiler/IntPtr.java diff --git a/src/core/org/luaj/vm2/compiler/LexState.java b/core/src/main/java/org/luaj/vm2/compiler/LexState.java similarity index 64% rename from src/core/org/luaj/vm2/compiler/LexState.java rename to core/src/main/java/org/luaj/vm2/compiler/LexState.java index 0192de05..e889514e 100644 --- a/src/core/org/luaj/vm2/compiler/LexState.java +++ b/core/src/main/java/org/luaj/vm2/compiler/LexState.java @@ -1,24 +1,24 @@ /******************************************************************************* -* Copyright (c) 2009 Luaj.org. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ + * Copyright (c) 2009 Luaj.org. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ package org.luaj.vm2.compiler; import java.io.IOException; @@ -37,81 +37,81 @@ import org.luaj.vm2.lib.MathLib; public class LexState extends Constants { - + protected static final String RESERVED_LOCAL_VAR_FOR_CONTROL = "(for control)"; - protected static final String RESERVED_LOCAL_VAR_FOR_STATE = "(for state)"; - protected static final String RESERVED_LOCAL_VAR_FOR_GENERATOR = "(for generator)"; - protected static final String RESERVED_LOCAL_VAR_FOR_STEP = "(for step)"; - protected static final String RESERVED_LOCAL_VAR_FOR_LIMIT = "(for limit)"; - protected static final String RESERVED_LOCAL_VAR_FOR_INDEX = "(for index)"; - - // keywords array - protected static final String[] RESERVED_LOCAL_VAR_KEYWORDS = new String[] { - RESERVED_LOCAL_VAR_FOR_CONTROL, - RESERVED_LOCAL_VAR_FOR_GENERATOR, - RESERVED_LOCAL_VAR_FOR_INDEX, - RESERVED_LOCAL_VAR_FOR_LIMIT, - RESERVED_LOCAL_VAR_FOR_STATE, - RESERVED_LOCAL_VAR_FOR_STEP - }; - private static final Hashtable RESERVED_LOCAL_VAR_KEYWORDS_TABLE = new Hashtable(); - static { - for ( int i=0; i=", "<=", "~=", - "::", "", "", "", "", "", + "and", "break", "do", "else", "elseif", + "end", "false", "for", "function", "goto", "if", + "in", "local", "nil", "not", "or", "repeat", + "return", "then", "true", "until", "while", + "..", "...", "==", ">=", "<=", "~=", + "::", "", "", "", "", "", }; final static int - /* terminal symbols denoted by reserved words */ - TK_AND=257, TK_BREAK=258, TK_DO=259, TK_ELSE=260, TK_ELSEIF=261, - TK_END=262, TK_FALSE=263, TK_FOR=264, TK_FUNCTION=265, TK_GOTO=266, TK_IF=267, - TK_IN=268, TK_LOCAL=269, TK_NIL=270, TK_NOT=271, TK_OR=272, TK_REPEAT=273, - TK_RETURN=274, TK_THEN=275, TK_TRUE=276, TK_UNTIL=277, TK_WHILE=278, - /* other terminal symbols */ - TK_CONCAT=279, TK_DOTS=280, TK_EQ=281, TK_GE=282, TK_LE=283, TK_NE=284, - TK_DBCOLON=285, TK_EOS=286, TK_NUMBER=287, TK_NAME=288, TK_STRING=289; - + /* terminal symbols denoted by reserved words */ + TK_AND=257, TK_BREAK=258, TK_DO=259, TK_ELSE=260, TK_ELSEIF=261, + TK_END=262, TK_FALSE=263, TK_FOR=264, TK_FUNCTION=265, TK_GOTO=266, TK_IF=267, + TK_IN=268, TK_LOCAL=269, TK_NIL=270, TK_NOT=271, TK_OR=272, TK_REPEAT=273, + TK_RETURN=274, TK_THEN=275, TK_TRUE=276, TK_UNTIL=277, TK_WHILE=278, + /* other terminal symbols */ + TK_CONCAT=279, TK_DOTS=280, TK_EQ=281, TK_GE=282, TK_LE=283, TK_NE=284, + TK_DBCOLON=285, TK_EOS=286, TK_NUMBER=287, TK_NAME=288, TK_STRING=289; + final static int FIRST_RESERVED = TK_AND; final static int NUM_RESERVED = TK_WHILE+1-FIRST_RESERVED; - + final static Hashtable RESERVED = new Hashtable(); static { for ( int i=0; i= '0' && c <= '9') - || (c >= 'a' && c <= 'z') - || (c >= 'A' && c <= 'Z') - || (c == '_'); + || (c >= 'a' && c <= 'z') + || (c >= 'A' && c <= 'Z') + || (c == '_'); // return Character.isLetterOrDigit(c); } - + private boolean isalpha(int c) { return (c >= 'a' && c <= 'z') - || (c >= 'A' && c <= 'Z'); + || (c >= 'A' && c <= 'Z'); } - + private boolean isdigit(int c) { return (c >= '0' && c <= '9'); } - + private boolean isxdigit(int c) { return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); } - + private boolean isspace(int c) { return (c >= 0 && c <= ' '); } - - + + public LexState(LuaC.CompileState state, InputStream stream) { this.z = stream; this.buff = new char[32]; @@ -210,7 +210,7 @@ public class LexState extends Constants { void nextChar() { try { - current = z.read(); + current = z.read(); } catch ( IOException e ) { e.printStackTrace(); current = EOZ; @@ -249,12 +249,12 @@ public class LexState extends Constants { String txtToken(int token) { switch ( token ) { - case TK_NAME: - case TK_STRING: - case TK_NUMBER: - return new String( buff, 0, nbuff ); - default: - return token2str( token ); + case TK_NAME: + case TK_STRING: + case TK_NUMBER: + return new String( buff, 0, nbuff ); + default: + return token2str( token ); } } @@ -303,20 +303,20 @@ public class LexState extends Constants { this.current = firstByte; /* read first char */ this.skipShebang(); } - + private void skipShebang() { if ( current == '#' ) while (!currIsNewline() && current != EOZ) nextChar(); } - + /* - ** ======================================================= - ** LEXICAL ANALYZER - ** ======================================================= - */ + ** ======================================================= + ** LEXICAL ANALYZER + ** ======================================================= + */ boolean check_next(String set) { @@ -382,7 +382,7 @@ public class LexState extends Constants { } return LuaValue.valueOf(sgn * m * MathLib.dpow_d(2.0, e)); } - + boolean str2d(String str, SemInfo seminfo) { if (str.indexOf('n')>=0 || str.indexOf('N')>=0) seminfo.r = LuaValue.ZERO; @@ -436,47 +436,47 @@ public class LexState extends Constants { inclinenumber(); /* skip it */ for (boolean endloop = false; !endloop;) { switch (current) { - case EOZ: - lexerror((seminfo != null) ? "unfinished long string" - : "unfinished long comment", TK_EOS); - break; /* to avoid warnings */ - case '[': { - if (skip_sep() == sep) { - save_and_next(); /* skip 2nd `[' */ - cont++; - if (LUA_COMPAT_LSTR == 1) { - if (sep == 0) - lexerror("nesting of [[...]] is deprecated", '['); + case EOZ: + lexerror((seminfo != null) ? "unfinished long string" + : "unfinished long comment", TK_EOS); + break; /* to avoid warnings */ + case '[': { + if (skip_sep() == sep) { + save_and_next(); /* skip 2nd `[' */ + cont++; + if (LUA_COMPAT_LSTR == 1) { + if (sep == 0) + lexerror("nesting of [[...]] is deprecated", '['); + } } + break; } - break; - } - case ']': { - if (skip_sep() == sep) { - save_and_next(); /* skip 2nd `]' */ - if (LUA_COMPAT_LSTR == 2) { - cont--; - if (sep == 0 && cont >= 0) - break; + case ']': { + if (skip_sep() == sep) { + save_and_next(); /* skip 2nd `]' */ + if (LUA_COMPAT_LSTR == 2) { + cont--; + if (sep == 0 && cont >= 0) + break; + } + endloop = true; } - endloop = true; + break; + } + case '\n': + case '\r': { + save('\n'); + inclinenumber(); + if (seminfo == null) + nbuff = 0; /* avoid wasting space */ + break; + } + default: { + if (seminfo != null) + save_and_next(); + else + nextChar(); } - break; - } - case '\n': - case '\r': { - save('\n'); - inclinenumber(); - if (seminfo == null) - nbuff = 0; /* avoid wasting space */ - break; - } - default: { - if (seminfo != null) - save_and_next(); - else - nextChar(); - } } } if (seminfo != null) @@ -501,79 +501,79 @@ public class LexState extends Constants { save_and_next(); while (current != del) { switch (current) { - case EOZ: - lexerror("unfinished string", TK_EOS); - continue; /* to avoid warnings */ - case '\n': - case '\r': - lexerror("unfinished string", TK_STRING); - continue; /* to avoid warnings */ - case '\\': { - int c; - nextChar(); /* do not save the `\' */ - switch (current) { - case 'a': /* bell */ - c = '\u0007'; - break; - case 'b': /* backspace */ - c = '\b'; - break; - case 'f': /* form feed */ - c = '\f'; - break; - case 'n': /* newline */ - c = '\n'; - break; - case 'r': /* carriage return */ - c = '\r'; - break; - case 't': /* tab */ - c = '\t'; - break; - case 'v': /* vertical tab */ - c = '\u000B'; - break; - case 'x': - c = readhexaesc(); - break; - case '\n': /* go through */ - case '\r': - save('\n'); - inclinenumber(); - continue; case EOZ: - continue; /* will raise an error next loop */ - case 'z': { /* zap following span of spaces */ - nextChar(); /* skip the 'z' */ - while (isspace(current)) { - if (currIsNewline()) inclinenumber(); - else nextChar(); - } - continue; - } - default: { - if (!isdigit(current)) - save_and_next(); /* handles \\, \", \', and \? */ - else { /* \xxx */ - int i = 0; - c = 0; - do { - c = 10 * c + (current - '0'); - nextChar(); - } while (++i < 3 && isdigit(current)); - if (c > UCHAR_MAX) - lexerror("escape sequence too large", TK_STRING); - save(c); + lexerror("unfinished string", TK_EOS); + continue; /* to avoid warnings */ + case '\n': + case '\r': + lexerror("unfinished string", TK_STRING); + continue; /* to avoid warnings */ + case '\\': { + int c; + nextChar(); /* do not save the `\' */ + switch (current) { + case 'a': /* bell */ + c = '\u0007'; + break; + case 'b': /* backspace */ + c = '\b'; + break; + case 'f': /* form feed */ + c = '\f'; + break; + case 'n': /* newline */ + c = '\n'; + break; + case 'r': /* carriage return */ + c = '\r'; + break; + case 't': /* tab */ + c = '\t'; + break; + case 'v': /* vertical tab */ + c = '\u000B'; + break; + case 'x': + c = readhexaesc(); + break; + case '\n': /* go through */ + case '\r': + save('\n'); + inclinenumber(); + continue; + case EOZ: + continue; /* will raise an error next loop */ + case 'z': { /* zap following span of spaces */ + nextChar(); /* skip the 'z' */ + while (isspace(current)) { + if (currIsNewline()) inclinenumber(); + else nextChar(); + } + continue; + } + default: { + if (!isdigit(current)) + save_and_next(); /* handles \\, \", \', and \? */ + else { /* \xxx */ + int i = 0; + c = 0; + do { + c = 10 * c + (current - '0'); + nextChar(); + } while (++i < 3 && isdigit(current)); + if (c > UCHAR_MAX) + lexerror("escape sequence too large", TK_STRING); + save(c); + } + continue; + } } + save(c); + nextChar(); continue; } - } - save(c); - nextChar(); - continue; - } - default: - save_and_next(); + default: + save_and_next(); } } save_and_next(); /* skip delimiter */ @@ -584,140 +584,140 @@ public class LexState extends Constants { nbuff = 0; while (true) { switch (current) { - case '\n': - case '\r': { - inclinenumber(); - continue; - } - case ' ': - case '\f': - case '\t': - case 0x0B: /* \v */ { - nextChar(); - continue; - } - case '-': { - nextChar(); - if (current != '-') - return '-'; - /* else is a comment */ - nextChar(); - if (current == '[') { + case '\n': + case '\r': { + inclinenumber(); + continue; + } + case ' ': + case '\f': + case '\t': + case 0x0B: /* \v */ { + nextChar(); + continue; + } + case '-': { + nextChar(); + if (current != '-') + return '-'; + /* else is a comment */ + nextChar(); + if (current == '[') { + int sep = skip_sep(); + nbuff = 0; /* `skip_sep' may dirty the buffer */ + if (sep >= 0) { + read_long_string(null, sep); /* long comment */ + nbuff = 0; + continue; + } + } + /* else short comment */ + while (!currIsNewline() && current != EOZ) + nextChar(); + continue; + } + case '[': { int sep = skip_sep(); - nbuff = 0; /* `skip_sep' may dirty the buffer */ if (sep >= 0) { - read_long_string(null, sep); /* long comment */ - nbuff = 0; - continue; + read_long_string(seminfo, sep); + return TK_STRING; + } else if (sep == -1) + return '['; + else + lexerror("invalid long string delimiter", TK_STRING); + } + case '=': { + nextChar(); + if (current != '=') + return '='; + else { + nextChar(); + return TK_EQ; } } - /* else short comment */ - while (!currIsNewline() && current != EOZ) + case '<': { nextChar(); - continue; - } - case '[': { - int sep = skip_sep(); - if (sep >= 0) { - read_long_string(seminfo, sep); + if (current != '=') + return '<'; + else { + nextChar(); + return TK_LE; + } + } + case '>': { + nextChar(); + if (current != '=') + return '>'; + else { + nextChar(); + return TK_GE; + } + } + case '~': { + nextChar(); + if (current != '=') + return '~'; + else { + nextChar(); + return TK_NE; + } + } + case ':': { + nextChar(); + if (current != ':') + return ':'; + else { + nextChar(); + return TK_DBCOLON; + } + } + case '"': + case '\'': { + read_string(current, seminfo); return TK_STRING; - } else if (sep == -1) - return '['; - else - lexerror("invalid long string delimiter", TK_STRING); - } - case '=': { - nextChar(); - if (current != '=') - return '='; - else { - nextChar(); - return TK_EQ; } - } - case '<': { - nextChar(); - if (current != '=') - return '<'; - else { - nextChar(); - return TK_LE; + case '.': { + save_and_next(); + if (check_next(".")) { + if (check_next(".")) + return TK_DOTS; /* ... */ + else + return TK_CONCAT; /* .. */ + } else if (!isdigit(current)) + return '.'; + else { + read_numeral(seminfo); + return TK_NUMBER; + } } - } - case '>': { - nextChar(); - if (current != '=') - return '>'; - else { - nextChar(); - return TK_GE; - } - } - case '~': { - nextChar(); - if (current != '=') - return '~'; - else { - nextChar(); - return TK_NE; - } - } - case ':': { - nextChar(); - if (current != ':') - return ':'; - else { - nextChar(); - return TK_DBCOLON; - } - } - case '"': - case '\'': { - read_string(current, seminfo); - return TK_STRING; - } - case '.': { - save_and_next(); - if (check_next(".")) { - if (check_next(".")) - return TK_DOTS; /* ... */ - else - return TK_CONCAT; /* .. */ - } else if (!isdigit(current)) - return '.'; - else { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': { read_numeral(seminfo); return TK_NUMBER; } - } - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': { - read_numeral(seminfo); - return TK_NUMBER; - } - case EOZ: { - return TK_EOS; - } - default: { - if (isalpha(current) || current == '_') { - /* identifier or reserved word */ - LuaString ts; - do { - save_and_next(); - } while (isalnum(current)); - ts = newstring(buff, 0, nbuff); - if ( RESERVED.containsKey(ts) ) - return ((Integer)RESERVED.get(ts)).intValue(); - else { - seminfo.ts = ts; - return TK_NAME; - } - } else { - int c = current; - nextChar(); - return c; /* single-char tokens (+ - / ...) */ + case EOZ: { + return TK_EOS; + } + default: { + if (isalpha(current) || current == '_') { + /* identifier or reserved word */ + LuaString ts; + do { + save_and_next(); + } while (isalnum(current)); + ts = newstring(buff, 0, nbuff); + if ( RESERVED.containsKey(ts) ) + return ((Integer)RESERVED.get(ts)).intValue(); + else { + seminfo.ts = ts; + return TK_NAME; + } + } else { + int c = current; + nextChar(); + return c; /* single-char tokens (+ - / ...) */ + } } - } } } } @@ -739,8 +739,8 @@ public class LexState extends Constants { // ============================================================= // from lcode.h // ============================================================= - - + + // ============================================================= // from lparser.c // ============================================================= @@ -832,8 +832,8 @@ public class LexState extends Constants { Labeldesc[] label; /* list of active labels */ int n_label = 0; }; - - + + boolean hasmultret(int k) { return ((k) == VCALL || (k) == VVARARG); } @@ -841,7 +841,7 @@ public class LexState extends Constants { /*---------------------------------------------------------------------- name args description ------------------------------------------------------------------------*/ - + void anchor_token () { /* last token from outer function must be EOS */ _assert(fs != null || t.token == TK_EOS); @@ -876,8 +876,8 @@ public class LexState extends Constants { } void checknext (int c) { - check(c); - next(); + check(c); + next(); } void check_condition(boolean c, String msg) { @@ -905,7 +905,7 @@ public class LexState extends Constants { next(); return ts; } - + void codestring(expdesc e, LuaString s) { e.init(VK, fs.stringK(s)); } @@ -914,7 +914,7 @@ public class LexState extends Constants { codestring(e, str_checkname()); } - + int registerlocalvar(LuaString varname) { FuncState fs = this.fs; Prototype f = fs.f; @@ -923,7 +923,7 @@ public class LexState extends Constants { f.locvars[fs.nlocvars] = new LocVars(varname,0,0); return fs.nlocvars++; } - + void new_localvar(LuaString name) { int reg = registerlocalvar(name); fs.checklimit(dyd.n_actvar + 1, FuncState.LUAI_MAXVARS, "local variables"); @@ -950,19 +950,19 @@ public class LexState extends Constants { while (fs.nactvar > tolevel) fs.getlocvar(--fs.nactvar).endpc = fs.pc; } - + void singlevar(expdesc var) { LuaString varname = this.str_checkname(); FuncState fs = this.fs; if (FuncState.singlevaraux(fs, varname, var, 1) == VVOID) { /* global name? */ expdesc key = new expdesc(); - FuncState.singlevaraux(fs, this.envn, var, 1); /* get environment variable */ - _assert(var.k == VLOCAL || var.k == VUPVAL); - this.codestring(key, varname); /* key is variable name */ - fs.indexed(var, key); /* env[varname] */ + FuncState.singlevaraux(fs, this.envn, var, 1); /* get environment variable */ + _assert(var.k == VLOCAL || var.k == VUPVAL); + this.codestring(key, varname); /* key is variable name */ + fs.indexed(var, key); /* env[varname] */ } } - + void adjust_assign(int nvars, int nexps, expdesc e) { FuncState fs = this.fs; int extra = nvars - nexps; @@ -986,12 +986,12 @@ public class LexState extends Constants { } } } - + void enterlevel() { if (++L.nCcalls > LUAI_MAXCCALLS) lexerror("chunk has too many syntax levels", 0); } - + void leavelevel() { L.nCcalls--; } @@ -1056,11 +1056,11 @@ public class LexState extends Constants { i++; } } - + /* - ** create a label named "break" to resolve break statements - */ + ** create a label named "break" to resolve break statements + */ void breaklabel () { LuaString n = LuaString.valueOf("break"); int l = newlabelentry(dyd.label=grow(dyd.label, dyd.n_label+1), dyd.n_label++, n, 0, fs.pc); @@ -1068,50 +1068,50 @@ public class LexState extends Constants { } /* - ** generates an error for an undefined 'goto'; choose appropriate - ** message when label name is a reserved word (which can only be 'break') - */ + ** generates an error for an undefined 'goto'; choose appropriate + ** message when label name is a reserved word (which can only be 'break') + */ void undefgoto (Labeldesc gt) { - String msg = L.pushfstring(isReservedKeyword(gt.name.tojstring()) - ? "<"+gt.name+"> at line "+gt.line+" not inside a loop" - : "no visible label '"+gt.name+"' for at line "+gt.line); - semerror(msg); + String msg = L.pushfstring(isReservedKeyword(gt.name.tojstring()) + ? "<"+gt.name+"> at line "+gt.line+" not inside a loop" + : "no visible label '"+gt.name+"' for at line "+gt.line); + semerror(msg); } Prototype addprototype () { - Prototype clp; - Prototype f = fs.f; /* prototype of current function */ - if (f.p == null || fs.np >= f.p.length) { - f.p = realloc(f.p, Math.max(1, fs.np * 2)); - } - f.p[fs.np++] = clp = new Prototype(); - return clp; + Prototype clp; + Prototype f = fs.f; /* prototype of current function */ + if (f.p == null || fs.np >= f.p.length) { + f.p = realloc(f.p, Math.max(1, fs.np * 2)); + } + f.p[fs.np++] = clp = new Prototype(); + return clp; } void codeclosure (expdesc v) { - FuncState fs = this.fs.prev; - v.init(VRELOCABLE, fs.codeABx(OP_CLOSURE, 0, fs.np - 1)); - fs.exp2nextreg(v); /* fix it at stack top (for GC) */ + FuncState fs = this.fs.prev; + v.init(VRELOCABLE, fs.codeABx(OP_CLOSURE, 0, fs.np - 1)); + fs.exp2nextreg(v); /* fix it at stack top (for GC) */ } void open_func (FuncState fs, BlockCnt bl) { - fs.prev = this.fs; /* linked list of funcstates */ - fs.ls = this; - this.fs = fs; - fs.pc = 0; - fs.lasttarget = -1; - fs.jpc = new IntPtr( NO_JUMP ); - fs.freereg = 0; - fs.nk = 0; - fs.np = 0; - fs.nups = 0; - fs.nlocvars = 0; - fs.nactvar = 0; - fs.firstlocal = dyd.n_actvar; - fs.bl = null; - fs.f.source = this.source; - fs.f.maxstacksize = 2; /* registers 0/1 are always valid */ - fs.enterblock(bl, false); + fs.prev = this.fs; /* linked list of funcstates */ + fs.ls = this; + this.fs = fs; + fs.pc = 0; + fs.lasttarget = -1; + fs.jpc = new IntPtr( NO_JUMP ); + fs.freereg = 0; + fs.nk = 0; + fs.np = 0; + fs.nups = 0; + fs.nlocvars = 0; + fs.nactvar = 0; + fs.firstlocal = dyd.n_actvar; + fs.bl = null; + fs.f.source = this.source; + fs.f.maxstacksize = 2; /* registers 0/1 are always valid */ + fs.enterblock(bl, false); } void close_func() { @@ -1144,7 +1144,7 @@ public class LexState extends Constants { this.checkname(key); fs.indexed(v, key); } - + void yindex(expdesc v) { /* index -> '[' expr ']' */ this.next(); /* skip the '[' */ @@ -1154,11 +1154,11 @@ public class LexState extends Constants { } - /* - ** {====================================================================== - ** Rules for Constructors - ** ======================================================================= - */ + /* + ** {====================================================================== + ** Rules for Constructors + ** ======================================================================= + */ static class ConsControl { @@ -1192,10 +1192,10 @@ public class LexState extends Constants { } void listfield (ConsControl cc) { - this.expr(cc.v); - fs.checklimit(cc.na, MAX_INT, "items in a constructor"); - cc.na++; - cc.tostore++; + this.expr(cc.v); + fs.checklimit(cc.na, MAX_INT, "items in a constructor"); + cc.na++; + cc.tostore++; } @@ -1217,22 +1217,22 @@ public class LexState extends Constants { break; fs.closelistfield(cc); switch (this.t.token) { - case TK_NAME: { /* may be listfields or recfields */ - this.lookahead(); - if (this.lookahead.token != '=') /* expression? */ - this.listfield(cc); - else + case TK_NAME: { /* may be listfields or recfields */ + this.lookahead(); + if (this.lookahead.token != '=') /* expression? */ + this.listfield(cc); + else + this.recfield(cc); + break; + } + case '[': { /* constructor_item -> recfield */ this.recfield(cc); - break; - } - case '[': { /* constructor_item -> recfield */ - this.recfield(cc); - break; - } - default: { /* constructor_part -> listfield */ - this.listfield(cc); - break; - } + break; + } + default: { /* constructor_part -> listfield */ + this.listfield(cc); + break; + } } } while (this.testnext(',') || this.testnext(';')); this.check_match('}', '{', line); @@ -1241,51 +1241,51 @@ public class LexState extends Constants { SETARG_B(i, luaO_int2fb(cc.na)); /* set initial array size */ SETARG_C(i, luaO_int2fb(cc.nh)); /* set initial table size */ } - + /* - ** converts an integer to a "floating point byte", represented as - ** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if - ** eeeee != 0 and (xxx) otherwise. - */ + ** converts an integer to a "floating point byte", represented as + ** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if + ** eeeee != 0 and (xxx) otherwise. + */ static int luaO_int2fb (int x) { - int e = 0; /* expoent */ - while (x >= 16) { - x = (x+1) >> 1; - e++; - } - if (x < 8) return x; - else return ((e+1) << 3) | (((int)x) - 8); + int e = 0; /* expoent */ + while (x >= 16) { + x = (x+1) >> 1; + e++; + } + if (x < 8) return x; + else return ((e+1) << 3) | (((int)x) - 8); } /* }====================================================================== */ void parlist () { - /* parlist -> [ param { `,' param } ] */ - FuncState fs = this.fs; - Prototype f = fs.f; - int nparams = 0; - f.is_vararg = 0; - if (this.t.token != ')') { /* is `parlist' not empty? */ - do { - switch (this.t.token) { - case TK_NAME: { /* param . NAME */ - this.new_localvar(this.str_checkname()); - ++nparams; - break; - } - case TK_DOTS: { /* param . `...' */ - this.next(); - f.is_vararg = 1; - break; - } - default: this.syntaxerror(" or " + LUA_QL("...") + " expected"); - } - } while ((f.is_vararg==0) && this.testnext(',')); - } - this.adjustlocalvars(nparams); - f.numparams = fs.nactvar; - fs.reserveregs(fs.nactvar); /* reserve register for parameters */ + /* parlist -> [ param { `,' param } ] */ + FuncState fs = this.fs; + Prototype f = fs.f; + int nparams = 0; + f.is_vararg = 0; + if (this.t.token != ')') { /* is `parlist' not empty? */ + do { + switch (this.t.token) { + case TK_NAME: { /* param . NAME */ + this.new_localvar(this.str_checkname()); + ++nparams; + break; + } + case TK_DOTS: { /* param . `...' */ + this.next(); + f.is_vararg = 1; + break; + } + default: this.syntaxerror(" or " + LUA_QL("...") + " expected"); + } + } while ((f.is_vararg==0) && this.testnext(',')); + } + this.adjustlocalvars(nparams); + f.numparams = fs.nactvar; + fs.reserveregs(fs.nactvar); /* reserve register for parameters */ } @@ -1309,7 +1309,7 @@ public class LexState extends Constants { this.codeclosure(e); this.close_func(); } - + int explist(expdesc v) { /* explist1 -> expr { `,' expr } */ int n = 1; /* at least one expression */ @@ -1328,30 +1328,30 @@ public class LexState extends Constants { expdesc args = new expdesc(); int base, nparams; switch (this.t.token) { - case '(': { /* funcargs -> `(' [ explist1 ] `)' */ - this.next(); - if (this.t.token == ')') /* arg list is empty? */ - args.k = VVOID; - else { - this.explist(args); - fs.setmultret(args); + case '(': { /* funcargs -> `(' [ explist1 ] `)' */ + this.next(); + if (this.t.token == ')') /* arg list is empty? */ + args.k = VVOID; + else { + this.explist(args); + fs.setmultret(args); + } + this.check_match(')', '(', line); + break; + } + case '{': { /* funcargs -> constructor */ + this.constructor(args); + break; + } + case TK_STRING: { /* funcargs -> STRING */ + this.codestring(args, this.t.seminfo.ts); + this.next(); /* must use `seminfo' before `next' */ + break; + } + default: { + this.syntaxerror("function arguments expected"); + return; } - this.check_match(')', '(', line); - break; - } - case '{': { /* funcargs -> constructor */ - this.constructor(args); - break; - } - case TK_STRING: { /* funcargs -> STRING */ - this.codestring(args, this.t.seminfo.ts); - this.next(); /* must use `seminfo' before `next' */ - break; - } - default: { - this.syntaxerror("function arguments expected"); - return; - } } _assert (f.k == VNONRELOC); base = f.u.info; /* base register for call */ @@ -1365,35 +1365,35 @@ public class LexState extends Constants { f.init(VCALL, fs.codeABC(Lua.OP_CALL, base, nparams + 1, 2)); fs.fixline(line); fs.freereg = (short)(base+1); /* call remove function and arguments and leaves - * (unless changed) one result */ + * (unless changed) one result */ } /* - ** {====================================================================== - ** Expression parsing - ** ======================================================================= - */ + ** {====================================================================== + ** Expression parsing + ** ======================================================================= + */ void primaryexp (expdesc v) { /* primaryexp -> NAME | '(' expr ')' */ switch (t.token) { - case '(': { - int line = linenumber; - this.next(); - this.expr(v); - this.check_match(')', '(', line); - fs.dischargevars(v); - return; - } - case TK_NAME: { - singlevar(v); - return; - } - default: { - this.syntaxerror("unexpected symbol " + t.token + " (" + ((char) t.token) + ")"); - return; - } + case '(': { + int line = linenumber; + this.next(); + this.expr(v); + this.check_match(')', '(', line); + fs.dischargevars(v); + return; + } + case TK_NAME: { + singlevar(v); + return; + } + default: { + this.syntaxerror("unexpected symbol " + t.token + " (" + ((char) t.token) + ")"); + return; + } } } @@ -1405,37 +1405,37 @@ public class LexState extends Constants { primaryexp(v); for (;;) { switch (t.token) { - case '.': { /* fieldsel */ - this.fieldsel(v); - break; - } - case '[': { /* `[' exp1 `]' */ - expdesc key = new expdesc(); - fs.exp2anyregup(v); - this.yindex(key); - fs.indexed(v, key); - break; - } - case ':': { /* `:' NAME funcargs */ - expdesc key = new expdesc(); - this.next(); - this.checkname(key); - fs.self(v, key); - this.funcargs(v, line); - break; - } - case '(': - case TK_STRING: - case '{': { /* funcargs */ - fs.exp2nextreg(v); - this.funcargs(v, line); - break; - } - default: - return; + case '.': { /* fieldsel */ + this.fieldsel(v); + break; + } + case '[': { /* `[' exp1 `]' */ + expdesc key = new expdesc(); + fs.exp2anyregup(v); + this.yindex(key); + fs.indexed(v, key); + break; + } + case ':': { /* `:' NAME funcargs */ + expdesc key = new expdesc(); + this.next(); + this.checkname(key); + fs.self(v, key); + this.funcargs(v, line); + break; + } + case '(': + case TK_STRING: + case '{': { /* funcargs */ + fs.exp2nextreg(v); + this.funcargs(v, line); + break; + } + default: + return; } } - } + } void simpleexp(expdesc v) { @@ -1444,47 +1444,47 @@ public class LexState extends Constants { * FUNCTION body | primaryexp */ switch (this.t.token) { - case TK_NUMBER: { - v.init(VKNUM, 0); - v.u.setNval(this.t.seminfo.r); - break; - } - case TK_STRING: { - this.codestring(v, this.t.seminfo.ts); - break; - } - case TK_NIL: { - v.init(VNIL, 0); - break; - } - case TK_TRUE: { - v.init(VTRUE, 0); - break; - } - case TK_FALSE: { - v.init(VFALSE, 0); - break; - } - case TK_DOTS: { /* vararg */ - FuncState fs = this.fs; - this.check_condition(fs.f.is_vararg!=0, "cannot use " + LUA_QL("...") - + " outside a vararg function"); - v.init(VVARARG, fs.codeABC(Lua.OP_VARARG, 0, 1, 0)); - break; - } - case '{': { /* constructor */ - this.constructor(v); - return; - } - case TK_FUNCTION: { - this.next(); - this.body(v, false, this.linenumber); - return; - } - default: { - this.suffixedexp(v); - return; - } + case TK_NUMBER: { + v.init(VKNUM, 0); + v.u.setNval(this.t.seminfo.r); + break; + } + case TK_STRING: { + this.codestring(v, this.t.seminfo.ts); + break; + } + case TK_NIL: { + v.init(VNIL, 0); + break; + } + case TK_TRUE: { + v.init(VTRUE, 0); + break; + } + case TK_FALSE: { + v.init(VFALSE, 0); + break; + } + case TK_DOTS: { /* vararg */ + FuncState fs = this.fs; + this.check_condition(fs.f.is_vararg!=0, "cannot use " + LUA_QL("...") + + " outside a vararg function"); + v.init(VVARARG, fs.codeABC(Lua.OP_VARARG, 0, 1, 0)); + break; + } + case '{': { /* constructor */ + this.constructor(v); + return; + } + case TK_FUNCTION: { + this.next(); + this.body(v, false, this.linenumber); + return; + } + default: { + this.suffixedexp(v); + return; + } } this.next(); } @@ -1492,52 +1492,52 @@ public class LexState extends Constants { int getunopr(int op) { switch (op) { - case TK_NOT: - return OPR_NOT; - case '-': - return OPR_MINUS; - case '#': - return OPR_LEN; - default: - return OPR_NOUNOPR; + case TK_NOT: + return OPR_NOT; + case '-': + return OPR_MINUS; + case '#': + return OPR_LEN; + default: + return OPR_NOUNOPR; } } int getbinopr(int op) { switch (op) { - case '+': - return OPR_ADD; - case '-': - return OPR_SUB; - case '*': - return OPR_MUL; - case '/': - return OPR_DIV; - case '%': - return OPR_MOD; - case '^': - return OPR_POW; - case TK_CONCAT: - return OPR_CONCAT; - case TK_NE: - return OPR_NE; - case TK_EQ: - return OPR_EQ; - case '<': - return OPR_LT; - case TK_LE: - return OPR_LE; - case '>': - return OPR_GT; - case TK_GE: - return OPR_GE; - case TK_AND: - return OPR_AND; - case TK_OR: - return OPR_OR; - default: - return OPR_NOBINOPR; + case '+': + return OPR_ADD; + case '-': + return OPR_SUB; + case '*': + return OPR_MUL; + case '/': + return OPR_DIV; + case '%': + return OPR_MOD; + case '^': + return OPR_POW; + case TK_CONCAT: + return OPR_CONCAT; + case TK_NE: + return OPR_NE; + case TK_EQ: + return OPR_EQ; + case '<': + return OPR_LT; + case TK_LE: + return OPR_LE; + case '>': + return OPR_GT; + case TK_GE: + return OPR_GE; + case TK_AND: + return OPR_AND; + case TK_OR: + return OPR_OR; + default: + return OPR_NOBINOPR; } } @@ -1551,29 +1551,29 @@ public class LexState extends Constants { right = (byte) j; } }; - + static Priority[] priority = { /* ORDER OPR */ - new Priority(6, 6), new Priority(6, 6), new Priority(7, 7), new Priority(7, 7), new Priority(7, 7), /* `+' `-' `/' `%' */ - new Priority(10, 9), new Priority(5, 4), /* power and concat (right associative) */ - new Priority(3, 3), new Priority(3, 3), /* equality and inequality */ - new Priority(3, 3), new Priority(3, 3), new Priority(3, 3), new Priority(3, 3), /* order */ - new Priority(2, 2), new Priority(1, 1) /* logical (and/or) */ + new Priority(6, 6), new Priority(6, 6), new Priority(7, 7), new Priority(7, 7), new Priority(7, 7), /* `+' `-' `/' `%' */ + new Priority(10, 9), new Priority(5, 4), /* power and concat (right associative) */ + new Priority(3, 3), new Priority(3, 3), /* equality and inequality */ + new Priority(3, 3), new Priority(3, 3), new Priority(3, 3), new Priority(3, 3), /* order */ + new Priority(2, 2), new Priority(1, 1) /* logical (and/or) */ }; static final int UNARY_PRIORITY = 8; /* priority for unary operators */ /* - ** subexpr -> (simpleexp | unop subexpr) { binop subexpr } - ** where `binop' is any binary operator with a priority higher than `limit' - */ + ** subexpr -> (simpleexp | unop subexpr) { binop subexpr } + ** where `binop' is any binary operator with a priority higher than `limit' + */ int subexpr(expdesc v, int limit) { int op; int uop; this.enterlevel(); uop = getunopr(this.t.token); if (uop != OPR_NOUNOPR) { - int line = linenumber; + int line = linenumber; this.next(); this.subexpr(v, UNARY_PRIORITY); fs.prefix(uop, v, line); @@ -1604,37 +1604,37 @@ public class LexState extends Constants { /* - ** {====================================================================== - ** Rules for Statements - ** ======================================================================= - */ + ** {====================================================================== + ** Rules for Statements + ** ======================================================================= + */ boolean block_follow (boolean withuntil) { switch (t.token) { - case TK_ELSE: case TK_ELSEIF: case TK_END: case TK_EOS: - return true; + case TK_ELSE: case TK_ELSEIF: case TK_END: case TK_EOS: + return true; case TK_UNTIL: - return withuntil; - default: return false; + return withuntil; + default: return false; } } void block () { - /* block -> chunk */ - FuncState fs = this.fs; - BlockCnt bl = new BlockCnt(); - fs.enterblock(bl, false); - this.statlist(); - fs.leaveblock(); + /* block -> chunk */ + FuncState fs = this.fs; + BlockCnt bl = new BlockCnt(); + fs.enterblock(bl, false); + this.statlist(); + fs.leaveblock(); } /* - ** structure to chain all variables in the left-hand side of an - ** assignment - */ + ** structure to chain all variables in the left-hand side of an + ** assignment + */ static class LHS_assign { LHS_assign prev; /* variable (global, local, upvalue, or indexed) */ @@ -1643,11 +1643,11 @@ public class LexState extends Constants { /* - ** check whether, in an assignment to a local variable, the local variable - ** is needed in a previous assignment (to a table). If so, save original - ** local value in a safe place and use this safe copy in the previous - ** assignment. - */ + ** check whether, in an assignment to a local variable, the local variable + ** is needed in a previous assignment (to a table). If so, save original + ** local value in a safe place and use this safe copy in the previous + ** assignment. + */ void check_conflict (LHS_assign lh, expdesc v) { FuncState fs = this.fs; short extra = (short) fs.freereg; /* eventual position to save local variable */ @@ -1668,10 +1668,10 @@ public class LexState extends Constants { } } if (conflict) { - /* copy upvalue/local value to a temporary (in position 'extra') */ - int op = (v.k == VLOCAL) ? Lua.OP_MOVE : Lua.OP_GETUPVAL; - fs.codeABC(op, extra, v.u.info, 0); - fs.reserveregs(1); + /* copy upvalue/local value to a temporary (in position 'extra') */ + int op = (v.k == VLOCAL) ? Lua.OP_MOVE : Lua.OP_GETUPVAL; + fs.codeABC(op, extra, v.u.info, 0); + fs.reserveregs(1); } } @@ -1679,32 +1679,32 @@ public class LexState extends Constants { void assignment (LHS_assign lh, int nvars) { expdesc e = new expdesc(); this.check_condition(VLOCAL <= lh.v.k && lh.v.k <= VINDEXED, - "syntax error"); + "syntax error"); if (this.testnext(',')) { /* assignment -> `,' primaryexp assignment */ - LHS_assign nv = new LHS_assign(); - nv.prev = lh; - this.suffixedexp(nv.v); - if (nv.v.k != VINDEXED) - this.check_conflict(lh, nv.v); - this.assignment(nv, nvars+1); + LHS_assign nv = new LHS_assign(); + nv.prev = lh; + this.suffixedexp(nv.v); + if (nv.v.k != VINDEXED) + this.check_conflict(lh, nv.v); + this.assignment(nv, nvars+1); } else { /* assignment . `=' explist1 */ - int nexps; - this.checknext('='); - nexps = this.explist(e); - if (nexps != nvars) { - this.adjust_assign(nvars, nexps, e); - if (nexps > nvars) - this.fs.freereg -= nexps - nvars; /* remove extra values */ - } - else { - fs.setoneret(e); /* close last expression */ - fs.storevar(lh.v, e); - return; /* avoid default */ - } - } - e.init(VNONRELOC, this.fs.freereg-1); /* default assignment */ - fs.storevar(lh.v, e); + int nexps; + this.checknext('='); + nexps = this.explist(e); + if (nexps != nvars) { + this.adjust_assign(nvars, nexps, e); + if (nexps > nvars) + this.fs.freereg -= nexps - nvars; /* remove extra values */ + } + else { + fs.setoneret(e); /* close last expression */ + fs.storevar(lh.v, e); + return; /* avoid default */ + } + } + e.init(VNONRELOC, this.fs.freereg-1); /* default assignment */ + fs.storevar(lh.v, e); } @@ -1755,9 +1755,9 @@ public class LexState extends Constants { dyd.label[l].nactvar = fs.bl.nactvar; } findgotos(dyd.label[l]); -} + } + - void whilestat (int line) { /* whilestat -> WHILE cond DO block END */ FuncState fs = this.fs; @@ -1790,7 +1790,7 @@ public class LexState extends Constants { this.check_match(TK_UNTIL, TK_REPEAT, line); condexit = this.cond(); /* read condition (inside scope block) */ if (bl2.upval) { /* upvalues? */ - fs.patchclose(condexit, bl2.nactvar); + fs.patchclose(condexit, bl2.nactvar); } fs.leaveblock(); /* finish scope */ fs.patchlist(condexit, repeat_init); /* close the loop */ @@ -1890,15 +1890,15 @@ public class LexState extends Constants { this.next(); /* skip `for' */ varname = this.str_checkname(); /* first variable name */ switch (this.t.token) { - case '=': - this.fornum(varname, line); - break; - case ',': - case TK_IN: - this.forlist(varname); - break; - default: - this.syntaxerror(LUA_QL("=") + " or " + LUA_QL("in") + " expected"); + case '=': + this.fornum(varname, line); + break; + case ',': + case TK_IN: + this.forlist(varname); + break; + default: + this.syntaxerror(LUA_QL("=") + " or " + LUA_QL("in") + " expected"); } this.check_match(TK_END, TK_FOR, line); fs.leaveblock(); /* loop scope (`break' jumps to this point) */ @@ -1941,9 +1941,9 @@ public class LexState extends Constants { IntPtr escapelist = new IntPtr(NO_JUMP); /* exit list for finished parts */ test_then_block(escapelist); /* IF cond THEN block */ while (t.token == TK_ELSEIF) - test_then_block(escapelist); /* ELSEIF cond THEN block */ + test_then_block(escapelist); /* ELSEIF cond THEN block */ if (testnext(TK_ELSE)) - block(); /* `else' part */ + block(); /* `else' part */ check_match(TK_END, TK_IF, line); fs.patchtohere(escapelist.i); /* patch escape list to 'if' end */ } @@ -2056,63 +2056,63 @@ public class LexState extends Constants { int line = this.linenumber; /* may be needed for error messages */ enterlevel(); switch (this.t.token) { - case ';': { /* stat -> ';' (empty statement) */ - next(); /* skip ';' */ - break; - } - case TK_IF: { /* stat -> ifstat */ - this.ifstat(line); - break; - } - case TK_WHILE: { /* stat -> whilestat */ - this.whilestat(line); - break; - } - case TK_DO: { /* stat -> DO block END */ - this.next(); /* skip DO */ - this.block(); - this.check_match(TK_END, TK_DO, line); - break; - } - case TK_FOR: { /* stat -> forstat */ - this.forstat(line); - break; - } - case TK_REPEAT: { /* stat -> repeatstat */ - this.repeatstat(line); - break; - } - case TK_FUNCTION: { - this.funcstat(line); /* stat -> funcstat */ - break; - } - case TK_LOCAL: { /* stat -> localstat */ - this.next(); /* skip LOCAL */ - if (this.testnext(TK_FUNCTION)) /* local function? */ - this.localfunc(); - else - this.localstat(); - break; - } - case TK_DBCOLON: { /* stat -> label */ - next(); /* skip double colon */ - labelstat(str_checkname(), line); - break; - } - case TK_RETURN: { /* stat -> retstat */ - next(); /* skip RETURN */ - this.retstat(); - break; - } - case TK_BREAK: - case TK_GOTO: { /* stat -> breakstat */ - this.gotostat(fs.jump()); - break; - } - default: { - this.exprstat(); - break; - } + case ';': { /* stat -> ';' (empty statement) */ + next(); /* skip ';' */ + break; + } + case TK_IF: { /* stat -> ifstat */ + this.ifstat(line); + break; + } + case TK_WHILE: { /* stat -> whilestat */ + this.whilestat(line); + break; + } + case TK_DO: { /* stat -> DO block END */ + this.next(); /* skip DO */ + this.block(); + this.check_match(TK_END, TK_DO, line); + break; + } + case TK_FOR: { /* stat -> forstat */ + this.forstat(line); + break; + } + case TK_REPEAT: { /* stat -> repeatstat */ + this.repeatstat(line); + break; + } + case TK_FUNCTION: { + this.funcstat(line); /* stat -> funcstat */ + break; + } + case TK_LOCAL: { /* stat -> localstat */ + this.next(); /* skip LOCAL */ + if (this.testnext(TK_FUNCTION)) /* local function? */ + this.localfunc(); + else + this.localstat(); + break; + } + case TK_DBCOLON: { /* stat -> label */ + next(); /* skip double colon */ + labelstat(str_checkname(), line); + break; + } + case TK_RETURN: { /* stat -> retstat */ + next(); /* skip RETURN */ + this.retstat(); + break; + } + case TK_BREAK: + case TK_GOTO: { /* stat -> breakstat */ + this.gotostat(fs.jump()); + break; + } + default: { + this.exprstat(); + break; + } } _assert(fs.f.maxstacksize >= fs.freereg && fs.freereg >= fs.nactvar); @@ -2132,22 +2132,22 @@ public class LexState extends Constants { } /* - ** compiles the main function, which is a regular vararg function with an - ** upvalue named LUA_ENV - */ + ** compiles the main function, which is a regular vararg function with an + ** upvalue named LUA_ENV + */ public void mainfunc(FuncState funcstate) { - BlockCnt bl = new BlockCnt(); - open_func(funcstate, bl); - fs.f.is_vararg = 1; /* main function is always vararg */ - expdesc v = new expdesc(); - v.init(VLOCAL, 0); /* create and... */ - fs.newupvalue(envn, v); /* ...set environment upvalue */ - next(); /* read first token */ - statlist(); /* parse main body */ - check(TK_EOS); - close_func(); + BlockCnt bl = new BlockCnt(); + open_func(funcstate, bl); + fs.f.is_vararg = 1; /* main function is always vararg */ + expdesc v = new expdesc(); + v.init(VLOCAL, 0); /* create and... */ + fs.newupvalue(envn, v); /* ...set environment upvalue */ + next(); /* read first token */ + statlist(); /* parse main body */ + check(TK_EOS); + close_func(); } - + /* }====================================================================== */ - -} + +} \ No newline at end of file diff --git a/src/core/org/luaj/vm2/compiler/LuaC.java b/core/src/main/java/org/luaj/vm2/compiler/LuaC.java similarity index 98% rename from src/core/org/luaj/vm2/compiler/LuaC.java rename to core/src/main/java/org/luaj/vm2/compiler/LuaC.java index 1e53636d..6d41ce08 100644 --- a/src/core/org/luaj/vm2/compiler/LuaC.java +++ b/core/src/main/java/org/luaj/vm2/compiler/LuaC.java @@ -43,7 +43,7 @@ import org.luaj.vm2.lib.BaseLib; * using a user-supplied environment. * *

    - * Implements the {@link org.luaj.vm2.Globals.Compiler} interface for loading + * Implements the {@link Globals.Compiler} interface for loading * initialized chunks, which is an interface common to * lua bytecode compiling and java bytecode compiling. * diff --git a/examples/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/examples/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock new file mode 100644 index 00000000..70daf29c Binary files /dev/null and b/examples/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/examples/android/.gradle/buildOutputCleanup/cache.properties b/examples/android/.gradle/buildOutputCleanup/cache.properties new file mode 100644 index 00000000..2598ceb3 --- /dev/null +++ b/examples/android/.gradle/buildOutputCleanup/cache.properties @@ -0,0 +1,2 @@ +#Sun Mar 01 11:42:21 CET 2026 +gradle.version=9.0.0 diff --git a/test/lua/errors/abc.txt b/examples/android/.gradle/vcs-1/gc.properties similarity index 100% rename from test/lua/errors/abc.txt rename to examples/android/.gradle/vcs-1/gc.properties diff --git a/examples/maven/pom.xml b/examples/maven/pom.xml index 85025c43..be00baae 100644 --- a/examples/maven/pom.xml +++ b/examples/maven/pom.xml @@ -7,16 +7,25 @@ 1.0-SNAPSHOT maven-example http://maven.apache.org + + + oac + https://repo.open-autonomous-connection.org/api/packages/open-autonomous-connection/maven + + true + + + - - org.luaj - luaj-jse - 3.0.1 - + junit junit - 3.8.1 + 4.13.2 test diff --git a/jme/pom.xml b/jme/pom.xml new file mode 100644 index 00000000..c0b7eef7 --- /dev/null +++ b/jme/pom.xml @@ -0,0 +1,122 @@ + + + 4.0.0 + + + org.openautonomousconnection.luaj + parent + 3.0.2 + + + jme + jar + + + + org.openautonomousconnection.luaj + core + ${project.version} + + + + + + jme + + + env.WTK_HOME + + + + + + + org.apache.maven.plugins + maven-resources-plugin + 3.3.1 + + + copy-sources + generate-sources + copy-resources + + ${project.build.directory}/generated-sources/luaj-jme + + + ${project.basedir}/../luaj-core/src/main/java + **/*.java + + + ${project.basedir}/src/main/java + **/*.java + + + + + + + + + com.google.code.maven-replacer-plugin + replacer + + + rewrite-branding + generate-sources + replace + + ${project.build.directory}/generated-sources/luaj-jme + **/*.java + + + "Luaj 0.0" + "${luaj.brand.jme}" + + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-generated-sources + generate-sources + add-source + + + ${project.build.directory}/generated-sources/luaj-jme + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 8 + + -bootclasspath + ${env.WTK_HOME}/lib/cldcapi11.jar${path.separator}${env.WTK_HOME}/lib/midpapi20.jar${path.separator}${env.WTK_HOME}/lib/mmapi.jar + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + jar + + + + + + + + \ No newline at end of file diff --git a/jme/src/main/java/org/openautonomousconnection/luaj/Main.java b/jme/src/main/java/org/openautonomousconnection/luaj/Main.java new file mode 100644 index 00000000..eaac0957 --- /dev/null +++ b/jme/src/main/java/org/openautonomousconnection/luaj/Main.java @@ -0,0 +1,17 @@ +package org.openautonomousconnection.luaj; + +//TIP To Run code, press or +// click the icon in the gutter. +public class Main { + static void main() { + //TIP Press with your caret at the highlighted text + // to see how IntelliJ IDEA suggests fixing it. + IO.println(String.format("Hello and welcome!")); + + for (int i = 1; i <= 5; i++) { + //TIP Press to start debugging your code. We have set one breakpoint + // for you, but you can always add more by pressing . + IO.println("i = " + i); + } + } +} diff --git a/jse/pom.xml b/jse/pom.xml new file mode 100644 index 00000000..75bd7b4c --- /dev/null +++ b/jse/pom.xml @@ -0,0 +1,134 @@ + + + 4.0.0 + + + org.openautonomousconnection.luaj + parent + 3.0.2 + + + jse + jar + + + + org.openautonomousconnection.luaj + core + ${project.version} + + + org.apache.bcel + bcel + 6.12.0 + + + + + + + org.apache.maven.plugins + maven-resources-plugin + 3.3.1 + + + copy-sources + generate-sources + copy-resources + + ${project.build.directory}/generated-sources/luaj-jse + + + ${project.basedir}/../luaj-core/src/main/java + **/*.java + + + ${project.basedir}/src/main/java + **/*.java + + + + + + + + com.google.code.maven-replacer-plugin + replacer + + + rewrite-branding-and-cleanup + generate-sources + replace + + ${project.build.directory}/generated-sources/luaj-jse + + **/*.java + + + + "Luaj 0.0" + "${luaj.brand.jse}" + + <String> + <Stat> + <Exp> + <Name> + <Block> + <TableField> + <VarExp> + <Exp.VarExp> + <Object,String> + <Double,String> + <Integer,Integer> + <Integer,LocalVariableGen> + <Exp,Integer> + <String,byte[]> + <String,Variable> + <LuaValue,String> + <LuaString,String> + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-generated-sources + generate-sources + add-source + + + ${project.build.directory}/generated-sources/luaj-jse + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.4.2 + + + **/* + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + jar + + + + + + + \ No newline at end of file diff --git a/src/jse/lua.java b/jse/src/main/java/lua.java similarity index 100% rename from src/jse/lua.java rename to jse/src/main/java/lua.java diff --git a/src/jse/luac.java b/jse/src/main/java/luac.java similarity index 100% rename from src/jse/luac.java rename to jse/src/main/java/luac.java diff --git a/src/jse/luajc.java b/jse/src/main/java/luajc.java similarity index 100% rename from src/jse/luajc.java rename to jse/src/main/java/luajc.java diff --git a/src/jse/org/luaj/vm2/ast/Block.java b/jse/src/main/java/org/luaj/vm2/ast/Block.java similarity index 100% rename from src/jse/org/luaj/vm2/ast/Block.java rename to jse/src/main/java/org/luaj/vm2/ast/Block.java diff --git a/src/jse/org/luaj/vm2/ast/Chunk.java b/jse/src/main/java/org/luaj/vm2/ast/Chunk.java similarity index 100% rename from src/jse/org/luaj/vm2/ast/Chunk.java rename to jse/src/main/java/org/luaj/vm2/ast/Chunk.java diff --git a/src/jse/org/luaj/vm2/ast/Exp.java b/jse/src/main/java/org/luaj/vm2/ast/Exp.java similarity index 100% rename from src/jse/org/luaj/vm2/ast/Exp.java rename to jse/src/main/java/org/luaj/vm2/ast/Exp.java diff --git a/src/jse/org/luaj/vm2/ast/FuncArgs.java b/jse/src/main/java/org/luaj/vm2/ast/FuncArgs.java similarity index 100% rename from src/jse/org/luaj/vm2/ast/FuncArgs.java rename to jse/src/main/java/org/luaj/vm2/ast/FuncArgs.java diff --git a/src/jse/org/luaj/vm2/ast/FuncBody.java b/jse/src/main/java/org/luaj/vm2/ast/FuncBody.java similarity index 100% rename from src/jse/org/luaj/vm2/ast/FuncBody.java rename to jse/src/main/java/org/luaj/vm2/ast/FuncBody.java diff --git a/src/jse/org/luaj/vm2/ast/FuncName.java b/jse/src/main/java/org/luaj/vm2/ast/FuncName.java similarity index 100% rename from src/jse/org/luaj/vm2/ast/FuncName.java rename to jse/src/main/java/org/luaj/vm2/ast/FuncName.java diff --git a/src/jse/org/luaj/vm2/ast/Name.java b/jse/src/main/java/org/luaj/vm2/ast/Name.java similarity index 100% rename from src/jse/org/luaj/vm2/ast/Name.java rename to jse/src/main/java/org/luaj/vm2/ast/Name.java diff --git a/src/jse/org/luaj/vm2/ast/NameResolver.java b/jse/src/main/java/org/luaj/vm2/ast/NameResolver.java similarity index 100% rename from src/jse/org/luaj/vm2/ast/NameResolver.java rename to jse/src/main/java/org/luaj/vm2/ast/NameResolver.java diff --git a/src/jse/org/luaj/vm2/ast/NameScope.java b/jse/src/main/java/org/luaj/vm2/ast/NameScope.java similarity index 100% rename from src/jse/org/luaj/vm2/ast/NameScope.java rename to jse/src/main/java/org/luaj/vm2/ast/NameScope.java diff --git a/src/jse/org/luaj/vm2/ast/ParList.java b/jse/src/main/java/org/luaj/vm2/ast/ParList.java similarity index 100% rename from src/jse/org/luaj/vm2/ast/ParList.java rename to jse/src/main/java/org/luaj/vm2/ast/ParList.java diff --git a/src/jse/org/luaj/vm2/ast/Stat.java b/jse/src/main/java/org/luaj/vm2/ast/Stat.java similarity index 100% rename from src/jse/org/luaj/vm2/ast/Stat.java rename to jse/src/main/java/org/luaj/vm2/ast/Stat.java diff --git a/src/jse/org/luaj/vm2/ast/Str.java b/jse/src/main/java/org/luaj/vm2/ast/Str.java similarity index 100% rename from src/jse/org/luaj/vm2/ast/Str.java rename to jse/src/main/java/org/luaj/vm2/ast/Str.java diff --git a/src/jse/org/luaj/vm2/ast/SyntaxElement.java b/jse/src/main/java/org/luaj/vm2/ast/SyntaxElement.java similarity index 100% rename from src/jse/org/luaj/vm2/ast/SyntaxElement.java rename to jse/src/main/java/org/luaj/vm2/ast/SyntaxElement.java diff --git a/src/jse/org/luaj/vm2/ast/TableConstructor.java b/jse/src/main/java/org/luaj/vm2/ast/TableConstructor.java similarity index 100% rename from src/jse/org/luaj/vm2/ast/TableConstructor.java rename to jse/src/main/java/org/luaj/vm2/ast/TableConstructor.java diff --git a/src/jse/org/luaj/vm2/ast/TableField.java b/jse/src/main/java/org/luaj/vm2/ast/TableField.java similarity index 100% rename from src/jse/org/luaj/vm2/ast/TableField.java rename to jse/src/main/java/org/luaj/vm2/ast/TableField.java diff --git a/src/jse/org/luaj/vm2/ast/Variable.java b/jse/src/main/java/org/luaj/vm2/ast/Variable.java similarity index 100% rename from src/jse/org/luaj/vm2/ast/Variable.java rename to jse/src/main/java/org/luaj/vm2/ast/Variable.java diff --git a/src/jse/org/luaj/vm2/ast/Visitor.java b/jse/src/main/java/org/luaj/vm2/ast/Visitor.java similarity index 99% rename from src/jse/org/luaj/vm2/ast/Visitor.java rename to jse/src/main/java/org/luaj/vm2/ast/Visitor.java index 8f49a566..ec1444ef 100644 --- a/src/jse/org/luaj/vm2/ast/Visitor.java +++ b/jse/src/main/java/org/luaj/vm2/ast/Visitor.java @@ -155,7 +155,7 @@ abstract public class Visitor { public void visitVars(List vars) { if ( vars != null ) for ( int i=0, n=vars.size(); i exps) { if ( exps != null ) diff --git a/src/jse/org/luaj/vm2/luajc/BasicBlock.java b/jse/src/main/java/org/luaj/vm2/luajc/BasicBlock.java similarity index 100% rename from src/jse/org/luaj/vm2/luajc/BasicBlock.java rename to jse/src/main/java/org/luaj/vm2/luajc/BasicBlock.java diff --git a/src/jse/org/luaj/vm2/luajc/JavaBuilder.java b/jse/src/main/java/org/luaj/vm2/luajc/JavaBuilder.java similarity index 100% rename from src/jse/org/luaj/vm2/luajc/JavaBuilder.java rename to jse/src/main/java/org/luaj/vm2/luajc/JavaBuilder.java diff --git a/src/jse/org/luaj/vm2/luajc/JavaGen.java b/jse/src/main/java/org/luaj/vm2/luajc/JavaGen.java similarity index 100% rename from src/jse/org/luaj/vm2/luajc/JavaGen.java rename to jse/src/main/java/org/luaj/vm2/luajc/JavaGen.java diff --git a/src/jse/org/luaj/vm2/luajc/JavaLoader.java b/jse/src/main/java/org/luaj/vm2/luajc/JavaLoader.java similarity index 100% rename from src/jse/org/luaj/vm2/luajc/JavaLoader.java rename to jse/src/main/java/org/luaj/vm2/luajc/JavaLoader.java diff --git a/src/jse/org/luaj/vm2/luajc/LuaJC.java b/jse/src/main/java/org/luaj/vm2/luajc/LuaJC.java similarity index 97% rename from src/jse/org/luaj/vm2/luajc/LuaJC.java rename to jse/src/main/java/org/luaj/vm2/luajc/LuaJC.java index 4b74ef4f..53117478 100644 --- a/src/jse/org/luaj/vm2/luajc/LuaJC.java +++ b/jse/src/main/java/org/luaj/vm2/luajc/LuaJC.java @@ -34,7 +34,7 @@ import org.luaj.vm2.Prototype; import org.luaj.vm2.compiler.LuaC; /** - * Implementation of {@link org.luaj.vm2.Globals.Compiler} which does direct + * Implementation of {@link Globals.Compiler} which does direct * lua-to-java-bytecode compiling. *

    * By default, when using {@link org.luaj.vm2.lib.jse.JsePlatform} or @@ -59,7 +59,7 @@ import org.luaj.vm2.compiler.LuaC; * * @see Globals#compiler * @see #install(Globals) - * @see org.luaj.vm2.compiler.LuaC + * @see LuaC * @see LuaValue */ public class LuaJC implements Globals.Loader { diff --git a/src/jse/org/luaj/vm2/luajc/ProtoInfo.java b/jse/src/main/java/org/luaj/vm2/luajc/ProtoInfo.java similarity index 100% rename from src/jse/org/luaj/vm2/luajc/ProtoInfo.java rename to jse/src/main/java/org/luaj/vm2/luajc/ProtoInfo.java diff --git a/src/jse/org/luaj/vm2/luajc/UpvalInfo.java b/jse/src/main/java/org/luaj/vm2/luajc/UpvalInfo.java similarity index 100% rename from src/jse/org/luaj/vm2/luajc/UpvalInfo.java rename to jse/src/main/java/org/luaj/vm2/luajc/UpvalInfo.java diff --git a/src/jse/org/luaj/vm2/luajc/VarInfo.java b/jse/src/main/java/org/luaj/vm2/luajc/VarInfo.java similarity index 100% rename from src/jse/org/luaj/vm2/luajc/VarInfo.java rename to jse/src/main/java/org/luaj/vm2/luajc/VarInfo.java diff --git a/src/jse/org/luaj/vm2/parser/LuaParser.java b/jse/src/main/java/org/luaj/vm2/parser/LuaParser.java similarity index 99% rename from src/jse/org/luaj/vm2/parser/LuaParser.java rename to jse/src/main/java/org/luaj/vm2/parser/LuaParser.java index d7e254fd..c85664f3 100644 --- a/src/jse/org/luaj/vm2/parser/LuaParser.java +++ b/jse/src/main/java/org/luaj/vm2/parser/LuaParser.java @@ -1741,7 +1741,7 @@ public class LuaParser implements LuaParserConstants { throw generateParseException(); } - static private final class LookaheadSuccess extends java.lang.Error { } + static private final class LookaheadSuccess extends Error { } final private LookaheadSuccess jj_ls = new LookaheadSuccess(); private boolean jj_scan_token(int kind) { if (jj_scanpos == jj_lastpos) { @@ -1791,7 +1791,7 @@ public class LuaParser implements LuaParserConstants { return (jj_ntk = jj_nt.kind); } - private java.util.List jj_expentries = new java.util.ArrayList(); + private List jj_expentries = new ArrayList(); private int[] jj_expentry; private int jj_kind = -1; private int[] jj_lasttokens = new int[100]; @@ -1806,7 +1806,7 @@ public class LuaParser implements LuaParserConstants { for (int i = 0; i < jj_endpos; i++) { jj_expentry[i] = jj_lasttokens[i]; } - jj_entries_loop: for (java.util.Iterator it = jj_expentries.iterator(); it.hasNext();) { + jj_entries_loop: for (Iterator it = jj_expentries.iterator(); it.hasNext();) { int[] oldentry = (int[])(it.next()); if (oldentry.length == jj_expentry.length) { for (int i = 0; i < jj_expentry.length; i++) { diff --git a/src/jse/org/luaj/vm2/parser/LuaParserConstants.java b/jse/src/main/java/org/luaj/vm2/parser/LuaParserConstants.java similarity index 100% rename from src/jse/org/luaj/vm2/parser/LuaParserConstants.java rename to jse/src/main/java/org/luaj/vm2/parser/LuaParserConstants.java diff --git a/src/jse/org/luaj/vm2/parser/LuaParserTokenManager.java b/jse/src/main/java/org/luaj/vm2/parser/LuaParserTokenManager.java similarity index 100% rename from src/jse/org/luaj/vm2/parser/LuaParserTokenManager.java rename to jse/src/main/java/org/luaj/vm2/parser/LuaParserTokenManager.java diff --git a/src/jse/org/luaj/vm2/parser/ParseException.java b/jse/src/main/java/org/luaj/vm2/parser/ParseException.java similarity index 100% rename from src/jse/org/luaj/vm2/parser/ParseException.java rename to jse/src/main/java/org/luaj/vm2/parser/ParseException.java diff --git a/src/jse/org/luaj/vm2/parser/SimpleCharStream.java b/jse/src/main/java/org/luaj/vm2/parser/SimpleCharStream.java similarity index 100% rename from src/jse/org/luaj/vm2/parser/SimpleCharStream.java rename to jse/src/main/java/org/luaj/vm2/parser/SimpleCharStream.java diff --git a/src/jse/org/luaj/vm2/parser/Token.java b/jse/src/main/java/org/luaj/vm2/parser/Token.java similarity index 100% rename from src/jse/org/luaj/vm2/parser/Token.java rename to jse/src/main/java/org/luaj/vm2/parser/Token.java diff --git a/src/jse/org/luaj/vm2/parser/TokenMgrError.java b/jse/src/main/java/org/luaj/vm2/parser/TokenMgrError.java similarity index 100% rename from src/jse/org/luaj/vm2/parser/TokenMgrError.java rename to jse/src/main/java/org/luaj/vm2/parser/TokenMgrError.java diff --git a/src/jse/org/luaj/vm2/script/LuaScriptEngine.java b/jse/src/main/java/org/luaj/vm2/script/LuaScriptEngine.java similarity index 54% rename from src/jse/org/luaj/vm2/script/LuaScriptEngine.java rename to jse/src/main/java/org/luaj/vm2/script/LuaScriptEngine.java index 415c885c..7c85a6e0 100644 --- a/src/jse/org/luaj/vm2/script/LuaScriptEngine.java +++ b/jse/src/main/java/org/luaj/vm2/script/LuaScriptEngine.java @@ -1,24 +1,24 @@ /******************************************************************************* -* Copyright (c) 2008-2013 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ + * Copyright (c) 2008-2013 LuaJ. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ package org.luaj.vm2.script; import java.io.*; @@ -33,7 +33,7 @@ import org.luaj.vm2.lib.jse.CoerceJavaToLua; /** * Implementation of the ScriptEngine interface which can compile and execute * scripts using luaj. - * + * *

    * This engine requires the types of the Bindings and ScriptContext to be * compatible with the engine. For creating new client context use @@ -42,35 +42,35 @@ import org.luaj.vm2.lib.jse.CoerceJavaToLua; * construct a {@link LuajBindings} directly. */ public class LuaScriptEngine extends AbstractScriptEngine implements ScriptEngine, Compilable { - - private static final String __ENGINE_VERSION__ = Lua._VERSION; - private static final String __NAME__ = "Luaj"; - private static final String __SHORT_NAME__ = "Luaj"; - private static final String __LANGUAGE__ = "lua"; - private static final String __LANGUAGE_VERSION__ = "5.2"; - private static final String __ARGV__ = "arg"; - private static final String __FILENAME__ = "?"; - - private static final ScriptEngineFactory myFactory = new LuaScriptEngineFactory(); - - private LuajContext context; - public LuaScriptEngine() { - // set up context - context = new LuajContext(); - context.setBindings(createBindings(), ScriptContext.ENGINE_SCOPE); - setContext(context); - - // set special values - put(LANGUAGE_VERSION, __LANGUAGE_VERSION__); - put(LANGUAGE, __LANGUAGE__); - put(ENGINE, __NAME__); - put(ENGINE_VERSION, __ENGINE_VERSION__); - put(ARGV, __ARGV__); - put(FILENAME, __FILENAME__); - put(NAME, __SHORT_NAME__); - put("THREADING", null); - } + private static final String __ENGINE_VERSION__ = Lua._VERSION; + private static final String __NAME__ = "Luaj"; + private static final String __SHORT_NAME__ = "Luaj"; + private static final String __LANGUAGE__ = "lua"; + private static final String __LANGUAGE_VERSION__ = "5.2"; + private static final String __ARGV__ = "arg"; + private static final String __FILENAME__ = "?"; + + private static final ScriptEngineFactory myFactory = new LuaScriptEngineFactory(); + + private LuajContext context; + + public LuaScriptEngine() { + // set up context + context = new LuajContext(); + context.setBindings(createBindings(), ScriptContext.ENGINE_SCOPE); + setContext(context); + + // set special values + put(LANGUAGE_VERSION, __LANGUAGE_VERSION__); + put(LANGUAGE, __LANGUAGE__); + put(ENGINE, __NAME__); + put(ENGINE_VERSION, __ENGINE_VERSION__); + put(ARGV, __ARGV__); + put(FILENAME, __FILENAME__); + put(NAME, __SHORT_NAME__); + put("THREADING", null); + } @Override public CompiledScript compile(String script) throws ScriptException { @@ -80,14 +80,14 @@ public class LuaScriptEngine extends AbstractScriptEngine implements ScriptEngin @Override public CompiledScript compile(Reader script) throws ScriptException { try { - InputStream is = new Utf8Encoder(script); - try { - final Globals g = context.globals; - final LuaFunction f = g.load(script, "script").checkfunction(); - return new LuajCompiledScript(f, g); + InputStream is = new Utf8Encoder(script); + try { + final Globals g = context.globals; + final LuaFunction f = g.load(script, "script").checkfunction(); + return new LuajCompiledScript(f, g); } catch ( LuaError lee ) { throw new ScriptException(lee.getMessage() ); - } finally { + } finally { is.close(); } } catch ( Exception e ) { @@ -124,7 +124,7 @@ public class LuaScriptEngine extends AbstractScriptEngine implements ScriptEngin @Override public Object eval(Reader reader, ScriptContext context) throws ScriptException { - return compile(reader).eval(context); + return compile(reader).eval(context); } @Override @@ -145,20 +145,20 @@ public class LuaScriptEngine extends AbstractScriptEngine implements ScriptEngin return LuaScriptEngine.this; } - public Object eval() throws ScriptException { - return eval(getContext()); - } - - public Object eval(Bindings bindings) throws ScriptException { - return eval(((LuajContext) getContext()).globals, bindings); - } - - public Object eval(ScriptContext context) throws ScriptException { - return eval(((LuajContext) context).globals, context.getBindings(ScriptContext.ENGINE_SCOPE)); + public Object eval() throws ScriptException { + return eval(getContext()); } - - Object eval(Globals g, Bindings b) throws ScriptException { - g.setmetatable(new BindingsMetatable(b)); + + public Object eval(Bindings bindings) throws ScriptException { + return eval(((LuajContext) getContext()).globals, bindings); + } + + public Object eval(ScriptContext context) throws ScriptException { + return eval(((LuajContext) context).globals, context.getBindings(ScriptContext.ENGINE_SCOPE)); + } + + Object eval(Globals g, Bindings b) throws ScriptException { + g.setmetatable(new BindingsMetatable(b)); LuaFunction f = function; if (f.isclosure()) f = new LuaClosure(f.checkclosure().p, g); @@ -193,22 +193,22 @@ public class LuaScriptEngine extends AbstractScriptEngine implements ScriptEngin return c; n = 0; if ( c < 0x800 ) { - buf[n++] = (0x80 | ( c & 0x3f)); + buf[n++] = (0x80 | ( c & 0x3f)); return (0xC0 | ((c>>6) & 0x1f)); } else { - buf[n++] = (0x80 | ( c & 0x3f)); + buf[n++] = (0x80 | ( c & 0x3f)); buf[n++] = (0x80 | ((c>>6) & 0x3f)); return (0xE0 | ((c>>12) & 0x0f)); } } } - + static class BindingsMetatable extends LuaTable { BindingsMetatable(final Bindings bindings) { this.rawset(LuaValue.INDEX, new TwoArgFunction() { public LuaValue call(LuaValue table, LuaValue key) { - if (key.isstring()) + if (key.isstring()) return toLua(bindings.get(key.tojstring())); else return this.rawget(key); @@ -231,36 +231,36 @@ public class LuaScriptEngine extends AbstractScriptEngine implements ScriptEngin }); } } - + static private LuaValue toLua(Object javaValue) { return javaValue == null? LuaValue.NIL: - javaValue instanceof LuaValue? (LuaValue) javaValue: - CoerceJavaToLua.coerce(javaValue); + javaValue instanceof LuaValue? (LuaValue) javaValue: + CoerceJavaToLua.coerce(javaValue); } static private Object toJava(LuaValue luajValue) { switch ( luajValue.type() ) { - case LuaValue.TNIL: return null; - case LuaValue.TSTRING: return luajValue.tojstring(); - case LuaValue.TUSERDATA: return luajValue.checkuserdata(Object.class); - case LuaValue.TNUMBER: return luajValue.isinttype()? - (Object) new Integer(luajValue.toint()): - (Object) new Double(luajValue.todouble()); - default: return luajValue; + case LuaValue.TNIL: return null; + case LuaValue.TSTRING: return luajValue.tojstring(); + case LuaValue.TUSERDATA: return luajValue.checkuserdata(Object.class); + case LuaValue.TNUMBER: return luajValue.isinttype()? + luajValue.toint(): + luajValue.todouble(); + default: return luajValue; } } static private Object toJava(Varargs v) { final int n = v.narg(); switch (n) { - case 0: return null; - case 1: return toJava(v.arg1()); - default: - Object[] o = new Object[n]; - for (int i=0; i expected = new java.util.ArrayList(); + java.util.List expected = new ArrayList(); Varargs n; int i; for (n = t.next(LuaValue.NIL), i = 0; !n.arg1().isnil(); n = t.next(n.arg1()), ++i) { @@ -410,7 +410,7 @@ public class TableTest extends TestCase { t.set(n.arg1(), LuaValue.NIL); } // Iterate over remaining table, and form list of entries still in table. - java.util.List actual = new java.util.ArrayList(); + java.util.List actual = new ArrayList(); for (n = t.next(LuaValue.NIL); !n.arg1().isnil(); n = t.next(n.arg1())) { actual.add(n.arg1() + "=" + n.arg(2)); } diff --git a/test/junit/org/luaj/vm2/TypeTest.java b/jse/src/test/java/org/luaj/vm2/TypeTest.java similarity index 100% rename from test/junit/org/luaj/vm2/TypeTest.java rename to jse/src/test/java/org/luaj/vm2/TypeTest.java diff --git a/test/junit/org/luaj/vm2/UTF8StreamTest.java b/jse/src/test/java/org/luaj/vm2/UTF8StreamTest.java similarity index 100% rename from test/junit/org/luaj/vm2/UTF8StreamTest.java rename to jse/src/test/java/org/luaj/vm2/UTF8StreamTest.java diff --git a/test/junit/org/luaj/vm2/UnaryBinaryOperatorsTest.java b/jse/src/test/java/org/luaj/vm2/UnaryBinaryOperatorsTest.java similarity index 100% rename from test/junit/org/luaj/vm2/UnaryBinaryOperatorsTest.java rename to jse/src/test/java/org/luaj/vm2/UnaryBinaryOperatorsTest.java diff --git a/test/junit/org/luaj/vm2/VarargsTest.java b/jse/src/test/java/org/luaj/vm2/VarargsTest.java similarity index 100% rename from test/junit/org/luaj/vm2/VarargsTest.java rename to jse/src/test/java/org/luaj/vm2/VarargsTest.java diff --git a/test/junit/org/luaj/vm2/WeakTableTest.java b/jse/src/test/java/org/luaj/vm2/WeakTableTest.java similarity index 100% rename from test/junit/org/luaj/vm2/WeakTableTest.java rename to jse/src/test/java/org/luaj/vm2/WeakTableTest.java diff --git a/test/junit/org/luaj/vm2/compiler/AbstractUnitTests.java b/jse/src/test/java/org/luaj/vm2/compiler/AbstractUnitTests.java similarity index 94% rename from test/junit/org/luaj/vm2/compiler/AbstractUnitTests.java rename to jse/src/test/java/org/luaj/vm2/compiler/AbstractUnitTests.java index dd29a9cb..5e4fb3a4 100644 --- a/test/junit/org/luaj/vm2/compiler/AbstractUnitTests.java +++ b/jse/src/test/java/org/luaj/vm2/compiler/AbstractUnitTests.java @@ -1,22 +1,16 @@ package org.luaj.vm2.compiler; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintStream; -import java.net.MalformedURLException; -import java.net.URL; - import junit.framework.TestCase; - import org.luaj.vm2.Globals; -import org.luaj.vm2.LoadState; import org.luaj.vm2.Print; import org.luaj.vm2.Prototype; +import org.luaj.vm2.compiler.DumpState; import org.luaj.vm2.lib.jse.JsePlatform; +import java.io.*; +import java.net.MalformedURLException; +import java.net.URL; + abstract public class AbstractUnitTests extends TestCase { private final String dir; diff --git a/test/junit/org/luaj/vm2/compiler/CompilerUnitTests.java b/jse/src/test/java/org/luaj/vm2/compiler/CompilerUnitTests.java similarity index 100% rename from test/junit/org/luaj/vm2/compiler/CompilerUnitTests.java rename to jse/src/test/java/org/luaj/vm2/compiler/CompilerUnitTests.java diff --git a/test/junit/org/luaj/vm2/compiler/DumpLoadEndianIntTest.java b/jse/src/test/java/org/luaj/vm2/compiler/DumpLoadEndianIntTest.java similarity index 93% rename from test/junit/org/luaj/vm2/compiler/DumpLoadEndianIntTest.java rename to jse/src/test/java/org/luaj/vm2/compiler/DumpLoadEndianIntTest.java index 69437a58..066af4c9 100644 --- a/test/junit/org/luaj/vm2/compiler/DumpLoadEndianIntTest.java +++ b/jse/src/test/java/org/luaj/vm2/compiler/DumpLoadEndianIntTest.java @@ -1,24 +1,12 @@ package org.luaj.vm2.compiler; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.io.StringReader; - import junit.framework.TestCase; - -import org.luaj.vm2.Globals; -import org.luaj.vm2.LoadState; -import org.luaj.vm2.LuaClosure; -import org.luaj.vm2.LuaFunction; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Prototype; +import org.luaj.vm2.*; +import org.luaj.vm2.compiler.DumpState; import org.luaj.vm2.lib.jse.JsePlatform; +import java.io.*; + public class DumpLoadEndianIntTest extends TestCase { private static final String SAVECHUNKS = "SAVECHUNKS"; diff --git a/test/junit/org/luaj/vm2/compiler/LuaParserTests.java b/jse/src/test/java/org/luaj/vm2/compiler/LuaParserTests.java similarity index 93% rename from test/junit/org/luaj/vm2/compiler/LuaParserTests.java rename to jse/src/test/java/org/luaj/vm2/compiler/LuaParserTests.java index 3c9c9d21..834e2674 100644 --- a/test/junit/org/luaj/vm2/compiler/LuaParserTests.java +++ b/jse/src/test/java/org/luaj/vm2/compiler/LuaParserTests.java @@ -1,12 +1,13 @@ package org.luaj.vm2.compiler; +import org.luaj.vm2.LuaValue; +import org.luaj.vm2.compiler.CompilerUnitTests; +import org.luaj.vm2.parser.LuaParser; + import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.parser.LuaParser; - public class LuaParserTests extends CompilerUnitTests { protected void setUp() throws Exception { diff --git a/test/junit/org/luaj/vm2/compiler/RegressionTests.java b/jse/src/test/java/org/luaj/vm2/compiler/RegressionTests.java similarity index 100% rename from test/junit/org/luaj/vm2/compiler/RegressionTests.java rename to jse/src/test/java/org/luaj/vm2/compiler/RegressionTests.java diff --git a/test/junit/org/luaj/vm2/compiler/SimpleTests.java b/jse/src/test/java/org/luaj/vm2/compiler/SimpleTests.java similarity index 99% rename from test/junit/org/luaj/vm2/compiler/SimpleTests.java rename to jse/src/test/java/org/luaj/vm2/compiler/SimpleTests.java index 993a9861..3055d281 100644 --- a/test/junit/org/luaj/vm2/compiler/SimpleTests.java +++ b/jse/src/test/java/org/luaj/vm2/compiler/SimpleTests.java @@ -1,7 +1,6 @@ package org.luaj.vm2.compiler; import junit.framework.TestCase; - import org.luaj.vm2.Globals; import org.luaj.vm2.LuaDouble; import org.luaj.vm2.LuaInteger; diff --git a/test/junit/org/luaj/vm2/require/RequireSampleClassCastExcep.java b/jse/src/test/java/org/luaj/vm2/require/RequireSampleClassCastExcep.java similarity index 100% rename from test/junit/org/luaj/vm2/require/RequireSampleClassCastExcep.java rename to jse/src/test/java/org/luaj/vm2/require/RequireSampleClassCastExcep.java diff --git a/test/junit/org/luaj/vm2/require/RequireSampleLoadLuaError.java b/jse/src/test/java/org/luaj/vm2/require/RequireSampleLoadLuaError.java similarity index 100% rename from test/junit/org/luaj/vm2/require/RequireSampleLoadLuaError.java rename to jse/src/test/java/org/luaj/vm2/require/RequireSampleLoadLuaError.java diff --git a/test/junit/org/luaj/vm2/require/RequireSampleLoadRuntimeExcep.java b/jse/src/test/java/org/luaj/vm2/require/RequireSampleLoadRuntimeExcep.java similarity index 100% rename from test/junit/org/luaj/vm2/require/RequireSampleLoadRuntimeExcep.java rename to jse/src/test/java/org/luaj/vm2/require/RequireSampleLoadRuntimeExcep.java diff --git a/test/junit/org/luaj/vm2/require/RequireSampleSuccess.java b/jse/src/test/java/org/luaj/vm2/require/RequireSampleSuccess.java similarity index 100% rename from test/junit/org/luaj/vm2/require/RequireSampleSuccess.java rename to jse/src/test/java/org/luaj/vm2/require/RequireSampleSuccess.java diff --git a/test/junit/org/luaj/vm2/script/ScriptEngineTests.java b/jse/src/test/java/org/luaj/vm2/script/ScriptEngineTests.java similarity index 100% rename from test/junit/org/luaj/vm2/script/ScriptEngineTests.java rename to jse/src/test/java/org/luaj/vm2/script/ScriptEngineTests.java diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..e242bf3b --- /dev/null +++ b/pom.xml @@ -0,0 +1,149 @@ + + + 4.0.0 + + org.openautonomousconnection.luaj + parent + 3.0.2 + pom + + + core + jse + jme + + + + UTF-8 + 8 + jse ${project.version} + jme ${project.version} + + + + + MIT License + https://opensource.org/license/mit + The license is readable in the LICENSE-File + + + + + + Enby + https://github.com/Enyby + LuaJ + https://github.com/luaj + + + Benjamin P. Jung + https://github.com/headcr4sh + LuaJ + https://github.com/luaj + + + Lorenzo Stanco + https://github.com/lorenzos + LuaJ + https://github.com/luaj + + + Mikhael-Danilov + https://github.com/Mikhael-Danilov + LuaJ + https://github.com/luaj + + + zaoqi + https://github.com/zaoqi + LuaJ + https://github.com/luaj + + + James Roseborough + + + Ian Farmer + + + Open Autonomous Connection + https://open-autonomous-connection.org/ + Open Autonomous Connection + https://open-autonomous-connection.org/ + + + + + Issue Tracker + https://repo.open-autonomous-connection.org/open-autonomous-connection/luaj/issues + + + + + oac + LuaJ + https://repo.open-autonomous-connection.org/api/packages/open-autonomous-connection/maven + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.6.3 + + false + false + none + en_US + UTF-8 + UTF-8 + UTF-8 + + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + ${maven.compiler.release} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-source-plugin + 3.3.1 + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.8.0 + + + com.google.code.maven-replacer-plugin + replacer + 1.5.3 + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.6.0 + + + + + \ No newline at end of file diff --git a/src/core/org/luaj/vm2/LuaThread.java b/src/core/org/luaj/vm2/LuaThread.java deleted file mode 100644 index a085abee..00000000 --- a/src/core/org/luaj/vm2/LuaThread.java +++ /dev/null @@ -1,260 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007-2012 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm2; - - -import java.lang.ref.WeakReference; - -/** - * Subclass of {@link LuaValue} that implements - * a lua coroutine thread using Java Threads. - *

    - * A LuaThread is typically created in response to a scripted call to - * {@code coroutine.create()} - *

    - * The threads must be initialized with the globals, so that - * the global environment may be passed along according to rules of lua. - * This is done via the constructor arguments {@link #LuaThread(Globals)} or - * {@link #LuaThread(Globals, LuaValue)}. - *

    - * The utility classes {@link org.luaj.vm2.lib.jse.JsePlatform} and - * {@link org.luaj.vm2.lib.jme.JmePlatform} - * see to it that this {@link Globals} are initialized properly. - *

    - * The behavior of coroutine threads matches closely the behavior - * of C coroutine library. However, because of the use of Java threads - * to manage call state, it is possible to yield from anywhere in luaj. - *

    - * Each Java thread wakes up at regular intervals and checks a weak reference - * to determine if it can ever be resumed. If not, it throws - * {@link OrphanedThread} which is an {@link java.lang.Error}. - * Applications should not catch {@link OrphanedThread}, because it can break - * the thread safety of luaj. The value controlling the polling interval - * is {@link #thread_orphan_check_interval} and may be set by the user. - *

    - * There are two main ways to abandon a coroutine. The first is to call - * {@code yield()} from lua, or equivalently {@link Globals#yield(Varargs)}, - * and arrange to have it never resumed possibly by values passed to yield. - * The second is to throw {@link OrphanedThread}, which should put the thread - * in a dead state. In either case all references to the thread must be - * dropped, and the garbage collector must run for the thread to be - * garbage collected. - * - * - * @see LuaValue - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - * @see org.luaj.vm2.lib.CoroutineLib - */ -public class LuaThread extends LuaValue { - - /** Shared metatable for lua threads. */ - public static LuaValue s_metatable; - - /** The current number of coroutines. Should not be set. */ - public static int coroutine_count = 0; - - /** Polling interval, in milliseconds, which each thread uses while waiting to - * return from a yielded state to check if the lua threads is no longer - * referenced and therefore should be garbage collected. - * A short polling interval for many threads will consume server resources. - * Orphaned threads cannot be detected and collected unless garbage - * collection is run. This can be changed by Java startup code if desired. - */ - public static long thread_orphan_check_interval = 5000; - - public static final int STATUS_INITIAL = 0; - public static final int STATUS_SUSPENDED = 1; - public static final int STATUS_RUNNING = 2; - public static final int STATUS_NORMAL = 3; - public static final int STATUS_DEAD = 4; - public static final String[] STATUS_NAMES = { - "suspended", - "suspended", - "running", - "normal", - "dead",}; - - public final State state; - - public static final int MAX_CALLSTACK = 256; - - /** Thread-local used by DebugLib to store debugging state. - * This is an opaque value that should not be modified by applications. */ - public Object callstack; - - public final Globals globals; - - /** Error message handler for this thread, if any. */ - public LuaValue errorfunc; - - /** Private constructor for main thread only */ - public LuaThread(Globals globals) { - state = new State(globals, this, null); - state.status = STATUS_RUNNING; - this.globals = globals; - } - - /** - * Create a LuaThread around a function and environment - * @param func The function to execute - */ - public LuaThread(Globals globals, LuaValue func) { - LuaValue.assert_(func != null, "function cannot be null"); - state = new State(globals, this, func); - this.globals = globals; - } - - public int type() { - return LuaValue.TTHREAD; - } - - public String typename() { - return "thread"; - } - - public boolean isthread() { - return true; - } - - public LuaThread optthread(LuaThread defval) { - return this; - } - - public LuaThread checkthread() { - return this; - } - - public LuaValue getmetatable() { - return s_metatable; - } - - public String getStatus() { - return STATUS_NAMES[state.status]; - } - - public boolean isMainThread() { - return this.state.function == null; - } - - public Varargs resume(Varargs args) { - final LuaThread.State s = this.state; - if (s.status > LuaThread.STATUS_SUSPENDED) - return LuaValue.varargsOf(LuaValue.FALSE, - LuaValue.valueOf("cannot resume "+(s.status==LuaThread.STATUS_DEAD? "dead": "non-suspended")+" coroutine")); - return s.lua_resume(this, args); - } - - public static class State implements Runnable { - private final Globals globals; - final WeakReference lua_thread; - public final LuaValue function; - Varargs args = LuaValue.NONE; - Varargs result = LuaValue.NONE; - String error = null; - - /** Hook function control state used by debug lib. */ - public LuaValue hookfunc; - - public boolean hookline; - public boolean hookcall; - public boolean hookrtrn; - public int hookcount; - public boolean inhook; - public int lastline; - public int bytecodes; - - public int status = LuaThread.STATUS_INITIAL; - - State(Globals globals, LuaThread lua_thread, LuaValue function) { - this.globals = globals; - this.lua_thread = new WeakReference(lua_thread); - this.function = function; - } - - public synchronized void run() { - try { - Varargs a = this.args; - this.args = LuaValue.NONE; - this.result = function.invoke(a); - } catch (Throwable t) { - this.error = t.getMessage(); - } finally { - this.status = LuaThread.STATUS_DEAD; - this.notify(); - } - } - - public synchronized Varargs lua_resume(LuaThread new_thread, Varargs args) { - LuaThread previous_thread = globals.running; - try { - globals.running = new_thread; - this.args = args; - if (this.status == STATUS_INITIAL) { - this.status = STATUS_RUNNING; - new Thread(this, "Coroutine-"+(++coroutine_count)).start(); - } else { - this.notify(); - } - if (previous_thread != null) - previous_thread.state.status = STATUS_NORMAL; - this.status = STATUS_RUNNING; - this.wait(); - return (this.error != null? - LuaValue.varargsOf(LuaValue.FALSE, LuaValue.valueOf(this.error)): - LuaValue.varargsOf(LuaValue.TRUE, this.result)); - } catch (InterruptedException ie) { - throw new OrphanedThread(); - } finally { - this.args = LuaValue.NONE; - this.result = LuaValue.NONE; - this.error = null; - globals.running = previous_thread; - if (previous_thread != null) - globals.running.state.status =STATUS_RUNNING; - } - } - - public synchronized Varargs lua_yield(Varargs args) { - try { - this.result = args; - this.status = STATUS_SUSPENDED; - this.notify(); - do { - this.wait(thread_orphan_check_interval); - if (this.lua_thread.get() == null) { - this.status = STATUS_DEAD; - throw new OrphanedThread(); - } - } while (this.status == STATUS_SUSPENDED); - return this.args; - } catch (InterruptedException ie) { - this.status = STATUS_DEAD; - throw new OrphanedThread(); - } finally { - this.args = LuaValue.NONE; - this.result = LuaValue.NONE; - } - } - } - -} diff --git a/src/core/org/luaj/vm2/lib/BaseLib.java b/src/core/org/luaj/vm2/lib/BaseLib.java deleted file mode 100644 index fb86825b..00000000 --- a/src/core/org/luaj/vm2/lib/BaseLib.java +++ /dev/null @@ -1,485 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2009 Luaj.org. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm2.lib; - -import java.io.IOException; -import java.io.InputStream; - -import org.luaj.vm2.Globals; -import org.luaj.vm2.Lua; -import org.luaj.vm2.LuaError; -import org.luaj.vm2.LuaString; -import org.luaj.vm2.LuaTable; -import org.luaj.vm2.LuaThread; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Varargs; - -/** - * Subclass of {@link LibFunction} which implements the lua basic library functions. - *

    - * This contains all library functions listed as "basic functions" in the lua documentation for JME. - * The functions dofile and loadfile use the - * {@link Globals#finder} instance to find resource files. - * Since JME has no file system by default, {@link BaseLib} implements - * {@link ResourceFinder} using {@link Class#getResource(String)}, - * which is the closest equivalent on JME. - * The default loader chain in {@link PackageLib} will use these as well. - *

    - * To use basic library functions that include a {@link ResourceFinder} based on - * directory lookup, use {@link org.luaj.vm2.lib.jse.JseBaseLib} instead. - *

    - * Typically, this library is included as part of a call to either - * {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} or - * {@link org.luaj.vm2.lib.jme.JmePlatform#standardGlobals()} - *

     {@code
    - * Globals globals = JsePlatform.standardGlobals();
    - * globals.get("print").call(LuaValue.valueOf("hello, world"));
    - * } 
    - *

    - * For special cases where the smallest possible footprint is desired, - * a minimal set of libraries could be loaded - * directly via {@link Globals#load(LuaValue)} using code such as: - *

     {@code
    - * Globals globals = new Globals();
    - * globals.load(new JseBaseLib());
    - * globals.get("print").call(LuaValue.valueOf("hello, world"));
    - * } 
    - * Doing so will ensure the library is properly initialized - * and loaded into the globals table. - *

    - * This is a direct port of the corresponding library in C. - * @see org.luaj.vm2.lib.jse.JseBaseLib - * @see ResourceFinder - * @see Globals#finder - * @see LibFunction - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - * @see Lua 5.2 Base Lib Reference - */ -public class BaseLib extends TwoArgFunction implements ResourceFinder { - - Globals globals; - - - /** Perform one-time initialization on the library by adding base functions - * to the supplied environment, and returning it as the return value. - * @param modname the module name supplied if this is loaded via 'require'. - * @param env the environment to load into, which must be a Globals instance. - */ - public LuaValue call(LuaValue modname, LuaValue env) { - globals = env.checkglobals(); - globals.finder = this; - globals.baselib = this; - env.set( "_G", env ); - env.set( "_VERSION", Lua._VERSION ); - env.set("assert", new _assert()); - env.set("collectgarbage", new collectgarbage()); - env.set("dofile", new dofile()); - env.set("error", new error()); - env.set("getmetatable", new getmetatable()); - env.set("load", new load()); - env.set("loadfile", new loadfile()); - env.set("pcall", new pcall()); - env.set("print", new print(this)); - env.set("rawequal", new rawequal()); - env.set("rawget", new rawget()); - env.set("rawlen", new rawlen()); - env.set("rawset", new rawset()); - env.set("select", new select()); - env.set("setmetatable", new setmetatable()); - env.set("tonumber", new tonumber()); - env.set("tostring", new tostring()); - env.set("type", new type()); - env.set("xpcall", new xpcall()); - - next next; - env.set("next", next = new next()); - env.set("pairs", new pairs(next)); - env.set("ipairs", new ipairs()); - - return env; - } - - /** ResourceFinder implementation - * - * Tries to open the file as a resource, which can work for JSE and JME. - */ - public InputStream findResource(String filename) { - return getClass().getResourceAsStream(filename.startsWith("/")? filename: "/"+filename); - } - - - // "assert", // ( v [,message] ) -> v, message | ERR - static final class _assert extends VarArgFunction { - public Varargs invoke(Varargs args) { - if ( !args.arg1().toboolean() ) - error( args.narg()>1? args.optjstring(2,"assertion failed!"): "assertion failed!" ); - return args; - } - } - - // "collectgarbage", // ( opt [,arg] ) -> value - static final class collectgarbage extends VarArgFunction { - public Varargs invoke(Varargs args) { - String s = args.optjstring(1, "collect"); - if ( "collect".equals(s) ) { - System.gc(); - return ZERO; - } else if ( "count".equals(s) ) { - Runtime rt = Runtime.getRuntime(); - long used = rt.totalMemory() - rt.freeMemory(); - return varargsOf(valueOf(used/1024.), valueOf(used%1024)); - } else if ( "step".equals(s) ) { - System.gc(); - return LuaValue.TRUE; - } else { - argerror(1, "invalid option '" + s + "'"); - } - return NIL; - } - } - - // "dofile", // ( filename ) -> result1, ... - final class dofile extends VarArgFunction { - public Varargs invoke(Varargs args) { - args.argcheck(args.isstring(1) || args.isnil(1), 1, "filename must be string or nil"); - String filename = args.isstring(1)? args.tojstring(1): null; - Varargs v = filename == null? - loadStream( globals.STDIN, "=stdin", "bt", globals ): - loadFile( args.checkjstring(1), "bt", globals ); - return v.isnil(1)? error(v.tojstring(2)): v.arg1().invoke(); - } - } - - // "error", // ( message [,level] ) -> ERR - static final class error extends TwoArgFunction { - public LuaValue call(LuaValue arg1, LuaValue arg2) { - if (arg1.isnil()) throw new LuaError(NIL); - if (!arg1.isstring() || arg2.optint(1) == 0) throw new LuaError(arg1); - throw new LuaError(arg1.tojstring(), arg2.optint(1)); - } - } - - // "getmetatable", // ( object ) -> table - static final class getmetatable extends LibFunction { - public LuaValue call() { - return argerror(1, "value expected"); - } - public LuaValue call(LuaValue arg) { - LuaValue mt = arg.getmetatable(); - return mt!=null? mt.rawget(METATABLE).optvalue(mt): NIL; - } - } - // "load", // ( ld [, source [, mode [, env]]] ) -> chunk | nil, msg - final class load extends VarArgFunction { - public Varargs invoke(Varargs args) { - LuaValue ld = args.arg1(); - if (!ld.isstring() && !ld.isfunction()) { - throw new LuaError("bad argument #1 to 'load' (string or function expected, got " + ld.typename() + ")"); - } - String source = args.optjstring(2, ld.isstring()? ld.tojstring(): "=(load)"); - String mode = args.optjstring(3, "bt"); - LuaValue env = args.optvalue(4, globals); - return loadStream(ld.isstring()? ld.strvalue().toInputStream(): - new StringInputStream(ld.checkfunction()), source, mode, env); - } - } - - // "loadfile", // ( [filename [, mode [, env]]] ) -> chunk | nil, msg - final class loadfile extends VarArgFunction { - public Varargs invoke(Varargs args) { - args.argcheck(args.isstring(1) || args.isnil(1), 1, "filename must be string or nil"); - String filename = args.isstring(1)? args.tojstring(1): null; - String mode = args.optjstring(2, "bt"); - LuaValue env = args.optvalue(3, globals); - return filename == null? - loadStream( globals.STDIN, "=stdin", mode, env ): - loadFile( filename, mode, env ); - } - } - - // "pcall", // (f, arg1, ...) -> status, result1, ... - final class pcall extends VarArgFunction { - public Varargs invoke(Varargs args) { - LuaValue func = args.checkvalue(1); - if (globals != null && globals.debuglib != null) - globals.debuglib.onCall(this); - try { - return varargsOf(TRUE, func.invoke(args.subargs(2))); - } catch ( LuaError le ) { - final LuaValue m = le.getMessageObject(); - return varargsOf(FALSE, m!=null? m: NIL); - } catch ( Exception e ) { - final String m = e.getMessage(); - return varargsOf(FALSE, valueOf(m!=null? m: e.toString())); - } finally { - if (globals != null && globals.debuglib != null) - globals.debuglib.onReturn(); - } - } - } - - // "print", // (...) -> void - final class print extends VarArgFunction { - final BaseLib baselib; - print(BaseLib baselib) { - this.baselib = baselib; - } - public Varargs invoke(Varargs args) { - LuaValue tostring = globals.get("tostring"); - for ( int i=1, n=args.narg(); i<=n; i++ ) { - if ( i>1 ) globals.STDOUT.print( '\t' ); - LuaString s = tostring.call( args.arg(i) ).strvalue(); - globals.STDOUT.print(s.tojstring()); - } - globals.STDOUT.print('\n'); - return NONE; - } - } - - - // "rawequal", // (v1, v2) -> boolean - static final class rawequal extends LibFunction { - public LuaValue call() { - return argerror(1, "value expected"); - } - public LuaValue call(LuaValue arg) { - return argerror(2, "value expected"); - } - public LuaValue call(LuaValue arg1, LuaValue arg2) { - return valueOf(arg1.raweq(arg2)); - } - } - - // "rawget", // (table, index) -> value - static final class rawget extends TableLibFunction { - public LuaValue call(LuaValue arg) { - return argerror(2, "value expected"); - } - public LuaValue call(LuaValue arg1, LuaValue arg2) { - return arg1.checktable().rawget(arg2); - } - } - - - // "rawlen", // (v) -> value - static final class rawlen extends LibFunction { - public LuaValue call(LuaValue arg) { - return valueOf(arg.rawlen()); - } - } - - // "rawset", // (table, index, value) -> table - static final class rawset extends TableLibFunction { - public LuaValue call(LuaValue table) { - return argerror(2,"value expected"); - } - public LuaValue call(LuaValue table, LuaValue index) { - return argerror(3,"value expected"); - } - public LuaValue call(LuaValue table, LuaValue index, LuaValue value) { - LuaTable t = table.checktable(); - if (!index.isvalidkey()) argerror(2, "table index is nil"); - t.rawset(index, value); - return t; - } - } - - // "select", // (f, ...) -> value1, ... - static final class select extends VarArgFunction { - public Varargs invoke(Varargs args) { - int n = args.narg()-1; - if ( args.arg1().equals(valueOf("#")) ) - return valueOf(n); - int i = args.checkint(1); - if ( i == 0 || i < -n ) - argerror(1,"index out of range"); - return args.subargs(i<0? n+i+2: i+1); - } - } - - // "setmetatable", // (table, metatable) -> table - static final class setmetatable extends TableLibFunction { - public LuaValue call(LuaValue table) { - return argerror(2,"nil or table expected"); - } - public LuaValue call(LuaValue table, LuaValue metatable) { - final LuaValue mt0 = table.checktable().getmetatable(); - if ( mt0!=null && !mt0.rawget(METATABLE).isnil() ) - error("cannot change a protected metatable"); - return table.setmetatable(metatable.isnil()? null: metatable.checktable()); - } - } - - // "tonumber", // (e [,base]) -> value - static final class tonumber extends LibFunction { - public LuaValue call(LuaValue e) { - return e.tonumber(); - } - public LuaValue call(LuaValue e, LuaValue base) { - if (base.isnil()) - return e.tonumber(); - final int b = base.checkint(); - if ( b < 2 || b > 36 ) - argerror(2, "base out of range"); - return e.checkstring().tonumber(b); - } - } - - // "tostring", // (e) -> value - static final class tostring extends LibFunction { - public LuaValue call(LuaValue arg) { - LuaValue h = arg.metatag(TOSTRING); - if ( ! h.isnil() ) - return h.call(arg); - LuaValue v = arg.tostring(); - if ( ! v.isnil() ) - return v; - return valueOf(arg.tojstring()); - } - } - - // "type", // (v) -> value - static final class type extends LibFunction { - public LuaValue call(LuaValue arg) { - return valueOf(arg.typename()); - } - } - - // "xpcall", // (f, err) -> result1, ... - final class xpcall extends VarArgFunction { - public Varargs invoke(Varargs args) { - final LuaThread t = globals.running; - final LuaValue preverror = t.errorfunc; - t.errorfunc = args.checkvalue(2); - try { - if (globals != null && globals.debuglib != null) - globals.debuglib.onCall(this); - try { - return varargsOf(TRUE, args.arg1().invoke(args.subargs(3))); - } catch ( LuaError le ) { - final LuaValue m = le.getMessageObject(); - return varargsOf(FALSE, m!=null? m: NIL); - } catch ( Exception e ) { - final String m = e.getMessage(); - return varargsOf(FALSE, valueOf(m!=null? m: e.toString())); - } finally { - if (globals != null && globals.debuglib != null) - globals.debuglib.onReturn(); - } - } finally { - t.errorfunc = preverror; - } - } - } - - // "pairs" (t) -> iter-func, t, nil - static final class pairs extends VarArgFunction { - final next next; - pairs(next next) { - this.next = next; - } - public Varargs invoke(Varargs args) { - return varargsOf( next, args.checktable(1), NIL ); - } - } - - // // "ipairs", // (t) -> iter-func, t, 0 - static final class ipairs extends VarArgFunction { - inext inext = new inext(); - public Varargs invoke(Varargs args) { - return varargsOf( inext, args.checktable(1), ZERO ); - } - } - - // "next" ( table, [index] ) -> next-index, next-value - static final class next extends VarArgFunction { - public Varargs invoke(Varargs args) { - return args.checktable(1).next(args.arg(2)); - } - } - - // "inext" ( table, [int-index] ) -> next-index, next-value - static final class inext extends VarArgFunction { - public Varargs invoke(Varargs args) { - return args.checktable(1).inext(args.arg(2)); - } - } - - /** - * Load from a named file, returning the chunk or nil,error of can't load - * @param env - * @param mode - * @return Varargs containing chunk, or NIL,error-text on error - */ - public Varargs loadFile(String filename, String mode, LuaValue env) { - InputStream is = globals.finder.findResource(filename); - if ( is == null ) - return varargsOf(NIL, valueOf("cannot open "+filename+": No such file or directory")); - try { - return loadStream(is, "@"+filename, mode, env); - } finally { - try { - is.close(); - } catch ( Exception e ) { - e.printStackTrace(); - } - } - } - - public Varargs loadStream(InputStream is, String chunkname, String mode, LuaValue env) { - try { - if ( is == null ) - return varargsOf(NIL, valueOf("not found: "+chunkname)); - return globals.load(is, chunkname, mode, env); - } catch (Exception e) { - return varargsOf(NIL, valueOf(e.getMessage())); - } - } - - - private static class StringInputStream extends InputStream { - final LuaValue func; - byte[] bytes; - int offset, remaining = 0; - StringInputStream(LuaValue func) { - this.func = func; - } - public int read() throws IOException { - if ( remaining < 0 ) - return -1; - if ( remaining == 0 ) { - LuaValue s = func.call(); - if ( s.isnil() ) - return remaining = -1; - LuaString ls = s.strvalue(); - bytes = ls.m_bytes; - offset = ls.m_offset; - remaining = ls.m_length; - if (remaining <= 0) - return -1; - } - --remaining; - return 0xFF&bytes[offset++]; - } - } -} diff --git a/src/core/org/luaj/vm2/lib/Bit32Lib.java b/src/core/org/luaj/vm2/lib/Bit32Lib.java deleted file mode 100644 index 699c6945..00000000 --- a/src/core/org/luaj/vm2/lib/Bit32Lib.java +++ /dev/null @@ -1,224 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2012 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.lib; - -import org.luaj.vm2.LuaTable; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Varargs; - -/** - * Subclass of LibFunction that implements the Lua standard {@code bit32} library. - *

    - * Typically, this library is included as part of a call to either - * {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} or {@link org.luaj.vm2.lib.jme.JmePlatform#standardGlobals()} - *

     {@code
    - * Globals globals = JsePlatform.standardGlobals();
    - * System.out.println( globals.get("bit32").get("bnot").call( LuaValue.valueOf(2) ) );
    - * } 
    - *

    - * To instantiate and use it directly, - * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as: - *

     {@code
    - * Globals globals = new Globals();
    - * globals.load(new JseBaseLib());
    - * globals.load(new PackageLib());
    - * globals.load(new Bit32Lib());
    - * System.out.println( globals.get("bit32").get("bnot").call( LuaValue.valueOf(2) ) );
    - * } 
    - *

    - * This has been implemented to match as closely as possible the behavior in the corresponding library in C. - * @see LibFunction - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - * @see Lua 5.2 Bitwise Operation Lib Reference - */ -public class Bit32Lib extends TwoArgFunction { - - public Bit32Lib() { - } - - /** Perform one-time initialization on the library by creating a table - * containing the library functions, adding that table to the supplied environment, - * adding the table to package.loaded, and returning table as the return value. - * @param modname the module name supplied if this is loaded via 'require'. - * @param env the environment to load into, which must be a Globals instance. - */ - public LuaValue call(LuaValue modname, LuaValue env) { - LuaTable t = new LuaTable(); - bind(t, Bit32LibV.class, new String[] { - "band", "bnot", "bor", "btest", "bxor", "extract", "replace" - }); - bind(t, Bit32Lib2.class, new String[] { - "arshift", "lrotate", "lshift", "rrotate", "rshift" - }); - env.set("bit32", t); - if (!env.get("package").isnil()) env.get("package").get("loaded").set("bit32", t); - return t; - } - - static final class Bit32LibV extends VarArgFunction { - public Varargs invoke(Varargs args) { - switch ( opcode ) { - case 0: return Bit32Lib.band( args ); - case 1: return Bit32Lib.bnot( args ); - case 2: return Bit32Lib.bor( args ); - case 3: return Bit32Lib.btest( args ); - case 4: return Bit32Lib.bxor( args ); - case 5: - return Bit32Lib.extract( args.checkint(1), args.checkint(2), args.optint(3, 1) ); - case 6: - return Bit32Lib.replace( args.checkint(1), args.checkint(2), - args.checkint(3), args.optint(4, 1) ); - } - return NIL; - } - } - - static final class Bit32Lib2 extends TwoArgFunction { - - public LuaValue call(LuaValue arg1, LuaValue arg2) { - switch ( opcode ) { - case 0: return Bit32Lib.arshift(arg1.checkint(), arg2.checkint()); - case 1: return Bit32Lib.lrotate(arg1.checkint(), arg2.checkint()); - case 2: return Bit32Lib.lshift(arg1.checkint(), arg2.checkint()); - case 3: return Bit32Lib.rrotate(arg1.checkint(), arg2.checkint()); - case 4: return Bit32Lib.rshift(arg1.checkint(), arg2.checkint()); - } - return NIL; - } - - } - - static LuaValue arshift(int x, int disp) { - if (disp >= 0) { - return bitsToValue(x >> disp); - } else { - return bitsToValue(x << -disp); - } - } - - static LuaValue rshift(int x, int disp) { - if (disp >= 32 || disp <= -32) { - return ZERO; - } else if (disp >= 0) { - return bitsToValue(x >>> disp); - } else { - return bitsToValue(x << -disp); - } - } - - static LuaValue lshift(int x, int disp) { - if (disp >= 32 || disp <= -32) { - return ZERO; - } else if (disp >= 0) { - return bitsToValue(x << disp); - } else { - return bitsToValue(x >>> -disp); - } - } - - static Varargs band( Varargs args ) { - int result = -1; - for ( int i = 1; i <= args.narg(); i++ ) { - result &= args.checkint(i); - } - return bitsToValue( result ); - } - - static Varargs bnot( Varargs args ) { - return bitsToValue( ~args.checkint(1) ); - } - - static Varargs bor( Varargs args ) { - int result = 0; - for ( int i = 1; i <= args.narg(); i++ ) { - result |= args.checkint(i); - } - return bitsToValue( result ); - } - - static Varargs btest( Varargs args ) { - int bits = -1; - for ( int i = 1; i <= args.narg(); i++ ) { - bits &= args.checkint(i); - } - return valueOf( bits != 0 ); - } - - static Varargs bxor( Varargs args ) { - int result = 0; - for ( int i = 1; i <= args.narg(); i++ ) { - result ^= args.checkint(i); - } - return bitsToValue( result ); - } - - static LuaValue lrotate(int x, int disp) { - if (disp < 0) { - return rrotate(x, -disp); - } else { - disp = disp & 31; - return bitsToValue((x << disp) | (x >>> (32 - disp))); - } - } - - static LuaValue rrotate(int x, int disp) { - if (disp < 0) { - return lrotate(x, -disp); - } else { - disp = disp & 31; - return bitsToValue((x >>> disp) | (x << (32 - disp))); - } - } - - static LuaValue extract(int n, int field, int width) { - if (field < 0) { - argerror(2, "field cannot be negative"); - } - if (width < 0) { - argerror(3, "width must be postive"); - } - if (field + width > 32) { - error("trying to access non-existent bits"); - } - return bitsToValue((n >>> field) & (-1 >>> (32 - width))); - } - - static LuaValue replace(int n, int v, int field, int width) { - if (field < 0) { - argerror(3, "field cannot be negative"); - } - if (width < 0) { - argerror(4, "width must be postive"); - } - if (field + width > 32) { - error("trying to access non-existent bits"); - } - int mask = (-1 >>> (32 - width)) << field; - n = (n & ~mask) | ((v << field) & mask); - return bitsToValue(n); - } - - private static LuaValue bitsToValue( int x ) { - return ( x < 0 ) ? valueOf((double) ((long) x & 0xFFFFFFFFL)) : valueOf(x); - } -} diff --git a/src/core/org/luaj/vm2/lib/CoroutineLib.java b/src/core/org/luaj/vm2/lib/CoroutineLib.java deleted file mode 100644 index 28cb246b..00000000 --- a/src/core/org/luaj/vm2/lib/CoroutineLib.java +++ /dev/null @@ -1,144 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007-2011 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm2.lib; - -import org.luaj.vm2.Globals; -import org.luaj.vm2.LuaTable; -import org.luaj.vm2.LuaThread; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Varargs; - -/** - * Subclass of {@link LibFunction} which implements the lua standard {@code coroutine} - * library. - *

    - * The coroutine library in luaj has the same behavior as the - * coroutine library in C, but is implemented using Java Threads to maintain - * the call state between invocations. Therefore it can be yielded from anywhere, - * similar to the "Coco" yield-from-anywhere patch available for C-based lua. - * However, coroutines that are yielded but never resumed to complete their execution - * may not be collected by the garbage collector. - *

    - * Typically, this library is included as part of a call to either - * {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} or {@link org.luaj.vm2.lib.jme.JmePlatform#standardGlobals()} - *

     {@code
    - * Globals globals = JsePlatform.standardGlobals();
    - * System.out.println( globals.get("coroutine").get("running").call() );
    - * } 
    - *

    - * To instantiate and use it directly, - * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as: - *

     {@code
    - * Globals globals = new Globals();
    - * globals.load(new JseBaseLib());
    - * globals.load(new PackageLib());
    - * globals.load(new CoroutineLib());
    - * System.out.println( globals.get("coroutine").get("running").call() );
    - * } 
    - *

    - * @see LibFunction - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - * @see Lua 5.2 Coroutine Lib Reference - */ -public class CoroutineLib extends TwoArgFunction { - - static int coroutine_count = 0; - - Globals globals; - - /** Perform one-time initialization on the library by creating a table - * containing the library functions, adding that table to the supplied environment, - * adding the table to package.loaded, and returning table as the return value. - * @param modname the module name supplied if this is loaded via 'require'. - * @param env the environment to load into, which must be a Globals instance. - */ - public LuaValue call(LuaValue modname, LuaValue env) { - globals = env.checkglobals(); - LuaTable coroutine = new LuaTable(); - coroutine.set("create", new create()); - coroutine.set("resume", new resume()); - coroutine.set("running", new running()); - coroutine.set("status", new status()); - coroutine.set("yield", new yield()); - coroutine.set("wrap", new wrap()); - env.set("coroutine", coroutine); - if (!env.get("package").isnil()) env.get("package").get("loaded").set("coroutine", coroutine); - return coroutine; - } - - final class create extends LibFunction { - public LuaValue call(LuaValue f) { - return new LuaThread(globals, f.checkfunction()); - } - } - - static final class resume extends VarArgFunction { - public Varargs invoke(Varargs args) { - final LuaThread t = args.checkthread(1); - return t.resume( args.subargs(2) ); - } - } - - final class running extends VarArgFunction { - public Varargs invoke(Varargs args) { - final LuaThread r = globals.running; - return varargsOf(r, valueOf(r.isMainThread())); - } - } - - static final class status extends LibFunction { - public LuaValue call(LuaValue t) { - LuaThread lt = t.checkthread(); - return valueOf( lt.getStatus() ); - } - } - - final class yield extends VarArgFunction { - public Varargs invoke(Varargs args) { - return globals.yield( args ); - } - } - - final class wrap extends LibFunction { - public LuaValue call(LuaValue f) { - final LuaValue func = f.checkfunction(); - final LuaThread thread = new LuaThread(globals, func); - return new wrapper(thread); - } - } - - static final class wrapper extends VarArgFunction { - final LuaThread luathread; - wrapper(LuaThread luathread) { - this.luathread = luathread; - } - public Varargs invoke(Varargs args) { - final Varargs result = luathread.resume(args); - if ( result.arg1().toboolean() ) { - return result.subargs(2); - } else { - return error( result.arg(2).tojstring() ); - } - } - } -} diff --git a/src/core/org/luaj/vm2/lib/DebugLib.java b/src/core/org/luaj/vm2/lib/DebugLib.java deleted file mode 100644 index 167ea36c..00000000 --- a/src/core/org/luaj/vm2/lib/DebugLib.java +++ /dev/null @@ -1,899 +0,0 @@ -/******************************************************************************* -* 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.lib; - -import org.luaj.vm2.Globals; -import org.luaj.vm2.Lua; -import org.luaj.vm2.LuaBoolean; -import org.luaj.vm2.LuaClosure; -import org.luaj.vm2.LuaError; -import org.luaj.vm2.LuaFunction; -import org.luaj.vm2.LuaNil; -import org.luaj.vm2.LuaNumber; -import org.luaj.vm2.LuaString; -import org.luaj.vm2.LuaTable; -import org.luaj.vm2.LuaThread; -import org.luaj.vm2.LuaUserdata; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Print; -import org.luaj.vm2.Prototype; -import org.luaj.vm2.Varargs; - -/** - * Subclass of {@link LibFunction} which implements the lua standard {@code debug} - * library. - *

    - * The debug library in luaj tries to emulate the behavior of the corresponding C-based lua library. - * To do this, it must maintain a separate stack of calls to {@link LuaClosure} and {@link LibFunction} - * instances. - * Especially when lua-to-java bytecode compiling is being used - * via a {@link org.luaj.vm2.Globals.Compiler} such as {@link org.luaj.vm2.luajc.LuaJC}, - * this cannot be done in all cases. - *

    - * Typically, this library is included as part of a call to either - * {@link org.luaj.vm2.lib.jse.JsePlatform#debugGlobals()} or - * {@link org.luaj.vm2.lib.jme.JmePlatform#debugGlobals()} - *

     {@code
    - * Globals globals = JsePlatform.debugGlobals();
    - * System.out.println( globals.get("debug").get("traceback").call() );
    - * } 
    - *

    - * To instantiate and use it directly, - * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as: - *

     {@code
    - * Globals globals = new Globals();
    - * globals.load(new JseBaseLib());
    - * globals.load(new PackageLib());
    - * globals.load(new DebugLib());
    - * System.out.println( globals.get("debug").get("traceback").call() );
    - * } 
    - *

    - * This library exposes the entire state of lua code, and provides method to see and modify - * all underlying lua values within a Java VM so should not be exposed to client code - * in a shared server environment. - * - * @see LibFunction - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - * @see Lua 5.2 Debug Lib Reference - */ -public class DebugLib extends TwoArgFunction { - public static boolean CALLS; - public static boolean TRACE; - static { - try { CALLS = (null != System.getProperty("CALLS")); } catch (Exception e) {} - try { TRACE = (null != System.getProperty("TRACE")); } catch (Exception e) {} - } - - static final LuaString LUA = valueOf("Lua"); - private static final LuaString QMARK = valueOf("?"); - private static final LuaString CALL = valueOf("call"); - private static final LuaString LINE = valueOf("line"); - private static final LuaString COUNT = valueOf("count"); - private static final LuaString RETURN = valueOf("return"); - - static final LuaString FUNC = valueOf("func"); - static final LuaString ISTAILCALL = valueOf("istailcall"); - static final LuaString ISVARARG = valueOf("isvararg"); - static final LuaString NUPS = valueOf("nups"); - static final LuaString NPARAMS = valueOf("nparams"); - static final LuaString NAME = valueOf("name"); - static final LuaString NAMEWHAT = valueOf("namewhat"); - static final LuaString WHAT = valueOf("what"); - static final LuaString SOURCE = valueOf("source"); - static final LuaString SHORT_SRC = valueOf("short_src"); - static final LuaString LINEDEFINED = valueOf("linedefined"); - static final LuaString LASTLINEDEFINED = valueOf("lastlinedefined"); - static final LuaString CURRENTLINE = valueOf("currentline"); - static final LuaString ACTIVELINES = valueOf("activelines"); - - Globals globals; - - /** Perform one-time initialization on the library by creating a table - * containing the library functions, adding that table to the supplied environment, - * adding the table to package.loaded, and returning table as the return value. - * @param modname the module name supplied if this is loaded via 'require'. - * @param env the environment to load into, which must be a Globals instance. - */ - public LuaValue call(LuaValue modname, LuaValue env) { - globals = env.checkglobals(); - globals.debuglib = this; - LuaTable debug = new LuaTable(); - debug.set("debug", new debug()); - debug.set("gethook", new gethook()); - debug.set("getinfo", new getinfo()); - debug.set("getlocal", new getlocal()); - debug.set("getmetatable", new getmetatable()); - debug.set("getregistry", new getregistry()); - debug.set("getupvalue", new getupvalue()); - debug.set("getuservalue", new getuservalue()); - debug.set("sethook", new sethook()); - debug.set("setlocal", new setlocal()); - debug.set("setmetatable", new setmetatable()); - debug.set("setupvalue", new setupvalue()); - debug.set("setuservalue", new setuservalue()); - debug.set("traceback", new traceback()); - debug.set("upvalueid", new upvalueid()); - debug.set("upvaluejoin", new upvaluejoin()); - env.set("debug", debug); - if (!env.get("package").isnil()) env.get("package").get("loaded").set("debug", debug); - return debug; - } - - // debug.debug() - static final class debug extends ZeroArgFunction { - public LuaValue call() { - return NONE; - } - } - - // debug.gethook ([thread]) - final class gethook extends VarArgFunction { - public Varargs invoke(Varargs args) { - LuaThread t = args.narg() > 0 ? args.checkthread(1): globals.running; - LuaThread.State s = t.state; - return varargsOf( - s.hookfunc != null? s.hookfunc: NIL, - valueOf((s.hookcall?"c":"")+(s.hookline?"l":"")+(s.hookrtrn?"r":"")), - valueOf(s.hookcount)); - } - } - - // debug.getinfo ([thread,] f [, what]) - final class getinfo extends VarArgFunction { - public Varargs invoke(Varargs args) { - int a=1; - LuaThread thread = args.isthread(a)? args.checkthread(a++): globals.running; - LuaValue func = args.arg(a++); - String what = args.optjstring(a++, "flnStu"); - DebugLib.CallStack callstack = callstack(thread); - - // find the stack info - DebugLib.CallFrame frame; - if ( func.isnumber() ) { - frame = callstack.getCallFrame(func.toint()); - if (frame == null) - return NONE; - func = frame.f; - } else if ( func.isfunction() ) { - frame = callstack.findCallFrame(func); - } else { - return argerror(a-2, "function or level"); - } - - // start a table - DebugInfo ar = callstack.auxgetinfo(what, (LuaFunction) func, frame); - LuaTable info = new LuaTable(); - if (what.indexOf('S') >= 0) { - info.set(WHAT, LUA); - info.set(SOURCE, valueOf(ar.source)); - info.set(SHORT_SRC, valueOf(ar.short_src)); - info.set(LINEDEFINED, valueOf(ar.linedefined)); - info.set(LASTLINEDEFINED, valueOf(ar.lastlinedefined)); - } - if (what.indexOf('l') >= 0) { - info.set( CURRENTLINE, valueOf(ar.currentline) ); - } - if (what.indexOf('u') >= 0) { - info.set(NUPS, valueOf(ar.nups)); - info.set(NPARAMS, valueOf(ar.nparams)); - info.set(ISVARARG, ar.isvararg? ONE: ZERO); - } - if (what.indexOf('n') >= 0) { - info.set(NAME, LuaValue.valueOf(ar.name!=null? ar.name: "?")); - info.set(NAMEWHAT, LuaValue.valueOf(ar.namewhat)); - } - if (what.indexOf('t') >= 0) { - info.set(ISTAILCALL, ZERO); - } - if (what.indexOf('L') >= 0) { - LuaTable lines = new LuaTable(); - info.set(ACTIVELINES, lines); - DebugLib.CallFrame cf; - for (int l = 1; (cf=callstack.getCallFrame(l)) != null; ++l) - if (cf.f == func) - lines.insert(-1, valueOf(cf.currentline())); - } - if (what.indexOf('f') >= 0) { - if (func != null) - info.set( FUNC, func ); - } - return info; - } - } - - // debug.getlocal ([thread,] f, local) - final class getlocal extends VarArgFunction { - public Varargs invoke(Varargs args) { - int a=1; - LuaThread thread = args.isthread(a)? args.checkthread(a++): globals.running; - int level = args.checkint(a++); - int local = args.checkint(a++); - CallFrame f = callstack(thread).getCallFrame(level); - return f != null? f.getLocal(local): NONE; - } - } - - // debug.getmetatable (value) - static final class getmetatable extends LibFunction { - public LuaValue call(LuaValue v) { - LuaValue mt = v.getmetatable(); - return mt != null? mt: NIL; - } - } - - // debug.getregistry () - final class getregistry extends ZeroArgFunction { - public LuaValue call() { - return globals; - } - } - - // debug.getupvalue (f, up) - static final class getupvalue extends VarArgFunction { - public Varargs invoke(Varargs args) { - LuaValue func = args.checkfunction(1); - int up = args.checkint(2); - if ( func instanceof LuaClosure ) { - LuaClosure c = (LuaClosure) func; - LuaString name = findupvalue(c, up); - if ( name != null ) { - return varargsOf(name, c.upValues[up-1].getValue() ); - } - } - return NIL; - } - } - - // debug.getuservalue (u) - static final class getuservalue extends LibFunction { - public LuaValue call(LuaValue u) { - return u.isuserdata()? u: NIL; - } - } - - - // debug.sethook ([thread,] hook, mask [, count]) - final class sethook extends VarArgFunction { - public Varargs invoke(Varargs args) { - int a=1; - LuaThread t = args.isthread(a)? args.checkthread(a++): globals.running; - LuaValue func = args.optfunction(a++, null); - String str = args.optjstring(a++,""); - int count = args.optint(a++,0); - boolean call=false,line=false,rtrn=false; - for ( int i=0; i 0 && up <= c.upValues.length ) { - return valueOf(c.upValues[up-1].hashCode()); - } - } - return NIL; - } - } - - // debug.upvaluejoin (f1, n1, f2, n2) - static final class upvaluejoin extends VarArgFunction { - public Varargs invoke(Varargs args) { - LuaClosure f1 = args.checkclosure(1); - int n1 = args.checkint(2); - LuaClosure f2 = args.checkclosure(3); - int n2 = args.checkint(4); - if (n1 < 1 || n1 > f1.upValues.length) - argerror("index out of range"); - if (n2 < 1 || n2 > f2.upValues.length) - argerror("index out of range"); - f1.upValues[n1-1] = f2.upValues[n2-1]; - return NONE; - } - } - - public void onCall(LuaFunction f) { - LuaThread.State s = globals.running.state; - if (s.inhook) return; - callstack().onCall(f); - if (s.hookcall) callHook(s, CALL, NIL); - } - - public void onCall(LuaClosure c, Varargs varargs, LuaValue[] stack) { - LuaThread.State s = globals.running.state; - if (s.inhook) return; - callstack().onCall(c, varargs, stack); - if (s.hookcall) callHook(s, CALL, NIL); - } - - public void onInstruction(int pc, Varargs v, int top) { - LuaThread.State s = globals.running.state; - if (s.inhook) return; - callstack().onInstruction(pc, v, top); - if (s.hookfunc == null) return; - if (s.hookcount > 0) - if (++s.bytecodes % s.hookcount == 0) - callHook(s, COUNT, NIL); - if (s.hookline) { - int newline = callstack().currentline(); - if ( newline != s.lastline ) { - s.lastline = newline; - callHook(s, LINE, LuaValue.valueOf(newline)); - } - } - } - - public void onReturn() { - LuaThread.State s = globals.running.state; - if (s.inhook) return; - callstack().onReturn(); - if (s.hookrtrn) callHook(s, RETURN, NIL); - } - - public String traceback(int level) { - return callstack().traceback(level); - } - - public CallFrame getCallFrame(int level) { - return callstack().getCallFrame(level); - } - - void callHook(LuaThread.State s, LuaValue type, LuaValue arg) { - if (s.inhook || s.hookfunc == null) return; - s.inhook = true; - try { - s.hookfunc.call(type, arg); - } catch (LuaError e) { - throw e; - } catch (RuntimeException e) { - throw new LuaError(e); - } finally { - s.inhook = false; - } - } - - CallStack callstack() { - return callstack(globals.running); - } - - CallStack callstack(LuaThread t) { - if (t.callstack == null) - t.callstack = new CallStack(); - return (CallStack) t.callstack; - } - - static class DebugInfo { - String name; /* (n) */ - String namewhat; /* (n) 'global', 'local', 'field', 'method' */ - String what; /* (S) 'Lua', 'C', 'main', 'tail' */ - String source; /* (S) */ - int currentline; /* (l) */ - int linedefined; /* (S) */ - int lastlinedefined; /* (S) */ - short nups; /* (u) number of upvalues */ - short nparams;/* (u) number of parameters */ - boolean isvararg; /* (u) */ - boolean istailcall; /* (t) */ - String short_src; /* (S) */ - CallFrame cf; /* active function */ - - public void funcinfo(LuaFunction f) { - if (f.isclosure()) { - Prototype p = f.checkclosure().p; - this.source = p.source != null ? p.source.tojstring() : "=?"; - this.linedefined = p.linedefined; - this.lastlinedefined = p.lastlinedefined; - this.what = (this.linedefined == 0) ? "main" : "Lua"; - this.short_src = p.shortsource(); - } else { - this.source = "=[Java]"; - this.linedefined = -1; - this.lastlinedefined = -1; - this.what = "Java"; - this.short_src = f.name(); - } - } - } - - public static class CallStack { - final static CallFrame[] EMPTY = {}; - CallFrame[] frame = EMPTY; - int calls = 0; - - CallStack() {} - - synchronized int currentline() { - return calls > 0? frame[calls-1].currentline(): -1; - } - - private synchronized CallFrame pushcall() { - if (calls >= frame.length) { - int n = Math.max(4, frame.length * 3 / 2); - CallFrame[] f = new CallFrame[n]; - System.arraycopy(frame, 0, f, 0, frame.length); - for (int i = frame.length; i < n; ++i) - f[i] = new CallFrame(); - frame = f; - for (int i = 1; i < n; ++i) - f[i].previous = f[i-1]; - } - return frame[calls++]; - } - - final synchronized void onCall(LuaFunction function) { - pushcall().set(function); - } - - final synchronized void onCall(LuaClosure function, Varargs varargs, LuaValue[] stack) { - pushcall().set(function, varargs, stack); - } - - final synchronized void onReturn() { - if (calls > 0) - frame[--calls].reset(); - } - - final synchronized void onInstruction(int pc, Varargs v, int top) { - if (calls > 0) - frame[calls-1].instr(pc, v, top); - } - - /** - * Get the traceback starting at a specific level. - * @param level - * @return String containing the traceback. - */ - synchronized String traceback(int level) { - StringBuffer sb = new StringBuffer(); - sb.append( "stack traceback:" ); - for (DebugLib.CallFrame c; (c = getCallFrame(level++)) != null; ) { - sb.append("\n\t"); - sb.append( c.shortsource() ); - sb.append( ':' ); - if (c.currentline() > 0) - sb.append( c.currentline()+":" ); - sb.append( " in " ); - DebugInfo ar = auxgetinfo("n", c.f, c); - if (c.linedefined() == 0) - sb.append("main chunk"); - else if ( ar.name != null ) { - sb.append( "function '" ); - sb.append( ar.name ); - sb.append( '\'' ); - } else { - sb.append( "function <" ); - sb.append( c.shortsource() ); - sb.append( ':' ); - sb.append( c.linedefined() ); - sb.append( '>' ); - } - } - sb.append("\n\t[Java]: in ?"); - return sb.toString(); - } - - synchronized DebugLib.CallFrame getCallFrame(int level) { - if (level < 1 || level > calls) - return null; - return frame[calls-level]; - } - - synchronized DebugLib.CallFrame findCallFrame(LuaValue func) { - for (int i = 1; i <= calls; ++i) - if (frame[calls-i].f == func) - return frame[i]; - return null; - } - - - synchronized DebugInfo auxgetinfo(String what, LuaFunction f, CallFrame ci) { - DebugInfo ar = new DebugInfo(); - for (int i = 0, n = what.length(); i < n; ++i) { - switch (what.charAt(i)) { - case 'S': - ar.funcinfo(f); - break; - case 'l': - ar.currentline = ci != null && ci.f.isclosure()? ci.currentline(): -1; - break; - case 'u': - if (f != null && f.isclosure()) { - Prototype p = f.checkclosure().p; - ar.nups = (short) p.upvalues.length; - ar.nparams = (short) p.numparams; - ar.isvararg = p.is_vararg != 0; - } else { - ar.nups = 0; - ar.isvararg = true; - ar.nparams = 0; - } - break; - case 't': - ar.istailcall = false; - break; - case 'n': { - /* calling function is a known Lua function? */ - if (ci != null && ci.previous != null) { - if (ci.previous.f.isclosure()) { - NameWhat nw = getfuncname(ci.previous); - if (nw != null) { - ar.name = nw.name; - ar.namewhat = nw.namewhat; - } - } - } - if (ar.namewhat == null) { - ar.namewhat = ""; /* not found */ - ar.name = null; - } - break; - } - case 'L': - case 'f': - break; - default: - // TODO: return bad status. - break; - } - } - return ar; - } - - } - - public static class CallFrame { - LuaFunction f; - int pc; - int top; - Varargs v; - LuaValue[] stack; - CallFrame previous; - void set(LuaClosure function, Varargs varargs, LuaValue[] stack) { - this.f = function; - this.v = varargs; - this.stack = stack; - } - public String shortsource() { - return f.isclosure()? f.checkclosure().p.shortsource(): "[Java]"; - } - void set(LuaFunction function) { - this.f = function; - } - void reset() { - this.f = null; - this.v = null; - this.stack = null; - } - void instr(int pc, Varargs v, int top) { - this.pc = pc; - this.v = v; - this.top = top; - if (TRACE) - Print.printState(f.checkclosure(), pc, stack, top, v); - } - Varargs getLocal(int i) { - LuaString name = getlocalname(i); - if ( i >= 1 && i <= stack.length && stack[i-1] != null ) - return varargsOf( name == null ? NIL : name, stack[i-1] ); - else - return NIL; - } - Varargs setLocal(int i, LuaValue value) { - LuaString name = getlocalname(i); - if ( i >= 1 && i <= stack.length && stack[i-1] != null ) { - stack[i-1] = value; - return name == null ? NIL : name; - } else { - return NIL; - } - } - public int currentline() { - if ( !f.isclosure() ) return -1; - int[] li = f.checkclosure().p.lineinfo; - return li==null || pc<0 || pc>=li.length? -1: li[pc]; - } - String sourceline() { - if ( !f.isclosure() ) return f.tojstring(); - return f.checkclosure().p.shortsource() + ":" + currentline(); - } - int linedefined() { - return f.isclosure()? f.checkclosure().p.linedefined: -1; - } - LuaString getlocalname(int index) { - if ( !f.isclosure() ) return null; - return f.checkclosure().p.getlocalname(index, pc); - } - } - - static LuaString findupvalue(LuaClosure c, int up) { - if ( c.upValues != null && up > 0 && up <= c.upValues.length ) { - if ( c.p.upvalues != null && up <= c.p.upvalues.length ) - return c.p.upvalues[up-1].name; - else - return LuaString.valueOf( "."+up ); - } - return null; - } - - static void lua_assert(boolean x) { - if (!x) throw new RuntimeException("lua_assert failed"); - } - - static class NameWhat { - final String name; - final String namewhat; - NameWhat(String name, String namewhat) { - this.name = name; - this.namewhat = namewhat; - } - } - - // Return the name info if found, or null if no useful information could be found. - static NameWhat getfuncname(DebugLib.CallFrame frame) { - if (!frame.f.isclosure()) - return new NameWhat(frame.f.classnamestub(), "Java"); - Prototype p = frame.f.checkclosure().p; - int pc = frame.pc; - int i = p.code[pc]; /* calling instruction */ - LuaString tm; - switch (Lua.GET_OPCODE(i)) { - case Lua.OP_CALL: - case Lua.OP_TAILCALL: /* get function name */ - return getobjname(p, pc, Lua.GETARG_A(i)); - case Lua.OP_TFORCALL: /* for iterator */ - return new NameWhat("(for iterator)", "(for iterator"); - /* all other instructions can call only through metamethods */ - case Lua.OP_SELF: - case Lua.OP_GETTABUP: - case Lua.OP_GETTABLE: tm = LuaValue.INDEX; break; - case Lua.OP_SETTABUP: - case Lua.OP_SETTABLE: tm = LuaValue.NEWINDEX; break; - case Lua.OP_EQ: tm = LuaValue.EQ; break; - case Lua.OP_ADD: tm = LuaValue.ADD; break; - case Lua.OP_SUB: tm = LuaValue.SUB; break; - case Lua.OP_MUL: tm = LuaValue.MUL; break; - case Lua.OP_DIV: tm = LuaValue.DIV; break; - case Lua.OP_MOD: tm = LuaValue.MOD; break; - case Lua.OP_POW: tm = LuaValue.POW; break; - case Lua.OP_UNM: tm = LuaValue.UNM; break; - case Lua.OP_LEN: tm = LuaValue.LEN; break; - case Lua.OP_LT: tm = LuaValue.LT; break; - case Lua.OP_LE: tm = LuaValue.LE; break; - case Lua.OP_CONCAT: tm = LuaValue.CONCAT; break; - default: - return null; /* else no useful name can be found */ - } - return new NameWhat( tm.tojstring(), "metamethod" ); - } - - // return NameWhat if found, null if not - public static NameWhat getobjname(Prototype p, int lastpc, int reg) { - int pc = lastpc; // currentpc(L, ci); - LuaString name = p.getlocalname(reg + 1, pc); - if (name != null) /* is a local? */ - return new NameWhat( name.tojstring(), "local" ); - - /* else try symbolic execution */ - pc = findsetreg(p, lastpc, reg); - if (pc != -1) { /* could find instruction? */ - int i = p.code[pc]; - switch (Lua.GET_OPCODE(i)) { - case Lua.OP_MOVE: { - int a = Lua.GETARG_A(i); - int b = Lua.GETARG_B(i); /* move from `b' to `a' */ - if (b < a) - return getobjname(p, pc, b); /* get name for `b' */ - break; - } - case Lua.OP_GETTABUP: - case Lua.OP_GETTABLE: { - int k = Lua.GETARG_C(i); /* key index */ - int t = Lua.GETARG_B(i); /* table index */ - LuaString vn = (Lua.GET_OPCODE(i) == Lua.OP_GETTABLE) /* name of indexed variable */ - ? p.getlocalname(t + 1, pc) - : (t < p.upvalues.length ? p.upvalues[t].name : QMARK); - String jname = kname(p, pc, k); - return new NameWhat( jname, vn != null && vn.eq_b(ENV)? "global": "field" ); - } - case Lua.OP_GETUPVAL: { - int u = Lua.GETARG_B(i); /* upvalue index */ - name = u < p.upvalues.length ? p.upvalues[u].name : QMARK; - return name == null ? null : new NameWhat( name.tojstring(), "upvalue" ); - } - case Lua.OP_LOADK: - case Lua.OP_LOADKX: { - int b = (Lua.GET_OPCODE(i) == Lua.OP_LOADK) ? Lua.GETARG_Bx(i) - : Lua.GETARG_Ax(p.code[pc + 1]); - if (p.k[b].isstring()) { - name = p.k[b].strvalue(); - return new NameWhat( name.tojstring(), "constant" ); - } - break; - } - case Lua.OP_SELF: { - int k = Lua.GETARG_C(i); /* key index */ - String jname = kname(p, pc, k); - return new NameWhat( jname, "method" ); - } - default: - break; - } - } - return null; /* no useful name found */ - } - - static String kname(Prototype p, int pc, int c) { - if (Lua.ISK(c)) { /* is 'c' a constant? */ - LuaValue k = p.k[Lua.INDEXK(c)]; - if (k.isstring()) { /* literal constant? */ - return k.tojstring(); /* it is its own name */ - } /* else no reasonable name found */ - } else { /* 'c' is a register */ - NameWhat what = getobjname(p, pc, c); /* search for 'c' */ - if (what != null && "constant".equals(what.namewhat)) { /* found a constant name? */ - return what.name; /* 'name' already filled */ - } - /* else no reasonable name found */ - } - return "?"; /* no reasonable name found */ - } - - /* - ** try to find last instruction before 'lastpc' that modified register 'reg' - */ - static int findsetreg (Prototype p, int lastpc, int reg) { - int pc; - int setreg = -1; /* keep last instruction that changed 'reg' */ - for (pc = 0; pc < lastpc; pc++) { - int i = p.code[pc]; - int op = Lua.GET_OPCODE(i); - int a = Lua.GETARG_A(i); - switch (op) { - case Lua.OP_LOADNIL: { - int b = Lua.GETARG_B(i); - if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */ - setreg = pc; - break; - } - case Lua.OP_TFORCALL: { - if (reg >= a + 2) setreg = pc; /* affect all regs above its base */ - break; - } - case Lua.OP_CALL: - case Lua.OP_TAILCALL: { - if (reg >= a) setreg = pc; /* affect all registers above base */ - break; - } - case Lua.OP_JMP: { - int b = Lua.GETARG_sBx(i); - int dest = pc + 1 + b; - /* jump is forward and do not skip `lastpc'? */ - if (pc < dest && dest <= lastpc) - pc += b; /* do the jump */ - break; - } - case Lua.OP_TEST: { - if (reg == a) setreg = pc; /* jumped code can change 'a' */ - break; - } - case Lua.OP_SETLIST: { // Lua.testAMode(Lua.OP_SETLIST) == false - if ( ((i>>14)&0x1ff) == 0 ) pc++; // if c == 0 then c stored in next op -> skip - break; - } - default: - if (Lua.testAMode(op) && reg == a) /* any instruction that set A */ - setreg = pc; - break; - } - } - return setreg; - } -} diff --git a/src/core/org/luaj/vm2/lib/IoLib.java b/src/core/org/luaj/vm2/lib/IoLib.java deleted file mode 100644 index 13f6f986..00000000 --- a/src/core/org/luaj/vm2/lib/IoLib.java +++ /dev/null @@ -1,684 +0,0 @@ -/******************************************************************************* -* 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.lib; - -import java.io.ByteArrayOutputStream; -import java.io.EOFException; -import java.io.IOException; - -import org.luaj.vm2.Globals; -import org.luaj.vm2.LuaString; -import org.luaj.vm2.LuaTable; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Varargs; - -/** - * Abstract base class extending {@link LibFunction} which implements the - * core of the lua standard {@code io} library. - *

    - * It contains the implementation of the io library support that is common to - * the JSE and JME platforms. - * In practice on of the concrete IOLib subclasses is chosen: - * {@link org.luaj.vm2.lib.jse.JseIoLib} for the JSE platform, and - * {@link org.luaj.vm2.lib.jme.JmeIoLib} for the JME platform. - *

    - * The JSE implementation conforms almost completely to the C-based lua library, - * while the JME implementation follows closely except in the area of random-access files, - * which are difficult to support properly on JME. - *

    - * Typically, this library is included as part of a call to either - * {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} or {@link org.luaj.vm2.lib.jme.JmePlatform#standardGlobals()} - *

     {@code
    - * Globals globals = JsePlatform.standardGlobals();
    - * globals.get("io").get("write").call(LuaValue.valueOf("hello, world\n"));
    - * } 
    - * In this example the platform-specific {@link org.luaj.vm2.lib.jse.JseIoLib} library will be loaded, which will include - * the base functionality provided by this class, whereas the {@link org.luaj.vm2.lib.jse.JsePlatform} would load the - * {@link org.luaj.vm2.lib.jse.JseIoLib}. - *

    - * To instantiate and use it directly, - * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as: - *

     {@code
    - * Globals globals = new Globals();
    - * globals.load(new JseBaseLib());
    - * globals.load(new PackageLib());
    - * globals.load(new OsLib());
    - * globals.get("io").get("write").call(LuaValue.valueOf("hello, world\n"));
    - * } 
    - *

    - * This has been implemented to match as closely as possible the behavior in the corresponding library in C. - * @see LibFunction - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - * @see org.luaj.vm2.lib.jse.JseIoLib - * @see org.luaj.vm2.lib.jme.JmeIoLib - * @see http://www.lua.org/manual/5.1/manual.html#5.7 - */ -abstract -public class IoLib extends TwoArgFunction { - - abstract - protected class File extends LuaValue{ - abstract public void write( LuaString string ) throws IOException; - abstract public void flush() throws IOException; - abstract public boolean isstdfile(); - abstract public void close() throws IOException; - abstract public boolean isclosed(); - // returns new position - abstract public int seek(String option, int bytecount) throws IOException; - abstract public void setvbuf(String mode, int size); - // get length remaining to read - abstract public int remaining() throws IOException; - // peek ahead one character - abstract public int peek() throws IOException, EOFException; - // return char if read, -1 if eof, throw IOException on other exception - abstract public int read() throws IOException, EOFException; - // return number of bytes read if positive, false if eof, throw IOException on other exception - abstract public int read(byte[] bytes, int offset, int length) throws IOException; - - public boolean eof() throws IOException { - try { - return peek() < 0; - } catch (EOFException e) { return true; } - } - - // delegate method access to file methods table - public LuaValue get( LuaValue key ) { - return filemethods.get(key); - } - - // essentially a userdata instance - public int type() { - return LuaValue.TUSERDATA; - } - public String typename() { - return "userdata"; - } - - // displays as "file" type - public String tojstring() { - return "file: " + Integer.toHexString(hashCode()); - } - - public void finalize() { - if (!isclosed()) { - try { - close(); - } catch (IOException ignore) {} - } - } - } - - /** Enumerated value representing stdin */ - protected static final int FTYPE_STDIN = 0; - /** Enumerated value representing stdout */ - protected static final int FTYPE_STDOUT = 1; - /** Enumerated value representing stderr */ - protected static final int FTYPE_STDERR = 2; - /** Enumerated value representing a file type for a named file */ - protected static final int FTYPE_NAMED = 3; - - /** - * Wrap the standard input. - * @return File - * @throws IOException - */ - abstract protected File wrapStdin() throws IOException; - - /** - * Wrap the standard output. - * @return File - * @throws IOException - */ - abstract protected File wrapStdout() throws IOException; - - /** - * Wrap the standard error output. - * @return File - * @throws IOException - */ - abstract protected File wrapStderr() throws IOException; - - /** - * Open a file in a particular mode. - * @param filename - * @param readMode true if opening in read mode - * @param appendMode true if opening in append mode - * @param updateMode true if opening in update mode - * @param binaryMode true if opening in binary mode - * @return File object if successful - * @throws IOException if could not be opened - */ - abstract protected File openFile( String filename, boolean readMode, boolean appendMode, boolean updateMode, boolean binaryMode ) throws IOException; - - /** - * Open a temporary file. - * @return File object if successful - * @throws IOException if could not be opened - */ - abstract protected File tmpFile() throws IOException; - - /** - * Start a new process and return a file for input or output - * @param prog the program to execute - * @param mode "r" to read, "w" to write - * @return File to read to or write from - * @throws IOException if an i/o exception occurs - */ - abstract protected File openProgram(String prog, String mode) throws IOException; - - private File infile = null; - private File outfile = null; - private File errfile = null; - - private static final LuaValue STDIN = valueOf("stdin"); - private static final LuaValue STDOUT = valueOf("stdout"); - private static final LuaValue STDERR = valueOf("stderr"); - private static final LuaValue FILE = valueOf("file"); - private static final LuaValue CLOSED_FILE = valueOf("closed file"); - - private static final int IO_CLOSE = 0; - private static final int IO_FLUSH = 1; - private static final int IO_INPUT = 2; - private static final int IO_LINES = 3; - private static final int IO_OPEN = 4; - private static final int IO_OUTPUT = 5; - private static final int IO_POPEN = 6; - private static final int IO_READ = 7; - private static final int IO_TMPFILE = 8; - private static final int IO_TYPE = 9; - private static final int IO_WRITE = 10; - - private static final int FILE_CLOSE = 11; - private static final int FILE_FLUSH = 12; - private static final int FILE_LINES = 13; - private static final int FILE_READ = 14; - private static final int FILE_SEEK = 15; - private static final int FILE_SETVBUF = 16; - private static final int FILE_WRITE = 17; - - private static final int IO_INDEX = 18; - private static final int LINES_ITER = 19; - - public static final String[] IO_NAMES = { - "close", - "flush", - "input", - "lines", - "open", - "output", - "popen", - "read", - "tmpfile", - "type", - "write", - }; - - public static final String[] FILE_NAMES = { - "close", - "flush", - "lines", - "read", - "seek", - "setvbuf", - "write", - }; - - LuaTable filemethods; - - protected Globals globals; - - public LuaValue call(LuaValue modname, LuaValue env) { - globals = env.checkglobals(); - - // io lib functions - LuaTable t = new LuaTable(); - bind(t, IoLibV.class, IO_NAMES ); - - // create file methods table - filemethods = new LuaTable(); - bind(filemethods, IoLibV.class, FILE_NAMES, FILE_CLOSE ); - - // set up file metatable - LuaTable mt = new LuaTable(); - bind(mt, IoLibV.class, new String[] { "__index" }, IO_INDEX ); - t.setmetatable( mt ); - - // all functions link to library instance - setLibInstance( t ); - setLibInstance( filemethods ); - setLibInstance( mt ); - - // return the table - env.set("io", t); - if (!env.get("package").isnil()) env.get("package").get("loaded").set("io", t); - return t; - } - - private void setLibInstance(LuaTable t) { - LuaValue[] k = t.keys(); - for ( int i=0, n=k.length; i bool - public Varargs _io_flush() throws IOException { - checkopen(output()); - outfile.flush(); - return LuaValue.TRUE; - } - - // io.tmpfile() -> file - public Varargs _io_tmpfile() throws IOException { - return tmpFile(); - } - - // io.close([file]) -> void - public Varargs _io_close(LuaValue file) throws IOException { - File f = file.isnil()? output(): checkfile(file); - checkopen(f); - return ioclose(f); - } - - // io.input([file]) -> file - public Varargs _io_input(LuaValue file) { - infile = file.isnil()? input(): - file.isstring()? ioopenfile(FTYPE_NAMED, file.checkjstring(),"r"): - checkfile(file); - return infile; - } - - // io.output(filename) -> file - public Varargs _io_output(LuaValue filename) { - outfile = filename.isnil()? output(): - filename.isstring()? ioopenfile(FTYPE_NAMED, filename.checkjstring(),"w"): - checkfile(filename); - return outfile; - } - - // io.type(obj) -> "file" | "closed file" | nil - public Varargs _io_type(LuaValue obj) { - File f = optfile(obj); - return f!=null? - f.isclosed()? CLOSED_FILE: FILE: - NIL; - } - - // io.popen(prog, [mode]) -> file - public Varargs _io_popen(String prog, String mode) throws IOException { - if (!"r".equals(mode) && !"w".equals(mode)) argerror(2, "invalid value: '" + mode + "'; must be one of 'r' or 'w'"); - return openProgram(prog, mode); - } - - // io.open(filename, [mode]) -> file | nil,err - public Varargs _io_open(String filename, String mode) throws IOException { - return rawopenfile(FTYPE_NAMED, filename, mode); - } - - // io.lines(filename, ...) -> iterator - public Varargs _io_lines(Varargs args) { - String filename = args.optjstring(1, null); - File infile = filename==null? input(): ioopenfile(FTYPE_NAMED, filename,"r"); - checkopen(infile); - return lines(infile, filename != null, args.subargs(2)); - } - - // io.read(...) -> (...) - public Varargs _io_read(Varargs args) throws IOException { - checkopen(input()); - return ioread(infile,args); - } - - // io.write(...) -> void - public Varargs _io_write(Varargs args) throws IOException { - checkopen(output()); - return iowrite(outfile,args); - } - - // file:close() -> void - public Varargs _file_close(LuaValue file) throws IOException { - return ioclose(checkfile(file)); - } - - // file:flush() -> void - public Varargs _file_flush(LuaValue file) throws IOException { - checkfile(file).flush(); - return LuaValue.TRUE; - } - - // file:setvbuf(mode,[size]) -> void - public Varargs _file_setvbuf(LuaValue file, String mode, int size) { - if ("no".equals(mode)) { - } else if ("full".equals(mode)) { - } else if ("line".equals(mode)) { - } else { - argerror(1, "invalid value: '" + mode + "'; must be one of 'no', 'full' or 'line'"); - } - checkfile(file).setvbuf(mode,size); - return LuaValue.TRUE; - } - - // file:lines(...) -> iterator - public Varargs _file_lines(Varargs args) { - return lines(checkfile(args.arg1()), false, args.subargs(2)); - } - - // file:read(...) -> (...) - public Varargs _file_read(LuaValue file, Varargs subargs) throws IOException { - return ioread(checkfile(file),subargs); - } - - // file:seek([whence][,offset]) -> pos | nil,error - public Varargs _file_seek(LuaValue file, String whence, int offset) throws IOException { - if ("set".equals(whence)) { - } else if ("end".equals(whence)) { - } else if ("cur".equals(whence)) { - } else { - argerror(1, "invalid value: '" + whence + "'; must be one of 'set', 'cur' or 'end'"); - } - return valueOf( checkfile(file).seek(whence,offset) ); - } - - // file:write(...) -> void - public Varargs _file_write(LuaValue file, Varargs subargs) throws IOException { - return iowrite(checkfile(file),subargs); - } - - // __index, returns a field - public Varargs _io_index(LuaValue v) { - return v.equals(STDOUT)?output(): - v.equals(STDIN)? input(): - v.equals(STDERR)? errput(): NIL; - } - - // lines iterator(s,var) -> var' - public Varargs _lines_iter(LuaValue file, boolean toclose, Varargs args) throws IOException { - File f = optfile(file); - if ( f == null ) argerror(1, "not a file: " + file); - if ( f.isclosed() ) error("file is already closed"); - Varargs ret = ioread(f, args); - if (toclose && ret.isnil(1) && f.eof()) f.close(); - return ret; - } - - private File output() { - return outfile!=null? outfile: (outfile=ioopenfile(FTYPE_STDOUT,"-","w")); - } - - private File errput() { - return errfile!=null? errfile: (errfile=ioopenfile(FTYPE_STDERR,"-","w")); - } - - private File ioopenfile(int filetype, String filename, String mode) { - try { - return rawopenfile(filetype, filename, mode); - } catch ( Exception e ) { - error("io error: "+e.getMessage()); - return null; - } - } - - private static Varargs ioclose(File f) throws IOException { - if ( f.isstdfile() ) - return errorresult("cannot close standard file"); - else { - f.close(); - return successresult(); - } - } - - private static Varargs successresult() { - return LuaValue.TRUE; - } - - static Varargs errorresult(Exception ioe) { - String s = ioe.getMessage(); - return errorresult("io error: "+(s!=null? s: ioe.toString())); - } - - private static Varargs errorresult(String errortext) { - return varargsOf(NIL, valueOf(errortext)); - } - - private Varargs lines(final File f, boolean toclose, Varargs args) { - try { - return new IoLibV(f,"lnext",LINES_ITER,this,toclose,args); - } catch ( Exception e ) { - return error("lines: "+e); - } - } - - private static Varargs iowrite(File f, Varargs args) throws IOException { - for ( int i=1, n=args.narg(); i<=n; i++ ) - f.write( args.checkstring(i) ); - return f; - } - - private Varargs ioread(File f, Varargs args) throws IOException { - int i,n=args.narg(); - if (n == 0) return freadline(f,false); - LuaValue[] v = new LuaValue[n]; - LuaValue ai,vi; - LuaString fmt; - for ( i=0; i= 2 && fmt.m_bytes[fmt.m_offset] == '*' ) { - switch ( fmt.m_bytes[fmt.m_offset+1] ) { - case 'n': vi = freadnumber(f); break item; - case 'l': vi = freadline(f,false); break item; - case 'L': vi = freadline(f,true); break item; - case 'a': vi = freadall(f); break item; - } - } - default: - return argerror( i+1, "(invalid format)" ); - } - if ( (v[i++] = vi).isnil() ) - break; - } - return i==0? NIL: varargsOf(v, 0, i); - } - - private static File checkfile(LuaValue val) { - File f = optfile(val); - if ( f == null ) - argerror(1,"file"); - checkopen( f ); - return f; - } - - private static File optfile(LuaValue val) { - return (val instanceof File)? (File) val: null; - } - - private static File checkopen(File file) { - if ( file.isclosed() ) - error("attempt to use a closed file"); - return file; - } - - private File rawopenfile(int filetype, String filename, String mode) throws IOException { - int len = mode.length(); - for (int i = 0; i < len; i++) { // [rwa][+]?b* - char ch = mode.charAt(i); - if (i == 0 && "rwa".indexOf(ch) >= 0) continue; - if (i == 1 && ch == '+') continue; - if (i >= 1 && ch == 'b') continue; - len = -1; - break; - } - if (len <= 0) argerror(2, "invalid mode: '" + mode + "'"); - - switch (filetype) { - case FTYPE_STDIN: return wrapStdin(); - case FTYPE_STDOUT: return wrapStdout(); - case FTYPE_STDERR: return wrapStderr(); - } - boolean isreadmode = mode.startsWith("r"); - boolean isappend = mode.startsWith("a"); - boolean isupdate = mode.indexOf('+') > 0; - boolean isbinary = mode.endsWith("b"); - return openFile( filename, isreadmode, isappend, isupdate, isbinary ); - } - - - // ------------- file reading utilitied ------------------ - - public static LuaValue freadbytes(File f, int count) throws IOException { - if (count == 0) return f.eof() ? NIL : EMPTYSTRING; - byte[] b = new byte[count]; - int r; - if ( ( r = f.read(b,0,b.length) ) < 0 ) - return NIL; - return LuaString.valueUsing(b, 0, r); - } - public static LuaValue freaduntil(File f,boolean lineonly,boolean withend) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - int c; - try { - if ( lineonly ) { - loop: while ( (c = f.read()) >= 0 ) { - switch ( c ) { - case '\r': if (withend) baos.write(c); break; - case '\n': if (withend) baos.write(c); break loop; - default: baos.write(c); break; - } - } - } else { - while ( (c = f.read()) >= 0 ) - baos.write(c); - } - } catch ( EOFException e ) { - c = -1; - } - return ( c < 0 && baos.size() == 0 )? - (LuaValue) NIL: - (LuaValue) LuaString.valueUsing(baos.toByteArray()); - } - public static LuaValue freadline(File f,boolean withend) throws IOException { - return freaduntil(f,true,withend); - } - public static LuaValue freadall(File f) throws IOException { - int n = f.remaining(); - if ( n >= 0 ) { - return n == 0 ? EMPTYSTRING : freadbytes(f, n); - } else { - return freaduntil(f,false,false); - } - } - public static LuaValue freadnumber(File f) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - freadchars(f," \t\r\n",null); - freadchars(f,"-+",baos); - //freadchars(f,"0",baos); - //freadchars(f,"xX",baos); - freadchars(f,"0123456789",baos); - freadchars(f,".",baos); - freadchars(f,"0123456789",baos); - //freadchars(f,"eEfFgG",baos); - // freadchars(f,"+-",baos); - //freadchars(f,"0123456789",baos); - String s = baos.toString(); - return s.length()>0? valueOf( Double.parseDouble(s) ): NIL; - } - private static void freadchars(File f, String chars, ByteArrayOutputStream baos) throws IOException { - int c; - while ( true ) { - c = f.peek(); - if ( chars.indexOf(c) < 0 ) { - return; - } - f.read(); - if ( baos != null ) - baos.write( c ); - } - } - - - -} diff --git a/src/core/org/luaj/vm2/lib/LibFunction.java b/src/core/org/luaj/vm2/lib/LibFunction.java deleted file mode 100644 index eba56072..00000000 --- a/src/core/org/luaj/vm2/lib/LibFunction.java +++ /dev/null @@ -1,222 +0,0 @@ -/******************************************************************************* -* 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.lib; - -import org.luaj.vm2.LuaError; -import org.luaj.vm2.LuaFunction; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Varargs; - -/** - * Subclass of {@link LuaFunction} common to Java functions exposed to lua. - *

    - * To provide for common implementations in JME and JSE, - * library functions are typically grouped on one or more library classes - * and an opcode per library function is defined and used to key the switch - * to the correct function within the library. - *

    - * Since lua functions can be called with too few or too many arguments, - * and there are overloaded {@link LuaValue#call()} functions with varying - * number of arguments, a Java function exposed in lua needs to handle the - * argument fixup when a function is called with a number of arguments - * differs from that expected. - *

    - * To simplify the creation of library functions, - * there are 5 direct subclasses to handle common cases based on number of - * argument values and number of return return values. - *

    - *

    - * To be a Java library that can be loaded via {@code require}, it should have - * a public constructor that returns a {@link LuaValue} that, when executed, - * initializes the library. - *

    - * For example, the following code will implement a library called "hyperbolic" - * with two functions, "sinh", and "cosh": -

     {@code
    - * import org.luaj.vm2.LuaValue;
    - * import org.luaj.vm2.lib.*;
    - * 
    - * public class hyperbolic extends TwoArgFunction {
    - *
    - *	public hyperbolic() {}
    - *
    - *	public LuaValue call(LuaValue modname, LuaValue env) {
    - *		LuaValue library = tableOf();
    - *		library.set( "sinh", new sinh() );
    - *		library.set( "cosh", new cosh() );
    - *		env.set( "hyperbolic", library );
    - *		return library;
    - *	}
    - *
    - *	static class sinh extends OneArgFunction {
    - *		public LuaValue call(LuaValue x) {
    - *			return LuaValue.valueOf(Math.sinh(x.checkdouble()));
    - *		}
    - *	}
    - *	
    - *	static class cosh extends OneArgFunction {
    - *		public LuaValue call(LuaValue x) {
    - *			return LuaValue.valueOf(Math.cosh(x.checkdouble()));
    - *		}
    - *	}
    - *}
    - *}
    - * The default constructor is used to instantiate the library - * in response to {@code require 'hyperbolic'} statement, - * provided it is on Java"s class path. - * This instance is then invoked with 2 arguments: the name supplied to require(), - * and the environment for this function. The library may ignore these, or use - * them to leave side effects in the global environment, for example. - * In the previous example, two functions are created, 'sinh', and 'cosh', and placed - * into a global table called 'hyperbolic' using the supplied 'env' argument. - *

    - * To test it, a script such as this can be used: - *

     {@code
    - * local t = require('hyperbolic')
    - * print( 't', t )
    - * print( 'hyperbolic', hyperbolic )
    - * for k,v in pairs(t) do
    - * 	print( 'k,v', k,v )
    - * end
    - * print( 'sinh(.5)', hyperbolic.sinh(.5) )
    - * print( 'cosh(.5)', hyperbolic.cosh(.5) )
    - * }
    - *

    - * It should produce something like: - *

     {@code
    - * t	table: 3dbbd23f
    - * hyperbolic	table: 3dbbd23f
    - * k,v	cosh	function: 3dbbd128
    - * k,v	sinh	function: 3dbbd242
    - * sinh(.5)	0.5210953
    - * cosh(.5)	1.127626
    - * }
    - *

    - * See the source code in any of the library functions - * such as {@link BaseLib} or {@link TableLib} for other examples. - */ -abstract public class LibFunction extends LuaFunction { - - /** User-defined opcode to differentiate between instances of the library function class. - *

    - * Subclass will typicall switch on this value to provide the specific behavior for each function. - */ - protected int opcode; - - /** The common name for this function, useful for debugging. - *

    - * Binding functions initialize this to the name to which it is bound. - */ - protected String name; - - /** Default constructor for use by subclasses */ - protected LibFunction() { - } - - public String tojstring() { - return name != null ? "function: " + name : super.tojstring(); - } - - /** - * Bind a set of library functions. - *

    - * An array of names is provided, and the first name is bound - * with opcode = 0, second with 1, etc. - * @param env The environment to apply to each bound function - * @param factory the Class to instantiate for each bound function - * @param names array of String names, one for each function. - * @see #bind(LuaValue, Class, String[], int) - */ - protected void bind(LuaValue env, Class factory, String[] names ) { - bind( env, factory, names, 0 ); - } - - /** - * Bind a set of library functions, with an offset - *

    - * An array of names is provided, and the first name is bound - * with opcode = {@code firstopcode}, second with {@code firstopcode+1}, etc. - * @param env The environment to apply to each bound function - * @param factory the Class to instantiate for each bound function - * @param names array of String names, one for each function. - * @param firstopcode the first opcode to use - * @see #bind(LuaValue, Class, String[]) - */ - protected void bind(LuaValue env, Class factory, String[] names, int firstopcode ) { - try { - for ( int i=0, n=names.length; i - * It contains only the math library support that is possible on JME. - * For a more complete implementation based on math functions specific to JSE - * use {@link org.luaj.vm2.lib.jse.JseMathLib}. - * In Particular the following math functions are not implemented by this library: - *

    - *

    - * The implementations of {@code exp()} and {@code pow()} are constructed by - * hand for JME, so will be slower and less accurate than when executed on the JSE platform. - *

    - * Typically, this library is included as part of a call to either - * {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} or - * {@link org.luaj.vm2.lib.jme.JmePlatform#standardGlobals()} - *

     {@code
    - * Globals globals = JsePlatform.standardGlobals();
    - * System.out.println( globals.get("math").get("sqrt").call( LuaValue.valueOf(2) ) );
    - * } 
    - * When using {@link org.luaj.vm2.lib.jse.JsePlatform} as in this example, - * the subclass {@link org.luaj.vm2.lib.jse.JseMathLib} will - * be included, which also includes this base functionality. - *

    - * To instantiate and use it directly, - * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as: - *

     {@code
    - * Globals globals = new Globals();
    - * globals.load(new JseBaseLib());
    - * globals.load(new PackageLib());
    - * globals.load(new MathLib());
    - * System.out.println( globals.get("math").get("sqrt").call( LuaValue.valueOf(2) ) );
    - * } 
    - * Doing so will ensure the library is properly initialized - * and loaded into the globals table. - *

    - * This has been implemented to match as closely as possible the behavior in the corresponding library in C. - * @see LibFunction - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - * @see org.luaj.vm2.lib.jse.JseMathLib - * @see Lua 5.2 Math Lib Reference - */ -public class MathLib extends TwoArgFunction { - - /** Pointer to the latest MathLib instance, used only to dispatch - * math.exp to tha correct platform math library. - */ - public static MathLib MATHLIB = null; - - /** Construct a MathLib, which can be initialized by calling it with a - * modname string, and a global environment table as arguments using - * {@link #call(LuaValue, LuaValue)}. */ - public MathLib() { - MATHLIB = this; - } - - /** Perform one-time initialization on the library by creating a table - * containing the library functions, adding that table to the supplied environment, - * adding the table to package.loaded, and returning table as the return value. - * @param modname the module name supplied if this is loaded via 'require'. - * @param env the environment to load into, typically a Globals instance. - */ - public LuaValue call(LuaValue modname, LuaValue env) { - LuaTable math = new LuaTable(0,30); - math.set("abs", new abs()); - math.set("ceil", new ceil()); - math.set("cos", new cos()); - math.set("deg", new deg()); - math.set("exp", new exp(this)); - math.set("floor", new floor()); - math.set("fmod", new fmod()); - math.set("frexp", new frexp()); - math.set("huge", LuaDouble.POSINF ); - math.set("ldexp", new ldexp()); - math.set("max", new max()); - math.set("min", new min()); - math.set("modf", new modf()); - math.set("pi", Math.PI ); - math.set("pow", new pow()); - random r; - math.set("random", r = new random()); - math.set("randomseed", new randomseed(r)); - math.set("rad", new rad()); - math.set("sin", new sin()); - math.set("sqrt", new sqrt()); - math.set("tan", new tan()); - env.set("math", math); - if (!env.get("package").isnil()) env.get("package").get("loaded").set("math", math); - return math; - } - - abstract protected static class UnaryOp extends OneArgFunction { - public LuaValue call(LuaValue arg) { - return valueOf(call(arg.checkdouble())); - } - abstract protected double call(double d); - } - - abstract protected static class BinaryOp extends TwoArgFunction { - public LuaValue call(LuaValue x, LuaValue y) { - return valueOf(call(x.checkdouble(), y.checkdouble())); - } - abstract protected double call(double x, double y); - } - - static final class abs extends UnaryOp { protected double call(double d) { return Math.abs(d); } } - static final class ceil extends UnaryOp { protected double call(double d) { return Math.ceil(d); } } - static final class cos extends UnaryOp { protected double call(double d) { return Math.cos(d); } } - static final class deg extends UnaryOp { protected double call(double d) { return Math.toDegrees(d); } } - static final class floor extends UnaryOp { protected double call(double d) { return Math.floor(d); } } - static final class rad extends UnaryOp { protected double call(double d) { return Math.toRadians(d); } } - static final class sin extends UnaryOp { protected double call(double d) { return Math.sin(d); } } - static final class sqrt extends UnaryOp { protected double call(double d) { return Math.sqrt(d); } } - static final class tan extends UnaryOp { protected double call(double d) { return Math.tan(d); } } - - static final class exp extends UnaryOp { - final MathLib mathlib; - exp(MathLib mathlib) { - this.mathlib = mathlib; - } - protected double call(double d) { - return mathlib.dpow_lib(Math.E,d); - } - } - - static final class fmod extends TwoArgFunction { - public LuaValue call(LuaValue xv, LuaValue yv) { - if (xv.islong() && yv.islong()) { - return valueOf(xv.tolong() % yv.tolong()); - } - return valueOf(xv.checkdouble() % yv.checkdouble()); - } - } - static final class ldexp extends BinaryOp { - protected double call(double x, double y) { - // This is the behavior on os-x, windows differs in rounding behavior. - return x * Double.longBitsToDouble((((long) y) + 1023) << 52); - } - } - static final class pow extends BinaryOp { - protected double call(double x, double y) { - return MathLib.dpow_default(x, y); - } - } - - static class frexp extends VarArgFunction { - public Varargs invoke(Varargs args) { - double x = args.checkdouble(1); - if ( x == 0 ) return varargsOf(ZERO,ZERO); - long bits = Double.doubleToLongBits( x ); - double m = ((bits & (~(-1L<<52))) + (1L<<52)) * ((bits >= 0)? (.5 / (1L<<52)): (-.5 / (1L<<52))); - double e = (((int) (bits >> 52)) & 0x7ff) - 1022; - return varargsOf( valueOf(m), valueOf(e) ); - } - } - - static class max extends VarArgFunction { - public Varargs invoke(Varargs args) { - LuaValue m = args.checkvalue(1); - for ( int i=2,n=args.narg(); i<=n; ++i ) { - LuaValue v = args.checkvalue(i); - if (m.lt_b(v)) m = v; - } - return m; - } - } - - static class min extends VarArgFunction { - public Varargs invoke(Varargs args) { - LuaValue m = args.checkvalue(1); - for ( int i=2,n=args.narg(); i<=n; ++i ) { - LuaValue v = args.checkvalue(i); - if (v.lt_b(m)) m = v; - } - return m; - } - } - - static class modf extends VarArgFunction { - public Varargs invoke(Varargs args) { - LuaValue n = args.arg1(); - /* number is its own integer part, no fractional part */ - if (n.islong()) return varargsOf(n, valueOf(0.0)); - double x = n.checkdouble(); - /* integer part (rounds toward zero) */ - double intPart = ( x > 0 ) ? Math.floor( x ) : Math.ceil( x ); - /* fractional part (test needed for inf/-inf) */ - double fracPart = x == intPart ? 0.0 : x - intPart; - return varargsOf( valueOf(intPart), valueOf(fracPart) ); - } - } - - static class random extends LibFunction { - Random random = new Random(); - public LuaValue call() { - return valueOf( random.nextDouble() ); - } - public LuaValue call(LuaValue a) { - int m = a.checkint(); - if (m<1) argerror(1, "interval is empty"); - return valueOf( 1 + random.nextInt(m) ); - } - public LuaValue call(LuaValue a, LuaValue b) { - int m = a.checkint(); - int n = b.checkint(); - if (n 0; whole>>=1, v*=v ) - if ( (whole & 1) != 0 ) - p *= v; - if ( (b -= whole) > 0 ) { - int frac = (int) (0x10000 * b); - for ( ; (frac&0xffff)!=0; frac<<=1 ) { - a = Math.sqrt(a); - if ( (frac & 0x8000) != 0 ) - p *= a; - } - } - return p; - } - -} diff --git a/src/core/org/luaj/vm2/lib/OneArgFunction.java b/src/core/org/luaj/vm2/lib/OneArgFunction.java deleted file mode 100644 index 3db6a321..00000000 --- a/src/core/org/luaj/vm2/lib/OneArgFunction.java +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* -* 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.lib; - -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Varargs; - -/** Abstract base class for Java function implementations that take one argument and - * return one value. - *

    - * Subclasses need only implement {@link LuaValue#call(LuaValue)} to complete this class, - * simplifying development. - * All other uses of {@link #call()}, {@link #invoke(Varargs)},etc, - * are routed through this method by this class, - * dropping or extending arguments with {@code nil} values as required. - *

    - * If more than one argument are required, or no arguments are required, - * or variable argument or variable return values, - * then use one of the related function - * {@link ZeroArgFunction}, {@link TwoArgFunction}, {@link ThreeArgFunction}, or {@link VarArgFunction}. - *

    - * See {@link LibFunction} for more information on implementation libraries and library functions. - * @see #call(LuaValue) - * @see LibFunction - * @see ZeroArgFunction - * @see TwoArgFunction - * @see ThreeArgFunction - * @see VarArgFunction - */ -abstract public class OneArgFunction extends LibFunction { - - abstract public LuaValue call(LuaValue arg); - - /** Default constructor */ - public OneArgFunction() { - } - - public final LuaValue call() { - return call(NIL); - } - - public final LuaValue call(LuaValue arg1, LuaValue arg2) { - return call(arg1); - } - - public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) { - return call(arg1); - } - - public Varargs invoke(Varargs varargs) { - return call(varargs.arg1()); - } -} diff --git a/src/core/org/luaj/vm2/lib/OsLib.java b/src/core/org/luaj/vm2/lib/OsLib.java deleted file mode 100644 index 85b8677e..00000000 --- a/src/core/org/luaj/vm2/lib/OsLib.java +++ /dev/null @@ -1,524 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2009 Luaj.org. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm2.lib; - -import java.io.IOException; -import java.util.Calendar; -import java.util.Date; - -import org.luaj.vm2.Buffer; -import org.luaj.vm2.Globals; -import org.luaj.vm2.LuaTable; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Varargs; - -/** - * Subclass of {@link LibFunction} which implements the standard lua {@code os} library. - *

    - * It is a usable base with simplified stub functions - * for library functions that cannot be implemented uniformly - * on Jse and Jme. - *

    - * This can be installed as-is on either platform, or extended - * and refined to be used in a complete Jse implementation. - *

    - * Because the nature of the {@code os} library is to encapsulate - * os-specific features, the behavior of these functions varies considerably - * from their counterparts in the C platform. - *

    - * The following functions have limited implementations of features - * that are not supported well on Jme: - *

    - *

    - * Typically, this library is included as part of a call to either - * {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} or {@link org.luaj.vm2.lib.jme.JmePlatform#standardGlobals()} - *

     {@code
    - * Globals globals = JsePlatform.standardGlobals();
    - * System.out.println( globals.get("os").get("time").call() );
    - * } 
    - * In this example the platform-specific {@link org.luaj.vm2.lib.jse.JseOsLib} library will be loaded, which will include - * the base functionality provided by this class. - *

    - * To instantiate and use it directly, - * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as: - *

     {@code
    - * Globals globals = new Globals();
    - * globals.load(new JseBaseLib());
    - * globals.load(new PackageLib());
    - * globals.load(new OsLib());
    - * System.out.println( globals.get("os").get("time").call() );
    - * } 
    - *

    - * @see LibFunction - * @see org.luaj.vm2.lib.jse.JseOsLib - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - * @see http://www.lua.org/manual/5.1/manual.html#5.8 - */ -public class OsLib extends TwoArgFunction { - public static final String TMP_PREFIX = ".luaj"; - public static final String TMP_SUFFIX = "tmp"; - - private static final int CLOCK = 0; - private static final int DATE = 1; - private static final int DIFFTIME = 2; - private static final int EXECUTE = 3; - private static final int EXIT = 4; - private static final int GETENV = 5; - private static final int REMOVE = 6; - private static final int RENAME = 7; - private static final int SETLOCALE = 8; - private static final int TIME = 9; - private static final int TMPNAME = 10; - - private static final String[] NAMES = { - "clock", - "date", - "difftime", - "execute", - "exit", - "getenv", - "remove", - "rename", - "setlocale", - "time", - "tmpname", - }; - - private static final long t0 = System.currentTimeMillis(); - private static long tmpnames = t0; - - protected Globals globals; - - /** - * Create and OsLib instance. - */ - public OsLib() { - } - - /** Perform one-time initialization on the library by creating a table - * containing the library functions, adding that table to the supplied environment, - * adding the table to package.loaded, and returning table as the return value. - * @param modname the module name supplied if this is loaded via 'require'. - * @param env the environment to load into, typically a Globals instance. - */ - public LuaValue call(LuaValue modname, LuaValue env) { - globals = env.checkglobals(); - LuaTable os = new LuaTable(); - for (int i = 0; i < NAMES.length; ++i) - os.set(NAMES[i], new OsLibFunc(i, NAMES[i])); - env.set("os", os); - if (!env.get("package").isnil()) env.get("package").get("loaded").set("os", os); - return os; - } - - class OsLibFunc extends VarArgFunction { - public OsLibFunc(int opcode, String name) { - this.opcode = opcode; - this.name = name; - } - public Varargs invoke(Varargs args) { - try { - switch ( opcode ) { - case CLOCK: - return valueOf(clock()); - case DATE: { - String s = args.optjstring(1, "%c"); - double t = args.isnumber(2)? args.todouble(2): time(null); - if (s.equals("*t")) { - Calendar d = Calendar.getInstance(); - d.setTime(new Date((long)(t*1000))); - LuaTable tbl = LuaValue.tableOf(); - tbl.set("year", LuaValue.valueOf(d.get(Calendar.YEAR))); - tbl.set("month", LuaValue.valueOf(d.get(Calendar.MONTH)+1)); - tbl.set("day", LuaValue.valueOf(d.get(Calendar.DAY_OF_MONTH))); - tbl.set("hour", LuaValue.valueOf(d.get(Calendar.HOUR_OF_DAY))); - tbl.set("min", LuaValue.valueOf(d.get(Calendar.MINUTE))); - tbl.set("sec", LuaValue.valueOf(d.get(Calendar.SECOND))); - tbl.set("wday", LuaValue.valueOf(d.get(Calendar.DAY_OF_WEEK))); - tbl.set("yday", LuaValue.valueOf(d.get(0x6))); // Day of year - tbl.set("isdst", LuaValue.valueOf(isDaylightSavingsTime(d))); - return tbl; - } - return valueOf( date(s, t==-1? time(null): t) ); - } - case DIFFTIME: - return valueOf(difftime(args.checkdouble(1),args.checkdouble(2))); - case EXECUTE: - return execute(args.optjstring(1, null)); - case EXIT: - exit(args.optint(1, 0)); - return NONE; - case GETENV: { - final String val = getenv(args.checkjstring(1)); - return val!=null? valueOf(val): NIL; - } - case REMOVE: - remove(args.checkjstring(1)); - return LuaValue.TRUE; - case RENAME: - rename(args.checkjstring(1), args.checkjstring(2)); - return LuaValue.TRUE; - case SETLOCALE: { - String s = setlocale(args.optjstring(1,null), args.optjstring(2, "all")); - return s!=null? valueOf(s): NIL; - } - case TIME: - return valueOf(time(args.opttable(1, null))); - case TMPNAME: - return valueOf(tmpname()); - } - return NONE; - } catch ( IOException e ) { - return varargsOf(NIL, valueOf(e.getMessage())); - } - } - } - - /** - * @return an approximation of the amount in seconds of CPU time used by - * the program. For luaj this simple returns the elapsed time since the - * OsLib class was loaded. - */ - protected double clock() { - return (System.currentTimeMillis()-t0) / 1000.; - } - - /** - * Returns the number of seconds from time t1 to time t2. - * In POSIX, Windows, and some other systems, this value is exactly t2-t1. - * @param t2 - * @param t1 - * @return diffeence in time values, in seconds - */ - protected double difftime(double t2, double t1) { - return t2 - t1; - } - - /** - * If the time argument is present, this is the time to be formatted - * (see the os.time function for a description of this value). - * Otherwise, date formats the current time. - * - * Date returns the date as a string, - * formatted according to the same rules as ANSII strftime, but without - * support for %g, %G, or %V. - * - * When called without arguments, date returns a reasonable date and - * time representation that depends on the host system and on the - * current locale (that is, os.date() is equivalent to os.date("%c")). - * - * @param format - * @param time time since epoch, or -1 if not supplied - * @return a LString or a LTable containing date and time, - * formatted according to the given string format. - */ - public String date(String format, double time) { - Calendar d = Calendar.getInstance(); - d.setTime(new Date((long)(time*1000))); - if (format.startsWith("!")) { - time -= timeZoneOffset(d); - d.setTime(new Date((long)(time*1000))); - format = format.substring(1); - } - byte[] fmt = format.getBytes(); - final int n = fmt.length; - Buffer result = new Buffer(n); - byte c; - for ( int i = 0; i < n; ) { - switch ( c = fmt[i++ ] ) { - case '\n': - result.append( "\n" ); - break; - default: - result.append( c ); - break; - case '%': - if (i >= n) break; - switch ( c = fmt[i++ ] ) { - default: - LuaValue.argerror(1, "invalid conversion specifier '%"+c+"'"); - break; - case '%': - result.append( (byte)'%' ); - break; - case 'a': - result.append(WeekdayNameAbbrev[d.get(Calendar.DAY_OF_WEEK)-1]); - break; - case 'A': - result.append(WeekdayName[d.get(Calendar.DAY_OF_WEEK)-1]); - break; - case 'b': - result.append(MonthNameAbbrev[d.get(Calendar.MONTH)]); - break; - case 'B': - result.append(MonthName[d.get(Calendar.MONTH)]); - break; - case 'c': - result.append(date("%a %b %d %H:%M:%S %Y", time)); - break; - case 'd': - result.append(String.valueOf(100+d.get(Calendar.DAY_OF_MONTH)).substring(1)); - break; - case 'H': - result.append(String.valueOf(100+d.get(Calendar.HOUR_OF_DAY)).substring(1)); - break; - case 'I': - result.append(String.valueOf(100+(d.get(Calendar.HOUR_OF_DAY)%12)).substring(1)); - break; - case 'j': { // day of year. - Calendar y0 = beginningOfYear(d); - int dayOfYear = (int) ((d.getTime().getTime() - y0.getTime().getTime()) / (24 * 3600L * 1000L)); - result.append(String.valueOf(1001+dayOfYear).substring(1)); - break; - } - case 'm': - result.append(String.valueOf(101+d.get(Calendar.MONTH)).substring(1)); - break; - case 'M': - result.append(String.valueOf(100+d.get(Calendar.MINUTE)).substring(1)); - break; - case 'p': - result.append(d.get(Calendar.HOUR_OF_DAY) < 12? "AM": "PM"); - break; - case 'S': - result.append(String.valueOf(100+d.get(Calendar.SECOND)).substring(1)); - break; - case 'U': - result.append(String.valueOf(weekNumber(d, 0))); - break; - case 'w': - result.append(String.valueOf((d.get(Calendar.DAY_OF_WEEK)+6)%7)); - break; - case 'W': - result.append(String.valueOf(weekNumber(d, 1))); - break; - case 'x': - result.append(date("%m/%d/%y", time)); - break; - case 'X': - result.append(date("%H:%M:%S", time)); - break; - case 'y': - result.append(String.valueOf(d.get(Calendar.YEAR)).substring(2)); - break; - case 'Y': - result.append(String.valueOf(d.get(Calendar.YEAR))); - break; - case 'z': { - final int tzo = timeZoneOffset(d) / 60; - final int a = Math.abs(tzo); - final String h = String.valueOf(100 + a / 60).substring(1); - final String m = String.valueOf(100 + a % 60).substring(1); - result.append((tzo>=0? "+": "-") + h + m); - break; - } - } - } - } - return result.tojstring(); - } - - private static final String[] WeekdayNameAbbrev = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; - private static final String[] WeekdayName = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; - private static final String[] MonthNameAbbrev = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - private static final String[] MonthName = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; - - private Calendar beginningOfYear(Calendar d) { - Calendar y0 = Calendar.getInstance(); - y0.setTime(d.getTime()); - y0.set(Calendar.MONTH, 0); - y0.set(Calendar.DAY_OF_MONTH, 1); - y0.set(Calendar.HOUR_OF_DAY, 0); - y0.set(Calendar.MINUTE, 0); - y0.set(Calendar.SECOND, 0); - y0.set(Calendar.MILLISECOND, 0); - return y0; - } - - private int weekNumber(Calendar d, int startDay) { - Calendar y0 = beginningOfYear(d); - y0.set(Calendar.DAY_OF_MONTH, 1 + (startDay + 8 - y0.get(Calendar.DAY_OF_WEEK)) % 7); - if (y0.after(d)) { - y0.set(Calendar.YEAR, y0.get(Calendar.YEAR) - 1); - y0.set(Calendar.DAY_OF_MONTH, 1 + (startDay + 8 - y0.get(Calendar.DAY_OF_WEEK)) % 7); - } - long dt = d.getTime().getTime() - y0.getTime().getTime(); - return 1 + (int) (dt / (7L * 24L * 3600L * 1000L)); - } - - private int timeZoneOffset(Calendar d) { - int localStandarTimeMillis = ( - d.get(Calendar.HOUR_OF_DAY) * 3600 + - d.get(Calendar.MINUTE) * 60 + - d.get(Calendar.SECOND)) * 1000; - return d.getTimeZone().getOffset( - 1, - d.get(Calendar.YEAR), - d.get(Calendar.MONTH), - d.get(Calendar.DAY_OF_MONTH), - d.get(Calendar.DAY_OF_WEEK), - localStandarTimeMillis) / 1000; - } - - private boolean isDaylightSavingsTime(Calendar d) { - return timeZoneOffset(d) != d.getTimeZone().getRawOffset() / 1000; - } - - /** - * This function is equivalent to the C function system. - * It passes command to be executed by an operating system shell. - * It returns a status code, which is system-dependent. - * If command is absent, then it returns nonzero if a shell - * is available and zero otherwise. - * @param command command to pass to the system - */ - protected Varargs execute(String command) { - return varargsOf(NIL, valueOf("exit"), ONE); - } - - /** - * Calls the C function exit, with an optional code, to terminate the host program. - * @param code - */ - protected void exit(int code) { - System.exit(code); - } - - /** - * Returns the value of the process environment variable varname, - * or the System property value for varname, - * or null if the variable is not defined in either environment. - * - * The default implementation, which is used by the JmePlatform, - * only queryies System.getProperty(). - * - * The JsePlatform overrides this behavior and returns the - * environment variable value using System.getenv() if it exists, - * or the System property value if it does not. - * - * A SecurityException may be thrown if access is not allowed - * for 'varname'. - * @param varname - * @return String value, or null if not defined - */ - protected String getenv(String varname) { - return System.getProperty(varname); - } - - /** - * Deletes the file or directory with the given name. - * Directories must be empty to be removed. - * If this function fails, it throws and IOException - * - * @param filename - * @throws IOException if it fails - */ - protected void remove(String filename) throws IOException { - throw new IOException( "not implemented" ); - } - - /** - * Renames file or directory named oldname to newname. - * If this function fails,it throws and IOException - * - * @param oldname old file name - * @param newname new file name - * @throws IOException if it fails - */ - protected void rename(String oldname, String newname) throws IOException { - throw new IOException( "not implemented" ); - } - - /** - * Sets the current locale of the program. locale is a string specifying - * a locale; category is an optional string describing which category to change: - * "all", "collate", "ctype", "monetary", "numeric", or "time"; the default category - * is "all". - * - * If locale is the empty string, the current locale is set to an implementation- - * defined native locale. If locale is the string "C", the current locale is set - * to the standard C locale. - * - * When called with null as the first argument, this function only returns the - * name of the current locale for the given category. - * - * @param locale - * @param category - * @return the name of the new locale, or null if the request - * cannot be honored. - */ - protected String setlocale(String locale, String category) { - return "C"; - } - - /** - * Returns the current time when called without arguments, - * or a time representing the date and time specified by the given table. - * This table must have fields year, month, and day, - * and may have fields hour, min, sec, and isdst - * (for a description of these fields, see the os.date function). - * @param table - * @return long value for the time - */ - protected double time(LuaTable table) { - java.util.Date d; - if (table == null) { - d = new java.util.Date(); - } else { - Calendar c = Calendar.getInstance(); - c.set(Calendar.YEAR, table.get("year").checkint()); - c.set(Calendar.MONTH, table.get("month").checkint()-1); - c.set(Calendar.DAY_OF_MONTH, table.get("day").checkint()); - c.set(Calendar.HOUR_OF_DAY, table.get("hour").optint(12)); - c.set(Calendar.MINUTE, table.get("min").optint(0)); - c.set(Calendar.SECOND, table.get("sec").optint(0)); - c.set(Calendar.MILLISECOND, 0); - d = c.getTime(); - } - return d.getTime() / 1000.; - } - - /** - * Returns a string with a file name that can be used for a temporary file. - * The file must be explicitly opened before its use and explicitly removed - * when no longer needed. - * - * On some systems (POSIX), this function also creates a file with that name, - * to avoid security risks. (Someone else might create the file with wrong - * permissions in the time between getting the name and creating the file.) - * You still have to open the file to use it and to remove it (even if you - * do not use it). - * - * @return String filename to use - */ - protected String tmpname() { - synchronized ( OsLib.class ) { - return TMP_PREFIX+(tmpnames++)+TMP_SUFFIX; - } - } -} diff --git a/src/core/org/luaj/vm2/lib/PackageLib.java b/src/core/org/luaj/vm2/lib/PackageLib.java deleted file mode 100644 index 4c2147c9..00000000 --- a/src/core/org/luaj/vm2/lib/PackageLib.java +++ /dev/null @@ -1,381 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2010-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.lib; - -import java.io.InputStream; - -import org.luaj.vm2.Globals; -import org.luaj.vm2.LuaFunction; -import org.luaj.vm2.LuaString; -import org.luaj.vm2.LuaTable; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Varargs; - -/** - * Subclass of {@link LibFunction} which implements the lua standard package and module - * library functions. - * - *

    Lua Environment Variables

    - * The following variables are available to lua scrips when this library has been loaded: - * - * - *

    Java Environment Variables

    - * These Java environment variables affect the library behavior: - * - * - *

    Loading

    - * Typically, this library is included as part of a call to either - * {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} or {@link org.luaj.vm2.lib.jme.JmePlatform#standardGlobals()} - *
     {@code
    - * Globals globals = JsePlatform.standardGlobals();
    - * System.out.println( globals.get("require").call"foo") );
    - * } 
    - *

    - * To instantiate and use it directly, - * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as: - *

     {@code
    - * Globals globals = new Globals();
    - * globals.load(new JseBaseLib());
    - * globals.load(new PackageLib());
    - * System.out.println( globals.get("require").call("foo") );
    - * } 
    - *

    Limitations

    - * This library has been implemented to match as closely as possible the behavior in the corresponding library in C. - * However, the default filesystem search semantics are different and delegated to the bas library - * as outlined in the {@link BaseLib} and {@link org.luaj.vm2.lib.jse.JseBaseLib} documentation. - *

    - * @see LibFunction - * @see BaseLib - * @see org.luaj.vm2.lib.jse.JseBaseLib - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - * @see Lua 5.2 Package Lib Reference - */ -public class PackageLib extends TwoArgFunction { - - /** The default value to use for package.path. This can be set with the system property - * "luaj.package.path", and is "?.lua" by default. */ - public static final String DEFAULT_LUA_PATH; - static { - String path = null; - try { - path = System.getProperty("luaj.package.path"); - } catch (Exception e) { - System.out.println(e.toString()); - } - if (path == null) { - path = "?.lua"; - } - DEFAULT_LUA_PATH = path; - } - - static final LuaString _LOADED = valueOf("loaded"); - private static final LuaString _LOADLIB = valueOf("loadlib"); - static final LuaString _PRELOAD = valueOf("preload"); - static final LuaString _PATH = valueOf("path"); - static final LuaString _SEARCHPATH = valueOf("searchpath"); - static final LuaString _SEARCHERS = valueOf("searchers"); - - /** The globals that were used to load this library. */ - Globals globals; - - /** The table for this package. */ - LuaTable package_; - - /** Loader that loads from {@code preload} table if found there */ - public preload_searcher preload_searcher; - - /** Loader that loads as a lua script using the lua path currently in {@link path} */ - public lua_searcher lua_searcher; - - /** Loader that loads as a Java class. Class must have public constructor and be a LuaValue. */ - public java_searcher java_searcher; - - private static final LuaString _SENTINEL = valueOf("\u0001"); - - private static final String FILE_SEP = System.getProperty("file.separator"); - - public PackageLib() {} - - /** Perform one-time initialization on the library by adding package functions - * to the supplied environment, and returning it as the return value. - * It also creates the package.preload and package.loaded tables for use by - * other libraries. - * @param modname the module name supplied if this is loaded via 'require'. - * @param env the environment to load into, typically a Globals instance. - */ - public LuaValue call(LuaValue modname, LuaValue env) { - globals = env.checkglobals(); - globals.set("require", new require()); - package_ = new LuaTable(); - package_.set(_LOADED, new LuaTable()); - package_.set(_PRELOAD, new LuaTable()); - package_.set(_PATH, LuaValue.valueOf(DEFAULT_LUA_PATH)); - package_.set(_LOADLIB, new loadlib()); - package_.set(_SEARCHPATH, new searchpath()); - LuaTable searchers = new LuaTable(); - searchers.set(1, preload_searcher = new preload_searcher()); - searchers.set(2, lua_searcher = new lua_searcher()); - searchers.set(3, java_searcher = new java_searcher()); - package_.set(_SEARCHERS, searchers); - package_.set("config", FILE_SEP + "\n;\n?\n!\n-\n"); - package_.get(_LOADED).set("package", package_); - env.set("package", package_); - globals.package_ = this; - return env; - } - - /** Allow packages to mark themselves as loaded */ - public void setIsLoaded(String name, LuaTable value) { - package_.get(_LOADED).set(name, value); - } - - - /** Set the lua path used by this library instance to a new value. - * Merely sets the value of {@link path} to be used in subsequent searches. */ - public void setLuaPath( String newLuaPath ) { - package_.set(_PATH, LuaValue.valueOf(newLuaPath)); - } - - public String tojstring() { - return "package"; - } - - // ======================== Package loading ============================= - - /** - * require (modname) - * - * Loads the given module. The function starts by looking into the package.loaded table - * to determine whether modname is already loaded. If it is, then require returns the value - * stored at package.loaded[modname]. Otherwise, it tries to find a loader for the module. - * - * To find a loader, require is guided by the package.searchers sequence. - * By changing this sequence, we can change how require looks for a module. - * The following explanation is based on the default configuration for package.searchers. - * - * First require queries package.preload[modname]. If it has a value, this value - * (which should be a function) is the loader. Otherwise require searches for a Lua loader using - * the path stored in package.path. If that also fails, it searches for a Java loader using - * the classpath, using the public default constructor, and casting the instance to LuaFunction. - * - * Once a loader is found, require calls the loader with two arguments: modname and an extra value - * dependent on how it got the loader. If the loader came from a file, this extra value is the file name. - * If the loader is a Java instance of LuaFunction, this extra value is the environment. - * If the loader returns any non-nil value, require assigns the returned value to package.loaded[modname]. - * If the loader does not return a non-nil value and has not assigned any value to package.loaded[modname], - * then require assigns true to this entry. - * In any case, require returns the final value of package.loaded[modname]. - * - * If there is any error loading or running the module, or if it cannot find any loader for the module, - * then require raises an error. - */ - public class require extends OneArgFunction { - public LuaValue call( LuaValue arg ) { - LuaString name = arg.checkstring(); - LuaValue loaded = package_.get(_LOADED); - LuaValue result = loaded.get(name); - if ( result.toboolean() ) { - if ( result == _SENTINEL ) - error("loop or previous error loading module '"+name+"'"); - return result; - } - - /* else must load it; iterate over available loaders */ - LuaTable tbl = package_.get(_SEARCHERS).checktable(); - StringBuffer sb = new StringBuffer(); - Varargs loader = null; - for ( int i=1; true; i++ ) { - LuaValue searcher = tbl.get(i); - if ( searcher.isnil() ) { - error( "module '"+name+"' not found: "+name+sb ); - } - - /* call loader with module name as argument */ - loader = searcher.invoke(name); - if ( loader.isfunction(1) ) - break; - if ( loader.isstring(1) ) - sb.append( loader.tojstring(1) ); - } - - // load the module using the loader - loaded.set(name, _SENTINEL); - result = loader.arg1().call(name, loader.arg(2)); - if ( ! result.isnil() ) - loaded.set( name, result ); - else if ( (result = loaded.get(name)) == _SENTINEL ) - loaded.set( name, result = LuaValue.TRUE ); - return result; - } - } - - public static class loadlib extends VarArgFunction { - public Varargs invoke( Varargs args ) { - args.checkstring(1); - return varargsOf(NIL, valueOf("dynamic libraries not enabled"), valueOf("absent")); - } - } - - public class preload_searcher extends VarArgFunction { - public Varargs invoke(Varargs args) { - LuaString name = args.checkstring(1); - LuaValue val = package_.get(_PRELOAD).get(name); - return val.isnil()? - valueOf("\n\tno field package.preload['"+name+"']"): - val; - } - } - - public class lua_searcher extends VarArgFunction { - public Varargs invoke(Varargs args) { - LuaString name = args.checkstring(1); - - // get package path - LuaValue path = package_.get(_PATH); - if ( ! path.isstring() ) - return valueOf("package.path is not a string"); - - // get the searchpath function. - Varargs v = package_.get(_SEARCHPATH).invoke(varargsOf(name, path)); - - // Did we get a result? - if (!v.isstring(1)) - return v.arg(2).tostring(); - LuaString filename = v.arg1().strvalue(); - - // Try to load the file. - v = globals.loadfile(filename.tojstring()); - if ( v.arg1().isfunction() ) - return LuaValue.varargsOf(v.arg1(), filename); - - // report error - return varargsOf(NIL, valueOf("'"+filename+"': "+v.arg(2).tojstring())); - } - } - - public class searchpath extends VarArgFunction { - public Varargs invoke(Varargs args) { - String name = args.checkjstring(1); - String path = args.checkjstring(2); - String sep = args.optjstring(3, "."); - String rep = args.optjstring(4, FILE_SEP); - - // check the path elements - int e = -1; - int n = path.length(); - StringBuffer sb = null; - name = name.replace(sep.charAt(0), rep.charAt(0)); - while ( e < n ) { - - // find next template - int b = e+1; - e = path.indexOf(';',b); - if ( e < 0 ) - e = path.length(); - String template = path.substring(b,e); - - // create filename - int q = template.indexOf('?'); - String filename = template; - if ( q >= 0 ) { - filename = template.substring(0,q) + name + template.substring(q+1); - } - - // try opening the file - InputStream is = globals.finder.findResource(filename); - if (is != null) { - try { is.close(); } catch ( java.io.IOException ioe ) {} - return valueOf(filename); - } - - // report error - if ( sb == null ) - sb = new StringBuffer(); - sb.append( "\n\t"+filename ); - } - return varargsOf(NIL, valueOf(sb.toString())); - } - } - - public class java_searcher extends VarArgFunction { - public Varargs invoke(Varargs args) { - String name = args.checkjstring(1); - String classname = toClassname( name ); - Class c = null; - LuaValue v = null; - try { - c = Class.forName(classname); - v = (LuaValue) c.newInstance(); - if (v.isfunction()) - ((LuaFunction)v).initupvalue1(globals); - return varargsOf(v, globals); - } catch ( ClassNotFoundException cnfe ) { - return valueOf("\n\tno class '"+classname+"'" ); - } catch ( Exception e ) { - return valueOf("\n\tjava load failed on '"+classname+"', "+e ); - } - } - } - - /** Convert lua filename to valid class name */ - public static final String toClassname( String filename ) { - int n=filename.length(); - int j=n; - if ( filename.endsWith(".lua") ) - j -= 4; - for ( int k=0; k='a'&&c<='z') || (c>='A'&&c<='Z') || (c>='0'&&c<='9') ) - return true; - switch ( c ) { - case '.': - case '$': - case '_': - return true; - default: - return false; - } - } -} diff --git a/src/core/org/luaj/vm2/lib/ResourceFinder.java b/src/core/org/luaj/vm2/lib/ResourceFinder.java deleted file mode 100644 index 3a7b38a6..00000000 --- a/src/core/org/luaj/vm2/lib/ResourceFinder.java +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************* - * 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.lib; - -import java.io.InputStream; - -import org.luaj.vm2.Globals; - -/** - * Interface for opening application resource files such as scripts sources. - *

    - * This is used by required to load files that are part of - * the application, and implemented by BaseLib - * for both the Jme and Jse platforms. - *

    - * The Jme version of base lib {@link BaseLib} - * implements {@link Globals#finder} via {@link Class#getResourceAsStream(String)}, - * while the Jse version {@link org.luaj.vm2.lib.jse.JseBaseLib} implements it using {@link java.io.File#File(String)}. - *

    - * The io library does not use this API for file manipulation. - *

    - * @see BaseLib - * @see Globals#finder - * @see org.luaj.vm2.lib.jse.JseBaseLib - * @see org.luaj.vm2.lib.jme.JmePlatform - * @see org.luaj.vm2.lib.jse.JsePlatform - */ -public interface ResourceFinder { - - /** - * Try to open a file, or return null if not found. - * - * @see org.luaj.vm2.lib.BaseLib - * @see org.luaj.vm2.lib.jse.JseBaseLib - * - * @param filename - * @return InputStream, or null if not found. - */ - public InputStream findResource( String filename ); -} \ No newline at end of file diff --git a/src/core/org/luaj/vm2/lib/StringLib.java b/src/core/org/luaj/vm2/lib/StringLib.java deleted file mode 100644 index 8011459a..00000000 --- a/src/core/org/luaj/vm2/lib/StringLib.java +++ /dev/null @@ -1,1223 +0,0 @@ -/******************************************************************************* -* 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.lib; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import org.luaj.vm2.Buffer; -import org.luaj.vm2.LuaClosure; -import org.luaj.vm2.LuaString; -import org.luaj.vm2.LuaTable; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Varargs; -import org.luaj.vm2.compiler.DumpState; - -/** - * Subclass of {@link LibFunction} which implements the lua standard {@code string} - * library. - *

    - * Typically, this library is included as part of a call to either - * {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} or {@link org.luaj.vm2.lib.jme.JmePlatform#standardGlobals()} - *

     {@code
    - * Globals globals = JsePlatform.standardGlobals();
    - * System.out.println( globals.get("string").get("upper").call( LuaValue.valueOf("abcde") ) );
    - * } 
    - *

    - * To instantiate and use it directly, - * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as: - *

     {@code
    - * Globals globals = new Globals();
    - * globals.load(new JseBaseLib());
    - * globals.load(new PackageLib());
    - * globals.load(new JseStringLib());
    - * System.out.println( globals.get("string").get("upper").call( LuaValue.valueOf("abcde") ) );
    - * } 
    - *

    - * This is a direct port of the corresponding library in C. - * @see LibFunction - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - * @see Lua 5.2 String Lib Reference - */ -public class StringLib extends TwoArgFunction { - - /** Construct a StringLib, which can be initialized by calling it with a - * modname string, and a global environment table as arguments using - * {@link #call(LuaValue, LuaValue)}. */ - public StringLib() { - } - - /** Perform one-time initialization on the library by creating a table - * containing the library functions, adding that table to the supplied environment, - * adding the table to package.loaded, and returning table as the return value. - * Creates a metatable that uses __INDEX to fall back on itself to support string - * method operations. - * If the shared strings metatable instance is null, will set the metatable as - * the global shared metatable for strings. - *

    - * All tables and metatables are read-write by default so if this will be used in - * a server environment, sandboxing should be used. In particular, the - * {@link LuaString#s_metatable} table should probably be made read-only. - * @param modname the module name supplied if this is loaded via 'require'. - * @param env the environment to load into, typically a Globals instance. - */ - public LuaValue call(LuaValue modname, LuaValue env) { - LuaTable string = new LuaTable(); - string.set("byte", new _byte()); - string.set("char", new _char()); - string.set("dump", new dump()); - string.set("find", new find()); - string.set("format", new format()); - string.set("gmatch", new gmatch()); - string.set("gsub", new gsub()); - string.set("len", new len()); - string.set("lower", new lower()); - string.set("match", new match()); - string.set("rep", new rep()); - string.set("reverse", new reverse()); - string.set("sub", new sub()); - string.set("upper", new upper()); - - env.set("string", string); - if (!env.get("package").isnil()) env.get("package").get("loaded").set("string", string); - if (LuaString.s_metatable == null) { - LuaString.s_metatable = LuaValue.tableOf(new LuaValue[] { INDEX, string }); - } - return string; - } - - /** - * string.byte (s [, i [, j]]) - * - * Returns the internal numerical codes of the - * characters s[i], s[i+1], ..., s[j]. The default value for i is 1; the - * default value for j is i. - * - * Note that numerical codes are not necessarily portable across platforms. - * - * @param args the calling args - */ - static final class _byte extends VarArgFunction { - public Varargs invoke(Varargs args) { - LuaString s = args.checkstring(1); - int l = s.m_length; - int posi = posrelat( args.optint(2,1), l ); - int pose = posrelat( args.optint(3,posi), l ); - int n,i; - if (posi <= 0) posi = 1; - if (pose > l) pose = l; - if (posi > pose) return NONE; /* empty interval; return no values */ - n = (int)(pose - posi + 1); - if (posi + n <= pose) /* overflow? */ - error("string slice too long"); - LuaValue[] v = new LuaValue[n]; - for (i=0; i=256) argerror(a, "invalid value for string.char [0; 255]: " + c); - bytes[i] = (byte) c; - } - return LuaString.valueUsing( bytes ); - } - } - - /** - * string.dump (function[, stripDebug]) - * - * Returns a string containing a binary representation of the given function, - * so that a later loadstring on this string returns a copy of the function. - * function must be a Lua function without upvalues. - * Boolean param stripDebug - true to strip debugging info, false otherwise. - * The default value for stripDebug is true. - * - * TODO: port dumping code as optional add-on - */ - static final class dump extends VarArgFunction { - public Varargs invoke(Varargs args) { - LuaValue f = args.checkfunction(1); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - DumpState.dump( ((LuaClosure)f).p, baos, args.optboolean(2, true) ); - return LuaString.valueUsing(baos.toByteArray()); - } catch (IOException e) { - return error( e.getMessage() ); - } - } - } - - /** - * string.find (s, pattern [, init [, plain]]) - * - * Looks for the first match of pattern in the string s. - * If it finds a match, then find returns the indices of s - * where this occurrence starts and ends; otherwise, it returns nil. - * A third, optional numerical argument init specifies where to start the search; - * its default value is 1 and may be negative. A value of true as a fourth, - * optional argument plain turns off the pattern matching facilities, - * so the function does a plain "find substring" operation, - * with no characters in pattern being considered "magic". - * Note that if plain is given, then init must be given as well. - * - * If the pattern has captures, then in a successful match the captured values - * are also returned, after the two indices. - */ - static final class find extends VarArgFunction { - public Varargs invoke(Varargs args) { - return str_find_aux( args, true ); - } - } - - /** - * string.format (formatstring, ...) - * - * Returns a formatted version of its variable number of arguments following - * the description given in its first argument (which must be a string). - * The format string follows the same rules as the printf family of standard C functions. - * The only differences are that the options/modifiers *, l, L, n, p, and h are not supported - * and that there is an extra option, q. The q option formats a string in a form suitable - * to be safely read back by the Lua interpreter: the string is written between double quotes, - * and all double quotes, newlines, embedded zeros, and backslashes in the string are correctly - * escaped when written. For instance, the call - * string.format('%q', 'a string with "quotes" and \n new line') - * - * will produce the string: - * "a string with \"quotes\" and \ - * new line" - * - * The options c, d, E, e, f, g, G, i, o, u, X, and x all expect a number as argument, - * whereas q and s expect a string. - * - * This function does not accept string values containing embedded zeros, - * except as arguments to the q option. - */ - final class format extends VarArgFunction { - public Varargs invoke(Varargs args) { - LuaString fmt = args.checkstring( 1 ); - final int n = fmt.length(); - Buffer result = new Buffer(n); - int arg = 1; - int c; - - for ( int i = 0; i < n; ) { - switch ( c = fmt.luaByte( i++ ) ) { - case '\n': - result.append( "\n" ); - break; - default: - result.append( (byte) c ); - break; - case L_ESC: - if ( i < n ) { - if ( ( c = fmt.luaByte( i ) ) == L_ESC ) { - ++i; - result.append( (byte)L_ESC ); - } else { - arg++; - FormatDesc fdsc = new FormatDesc(args, fmt, i ); - i += fdsc.length; - switch ( fdsc.conversion ) { - case 'c': - fdsc.format( result, (byte)args.checkint( arg ) ); - break; - case 'i': - case 'd': - fdsc.format( result, args.checklong( arg ) ); - break; - case 'o': - case 'u': - case 'x': - case 'X': - fdsc.format( result, args.checklong( arg ) ); - break; - case 'e': - case 'E': - case 'f': - case 'g': - case 'G': - fdsc.format( result, args.checkdouble( arg ) ); - break; - case 'q': - addquoted( result, args.checkstring( arg ) ); - break; - case 's': { - LuaString s = args.checkstring( arg ); - if ( fdsc.precision == -1 && s.length() >= 100 ) { - result.append( s ); - } else { - fdsc.format( result, s ); - } - } break; - default: - error("invalid option '%"+(char)fdsc.conversion+"' to 'format'"); - break; - } - } - } - } - } - - return result.tostring(); - } - } - - static void addquoted(Buffer buf, LuaString s) { - int c; - buf.append( (byte) '"' ); - for ( int i = 0, n = s.length(); i < n; i++ ) { - switch ( c = s.luaByte( i ) ) { - case '"': case '\\': case '\n': - buf.append( (byte)'\\' ); - buf.append( (byte)c ); - break; - default: - if (c <= 0x1F || c == 0x7F) { - buf.append( (byte) '\\' ); - if (i+1 == n || s.luaByte(i+1) < '0' || s.luaByte(i+1) > '9') { - buf.append(Integer.toString(c)); - } else { - buf.append( (byte) '0' ); - buf.append( (byte) (char) ('0' + c / 10) ); - buf.append( (byte) (char) ('0' + c % 10) ); - } - } else { - buf.append((byte) c); - } - break; - } - } - buf.append( (byte) '"' ); - } - - private static final String FLAGS = "-+ #0"; - - class FormatDesc { - - private boolean leftAdjust; - private boolean zeroPad; - private boolean explicitPlus; - private boolean space; - private boolean alternateForm; - private static final int MAX_FLAGS = 5; - - private int width; - int precision; - - public final int conversion; - public final int length; - - public final String src; - - public FormatDesc(Varargs args, LuaString strfrmt, final int start) { - int p = start, n = strfrmt.length(); - int c = 0; - - boolean moreFlags = true; - while ( moreFlags ) { - switch ( c = ( (p < n) ? strfrmt.luaByte( p++ ) : 0 ) ) { - case '-': leftAdjust = true; break; - case '+': explicitPlus = true; break; - case ' ': space = true; break; - case '#': alternateForm = true; break; - case '0': zeroPad = true; break; - default: moreFlags = false; break; - } - } - if ( p - start > MAX_FLAGS ) - error("invalid format (repeated flags)"); - - width = -1; - if ( Character.isDigit( (char)c ) ) { - width = c - '0'; - c = ( (p < n) ? strfrmt.luaByte( p++ ) : 0 ); - if ( Character.isDigit( (char) c ) ) { - width = width * 10 + (c - '0'); - c = ( (p < n) ? strfrmt.luaByte( p++ ) : 0 ); - } - } - - precision = -1; - if ( c == '.' ) { - c = ( (p < n) ? strfrmt.luaByte( p++ ) : 0 ); - if ( Character.isDigit( (char) c ) ) { - precision = c - '0'; - c = ( (p < n) ? strfrmt.luaByte( p++ ) : 0 ); - if ( Character.isDigit( (char) c ) ) { - precision = precision * 10 + (c - '0'); - c = ( (p < n) ? strfrmt.luaByte( p++ ) : 0 ); - } - } - } - - if ( Character.isDigit( (char) c ) ) - error("invalid format (width or precision too long)"); - - zeroPad &= !leftAdjust; // '-' overrides '0' - conversion = c; - length = p - start; - src = strfrmt.substring(start - 1, p).tojstring(); - } - - public void format(Buffer buf, byte c) { - // TODO: not clear that any of width, precision, or flags apply here. - buf.append(c); - } - - public void format(Buffer buf, long number) { - String digits; - - if ( number == 0 && precision == 0 ) { - digits = ""; - } else { - int radix; - switch ( conversion ) { - case 'x': - case 'X': - radix = 16; - break; - case 'o': - radix = 8; - break; - default: - radix = 10; - break; - } - digits = Long.toString( number, radix ); - if ( conversion == 'X' ) - digits = digits.toUpperCase(); - } - - int minwidth = digits.length(); - int ndigits = minwidth; - int nzeros; - - if ( number < 0 ) { - ndigits--; - } else if ( explicitPlus || space ) { - minwidth++; - } - - if ( precision > ndigits ) - nzeros = precision - ndigits; - else if ( precision == -1 && zeroPad && width > minwidth ) - nzeros = width - minwidth; - else - nzeros = 0; - - minwidth += nzeros; - int nspaces = width > minwidth ? width - minwidth : 0; - - if ( !leftAdjust ) - pad( buf, ' ', nspaces ); - - if ( number < 0 ) { - if ( nzeros > 0 ) { - buf.append( (byte)'-' ); - digits = digits.substring( 1 ); - } - } else if ( explicitPlus ) { - buf.append( (byte)'+' ); - } else if ( space ) { - buf.append( (byte)' ' ); - } - - if ( nzeros > 0 ) - pad( buf, '0', nzeros ); - - buf.append( digits ); - - if ( leftAdjust ) - pad( buf, ' ', nspaces ); - } - - public void format(Buffer buf, double x) { - buf.append( StringLib.this.format(src, x) ); - } - - public void format(Buffer buf, LuaString s) { - int nullindex = s.indexOf( (byte)'\0', 0 ); - if ( nullindex != -1 ) - s = s.substring( 0, nullindex ); - buf.append(s); - } - - public final void pad(Buffer buf, char c, int n) { - byte b = (byte)c; - while ( n-- > 0 ) - buf.append(b); - } - } - - protected String format(String src, double x) { - return String.valueOf(x); - } - - /** - * string.gmatch (s, pattern) - * - * Returns an iterator function that, each time it is called, returns the next captures - * from pattern over string s. If pattern specifies no captures, then the - * whole match is produced in each call. - * - * As an example, the following loop - * s = "hello world from Lua" - * for w in string.gmatch(s, "%a+") do - * print(w) - * end - * - * will iterate over all the words from string s, printing one per line. - * The next example collects all pairs key=value from the given string into a table: - * t = {} - * s = "from=world, to=Lua" - * for k, v in string.gmatch(s, "(%w+)=(%w+)") do - * t[k] = v - * end - * - * For this function, a '^' at the start of a pattern does not work as an anchor, - * as this would prevent the iteration. - */ - static final class gmatch extends VarArgFunction { - public Varargs invoke(Varargs args) { - LuaString src = args.checkstring( 1 ); - LuaString pat = args.checkstring( 2 ); - return new GMatchAux(args, src, pat); - } - } - - static class GMatchAux extends VarArgFunction { - private final int srclen; - private final MatchState ms; - private int soffset; - private int lastmatch; - public GMatchAux(Varargs args, LuaString src, LuaString pat) { - this.srclen = src.length(); - this.ms = new MatchState(args, src, pat); - this.soffset = 0; - this.lastmatch = -1; - } - public Varargs invoke(Varargs args) { - for ( ; soffset<=srclen; soffset++ ) { - ms.reset(); - int res = ms.match(soffset, 0); - if ( res >=0 && res != lastmatch ) { - int soff = soffset; - lastmatch = soffset = res; - return ms.push_captures( true, soff, res ); - } - } - return NIL; - } - } - - - /** - * string.gsub (s, pattern, repl [, n]) - * Returns a copy of s in which all (or the first n, if given) occurrences of the - * pattern have been replaced by a replacement string specified by repl, which - * may be a string, a table, or a function. gsub also returns, as its second value, - * the total number of matches that occurred. - * - * If repl is a string, then its value is used for replacement. - * The character % works as an escape character: any sequence in repl of the form %n, - * with n between 1 and 9, stands for the value of the n-th captured substring (see below). - * The sequence %0 stands for the whole match. The sequence %% stands for a single %. - * - * If repl is a table, then the table is queried for every match, using the first capture - * as the key; if the pattern specifies no captures, then the whole match is used as the key. - * - * If repl is a function, then this function is called every time a match occurs, - * with all captured substrings passed as arguments, in order; if the pattern specifies - * no captures, then the whole match is passed as a sole argument. - * - * If the value returned by the table query or by the function call is a string or a number, - * then it is used as the replacement string; otherwise, if it is false or nil, - * then there is no replacement (that is, the original match is kept in the string). - * - * Here are some examples: - * x = string.gsub("hello world", "(%w+)", "%1 %1") - * --> x="hello hello world world" - * - * x = string.gsub("hello world", "%w+", "%0 %0", 1) - * --> x="hello hello world" - * - * x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1") - * --> x="world hello Lua from" - * - * x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv) - * --> x="home = /home/roberto, user = roberto" - * - * x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s) - * return loadstring(s)() - * end) - * --> x="4+5 = 9" - * - * local t = {name="lua", version="5.1"} - * x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t) - * --> x="lua-5.1.tar.gz" - */ - static final class gsub extends VarArgFunction { - public Varargs invoke(Varargs args) { - LuaString src = args.checkstring( 1 ); - final int srclen = src.length(); - LuaString p = args.checkstring( 2 ); - int lastmatch = -1; /* end of last match */ - LuaValue repl = args.arg( 3 ); - int max_s = args.optint( 4, srclen + 1 ); - final boolean anchor = p.length() > 0 && p.charAt( 0 ) == '^'; - - Buffer lbuf = new Buffer( srclen ); - MatchState ms = new MatchState( args, src, p ); - - int soffset = 0; - int n = 0; - while ( n < max_s ) { - ms.reset(); - int res = ms.match( soffset, anchor ? 1 : 0 ); - if ( res != -1 && res != lastmatch ) { /* match? */ - n++; - ms.add_value( lbuf, soffset, res, repl ); /* add replacement to buffer */ - soffset = lastmatch = res; - } - else if ( soffset < srclen ) /* otherwise, skip one character */ - lbuf.append( (byte) src.luaByte( soffset++ ) ); - else break; /* end of subject */ - if ( anchor ) break; - } - lbuf.append( src.substring( soffset, srclen ) ); - return varargsOf(lbuf.tostring(), valueOf(n)); - } - } - - /** - * string.len (s) - * - * Receives a string and returns its length. The empty string "" has length 0. - * Embedded zeros are counted, so "a\000bc\000" has length 5. - */ - static final class len extends OneArgFunction { - public LuaValue call(LuaValue arg) { - return arg.checkstring().len(); - } - } - - /** - * string.lower (s) - * - * Receives a string and returns a copy of this string with all uppercase letters - * changed to lowercase. All other characters are left unchanged. - * The definition of what an uppercase letter is depends on the current locale. - */ - static final class lower extends OneArgFunction { - public LuaValue call(LuaValue arg) { - return valueOf( arg.checkjstring().toLowerCase() ); - } - } - - /** - * string.match (s, pattern [, init]) - * - * Looks for the first match of pattern in the string s. If it finds one, - * then match returns the captures from the pattern; otherwise it returns - * nil. If pattern specifies no captures, then the whole match is returned. - * A third, optional numerical argument init specifies where to start the - * search; its default value is 1 and may be negative. - */ - static final class match extends VarArgFunction { - public Varargs invoke(Varargs args) { - return str_find_aux( args, false ); - } - } - - /** - * string.rep (s, n) - * - * Returns a string that is the concatenation of n copies of the string s. - */ - static final class rep extends VarArgFunction { - public Varargs invoke(Varargs args) { - LuaString s = args.checkstring( 1 ); - int n = args.checkint( 2 ); - final byte[] bytes = new byte[ s.length() * n ]; - int len = s.length(); - for ( int offset = 0; offset < bytes.length; offset += len ) { - s.copyInto( 0, bytes, offset, len ); - } - return LuaString.valueUsing( bytes ); - } - } - - /** - * string.reverse (s) - * - * Returns a string that is the string s reversed. - */ - static final class reverse extends OneArgFunction { - public LuaValue call(LuaValue arg) { - LuaString s = arg.checkstring(); - int n = s.length(); - byte[] b = new byte[n]; - for ( int i=0, j=n-1; i l ) - end = l; - - if ( start <= end ) { - return s.substring( start-1 , end ); - } else { - return EMPTYSTRING; - } - } - } - - /** - * string.upper (s) - * - * Receives a string and returns a copy of this string with all lowercase letters - * changed to uppercase. All other characters are left unchanged. - * The definition of what a lowercase letter is depends on the current locale. - */ - static final class upper extends OneArgFunction { - public LuaValue call(LuaValue arg) { - return valueOf(arg.checkjstring().toUpperCase()); - } - } - - /** - * This utility method implements both string.find and string.match. - */ - static Varargs str_find_aux( Varargs args, boolean find ) { - LuaString s = args.checkstring( 1 ); - LuaString pat = args.checkstring( 2 ); - int init = args.optint( 3, 1 ); - - if ( init > 0 ) { - init = Math.min( init - 1, s.length() ); - } else if ( init < 0 ) { - init = Math.max( 0, s.length() + init ); - } - - boolean fastMatch = find && ( args.arg(4).toboolean() || pat.indexOfAny( SPECIALS ) == -1 ); - - if ( fastMatch ) { - int result = s.indexOf( pat, init ); - if ( result != -1 ) { - return varargsOf( valueOf(result+1), valueOf(result+pat.length()) ); - } - } else { - MatchState ms = new MatchState( args, s, pat ); - - boolean anchor = false; - int poff = 0; - if ( pat.length() > 0 && pat.luaByte( 0 ) == '^' ) { - anchor = true; - poff = 1; - } - - int soff = init; - do { - int res; - ms.reset(); - if ( ( res = ms.match( soff, poff ) ) != -1 ) { - if ( find ) { - return varargsOf( valueOf(soff+1), valueOf(res), ms.push_captures( false, soff, res )); - } else { - return ms.push_captures( true, soff, res ); - } - } - } while ( soff++ < s.length() && !anchor ); - } - return NIL; - } - - static int posrelat( int pos, int len ) { - return ( pos >= 0 ) ? pos : len + pos + 1; - } - - // Pattern matching implementation - - private static final int L_ESC = '%'; - private static final LuaString SPECIALS = valueOf("^$*+?.([%-"); - private static final int MAX_CAPTURES = 32; - - private static final int MAXCCALLS = 200; - - private static final int CAP_UNFINISHED = -1; - private static final int CAP_POSITION = -2; - - private static final byte MASK_ALPHA = 0x01; - private static final byte MASK_LOWERCASE = 0x02; - private static final byte MASK_UPPERCASE = 0x04; - private static final byte MASK_DIGIT = 0x08; - private static final byte MASK_PUNCT = 0x10; - private static final byte MASK_SPACE = 0x20; - private static final byte MASK_CONTROL = 0x40; - private static final byte MASK_HEXDIGIT = (byte)0x80; - - static final byte[] CHAR_TABLE; - - static { - CHAR_TABLE = new byte[256]; - - for ( int i = 0; i < 128; ++i ) { - final char c = (char) i; - CHAR_TABLE[i] = (byte)( ( Character.isDigit( c ) ? MASK_DIGIT : 0 ) | - ( Character.isLowerCase( c ) ? MASK_LOWERCASE : 0 ) | - ( Character.isUpperCase( c ) ? MASK_UPPERCASE : 0 ) | - ( ( c < ' ' || c == 0x7F ) ? MASK_CONTROL : 0 ) ); - if ( ( c >= 'a' && c <= 'f' ) || ( c >= 'A' && c <= 'F' ) || ( c >= '0' && c <= '9' ) ) { - CHAR_TABLE[i] |= MASK_HEXDIGIT; - } - if ( ( c >= '!' && c <= '/' ) || ( c >= ':' && c <= '@' ) || ( c >= '[' && c <= '`' ) || ( c >= '{' && c <= '~' ) ) { - CHAR_TABLE[i] |= MASK_PUNCT; - } - if ( ( CHAR_TABLE[i] & ( MASK_LOWERCASE | MASK_UPPERCASE ) ) != 0 ) { - CHAR_TABLE[i] |= MASK_ALPHA; - } - } - - CHAR_TABLE[' '] = MASK_SPACE; - CHAR_TABLE['\r'] |= MASK_SPACE; - CHAR_TABLE['\n'] |= MASK_SPACE; - CHAR_TABLE['\t'] |= MASK_SPACE; - CHAR_TABLE[0x0B /* '\v' */ ] |= MASK_SPACE; - CHAR_TABLE['\f'] |= MASK_SPACE; - }; - - static class MatchState { - int matchdepth; /* control for recursive depth (to avoid C stack overflow) */ - final LuaString s; - final LuaString p; - final Varargs args; - int level; - int[] cinit; - int[] clen; - - MatchState( Varargs args, LuaString s, LuaString pattern ) { - this.s = s; - this.p = pattern; - this.args = args; - this.level = 0; - this.cinit = new int[ MAX_CAPTURES ]; - this.clen = new int[ MAX_CAPTURES ]; - this.matchdepth = MAXCCALLS; - } - - void reset() { - level = 0; - this.matchdepth = MAXCCALLS; - } - - private void add_s( Buffer lbuf, LuaString news, int soff, int e ) { - int l = news.length(); - for ( int i = 0; i < l; ++i ) { - byte b = (byte) news.luaByte( i ); - if ( b != L_ESC ) { - lbuf.append( (byte) b ); - } else { - ++i; // skip ESC - b = (byte)(i < l ? news.luaByte( i ) : 0); - if ( !Character.isDigit( (char) b ) ) { - if (b != L_ESC) error( "invalid use of '" + (char)L_ESC + - "' in replacement string: after '" + (char)L_ESC + - "' must be '0'-'9' or '" + (char)L_ESC + - "', but found " + (i < l ? "symbol '" + (char)b + "' with code " + b + - " at pos " + (i + 1) : - "end of string")); - lbuf.append( b ); - } else if ( b == '0' ) { - lbuf.append( s.substring( soff, e ) ); - } else { - lbuf.append( push_onecapture( b - '1', soff, e ).strvalue() ); - } - } - } - } - - public void add_value( Buffer lbuf, int soffset, int end, LuaValue repl ) { - switch ( repl.type() ) { - case LuaValue.TSTRING: - case LuaValue.TNUMBER: - add_s( lbuf, repl.strvalue(), soffset, end ); - return; - - case LuaValue.TFUNCTION: - repl = repl.invoke( push_captures( true, soffset, end ) ).arg1(); - break; - - case LuaValue.TTABLE: - // Need to call push_onecapture here for the error checking - repl = repl.get( push_onecapture( 0, soffset, end ) ); - break; - - default: - error( "bad argument: string/function/table expected" ); - return; - } - - if ( !repl.toboolean() ) { - repl = s.substring( soffset, end ); - } else if ( ! repl.isstring() ) { - error( "invalid replacement value (a "+repl.typename()+")" ); - } - lbuf.append( repl.strvalue() ); - } - - Varargs push_captures( boolean wholeMatch, int soff, int end ) { - int nlevels = ( this.level == 0 && wholeMatch ) ? 1 : this.level; - switch ( nlevels ) { - case 0: return NONE; - case 1: return push_onecapture( 0, soff, end ); - } - LuaValue[] v = new LuaValue[nlevels]; - for ( int i = 0; i < nlevels; ++i ) - v[i] = push_onecapture( i, soff, end ); - return varargsOf(v); - } - - private LuaValue push_onecapture( int i, int soff, int end ) { - if ( i >= this.level ) { - if ( i == 0 ) { - return s.substring( soff, end ); - } else { - return error( "invalid capture index %" + (i + 1) ); - } - } else { - int l = clen[i]; - if ( l == CAP_UNFINISHED ) { - return error( "unfinished capture" ); - } - if ( l == CAP_POSITION ) { - return valueOf( cinit[i] + 1 ); - } else { - int begin = cinit[i]; - return s.substring( begin, begin + l ); - } - } - } - - private int check_capture( int l ) { - l -= '1'; - if ( l < 0 || l >= level || this.clen[l] == CAP_UNFINISHED ) { - error("invalid capture index %" + (l + 1)); - } - return l; - } - - private int capture_to_close() { - int level = this.level; - for ( level--; level >= 0; level-- ) - if ( clen[level] == CAP_UNFINISHED ) - return level; - error("invalid pattern capture"); - return 0; - } - - int classend( int poffset ) { - switch ( p.luaByte( poffset++ ) ) { - case L_ESC: - if ( poffset == p.length() ) { - error( "malformed pattern (ends with '%')" ); - } - return poffset + 1; - - case '[': - if ( poffset != p.length() && p.luaByte( poffset ) == '^' ) poffset++; - do { - if ( poffset == p.length() ) { - error( "malformed pattern (missing ']')" ); - } - if ( p.luaByte( poffset++ ) == L_ESC && poffset < p.length() ) - poffset++; /* skip escapes (e.g. '%]') */ - } while ( poffset == p.length() || p.luaByte( poffset ) != ']' ); - return poffset + 1; - default: - return poffset; - } - } - - static boolean match_class( int c, int cl ) { - final char lcl = Character.toLowerCase( (char) cl ); - int cdata = CHAR_TABLE[c]; - - boolean res; - switch ( lcl ) { - case 'a': res = ( cdata & MASK_ALPHA ) != 0; break; - case 'd': res = ( cdata & MASK_DIGIT ) != 0; break; - case 'l': res = ( cdata & MASK_LOWERCASE ) != 0; break; - case 'u': res = ( cdata & MASK_UPPERCASE ) != 0; break; - case 'c': res = ( cdata & MASK_CONTROL ) != 0; break; - case 'p': res = ( cdata & MASK_PUNCT ) != 0; break; - case 's': res = ( cdata & MASK_SPACE ) != 0; break; - case 'g': res = ( cdata & ( MASK_ALPHA | MASK_DIGIT | MASK_PUNCT ) ) != 0; break; - case 'w': res = ( cdata & ( MASK_ALPHA | MASK_DIGIT ) ) != 0; break; - case 'x': res = ( cdata & MASK_HEXDIGIT ) != 0; break; - case 'z': res = ( c == 0 ); break; /* deprecated option */ - default: return cl == c; - } - return ( lcl == cl ) ? res : !res; - } - - boolean matchbracketclass( int c, int poff, int ec ) { - boolean sig = true; - if ( p.luaByte( poff + 1 ) == '^' ) { - sig = false; - poff++; - } - while ( ++poff < ec ) { - if ( p.luaByte( poff ) == L_ESC ) { - poff++; - if ( match_class( c, p.luaByte( poff ) ) ) - return sig; - } - else if ( ( p.luaByte( poff + 1 ) == '-' ) && ( poff + 2 < ec ) ) { - poff += 2; - if ( p.luaByte( poff - 2 ) <= c && c <= p.luaByte( poff ) ) - return sig; - } - else if ( p.luaByte( poff ) == c ) return sig; - } - return !sig; - } - - boolean singlematch( int c, int poff, int ep ) { - switch ( p.luaByte( poff ) ) { - case '.': return true; - case L_ESC: return match_class( c, p.luaByte( poff + 1 ) ); - case '[': return matchbracketclass( c, poff, ep - 1 ); - default: return p.luaByte( poff ) == c; - } - } - - /** - * Perform pattern matching. If there is a match, returns offset into s - * where match ends, otherwise returns -1. - */ - int match( int soffset, int poffset ) { - if (matchdepth-- == 0) error("pattern too complex"); - try { - while ( true ) { - // Check if we are at the end of the pattern - - // equivalent to the '\0' case in the C version, but our pattern - // string is not NUL-terminated. - if ( poffset == p.length() ) - return soffset; - switch ( p.luaByte( poffset ) ) { - case '(': - if ( ++poffset < p.length() && p.luaByte( poffset ) == ')' ) - return start_capture( soffset, poffset + 1, CAP_POSITION ); - else - return start_capture( soffset, poffset, CAP_UNFINISHED ); - case ')': - return end_capture( soffset, poffset + 1 ); - case L_ESC: - if ( poffset + 1 == p.length() ) - error("malformed pattern (ends with '%')"); - switch ( p.luaByte( poffset + 1 ) ) { - case 'b': - soffset = matchbalance( soffset, poffset + 2 ); - if ( soffset == -1 ) return -1; - poffset += 4; - continue; - case 'f': { - poffset += 2; - if ( poffset == p.length() || p.luaByte( poffset ) != '[' ) { - error("missing '[' after '%f' in pattern"); - } - int ep = classend( poffset ); - int previous = ( soffset == 0 ) ? '\0' : s.luaByte( soffset - 1 ); - int next = ( soffset == s.length() ) ? '\0' : s.luaByte( soffset ); - if ( matchbracketclass( previous, poffset, ep - 1 ) || - !matchbracketclass( next, poffset, ep - 1 ) ) - return -1; - poffset = ep; - continue; - } - default: { - int c = p.luaByte( poffset + 1 ); - if ( Character.isDigit( (char) c ) ) { - soffset = match_capture( soffset, c ); - if ( soffset == -1 ) - return -1; - return match( soffset, poffset + 2 ); - } - } - } - case '$': - if ( poffset + 1 == p.length() ) - return ( soffset == s.length() ) ? soffset : -1; - } - int ep = classend( poffset ); - boolean m = soffset < s.length() && singlematch( s.luaByte( soffset ), poffset, ep ); - int pc = ( ep < p.length() ) ? p.luaByte( ep ) : '\0'; - - switch ( pc ) { - case '?': - int res; - if ( m && ( ( res = match( soffset + 1, ep + 1 ) ) != -1 ) ) - return res; - poffset = ep + 1; - continue; - case '*': - return max_expand( soffset, poffset, ep ); - case '+': - return ( m ? max_expand( soffset + 1, poffset, ep ) : -1 ); - case '-': - return min_expand( soffset, poffset, ep ); - default: - if ( !m ) - return -1; - soffset++; - poffset = ep; - continue; - } - } - } finally { - matchdepth++; - } - } - - int max_expand( int soff, int poff, int ep ) { - int i = 0; - while ( soff + i < s.length() && - singlematch( s.luaByte( soff + i ), poff, ep ) ) - i++; - while ( i >= 0 ) { - int res = match( soff + i, ep + 1 ); - if ( res != -1 ) - return res; - i--; - } - return -1; - } - - int min_expand( int soff, int poff, int ep ) { - for ( ;; ) { - int res = match( soff, ep + 1 ); - if ( res != -1 ) - return res; - else if ( soff < s.length() && singlematch( s.luaByte( soff ), poff, ep ) ) - soff++; - else return -1; - } - } - - int start_capture( int soff, int poff, int what ) { - int res; - int level = this.level; - if ( level >= MAX_CAPTURES ) { - error( "too many captures" ); - } - cinit[ level ] = soff; - clen[ level ] = what; - this.level = level + 1; - if ( ( res = match( soff, poff ) ) == -1 ) - this.level--; - return res; - } - - int end_capture( int soff, int poff ) { - int l = capture_to_close(); - int res; - clen[l] = soff - cinit[l]; - if ( ( res = match( soff, poff ) ) == -1 ) - clen[l] = CAP_UNFINISHED; - return res; - } - - int match_capture( int soff, int l ) { - l = check_capture( l ); - int len = clen[ l ]; - if ( ( s.length() - soff ) >= len && - LuaString.equals( s, cinit[l], s, soff, len ) ) - return soff + len; - else - return -1; - } - - int matchbalance( int soff, int poff ) { - final int plen = p.length(); - if ( poff == plen || poff + 1 == plen ) { - error( "malformed pattern (missing arguments to '%b')" ); - } - final int slen = s.length(); - if ( soff >= slen ) - return -1; - final int b = p.luaByte( poff ); - if ( s.luaByte( soff ) != b ) - return -1; - final int e = p.luaByte( poff + 1 ); - int cont = 1; - while ( ++soff < slen ) { - if ( s.luaByte( soff ) == e ) { - if ( --cont == 0 ) return soff + 1; - } - else if ( s.luaByte( soff ) == b ) cont++; - } - return -1; - } - } -} diff --git a/src/core/org/luaj/vm2/lib/TableLib.java b/src/core/org/luaj/vm2/lib/TableLib.java deleted file mode 100644 index 64959277..00000000 --- a/src/core/org/luaj/vm2/lib/TableLib.java +++ /dev/null @@ -1,158 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2009 Luaj.org. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm2.lib; - -import org.luaj.vm2.LuaTable; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Varargs; - -/** - * Subclass of {@link LibFunction} which implements the lua standard {@code table} - * library. - * - *

    - * Typically, this library is included as part of a call to either - * {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} or {@link org.luaj.vm2.lib.jme.JmePlatform#standardGlobals()} - *

     {@code
    - * Globals globals = JsePlatform.standardGlobals();
    - * System.out.println( globals.get("table").get("length").call( LuaValue.tableOf() ) );
    - * } 
    - *

    - * To instantiate and use it directly, - * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as: - *

     {@code
    - * Globals globals = new Globals();
    - * globals.load(new JseBaseLib());
    - * globals.load(new PackageLib());
    - * globals.load(new TableLib());
    - * System.out.println( globals.get("table").get("length").call( LuaValue.tableOf() ) );
    - * } 
    - *

    - * This has been implemented to match as closely as possible the behavior in the corresponding library in C. - * @see LibFunction - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - * @see Lua 5.2 Table Lib Reference - */ -public class TableLib extends TwoArgFunction { - - /** Perform one-time initialization on the library by creating a table - * containing the library functions, adding that table to the supplied environment, - * adding the table to package.loaded, and returning table as the return value. - * @param modname the module name supplied if this is loaded via 'require'. - * @param env the environment to load into, typically a Globals instance. - */ - public LuaValue call(LuaValue modname, LuaValue env) { - LuaTable table = new LuaTable(); - table.set("concat", new concat()); - table.set("insert", new insert()); - table.set("pack", new pack()); - table.set("remove", new remove()); - table.set("sort", new sort()); - table.set("unpack", new unpack()); - env.set("table", table); - if (!env.get("package").isnil()) env.get("package").get("loaded").set("table", table); - return NIL; - } - - // "concat" (table [, sep [, i [, j]]]) -> string - static class concat extends TableLibFunction { - public LuaValue call(LuaValue list) { - return list.checktable().concat(EMPTYSTRING,1,list.length()); - } - public LuaValue call(LuaValue list, LuaValue sep) { - return list.checktable().concat(sep.checkstring(),1,list.length()); - } - public LuaValue call(LuaValue list, LuaValue sep, LuaValue i) { - return list.checktable().concat(sep.checkstring(),i.checkint(),list.length()); - } - public LuaValue call(LuaValue list, LuaValue sep, LuaValue i, LuaValue j) { - return list.checktable().concat(sep.checkstring(),i.checkint(),j.checkint()); - } - } - - // "insert" (table, [pos,] value) - static class insert extends VarArgFunction { - public Varargs invoke(Varargs args) { - switch (args.narg()) { - case 2: { - LuaTable table = args.checktable(1); - table.insert(table.length()+1,args.arg(2)); - return NONE; - } - case 3: { - LuaTable table = args.checktable(1); - int pos = args.checkint(2); - int max = table.length() + 1; - if (pos < 1 || pos > max) argerror(2, "position out of bounds: " + pos + " not between 1 and " + max); - table.insert(pos, args.arg(3)); - return NONE; - } - default: { - return error("wrong number of arguments to 'table.insert': " + args.narg() + " (must be 2 or 3)"); - } - } - } - } - - // "pack" (...) -> table - static class pack extends VarArgFunction { - public Varargs invoke(Varargs args) { - LuaValue t = tableOf(args, 1); - t.set("n", args.narg()); - return t; - } - } - - // "remove" (table [, pos]) -> removed-ele - static class remove extends VarArgFunction { - public Varargs invoke(Varargs args) { - LuaTable table = args.checktable(1); - int size = table.length(); - int pos = args.optint(2, size); - if (pos != size && (pos < 1 || pos > size + 1)) { - argerror(2, "position out of bounds: " + pos + " not between 1 and " + (size + 1)); - } - return table.remove(pos); - } - } - - // "sort" (table [, comp]) - static class sort extends VarArgFunction { - public Varargs invoke(Varargs args) { - args.checktable(1).sort( - args.isnil(2)? NIL: args.checkfunction(2)); - return NONE; - } - } - - - // "unpack", // (list [,i [,j]]) -> result1, ... - static class unpack extends VarArgFunction { - public Varargs invoke(Varargs args) { - LuaTable t = args.checktable(1); - // do not waste resource for calc rawlen if arg3 is not nil - int len = args.arg(3).isnil() ? t.length() : 0; - return t.unpack(args.optint(2, 1), args.optint(3, len)); - } - } -} diff --git a/src/core/org/luaj/vm2/lib/TableLibFunction.java b/src/core/org/luaj/vm2/lib/TableLibFunction.java deleted file mode 100644 index 5fabef7e..00000000 --- a/src/core/org/luaj/vm2/lib/TableLibFunction.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.luaj.vm2.lib; - -import org.luaj.vm2.LuaValue; - -class TableLibFunction extends LibFunction { - public LuaValue call() { - return argerror(1, "table expected, got no value"); - } -} diff --git a/src/core/org/luaj/vm2/lib/ThreeArgFunction.java b/src/core/org/luaj/vm2/lib/ThreeArgFunction.java deleted file mode 100644 index 68ceb243..00000000 --- a/src/core/org/luaj/vm2/lib/ThreeArgFunction.java +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2009 Luaj.org. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm2.lib; - -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Varargs; - -/** Abstract base class for Java function implementations that take two arguments and - * return one value. - *

    - * Subclasses need only implement {@link LuaValue#call(LuaValue,LuaValue,LuaValue)} to complete this class, - * simplifying development. - * All other uses of {@link #call()}, {@link #invoke(Varargs)},etc, - * are routed through this method by this class, - * dropping or extending arguments with {@code nil} values as required. - *

    - * If more or less than three arguments are required, - * or variable argument or variable return values, - * then use one of the related function - * {@link ZeroArgFunction}, {@link OneArgFunction}, {@link TwoArgFunction}, or {@link VarArgFunction}. - *

    - * See {@link LibFunction} for more information on implementation libraries and library functions. - * @see #call(LuaValue,LuaValue,LuaValue) - * @see LibFunction - * @see ZeroArgFunction - * @see OneArgFunction - * @see TwoArgFunction - * @see VarArgFunction - */ -abstract public class ThreeArgFunction extends LibFunction { - - abstract public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3); - - /** Default constructor */ - public ThreeArgFunction() { - } - - public final LuaValue call() { - return call(NIL, NIL, NIL); - } - - public final LuaValue call(LuaValue arg) { - return call(arg, NIL, NIL); - } - - public LuaValue call(LuaValue arg1, LuaValue arg2) { - return call(arg1, arg2, NIL); - } - - public Varargs invoke(Varargs varargs) { - return call(varargs.arg1(),varargs.arg(2),varargs.arg(3)); - } - -} diff --git a/src/core/org/luaj/vm2/lib/TwoArgFunction.java b/src/core/org/luaj/vm2/lib/TwoArgFunction.java deleted file mode 100644 index 8a97f6fb..00000000 --- a/src/core/org/luaj/vm2/lib/TwoArgFunction.java +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2009 Luaj.org. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm2.lib; - -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Varargs; - -/** Abstract base class for Java function implementations that take two arguments and - * return one value. - *

    - * Subclasses need only implement {@link LuaValue#call(LuaValue,LuaValue)} to complete this class, - * simplifying development. - * All other uses of {@link #call()}, {@link #invoke(Varargs)},etc, - * are routed through this method by this class, - * dropping or extending arguments with {@code nil} values as required. - *

    - * If more or less than two arguments are required, - * or variable argument or variable return values, - * then use one of the related function - * {@link ZeroArgFunction}, {@link OneArgFunction}, {@link ThreeArgFunction}, or {@link VarArgFunction}. - *

    - * See {@link LibFunction} for more information on implementation libraries and library functions. - * @see #call(LuaValue,LuaValue) - * @see LibFunction - * @see ZeroArgFunction - * @see OneArgFunction - * @see ThreeArgFunction - * @see VarArgFunction - */ -abstract public class TwoArgFunction extends LibFunction { - - abstract public LuaValue call(LuaValue arg1, LuaValue arg2); - - /** Default constructor */ - public TwoArgFunction() { - } - - public final LuaValue call() { - return call(NIL, NIL); - } - - public final LuaValue call(LuaValue arg) { - return call(arg, NIL); - } - - public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) { - return call(arg1, arg2); - } - - public Varargs invoke(Varargs varargs) { - return call(varargs.arg1(),varargs.arg(2)); - } - -} diff --git a/src/core/org/luaj/vm2/lib/VarArgFunction.java b/src/core/org/luaj/vm2/lib/VarArgFunction.java deleted file mode 100644 index 8e2bd614..00000000 --- a/src/core/org/luaj/vm2/lib/VarArgFunction.java +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2009 Luaj.org. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm2.lib; - -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Varargs; - -/** Abstract base class for Java function implementations that takes varaiable arguments and - * returns multiple return values. - *

    - * Subclasses need only implement {@link LuaValue#invoke(Varargs)} to complete this class, - * simplifying development. - * All other uses of {@link #call(LuaValue)}, {@link #invoke()},etc, - * are routed through this method by this class, - * converting arguments to {@link Varargs} and - * dropping or extending return values with {@code nil} values as required. - *

    - * If between one and three arguments are required, and only one return value is returned, - * {@link ZeroArgFunction}, {@link OneArgFunction}, {@link TwoArgFunction}, or {@link ThreeArgFunction}. - *

    - * See {@link LibFunction} for more information on implementation libraries and library functions. - * @see #invoke(Varargs) - * @see LibFunction - * @see ZeroArgFunction - * @see OneArgFunction - * @see TwoArgFunction - * @see ThreeArgFunction - */ -abstract public class VarArgFunction extends LibFunction { - - public VarArgFunction() { - } - - public LuaValue call() { - return invoke(NONE).arg1(); - } - - public LuaValue call(LuaValue arg) { - return invoke(arg).arg1(); - } - - public LuaValue call(LuaValue arg1, LuaValue arg2) { - return invoke(varargsOf(arg1,arg2)).arg1(); - } - - public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) { - return invoke(varargsOf(arg1,arg2,arg3)).arg1(); - } - - /** - * Subclass responsibility. - * May not have expected behavior for tail calls. - * Should not be used if: - * - function has a possibility of returning a TailcallVarargs - * @param args the arguments to the function call. - */ - public Varargs invoke(Varargs args) { - return onInvoke(args).eval(); - } - - public Varargs onInvoke(Varargs args) { - return invoke(args); - } -} diff --git a/src/core/org/luaj/vm2/lib/ZeroArgFunction.java b/src/core/org/luaj/vm2/lib/ZeroArgFunction.java deleted file mode 100644 index 06169d74..00000000 --- a/src/core/org/luaj/vm2/lib/ZeroArgFunction.java +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* -* 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.lib; - -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Varargs; - -/** Abstract base class for Java function implementations that take no arguments and - * return one value. - *

    - * Subclasses need only implement {@link LuaValue#call()} to complete this class, - * simplifying development. - * All other uses of {@link #call(LuaValue)}, {@link #invoke(Varargs)},etc, - * are routed through this method by this class. - *

    - * If one or more arguments are required, or variable argument or variable return values, - * then use one of the related function - * {@link OneArgFunction}, {@link TwoArgFunction}, {@link ThreeArgFunction}, or {@link VarArgFunction}. - *

    - * See {@link LibFunction} for more information on implementation libraries and library functions. - * @see #call() - * @see LibFunction - * @see OneArgFunction - * @see TwoArgFunction - * @see ThreeArgFunction - * @see VarArgFunction - */ -abstract public class ZeroArgFunction extends LibFunction { - - abstract public LuaValue call(); - - /** Default constructor */ - public ZeroArgFunction() { - } - - public LuaValue call(LuaValue arg) { - return call(); - } - - public LuaValue call(LuaValue arg1, LuaValue arg2) { - return call(); - } - - public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) { - return call(); - } - - public Varargs invoke(Varargs varargs) { - return call(); - } -} diff --git a/src/jme/org/luaj/vm2/lib/jme/JmeIoLib.java b/src/jme/org/luaj/vm2/lib/jme/JmeIoLib.java deleted file mode 100644 index e7cbd3c1..00000000 --- a/src/jme/org/luaj/vm2/lib/jme/JmeIoLib.java +++ /dev/null @@ -1,230 +0,0 @@ -/******************************************************************************* -* 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.lib.jme; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import javax.microedition.io.Connector; -import javax.microedition.io.StreamConnection; - -import org.luaj.vm2.Globals; -import org.luaj.vm2.LuaString; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.lib.IoLib; -import org.luaj.vm2.lib.LibFunction; - -/** - * Subclass of {@link IoLib} and therefore {@link LibFunction} which implements the lua standard {@code io} - * library for the JSE platform. - *

    - * The implementation of the is based on CLDC 1.0 and StreamConnection. - * However, seek is not supported. - *

    - * Typically, this library is included as part of a call to - * {@link org.luaj.vm2.lib.jme.JmePlatform#standardGlobals()} - *

     {@code
    - * Globals globals = JmePlatform.standardGlobals();
    - * globals.get("io").get("write").call(LuaValue.valueOf("hello, world\n"));
    - * } 
    - *

    - * For special cases where the smallest possible footprint is desired, - * a minimal set of libraries could be loaded - * directly via {@link Globals#load(LuaValue)} using code such as: - *

     {@code
    - * Globals globals = new Globals();
    - * globals.load(new JmeBaseLib());
    - * globals.load(new PackageLib());
    - * globals.load(new JmeIoLib());
    - * globals.get("io").get("write").call(LuaValue.valueOf("hello, world\n"));
    - * } 
    - *

    However, other libraries such as MathLib are not loaded in this case. - *

    - * This has been implemented to match as closely as possible the behavior in the corresponding library in C. - * @see LibFunction - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - * @see IoLib - * @see org.luaj.vm2.lib.jse.JseIoLib - * @see Lua 5.2 I/O Lib Reference - */ -public class JmeIoLib extends IoLib { - - protected File wrapStdin() throws IOException { - return new FileImpl(globals.STDIN); - } - - protected File wrapStdout() throws IOException { - return new FileImpl(globals.STDOUT); - } - - protected File wrapStderr() throws IOException { - return new FileImpl(globals.STDERR); - } - - protected File openFile( String filename, boolean readMode, boolean appendMode, boolean updateMode, boolean binaryMode ) throws IOException { - String url = "file:///" + filename; - int mode = readMode? Connector.READ: Connector.READ_WRITE; - StreamConnection conn = (StreamConnection) Connector.open( url, mode ); - File f = readMode? - new FileImpl(conn, conn.openInputStream(), null): - new FileImpl(conn, conn.openInputStream(), conn.openOutputStream()); - /* - if ( appendMode ) { - f.seek("end",0); - } else { - if ( ! readMode ) - conn.truncate(0); - } - */ - return f; - } - - private static void notimplemented() throws IOException { - throw new IOException("not implemented"); - } - - protected File openProgram(String prog, String mode) throws IOException { - notimplemented(); - return null; - } - - protected File tmpFile() throws IOException { - notimplemented(); - return null; - } - - private final class FileImpl extends File { - private final StreamConnection conn; - private final InputStream is; - private final OutputStream os; - private boolean closed = false; - private boolean nobuffer = false; - private int lookahead = -1; - private FileImpl( StreamConnection conn, InputStream is, OutputStream os ) { - this.conn = conn; - this.is = is; - this.os = os; - } - private FileImpl( InputStream i ) { - this( null, i, null ); - } - private FileImpl( OutputStream o ) { - this( null, null, o ); - } - public String tojstring() { - return "file ("+this.hashCode()+")"; - } - public boolean isstdfile() { - return conn == null; - } - public void close() throws IOException { - closed = true; - if ( conn != null ) { - conn.close(); - } - } - public void flush() throws IOException { - if ( os != null ) - os.flush(); - } - public void write(LuaString s) throws IOException { - if ( os != null ) - os.write( s.m_bytes, s.m_offset, s.m_length ); - else - notimplemented(); - if ( nobuffer ) - flush(); - } - public boolean isclosed() { - return closed; - } - public int seek(String option, int pos) throws IOException { - /* - if ( conn != null ) { - if ( "set".equals(option) ) { - conn.seek(pos); - return (int) conn.getFilePointer(); - } else if ( "end".equals(option) ) { - conn.seek(conn.length()+1+pos); - return (int) conn.length()+1; - } else { - conn.seek(conn.getFilePointer()+pos); - return (int) conn.getFilePointer(); - } - } - */ - notimplemented(); - return 0; - } - public void setvbuf(String mode, int size) { - nobuffer = "no".equals(mode); - } - - // get length remaining to read - public int remaining() throws IOException { - return -1; - } - - // peek ahead one character - public int peek() throws IOException { - if ( lookahead < 0 ) - lookahead = is.read(); - return lookahead; - } - - // return char if read, -1 if eof, throw IOException on other exception - public int read() throws IOException { - if ( lookahead >= 0 ) { - int c = lookahead; - lookahead = -1; - return c; - } - if ( is != null ) - return is.read(); - notimplemented(); - return 0; - } - - // return number of bytes read if positive, -1 if eof, throws IOException - public int read(byte[] bytes, int offset, int length) throws IOException { - int n,i=0; - if (is!=null) { - if ( length > 0 && lookahead >= 0 ) { - bytes[offset] = (byte) lookahead; - lookahead = -1; - i += 1; - } - for ( ; i 0 ? i : -1 ); - i += n; - } - } else { - notimplemented(); - } - return length; - } - } -} diff --git a/src/jme/org/luaj/vm2/lib/jme/JmePlatform.java b/src/jme/org/luaj/vm2/lib/jme/JmePlatform.java deleted file mode 100644 index c7c8bb66..00000000 --- a/src/jme/org/luaj/vm2/lib/jme/JmePlatform.java +++ /dev/null @@ -1,135 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Luaj.org. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ -package org.luaj.vm2.lib.jme; - -import org.luaj.vm2.Globals; -import org.luaj.vm2.LoadState; -import org.luaj.vm2.LuaThread; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.compiler.LuaC; -import org.luaj.vm2.lib.BaseLib; -import org.luaj.vm2.lib.Bit32Lib; -import org.luaj.vm2.lib.CoroutineLib; -import org.luaj.vm2.lib.DebugLib; -import org.luaj.vm2.lib.MathLib; -import org.luaj.vm2.lib.OsLib; -import org.luaj.vm2.lib.PackageLib; -import org.luaj.vm2.lib.ResourceFinder; -import org.luaj.vm2.lib.StringLib; -import org.luaj.vm2.lib.TableLib; - -/** The {@link org.luaj.vm2.lib.jme.JmePlatform} class is a convenience class to standardize - * how globals tables are initialized for the JME platform. - *

    - * The JME platform, being limited, cannot implement all libraries in all aspects. The main limitations are - *

    - *

    - * It is used to allocate either a set of standard globals using - * {@link #standardGlobals()} or debug globals using {@link #debugGlobals()} - *

    - * A simple example of initializing globals and using them from Java is: - *

     {@code
    - * Globals global = JmePlatform.standardGlobals();
    - * global.get("print").call(LuaValue.valueOf("hello, world"));
    - * } 
    - *

    - * Once globals are created, a simple way to load and run a script is: - *

     {@code
    - * LoadState.load( getClass().getResourceAsStream("main.lua"), "main.lua", globals ).call();
    - * } 
    - *

    - * although {@code require} could also be used: - *

     {@code
    - * globals.get("require").call(LuaValue.valueOf("main"));
    - * } 
    - * For this to succeed, the file "main.lua" must be a resource in the class path. - * See {@link BaseLib} for details on finding scripts using {@link ResourceFinder}. - *

    - * The standard globals will contain all standard libraries in their JME flavors: - *

    - * In addition, the {@link LuaC} compiler is installed so lua files may be loaded in their source form. - *

    - * The debug globals are simply the standard globals plus the {@code debug} library {@link DebugLib}. - *

    - *

    - * The class ensures that initialization is done in the correct order. - * - * @see Globals - * @see org.luaj.vm2.lib.jse.JsePlatform - */ -public class JmePlatform { - - /** - * Create a standard set of globals for JME including all the libraries. - * - * @return Table of globals initialized with the standard JME libraries - * @see #debugGlobals() - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - */ - public static Globals standardGlobals() { - Globals globals = new Globals(); - globals.load(new BaseLib()); - globals.load(new PackageLib()); - globals.load(new Bit32Lib()); - globals.load(new OsLib()); - globals.load(new MathLib()); - globals.load(new TableLib()); - globals.load(new StringLib()); - globals.load(new CoroutineLib()); - globals.load(new JmeIoLib()); - LoadState.install(globals); - LuaC.install(globals); - return globals; - } - - /** Create standard globals including the {@link DebugLib} library. - * - * @return Table of globals initialized with the standard JSE and debug libraries - * @see #standardGlobals() - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - * @see DebugLib - */ - public static Globals debugGlobals() { - Globals globals = standardGlobals(); - globals.load(new DebugLib()); - return globals; - } -} diff --git a/src/jse/org/luaj/vm2/lib/jse/CoerceJavaToLua.java b/src/jse/org/luaj/vm2/lib/jse/CoerceJavaToLua.java deleted file mode 100644 index 177f9acf..00000000 --- a/src/jse/org/luaj/vm2/lib/jse/CoerceJavaToLua.java +++ /dev/null @@ -1,196 +0,0 @@ -/******************************************************************************* -* 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.lib.jse; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.luaj.vm2.LuaDouble; -import org.luaj.vm2.LuaInteger; -import org.luaj.vm2.LuaString; -import org.luaj.vm2.LuaUserdata; -import org.luaj.vm2.LuaValue; - -/** - * Helper class to coerce values from Java to lua within the luajava library. - *

    - * This class is primarily used by the {@link org.luaj.vm2.lib.jse.LuajavaLib}, - * but can also be used directly when working with Java/lua bindings. - *

    - * To coerce scalar types, the various, generally the {@code valueOf(type)} methods - * on {@link LuaValue} may be used: - *

    - *

    - * To coerce arrays of objects and lists, the {@code listOf(..)} and {@code tableOf(...)} methods - * on {@link LuaValue} may be used: - *

    - * The method {@link CoerceJavaToLua#coerce(Object)} looks as the type and dimesioning - * of the argument and tries to guess the best fit for corrsponding lua scalar, - * table, or table of tables. - * - * @see CoerceJavaToLua#coerce(Object) - * @see org.luaj.vm2.lib.jse.LuajavaLib - */ -public class CoerceJavaToLua { - - static interface Coercion { - public LuaValue coerce( Object javaValue ); - }; - - private static final class BoolCoercion implements Coercion { - public LuaValue coerce( Object javaValue ) { - Boolean b = (Boolean) javaValue; - return b.booleanValue()? LuaValue.TRUE: LuaValue.FALSE; - } - } - - private static final class IntCoercion implements Coercion { - public LuaValue coerce( Object javaValue ) { - Number n = (Number) javaValue; - return LuaInteger.valueOf( n.intValue() ); - } - } - - private static final class CharCoercion implements Coercion { - public LuaValue coerce( Object javaValue ) { - Character c = (Character) javaValue; - return LuaInteger.valueOf( c.charValue() ); - } - } - - private static final class DoubleCoercion implements Coercion { - public LuaValue coerce( Object javaValue ) { - Number n = (Number) javaValue; - return LuaDouble.valueOf( n.doubleValue() ); - } - } - - private static final class StringCoercion implements Coercion { - public LuaValue coerce( Object javaValue ) { - return LuaString.valueOf( javaValue.toString() ); - } - } - - private static final class BytesCoercion implements Coercion { - public LuaValue coerce( Object javaValue ) { - return LuaValue.valueOf((byte[]) javaValue); - } - } - - private static final class ClassCoercion implements Coercion { - public LuaValue coerce( Object javaValue ) { - return JavaClass.forClass((Class) javaValue); - } - } - - private static final class InstanceCoercion implements Coercion { - public LuaValue coerce(Object javaValue) { - return new JavaInstance(javaValue); - } - } - - private static final class ArrayCoercion implements Coercion { - public LuaValue coerce(Object javaValue) { - // should be userdata? - return new JavaArray(javaValue); - } - } - - private static final class LuaCoercion implements Coercion { - public LuaValue coerce( Object javaValue ) { - return (LuaValue) javaValue; - } - } - - - static final Map COERCIONS = Collections.synchronizedMap(new HashMap()); - - static { - Coercion boolCoercion = new BoolCoercion() ; - Coercion intCoercion = new IntCoercion() ; - Coercion charCoercion = new CharCoercion() ; - Coercion doubleCoercion = new DoubleCoercion() ; - Coercion stringCoercion = new StringCoercion() ; - Coercion bytesCoercion = new BytesCoercion() ; - Coercion classCoercion = new ClassCoercion() ; - COERCIONS.put( Boolean.class, boolCoercion ); - COERCIONS.put( Byte.class, intCoercion ); - COERCIONS.put( Character.class, charCoercion ); - COERCIONS.put( Short.class, intCoercion ); - COERCIONS.put( Integer.class, intCoercion ); - COERCIONS.put( Long.class, doubleCoercion ); - COERCIONS.put( Float.class, doubleCoercion ); - COERCIONS.put( Double.class, doubleCoercion ); - COERCIONS.put( String.class, stringCoercion ); - COERCIONS.put( byte[].class, bytesCoercion ); - COERCIONS.put( Class.class, classCoercion ); - } - - /** - * Coerse a Java object to a corresponding lua value. - *

    - * Integral types {@code boolean}, {@code byte}, {@code char}, and {@code int} - * will become {@link LuaInteger}; - * {@code long}, {@code float}, and {@code double} will become {@link LuaDouble}; - * {@code String} and {@code byte[]} will become {@link LuaString}; - * types inheriting from {@link LuaValue} will be returned without coercion; - * other types will become {@link LuaUserdata}. - * @param o Java object needing conversion - * @return {@link LuaValue} corresponding to the supplied Java value. - * @see LuaValue - * @see LuaInteger - * @see LuaDouble - * @see LuaString - * @see LuaUserdata - */ - public static LuaValue coerce(Object o) { - if ( o == null ) - return LuaValue.NIL; - Class clazz = o.getClass(); - Coercion c = (Coercion) COERCIONS.get( clazz ); - if ( c == null ) { - c = clazz.isArray()? arrayCoercion: - o instanceof LuaValue ? luaCoercion: - instanceCoercion; - COERCIONS.put( clazz, c ); - } - return c.coerce(o); - } - - static final Coercion instanceCoercion = new InstanceCoercion(); - - static final Coercion arrayCoercion = new ArrayCoercion(); - - static final Coercion luaCoercion = new LuaCoercion() ; -} diff --git a/src/jse/org/luaj/vm2/lib/jse/CoerceLuaToJava.java b/src/jse/org/luaj/vm2/lib/jse/CoerceLuaToJava.java deleted file mode 100644 index c658aacc..00000000 --- a/src/jse/org/luaj/vm2/lib/jse/CoerceLuaToJava.java +++ /dev/null @@ -1,372 +0,0 @@ -/******************************************************************************* -* 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.lib.jse; - -import java.lang.reflect.Array; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.luaj.vm2.LuaString; -import org.luaj.vm2.LuaTable; -import org.luaj.vm2.LuaValue; - -/** - * Helper class to coerce values from lua to Java within the luajava library. - *

    - * This class is primarily used by the {@link org.luaj.vm2.lib.jse.LuajavaLib}, - * but can also be used directly when working with Java/lua bindings. - *

    - * To coerce to specific Java values, generally the {@code toType()} methods - * on {@link LuaValue} may be used: - *

    - *

    - * For data in lua tables, the various methods on {@link LuaTable} can be used directly - * to convert data to something more useful. - * - * @see org.luaj.vm2.lib.jse.LuajavaLib - * @see CoerceJavaToLua - */ -public class CoerceLuaToJava { - - static int SCORE_NULL_VALUE = 0x10; - static int SCORE_WRONG_TYPE = 0x100; - static int SCORE_UNCOERCIBLE = 0x10000; - - static interface Coercion { - public int score( LuaValue value ); - public Object coerce( LuaValue value ); - }; - - /** - * Coerce a LuaValue value to a specified java class - * @param value LuaValue to coerce - * @param clazz Class to coerce into - * @return Object of type clazz (or a subclass) with the corresponding value. - */ - public static Object coerce(LuaValue value, Class clazz) { - return getCoercion(clazz).coerce(value); - } - - static final Map COERCIONS = Collections.synchronizedMap(new HashMap()); - - static final class BoolCoercion implements Coercion { - public String toString() { - return "BoolCoercion()"; - } - public int score( LuaValue value ) { - switch ( value.type() ) { - case LuaValue.TBOOLEAN: - return 0; - } - return 1; - } - - public Object coerce(LuaValue value) { - return value.toboolean()? Boolean.TRUE: Boolean.FALSE; - } - } - - static final class NumericCoercion implements Coercion { - static final int TARGET_TYPE_BYTE = 0; - static final int TARGET_TYPE_CHAR = 1; - static final int TARGET_TYPE_SHORT = 2; - static final int TARGET_TYPE_INT = 3; - static final int TARGET_TYPE_LONG = 4; - static final int TARGET_TYPE_FLOAT = 5; - static final int TARGET_TYPE_DOUBLE = 6; - static final String[] TYPE_NAMES = { "byte", "char", "short", "int", "long", "float", "double" }; - final int targetType; - public String toString() { - return "NumericCoercion("+TYPE_NAMES[targetType]+")"; - } - NumericCoercion(int targetType) { - this.targetType = targetType; - } - public int score( LuaValue value ) { - int fromStringPenalty = 0; - if ( value.type() == LuaValue.TSTRING ) { - value = value.tonumber(); - if ( value.isnil() ) { - return SCORE_UNCOERCIBLE; - } - fromStringPenalty = 4; - } - if ( value.isint() ) { - switch ( targetType ) { - case TARGET_TYPE_BYTE: { - int i = value.toint(); - return fromStringPenalty + ((i==(byte)i)? 0: SCORE_WRONG_TYPE); - } - case TARGET_TYPE_CHAR: { - int i = value.toint(); - return fromStringPenalty + ((i==(byte)i)? 1: (i==(char)i)? 0: SCORE_WRONG_TYPE); - } - case TARGET_TYPE_SHORT: { - int i = value.toint(); - return fromStringPenalty + - ((i==(byte)i)? 1: (i==(short)i)? 0: SCORE_WRONG_TYPE); - } - case TARGET_TYPE_INT: { - int i = value.toint(); - return fromStringPenalty + - ((i==(byte)i)? 2: ((i==(char)i) || (i==(short)i))? 1: 0); - } - case TARGET_TYPE_FLOAT: return fromStringPenalty + 1; - case TARGET_TYPE_LONG: return fromStringPenalty + 1; - case TARGET_TYPE_DOUBLE: return fromStringPenalty + 2; - default: return SCORE_WRONG_TYPE; - } - } else if ( value.isnumber() ) { - switch ( targetType ) { - case TARGET_TYPE_BYTE: return SCORE_WRONG_TYPE; - case TARGET_TYPE_CHAR: return SCORE_WRONG_TYPE; - case TARGET_TYPE_SHORT: return SCORE_WRONG_TYPE; - case TARGET_TYPE_INT: return SCORE_WRONG_TYPE; - case TARGET_TYPE_LONG: { - double d = value.todouble(); - return fromStringPenalty + ((d==(long)d)? 0: SCORE_WRONG_TYPE); - } - case TARGET_TYPE_FLOAT: { - double d = value.todouble(); - return fromStringPenalty + ((d==(float)d)? 0: SCORE_WRONG_TYPE); - } - case TARGET_TYPE_DOUBLE: { - double d = value.todouble(); - return fromStringPenalty + (((d==(long)d) || (d==(float)d))? 1: 0); - } - default: return SCORE_WRONG_TYPE; - } - } else { - return SCORE_UNCOERCIBLE; - } - } - - public Object coerce(LuaValue value) { - switch ( targetType ) { - case TARGET_TYPE_BYTE: return new Byte( (byte) value.toint() ); - case TARGET_TYPE_CHAR: return new Character( (char) value.toint() ); - case TARGET_TYPE_SHORT: return new Short( (short) value.toint() ); - case TARGET_TYPE_INT: return new Integer( (int) value.toint() ); - case TARGET_TYPE_LONG: return new Long( (long) value.todouble() ); - case TARGET_TYPE_FLOAT: return new Float( (float) value.todouble() ); - case TARGET_TYPE_DOUBLE: return new Double( (double) value.todouble() ); - default: return null; - } - } - } - - static final class StringCoercion implements Coercion { - public static final int TARGET_TYPE_STRING = 0; - public static final int TARGET_TYPE_BYTES = 1; - final int targetType; - public StringCoercion(int targetType) { - this.targetType = targetType; - } - public String toString() { - return "StringCoercion("+(targetType==TARGET_TYPE_STRING? "String": "byte[]")+")"; - } - public int score(LuaValue value) { - switch ( value.type() ) { - case LuaValue.TSTRING: - return value.checkstring().isValidUtf8()? - (targetType==TARGET_TYPE_STRING? 0: 1): - (targetType==TARGET_TYPE_BYTES? 0: SCORE_WRONG_TYPE); - case LuaValue.TNIL: - return SCORE_NULL_VALUE; - default: - return targetType == TARGET_TYPE_STRING? SCORE_WRONG_TYPE: SCORE_UNCOERCIBLE; - } - } - public Object coerce(LuaValue value) { - if ( value.isnil() ) - return null; - if ( targetType == TARGET_TYPE_STRING ) - return value.tojstring(); - LuaString s = value.checkstring(); - byte[] b = new byte[s.m_length]; - s.copyInto(0, b, 0, b.length); - return b; - } - } - - static final class ArrayCoercion implements Coercion { - final Class componentType; - final Coercion componentCoercion; - public ArrayCoercion(Class componentType) { - this.componentType = componentType; - this.componentCoercion = getCoercion(componentType); - } - public String toString() { - return "ArrayCoercion("+componentType.getName()+")"; - } - public int score(LuaValue value) { - switch ( value.type() ) { - case LuaValue.TTABLE: - return value.length()==0? 0: componentCoercion.score( value.get(1) ); - case LuaValue.TUSERDATA: - return inheritanceLevels( componentType, value.touserdata().getClass().getComponentType() ); - case LuaValue.TNIL: - return SCORE_NULL_VALUE; - default: - return SCORE_UNCOERCIBLE; - } - } - public Object coerce(LuaValue value) { - switch ( value.type() ) { - case LuaValue.TTABLE: { - int n = value.length(); - Object a = Array.newInstance(componentType, n); - for ( int i=0; i - * Can get elements by their integer key index, as well as the length. - *

    - * This class is not used directly. - * It is returned by calls to {@link CoerceJavaToLua#coerce(Object)} - * when an array is supplied. - * @see CoerceJavaToLua - * @see CoerceLuaToJava - */ -class JavaArray extends LuaUserdata { - - private static final class LenFunction extends OneArgFunction { - public LuaValue call(LuaValue u) { - return LuaValue.valueOf(Array.getLength(((LuaUserdata)u).m_instance)); - } - } - - static final LuaValue LENGTH = valueOf("length"); - - static final LuaTable array_metatable; - static { - array_metatable = new LuaTable(); - array_metatable.rawset(LuaValue.LEN, new LenFunction()); - } - - JavaArray(Object instance) { - super(instance); - setmetatable(array_metatable); - } - - public LuaValue get(LuaValue key) { - if ( key.equals(LENGTH) ) - return valueOf(Array.getLength(m_instance)); - if ( key.isint() ) { - int i = key.toint() - 1; - return i>=0 && i=0 && i - * Will respond to get() and set() by returning field values, or java methods. - *

    - * This class is not used directly. - * It is returned by calls to {@link CoerceJavaToLua#coerce(Object)} - * when a Class is supplied. - * @see CoerceJavaToLua - * @see CoerceLuaToJava - */ -class JavaClass extends JavaInstance implements CoerceJavaToLua.Coercion { - - static final Map classes = Collections.synchronizedMap(new HashMap()); - - static final LuaValue NEW = valueOf("new"); - - Map fields; - Map methods; - Map innerclasses; - - static JavaClass forClass(Class c) { - JavaClass j = (JavaClass) classes.get(c); - if ( j == null ) - classes.put( c, j = new JavaClass(c) ); - return j; - } - - JavaClass(Class c) { - super(c); - this.jclass = this; - } - - public LuaValue coerce(Object javaValue) { - return this; - } - - Field getField(LuaValue key) { - if ( fields == null ) { - Map m = new HashMap(); - Field[] f = ((Class)m_instance).getFields(); - for ( int i=0; i - * May be called with arguments to return a JavaInstance - * created by calling the constructor. - *

    - * This class is not used directly. - * It is returned by calls to {@link JavaClass#new(LuaValue key)} - * when the value of key is "new". - * @see CoerceJavaToLua - * @see CoerceLuaToJava - */ -class JavaConstructor extends JavaMember { - - static final Map constructors = Collections.synchronizedMap(new HashMap()); - - static JavaConstructor forConstructor(Constructor c) { - JavaConstructor j = (JavaConstructor) constructors.get(c); - if ( j == null ) - constructors.put( c, j = new JavaConstructor(c) ); - return j; - } - - public static LuaValue forConstructors(JavaConstructor[] array) { - return new Overload(array); - } - - final Constructor constructor; - - private JavaConstructor(Constructor c) { - super( c.getParameterTypes(), c.getModifiers() ); - this.constructor = c; - } - - public Varargs invoke(Varargs args) { - Object[] a = convertArgs(args); - try { - return CoerceJavaToLua.coerce( constructor.newInstance(a) ); - } catch (InvocationTargetException e) { - throw new LuaError(e.getTargetException()); - } catch (Exception e) { - return LuaValue.error("coercion error "+e); - } - } - - /** - * LuaValue that represents an overloaded Java constructor. - *

    - * On invocation, will pick the best method from the list, and invoke it. - *

    - * This class is not used directly. - * It is returned by calls to calls to {@link JavaClass#get(LuaValue key)} - * when key is "new" and there is more than one public constructor. - */ - static class Overload extends VarArgFunction { - final JavaConstructor[] constructors; - public Overload(JavaConstructor[] c) { - this.constructors = c; - } - - public Varargs invoke(Varargs args) { - JavaConstructor best = null; - int score = CoerceLuaToJava.SCORE_UNCOERCIBLE; - for ( int i=0; i - * Will respond to get() and set() by returning field values or methods. - *

    - * This class is not used directly. - * It is returned by calls to {@link CoerceJavaToLua#coerce(Object)} - * when a subclass of Object is supplied. - * @see CoerceJavaToLua - * @see CoerceLuaToJava - */ -class JavaInstance extends LuaUserdata { - - JavaClass jclass; - - JavaInstance(Object instance) { - super(instance); - } - - public LuaValue get(LuaValue key) { - if ( jclass == null ) - jclass = JavaClass.forClass(m_instance.getClass()); - Field f = jclass.getField(key); - if ( f != null ) - try { - return CoerceJavaToLua.coerce(f.get(m_instance)); - } catch (Exception e) { - throw new LuaError(e); - } - LuaValue m = jclass.getMethod(key); - if ( m != null ) - return m; - Class c = jclass.getInnerClass(key); - if ( c != null ) - return JavaClass.forClass(c); - return super.get(key); - } - - public void set(LuaValue key, LuaValue value) { - if ( jclass == null ) - jclass = JavaClass.forClass(m_instance.getClass()); - Field f = jclass.getField(key); - if ( f != null ) - try { - f.set(m_instance, CoerceLuaToJava.coerce(value, f.getType())); - return; - } catch (Exception e) { - throw new LuaError(e); - } - super.set(key, value); - } - -} diff --git a/src/jse/org/luaj/vm2/lib/jse/JavaMember.java b/src/jse/org/luaj/vm2/lib/jse/JavaMember.java deleted file mode 100644 index e4e9b7ed..00000000 --- a/src/jse/org/luaj/vm2/lib/jse/JavaMember.java +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* -* Copyright (c) 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.lib.jse; - -import org.luaj.vm2.Varargs; -import org.luaj.vm2.lib.VarArgFunction; -import org.luaj.vm2.lib.jse.CoerceLuaToJava.Coercion; - -/** - * Java method or constructor. - *

    - * Primarily handles argument coercion for parameter lists including scoring of compatibility and - * java varargs handling. - *

    - * This class is not used directly. - * It is an abstract base class for {@link JavaConstructor} and {@link JavaMethod}. - * @see JavaConstructor - * @see JavaMethod - * @see CoerceJavaToLua - * @see CoerceLuaToJava - */ -abstract -class JavaMember extends VarArgFunction { - - static final int METHOD_MODIFIERS_VARARGS = 0x80; - - final Coercion[] fixedargs; - final Coercion varargs; - - protected JavaMember(Class[] params, int modifiers) { - boolean isvarargs = ((modifiers & METHOD_MODIFIERS_VARARGS) != 0); - fixedargs = new CoerceLuaToJava.Coercion[isvarargs? params.length-1: params.length]; - for ( int i=0; ifixedargs.length? CoerceLuaToJava.SCORE_WRONG_TYPE * (n-fixedargs.length): 0; - for ( int j=0; j - * Can be invoked via call(LuaValue...) and related methods. - *

    - * This class is not used directly. - * It is returned by calls to calls to {@link JavaInstance#get(LuaValue key)} - * when a method is named. - * @see CoerceJavaToLua - * @see CoerceLuaToJava - */ -class JavaMethod extends JavaMember { - - static final Map methods = Collections.synchronizedMap(new HashMap()); - - static JavaMethod forMethod(Method m) { - JavaMethod j = (JavaMethod) methods.get(m); - if ( j == null ) - methods.put( m, j = new JavaMethod(m) ); - return j; - } - - static LuaFunction forMethods(JavaMethod[] m) { - return new Overload(m); - } - - final Method method; - - private JavaMethod(Method m) { - super( m.getParameterTypes(), m.getModifiers() ); - this.method = m; - try { - if (!m.isAccessible()) - m.setAccessible(true); - } catch (SecurityException s) { - } - } - - public LuaValue call() { - return error("method cannot be called without instance"); - } - - public LuaValue call(LuaValue arg) { - return invokeMethod(arg.checkuserdata(), LuaValue.NONE); - } - - public LuaValue call(LuaValue arg1, LuaValue arg2) { - return invokeMethod(arg1.checkuserdata(), arg2); - } - - public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) { - return invokeMethod(arg1.checkuserdata(), LuaValue.varargsOf(arg2, arg3)); - } - - public Varargs invoke(Varargs args) { - return invokeMethod(args.checkuserdata(1), args.subargs(2)); - } - - LuaValue invokeMethod(Object instance, Varargs args) { - Object[] a = convertArgs(args); - try { - return CoerceJavaToLua.coerce( method.invoke(instance, a) ); - } catch (InvocationTargetException e) { - throw new LuaError(e.getTargetException()); - } catch (Exception e) { - return LuaValue.error("coercion error "+e); - } - } - - /** - * LuaValue that represents an overloaded Java method. - *

    - * On invocation, will pick the best method from the list, and invoke it. - *

    - * This class is not used directly. - * It is returned by calls to calls to {@link JavaInstance#get(LuaValue key)} - * when an overloaded method is named. - */ - static class Overload extends LuaFunction { - - final JavaMethod[] methods; - - Overload(JavaMethod[] methods) { - this.methods = methods; - } - - public LuaValue call() { - return error("method cannot be called without instance"); - } - - public LuaValue call(LuaValue arg) { - return invokeBestMethod(arg.checkuserdata(), LuaValue.NONE); - } - - public LuaValue call(LuaValue arg1, LuaValue arg2) { - return invokeBestMethod(arg1.checkuserdata(), arg2); - } - - public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) { - return invokeBestMethod(arg1.checkuserdata(), LuaValue.varargsOf(arg2, arg3)); - } - - public Varargs invoke(Varargs args) { - return invokeBestMethod(args.checkuserdata(1), args.subargs(2)); - } - - private LuaValue invokeBestMethod(Object instance, Varargs args) { - JavaMethod best = null; - int score = CoerceLuaToJava.SCORE_UNCOERCIBLE; - for ( int i=0; i - * Since JME has no file system by default, {@link BaseLib} implements - * {@link ResourceFinder} using {@link Class#getResource(String)}. - * The {@link org.luaj.vm2.lib.jse.JseBaseLib} implements {@link Globals#finder} by scanning the current directory - * first, then falling back to {@link Class#getResource(String)} if that fails. - * Otherwise, the behavior is the same as that of {@link BaseLib}. - *

    - * Typically, this library is included as part of a call to - * {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} - *

     {@code
    - * Globals globals = JsePlatform.standardGlobals();
    - * globals.get("print").call(LuaValue.valueOf("hello, world"));
    - * } 
    - *

    - * For special cases where the smallest possible footprint is desired, - * a minimal set of libraries could be loaded - * directly via {@link Globals#load(LuaValue)} using code such as: - *

     {@code
    - * Globals globals = new Globals();
    - * globals.load(new JseBaseLib());
    - * globals.get("print").call(LuaValue.valueOf("hello, world"));
    - * } 
    - *

    However, other libraries such as PackageLib are not loaded in this case. - *

    - * This is a direct port of the corresponding library in C. - * @see Globals - * @see BaseLib - * @see ResourceFinder - * @see Globals#finder - * @see LibFunction - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - * @see Lua 5.2 Base Lib Reference - */ - -public class JseBaseLib extends org.luaj.vm2.lib.BaseLib { - - - /** Perform one-time initialization on the library by creating a table - * containing the library functions, adding that table to the supplied environment, - * adding the table to package.loaded, and returning table as the return value. - *

    Specifically, extend the library loading to set the default value for {@link Globals#STDIN} - * @param modname the module name supplied if this is loaded via 'require'. - * @param env the environment to load into, which must be a Globals instance. - */ - public LuaValue call(LuaValue modname, LuaValue env) { - super.call(modname, env); - env.checkglobals().STDIN = System.in; - return env; - } - - - /** - * Try to open a file in the current working directory, - * or fall back to base opener if not found. - * - * This implementation attempts to open the file using new File(filename). - * It falls back to the base implementation that looks it up as a resource - * in the class path if not found as a plain file. - * - * @see org.luaj.vm2.lib.BaseLib - * @see org.luaj.vm2.lib.ResourceFinder - * - * @param filename - * @return InputStream, or null if not found. - */ - public InputStream findResource(String filename) { - File f = new File(filename); - if ( ! f.exists() ) - return super.findResource(filename); - try { - return new BufferedInputStream(new FileInputStream(f)); - } catch ( IOException ioe ) { - return null; - } - } -} - diff --git a/src/jse/org/luaj/vm2/lib/jse/JseIoLib.java b/src/jse/org/luaj/vm2/lib/jse/JseIoLib.java deleted file mode 100644 index cfaf6f4a..00000000 --- a/src/jse/org/luaj/vm2/lib/jse/JseIoLib.java +++ /dev/null @@ -1,343 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2009 Luaj.org. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm2.lib.jse; - -import java.io.BufferedInputStream; -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintStream; -import java.io.RandomAccessFile; - -import org.luaj.vm2.Globals; -import org.luaj.vm2.LuaError; -import org.luaj.vm2.LuaString; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.lib.IoLib; -import org.luaj.vm2.lib.LibFunction; - -/** - * Subclass of {@link IoLib} and therefore {@link LibFunction} which implements the lua standard {@code io} - * library for the JSE platform. - *

    - * It uses RandomAccessFile to implement seek on files. - *

    - * Typically, this library is included as part of a call to - * {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} - *

     {@code
    - * Globals globals = JsePlatform.standardGlobals();
    - * globals.get("io").get("write").call(LuaValue.valueOf("hello, world\n"));
    - * } 
    - *

    - * For special cases where the smallest possible footprint is desired, - * a minimal set of libraries could be loaded - * directly via {@link Globals#load(LuaValue)} using code such as: - *

     {@code
    - * Globals globals = new Globals();
    - * globals.load(new JseBaseLib());
    - * globals.load(new PackageLib());
    - * globals.load(new JseIoLib());
    - * globals.get("io").get("write").call(LuaValue.valueOf("hello, world\n"));
    - * } 
    - *

    However, other libraries such as MathLib are not loaded in this case. - *

    - * This has been implemented to match as closely as possible the behavior in the corresponding library in C. - * @see LibFunction - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - * @see IoLib - * @see org.luaj.vm2.lib.jme.JmeIoLib - * @see Lua 5.2 I/O Lib Reference - */ -public class JseIoLib extends IoLib { - - protected File wrapStdin() throws IOException { - return new StdinFile(); - } - - protected File wrapStdout() throws IOException { - return new StdoutFile(FTYPE_STDOUT); - } - - protected File wrapStderr() throws IOException { - return new StdoutFile(FTYPE_STDERR); - } - - protected File openFile( String filename, boolean readMode, boolean appendMode, boolean updateMode, boolean binaryMode ) throws IOException { - RandomAccessFile f = new RandomAccessFile(filename,readMode? "r": "rw"); - if ( appendMode ) { - f.seek(f.length()); - } else { - if ( ! readMode ) - f.setLength(0); - } - return new FileImpl( f ); - } - - protected File openProgram(String prog, String mode) throws IOException { - final Process p = Runtime.getRuntime().exec(prog); - return "w".equals(mode)? - new FileImpl( p.getOutputStream() ): - new FileImpl( p.getInputStream() ); - } - - protected File tmpFile() throws IOException { - java.io.File f = java.io.File.createTempFile(".luaj","bin"); - f.deleteOnExit(); - return new FileImpl( new RandomAccessFile(f,"rw") ); - } - - private static void notimplemented() { - throw new LuaError("not implemented"); - } - - - private final class FileImpl extends File { - private final RandomAccessFile file; - private final InputStream is; - private final OutputStream os; - private boolean closed = false; - private boolean nobuffer = false; - private FileImpl( RandomAccessFile file, InputStream is, OutputStream os ) { - this.file = file; - this.is = is!=null? is.markSupported()? is: new BufferedInputStream(is): null; - this.os = os; - } - private FileImpl( RandomAccessFile f ) { - this( f, null, null ); - } - private FileImpl( InputStream i ) { - this( null, i, null ); - } - private FileImpl( OutputStream o ) { - this( null, null, o ); - } - public String tojstring() { - return "file (" + (this.closed ? "closed" : String.valueOf(this.hashCode())) + ")"; - } - public boolean isstdfile() { - return file == null; - } - public void close() throws IOException { - closed = true; - if ( file != null ) { - file.close(); - } - } - public void flush() throws IOException { - if ( os != null ) - os.flush(); - } - public void write(LuaString s) throws IOException { - if ( os != null ) - os.write( s.m_bytes, s.m_offset, s.m_length ); - else if ( file != null ) - file.write( s.m_bytes, s.m_offset, s.m_length ); - else - notimplemented(); - if ( nobuffer ) - flush(); - } - public boolean isclosed() { - return closed; - } - public int seek(String option, int pos) throws IOException { - if ( file != null ) { - if ( "set".equals(option) ) { - file.seek(pos); - } else if ( "end".equals(option) ) { - file.seek(file.length()+pos); - } else { - file.seek(file.getFilePointer()+pos); - } - return (int) file.getFilePointer(); - } - notimplemented(); - return 0; - } - public void setvbuf(String mode, int size) { - nobuffer = "no".equals(mode); - } - - // get length remaining to read - public int remaining() throws IOException { - return file!=null? (int) (file.length()-file.getFilePointer()): -1; - } - - // peek ahead one character - public int peek() throws IOException { - if ( is != null ) { - is.mark(1); - int c = is.read(); - is.reset(); - return c; - } else if ( file != null ) { - long fp = file.getFilePointer(); - int c = file.read(); - file.seek(fp); - return c; - } - notimplemented(); - return 0; - } - - // return char if read, -1 if eof, throw IOException on other exception - public int read() throws IOException { - if ( is != null ) - return is.read(); - else if ( file != null ) { - return file.read(); - } - notimplemented(); - return 0; - } - - // return number of bytes read if positive, -1 if eof, throws IOException - public int read(byte[] bytes, int offset, int length) throws IOException { - if (file!=null) { - return file.read(bytes, offset, length); - } else if (is!=null) { - return is.read(bytes, offset, length); - } else { - notimplemented(); - } - return length; - } - } - - private final class StdoutFile extends File { - private final int file_type; - - private StdoutFile(int file_type) { - this.file_type = file_type; - } - - public String tojstring() { - return "file ("+this.hashCode()+")"; - } - - private final PrintStream getPrintStream() { - return file_type == FTYPE_STDERR? - globals.STDERR: - globals.STDOUT; - } - - public void write(LuaString string) throws IOException { - getPrintStream().write(string.m_bytes, string.m_offset, string.m_length); - } - - public void flush() throws IOException { - getPrintStream().flush(); - } - - public boolean isstdfile() { - return true; - } - - public void close() throws IOException { - // do not close std files. - } - - public boolean isclosed() { - return false; - } - - public int seek(String option, int bytecount) throws IOException { - return 0; - } - - public void setvbuf(String mode, int size) { - } - - public int remaining() throws IOException { - return 0; - } - - public int peek() throws IOException, EOFException { - return 0; - } - - public int read() throws IOException, EOFException { - return 0; - } - - public int read(byte[] bytes, int offset, int length) - throws IOException { - return 0; - } - } - - private final class StdinFile extends File { - private StdinFile() { - } - - public String tojstring() { - return "file ("+this.hashCode()+")"; - } - - public void write(LuaString string) throws IOException { - } - - public void flush() throws IOException { - } - - public boolean isstdfile() { - return true; - } - - public void close() throws IOException { - // do not close std files. - } - - public boolean isclosed() { - return false; - } - - public int seek(String option, int bytecount) throws IOException { - return 0; - } - - public void setvbuf(String mode, int size) { - } - - public int remaining() throws IOException { - return -1; - } - - public int peek() throws IOException, EOFException { - globals.STDIN.mark(1); - int c = globals.STDIN.read(); - globals.STDIN.reset(); - return c; - } - - public int read() throws IOException, EOFException { - return globals.STDIN.read(); - } - - public int read(byte[] bytes, int offset, int length) - throws IOException { - return globals.STDIN.read(bytes, offset, length); - } - } -} diff --git a/src/jse/org/luaj/vm2/lib/jse/JseMathLib.java b/src/jse/org/luaj/vm2/lib/jse/JseMathLib.java deleted file mode 100644 index 87f133a1..00000000 --- a/src/jse/org/luaj/vm2/lib/jse/JseMathLib.java +++ /dev/null @@ -1,120 +0,0 @@ -/******************************************************************************* -* 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.lib.jse; - -import org.luaj.vm2.Globals; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.lib.LibFunction; -import org.luaj.vm2.lib.TwoArgFunction; - -/** - * Subclass of {@link LibFunction} which implements the lua standard {@code math} - * library. - *

    - * It contains all lua math functions, including those not available on the JME platform. - * See {@link org.luaj.vm2.lib.MathLib} for the exception list. - *

    - * Typically, this library is included as part of a call to - * {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} - *

     {@code
    - * Globals globals = JsePlatform.standardGlobals();
    - * System.out.println( globals.get("math").get("sqrt").call( LuaValue.valueOf(2) ) );
    - * } 
    - *

    - * For special cases where the smallest possible footprint is desired, - * a minimal set of libraries could be loaded - * directly via {@link Globals#load(LuaValue)} using code such as: - *

     {@code
    - * Globals globals = new Globals();
    - * globals.load(new JseBaseLib());
    - * globals.load(new PackageLib());
    - * globals.load(new JseMathLib());
    - * System.out.println( globals.get("math").get("sqrt").call( LuaValue.valueOf(2) ) );
    - * } 
    - *

    However, other libraries such as CoroutineLib are not loaded in this case. - *

    - * This has been implemented to match as closely as possible the behavior in the corresponding library in C. - * @see LibFunction - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - * @see org.luaj.vm2.lib.jse.JseMathLib - * @see Lua 5.2 Math Lib Reference - */ -public class JseMathLib extends org.luaj.vm2.lib.MathLib { - - public JseMathLib() {} - - - /** Perform one-time initialization on the library by creating a table - * containing the library functions, adding that table to the supplied environment, - * adding the table to package.loaded, and returning table as the return value. - *

    Specifically, adds all library functions that can be implemented directly - * in JSE but not JME: acos, asin, atan, atan2, cosh, exp, log, pow, sinh, and tanh. - * @param modname the module name supplied if this is loaded via 'require'. - * @param env the environment to load into, which must be a Globals instance. - */ - public LuaValue call(LuaValue modname, LuaValue env) { - super.call(modname, env); - LuaValue math = env.get("math"); - math.set("acos", new acos()); - math.set("asin", new asin()); - LuaValue atan = new atan2(); - math.set("atan", atan); - math.set("atan2", atan); - math.set("cosh", new cosh()); - math.set("exp", new exp()); - math.set("log", new log()); - math.set("pow", new pow()); - math.set("sinh", new sinh()); - math.set("tanh", new tanh()); - return math; - } - - static final class acos extends UnaryOp { protected double call(double d) { return Math.acos(d); } } - static final class asin extends UnaryOp { protected double call(double d) { return Math.asin(d); } } - static final class atan2 extends TwoArgFunction { - public LuaValue call(LuaValue x, LuaValue y) { - return valueOf(Math.atan2(x.checkdouble(), y.optdouble(1))); - } - } - static final class cosh extends UnaryOp { protected double call(double d) { return Math.cosh(d); } } - static final class exp extends UnaryOp { protected double call(double d) { return Math.exp(d); } } - static final class log extends TwoArgFunction { - public LuaValue call(LuaValue x, LuaValue base) { - double nat = Math.log(x.checkdouble()); - double b = base.optdouble(Math.E); - if (b != Math.E) nat /= Math.log(b); - return valueOf(nat); - } - } - static final class pow extends BinaryOp { protected double call(double x, double y) { return Math.pow(x, y); } } - static final class sinh extends UnaryOp { protected double call(double d) { return Math.sinh(d); } } - static final class tanh extends UnaryOp { protected double call(double d) { return Math.tanh(d); } } - - /** Faster, better version of pow() used by arithmetic operator ^ */ - public double dpow_lib(double a, double b) { - return Math.pow(a, b); - } - - -} - diff --git a/src/jse/org/luaj/vm2/lib/jse/JseOsLib.java b/src/jse/org/luaj/vm2/lib/jse/JseOsLib.java deleted file mode 100644 index af63c8af..00000000 --- a/src/jse/org/luaj/vm2/lib/jse/JseOsLib.java +++ /dev/null @@ -1,135 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2009 Luaj.org. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm2.lib.jse; - -import java.io.File; -import java.io.IOException; - -import org.luaj.vm2.Globals; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Varargs; -import org.luaj.vm2.lib.LibFunction; -import org.luaj.vm2.lib.OsLib; - -/** - * Subclass of {@link LibFunction} which implements the standard lua {@code os} library. - *

    - * This contains more complete implementations of the following functions - * using features that are specific to JSE: - *

    - *

    - * Because the nature of the {@code os} library is to encapsulate - * os-specific features, the behavior of these functions varies considerably - * from their counterparts in the C platform. - *

    - * Typically, this library is included as part of a call to - * {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} - *

     {@code
    - * Globals globals = JsePlatform.standardGlobals();
    - * System.out.println( globals.get("os").get("time").call() );
    - * } 
    - *

    - * For special cases where the smallest possible footprint is desired, - * a minimal set of libraries could be loaded - * directly via {@link Globals#load(LuaValue)} using code such as: - *

     {@code
    - * Globals globals = new Globals();
    - * globals.load(new JseBaseLib());
    - * globals.load(new PackageLib());
    - * globals.load(new JseOsLib());
    - * System.out.println( globals.get("os").get("time").call() );
    - * } 
    - *

    However, other libraries such as MathLib are not loaded in this case. - *

    - * @see LibFunction - * @see OsLib - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - * @see Lua 5.2 OS Lib Reference - */ -public class JseOsLib extends org.luaj.vm2.lib.OsLib { - - /** return code indicating the execute() threw an I/O exception */ - public static final int EXEC_IOEXCEPTION = 1; - - /** return code indicating the execute() was interrupted */ - public static final int EXEC_INTERRUPTED = -2; - - /** return code indicating the execute() threw an unknown exception */ - public static final int EXEC_ERROR = -3; - - /** public constructor */ - public JseOsLib() { - } - - protected String getenv(String varname) { - String s = System.getenv(varname); - return s != null? s : System.getProperty(varname); - } - - protected Varargs execute(String command) { - int exitValue; - try { - exitValue = new JseProcess(command, null, globals.STDOUT, globals.STDERR).waitFor(); - } catch (IOException ioe) { - exitValue = EXEC_IOEXCEPTION; - } catch (InterruptedException e) { - exitValue = EXEC_INTERRUPTED; - } catch (Throwable t) { - exitValue = EXEC_ERROR; - } - if (exitValue == 0) - return varargsOf(TRUE, valueOf("exit"), ZERO); - return varargsOf(NIL, valueOf("signal"), valueOf(exitValue)); - } - - protected void remove(String filename) throws IOException { - File f = new File(filename); - if ( ! f.exists() ) - throw new IOException("No such file or directory"); - if ( ! f.delete() ) - throw new IOException("Failed to delete"); - } - - protected void rename(String oldname, String newname) throws IOException { - File f = new File(oldname); - if ( ! f.exists() ) - throw new IOException("No such file or directory"); - if ( ! f.renameTo(new File(newname)) ) - throw new IOException("Failed to rename"); - } - - protected String tmpname() { - try { - java.io.File f = java.io.File.createTempFile(TMP_PREFIX ,TMP_SUFFIX); - return f.getAbsolutePath(); - } catch ( IOException ioe ) { - return super.tmpname(); - } - } - -} diff --git a/src/jse/org/luaj/vm2/lib/jse/JsePlatform.java b/src/jse/org/luaj/vm2/lib/jse/JsePlatform.java deleted file mode 100644 index 00575aaf..00000000 --- a/src/jse/org/luaj/vm2/lib/jse/JsePlatform.java +++ /dev/null @@ -1,143 +0,0 @@ -/******************************************************************************* - * 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.lib.jse; - -import org.luaj.vm2.Globals; -import org.luaj.vm2.LoadState; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Varargs; -import org.luaj.vm2.compiler.LuaC; -import org.luaj.vm2.lib.Bit32Lib; -import org.luaj.vm2.lib.CoroutineLib; -import org.luaj.vm2.lib.DebugLib; -import org.luaj.vm2.lib.PackageLib; -import org.luaj.vm2.lib.ResourceFinder; -import org.luaj.vm2.lib.StringLib; -import org.luaj.vm2.lib.TableLib; - -/** The {@link org.luaj.vm2.lib.jse.JsePlatform} class is a convenience class to standardize - * how globals tables are initialized for the JSE platform. - *

    - * It is used to allocate either a set of standard globals using - * {@link #standardGlobals()} or debug globals using {@link #debugGlobals()} - *

    - * A simple example of initializing globals and using them from Java is: - *

     {@code
    - * Globals globals = JsePlatform.standardGlobals();
    - * globals.get("print").call(LuaValue.valueOf("hello, world"));
    - * } 
    - *

    - * Once globals are created, a simple way to load and run a script is: - *

     {@code
    - * globals.load( new FileInputStream("main.lua"), "main.lua" ).call();
    - * } 
    - *

    - * although {@code require} could also be used: - *

     {@code
    - * globals.get("require").call(LuaValue.valueOf("main"));
    - * } 
    - * For this to succeed, the file "main.lua" must be in the current directory or a resource. - * See {@link org.luaj.vm2.lib.jse.JseBaseLib} for details on finding scripts using {@link ResourceFinder}. - *

    - * The standard globals will contain all standard libraries plus {@code luajava}: - *

    - * In addition, the {@link LuaC} compiler is installed so lua files may be loaded in their source form. - *

    - * The debug globals are simply the standard globals plus the {@code debug} library {@link DebugLib}. - *

    - * The class ensures that initialization is done in the correct order. - * - * @see Globals - * @see org.luaj.vm2.lib.jme.JmePlatform - */ -public class JsePlatform { - - /** - * Create a standard set of globals for JSE including all the libraries. - * - * @return Table of globals initialized with the standard JSE libraries - * @see #debugGlobals() - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - */ - public static Globals standardGlobals() { - Globals globals = new Globals(); - globals.load(new JseBaseLib()); - globals.load(new PackageLib()); - globals.load(new Bit32Lib()); - globals.load(new TableLib()); - globals.load(new JseStringLib()); - globals.load(new CoroutineLib()); - globals.load(new JseMathLib()); - globals.load(new JseIoLib()); - globals.load(new JseOsLib()); - globals.load(new LuajavaLib()); - LoadState.install(globals); - LuaC.install(globals); - return globals; - } - - /** Create standard globals including the {@link DebugLib} library. - * - * @return Table of globals initialized with the standard JSE and debug libraries - * @see #standardGlobals() - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - * @see DebugLib - */ - public static Globals debugGlobals() { - Globals globals = standardGlobals(); - globals.load(new DebugLib()); - return globals; - } - - - /** Simple wrapper for invoking a lua function with command line arguments. - * The supplied function is first given a new Globals object as its environment - * then the program is run with arguments. - * @return {@link Varargs} containing any values returned by mainChunk. - */ - public static Varargs luaMain(LuaValue mainChunk, String[] args) { - Globals g = standardGlobals(); - int n = args.length; - LuaValue[] vargs = new LuaValue[args.length]; - for (int i = 0; i < n; ++i) - vargs[i] = LuaValue.valueOf(args[i]); - LuaValue arg = LuaValue.listOf(vargs); - arg.set("n", n); - g.set("arg", arg); - mainChunk.initupvalue1(g); - return mainChunk.invoke(LuaValue.varargsOf(vargs)); - } -} diff --git a/src/jse/org/luaj/vm2/lib/jse/JseProcess.java b/src/jse/org/luaj/vm2/lib/jse/JseProcess.java deleted file mode 100644 index 3fcd79f1..00000000 --- a/src/jse/org/luaj/vm2/lib/jse/JseProcess.java +++ /dev/null @@ -1,132 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2012 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.lib.jse; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** Analog of Process that pipes input and output to client-specified streams. - */ -public class JseProcess { - - final Process process; - final Thread input,output,error; - - /** Construct a process around a command, with specified streams to redirect input and output to. - * - * @param cmd The command to execute, including arguments, if any - * @param stdin Optional InputStream to read from as process input, or null if input is not needed. - * @param stdout Optional OutputStream to copy process output to, or null if output is ignored. - * @param stderr Optinoal OutputStream to copy process stderr output to, or null if output is ignored. - * @throws IOException If the system process could not be created. - * @see Process - */ - public JseProcess(String[] cmd, InputStream stdin, OutputStream stdout, OutputStream stderr) throws IOException { - this(Runtime.getRuntime().exec(cmd), stdin, stdout, stderr); - } - - /** Construct a process around a command, with specified streams to redirect input and output to. - * - * @param cmd The command to execute, including arguments, if any - * @param stdin Optional InputStream to read from as process input, or null if input is not needed. - * @param stdout Optional OutputStream to copy process output to, or null if output is ignored. - * @param stderr Optinoal OutputStream to copy process stderr output to, or null if output is ignored. - * @throws IOException If the system process could not be created. - * @see Process - */ - public JseProcess(String cmd, InputStream stdin, OutputStream stdout, OutputStream stderr) throws IOException { - this(Runtime.getRuntime().exec(cmd), stdin, stdout, stderr); - } - - private JseProcess(Process process, InputStream stdin, OutputStream stdout, OutputStream stderr) { - this.process = process; - input = stdin == null? null: copyBytes(stdin, process.getOutputStream(), null, process.getOutputStream()); - output = stdout == null? null: copyBytes(process.getInputStream(), stdout, process.getInputStream(), null); - error = stderr == null? null: copyBytes(process.getErrorStream(), stderr, process.getErrorStream(), null); - } - - /** Get the exit value of the process. */ - public int exitValue() { - return process.exitValue(); - } - - /** Wait for the process to complete, and all pending output to finish. - * @return The exit status. - * @throws InterruptedException - */ - public int waitFor() throws InterruptedException { - int r = process.waitFor(); - if (input != null) - input.join(); - if (output != null) - output.join(); - if (error != null) - error.join(); - process.destroy(); - return r; - } - - /** Create a thread to copy bytes from input to output. */ - private Thread copyBytes(final InputStream input, - final OutputStream output, final InputStream ownedInput, - final OutputStream ownedOutput) { - Thread t = (new CopyThread(output, ownedOutput, ownedInput, input)); - t.start(); - return t; - } - - private static final class CopyThread extends Thread { - private final OutputStream output; - private final OutputStream ownedOutput; - private final InputStream ownedInput; - private final InputStream input; - - private CopyThread(OutputStream output, OutputStream ownedOutput, - InputStream ownedInput, InputStream input) { - this.output = output; - this.ownedOutput = ownedOutput; - this.ownedInput = ownedInput; - this.input = input; - } - - public void run() { - try { - byte[] buf = new byte[1024]; - int r; - try { - while ((r = input.read(buf)) >= 0) { - output.write(buf, 0, r); - } - } finally { - if (ownedInput != null) - ownedInput.close(); - if (ownedOutput != null) - ownedOutput.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - } - -} diff --git a/src/jse/org/luaj/vm2/lib/jse/JseStringLib.java b/src/jse/org/luaj/vm2/lib/jse/JseStringLib.java deleted file mode 100644 index 41177787..00000000 --- a/src/jse/org/luaj/vm2/lib/jse/JseStringLib.java +++ /dev/null @@ -1,39 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2009 Luaj.org. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm2.lib.jse; - -public class JseStringLib extends org.luaj.vm2.lib.StringLib { - - /** public constructor */ - public JseStringLib() { - } - - protected String format(String src, double x) { - String out; - try { - out = String.format(src, new Object[] {Double.valueOf(x)}); - } catch (Throwable e) { - out = super.format(src, x); - } - return out; - } -} diff --git a/src/jse/org/luaj/vm2/lib/jse/LuajavaLib.java b/src/jse/org/luaj/vm2/lib/jse/LuajavaLib.java deleted file mode 100644 index 35f1f850..00000000 --- a/src/jse/org/luaj/vm2/lib/jse/LuajavaLib.java +++ /dev/null @@ -1,214 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2009 Luaj.org. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm2.lib.jse; - - -import java.lang.reflect.Array; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; - -import org.luaj.vm2.Globals; -import org.luaj.vm2.LuaError; -import org.luaj.vm2.LuaTable; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Varargs; -import org.luaj.vm2.compiler.LuaC; -import org.luaj.vm2.lib.LibFunction; -import org.luaj.vm2.lib.VarArgFunction; - -/** - * Subclass of {@link LibFunction} which implements the features of the luajava package. - *

    - * Luajava is an approach to mixing lua and java using simple functions that bind - * java classes and methods to lua dynamically. The API is documented on the - * luajava documentation pages. - * - *

    - * Typically, this library is included as part of a call to - * {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} - *

     {@code
    - * Globals globals = JsePlatform.standardGlobals();
    - * System.out.println( globals.get("luajava").get("bindClass").call( LuaValue.valueOf("java.lang.System") ).invokeMethod("currentTimeMillis") );
    - * } 
    - *

    - * To instantiate and use it directly, - * link it into your globals table via {@link Globals#load} using code such as: - *

     {@code
    - * Globals globals = new Globals();
    - * globals.load(new JseBaseLib());
    - * globals.load(new PackageLib());
    - * globals.load(new LuajavaLib());
    - * globals.load(
    - *      "sys = luajava.bindClass('java.lang.System')\n"+
    - *      "print ( sys:currentTimeMillis() )\n", "main.lua" ).call();
    - * } 
    - *

    - * - * The {@code luajava} library is available - * on all JSE platforms via the call to {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} - * and the luajava api's are simply invoked from lua. - * Because it makes extensive use of Java's reflection API, it is not available - * on JME, but can be used in Android applications. - *

    - * This has been implemented to match as closely as possible the behavior in the corresponding library in C. - * - * @see LibFunction - * @see org.luaj.vm2.lib.jse.JsePlatform - * @see org.luaj.vm2.lib.jme.JmePlatform - * @see LuaC - * @see CoerceJavaToLua - * @see CoerceLuaToJava - * @see http://www.keplerproject.org/luajava/manual.html#luareference - */ -public class LuajavaLib extends VarArgFunction { - - static final int INIT = 0; - static final int BINDCLASS = 1; - static final int NEWINSTANCE = 2; - static final int NEW = 3; - static final int CREATEPROXY = 4; - static final int LOADLIB = 5; - - static final String[] NAMES = { - "bindClass", - "newInstance", - "new", - "createProxy", - "loadLib", - }; - - static final int METHOD_MODIFIERS_VARARGS = 0x80; - - public LuajavaLib() { - } - - public Varargs invoke(Varargs args) { - try { - switch ( opcode ) { - case INIT: { - // LuaValue modname = args.arg1(); - LuaValue env = args.arg(2); - LuaTable t = new LuaTable(); - bind( t, this.getClass(), NAMES, BINDCLASS ); - env.set("luajava", t); - if (!env.get("package").isnil()) env.get("package").get("loaded").set("luajava", t); - return t; - } - case BINDCLASS: { - final Class clazz = classForName(args.checkjstring(1)); - return JavaClass.forClass(clazz); - } - case NEWINSTANCE: - case NEW: { - // get constructor - final LuaValue c = args.checkvalue(1); - final Class clazz = (opcode==NEWINSTANCE? classForName(c.tojstring()): (Class) c.checkuserdata(Class.class)); - final Varargs consargs = args.subargs(2); - return JavaClass.forClass(clazz).getConstructor().invoke(consargs); - } - - case CREATEPROXY: { - final int niface = args.narg()-1; - if ( niface <= 0 ) - throw new LuaError("no interfaces"); - final LuaValue lobj = args.checktable(niface+1); - - // get the interfaces - final Class[] ifaces = new Class[niface]; - for ( int i=0; i=0 ); - } - - public void testLuaErrorCause() { - String script = "luajava.bindClass( \""+SomeClass.class.getName()+"\"):someMethod()"; - LuaValue chunk = globals.get("load").call(LuaValue.valueOf(script)); - try { - chunk.invoke(LuaValue.NONE); - fail( "call should not have succeeded" ); - } catch ( LuaError lee ) { - Throwable c = lee.getCause(); - assertEquals( SomeException.class, c.getClass() ); - } - } - - public interface VarArgsInterface { - public String varargsMethod( String a, String ... v ); - public String arrayargsMethod( String a, String[] v ); - } - - public void testVarArgsProxy() { - String script = "return luajava.createProxy( \""+VarArgsInterface.class.getName()+"\", \n"+ - "{\n" + - " varargsMethod = function(a,...)\n" + - " return table.concat({a,...},'-')\n" + - " end,\n" + - " arrayargsMethod = function(a,array)\n" + - " return tostring(a)..(array and \n" + - " ('-'..tostring(array.length)\n" + - " ..'-'..tostring(array[1])\n" + - " ..'-'..tostring(array[2])\n" + - " ) or '-nil')\n" + - " end,\n" + - "} )\n"; - Varargs chunk = globals.get("load").call(LuaValue.valueOf(script)); - if ( ! chunk.arg1().toboolean() ) - fail( chunk.arg(2).toString() ); - LuaValue result = chunk.arg1().call(); - Object u = result.touserdata(); - VarArgsInterface v = (VarArgsInterface) u; - assertEquals( "foo", v.varargsMethod("foo") ); - assertEquals( "foo-bar", v.varargsMethod("foo", "bar") ); - assertEquals( "foo-bar-etc", v.varargsMethod("foo", "bar", "etc") ); - assertEquals( "foo-0-nil-nil", v.arrayargsMethod("foo", new String[0]) ); - assertEquals( "foo-1-bar-nil", v.arrayargsMethod("foo", new String[] {"bar"}) ); - assertEquals( "foo-2-bar-etc", v.arrayargsMethod("foo", new String[] {"bar","etc"}) ); - assertEquals( "foo-3-bar-etc", v.arrayargsMethod("foo", new String[] {"bar","etc","etc"}) ); - assertEquals( "foo-nil", v.arrayargsMethod("foo", null) ); - } - - public void testBigNum() { - String script = - "bigNumA = luajava.newInstance('java.math.BigDecimal','12345678901234567890');\n" + - "bigNumB = luajava.newInstance('java.math.BigDecimal','12345678901234567890');\n" + - "bigNumC = bigNumA:multiply(bigNumB);\n" + - //"print(bigNumA:toString())\n" + - //"print(bigNumB:toString())\n" + - //"print(bigNumC:toString())\n" + - "return bigNumA:toString(), bigNumB:toString(), bigNumC:toString()"; - Varargs chunk = globals.get("load").call(LuaValue.valueOf(script)); - if ( ! chunk.arg1().toboolean() ) - fail( chunk.arg(2).toString() ); - Varargs results = chunk.arg1().invoke(); - int nresults = results.narg(); - String sa = results.tojstring(1); - String sb = results.tojstring(2); - String sc = results.tojstring(3); - assertEquals( 3, nresults ); - assertEquals( "12345678901234567890", sa ); - assertEquals( "12345678901234567890", sb ); - assertEquals( "152415787532388367501905199875019052100", sc ); - } - - public interface IA {} - public interface IB extends IA {} - public interface IC extends IB {} - - public static class A implements IA { - } - public static class B extends A implements IB { - public String set( Object x ) { return "set(Object) "; } - public String set( String x ) { return "set(String) "+x; } - public String set( A x ) { return "set(A) "; } - public String set( B x ) { return "set(B) "; } - public String set( C x ) { return "set(C) "; } - public String set( byte x ) { return "set(byte) "+x; } - public String set( char x ) { return "set(char) "+(int)x; } - public String set( short x ) { return "set(short) "+x; } - public String set( int x ) { return "set(int) "+x; } - public String set( long x ) { return "set(long) "+x; } - public String set( float x ) { return "set(float) "+x; } - public String set( double x ) { return "set(double) "+x; } - - public String setr( double x ) { return "setr(double) "+x; } - public String setr( float x ) { return "setr(float) "+x; } - public String setr( long x ) { return "setr(long) "+x; } - public String setr( int x ) { return "setr(int) "+x; } - public String setr( short x ) { return "setr(short) "+x; } - public String setr( char x ) { return "setr(char) "+(int)x; } - public String setr( byte x ) { return "setr(byte) "+x; } - public String setr( C x ) { return "setr(C) "; } - public String setr( B x ) { return "setr(B) "; } - public String setr( A x ) { return "setr(A) "; } - public String setr( String x ) { return "setr(String) "+x; } - public String setr( Object x ) { return "setr(Object) "; } - - public Object getObject() { return new Object(); } - public String getString() { return "abc"; } - public byte[] getbytearray() { return new byte[] { 1, 2, 3 }; } - public A getA() { return new A(); } - public B getB() { return new B(); } - public C getC() { return new C(); } - public byte getbyte() { return 1; } - public char getchar() { return 65000; } - public short getshort() { return -32000; } - public int getint() { return 100000; } - public long getlong() { return 50000000000L; } - public float getfloat() { return 6.5f; } - public double getdouble() { return Math.PI; } - } - public static class C extends B implements IC { - } - public static class D extends C implements IA { - } - - public void testOverloadedJavaMethodObject() { doOverloadedMethodTest( "Object", "" ); } - public void testOverloadedJavaMethodString() { doOverloadedMethodTest( "String", "abc" ); } - public void testOverloadedJavaMethodA() { doOverloadedMethodTest( "A", "" ); } - public void testOverloadedJavaMethodB() { doOverloadedMethodTest( "B", "" ); } - public void testOverloadedJavaMethodC() { doOverloadedMethodTest( "C", "" ); } - public void testOverloadedJavaMethodByte() { doOverloadedMethodTest( "byte", "1" ); } - public void testOverloadedJavaMethodChar() { doOverloadedMethodTest( "char", "65000" ); } - public void testOverloadedJavaMethodShort() { doOverloadedMethodTest( "short", "-32000" ); } - public void testOverloadedJavaMethodInt() { doOverloadedMethodTest( "int", "100000" ); } - public void testOverloadedJavaMethodLong() { doOverloadedMethodTest( "long", "50000000000" ); } - public void testOverloadedJavaMethodFloat() { doOverloadedMethodTest( "float", "6.5" ); } - public void testOverloadedJavaMethodDouble() { doOverloadedMethodTest( "double", "3.141592653589793" ); } - - private void doOverloadedMethodTest( String typename, String value ) { - String script = - "local a = luajava.newInstance('"+B.class.getName()+"');\n" + - "local b = a:set(a:get"+typename+"())\n" + - "local c = a:setr(a:get"+typename+"())\n" + - "return b,c"; - Varargs chunk = globals.get("load").call(LuaValue.valueOf(script)); - if ( ! chunk.arg1().toboolean() ) - fail( chunk.arg(2).toString() ); - Varargs results = chunk.arg1().invoke(); - int nresults = results.narg(); - assertEquals( 2, nresults ); - LuaValue b = results.arg(1); - LuaValue c = results.arg(2); - String sb = b.tojstring(); - String sc = c.tojstring(); - assertEquals( "set("+typename+") "+value, sb ); - assertEquals( "setr("+typename+") "+value, sc ); - } - - public void testClassInheritanceLevels() { - assertEquals( 0, CoerceLuaToJava.inheritanceLevels(Object.class, Object.class) ); - assertEquals( 1, CoerceLuaToJava.inheritanceLevels(Object.class, String.class) ); - assertEquals( 1, CoerceLuaToJava.inheritanceLevels(Object.class, A.class) ); - assertEquals( 2, CoerceLuaToJava.inheritanceLevels(Object.class, B.class) ); - assertEquals( 3, CoerceLuaToJava.inheritanceLevels(Object.class, C.class) ); - - assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(A.class, Object.class) ); - assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(A.class, String.class) ); - assertEquals( 0, CoerceLuaToJava.inheritanceLevels(A.class, A.class) ); - assertEquals( 1, CoerceLuaToJava.inheritanceLevels(A.class, B.class) ); - assertEquals( 2, CoerceLuaToJava.inheritanceLevels(A.class, C.class) ); - - assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(B.class, Object.class) ); - assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(B.class, String.class) ); - assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(B.class, A.class) ); - assertEquals( 0, CoerceLuaToJava.inheritanceLevels(B.class, B.class) ); - assertEquals( 1, CoerceLuaToJava.inheritanceLevels(B.class, C.class) ); - - assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(C.class, Object.class) ); - assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(C.class, String.class) ); - assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(C.class, A.class) ); - assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(C.class, B.class) ); - assertEquals( 0, CoerceLuaToJava.inheritanceLevels(C.class, C.class) ); - } - - public void testInterfaceInheritanceLevels() { - assertEquals( 1, CoerceLuaToJava.inheritanceLevels(IA.class, A.class) ); - assertEquals( 1, CoerceLuaToJava.inheritanceLevels(IB.class, B.class) ); - assertEquals( 2, CoerceLuaToJava.inheritanceLevels(IA.class, B.class) ); - assertEquals( 1, CoerceLuaToJava.inheritanceLevels(IC.class, C.class) ); - assertEquals( 2, CoerceLuaToJava.inheritanceLevels(IB.class, C.class) ); - assertEquals( 3, CoerceLuaToJava.inheritanceLevels(IA.class, C.class) ); - assertEquals( 1, CoerceLuaToJava.inheritanceLevels(IA.class, D.class) ); - assertEquals( 2, CoerceLuaToJava.inheritanceLevels(IC.class, D.class) ); - assertEquals( 3, CoerceLuaToJava.inheritanceLevels(IB.class, D.class) ); - - assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(IB.class, A.class) ); - assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(IC.class, A.class) ); - assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(IC.class, B.class) ); - assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(IB.class, IA.class) ); - assertEquals( 1, CoerceLuaToJava.inheritanceLevels(IA.class, IB.class) ); - } - - public void testCoerceJavaToLuaLuaValue() { - assertSame(LuaValue.NIL, CoerceJavaToLua.coerce(LuaValue.NIL)); - assertSame(LuaValue.ZERO, CoerceJavaToLua.coerce(LuaValue.ZERO)); - assertSame(LuaValue.ONE, CoerceJavaToLua.coerce(LuaValue.ONE)); - assertSame(LuaValue.INDEX, CoerceJavaToLua.coerce(LuaValue.INDEX)); - LuaTable table = LuaValue.tableOf(); - assertSame(table, CoerceJavaToLua.coerce(table)); - } - - public void testCoerceJavaToLuaByeArray() { - byte[] bytes = "abcd".getBytes(); - LuaValue value = CoerceJavaToLua.coerce(bytes); - assertEquals(LuaString.class, value.getClass()); - assertEquals(LuaValue.valueOf("abcd"), value); - } -} - diff --git a/test/junit/org/luaj/vm2/lib/jse/LuajavaAccessibleMembersTest.java b/test/junit/org/luaj/vm2/lib/jse/LuajavaAccessibleMembersTest.java deleted file mode 100644 index 3a86a8e6..00000000 --- a/test/junit/org/luaj/vm2/lib/jse/LuajavaAccessibleMembersTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.luaj.vm2.lib.jse; - -import junit.framework.TestCase; - -import org.luaj.vm2.Globals; -import org.luaj.vm2.LuaValue; - -public class LuajavaAccessibleMembersTest extends TestCase { - - private Globals globals; - - protected void setUp() throws Exception { - super.setUp(); - globals = JsePlatform.standardGlobals(); - } - - private String invokeScript(String script) { - try { - LuaValue c = globals.load(script, "script"); - return c.call().tojstring(); - } catch ( Exception e ) { - fail("exception: "+e ); - return "failed"; - } - } - - public void testAccessFromPrivateClassImplementedMethod() { - assertEquals("privateImpl-aaa-interface_method(bar)", invokeScript( - "b = luajava.newInstance('"+TestClass.class.getName()+"');" + - "a = b:create_PrivateImpl('aaa');" + - "return a:interface_method('bar');")); - } - - public void testAccessFromPrivateClassPublicMethod() { - assertEquals("privateImpl-aaa-public_method", invokeScript( - "b = luajava.newInstance('"+TestClass.class.getName()+"');" + - "a = b:create_PrivateImpl('aaa');" + - "return a:public_method();")); - } - - public void testAccessFromPrivateClassGetPublicField() { - assertEquals("aaa", invokeScript( - "b = luajava.newInstance('"+TestClass.class.getName()+"');" + - "a = b:create_PrivateImpl('aaa');" + - "return a.public_field;")); - } - - public void testAccessFromPrivateClassSetPublicField() { - assertEquals("foo", invokeScript( - "b = luajava.newInstance('"+TestClass.class.getName()+"');" + - "a = b:create_PrivateImpl('aaa');" + - "a.public_field = 'foo';" + - "return a.public_field;")); - } - - public void testAccessFromPrivateClassPublicConstructor() { - assertEquals("privateImpl-constructor", invokeScript( - "b = luajava.newInstance('"+TestClass.class.getName()+"');" + - "c = b:get_PrivateImplClass();" + - "return luajava.new(c);")); - } - - public void testAccessPublicEnum() { - assertEquals("class org.luaj.vm2.lib.jse.TestClass$SomeEnum", invokeScript( - "b = luajava.newInstance('"+TestClass.class.getName()+"');" + - "return b.SomeEnum")); - } -} diff --git a/test/junit/org/luaj/vm2/lib/jse/LuajavaClassMembersTest.java b/test/junit/org/luaj/vm2/lib/jse/LuajavaClassMembersTest.java deleted file mode 100644 index 496adffe..00000000 --- a/test/junit/org/luaj/vm2/lib/jse/LuajavaClassMembersTest.java +++ /dev/null @@ -1,238 +0,0 @@ -package org.luaj.vm2.lib.jse; - -import junit.framework.TestCase; - -import org.luaj.vm2.LuaError; -import org.luaj.vm2.LuaValue; - -public class LuajavaClassMembersTest extends TestCase { - public static class A { - protected A() {} - } - public static class B extends A { - public byte m_byte_field; - public int m_int_field; - public double m_double_field; - public String m_string_field; - - protected B() {} - public B(int i) { m_int_field = i; } - - public String setString( String x ) { return "setString(String) "+x; } - public String getString() { return "abc"; } - public int getint() { return 100000; } - - public String uniq() { return "uniq()"; } - public String uniqs(String s) { return "uniqs(string:"+s+")"; } - public String uniqi(int i) { return "uniqi(int:"+i+")"; } - public String uniqsi(String s, int i) { return "uniqsi(string:"+s+",int:"+i+")"; } - public String uniqis(int i, String s) { return "uniqis(int:"+i+",string:"+s+")"; } - - public String pick() { return "pick()"; } - public String pick(String s) { return "pick(string:"+s+")"; } - public String pick(int i) { return "pick(int:"+i+")"; } - public String pick(String s, int i) { return "pick(string:"+s+",int:"+i+")"; } - public String pick(int i, String s) { return "pick(int:"+i+",string:"+s+")"; } - - public static String staticpick() { return "static-pick()"; } - public static String staticpick(String s) { return "static-pick(string:"+s+")"; } - public static String staticpick(int i) { return "static-pick(int:"+i+")"; } - public static String staticpick(String s, int i) { return "static-pick(string:"+s+",int:"+i+")"; } - public static String staticpick(int i, String s) { return "static-pick(int:"+i+",string:"+s+")"; } - } - public static class C extends B { - public C() {} - public C(String s) { m_string_field = s; } - public C(int i) { m_int_field = i; } - public C(String s, int i) { m_string_field = s; m_int_field = i; } - public int getint() { return 200000; } - - public String pick(String s) { return "class-c-pick(string:"+s+")"; } - public String pick(int i) { return "class-c-pick(int:"+i+")"; } - public static class D { - public static String name() { return "name-of-D"; } - } - } - - static LuaValue ZERO = LuaValue.ZERO; - static LuaValue ONE = LuaValue.ONE; - static LuaValue PI = LuaValue.valueOf(Math.PI); - static LuaValue THREE = LuaValue.valueOf(3); - static LuaValue NUMS = LuaValue.valueOf(123); - static LuaValue ABC = LuaValue.valueOf("abc"); - static LuaValue SOMEA = CoerceJavaToLua.coerce(new A()); - static LuaValue SOMEB = CoerceJavaToLua.coerce(new B()); - static LuaValue SOMEC = CoerceJavaToLua.coerce(new C()); - - public void testSetByteField() { - B b = new B(); - JavaInstance i = new JavaInstance(b); - i.set("m_byte_field", ONE ); assertEquals( 1, b.m_byte_field ); assertEquals( ONE, i.get("m_byte_field") ); - i.set("m_byte_field", PI ); assertEquals( 3, b.m_byte_field ); assertEquals( THREE, i.get("m_byte_field") ); - i.set("m_byte_field", ABC ); assertEquals( 0, b.m_byte_field ); assertEquals( ZERO, i.get("m_byte_field") ); - } - public void testSetDoubleField() { - B b = new B(); - JavaInstance i = new JavaInstance(b); - i.set("m_double_field", ONE ); assertEquals( 1., b.m_double_field ); assertEquals( ONE, i.get("m_double_field") ); - i.set("m_double_field", PI ); assertEquals( Math.PI, b.m_double_field ); assertEquals( PI, i.get("m_double_field") ); - i.set("m_double_field", ABC ); assertEquals( 0., b.m_double_field ); assertEquals( ZERO, i.get("m_double_field") ); - } - public void testNoFactory() { - JavaClass c = JavaClass.forClass(A.class); - try { - c.call(); - fail( "did not throw lua error as expected" ); - } catch ( LuaError e ) { - } - } - public void testUniqueFactoryCoercible() { - JavaClass c = JavaClass.forClass(B.class); - assertEquals( JavaClass.class, c.getClass() ); - LuaValue constr = c.get("new"); - assertEquals( JavaConstructor.class, constr.getClass() ); - LuaValue v = constr.call(NUMS); - Object b = v.touserdata(); - assertEquals( B.class, b.getClass() ); - assertEquals( 123, ((B)b).m_int_field ); - Object b0 = constr.call().touserdata(); - assertEquals( B.class, b0.getClass() ); - assertEquals( 0, ((B)b0).m_int_field ); - } - public void testUniqueFactoryUncoercible() { - JavaClass f = JavaClass.forClass(B.class); - LuaValue constr = f.get("new"); - assertEquals( JavaConstructor.class, constr.getClass() ); - try { - LuaValue v = constr.call(LuaValue.userdataOf(new Object())); - Object b = v.touserdata(); - // fail( "did not throw lua error as expected" ); - assertEquals( 0, ((B)b).m_int_field ); - } catch ( LuaError e ) { - } - } - public void testOverloadedFactoryCoercible() { - JavaClass f = JavaClass.forClass(C.class); - LuaValue constr = f.get("new"); - assertEquals( JavaConstructor.Overload.class, constr.getClass() ); - Object c = constr.call().touserdata(); - Object ci = constr.call(LuaValue.valueOf(123)).touserdata(); - Object cs = constr.call(LuaValue.valueOf("abc")).touserdata(); - Object csi = constr.call( LuaValue.valueOf("def"), LuaValue.valueOf(456) ).touserdata(); - assertEquals( C.class, c.getClass() ); - assertEquals( C.class, ci.getClass() ); - assertEquals( C.class, cs.getClass() ); - assertEquals( C.class, csi.getClass() ); - assertEquals( null, ((C)c).m_string_field ); - assertEquals( 0, ((C)c).m_int_field ); - assertEquals( "abc", ((C)cs).m_string_field ); - assertEquals( 0, ((C)cs).m_int_field ); - assertEquals( null, ((C)ci).m_string_field ); - assertEquals( 123, ((C)ci).m_int_field ); - assertEquals( "def", ((C)csi).m_string_field ); - assertEquals( 456, ((C)csi).m_int_field ); - } - public void testOverloadedFactoryUncoercible() { - JavaClass f = JavaClass.forClass(C.class); - try { - Object c = f.call(LuaValue.userdataOf(new Object())); - // fail( "did not throw lua error as expected" ); - assertEquals( 0, ((C)c).m_int_field ); - assertEquals( null, ((C)c).m_string_field ); - } catch ( LuaError e ) { - } - } - - public void testNoAttribute() { - JavaClass f = JavaClass.forClass(A.class); - LuaValue v = f.get("bogus"); - assertEquals( v, LuaValue.NIL ); - try { - f.set("bogus",ONE); - fail( "did not throw lua error as expected" ); - } catch ( LuaError e ) {} - } - public void testFieldAttributeCoercible() { - JavaInstance i = new JavaInstance(new B()); - i.set("m_int_field", ONE ); assertEquals( 1, i.get("m_int_field").toint() ); - i.set("m_int_field", THREE ); assertEquals( 3, i.get("m_int_field").toint() ); - i = new JavaInstance(new C()); - i.set("m_int_field", ONE ); assertEquals( 1, i.get("m_int_field").toint() ); - i.set("m_int_field", THREE ); assertEquals( 3, i.get("m_int_field").toint() ); - } - public void testUniqueMethodAttributeCoercible() { - B b = new B(); - JavaInstance ib = new JavaInstance(b); - LuaValue b_getString = ib.get("getString"); - LuaValue b_getint = ib.get("getint"); - assertEquals( JavaMethod.class, b_getString.getClass() ); - assertEquals( JavaMethod.class, b_getint.getClass() ); - assertEquals( "abc", b_getString.call(SOMEB).tojstring() ); - assertEquals( 100000, b_getint.call(SOMEB).toint()); - assertEquals( "abc", b_getString.call(SOMEC).tojstring() ); - assertEquals( 200000, b_getint.call(SOMEC).toint()); - } - public void testUniqueMethodAttributeArgsCoercible() { - B b = new B(); - JavaInstance ib = new JavaInstance(b); - LuaValue uniq = ib.get("uniq"); - LuaValue uniqs = ib.get("uniqs"); - LuaValue uniqi = ib.get("uniqi"); - LuaValue uniqsi = ib.get("uniqsi"); - LuaValue uniqis = ib.get("uniqis"); - assertEquals( JavaMethod.class, uniq.getClass() ); - assertEquals( JavaMethod.class, uniqs.getClass() ); - assertEquals( JavaMethod.class, uniqi.getClass() ); - assertEquals( JavaMethod.class, uniqsi.getClass() ); - assertEquals( JavaMethod.class, uniqis.getClass() ); - assertEquals( "uniq()", uniq.call(SOMEB).tojstring() ); - assertEquals( "uniqs(string:abc)", uniqs.call(SOMEB,ABC).tojstring() ); - assertEquals( "uniqi(int:1)", uniqi.call(SOMEB,ONE).tojstring() ); - assertEquals( "uniqsi(string:abc,int:1)", uniqsi.call(SOMEB,ABC,ONE).tojstring() ); - assertEquals( "uniqis(int:1,string:abc)", uniqis.call(SOMEB,ONE,ABC).tojstring() ); - assertEquals( "uniqis(int:1,string:abc)", uniqis.invoke(LuaValue.varargsOf(new LuaValue[] {SOMEB,ONE,ABC,ONE})).arg1().tojstring() ); - } - public void testOverloadedMethodAttributeCoercible() { - B b = new B(); - JavaInstance ib = new JavaInstance(b); - LuaValue p = ib.get("pick"); - assertEquals( "pick()", p.call(SOMEB).tojstring() ); - assertEquals( "pick(string:abc)", p.call(SOMEB,ABC).tojstring() ); - assertEquals( "pick(int:1)", p.call(SOMEB,ONE).tojstring() ); - assertEquals( "pick(string:abc,int:1)", p.call(SOMEB,ABC,ONE).tojstring() ); - assertEquals( "pick(int:1,string:abc)", p.call(SOMEB,ONE,ABC).tojstring() ); - assertEquals( "pick(int:1,string:abc)", p.invoke(LuaValue.varargsOf(new LuaValue[] {SOMEB,ONE,ABC,ONE})).arg1().tojstring() ); - } - public void testUnboundOverloadedMethodAttributeCoercible() { - B b = new B(); - JavaInstance ib = new JavaInstance(b); - LuaValue p = ib.get("pick"); - assertEquals( JavaMethod.Overload.class, p.getClass() ); - assertEquals( "pick()", p.call(SOMEC).tojstring() ); - assertEquals( "class-c-pick(string:abc)", p.call(SOMEC,ABC).tojstring() ); - assertEquals( "class-c-pick(int:1)", p.call(SOMEC,ONE).tojstring() ); - assertEquals( "pick(string:abc,int:1)", p.call(SOMEC,ABC,ONE).tojstring() ); - assertEquals( "pick(int:1,string:abc)", p.call(SOMEC,ONE,ABC).tojstring() ); - assertEquals( "pick(int:1,string:abc)", p.invoke(LuaValue.varargsOf(new LuaValue[] {SOMEC,ONE,ABC,ONE})).arg1().tojstring() ); - } - public void testOverloadedStaticMethodAttributeCoercible() { - B b = new B(); - JavaInstance ib = new JavaInstance(b); - LuaValue p = ib.get("staticpick"); - assertEquals( "static-pick()", p.call(SOMEB).tojstring() ); - assertEquals( "static-pick(string:abc)", p.call(SOMEB,ABC).tojstring() ); - assertEquals( "static-pick(int:1)", p.call(SOMEB,ONE).tojstring() ); - assertEquals( "static-pick(string:abc,int:1)", p.call(SOMEB,ABC,ONE).tojstring() ); - assertEquals( "static-pick(int:1,string:abc)", p.call(SOMEB,ONE,ABC).tojstring() ); - assertEquals( "static-pick(int:1,string:abc)", p.invoke(LuaValue.varargsOf(new LuaValue[] {SOMEB,ONE,ABC,ONE})).arg1().tojstring() ); - } - public void testGetInnerClass() { - C c = new C(); - JavaInstance ic = new JavaInstance(c); - LuaValue d = ic.get("D"); - assertFalse(d.isnil()); - assertSame(d, JavaClass.forClass(C.D.class)); - LuaValue e = ic.get("E"); - assertTrue(e.isnil()); - } -} diff --git a/test/junit/org/luaj/vm2/lib/jse/OsLibTest.java b/test/junit/org/luaj/vm2/lib/jse/OsLibTest.java deleted file mode 100644 index 6c698acc..00000000 --- a/test/junit/org/luaj/vm2/lib/jse/OsLibTest.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.luaj.vm2.lib.jse; - -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.lib.OsLib; -import org.luaj.vm2.lib.jme.JmePlatform; - -import junit.framework.TestCase; - -public class OsLibTest extends TestCase { - - LuaValue jme_lib; - LuaValue jse_lib; - double time; - - public void setUp() { - jse_lib = JsePlatform.standardGlobals().get("os");; - jme_lib = JmePlatform.standardGlobals().get("os");; - time = new java.util.Date(2001-1900, 7, 23, 14, 55, 02).getTime() / 1000.0; - } - - void t(String format, String expected) { - String actual = jme_lib.get("date").call(LuaValue.valueOf(format), LuaValue.valueOf(time)).tojstring(); - assertEquals(expected, actual); - } - - public void testStringDateChars() { t("foo", "foo"); } - public void testStringDate_a() { t("%a", "Thu"); } - public void testStringDate_A() { t("%A", "Thursday"); } - public void testStringDate_b() { t("%b", "Aug"); } - public void testStringDate_B() { t("%B", "August"); } - public void testStringDate_c() { t("%c", "Thu Aug 23 14:55:02 2001"); } - public void testStringDate_d() { t("%d", "23"); } - public void testStringDate_H() { t("%H", "14"); } - public void testStringDate_I() { t("%I", "02"); } - public void testStringDate_j() { t("%j", "235"); } - public void testStringDate_m() { t("%m", "08"); } - public void testStringDate_M() { t("%M", "55"); } - public void testStringDate_p() { t("%p", "PM"); } - public void testStringDate_S() { t("%S", "02"); } - public void testStringDate_U() { t("%U", "33"); } - public void testStringDate_w() { t("%w", "4"); } - public void testStringDate_W() { t("%W", "34"); } - public void testStringDate_x() { t("%x", "08/23/01"); } - public void testStringDate_X() { t("%X", "14:55:02"); } - public void testStringDate_y() { t("%y", "01"); } - public void testStringDate_Y() { t("%Y", "2001"); } - public void testStringDate_Pct() { t("%%", "%"); } - - static final double DAY = 24. * 3600.; - public void testStringDate_UW_neg4() { time-=4*DAY; t("%c %U %W", "Sun Aug 19 14:55:02 2001 33 33"); } - public void testStringDate_UW_neg3() { time-=3*DAY; t("%c %U %W", "Mon Aug 20 14:55:02 2001 33 34"); } - public void testStringDate_UW_neg2() { time-=2*DAY; t("%c %U %W", "Tue Aug 21 14:55:02 2001 33 34"); } - public void testStringDate_UW_neg1() { time-=DAY; t("%c %U %W", "Wed Aug 22 14:55:02 2001 33 34"); } - public void testStringDate_UW_pos0() { time+=0; t("%c %U %W", "Thu Aug 23 14:55:02 2001 33 34"); } - public void testStringDate_UW_pos1() { time+=DAY; t("%c %U %W", "Fri Aug 24 14:55:02 2001 33 34"); } - public void testStringDate_UW_pos2() { time+=2*DAY; t("%c %U %W", "Sat Aug 25 14:55:02 2001 33 34"); } - public void testStringDate_UW_pos3() { time+=3*DAY; t("%c %U %W", "Sun Aug 26 14:55:02 2001 34 34"); } - public void testStringDate_UW_pos4() { time+=4*DAY; t("%c %U %W", "Mon Aug 27 14:55:02 2001 34 35"); } - - public void testJseOsGetenvForEnvVariables() { - LuaValue USER = LuaValue.valueOf("USER"); - LuaValue jse_user = jse_lib.get("getenv").call(USER); - LuaValue jme_user = jme_lib.get("getenv").call(USER); - assertFalse(jse_user.isnil()); - assertTrue(jme_user.isnil()); - System.out.println("User: " + jse_user); - } - - public void testJseOsGetenvForSystemProperties() { - System.setProperty("test.key.foo", "test.value.bar"); - LuaValue key = LuaValue.valueOf("test.key.foo"); - LuaValue value = LuaValue.valueOf("test.value.bar"); - LuaValue jse_value = jse_lib.get("getenv").call(key); - LuaValue jme_value = jme_lib.get("getenv").call(key); - assertEquals(value, jse_value); - assertEquals(value, jme_value); - } -} diff --git a/test/junit/org/luaj/vm2/lib/jse/TestClass.java b/test/junit/org/luaj/vm2/lib/jse/TestClass.java deleted file mode 100644 index dc57bc4b..00000000 --- a/test/junit/org/luaj/vm2/lib/jse/TestClass.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.luaj.vm2.lib.jse; - -public class TestClass { - private static class PrivateImpl implements TestInterface { - public String public_field; - public PrivateImpl() { - this.public_field = "privateImpl-constructor"; - } - PrivateImpl(String f) { - this.public_field = f; - } - public String public_method() { return "privateImpl-"+public_field+"-public_method"; } - public String interface_method(String x) { return "privateImpl-"+public_field+"-interface_method("+x+")"; } - public String toString() { return public_field; } - } - public TestInterface create_PrivateImpl(String f) { return new PrivateImpl(f); } - public Class get_PrivateImplClass() { return PrivateImpl.class; } - public enum SomeEnum { - ValueOne, - ValueTwo, - } -} \ No newline at end of file diff --git a/test/junit/org/luaj/vm2/lib/jse/TestInterface.java b/test/junit/org/luaj/vm2/lib/jse/TestInterface.java deleted file mode 100644 index 1b58a0a5..00000000 --- a/test/junit/org/luaj/vm2/lib/jse/TestInterface.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.luaj.vm2.lib.jse; - -public interface TestInterface { - String interface_method(String x); -} \ No newline at end of file diff --git a/test/lua/baselib.lua b/test/lua/baselib.lua deleted file mode 100644 index 96c50ce8..00000000 --- a/test/lua/baselib.lua +++ /dev/null @@ -1,277 +0,0 @@ - --- tostring replacement that assigns ids -local ts,id,nid,types = tostring,{},0,{table='tbl',thread='thr',userdata='uda',['function']='func'} -tostring = function(x) - if not x or not types[type(x)] then return ts(x) end - if not id[x] then nid=nid+1; id[x]=types[type(x)]..'.'..nid end - return id[x] -end - --- wrap pcall to return one result --- error message are tested elsewhere -local pc = pcall -local pcall = function(...) - local s,e = pc(...) - if s then return e end - return false, type(e) -end - --- print -print() -print(11) -print("abc",123,nil,"pqr") -print( nil and 'T' or 'F' ) -print( false and 'T' or 'F' ) -print( 0 and 'T' or 'F' ) - --- assert -print( 'assert(true)', assert(true) ) -print( 'pcall(assert,true)', pcall(assert,true) ) -print( 'pcall(assert,false)', pcall(assert,false) ) -print( 'pcall(assert,nil)', pcall(assert,nil) ) -print( 'pcall(assert,true,"msg")', pcall(assert,true,"msg") ) -print( 'pcall(assert,false,"msg")', pcall(assert,false,"msg") ) -print( 'pcall(assert,nil,"msg")', pcall(assert,nil,"msg") ) -print( 'pcall(assert,false,"msg","msg2")', pcall(assert,false,"msg","msg2") ) - --- collectgarbage (not supported) -print( 'collectgarbage("count")', type(collectgarbage("count"))) -print( 'collectgarbage("collect")', type(collectgarbage("collect"))) -print( 'collectgarbage("count")', type(collectgarbage("count"))) - --- dofile (not supported) --- ipairs -print( 'pcall(ipairs)', pcall(ipairs) ) -print( 'pcall(ipairs,nil)', pcall(ipairs,nil) ) -print( 'pcall(ipairs,"a")', pcall(ipairs,"a") ) -print( 'pcall(ipairs,1)', pcall(ipairs,1) ) -for k,v in ipairs({}) do print('ipairs1',k,v)end -for k,v in ipairs({'one','two'}) do print('ipairs2',k,v)end -for k,v in ipairs({aa='aaa',bb='bbb'}) do print('ipairs3',k,v)end -for k,v in ipairs({aa='aaa',bb='bbb','one','two'}) do print('ipairs4',k,v)end -for k,v in ipairs({[30]='30',[20]='20'}) do print('ipairs5',k,v)end - --- load -t = { "print ", "'table ", "loaded'", "", " print'after empty string'" } -i = 0 -f = function() i = i + 1; return t[i]; end -c,e = load(f) -if c then print('load: ', pcall(c)) else print('load failed:', e) end - --- loadfile --- load -local lst = "print(3+4); return 8" -local chunk, err = load( lst ) -print( 'load("'..lst..'")', chunk, err ) -print( 'load("'..lst..'")()', chunk() ) - --- pairs -print( 'pcall(pairs)', pcall(pairs) ) -print( 'pcall(pairs,nil)', pcall(pairs,nil) ) -print( 'pcall(pairs,"a")', pcall(pairs,"a") ) -print( 'pcall(pairs,1)', pcall(pairs,1) ) -for k,v in pairs({}) do print('pairs1',k,v)end -for k,v in pairs({'one','two'}) do print('pairs2',k,v)end -for k,v in pairs({aa='aaa'}) do print('pairs3',k,v)end -for k,v in pairs({aa='aaa','one','two'}) do print('pairs4',k,v)end -for k,v in pairs({[20]='30',[30]='20'}) do print('pairs5',k,v)end - --- _G -print( '_G["abc"] (before)', _G["abc"] ) -abc='def' -print( '_G["abc"] (after)', _G["abc"] ) - --- type -print( 'type(nil)', type(nil) ) -print( 'type("a")', type("a") ) -print( 'type(1)', type(1) ) -print( 'type(1.5)', type(1.5) ) -print( 'type(function() end)', type(function() end) ) -print( 'type({})', type({}) ) -print( 'type(true)', type(true) ) -print( 'type(false)', type(false) ) -print( 'pcall(type,type)', pcall(type,type) ) -print( 'pcall(type)', pcall(type) ) -print( '(function() return pcall(type) end)()', (function() return pcall(type) end)() ) -local function la() return pcall(type) end -print( 'la()', la() ) -function ga() return pcall(type) end -print( 'ga()', ga() ) - --- getmetatable, setmetatable -ta = { aa1="aaa1", aa2="aaa2" } -tb = { bb1="bbb1", bb2="bbb2" } -print( 'getmetatable(ta)', getmetatable(ta) ) -print( 'getmetatable(tb)', getmetatable(tb) ) -print( 'setmetatable(ta),{cc1="ccc1"}', type( setmetatable(ta,{cc1="ccc1"}) ) ) -print( 'setmetatable(tb),{dd1="ddd1"}', type( setmetatable(tb,{dd1="ddd1"}) ) ) -print( 'getmetatable(ta)["cc1"]', getmetatable(ta)["cc1"] ) -print( 'getmetatable(tb)["dd1"]', getmetatable(tb)["dd1"] ) -print( 'getmetatable(1)', getmetatable(1) ) -print( 'pcall(setmetatable,1)', pcall(setmetatable,1) ) -print( 'pcall(setmetatable,nil)', pcall(setmetatable,nil) ) -print( 'pcall(setmetatable,"ABC")', pcall(setmetatable,"ABC") ) -print( 'pcall(setmetatable,function() end)', pcall(setmetatable,function() end) ) - --- rawget,rawset -local mt = {aa="aaa", bb="bbb"} -mt.__index = mt -mt.__newindex = mt -local s = {cc="ccc", dd="ddd", } -local t = {cc="ccc", dd="ddd"} -setmetatable(t,mt) -print( 'pcall(rawget)', pcall(rawget)) -print( 'pcall(rawget,"a")', pcall(rawget,"a")) -print( 'pcall(rawget,s)', pcall(rawget,s)) -print( 'pcall(rawget,t)', pcall(rawget,t)) - -function printtables() - function printtable(name,t) - print( ' '..name, t["aa"], t["bb"], t["cc"], t["dd"], t["ee"], t["ff"], t["gg"] ) - print( ' '..name, - rawget(t,"aa"), - rawget(t,"bb"), - rawget(t,"cc"), - rawget(t,"dd"), - rawget(t,"ee"), - rawget(t,"ff"), - rawget(t,"gg") ) - end - printtable( 's', s ) - printtable( 't', t ) - printtable( 'mt', mt ) -end -printtables() -print( 'pcall(rawset,s,"aa","www")', rawset(s,"aa","www")) -printtables() -print( 'pcall(rawset,s,"cc","xxx")', rawset(s,"cc","xxx")) -printtables() -print( 'pcall(rawset,t,"aa","yyy")', rawset(t,"aa","yyy")) -printtables() -print( 'pcall(rawset,t,"dd","zzz")', rawset(t,"dd","zzz")) -printtables() - --- rawlen -print( 'pcall(rawlen, {})', pcall(rawlen, {})) -print( 'pcall(rawlen, {"a"})', pcall(rawlen, {'a'})) -print( 'pcall(rawlen, {"a","b"})', pcall(rawlen, {'a','b'})) -print( 'pcall(rawlen, "")', pcall(rawlen, "")) -print( 'pcall(rawlen, "a")', pcall(rawlen, 'a')) -print( 'pcall(rawlen, "ab")', pcall(rawlen, 'ab')) -print( 'pcall(rawlen, 1)', pcall(rawlen, 1)) -print( 'pcall(rawlen, nil)', pcall(rawlen, nil)) -print( 'pcall(rawlen)', pcall(rawlen)) - -printtables() -print( 's["ee"]="ppp"' ); s["ee"]="ppp" -printtables() -print( 's["cc"]="qqq"' ); s["cc"]="qqq" -printtables() -print( 't["ff"]="rrr"' ); t["ff"]="rrr" -printtables() -print( 't["dd"]="sss"' ); t["dd"]="sss" -printtables() -print( 'mt["gg"]="ttt"' ); mt["gg"]="ttt" -printtables() - - --- select -print( 'pcall(select)', pcall(select) ) -print( 'select(1,11,22,33,44,55)', select(1,11,22,33,44,55) ) -print( 'select(2,11,22,33,44,55)', select(2,11,22,33,44,55) ) -print( 'select(3,11,22,33,44,55)', select(3,11,22,33,44,55) ) -print( 'select(4,11,22,33,44,55)', select(4,11,22,33,44,55) ) -print( 'pcall(select,5,11,22,33,44,55)', pcall(select,5,11,22,33,44,55) ) -print( 'pcall(select,6,11,22,33,44,55)', pcall(select,6,11,22,33,44,55) ) -print( 'pcall(select,7,11,22,33,44,55)', pcall(select,7,11,22,33,44,55) ) -print( 'pcall(select,0,11,22,33,44,55)', pcall(select,0,11,22,33,44,55) ) -print( 'pcall(select,-1,11,22,33,44,55)', pcall(select,-1,11,22,33,44,55) ) -print( 'pcall(select,-2,11,22,33,44,55)', pcall(select,-2,11,22,33,44,55) ) -print( 'pcall(select,-4,11,22,33,44,55)', pcall(select,-4,11,22,33,44,55) ) -print( 'pcall(select,-5,11,22,33,44,55)', pcall(select,-5,11,22,33,44,55) ) -print( 'pcall(select,-6,11,22,33,44,55)', pcall(select,-6,11,22,33,44,55) ) -print( 'pcall(select,1)', pcall(select,1) ) -print( 'pcall(select,select)', pcall(select,select) ) -print( 'pcall(select,{})', pcall(select,{}) ) -print( 'pcall(select,"2",11,22,33)', pcall(select,"2",11,22,33) ) -print( 'pcall(select,"abc",11,22,33)', pcall(select,"abc",11,22,33) ) - - --- tonumber -print( 'pcall(tonumber)', pcall(tostring) ) -print( 'pcall(tonumber,nil)', pcall(tonumber,nil) ) -print( 'pcall(tonumber,"abc")', pcall(tonumber,"abc") ) -print( 'pcall(tonumber,"123")', pcall(tonumber,"123") ) -print( 'pcall(tonumber,"123",10)', pcall(tonumber,"123", 10) ) -print( 'pcall(tonumber,"123",8)', pcall(tonumber,"123", 8) ) -print( 'pcall(tonumber,"123",6)', pcall(tonumber,"123", 6) ) -print( 'pcall(tonumber,"10101",4)', pcall(tonumber,"10101", 4) ) -print( 'pcall(tonumber,"10101",3)', pcall(tonumber,"10101", 3) ) -print( 'pcall(tonumber,"10101",2)', pcall(tonumber,"10101", 2) ) -print( 'pcall(tonumber,"1a1",16)', pcall(tonumber,"1a1", 16) ) -print( 'pcall(tonumber,"1a1",32)', pcall(tonumber,"1a1", 32) ) -print( 'pcall(tonumber,"1a1",54)', pcall(tonumber,"1a1", 54) ) -print( 'pcall(tonumber,"1a1",1)', pcall(tonumber,"1a1", 1) ) -print( 'pcall(tonumber,"1a1",0)', pcall(tonumber,"1a1", 0) ) -print( 'pcall(tonumber,"1a1",-1)', pcall(tonumber,"1a1", -1) ) -print( 'pcall(tonumber,"1a1","32")', pcall(tonumber,"1a1", "32") ) -print( 'pcall(tonumber,"123","456")', pcall(tonumber,"123","456") ) -print( 'pcall(tonumber,"1a1",10)', pcall(tonumber,"1a1", 10) ) -print( 'pcall(tonumber,"151",4)', pcall(tonumber,"151", 4) ) -print( 'pcall(tonumber,"151",3)', pcall(tonumber,"151", 3) ) -print( 'pcall(tonumber,"151",2)', pcall(tonumber,"151", 2) ) -print( 'pcall(tonumber,"123",8,8)', pcall(tonumber,"123", 8, 8) ) -print( 'pcall(tonumber,123)', pcall(tonumber,123) ) -print( 'pcall(tonumber,true)', pcall(tonumber,true) ) -print( 'pcall(tonumber,false)', pcall(tonumber,false) ) -print( 'pcall(tonumber,tonumber)', pcall(tonumber,tonumber) ) -print( 'pcall(tonumber,function() end)', pcall(tonumber,function() end) ) -print( 'pcall(tonumber,{"one","two",a="aa",b="bb"})', pcall(tonumber,{"one","two",a="aa",b="bb"}) ) -print( 'pcall(tonumber,"123.456")', pcall(tonumber,"123.456") ) -print( 'pcall(tonumber," 123.456")', pcall(tonumber," 123.456") ) -print( 'pcall(tonumber," 234qwer")', pcall(tonumber," 234qwer") ) -print( 'pcall(tonumber,"0x20")', pcall(tonumber,"0x20") ) -print( 'pcall(tonumber," 0x20")', pcall(tonumber," 0x20") ) -print( 'pcall(tonumber,"0x20 ")', pcall(tonumber,"0x20 ") ) -print( 'pcall(tonumber," 0x20 ")', pcall(tonumber," 0x20 ") ) -print( 'pcall(tonumber,"0X20")', pcall(tonumber,"0X20") ) -print( 'pcall(tonumber," 0X20")', pcall(tonumber," 0X20") ) -print( 'pcall(tonumber,"0X20 ")', pcall(tonumber,"0X20 ") ) -print( 'pcall(tonumber," 0X20 ")', pcall(tonumber," 0X20 ") ) -print( 'pcall(tonumber,"0x20",10)', pcall(tonumber,"0x20",10) ) -print( 'pcall(tonumber,"0x20",16)', pcall(tonumber,"0x20",16) ) -print( 'pcall(tonumber,"0x20",8)', pcall(tonumber,"0x20",8) ) - --- tostring -print( 'pcall(tostring)', pcall(tostring) ) -print( 'pcall(tostring,nil)', pcall(tostring,nil) ) -print( 'pcall(tostring,"abc")', pcall(tostring,"abc") ) -print( 'pcall(tostring,"abc","def")', pcall(tostring,"abc","def") ) -print( 'pcall(tostring,123)', pcall(tostring,123) ) -print( 'pcall(tostring,true)', pcall(tostring,true) ) -print( 'pcall(tostring,false)', pcall(tostring,false) ) -print( 'tostring(tostring)', type(tostring(tostring)) ) -print( 'tostring(function() end)', type(tostring(function() end)) ) -print( 'tostring({"one","two",a="aa",b="bb"})', type(tostring({"one","two",a="aa",b="bb"})) ) - --- _VERSION -print( '_VERSION', type(_VERSION) ) - --- xpcall -local errfunc = function( detail ) - print( ' in errfunc', type(detail) ) - return 'response-from-xpcall' -end -local badfunc = function() error( 'error-from-badfunc' ) end -local wrappedbad = function() pcall( badfunc ) end -print( 'pcall(badfunc)', pcall(badfunc) ) -print( 'pcall(badfunc,errfunc)', pcall(badfunc,errfunc) ) -print( 'pcall(badfunc,badfunc)', pcall(badfunc,badfunc) ) -print( 'pcall(wrappedbad)', pcall(wrappedbad) ) -print( 'pcall(wrappedbad,errfunc)', pcall(wrappedbad,errfunc) ) -print( 'pcall(xpcall(badfunc))', pcall(xpcall,badfunc) ) -print( 'pcall(xpcall(badfunc,errfunc))', pcall(xpcall,badfunc,errfunc) ) -print( 'pcall(xpcall(badfunc,badfunc))', pcall(xpcall,badfunc,badfunc) ) -print( 'pcall(xpcall(wrappedbad))', pcall(xpcall,wrappedbad) ) -print( 'xpcall(wrappedbad,errfunc)', xpcall(wrappedbad,errfunc) ) - diff --git a/test/lua/coroutinelib.lua b/test/lua/coroutinelib.lua deleted file mode 100644 index 468dc1f7..00000000 --- a/test/lua/coroutinelib.lua +++ /dev/null @@ -1,126 +0,0 @@ -function printrunning() - if coroutine.running() == nil then - print("running is nil"); - else - print("running is not nil") - end -end - -function foo (a) - print("foo", a) - return coroutine.yield(2*a) -end - -co = coroutine.create(function (a,b) - print("co-body", a, b) - local r = foo(a+1) - print("co-body", r) - local r, s = coroutine.yield(a+b, a-b) - print("co-body", r, s) - - printrunning() - print("co.status.inside",coroutine.status(co)); - local co2 = coroutine.create(function() - print("co.status.inside2",coroutine.status(co)); - end) - print("co.status.inside",coroutine.status(co)); - coroutine.resume(co2); - - return b, "end" -end) - -function exercise() - printrunning() - print("co.status",coroutine.status(co)); - print("main", coroutine.resume(co, 1, 10)) - print("co.status",coroutine.status(co)); - print("main", coroutine.resume(co, "r")) - print("co.status",coroutine.status(co)); - print("main", coroutine.resume(co, "x", "y")) - print("co.status",coroutine.status(co)); - print("main", coroutine.resume(co, "x", "y")) - print("co.status",coroutine.status(co)); -end - -exercise(); - -co = coroutine.create(function (a,b) - print("co-body", a, b) --- TODO: make java and C behave the same for yielding in pcalls --- local status,r = pcall( foo, a+1 ) -foo(a+1) - print("co-body", status,r) - local r, s = coroutine.yield(a+b, a-b) - print("co-body", r, s) - return b, "end" -end) - -exercise(); - - --- wrap test -local g = coroutine.wrap(function (a,b) - print("co-body", a, b) - local r = foo(a+1) - print("co-body", r) - local r, s = coroutine.yield(a+b, a-b) - print("co-body", r, s) - return b, "end" -end ) - -print("g", g(1, 10)) -print("g", g("r")) -print("g", g("x", "y")) -local s,e = pcall( g, "x", "y" ) -print("g", string.match(e,'cannot resume dead coroutine') or 'badmessage: '..tostring(e)) - --- varargs passing -local echo = function(msg,...) - print( msg, ...) - return ... -end -local echocr = function(...) - local arg = table.pack(...) - echo('(echocr) first args', table.unpack(arg,1,arg.n)) - local a = arg - while true do - a = { echo( '(echoch) yield returns', coroutine.yield( table.unpack(a) ) ) } - end -end -local c = coroutine.create( echocr ) -local step = function(...) - echo( '(main) resume returns', - coroutine.resume(c, echo('(main) sending args', ...)) ) -end -step(111,222,333) -step() -step(111) -step(111,222,333) - --- test loops in resume calls -b = coroutine.create( function( arg ) - while ( true ) do - print( ' b-resumed', arg, b == coroutine.running() ) - print( ' b-b', coroutine.status(b) ) - print( ' b-c', coroutine.status(c) ) - print( ' b-resume-b',coroutine.resume( b, 'b-arg-for-b' ) ) - print( ' b-resume-c',coroutine.resume( c, 'b-arg-for-c' ) ) - arg = coroutine.yield( 'b-rslt' ) - end -end ) -c = coroutine.create( function( arg ) - for i=1,3 do - print( ' c-resumed', arg, c == coroutine.running() ) - print( ' c-b', coroutine.status(b) ) - print( ' c-c', coroutine.status(c) ) - print( ' c-resume-b',coroutine.resume( b, 'b-arg-for-b' ) ) - print( ' c-resume-c',coroutine.resume( c, 'b-arg-for-c' ) ) - arg = coroutine.yield( 'c-rslt' ) - end -end ) -for i=1,3 do - print( 'main-b', coroutine.status(b) ) - print( 'main-c', coroutine.status(c) ) - print( 'main-resume-b',coroutine.resume( b, 'main-arg-for-b' ) ) - print( 'main-resume-c',coroutine.resume( c, 'main-arg-for-c' ) ) -end diff --git a/test/lua/debuglib.lua b/test/lua/debuglib.lua deleted file mode 100644 index 11894486..00000000 --- a/test/lua/debuglib.lua +++ /dev/null @@ -1,280 +0,0 @@ - -local print,tostring,_G,pcall,ipairs,isnumber = print,tostring,_G,pcall,ipairs,isnumber -local e,f,g,h,s -print( 'has debug', debug~=nil ) -if not debug then error( 'no debug' ) end - - -print( '----- debug.getlocal, debug.setlocal' ) -h = function(v,i,n) - s = 'h-'..v..'-'..i - local x1,y1 = debug.getlocal(v,i) - local x2,y2 = debug.setlocal(v,i,n) - local x3,y3 = debug.getlocal(v,i) - return s..' -> '..v..'-'..i..' '.. - 'get='..tostring(x1)..','..tostring(y1)..' '.. - 'set='..tostring(x2)..','..tostring(y2)..' '.. - 'get='..tostring(x3)..','..tostring(y3)..' ' -end -g = function(...) - local p,q,r=7,8,9 - local t = h(...) - local b = table.concat({...},',') - return t..'\tg locals='..p..','..q..','..r..' tbl={'..b..'}' -end -f = function(a,b,c) - local d,e,f = 4,5,6 - local t = g(a,b,c) - return t..'\tf locals='..','..a..','..b..','..c..','..d..','..e..','..f -end -for lvl=3,2,-1 do - for lcl=0,7 do - print( pcall( f, lvl, lcl, '#' ) ) - end -end -for lvl=1,1 do - for lcl=3,7 do - print( pcall( f, lvl, lcl, '#' ) ) - end -end - - -print( '----- debug.getupvalue, debug.setupvalue' ) -local m,n,o = 101,102,103 -f = function(p,q,r) - local p,q,r = 104,105,106 - local g = function(s,t,u) - local v,w,x = 107,108,109 - return function() - return m,n,o,p,q,r,v,w,x - end - end - return g -end -g = f() -h = g() -local callh = function() - local t = {} - for i,v in ipairs( { pcall(h) } ) do - t[i] = tostring(v) - end - return table.concat(t,',') -end -print( 'h', h() ) -local funs = { f, g, h } -local names = { 'f', 'g', 'h' } -for i=1,3 do - local fun,name = funs[i],names[i] - for index=0,10 do - local s1,x1,y1 = pcall( debug.getupvalue, fun, index ) - local s2,x2,y2 = pcall( debug.setupvalue, fun, index, 666000+i*111000+index ) - local s3,x3,y3 = pcall( debug.getupvalue, fun, index ) - print( name..' -> '..i..'-'..index..' '.. - 'get='..tostring(s1)..','..tostring(x1)..','..tostring(y1)..' '.. - 'set='..tostring(s2)..','..tostring(x2)..','..tostring(y2)..' '.. - 'get='..tostring(s3)..','..tostring(x3)..','..tostring(y3)..' '.. - 'tbl='..callh() ) - end -end - -print( '----- debug.setmetatable, debug.getmetatable' ) -local a = {a='bbb'} -local b = {} -local mt = {__index={b='ccc'}} -print( 'a.a='..tostring(a.a)..' a.b='..tostring(a.b)..' b.a='..tostring(b.a)..' b.b='..tostring(b.b)) -local s1,x1,y1 = pcall( debug.getmetatable, a ) -local s2,x2,y2 = pcall( debug.setmetatable, a, mt ) -print( 'a.a='..tostring(a.a)..' a.b='..tostring(a.b)..' b.a='..tostring(b.a)..' b.b='..tostring(b.b)) -local s3,x3,y3 = pcall( debug.getmetatable, a ) print(type(s3), type(x3), type(y3), type(getmetatable(a))) -local s4,x4,y4 = pcall( debug.getmetatable, b ) print(type(s4), type(x4), type(y4), type(getmetatable(b))) -local s5,x5,y5 = pcall( debug.setmetatable, a, nil ) print(type(s5), type(x5), type(y5), type(getmetatable(a))) -print( 'a.a='..tostring(a.a)..' a.b='..tostring(a.b)..' b.a='..tostring(b.a)..' b.b='..tostring(b.b)) -local s6,x6,y6 = pcall( debug.getmetatable, a ) print(type(s6), type(x6), type(y6), type(getmetatable(a))) -if not s1 then print( 's1 error', x1 ) end -if not s2 then print( 's2 error', x2 ) end -if not s3 then print( 's3 error', x3 ) end -if not s4 then print( 's4 error', x4 ) end -if not s5 then print( 's5 error', x5 ) end -if not s6 then print( 's6 error', x6 ) end -print( 'get='..tostring(s1)..','..tostring(x1==nil)..','..tostring(y1) ) -print( 'set='..tostring(s2)..','..tostring(x2==a)..','..tostring(y2) ) -print( 'get='..tostring(s3)..','..tostring(x3==mt)..','..tostring(y3) ) -print( 'get='..tostring(s4)..','..tostring(x4==nil)..','..tostring(y4) ) -print( 'set='..tostring(s5)..','..tostring(x5==a)..','..tostring(y5) ) -print( 'get='..tostring(s6)..','..tostring(x6==nil)..','..tostring(y6) ) -print( pcall( debug.getmetatable, 1 ) ) -print( pcall( debug.setmetatable, 1, {} ) ) -print( pcall( debug.setmetatable, 1, nil ) ) - -print( '----- debug.getinfo' ) -local printfield = function(tbl, field) - local x = tbl[field] - if x == nil then return end - local typ = type(x) - if typ=='table' then - x = '{'..table.concat(x,',')..'}' - elseif typ=='function' then - x = typ - end - print( ' '..field..': '..tostring(x) ) -end -local fields = { 'source', 'short_src', 'what', - 'currentline', 'linedefined', 'lastlinedefined', - 'nups', 'func', 'activelines' } -local printinfo = function(...) - for i,a in ipairs({...}) do - if type(a) == 'table' then - for j,field in ipairs(fields) do - printfield( a, field) - end - else - print( tostring(a) ) - end - end -end -function test() - local x = 5 - function f() - x = x + 1 - return x - end - function g() - x = x - 1 - print( '---' ) - printinfo( 'debug.getinfo(1)', debug.getinfo(1) ) - printinfo( 'debug.getinfo(1,"")', debug.getinfo(1, "") ) - printinfo( 'debug.getinfo(1,"l")', debug.getinfo(1, "l") ) - printinfo( 'debug.getinfo(1,"fL")', debug.getinfo(1, "fL") ) - printinfo( 'debug.getinfo(2)', debug.getinfo(2) ) - printinfo( 'debug.getinfo(2,"l")', debug.getinfo(2, "l") ) - printinfo( 'debug.getinfo(2,"fL")', debug.getinfo(2, "fL") ) - printinfo( 'debug.getinfo(10,"")', pcall( debug.getinfo, 10, "" ) ) - printinfo( 'debug.getinfo(-10,"")', pcall( debug.getinfo, -10, "" ) ) - print( '---' ) - return x - end - print(f()) - print(g()) - return f, g -end - -local options = "nSlufL" -local e,f,g = pcall( test ) -print( 'e,f,g', e, type(f), type(g) ) -printinfo( 'debug.getinfo(f)', pcall(debug.getinfo, f) ) -printinfo( 'debug.getinfo(f,"'..options..'")', pcall(debug.getinfo, f, options) ) -for j=1,6 do - local opts = options:sub(j,j) - printinfo( 'debug.getinfo(f,"'..opts..'")', pcall(debug.getinfo, f, opts) ) -end -printinfo( 'debug.getinfo(g)', pcall(debug.getinfo, g) ) -printinfo( 'debug.getinfo(test)', pcall(debug.getinfo, test) ) - -print( '----- debug.sethook, debug.gethook' ) -f = function(x) - g = function(y) - return math.min(x,h) - end - local a = g(x) - return a + a -end -local hook = function(...) - print( ' ... in hook', ... ) - local info = debug.getinfo(2,"Sl") - if info then - print( ' info[2]='..tostring(info.short_src)..','..tostring(info.currentline) ) - end -end -local tryfunc = function(hook,mask,func,arg) - local x,f,h,m - pcall( function() - debug.sethook(hook,mask) - x = func(arg) - f,h,m = debug.gethook() - end ) - debug.sethook() - return x,f,h,m -end - -local tryhooks = function(mask) - local s1,a1,b1,c1,d1 = pcall( tryfunc, hook, mask, f, 333 ) - print( 'hook = '..mask..' -> '.. - 'result='..tostring(s1)..','..tostring(a1)..','.. - type(b1)..','..type(c1)..','.. - tostring(b1==f)..','..tostring(c1==hook)..','.. - tostring(d1)..' ' ) -end - -tryhooks("c") -tryhooks("r") -tryhooks("l") -tryhooks("crl") - -print( '----- debug.traceback' ) -function test() - function a(msg) - print((string.gsub(debug.traceback(msg), "%[Java]", "[C]"))) - end - local function b(msg) - pcall(a,msg) - end - c = function(i) - if i <= 0 then b('hi') return end - return c(i-1) - end - d = setmetatable({},{__index=function(t,k) v = c(k) return v end}) - local e = function() - return d[0] - end - local f = { - g = function() - e() - end - } - h = function() - f.g() - end - local i = h - i() -end -pcall(test) - - -print( '----- debug.upvalueid' ) -local x,y = 100,200 -function a(b,c) - local z,w = b,c - return function() - x,y,z,w = x+1,y+1,z+1,w+1 - return x,y,z,w - end -end -a1 = a(300,400) -a2 = a(500,600) -print('debug.getupvalue(a1,1)', debug.getupvalue(a1,1)) -print('debug.getupvalue(a1,2)', debug.getupvalue(a1,2)) -print('debug.getupvalue(a2,1)', debug.getupvalue(a2,1)) -print('debug.getupvalue(a2,2)', debug.getupvalue(a2,2)) -print('debug.upvalueid(a1,1) == debug.upvalueid(a1,1)', debug.upvalueid(a1,1) == debug.upvalueid(a1,1)) -print('debug.upvalueid(a1,1) == debug.upvalueid(a2,1)', debug.upvalueid(a1,1) == debug.upvalueid(a2,1)) -print('debug.upvalueid(a1,1) == debug.upvalueid(a1,2)', debug.upvalueid(a1,1) == debug.upvalueid(a1,2)) - -print( '----- debug.upvaluejoin' ) -print('a1',a1()) -print('a2',a2()) -print('debug.upvaluejoin(a1,1,a2,2)', debug.upvaluejoin(a1,1,a2,2)) -print('debug.upvaluejoin(a1,3,a2,4)', debug.upvaluejoin(a1,3,a2,4)) -print('a1',a1()) -print('a2',a2()) -print('a1',a1()) -print('a2',a2()) -for i = 1,4 do - print('debug.getupvalue(a1,'..i..')', debug.getupvalue(a1,i)) - print('debug.getupvalue(a2,'..i..')', debug.getupvalue(a2,i)) - for j = 1,4 do - print('debug.upvalueid(a1,'..i..') == debug.upvalueid(a1,'..j..')', debug.upvalueid(a1,i) == debug.upvalueid(a1,j)) - print('debug.upvalueid(a1,'..i..') == debug.upvalueid(a2,'..j..')', debug.upvalueid(a1,i) == debug.upvalueid(a2,j)) - print('debug.upvalueid(a2,'..i..') == debug.upvalueid(a1,'..j..')', debug.upvalueid(a2,i) == debug.upvalueid(a1,j)) - print('debug.upvalueid(a2,'..i..') == debug.upvalueid(a2,'..j..')', debug.upvalueid(a2,i) == debug.upvalueid(a2,j)) - end -end diff --git a/test/lua/errors.lua b/test/lua/errors.lua deleted file mode 100644 index 3ed06c2e..00000000 --- a/test/lua/errors.lua +++ /dev/null @@ -1,137 +0,0 @@ --- tostring replacement that assigns ids -local ts,id,nid,types = tostring,{},0,{table='tbl',thread='thr',userdata='uda',['function']='func'} -tostring = function(x) - if not x or not types[type(x)] then return ts(x) end - if not id[x] then nid=nid+1; id[x]=types[type(x)]..'.'..nid end - return id[x] -end - --- test of common types of errors --- local function c(f,...) return f(...) end --- local function b(...) return c(...) end ---local function a(...) return (pcall(b,...)) end -local function a(...) local s,e=pcall(...) if s then return s,e else return false,type(e) end end -s = 'some string' -local t = {} --- error message tests -print( 'a(error)', a(error) ) -print( 'a(error,"msg")', a(error,"msg") ) -print( 'a(error,"msg",0)', a(error,"msg",0) ) -print( 'a(error,"msg",1)', a(error,"msg",1) ) -print( 'a(error,"msg",2)', a(error,"msg",2) ) -print( 'a(error,"msg",3)', a(error,"msg",3) ) -print( 'a(error,"msg",4)', a(error,"msg",4) ) -print( 'a(error,"msg",5)', a(error,"msg",5) ) -print( 'a(error,"msg",6)', a(error,"msg",6) ) - --- call errors -print( 'a(nil())', a(function() return n() end) ) -print( 'a(t()) ', a(function() return t() end) ) -print( 'a(s()) ', a(function() return s() end) ) -print( 'a(true())', a(function() local b = true; return b() end) ) - --- arithmetic errors -print( 'a(nil+1)', a(function() return nil+1 end) ) -print( 'a(a+1) ', a(function() return a+1 end) ) -print( 'a(s+1) ', a(function() return s+1 end) ) -print( 'a(true+1)', a(function() local b = true; return b+1 end) ) - --- table errors -print( 'a(nil.x)', a(function() return n.x end) ) -print( 'a(a.x) ', a(function() return a.x end) ) -print( 'a(s.x) ', a(function() return s.x end) ) -print( 'a(true.x)', a(function() local b = true; return b.x end) ) -print( 'a(nil.x=5)', a(function() n.x=5 end) ) -print( 'a(a.x=5) ', a(function() a.x=5 end) ) -print( 'a(s.x=5) ', a(function() s.x=5 end) ) -print( 'a(true.x=5)', a(function() local b = true; b.x=5 end) ) - --- len operator -print( 'a(#nil) ', a(function() return #n end) ) -print( 'a(#t) ', a(function() return #t end) ) -print( 'a(#s) ', a(function() return #s end) ) -print( 'a(#a) ', a(function() return #a end) ) -print( 'a(#true)', a(function() local b = true; return #b end) ) - --- comparison errors -print( 'a(nil>1)', a(function() return nil>1 end) ) -print( 'a(a>1) ', a(function() return a>1 end) ) -print( 'a(s>1) ', a(function() return s>1 end) ) -print( 'a(true>1)', a(function() local b = true; return b>1 end) ) - --- unary minus errors -print( 'a(-nil)', a(function() return -n end) ) -print( 'a(-a) ', a(function() return -a end) ) -print( 'a(-s) ', a(function() return -s end) ) -print( 'a(-true)', a(function() local b = true; return -b end) ) - --- string concatenation -local function concatsuite(comparefunc) - print( '"a".."b"', comparefunc("a","b") ) - print( '"a"..nil', comparefunc("a",nil) ) - print( 'nil.."b"', comparefunc(nil,"b") ) - print( '"a"..{}', comparefunc("a",{}) ) - print( '{}.."b"', comparefunc({},"b") ) - print( '"a"..2', comparefunc("a",2) ) - print( '2.."b"', comparefunc(2,"b") ) - print( '"a"..print', comparefunc("a",print) ) - print( 'print.."b"', comparefunc(print,"b") ) - print( '"a"..true', comparefunc("a",true) ) - print( 'true.."b"', comparefunc(true,"b") ) - print( 'nil..true', comparefunc(nil,true) ) - print( '"a"..3.5', comparefunc("a",3.5) ) - print( '3.5.."b"', comparefunc(3.5,"b") ) -end -local function strconcat(a,b) - return (pcall( function() return a..b end) ) -end -local function tblconcat(a,b) - local t={a,b} - return (pcall( function() return table.concat(t,'-',1,2) end )) -end - -print( '-------- string concatenation' ) -concatsuite(strconcat) -print( '-------- table concatenation' ) -concatsuite(tblconcat) - --- pairs -print( '-------- pairs tests' ) -print( 'a(pairs(nil))', a(function() return pairs(nil,{}) end) ) -print( 'a(pairs(a)) ', a(function() return pairs(a,{}) end) ) -print( 'a(pairs(s)) ', a(function() return pairs(s,{}) end) ) -print( 'a(pairs(t)) ', a(function() return pairs(t,{}) end) ) -print( 'a(pairs(true))', a(function() local b = true; return pairs(b,{}) end) ) - --- setmetatable -print( '-------- setmetatable tests' ) -function sm(...) - return tostring(setmetatable(...)) -end -print( 'a(setmetatable(nil))', a(function() return sm(nil,{}) end) ) -print( 'a(setmetatable(a)) ', a(function() return sm(a,{}) end) ) -print( 'a(setmetatable(s)) ', a(function() return sm(s,{}) end) ) -print( 'a(setmetatable(true))', a(function() local b = true; return sm(b,{}) end) ) -print( 'a(setmetatable(t)) ', a(function() return sm(t,{}) end) ) -print( 'a(getmetatable(t)) ', a(function() return getmetatable(t),type(getmetatable(t)) end) ) -print( 'a(setmetatable(t*)) ', a(function() return sm(t,{__metatable={}}) end) ) -print( 'a(getmetatable(t)) ', a(function() return getmetatable(t),type(getmetatable(t)) end) ) -print( 'a(setmetatable(t)) ', a(function() return sm(t,{}) end) ) -print( 'a(getmetatable(t)) ', a(function() return getmetatable(t),type(getmetatable(t)) end) ) -t = {} -print( 'a(setmetatable(t)) ', a(function() return sm(t,{}) end) ) -print( 'a(getmetatable(t)) ', a(function() return getmetatable(t),type(getmetatable(t)) end) ) -print( 'a(setmetatable(t*)) ', a(function() return sm(t,{__metatable='some string'}) end) ) -print( 'a(getmetatable(t)) ', a(function() return getmetatable(t),type(getmetatable(t)) end) ) -print( 'a(setmetatable(t)) ', a(function() return sm(t,{}) end) ) -print( 'a(getmetatable(t)) ', a(function() return getmetatable(t),type(getmetatable(t)) end) ) -print( 'a(setmetatable(t,nil)) ', a(function() return sm(t,nil) end) ) -print( 'a(setmetatable(t)) ', a(function() return sm(t) end) ) -print( 'a(setmetatable({},"abc")) ', a(function() return sm({},'abc') end) ) - --- bad args to error! -print( 'error("msg","arg")', a(function() error('some message', 'some bad arg') end) ) - --- loadfile, dofile on missing files -print( 'loadfile("bogus.txt")', a(function() return loadfile("bogus.txt") end) ) -print( 'dofile("bogus.txt")', a(function() return dofile("bogus.txt") end) ) diff --git a/test/lua/errors/args.lua b/test/lua/errors/args.lua deleted file mode 100644 index f74e48fa..00000000 --- a/test/lua/errors/args.lua +++ /dev/null @@ -1,198 +0,0 @@ --- utilities to check that args of various types pass or fail --- argument type checking -local ok = '-\t' -local fail = 'fail ' -local needcheck = 'needcheck ' -local badmsg = 'badmsg ' - -akey = 'aa' -astring = 'abc' -astrnum = '789' -anumber = 1.25 -ainteger = 345 -adouble = 12.75 -aboolean = true -atable = {[akey]=456} -afunction = function() end -anil = nil -athread = coroutine.create(afunction) - -anylua = { nil, astring, anumber, aboolean, atable, afunction, athread } - -somestring = { astring, anumber } -somenumber = { anumber, astrnum } -someboolean = { aboolean } -sometable = { atable } -somefunction = { afunction } -somenil = { anil } -somekey = { akey } -notakey = { astring, anumber, aboolean, atable, afunction } - -notastring = { nil, aboolean, atable, afunction, athread } -notanumber = { nil, astring, aboolean, atable, afunction, athread } -notaboolean = { nil, astring, anumber, atable, afunction, athread } -notatable = { nil, astring, anumber, aboolean, afunction, athread } -notafunction = { nil, astring, anumber, aboolean, atable, athread } -notathread = { nil, astring, anumber, aboolean, atable, afunction } -notanil = { astring, anumber, aboolean, atable, afunction, athread } - -nonstring = { aboolean, atable, afunction, athread } -nonnumber = { astring, aboolean, atable, afunction, athread } -nonboolean = { astring, anumber, atable, afunction, athread } -nontable = { astring, anumber, aboolean, afunction, athread } -nonfunction = { astring, anumber, aboolean, atable, athread } -nonthread = { astring, anumber, aboolean, atable, afunction } -nonkey = { astring, anumber, aboolean, atable, afunction } - -local structtypes = { - ['table']='', - ['function']='', - ['thread']='', - ['userdata']='', -} - -local function bracket(v) - return "<"..type(v)..">" -end - -local function quote(v) - return "'"..v.."'" -end - -local function ellipses(v) - local s = tostring(v) - return #s <= 8 and s or (string.sub(s,1,8)..'...') -end - -local pretty = { - ['table']=bracket, - ['function']=bracket, - ['thread']=bracket, - ['userdata']=bracket, - ['string']= quote, - ['number']= ellipses, -} - -local function values(list) - local t = {} - for i=1,(list.n or #list) do - local ai = list[i] - local fi = pretty[type(ai)] - t[i] = fi and fi(ai) or tostring(ai) - end - return table.concat(t,',') -end - -local function types(list) - local t = {} - for i=1,(list.n or #list) do - local ai = list[i] - t[i] = type(ai) - end - return table.concat(t,',') -end - -local function signature(name,arglist) - return name..'('..values(arglist)..')' -end - -local function dup(t) - local s = {} - for i=1,(t.n or #t) do - s[i] = t[i] - end - return s -end - -local function split(t) - local s = {} - local n = (t.n or #t) - for i=1,n-1 do - s[i] = t[i] - end - return s,t[n] -end - -local function expand(argsets, typesets, ...) - local arg = table.pack(...) - local n = typesets and #typesets or 0 - if n <= 0 then - table.insert(argsets,arg) - return argsets - end - - local s,v = split(typesets) - for i=1,(v.n or #v) do - expand(argsets, s, v[i], table.unpack(arg,1,arg.n)) - end - return argsets -end - -local function arglists(typesets) - local argsets = expand({},typesets) - return ipairs(argsets) -end - -function lookup( name ) - return load('return '..name)() -end - -function invoke( name, arglist ) - local s,c = pcall(lookup, name) - if not s then return s,c end - return pcall(c, table.unpack(arglist,1,arglist.n or #arglist)) -end - --- messages, banners -local _print = print -local _tostring = tostring -local _find = string.find -function banner(name) - _print( '====== '.._tostring(name)..' ======' ) -end - -local function subbanner(name) - _print( '--- '.._tostring(name) ) -end - -local function pack(s,...) - return s,{...} -end - --- check that all combinations of arguments pass -function checkallpass( name, typesets, typesonly ) - subbanner('checkallpass') - for i,v in arglists(typesets) do - local sig = signature(name,v) - local s,r = pack( invoke( name, v ) ) - if s then - if typesonly then - _print( ok, sig, types(r) ) - else - _print( ok, sig, values(r) ) - end - else - _print( fail, sig, values(r) ) - end - end -end - --- check that all combinations of arguments fail in some way, --- ignore error messages -function checkallerrors( name, typesets, template ) - subbanner('checkallerrors') - template = _tostring(template) - for i,v in arglists(typesets) do - local sig = signature(name,v) - local s,e = invoke( name, v ) - if not s then - if _find(e, template, 1, true) then - _print( ok, sig, '...'..template..'...' ) - else - _print( badmsg, sig, "template='"..template.."' actual='"..e.."'" ) - end - else - _print( needcheck, sig, e ) - end - end -end diff --git a/test/lua/errors/baselibargs.lua b/test/lua/errors/baselibargs.lua deleted file mode 100644 index a2cc6d1c..00000000 --- a/test/lua/errors/baselibargs.lua +++ /dev/null @@ -1,145 +0,0 @@ -package.path = "?.lua;test/lua/errors/?.lua" -require 'args' - --- arg types for basic library functions - --- assert -banner('assert') -checkallpass('assert',{{true,123},anylua}) -checkallerrors('assert',{{nil,false,n=2},{nil,n=1}},'assertion failed') -checkallerrors('assert',{{nil,false,n=2},{'message'}},'message') - --- collectgarbage -banner('collectgarbage') -checkallpass('collectgarbage',{{'collect','count'}},true) -checkallerrors('collectgarbage',{{astring, anumber}},'bad argument') -checkallerrors('collectgarbage',{{aboolean, atable, afunction, athread}},'string expected') - --- dofile -banner('dofile') ---checkallpass('dofile', {}) ---checkallpass('dofile', {{'test/lua/errors/args.lua'}}) ---checkallerrors('dofile', {{'foo.bar'}}, 'cannot open foo.bar') ---checkallerrors('dofile', {nonstring}, 'bad argument') - --- error -banner('error') ---checkallerrors('error', {{'message'},{nil,0,1,2,n=4}}, 'message') ---checkallerrors('error', {{123},{nil,1,2,n=3}}, 123) - --- getmetatable -banner('getmetatable') -checkallpass('getmetatable', {notanil}) -checkallerrors('getmetatable',{},'bad argument') - --- ipairs -banner('ipairs') -checkallpass('ipairs', {sometable}) -checkallerrors('ipairs', {notatable}, 'bad argument') - --- load -banner('load') -checkallpass('load', {somefunction,{nil,astring,n=2}}) -checkallerrors('load', {notafunction,{nil,astring,anumber,n=3}}, 'bad argument') -checkallerrors('load', {somefunction,{afunction,atable}}, 'bad argument') - --- loadfile -banner('loadfile') ---checkallpass('loadfile', {}) ---checkallpass('loadfile', {{'bogus'}}) ---checkallpass('loadfile', {{'test/lua/errors/args.lua'}}) ---checkallpass('loadfile', {{'args.lua'}}) ---checkallerrors('loadfile', {nonstring}, 'bad argument') - --- load -banner('load') -checkallpass('load', {{'return'}}) -checkallpass('load', {{'return'},{'mychunk'}}) -checkallpass('load', {{'return a ... b'},{'mychunk'}},true) -checkallerrors('load', {notastring,{nil,astring,anumber,n=3}}, 'bad argument') -checkallerrors('load', {{'return'},{afunction,atable}}, 'bad argument') - --- next -banner('next') -checkallpass('next', {sometable,somekey}) -checkallerrors('next', {notatable,{nil,1,n=2}}, 'bad argument') -checkallerrors('next', {sometable,nonkey}, 'invalid key') - --- pairs -banner('pairs') -checkallpass('pairs', {sometable}) -checkallerrors('pairs', {notatable}, 'bad argument') - --- pcall -banner('pcall') -checkallpass('pcall', {notanil,anylua}, true) -checkallerrors('pcall',{},'bad argument') - --- print -banner('print') -checkallpass('print', {}) -checkallpass('print', {{nil,astring,anumber,aboolean,n=4}}) - --- rawequal -banner('rawequal') -checkallpass('rawequal', {notanil,notanil}) -checkallerrors('rawequal', {}, 'bad argument') -checkallerrors('rawequal', {notanil}, 'bad argument') - --- rawget -banner('rawget') -checkallpass('rawget', {sometable,somekey}) -checkallpass('rawget', {sometable,nonkey}) -checkallerrors('rawget', {sometable,somenil},'bad argument') -checkallerrors('rawget', {notatable,notakey}, 'bad argument') -checkallerrors('rawget', {}, 'bad argument') - --- rawset -banner('rawset') -checkallpass('rawset', {sometable,somekey,notanil}) -checkallpass('rawset', {sometable,nonkey,notanil}) -checkallerrors('rawset', {sometable,somenil},'table index is nil') -checkallerrors('rawset', {}, 'bad argument') -checkallerrors('rawset', {notatable,somestring,somestring}, 'bad argument') -checkallerrors('rawset', {sometable,somekey}, 'bad argument') - --- select -banner('select') -checkallpass('select', {{anumber,'#'},anylua}) -checkallerrors('select', {notanumber}, 'bad argument') - --- setmetatable -banner('setmetatable') -checkallpass('setmetatable', {sometable,sometable}) -checkallpass('setmetatable', {sometable,{}}) -checkallerrors('setmetatable',{notatable,sometable},'bad argument') -checkallerrors('setmetatable',{sometable,nontable},'bad argument') - --- tonumber -banner('tonumber') -checkallpass('tonumber',{somenumber,{nil,2,10,36,n=4}}) -checkallpass('tonumber',{notanil,{nil,10,n=2}}) -checkallerrors('tonumber',{{nil,afunction,atable,n=3},{2,9,11,36}},'bad argument') -checkallerrors('tonumber',{somenumber,{1,37,atable,afunction,aboolean}},'bad argument') - --- tostring -banner('tostring') -checkallpass('tostring',{{astring,anumber,aboolean}}) -checkallpass('tostring',{{atable,afunction,athread}},true) -checkallpass('tostring',{{astring,anumber,aboolean},{'anchor'}}) -checkallpass('tostring',{{atable,afunction,athread},{'anchor'}},true) -checkallerrors('tostring',{},'bad argument') - --- type -banner('type') -checkallpass('type',{notanil}) -checkallpass('type',{anylua,{'anchor'}}) -checkallerrors('type',{},'bad argument') - --- xpcall -banner('xpcall') -checkallpass('xpcall', {notanil,nonfunction}) -checkallpass('xpcall', {notanil,{function(...)return 'aaa', 'bbb', #{...} end}}) -checkallerrors('xpcall',{anylua},'bad argument') - - diff --git a/test/lua/errors/coroutinelibargs.lua b/test/lua/errors/coroutinelibargs.lua deleted file mode 100644 index caad6200..00000000 --- a/test/lua/errors/coroutinelibargs.lua +++ /dev/null @@ -1,47 +0,0 @@ -package.path = "?.lua;test/lua/errors/?.lua" -require 'args' - --- arg type tests for coroutine library functions - --- coroutine.create -banner('coroutine.create') -checkallpass('coroutine.create',{somefunction}) -checkallerrors('coroutine.create',{notafunction},'bad argument') - --- coroutine.resume -banner('coroutine.resume') -local co = coroutine.create(function() while true do coroutine.yield() end end) -checkallpass('coroutine.resume',{{co},anylua}) -checkallerrors('coroutine.resume',{notathread},'bad argument') - --- coroutine.running -banner('coroutine.running') -checkallpass('coroutine.running',{anylua}) - --- coroutine.status -banner('coroutine.status') -checkallpass('coroutine.status',{{co}}) -checkallerrors('coroutine.status',{notathread},'bad argument') - --- coroutine.wrap -banner('coroutine.wrap') -checkallpass('coroutine.wrap',{somefunction}) -checkallerrors('coroutine.wrap',{notafunction},'bad argument') - --- coroutine.yield -banner('coroutine.yield') -local function f() - print( 'yield', coroutine.yield() ) - print( 'yield', coroutine.yield(astring,anumber,aboolean) ) - error('error within coroutine thread') -end -local co = coroutine.create( f ) -print( 'status', coroutine.status(co) ) -print( coroutine.resume(co,astring,anumber) ) -print( 'status', coroutine.status(co) ) -print( coroutine.resume(co,astring,anumber) ) -print( 'status', coroutine.status(co) ) -local s,e = coroutine.resume(co,astring,anumber) -print( s, string.match(e,'error within coroutine thread') or 'bad message: '..tostring(e) ) -print( 'status', coroutine.status(co) ) - diff --git a/test/lua/errors/debuglibargs.lua b/test/lua/errors/debuglibargs.lua deleted file mode 100644 index ad4a9300..00000000 --- a/test/lua/errors/debuglibargs.lua +++ /dev/null @@ -1,150 +0,0 @@ -package.path = "?.lua;test/lua/errors/?.lua" -require 'args' - -local alevel = {25,'25'} -local afuncorlevel = {afunction,25,'25'} -local notafuncorlevel = {nil,astring,aboolean,athread} -local notafuncorthread = {nil,astring,aboolean} - --- debug.debug() -banner('debug.debug - no tests') - --- debug.gethook ([thread]) -banner('debug.gethook') -checkallpass('debug.gethook',{}) - --- debug.getinfo ([thread,] f [, what]) -banner('debug.getinfo') -local awhat = {"","n","flnStu"} -local notawhat = {"qzQZ"} -checkallpass('debug.getinfo',{afuncorlevel}) -checkallpass('debug.getinfo',{somethread,afuncorlevel}) -checkallpass('debug.getinfo',{afuncorlevel,awhat}) -checkallpass('debug.getinfo',{somethread,afuncorlevel,awhat}) -checkallerrors('debug.getinfo',{},'function or level') -checkallerrors('debug.getinfo',{notafuncorlevel},'function or level') -checkallerrors('debug.getinfo',{somefunction,nonstring}, 'string expected') -checkallerrors('debug.getinfo',{notafuncorthread,somefunction}, 'string expected') -checkallerrors('debug.getinfo',{nonthread,somefunction,{astring}}, 'string expected') -checkallerrors('debug.getinfo',{somethread,somefunction,notawhat}, 'invalid option') - --- debug.getlocal ([thread,] f, local) -banner('debug.getlocal') -local p,q = 'p','q'; -f = function(x,y) - print('f: x,y,a,b,p,q', x, y, a, b, p, q) - local a,b = x,y - local t = coroutine.running() - checkallpass('debug.getlocal',{{f,1},{1,'2'}}) - checkallpass('debug.getlocal',{{t},{f},{1}}) - checkallerrors('debug.getlocal',{},'number expected') - checkallerrors('debug.getlocal',{afuncorlevel,notanumber},'number expected') - checkallerrors('debug.getlocal',{notafuncorlevel,somenumber}, 'number expected') - checkallerrors('debug.getlocal',{{t},afuncorlevel}, 'got no value') - checkallerrors('debug.getlocal',{nonthread,{f},{1,'2'}}, 'number expected') - checkallerrors('debug.getlocal',{{t},{100},{1}}, 'level out of range') -end -f(1,2) - --- debug.getmetatable (value) -banner('debug.getmetatable') -checkallpass('debug.getmetatable',{anylua}) -checkallerrors('debug.getmetatable',{},'value expected') - --- debug.getregistry () -banner('debug.getregistry') -checkallpass('debug.getregistry',{}) -checkallpass('debug.getregistry',{anylua}) - --- debug.getupvalue (f, up) -banner('debug.getupvalue') -checkallpass('debug.getupvalue',{{f},{1,'2'}}) -checkallerrors('debug.getupvalue',{},'number expected') -checkallerrors('debug.getupvalue',{notafunction,{1,'2'}}, 'function expected') -checkallerrors('debug.getupvalue',{{f},notanumber}, 'number expected') - --- debug.getuservalue (u) -checkallpass('debug.getuservalue',{}) -checkallpass('debug.getuservalue',{anylua}) - --- debug.sethook ([thread,] hook, mask [, count]) -local ahookstr = {"cr","l"} -checkallpass('debug.sethook',{}) -checkallpass('debug.sethook',{somenil,ahookstr}) -checkallpass('debug.sethook',{somefunction,ahookstr}) -checkallpass('debug.sethook',{{nil,athread,n=2},somefunction,ahookstr}) -checkallerrors('debug.sethook',{{astring,afunction,aboolean}},'string expected') -checkallerrors('debug.sethook',{{astring,afunction,aboolean},{nil,afunction,n=2},ahookstr},'string expected') - --- debug.setlocal ([thread,] level, local, value) -banner('debug.setlocal') -local p,q = 'p','q'; -f = function(x,y) - print('f: x,y,a,b,p,q', x, y, a, b, p, q) - local a,b = x,y - local t = coroutine.running() - checkallpass('debug.setlocal',{{1},{1},{nil,'foo',n=2}}) - print('f: x,y,a,b,p,q', x, y, a, b, p, q) - checkallpass('debug.setlocal',{{t},{1},{2},{nil,'bar',n=2}}) - print('f: x,y,a,b,p,q', x, y, a, b, p, q) - checkallerrors('debug.setlocal',{},'number expected') - checkallerrors('debug.setlocal',{{1}},'value expected') - checkallerrors('debug.setlocal',{{1},{1}}, 'value expected') - checkallerrors('debug.setlocal',{{t},{1},{2}}, 'value expected') - checkallerrors('debug.setlocal',{{atable,astring},{1}}, 'number expected') - checkallerrors('debug.setlocal',{{1},nonnumber}, 'value expected') - checkallerrors('debug.setlocal',{{atable,astring},{1},{1},{nil,'foo',n=2}}, 'number expected') - checkallerrors('debug.setlocal',{{10},{1},{'foo'}}, 'level out of range') - return p,q -end -f(1,2) - --- debug.setmetatable (value, table) -banner('debug.setmetatable') -checkallpass('debug.setmetatable',{anylua,{atable,nil,n=2}}) -checkallerrors('debug.setmetatable',{},'nil or table') -checkallerrors('debug.setmetatable',{anylua},'nil or table') - --- debug.setupvalue (f, up, value) -banner('debug.setupvalue') -checkallpass('debug.setupvalue',{{f},{2,'3'},{nil,aboolean,astring,n=3}}) -print('p,q', p, q) -checkallerrors('debug.setupvalue',{},'value expected') -checkallerrors('debug.setupvalue',{{f}},'value expected') -checkallerrors('debug.setupvalue',{{f},{2}},'value expected') -checkallerrors('debug.setupvalue',{notafunction,{2}}, 'value expected') -checkallerrors('debug.setupvalue',{{f},notanumber}, 'value expected') - --- debug.setuservalue (udata, value) -banner('debug.setuservalue') -checkallerrors('debug.setuservalue',{},'userdata expected') -checkallerrors('debug.setuservalue',{anylua},'userdata expected') -checkallerrors('debug.setuservalue',{anylua,somestring},'userdata expected') - --- debug.traceback ([thread,] [message [, level]]) -banner('debug.traceback') -local t = coroutine.running() -checkallpass('debug.traceback',{}) -checkallpass('debug.traceback',{{astring}}) -checkallpass('debug.traceback',{{astring},{anumber}}) -checkallpass('debug.traceback',{{t}}) -checkallpass('debug.traceback',{{t},{astring}}) -checkallpass('debug.traceback',{{t},{astring},{anumber}}) -checkallpass('debug.traceback',{{afunction,aboolean,atable}}) -checkallpass('debug.traceback',{{afunction,aboolean,atable},notanumber}) - --- debug.upvalueid (f, n) -banner('debug.upvalueid') -checkallpass('debug.upvalueid',{{f},{1,'2'}}) -checkallerrors('debug.upvalueid',{},'number expected') -checkallerrors('debug.upvalueid',{notafunction,{1,'2'}}, 'function expected') -checkallerrors('debug.upvalueid',{{f},notanumber}, 'number expected') - --- debug.upvaluejoin (f1, n1, f2, n2) -banner('debug.upvaluejoin') -checkallpass('debug.upvaluejoin',{{f},{1,'2'},{f},{1,'2'}}) -checkallerrors('debug.upvaluejoin',{},'number expected') -checkallerrors('debug.upvaluejoin',{notafunction,{1,'2'}}, 'function expected') -checkallerrors('debug.upvaluejoin',{{f},notanumber}, 'number expected') -checkallerrors('debug.upvaluejoin',{{f},{1},notafunction,{1,'2'}}, 'function expected') -checkallerrors('debug.upvaluejoin',{{f},{1},{f},notanumber}, 'number expected') diff --git a/test/lua/errors/iolibargs.lua b/test/lua/errors/iolibargs.lua deleted file mode 100644 index 1f8a3ac4..00000000 --- a/test/lua/errors/iolibargs.lua +++ /dev/null @@ -1,85 +0,0 @@ -package.path = "?.lua;test/lua/errors/?.lua" -require 'args' - --- arg type tests for io library functions -local f - --- io.close ([file]) -banner('io.close') -f = io.open("abc.txt","w") -checkallpass('io.close',{{f}}) -checkallerrors('io.close',{notanil},'bad argument') - --- io.input ([file]) -banner('io.input') -f = io.open("abc.txt","r") -checkallpass('io.input',{{nil,f,"abc.txt",n=3}}) -checkallerrors('io.input',{nonstring},'bad argument') - --- io.lines ([filename]) -banner('io.lines') -io.input("abc.txt") -checkallpass('io.lines',{{"abc.txt"}}) -checkallerrors('io.lines',{{f}},'bad argument') -checkallerrors('io.lines',{notastring},'bad argument') - --- io.open (filename [, mode]) -banner('io.open') -checkallpass('io.open',{{"abc.txt"},{nil,"r","w","a","r+","w+","a+"}}) -checkallerrors('io.open',{notastring},'bad argument') -checkallerrors('io.open',{{"abc.txt"},{nonstring}},'bad argument') - --- io.output ([file]) -banner('io.output') -checkallpass('io.output',{{nil,f,"abc.txt",n=3}}) -checkallerrors('io.output',{nonstring},'bad argument') - --- io.popen (prog [, mode]) -banner('io.popen') ---checkallpass('io.popen',{{"hostname"},{nil,"w",n=2}}) -checkallerrors('io.popen',{notastring},'bad argument') -checkallerrors('io.popen',{{"hostname"},{nonstring}},'bad argument') - --- io.read (���) -banner('io.read') -checkallpass('io.read',{}) -checkallpass('io.read',{{2,"*n","*a","*l"}}) -checkallpass('io.read',{{2,"*n","*a","*l"},{2,"*a","*l"}}) -checkallerrors('io.read',{{aboolean,afunction,atable,"3"}},'bad argument') - --- io.write (���) -banner('io.write') -checkallpass('io.write',{}) -checkallpass('io.write',{somestring}) -checkallpass('io.write',{somestring,somestring}) -checkallerrors('io.write',{nonstring},'bad argument') -checkallerrors('io.write',{somestring,nonstring},'bad argument') - --- file:write () -banner('file:write') -file = io.open("seektest.txt","w") -checkallpass('file.write',{{file},somestring}) -checkallpass('file.write',{{file},somestring,somestring}) -checkallerrors('file.write',{},'bad argument') -checkallerrors('file.write',{{file},nonstring},'bad argument') -checkallerrors('file.write',{{file},somestring,nonstring},'bad argument') -pcall( file.close, file ) - --- file:seek ([whence] [, offset]) -banner('file:seek') -file = io.open("seektest.txt","r") -checkallpass('file.seek',{{file}}) -checkallpass('file.seek',{{file},{"set","cur","end"}}) -checkallpass('file.seek',{{file},{"set","cur","end"},{2,"3"}}) -checkallerrors('file.seek',{},'bad argument') -checkallerrors('file.seek',{{file},nonstring},'bad argument') -checkallerrors('file.seek',{{file},{"set","cur","end"},nonnumber},'bad argument') - --- file:setvbuf (mode [, size]) -banner('file:setvbuf') -checkallpass('file.setvbuf',{{file},{"no","full","line"}}) -checkallpass('file.setvbuf',{{file},{"full"},{1024,"512"}}) -checkallerrors('file.setvbuf',{},'bad argument') -checkallerrors('file.setvbuf',{{file},notastring},'bad argument') -checkallerrors('file.setvbuf',{{file},{"full"},nonnumber},'bad argument') - diff --git a/test/lua/errors/mathlibargs.lua b/test/lua/errors/mathlibargs.lua deleted file mode 100644 index 54d48e20..00000000 --- a/test/lua/errors/mathlibargs.lua +++ /dev/null @@ -1,112 +0,0 @@ -package.path = "?.lua;test/lua/errors/?.lua" -require 'args' - -local tostring = tostring -_G.tostring = function(x) - local s = tostring(x) - return type(x)=='number' and #s>4 and (s:sub(1,5)..'...') or s -end - --- arg type tests for math library functions -local somenumber = {1,0.75,'-1','-0.25'} -local somepositive = {1,0.75,'2', '2.5'} -local notanumber = {nil,astring,aboolean,afunction,atable,athread} -local nonnumber = {astring,aboolean,afunction,atable} - -local singleargfunctions = { - 'abs', 'acos', 'asin', 'atan', 'cos', 'cosh', 'deg', 'exp', 'floor', - 'rad', 'randomseed', 'sin', 'sinh', 'tan', 'tanh', 'frexp', - } - -local singleargposdomain = { - 'log', 'sqrt', 'ceil', - } - -local twoargfunctions = { - 'atan2', - } - -local twoargsposdomain = { - 'pow', 'fmod', -} - --- single argument tests -for i,v in ipairs(singleargfunctions) do - local funcname = 'math.'..v - banner(funcname) - checkallpass(funcname,{somenumber}) - checkallerrors(funcname,{notanumber},'bad argument') -end - --- single argument, positive domain tests -for i,v in ipairs(singleargposdomain) do - local funcname = 'math.'..v - banner(funcname) - checkallpass(funcname,{somepositive}) - checkallerrors(funcname,{notanumber},'bad argument') -end - --- two-argument tests -for i,v in ipairs(twoargfunctions) do - local funcname = 'math.'..v - banner(funcname) - checkallpass(funcname,{somenumber,somenumber}) - checkallerrors(funcname,{},'bad argument') - checkallerrors(funcname,{notanumber},'bad argument') - checkallerrors(funcname,{notanumber,somenumber},'bad argument') - checkallerrors(funcname,{somenumber},'bad argument') - checkallerrors(funcname,{somenumber,notanumber},'bad argument') -end - --- two-argument, positive domain tests -for i,v in ipairs(twoargsposdomain) do - local funcname = 'math.'..v - banner(funcname) - checkallpass(funcname,{somepositive,somenumber}) - checkallerrors(funcname,{},'bad argument') - checkallerrors(funcname,{notanumber},'bad argument') - checkallerrors(funcname,{notanumber,somenumber},'bad argument') - checkallerrors(funcname,{somenumber},'bad argument') - checkallerrors(funcname,{somenumber,notanumber},'bad argument') -end - --- math.max -banner('math.max') -checkallpass('math.max',{somenumber}) -checkallpass('math.max',{somenumber,somenumber}) -checkallerrors('math.max',{},'bad argument') -checkallerrors('math.max',{nonnumber},'bad argument') -checkallerrors('math.max',{somenumber,nonnumber},'bad argument') - --- math.min -banner('math.min') -checkallpass('math.min',{somenumber}) -checkallpass('math.min',{somenumber,somenumber}) -checkallerrors('math.min',{},'bad argument') -checkallerrors('math.min',{nonnumber},'bad argument') -checkallerrors('math.min',{somenumber,nonnumber},'bad argument') - --- math.random -local somem = {3,4.5,'6.7'} -local somen = {8,9.10,'12.34'} -local notamn = {astring,aboolean,atable,afunction} -banner('math.random') -checkallpass('math.random',{},true) -checkallpass('math.random',{somem},true) -checkallpass('math.random',{somem,somen},true) -checkallpass('math.random',{{-4,-5.6,'-7','-8.9'},{-1,100,23.45,'-1.23'}},true) -checkallerrors('math.random',{{-4,-5.6,'-7','-8.9'}},'interval is empty') -checkallerrors('math.random',{somen,somem},'interval is empty') -checkallerrors('math.random',{notamn,somen},'bad argument') -checkallerrors('math.random',{somem,notamn},'bad argument') - --- math.ldexp -local somee = {-3,0,3,9.10,'12.34'} -local notae = {nil,astring,aboolean,atable,afunction} -banner('math.ldexp') -checkallpass('math.ldexp',{somenumber,somee}) -checkallerrors('math.ldexp',{},'bad argument') -checkallerrors('math.ldexp',{notanumber},'bad argument') -checkallerrors('math.ldexp',{notanumber,somee},'bad argument') -checkallerrors('math.ldexp',{somenumber},'bad argument') -checkallerrors('math.ldexp',{somenumber,notae},'bad argument') \ No newline at end of file diff --git a/test/lua/errors/modulelibargs.lua b/test/lua/errors/modulelibargs.lua deleted file mode 100644 index d323123b..00000000 --- a/test/lua/errors/modulelibargs.lua +++ /dev/null @@ -1,21 +0,0 @@ -package.path = "?.lua;test/lua/errors/?.lua" -require 'args' - --- arg type tests for module library functions - --- require -banner('require') -checkallpass('require',{{'math','coroutine','package','string','table'}},true) -checkallerrors('require',{{anumber}},'not found') -checkallerrors('require',{{anil,aboolean,afunction,atable}},'bad argument') - --- package.loadlib -banner('package.loadlib') -checkallpass('package.loadlib',{{'foo'},{'bar'}},true) -checkallerrors('package.loadlib',{notastring},'bad argument') - --- package.seeall -banner('package.seeall') -checkallpass('package.seeall',{sometable}) -checkallerrors('package.seeall',{notatable},'bad argument') - diff --git a/test/lua/errors/operators.lua b/test/lua/errors/operators.lua deleted file mode 100644 index ba53b507..00000000 --- a/test/lua/errors/operators.lua +++ /dev/null @@ -1,157 +0,0 @@ -package.path = "?.lua;test/lua/errors/?.lua" -require 'args' - --- arg types for language operator - --- ========= unary operators: - # not - --- unary minus - -banner('unary -') -negative = function(a) return - a end -checkallpass('negative',{somenumber}) -checkallerrors('negative',{notanumber},'attempt to perform arithmetic') - --- length -banner('#') -lengthop = function(a) return #a end -checkallpass('lengthop',{sometable}) -checkallerrors('lengthop',{notatable},'attempt to get length of') - --- length -banner('not') -notop = function(a) return not a end -checkallpass('notop',{somenumber}) -checkallpass('notop',{notanumber}) - --- function call -banner( '()' ) -funcop = function(a) return a() end -checkallpass('funcop',{somefunction}) -checkallerrors('funcop',{notafunction},'attempt to call') - --- ========= binary ops: .. + - * / % ^ == ~= <= >= < > [] . and or -banner( '..' ) -concatop = function(a,b) return a..b end -checkallpass('concatop',{somestring,somestring}) -checkallerrors('concatop',{notastring,somestring},'attempt to concatenate') -checkallerrors('concatop',{somestring,notastring},'attempt to concatenate') - -banner( '+' ) -plusop = function(a,b) return a+b end -checkallpass('plusop',{somenumber,somenumber}) -checkallerrors('plusop',{notanumber,somenumber},'attempt to perform arithmetic') -checkallerrors('plusop',{somenumber,notanumber},'attempt to perform arithmetic') - -banner( '-' ) -minusop = function(a,b) return a-b end -checkallpass('minusop',{somenumber,somenumber}) -checkallerrors('minusop',{notanumber,somenumber},'attempt to perform arithmetic') -checkallerrors('minusop',{somenumber,notanumber},'attempt to perform arithmetic') - -banner( '*' ) -timesop = function(a,b) return a*b end -checkallpass('timesop',{somenumber,somenumber}) -checkallerrors('timesop',{notanumber,somenumber},'attempt to perform arithmetic') -checkallerrors('timesop',{somenumber,notanumber},'attempt to perform arithmetic') - -banner( '/' ) -divideop = function(a,b) return a/b end -checkallpass('divideop',{somenumber,somenumber}) -checkallerrors('divideop',{notanumber,somenumber},'attempt to perform arithmetic') -checkallerrors('divideop',{somenumber,notanumber},'attempt to perform arithmetic') - -banner( '%' ) -modop = function(a,b) return a%b end -checkallpass('modop',{somenumber,somenumber}) -checkallerrors('modop',{notanumber,somenumber},'attempt to perform arithmetic') -checkallerrors('modop',{somenumber,notanumber},'attempt to perform arithmetic') - -banner( '^' ) -powerop = function(a,b) return a^b end -checkallpass('powerop',{{2,'2.5'},{3,'3.5'}}) -checkallerrors('powerop',{notanumber,{3,'3.1'}},'attempt to perform arithmetic') -checkallerrors('powerop',{{2,'2.1'},notanumber},'attempt to perform arithmetic') - -banner( '==' ) -equalsop = function(a,b) return a==b end -checkallpass('equalsop',{anylua,anylua}) - -banner( '~=' ) -noteqop = function(a,b) return a~=b end -checkallpass('noteqop',{anylua,anylua}) - -banner( '<=' ) -leop = function(a,b) return a<=b end -checkallpass('leop',{{anumber},{anumber}}) -checkallpass('leop',{{astring,astrnum},{astring,astrnum}}) -checkallerrors('leop',{notanumber,{anumber}},'attempt to compare') -checkallerrors('leop',{{astrnum},{anumber}},'attempt to compare') -checkallerrors('leop',{notastring,{astring,astrnum}},'attempt to compare') -checkallerrors('leop',{{anumber},notanumber},'attempt to compare') -checkallerrors('leop',{{anumber},{astrnum}},'attempt to compare') -checkallerrors('leop',{{astring,astrnum},notastring},'attempt to compare') - -banner( '>=' ) -geop = function(a,b) return a>=b end -checkallpass('geop',{{anumber},{anumber}}) -checkallpass('geop',{{astring,astrnum},{astring,astrnum}}) -checkallerrors('geop',{notanumber,{anumber}},'attempt to compare') -checkallerrors('geop',{{astrnum},{anumber}},'attempt to compare') -checkallerrors('geop',{notastring,{astring,astrnum}},'attempt to compare') -checkallerrors('geop',{{anumber},notanumber},'attempt to compare') -checkallerrors('geop',{{anumber},{astrnum}},'attempt to compare') -checkallerrors('geop',{{astring,astrnum},notastring},'attempt to compare') - -banner( '<' ) -ltop = function(a,b) return a' ) -gtop = function(a,b) return a>b end -checkallpass('gtop',{{anumber},{anumber}}) -checkallpass('gtop',{{astring,astrnum},{astring,astrnum}}) -checkallerrors('gtop',{notanumber,{anumber}},'attempt to compare') -checkallerrors('gtop',{{astrnum},{anumber}},'attempt to compare') -checkallerrors('gtop',{notastring,{astring,astrnum}},'attempt to compare') -checkallerrors('gtop',{{anumber},notanumber},'attempt to compare') -checkallerrors('gtop',{{anumber},{astrnum}},'attempt to compare') -checkallerrors('gtop',{{astring,astrnum},notastring},'attempt to compare') - -banner( '[]' ) -bracketop = function(a,b) return a[b] end -checkallpass('bracketop',{sometable,notanil}) -checkallerrors('bracketop',{notatable,notanil},'attempt to index') -checkallerrors('bracketop',{sometable},'attempt to index') - -banner( '.' ) -dotop = function(a,b) return a.b end -checkallpass('dotop',{sometable,notanil}) -checkallerrors('dotop',{notatable,notanil},'attempt to index') -checkallerrors('dotop',{sometable},'attempt to index') - -banner( 'and' ) -types = {['table']='table',['function']='function',['thread']='thread'} -clean = function(x) return types[type(x)] or x end -andop = function(a,b) return clean(a and b) end -checkallpass('andop',{anylua,anylua}) - -banner( 'or' ) -orop = function(a,b) return clean(a or b) end -checkallpass('orop',{anylua,anylua}) - --- ========= for x in y -banner( 'for x=a,b,c' ) -forop = function(a,b,c) for x=a,b,c do end end -checkallpass('forop',{{1,'1.1'},{10,'10.1'},{2,'2.1'}}) -checkallerrors('forop',{notanumber,{10,'10.1'},{2,'2.1'}},"'for' initial value must be a number") -checkallerrors('forop',{{1,'1.1'},notanumber,{2,'2.1'}},"'for' limit must be a number") -checkallerrors('forop',{{1,'1.1'},{10,'10.1'},notanumber},"'for' step must be a number") - - diff --git a/test/lua/errors/stringlibargs.lua b/test/lua/errors/stringlibargs.lua deleted file mode 100644 index 6cb732e8..00000000 --- a/test/lua/errors/stringlibargs.lua +++ /dev/null @@ -1,120 +0,0 @@ -package.path = "?.lua;test/lua/errors/?.lua" -require 'args' - --- arg type tests for string library functions - --- string.byte -banner('string.byte') -checkallpass('string.byte',{somestring}) -checkallpass('string.byte',{somestring,somenumber}) -checkallpass('string.byte',{somestring,somenumber,somenumber}) -checkallerrors('string.byte',{somestring,{astring,afunction,atable}},'bad argument') -checkallerrors('string.byte',{notastring,{nil,111,n=2}},'bad argument') - --- string.char -function string_char(...) - return string.byte( string.char( ... ) ) -end -banner('string_char') -checkallpass('string.char',{{60}}) -checkallpass('string.char',{{60},{70}}) -checkallpass('string.char',{{60},{70},{80}}) -checkallpass('string_char',{{0,9,40,127,128,255,'0','9','255','9.2',9.2}}) -checkallpass('string_char',{{0,127,255},{0,127,255}}) -checkallerrors('string_char',{},'bad argument') -checkallerrors('string_char',{{nil,-1,256,3}},'bad argument') -checkallerrors('string_char',{notanumber,{23,'45',6.7}},'bad argument') -checkallerrors('string_char',{{23,'45',6.7},nonnumber},'bad argument') - --- string.dump -banner('string.dump') -local someupval = 435 -local function funcwithupvals() return someupval end -checkallpass('string.dump',{{function() return 123 end}}) -checkallpass('string.dump',{{funcwithupvals}}) -checkallerrors('string.dump',{notafunction},'bad argument') - --- string.find -banner('string.find') -checkallpass('string.find',{somestring,somestring}) -checkallpass('string.find',{somestring,somestring,{nil,-3,3,n=3}}) -checkallpass('string.find',{somestring,somestring,somenumber,anylua}) -checkallerrors('string.find',{notastring,somestring},'bad argument') -checkallerrors('string.find',{somestring,notastring},'bad argument') -checkallerrors('string.find',{somestring,somestring,nonnumber},'bad argument') - --- string.format ---local numfmts = {'%c','%d','%E','%e','%f','%g','%G','%i','%o','%u','%X','%x'} -local numfmts = {'%c','%d','%i','%o','%u','%X','%x'} -local strfmts = {'%q','%s'} -local badfmts = {'%w'} -banner('string.format') -checkallpass('string.format',{somestring,anylua}) -checkallpass('string.format',{numfmts,somenumber}) -checkallpass('string.format',{strfmts,somestring}) -checkallerrors('string.format',{numfmts,notanumber},'bad argument') -checkallerrors('string.format',{strfmts,notastring},'bad argument') -checkallerrors('string.format',{badfmts,somestring},"invalid option '%w'") - --- string.gmatch -banner('string.gmatch') -checkallpass('string.gmatch',{somestring,somestring}) -checkallerrors('string.gmatch',{notastring,somestring},'bad argument') -checkallerrors('string.gmatch',{somestring,notastring},'bad argument') - --- string.gsub -local somerepl = {astring,atable,afunction} -local notarepl = {nil,aboolean,n=2} -banner('string.gsub') -checkallpass('string.gsub',{somestring,somestring,somerepl,{nil,-1,n=2}}) -checkallerrors('string.gsub',{nonstring,somestring,somerepl},'bad argument') -checkallerrors('string.gsub',{somestring,nonstring,somerepl},'bad argument') -checkallerrors('string.gsub',{{astring},{astring},notarepl},'bad argument') -checkallerrors('string.gsub',{{astring},{astring},somerepl,nonnumber},'bad argument') - --- string.len -banner('string.len') -checkallpass('string.len',{somestring}) -checkallerrors('string.len',{notastring},'bad argument') - --- string.lower -banner('string.lower') -checkallpass('string.lower',{somestring}) -checkallerrors('string.lower',{notastring},'bad argument') - --- string.match -banner('string.match') -checkallpass('string.match',{somestring,somestring}) -checkallpass('string.match',{somestring,somestring,{nil,-3,3,n=3}}) -checkallerrors('string.match',{},'bad argument') -checkallerrors('string.match',{nonstring,somestring},'bad argument') -checkallerrors('string.match',{somestring},'bad argument') -checkallerrors('string.match',{somestring,nonstring},'bad argument') -checkallerrors('string.match',{somestring,somestring,notanumber},'bad argument') - --- string.reverse -banner('string.reverse') -checkallpass('string.reverse',{somestring}) -checkallerrors('string.reverse',{notastring},'bad argument') - --- string.rep -banner('string.rep') -checkallpass('string.rep',{somestring,somenumber}) -checkallerrors('string.rep',{notastring,somenumber},'bad argument') -checkallerrors('string.rep',{somestring,notanumber},'bad argument') - --- string.sub -banner('string.sub') -checkallpass('string.sub',{somestring,somenumber}) -checkallpass('string.sub',{somestring,somenumber,somenumber}) -checkallerrors('string.sub',{},'bad argument') -checkallerrors('string.sub',{nonstring,somenumber,somenumber},'bad argument') -checkallerrors('string.sub',{somestring},'bad argument') -checkallerrors('string.sub',{somestring,nonnumber,somenumber},'bad argument') -checkallerrors('string.sub',{somestring,somenumber,nonnumber},'bad argument') - --- string.upper -banner('string.upper') -checkallpass('string.upper',{somestring}) -checkallerrors('string.upper',{notastring},'bad argument') - diff --git a/test/lua/errors/tablelibargs.lua b/test/lua/errors/tablelibargs.lua deleted file mode 100644 index 895b79a6..00000000 --- a/test/lua/errors/tablelibargs.lua +++ /dev/null @@ -1,70 +0,0 @@ -package.path = "?.lua;test/lua/errors/?.lua" -require 'args' - --- arg type tests for table library functions - --- table.concat -local somestringstable = {{8,7,6,5,4,3,2,1,}} -local somenonstringtable = {{true,true,true,true,true,true,true,true,}} -local somesep = {',',1.23} -local notasep = {aboolean,atable,afunction} -local somei = {2,'2','2.2'} -local somej = {4,'4','4.4'} -local notij = {astring,aboolean,atable,afunction} -banner('table.concat') -checkallpass('table.concat',{somestringstable}) -checkallpass('table.concat',{somestringstable,somesep}) -checkallpass('table.concat',{somestringstable,{'-'},somei}) -checkallpass('table.concat',{somestringstable,{'-'},{2},somej}) -checkallerrors('table.concat',{notatable},'bad argument') -checkallerrors('table.concat',{somenonstringtable},'boolean') -checkallerrors('table.concat',{somestringstable,notasep},'bad argument') -checkallerrors('table.concat',{somestringstable,{'-'},notij},'bad argument') -checkallerrors('table.concat',{somestringstable,{'-'},{2},notij},'bad argument') - --- table.insert -banner('table.insert') -checkallpass('table.insert',{sometable,notanil}) -checkallpass('table.insert',{sometable,somei,notanil}) -checkallerrors('table.insert',{notatable,somestring},'bad argument') -checkallerrors('table.insert',{sometable,notij,notanil},'bad argument') - --- table.remove -banner('table.remove') -checkallpass('table.remove',{sometable}) -checkallpass('table.remove',{sometable,somei}) -checkallerrors('table.remove',{notatable},'bad argument') -checkallerrors('table.remove',{notatable,somei},'bad argument') -checkallerrors('table.remove',{sometable,notij},'bad argument') - --- table.sort -local somecomp = {nil,afunction,n=2} -local notacomp = {astring,anumber,aboolean,atable} -banner('table.sort') -checkallpass('table.sort',{somestringstable,somecomp}) -checkallerrors('table.sort',{sometable},'attempt to') -checkallerrors('table.sort',{notatable,somecomp},'bad argument') -checkallerrors('table.sort',{sometable,notacomp},'bad argument') - --- table get -banner('table_get - tbl[key]') -function table_get(tbl,key) return tbl[key] end -checkallpass('table_get',{sometable,anylua}) - --- table set -banner('table_set - tbl[key]=val') -function table_set(tbl,key,val) tbl[key]=val end -function table_set_nil_key(tbl,val) tbl[nil]=val end -checkallpass('table_set',{sometable,notanil,anylua}) -checkallerrors('table_set_nil_key',{sometable,anylua},'table index') - --- table.unpack -banner('table.unpack') -checkallpass('table.unpack',{sometable}) -checkallpass('table.unpack',{sometable,{3,'5'}}) -checkallpass('table.unpack',{sometable,{3,'5'},{1.25,'7'}}) -checkallerrors('table.unpack',{notatable,somenumber,somenumber},'bad argument') -checkallerrors('table.unpack',{sometable,nonnumber,somenumber},'bad argument') -checkallerrors('table.unpack',{sometable,somenumber,nonnumber},'bad argument') - - diff --git a/test/lua/functions.lua b/test/lua/functions.lua deleted file mode 100644 index e55f0357..00000000 --- a/test/lua/functions.lua +++ /dev/null @@ -1,74 +0,0 @@ - -function f0() print( "f0:" ) end -function f1(a) print( "f1:", a ) end -function f2(a,b) print( "f2:", a, b ) end -function f3(a,b,c) print( "f3:", a, b, c ) end -function f4(a,b,c,d) print( "f4:", a, b, c, d ) end - -f0() f0( "a1/1" ) f0( "a1/2", "a2/2" ) f0( "a1/3", "a2/3", "a3/3" ) f0( "a1/4", "a2/4", "a3/4", "a4/4" ) -f1() f1( "a1/1" ) f1( "a1/2", "a2/2" ) f1( "a1/3", "a2/3", "a3/3" ) f1( "a1/4", "a2/4", "a3/4", "a4/4" ) -f2() f2( "a1/1" ) f2( "a1/2", "a2/2" ) f2( "a1/3", "a2/3", "a3/3" ) f2( "a1/4", "a2/4", "a3/4", "a4/4" ) -f3() f3( "a1/1" ) f3( "a1/2", "a2/2" ) f3( "a1/3", "a2/3", "a3/3" ) f3( "a1/4", "a2/4", "a3/4", "a4/4" ) -f4() f4( "a1/1" ) f4( "a1/2", "a2/2" ) f4( "a1/3", "a2/3", "a3/3" ) f4( "a1/4", "a2/4", "a3/4", "a4/4" ) - -function g0(a,b,c,d) return end -function g1(a,b,c,d) return d end -function g2(a,b,c,d) return c, d end -function g3(a,b,c,d) return b, c, d end -function g4(a,b,c,d) return a, b, c, d end - -z = g0("c0.1/4", "c0.2/4", "c0.3/4", "c0.4/4") -print( "z0:", z ) -z = g2("c2.1/4", "c2.2/4", "c2.3/4", "c2.4/4") -print( "z2:", z ) -z = g4("c4.1/4", "c4.2/4", "c4.3/4", "c4.4/4") -print( "z4:", z ) - -a,b,c,d = g0( "c0.1/4", "c0.2/4", "c0.3/4", "c0.4/4" ) -print( "g0:", a, b, c, d, "(eol)" ) -a,b,c,d = g2( "b2.1/4", "b2.2/4", "b2.3/4", "b2.4/4" ) -print( "g2:", a, b, c, d, "(eol)" ) -a,b,c,d = g4( "b4.1/4", "b4.2/4", "b4.3/4", "b4.4/4" ) -print( "g4:", a, b, c, d, "(eol)" ) - -function func(a,b,c) - return a, b, c -end - -print( func(11, 12, 13) ) -print( func(23, 22, 21) ) -print( func(func(32,33,34), func(45,46,47), func(58,59,50)) ) - -function p(a,...) - print("a",a) - print("...",...) - print("...,a",...,a) - print("a,...",a,...) -end -p() -p("q") -p("q","r") -p("q","r","s") - --- tail call tests -function first(...) - return 'abc', ..., '|', ... -end - -function second(a,...) - return 'def', ..., '|', a, ... -end - -function third( a, b, c ) - print( 'third', first( a, b, c ) ) - print( 'third', second( a, b, c ) ) - return second( a, b, c ) -end - -print( 'third', third() ) -print( 'third', third('p') ) -print( 'third', third('p','q') ) -print( 'third', third('p','q','r') ) -print( 'third', third('p','q','r','s') ) -print( 'third', third() ) - diff --git a/test/lua/iolib.lua b/test/lua/iolib.lua deleted file mode 100644 index ab086e51..00000000 --- a/test/lua/iolib.lua +++ /dev/null @@ -1,153 +0,0 @@ -local platform = ... ---print( 'platform', platform ) - --- simple io-library tests --- --- C version on Windows will add change \n into \r\n for text files at least --- -local tostr,files,nfiles = tostring,{},0 -tostring = function(x) - local s = tostr(x) - if s:sub(1,4) ~= 'file' then return s end - if files[s] then return files[s] end - files[s] = 'file.'..nfiles - nfiles = nfiles + 1 - return files[s] -end -print( io ~= nil ) -print( io.open ~= nil ) -print( io.stdin ~= nil ) -print( io.stdout ~= nil ) -print( io.stderr ~= nil ) -print( 'write', io.write() ) -print( 'write', io.write("This") ) -print( 'write', io.write(" is a pen.") ) -print( 'flush', io.flush() ) - -local f = io.open("abc.txt","w") -print( 'f', type(f) ) -print( io.type(f) ) -print( 'write', f:write("abcdef 12345 \t\t 678910 more\aaaaaaa\bbbbthe rest") ) -print( 'type(f)', io.type(f) ) -print( 'close', f:close() ) -print( 'type(f)', io.type(f) ) -print( 'type("f")', io.type("f") ) - -local g = io.open("abc.txt","r") -local t = { g:read(3, 3, "*n", "*n", "*l", "*l", "*a") } -for i,v in ipairs(t) do - print( string.format("%q",tostring(v)), type(v)) - print( '----- ', i ) -end - -local h,s = io.open("abc.txt", "a") -print( 'h', io.type(h), string.sub(tostring(h),1,6), s ) -print( 'write', h:write('and more and more and more text.') ) -print( 'close', h:close() ) - -if platform ~= 'JME' then - local j = io.open( "abc.txt", "r" ) - print( 'j', io.type(j) ) - print( 'seek', j:seek("set", 3) ) - print( 'read', j:read(4), j:read(3) ) - print( 'seek', j:seek("set", 2) ) - print( 'read', j:read(4), j:read(3) ) - print( 'seek', j:seek("cur", -8 ) ) - print( 'read', j:read(4), j:read(3) ) - print( 'seek(cur,0)', j:seek("cur",0) ) - print( 'seek(cur,20)', j:seek("cur",20) ) - print( 'seek(end,-5)', j:seek("end", -5) ) - print( 'read(4)', string.format("%q", tostring(j:read(4))) ) - print( 'read(4)', string.format("%q", tostring(j:read(4))) ) - print( 'read(4)', string.format("%q", tostring(j:read(4))) ) - print( 'close', j:close() ) -end - --- write a few lines, including a non-terminating one -files = {} -f = io.open("abc.txt","w") -print( 'f.type', io.type(f) ) -print( 'f', f ) -print( 'write', f:write("line one\nline two\n\nafter blank line\nunterminated line") ) -print( 'type(f)', io.type(f) ) -print( 'close', f:close() ) -files = {} - --- read using io.lines() -for l in io.lines("abc.txt") do - print( string.format('%q',l) ) -end -io.input("abc.txt") -for l in io.lines() do - print( string.format('%q',l) ) -end -io.input(io.open("abc.txt","r")) -for l in io.lines() do - print( string.format('%q',l) ) -end -io.input("abc.txt") -io.input(io.input()) -for l in io.lines() do - print( string.format('%q',l) ) -end - -local count = 0 -io.tmpfile = function() - count = count + 1 - return io.open("tmp"..count..".out","w") -end - -local a = io.tmpfile() -local b = io.tmpfile() -print( io.type(a) ) -print( io.type(b) ) -print( "a:write", a:write('aaaaaaa') ) -print( "b:write", b:write('bbbbbbb') ) -print( "a:setvbuf", a:setvbuf("no") ) -print( "a:setvbuf", a:setvbuf("full",1024) ) -print( "a:setvbuf", a:setvbuf("line") ) -print( "a:write", a:write('ccccc') ) -print( "b:write", b:write('ddddd') ) -print( "a:flush", a:flush() ) -print( "b:flush", b:flush() ) ---[[ -print( "a:read", a:read(7) ) -print( "b:read", b:read(7) ) -print( "a:seek", a:seek("cur",-4) ) -print( "b:seek", b:seek("cur",-4) ) -print( "a:read", ( a:read(7) ) ) -print( "b:read", ( b:read(7) ) ) -print( "a:seek", a:seek("cur",-8) ) -print( "b:seek", b:seek("cur",-8) ) -print( "a:read", ( a:read(7) ) ) -print( "b:read", ( b:read(7) ) ) ---]] - -local pcall = function(...) - local s,e = pcall(...) - if s then return s end - return s,e:match("closed") -end - -print( 'a:close', pcall( a.close, a ) ) -print( 'a:write', pcall( a.write, a, 'eee') ) -print( 'a:flush', pcall( a.flush, a) ) -print( 'a:read', pcall( a.read, a, 5) ) -print( 'a:lines', pcall( a.lines, a) ) -print( 'a:seek', pcall( a.seek, a, "cur", -2) ) -print( 'a:setvbuf', pcall( a.setvbuf, a, "no") ) -print( 'a:close', pcall( a.close, a ) ) -print( 'io.type(a)', pcall( io.type, a ) ) - -print( 'io.close()', pcall( io.close ) ) -print( 'io.close(io.output())', pcall( io.close, io.output() ) ) - -io.output('abc.txt') -print( 'io.close()', pcall( io.close ) ) -print( 'io.write', pcall( io.write, 'eee') ) -print( 'io.flush', pcall( io.flush) ) -print( 'io.close', pcall( io.close ) ) -io.input('abc.txt'):close() -print( 'io.read', pcall( io.read, 5) ) -print( 'io.lines', pcall( io.lines) ) - diff --git a/test/lua/luaj3.0-tests.zip b/test/lua/luaj3.0-tests.zip deleted file mode 100644 index 40b70f02..00000000 Binary files a/test/lua/luaj3.0-tests.zip and /dev/null differ diff --git a/test/lua/manyupvals.lua b/test/lua/manyupvals.lua deleted file mode 100644 index e1ae06ce..00000000 --- a/test/lua/manyupvals.lua +++ /dev/null @@ -1,37 +0,0 @@ -local t = {} -local template = [[ - local f - do - local result - function f() - if not result then - result = f() + f() - end - return result - end - end -]] -t[1] = [[ - local f1 - f1 = function() return 1 end -]] -t[2] = [[ - local f2 - f2 = function() return 1 end -]] -for i = 3, 199 do - t[i] = template:gsub("<([^>]+)>", function(s) - local c = assert(load('return '..s, 'f'..i, 'bt', { i = i }), 'could not compile: '..s) - return c() - end) -end -t[200] = [[ - print("5th fibonacci number is", f5()) - print("10th fibonacci number is", f10()) - print("199th fibonacci number is", f199()) -]] - -local s = table.concat(t) -print(s) -f = load(s) -f() diff --git a/test/lua/mathlib.lua b/test/lua/mathlib.lua deleted file mode 100644 index 64598093..00000000 --- a/test/lua/mathlib.lua +++ /dev/null @@ -1,239 +0,0 @@ -local platform = ... ---print( 'platform', platform ) - -local aliases = { - ['0']='', - ['-0']='', - ['nan']='', - ['inf']='', - ['-inf']='', - ['1.#INF']='', - ['-1.#INF']='', - ['1.#IND']='', - ['-1.#IND']='', -} - -local UNOPVALUES = { -2.5, -2, 0, 2, 2.5, "'-2.5'", "'-2'", "'0'", "'2'", "'2.5'" } - -local NUMBERPAIRS = { - { 2, 0 }, { -2.5, 0 }, { 2, 1 }, - { 5, 2 }, {-5, 2 }, {16, 2}, {-16, -2}, - { .5, 0}, {.5, 1}, {.5, 2}, {.5, -1}, {.5, 2}, - {2.25, 0}, {2.25, 2}, {-2, 0}, - { 3, 3 }, -} - -local STRINGPAIRS = { - { "'2'", "'0'" }, { "'2.5'","'3'" }, { "'-2'", "'1.5'" }, { "'-2.5'", "'-1.5'" }, - { "'3.0'", "'3.0'" }, { 2.75, 2.75 }, { "'2.75'", "'2.75'" }, -} - -local MIXEDPAIRS = { - { 3, "'3'" }, { "'3'", 3 }, { 2.75, "'2.75'" }, { "'2.75'", 2.75 }, - { -3, "'-4'" }, { "'-3'", 4 }, { -3, "'4'" }, { "'-3'", -4 }, - { -4.75, "'2.75'" }, { "'-2.75'", 1.75 }, { 4.75, "'-2.75'" }, { "'2.75'", -1.75 }, -} - -local BINOPVALUES = {} - -local RELATIONALOPVALUES = {} - -local function addall( t, s ) - for i,v in ipairs(s) do - t[#t+1] = v - end -end -addall( BINOPVALUES, NUMBERPAIRS ) -addall( BINOPVALUES, STRINGPAIRS ) -addall( BINOPVALUES, MIXEDPAIRS ) -addall( RELATIONALOPVALUES, NUMBERPAIRS ) -addall( RELATIONALOPVALUES, STRINGPAIRS ) - -local VARARGSVALUES = { - { 4, }, { -4.5 }, { "'5.5'" }, { "'-5'" }, - { 4, "'8'" }, { -4.5, "'-8'" }, { "'5.5'", 2.2 }, { "'-5'", -2.2 }, - { 111,222,333 }, { -222,-333,-111 }, { 444,-111,-222 }, -} - -local CONSTANTS = { - "huge", "pi", -} -local UNARYOPS = { - "-", "not ", -} -local BINARYOPS = { - "+", "-", "*", "^", "/", "%", -} -local RELATIONALS = { - "==", "~=", ">", "<", ">=", "<=", -} -local ONEARG_JME = { - "abs", "ceil", "cos", "deg", - "exp", "floor", "frexp", "modf", - "rad", "sin", "sqrt", "tan", -} -local ONEARG_JSE = { - "acos", "asin", "atan", "cosh", - "log", "sinh", "tanh", -} -local TWOARGS_JME = { - "fmod", "ldexp", "pow", -} -local TWOARGS_JSE = { - "atan2", -} -local VARARGSFUNCS = { - "max", "min", -} - -local ts = tostring -tostring = function(x) - local s = ts(x) - if type(x)~='number' then return s end - if aliases[s] then return aliases[s] end - if #s < 7 then return s end - local a,b = string.match(s,'([%-0-9%.]*)([eE]?[%-0-9]*)') - return a and (string.sub(a,1,6)..(b or '')) or s -end - -local function eval( expr, script ) - script = script or ('return '..expr) - local s,a,b = load( script, 'expr' ) - if s then print( expr, pcall( s ) ) - else print( expr, 'load:', a ) end -end - --- misc tests -print( '---------- miscellaneous tests ----------' ) -eval( 'math.sin( 0.0 )' ) -eval( 'math.cos( math.pi )' ) -eval( 'math.sqrt( 9.0 )' ) -eval( 'math.modf( 5.25 )') -eval( 'math.frexp(0.00625)' ) -eval( '-5 ^ 2' ) -eval( '-5 / 2' ) -eval( '-5 % 2' ) - --- constants -print( '---------- constants ----------' ) -for i,v in ipairs(CONSTANTS) do - eval( 'math.'..v ) -end - --- unary operators -for i,v in ipairs(UNARYOPS) do - print( '---------- unary operator '..v..' ----------' ) - for j,a in ipairs(UNOPVALUES) do - eval( v..a, 'return '..v..a ) - end -end - --- binary operators -for i,v in ipairs(BINARYOPS) do - print( '---------- binary operator '..v..' ----------' ) - for j,xy in ipairs(BINOPVALUES) do - eval( xy[1]..v..xy[2], - 'local x,y='..xy[1]..','..xy[2]..'; return x'..v..'y' ) - end -end - --- relational operators -for i,v in ipairs(RELATIONALS) do - print( '---------- binary operator '..v..' ----------' ) - for j,xy in ipairs(RELATIONALOPVALUES) do - eval( xy[1]..v..xy[2], - 'local x,y='..xy[1]..','..xy[2]..'; return x'..v..'y' ) - end -end - --- one-argument math functions -for i,v in ipairs(ONEARG_JME) do - print( '---------- math.'..v..' ----------' ) - for j,x in ipairs(UNOPVALUES) do - eval( 'math.'..v..'('..x..')' ) - end -end -if platform ~= 'JME' then - for i,v in ipairs(ONEARG_JSE) do - print( '---------- math.'..v..' (jse only) ----------' ) - for j,x in ipairs(UNOPVALUES) do - eval( 'math.'..v..'('..x..')' ) - end - end -end - --- two-argument math functions -for i,v in ipairs(TWOARGS_JME) do - print( '---------- math.'..v..' ----------' ) - for j,x in ipairs(BINOPVALUES) do - eval( 'math.'..v..'('..x[1]..','..x[2]..')' ) - end -end -if platform ~= 'JME' then - for i,v in ipairs(TWOARGS_JSE) do - print( '---------- math.'..v..' (jse only) ----------' ) - for j,x in ipairs(BINOPVALUES) do - eval( 'math.'..v..'('..x[1]..','..x[2]..')' ) - end - end -end - --- var-arg math functions -for i,v in ipairs(VARARGSFUNCS) do - print( '---------- math.'..v..' ----------' ) - for j,x in ipairs(VARARGSVALUES) do - eval( 'math.'..v..'('..table.concat(x,',')..')' ) - end -end - --- random tests -print("----------- Random number tests") -local function testrandom(string,lo,hi) - local c,e = load('return '..string) - for i=1,5 do - local s,e = pcall(c) - if s then - print( string, s and type(e) or e, (e>=lo) and (e<=hi) ) - else - print( string, 'error', e ) - end - end -end -testrandom('math.random()',0,1) -testrandom('math.random(5,10)',5,10) -testrandom('math.random(30)',0,30) -testrandom('math.random(-4,-2)',-4,-2) -local t = {} -print( math.randomseed(20) ) -for i=1,20 do - t[i] = math.random() -end -print( '-- comparing new numbers') -for i=1,20 do - print( t[i] == math.random(), t[i] == t[0] ) -end -print( '-- resetting seed') - -print( math.randomseed(20) ) -for i=1,20 do - print( t[i] == math.random() ) -end - --- tests involving -0, which is folded into 0 for luaj, but not for plain lua -print("----------- Tests involving -0 and NaN") -print('0 == -0', 0 == -0) -t = {[0] = 10, 20, 30, 40, 50} -print('t[-0] == t[0]',t[-0] == t[0]) -local x = -1 -local mz, z = 0/x, 0 -- minus zero, zero -print('mz, z', mz, z) -print('mz == z', mz == z) -local a = {[mz] = 1} -print('a[z] == 1 and a[mz] == 1', a[z] == 1 and a[mz] == 1) --- string with same binary representation as 0.0 (may create problems --- for constant manipulation in the pre-compiler) -local a1, a2, a3, a4, a5 = 0, 0, "\0\0\0\0\0\0\0\0", 0, "\0\0\0\0\0\0\0\0" -assert(a1 == a2 and a2 == a4 and a1 ~= a3) -assert(a3 == a5) - ---]] diff --git a/test/lua/metatags.lua b/test/lua/metatags.lua deleted file mode 100644 index 676590be..00000000 --- a/test/lua/metatags.lua +++ /dev/null @@ -1,286 +0,0 @@ -local anumber,bnumber = 111,23.45 -local astring,bstring = "abc","def" -local anumstr,bnumstr = tostring(anumber),tostring(bnumber) -local aboolean,bboolean = false,true -local afunction,bfunction = function() end, function() end -local athread,bthead = coroutine.create(afunction),coroutine.create(bfunction) -local atable,btable = {},{} -local values = { anumber, aboolean, afunction, athread, atable } -local groups -local ts = tostring -local tb,count = {},0 - -tostring = function(o) - local t = type(o) - if t~='thread' and t~='function' and t~='table' then return ts(o) end - if not tb[o] then - count = count + 1 - tb[o] = t..'.'..count - end - return tb[o] -end - -local buildop = function(name) - return function(a,b) - print( 'mt.__'..name..'()', a, b ) - return '__'..name..'-result' - end -end -local buildop3 = function(name) - return function(a,b,c) - print( 'mt.__'..name..'()', a, b, c ) - return '__'..name..'-result' - end -end -local buildop1 = function(name) - return function(a) - print( 'mt.__'..name..'()', a ) - return '__'..name..'-result' - end -end - -local mt = { - __call=buildop('call'), - __add=buildop('add'), - __sub=buildop('sub'), - __mul=buildop('mul'), - __div=buildop('div'), - __pow=buildop('pow'), - __mod=buildop('mod'), - __unm=buildop1('unm'), - __len=buildop1('len'), - __lt=buildop('lt'), - __le=buildop('le'), - __index=buildop('index'), - __newindex=buildop3('newindex'), - __concat=buildop('concat'), -} - --- pcall a function and check for a pattern in the error string -ecall = function(pattern, ...) - local s,e = pcall(...) - if not s then e = string.match(e,pattern) or e end - return s,e -end - -print( '---- __eq same types' ) -local eqmt = { __eq=buildop('eq'), } -groups = { {nil,nil}, {true,false}, {123,456}, {11,5.5}, {afunction,bfunction}, {athread,bthread}, {astring,bstring}, {anumber,anumstr} } -for i=1,#groups do - local a,b = groups[i][1], groups[i][2] - local amt,bmt = debug.getmetatable(a),debug.getmetatable(b) - print( type(a), type(b), 'before', pcall( function() return a==b end ) ) - print( type(a), type(b), 'before', pcall( function() return a~=b end ) ) - print( debug.setmetatable( a, eqmt ) ) - print( debug.setmetatable( b, eqmt ) ) - print( type(a), type(b), 'after', pcall( function() return a==b end ) ) - print( type(a), type(b), 'after', pcall( function() return a~=b end ) ) - print( debug.setmetatable( a, amt ) ) - print( debug.setmetatable( b, bmt ) ) -end - -print( '---- __eq, tables - should invoke metatag comparison' ) -groups = { {atable,btable} } -for i=1,#groups do - local a,b = groups[i][1], groups[i][2] - local amt,bmt = debug.getmetatable(a),debug.getmetatable(b) - print( type(a), type(b), 'before', pcall( function() return a==b end ) ) - print( type(a), type(b), 'before', pcall( function() return a~=b end ) ) - print( debug.setmetatable( a, eqmt ) ) - print( debug.setmetatable( b, eqmt ) ) - print( type(a), type(b), 'after-a', pcall( function() return a==b end ) ) - print( type(a), type(b), 'after-a', pcall( function() return a~=b end ) ) - print( debug.setmetatable( a, amt ) ) - print( debug.setmetatable( b, bmt ) ) -end - - -print( 'nilmt', debug.getmetatable(nil) ) -print( 'boolmt', debug.getmetatable(true) ) -print( 'number', debug.getmetatable(1) ) -print( 'function', debug.getmetatable(afunction) ) -print( 'thread', debug.getmetatable(athread) ) - -print( '---- __call' ) -for i=1,#values do - local a = values[i] - local amt = debug.getmetatable(a) - print( type(a), 'before', ecall( 'attempt to call', function() return a('a','b') end ) ) - print( debug.setmetatable( a, mt ) ) - print( type(a), 'after', pcall( function() return a() end ) ) - print( type(a), 'after', pcall( function() return a('a') end ) ) - print( type(a), 'after', pcall( function() return a('a','b') end ) ) - print( type(a), 'after', pcall( function() return a('a','b','c') end ) ) - print( type(a), 'after', pcall( function() return a('a','b','c','d') end ) ) - print( debug.setmetatable( a, amt ) ) -end - -print( '---- __add, __sub, __mul, __div, __pow, __mod' ) -local groups = { {aboolean, aboolean}, {aboolean, athread}, {aboolean, afunction}, {aboolean, "abc"}, {aboolean, atable} } -for i=1,#groups do - local a,b = groups[i][1], groups[i][2] - local amt,bmt = debug.getmetatable(a),debug.getmetatable(b) - print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return a+b end ) ) - print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return b+a end ) ) - print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return a-b end ) ) - print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return b-a end ) ) - print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return a*b end ) ) - print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return b*a end ) ) - print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return a^b end ) ) - print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return b^a end ) ) - print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return a%b end ) ) - print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return b%a end ) ) - print( debug.setmetatable( a, mt ) ) - print( type(a), type(b), 'after', pcall( function() return a+b end ) ) - print( type(a), type(b), 'after', pcall( function() return b+a end ) ) - print( type(a), type(b), 'after', pcall( function() return a-b end ) ) - print( type(a), type(b), 'after', pcall( function() return b-a end ) ) - print( type(a), type(b), 'after', pcall( function() return a*b end ) ) - print( type(a), type(b), 'after', pcall( function() return b*a end ) ) - print( type(a), type(b), 'after', pcall( function() return a^b end ) ) - print( type(a), type(b), 'after', pcall( function() return b^a end ) ) - print( type(a), type(b), 'after', pcall( function() return a%b end ) ) - print( type(a), type(b), 'after', pcall( function() return b%a end ) ) - print( debug.setmetatable( a, amt ) ) - print( debug.setmetatable( b, bmt ) ) -end - -print( '---- __len' ) -values = { aboolean, afunction, athread, anumber } -for i=1,#values do - local a = values[i] - local amt = debug.getmetatable(a) - print( type(a), 'before', ecall( 'attempt to get length of ', function() return #a end ) ) - print( debug.setmetatable( a, mt ) ) - print( type(a), 'after', pcall( function() return #a end ) ) - print( debug.setmetatable( a, amt ) ) -end --- -print( '---- __neg' ) -values = { aboolean, afunction, athread, "abcd", atable, anumber } -for i=1,#values do - local a = values[i] - local amt = debug.getmetatable(a) - print( type(v), 'before', ecall( 'attempt to perform arithmetic ', function() return -a end ) ) - print( debug.setmetatable( a, mt ) ) - print( type(v), 'after', pcall( function() return -a end ) ) - print( debug.setmetatable( a, amt ) ) -end - -print( '---- __lt, __le, same types' ) -local bfunction = function() end -local bthread = coroutine.create( bfunction ) -local btable = {} -local groups -groups = { {true, true}, {true, false}, {afunction, bfunction}, {athread, bthread}, {atable, atable}, {atable, btable} } -for i=1,#groups do - local a,b = groups[i][1], groups[i][2] - local amt,bmt = debug.getmetatable(a),debug.getmetatable(b) - print( type(a), type(b), 'before', ecall( 'attempt to compare', function() return ab end ) ) - print( type(a), type(b), 'before', ecall( 'attempt to compare', function() return a>=b end ) ) - print( debug.setmetatable( a, mt ) ) - print( debug.setmetatable( b, mt ) ) - print( type(a), type(b), 'after', pcall( function() return ab end ) ) - print( type(a), type(b), 'after', pcall( function() return a>=b end ) ) - print( debug.setmetatable( a, amt ) ) - print( debug.setmetatable( b, bmt ) ) -end - -print( '---- __lt, __le, different types' ) -groups = { {aboolean, athread}, } -for i=1,#groups do - local a,b = groups[i][1], groups[i][2] - local amt,bmt = debug.getmetatable(a),debug.getmetatable(b) - print( type(a), type(b), 'before', ecall( 'attempt to compare', function() return ab end ) ) - print( type(a), type(b), 'before', ecall( 'attempt to compare', function() return a>=b end ) ) - print( debug.setmetatable( a, mt ) ) - print( debug.setmetatable( b, mt ) ) - print( type(a), type(b), 'after-a', ecall( 'attempt to compare', function() return ab end ) ) - print( type(a), type(b), 'after-a', ecall( 'attempt to compare', function() return a>=b end ) ) - print( debug.setmetatable( a, amt ) ) - print( debug.setmetatable( b, bmt ) ) -end - -print( '---- __tostring' ) -values = { aboolean, afunction, athread, atable, "abc" } -local strmt = { __tostring=function(a) - return 'mt.__tostring('..type(a)..')' - end, -} -for i=1,#values do - local a = values[i] - local amt = debug.getmetatable(a) - print( debug.setmetatable( a, strmt ) ) - print( type(a), 'after', pcall( function() return ts(a) end ) ) - print( debug.setmetatable( a, amt ) ) -end - -print( '---- __index, __newindex' ) -values = { aboolean, anumber, afunction, athread } -for i=1,#values do - local a = values[i] - local amt = debug.getmetatable(a) - print( type(a), 'before', ecall( 'attempt to index', function() return a.foo end ) ) - print( type(a), 'before', ecall( 'attempt to index', function() return a[123] end ) ) - print( type(a), 'before', ecall( 'index', function() a.foo = 'bar' end ) ) - print( type(a), 'before', ecall( 'index', function() a[123] = 'bar' end ) ) - print( type(a), 'before', ecall( 'attempt to index', function() return a:foo() end ) ) - print( debug.setmetatable( a, mt ) ) - print( type(a), 'after', pcall( function() return a.foo end ) ) - print( type(a), 'after', pcall( function() return a[123] end ) ) - print( type(a), 'after', pcall( function() a.foo = 'bar' end ) ) - print( type(a), 'after', pcall( function() a[123] = 'bar' end ) ) - print( type(a), 'after', ecall( 'attempt to call', function() return a:foo() end ) ) - print( debug.setmetatable( a, amt ) ) -end - -print( '---- __concat' ) -groups = { {atable, afunction}, {afunction, atable}, {123, nil}, {nil, 123} } -local s,t,u = 'sss',777 -local concatresult = setmetatable( { '__concat-result' }, { - __tostring=function() - return 'concat-string-result' - end } ) -local concatmt = { - __concat=function(a,b) - print( 'mt.__concat('..type(a)..','..type(b)..')', a, b ) - return concatresult - end -} -for i=1,#groups do - local a,b = groups[i][1], groups[i][2] - local amt,bmt = debug.getmetatable(a),debug.getmetatable(b) - print( type(a), type(b), 'before', ecall( 'attempt to concatenate ', function() return a..b end ) ) - print( type(a), type(b), 'before', ecall( 'attempt to concatenate ', function() return b..a end ) ) - print( type(a), type(s), type(t), 'before', ecall( 'attempt to concatenate ', function() return a..s..t end ) ) - print( type(s), type(a), type(t), 'before', ecall( 'attempt to concatenate ', function() return s..a..t end ) ) - print( type(s), type(t), type(a), 'before', ecall( 'attempt to concatenate ', function() return s..t..a end ) ) - print( debug.setmetatable( a, concatmt ) ) - print( type(a), type(b), 'after', pcall( function() return a..b end ) ) - print( type(a), type(b), 'after', pcall( function() return b..a end ) ) - print( type(a), type(s), type(t), 'before', pcall( function() return a..s..t end ) ) - print( type(s), type(a), type(t), 'before', ecall( 'attempt to concatenate ', function() return s..a..t end ) ) - print( type(s), type(t), type(a), 'before', ecall( 'attempt to concatenate ', function() return s..t..a end ) ) - print( debug.setmetatable( a, amt ) ) - print( debug.setmetatable( b, bmt ) ) -end - -print( '---- __metatable' ) -values = { aboolean, afunction, athread, atable, "abc" } -local mtmt = { __metatable={}, } -for i=1,#values do - local a = values[i] - local amt = debug.getmetatable(a) - print( type(a), 'before', pcall( function() return debug.getmetatable(a), getmetatable(a) end ) ) - print( debug.setmetatable( a, mtmt ) ) - print( type(a), 'after', pcall( function() return debug.getmetatable(a), getmetatable(a) end ) ) - print( debug.setmetatable( a, amt ) ) -end diff --git a/test/lua/oslib.lua b/test/lua/oslib.lua deleted file mode 100644 index dd40a791..00000000 --- a/test/lua/oslib.lua +++ /dev/null @@ -1,60 +0,0 @@ --- simple os-library tests --- --- because the nature of the "os" library is to provide os-specific behavior, --- the compatibility tests must be extremely loose, and can really only --- compare things like return value type to be meaningful. --- --- actual os behavior needs to go in an oslib function test --- -local pcall = function(...) - local s,e,f = pcall(...) - return s,type(e),type(f) -end -print( 'os', type(os) ) -print( 'os.clock()', pcall( os.clock ) ) -print( 'os.date()', pcall( os.date ) ) -print( 'os.difftime(123000, 21500)', pcall( os.difftime, 123000, 21250 ) ) -print( 'os.getenv()', pcall( os.getenv ) ) -print( 'os.getenv("bogus.key")', pcall( os.getenv, 'bogus.key' ) ) -local s,p = pcall( os.tmpname ) -local s,q = pcall( os.tmpname ) -print( 'os.tmpname()', s, p ) -print( 'os.tmpname()', s, q ) --- permission denied on windows ---print( 'os.remove(p)', pcall( os.remove, p ) ) ---print( 'os.rename(p,q)', pcall( os.rename, p, q ) ) -local s,f = pcall( io.open, p,"w" ) -print( 'io.open', s, f ) -print( 'write', pcall( f.write, f, "abcdef 12345" ) ) -print( 'close', pcall( f.close, f ) ) -print( 'os.rename(p,q)', pcall( os.rename, p, q ) ) -print( 'os.remove(q)', pcall( os.remove, q ) ) -print( 'os.remove(q)', pcall( os.remove, q ) ) --- setlocale not supported on jse yet --- print( 'os.setlocale()', pcall( os.setlocale ) ) --- print( 'os.setlocale("jp")', pcall( os.setlocale, "jp" ) ) --- print( 'os.setlocale("us","monetary")', pcall( os.setlocale, "us", "monetary" ) ) --- print( 'os.setlocale(nil,"all")', pcall( os.setlocale, nil, "all" ) ) -print( 'os.setlocale("C")', pcall( os.setlocale, "C" ) ) -print( 'os.exit', type(os.exit) ) - --- os.date() formatting -local t = 1281364496 -- Aug 9, 2010, 2:34:56 PM (Monday) -local function p(s) - if pcall(os.date, s, t) then - print( "os.date('"..s.."', "..t..")", pcall(os.date, s, t)) - end -end -for i= 65, 90 do - p('%'..string.char(i + 97 - 65)) - p('%'..string.char(i)) -end -local tbl = os.date('*t', t) -for i,k in ipairs({'year', 'month', 'day', 'hour', 'min', 'sec', 'wday', 'yday', 'isdst'}) do - local v = tbl[k] - print('k', type(k), k, 'v', type(v), v) -end - -print('type(os.time())', type(os.time())) -print('os.time({year=1971, month=2, day=25})', os.time({year=1971, month=2, day=25})) -print('os.time({year=1971, month=2, day=25, hour=11, min=22, sec=33})', os.time({year=1971, month=2, day=25, hour=11, min=22, sec=33})) diff --git a/test/lua/perf/binarytrees.lua b/test/lua/perf/binarytrees.lua deleted file mode 100644 index 04ca7eee..00000000 --- a/test/lua/perf/binarytrees.lua +++ /dev/null @@ -1,50 +0,0 @@ --- The Computer Language Benchmarks Game --- http://shootout.alioth.debian.org/ --- contributed by Mike Pall - -local function BottomUpTree(item, depth) - if depth > 0 then - local i = item + item - depth = depth - 1 - local left, right = BottomUpTree(i-1, depth), BottomUpTree(i, depth) - return { item, left, right } - else - return { item } - end -end - -local function ItemCheck(tree) - if tree[2] then - return tree[1] + ItemCheck(tree[2]) - ItemCheck(tree[3]) - else - return tree[1] - end -end - -local N = tonumber(arg and arg[1]) or 0 -local mindepth = 4 -local maxdepth = mindepth + 2 -if maxdepth < N then maxdepth = N end - -do - local stretchdepth = maxdepth + 1 - local stretchtree = BottomUpTree(0, stretchdepth) - io.write(string.format("stretch tree of depth %d\t check: %d\n", - stretchdepth, ItemCheck(stretchtree))) -end - -local longlivedtree = BottomUpTree(0, maxdepth) - -for depth=mindepth,maxdepth,2 do - local iterations = 2 ^ (maxdepth - depth + mindepth) - local check = 0 - for i=1,iterations do - check = check + ItemCheck(BottomUpTree(1, depth)) + - ItemCheck(BottomUpTree(-1, depth)) - end - io.write(string.format("%d\t trees of depth %d\t check: %d\n", - iterations*2, depth, check)) -end - -io.write(string.format("long lived tree of depth %d\t check: %d\n", - maxdepth, ItemCheck(longlivedtree))) diff --git a/test/lua/perf/fannkuch.lua b/test/lua/perf/fannkuch.lua deleted file mode 100644 index fc706d7f..00000000 --- a/test/lua/perf/fannkuch.lua +++ /dev/null @@ -1,51 +0,0 @@ --- The Computer Language Benchmarks Game --- http://shootout.alioth.debian.org/ --- contributed by Mike Pall - -local function fannkuch(n) - local p, q, s, odd, check, maxflips = {}, {}, {}, true, 0, 0 - for i=1,n do p[i] = i; q[i] = i; s[i] = i end - repeat - -- Print max. 30 permutations. - if check < 30 then - if not p[n] then return maxflips end -- Catch n = 0, 1, 2. - io.write(table.unpack(p)); io.write("\n") - check = check + 1 - end - -- Copy and flip. - local q1 = p[1] -- Cache 1st element. - if p[n] ~= n and q1 ~= 1 then -- Avoid useless work. - for i=2,n do q[i] = p[i] end -- Work on a copy. - for flips=1,1000000 do -- Flip ... - local qq = q[q1] - if qq == 1 then -- ... until 1st element is 1. - if flips > maxflips then maxflips = flips end -- New maximum? - break - end - q[q1] = q1 - if q1 >= 4 then - local i, j = 2, q1 - 1 - repeat q[i], q[j] = q[j], q[i]; i = i + 1; j = j - 1; until i >= j - end - q1 = qq - end - end - -- Permute. - if odd then - p[2], p[1] = p[1], p[2]; odd = false -- Rotate 1<-2. - else - p[2], p[3] = p[3], p[2]; odd = true -- Rotate 1<-2 and 1<-2<-3. - for i=3,n do - local sx = s[i] - if sx ~= 1 then s[i] = sx-1; break end - if i == n then return maxflips end -- Out of permutations. - s[i] = i - -- Rotate 1<-...<-i+1. - local t = p[1]; for j=1,i do p[j] = p[j+1] end; p[i+1] = t - end - end - until false -end - -local n = tonumber(arg and arg[1]) or 1 -io.write("Pfannkuchen(", n, ") = ", fannkuch(n), "\n") diff --git a/test/lua/perf/nbody.lua b/test/lua/perf/nbody.lua deleted file mode 100644 index b244adf3..00000000 --- a/test/lua/perf/nbody.lua +++ /dev/null @@ -1,123 +0,0 @@ --- The Great Computer Language Shootout --- http://shootout.alioth.debian.org/ --- contributed by Isaac Gouy, tuned by Mike Pall - -local sqrt = math.sqrt - -local PI = 3.141592653589793 -local SOLAR_MASS = 4 * PI * PI -local DAYS_PER_YEAR = 365.24 - -local Jupiter = { - x = 4.84143144246472090e+00 - ,y = -1.16032004402742839e+00 - ,z = -1.03622044471123109e-01 - ,vx = 1.66007664274403694e-03 * DAYS_PER_YEAR - ,vy = 7.69901118419740425e-03 * DAYS_PER_YEAR - ,vz = -6.90460016972063023e-05 * DAYS_PER_YEAR - ,mass = 9.54791938424326609e-04 * SOLAR_MASS -} - -local Saturn = { - x = 8.34336671824457987e+00 - ,y = 4.12479856412430479e+00 - ,z = -4.03523417114321381e-01 - ,vx = -2.76742510726862411e-03 * DAYS_PER_YEAR - ,vy = 4.99852801234917238e-03 * DAYS_PER_YEAR - ,vz = 2.30417297573763929e-05 * DAYS_PER_YEAR - ,mass = 2.85885980666130812e-04 * SOLAR_MASS -} - -local Uranus = { - x = 1.28943695621391310e+01 - ,y = -1.51111514016986312e+01 - ,z = -2.23307578892655734e-01 - ,vx = 2.96460137564761618e-03 * DAYS_PER_YEAR - ,vy = 2.37847173959480950e-03 * DAYS_PER_YEAR - ,vz = -2.96589568540237556e-05 * DAYS_PER_YEAR - ,mass = 4.36624404335156298e-05 * SOLAR_MASS -} - -local Neptune = { - x = 1.53796971148509165e+01 - ,y = -2.59193146099879641e+01 - ,z = 1.79258772950371181e-01 - ,vx = 2.68067772490389322e-03 * DAYS_PER_YEAR - ,vy = 1.62824170038242295e-03 * DAYS_PER_YEAR - ,vz = -9.51592254519715870e-05 * DAYS_PER_YEAR - ,mass = 5.15138902046611451e-05 * SOLAR_MASS -} - -local Sun = { x = 0, y = 0, z = 0, - vx = 0, vy = 0, vz = 0, mass = SOLAR_MASS } - -local function advance(bodies, nbody, dt) - for i=1,nbody do - local bi = bodies[i] - local bix, biy, biz, bimass = bi.x, bi.y, bi.z, bi.mass - local bivx, bivy, bivz = bi.vx, bi.vy, bi.vz - for j=i+1,nbody do - local bj = bodies[j] - local dx, dy, dz = bix-bj.x, biy-bj.y, biz-bj.z - local distance = sqrt(dx*dx + dy*dy + dz*dz) - local mag = dt / (distance * distance * distance) - local bim, bjm = bimass*mag, bj.mass*mag - bivx = bivx - (dx * bjm) - bivy = bivy - (dy * bjm) - bivz = bivz - (dz * bjm) - bj.vx = bj.vx + (dx * bim) - bj.vy = bj.vy + (dy * bim) - bj.vz = bj.vz + (dz * bim) - end - bi.vx = bivx - bi.vy = bivy - bi.vz = bivz - end - for i=1,nbody do - local bi = bodies[i] - bi.x = bi.x + (dt * bi.vx) - bi.y = bi.y + (dt * bi.vy) - bi.z = bi.z + (dt * bi.vz) - end -end - - -local function energy(bodies, nbody) - local e = 0 - for i=1,nbody do - local bi = bodies[i] - local vx, vy, vz, bim = bi.vx, bi.vy, bi.vz, bi.mass - e = e + (0.5 * bim * (vx*vx + vy*vy + vz*vz)) - for j=i+1,nbody do - local bj = bodies[j] - local dx, dy, dz = bi.x-bj.x, bi.y-bj.y, bi.z-bj.z - local distance = sqrt(dx*dx + dy*dy + dz*dz) - e = e - ((bim * bj.mass) / distance) - end - end - return e -end - - -local function offsetMomentum(b, nbody) - local px, py, pz = 0, 0, 0 - for i=1,nbody do - local bi = b[i] - local bim = bi.mass - px = px + (bi.vx * bim) - py = py + (bi.vy * bim) - pz = pz + (bi.vz * bim) - end - b[1].vx = -px / SOLAR_MASS - b[1].vy = -py / SOLAR_MASS - b[1].vz = -pz / SOLAR_MASS -end - -local N = tonumber(arg and arg[1]) or 1000 -local bodies = { Sun, Jupiter, Saturn, Uranus, Neptune } -local nbody = #bodies - -offsetMomentum(bodies, nbody) -io.write( string.format("%0.9f",energy(bodies, nbody)), "\n") -for i=1,N do advance(bodies, nbody, 0.01) end -io.write( string.format("%0.9f",energy(bodies, nbody)), "\n") diff --git a/test/lua/perf/nsieve.lua b/test/lua/perf/nsieve.lua deleted file mode 100644 index 475a05b4..00000000 --- a/test/lua/perf/nsieve.lua +++ /dev/null @@ -1,35 +0,0 @@ --- The Computer Language Shootout --- http://shootout.alioth.debian.org/ --- contributed by Isaac Gouy --- modified by Mike Pall - - -local function nsieve(m,isPrime) - for i=2,m do - isPrime[i] = true - end - local count = 0 - - for i=2,m do - if isPrime[i] then - for k=i+i, m, i do - if isPrime[k] then isPrime[k] = false end - end - count = count + 1 - end - end - return count -end - - -local n = tonumber(arg and arg[1]) or 1 -local flags = {} - -local m = (2^n)*10000 -print( string.format("Primes up to %8d %8d", m, nsieve(m,flags))) - -m = (2^(n-1))*10000 -print( string.format("Primes up to %8d %8d", m, nsieve(m,flags))) - -m = (2^(n-2))*10000 -print( string.format("Primes up to %8d %8d", m, nsieve(m,flags))) diff --git a/test/lua/repack.sh b/test/lua/repack.sh deleted file mode 100644 index ffece46c..00000000 --- a/test/lua/repack.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash -# -# unpack the luaj test archive, compile and run it locally, and repack the results - -# unzip existing archive -unzip -n luaj3.0-tests.zip -rm *.lc *.out */*.lc */*.out - -# compile tests for compiler and save binary files -for DIR in "lua5.2.1-tests" "regressions"; do - cd ${DIR} - FILES=`ls -1 *.lua | awk 'BEGIN { FS="." } ; { print $1 }'` - for FILE in $FILES ; do - echo 'compiling' `pwd` $FILE - luac ${FILE}.lua - mv luac.out ${FILE}.lc - done - cd .. -done - -# run test lua scripts and save output -for DIR in "errors" "perf" "."; do - cd ${DIR} - FILES=`ls -1 *.lua | awk 'BEGIN { FS="." } ; { print $1 }'` - for FILE in $FILES ; do - echo 'executing' `pwd` $FILE - lua ${FILE}.lua JSE > ${FILE}.out - done - cd .. -done -cd lua - -# create new zipfile -rm -f luaj3.0-tests.zip regressions -zip luaj3.0-tests.zip *.lua *.lc *.out */*.lua */*.lc */*.out - -# cleanup -rm *.out */*.lc */*.out -rm -r lua5.2.1-tests diff --git a/test/lua/stringlib.lua b/test/lua/stringlib.lua deleted file mode 100644 index dbaf1931..00000000 --- a/test/lua/stringlib.lua +++ /dev/null @@ -1,192 +0,0 @@ -print( string.find("1234567890", ".", 0, true) ) -print( string.find( 'alo alx 123 b\0o b\0o', '(..*) %1' ) ) -print( string.find( 'aloALO', '%l*' ) ) -print( string.find( ' \n isto � assim', '%S%S*' ) ) - -print( string.find( "", "" ) ) -print( string.find( "ababaabbaba", "abb" ) ) -print( string.find( "ababaabbaba", "abb", 7 ) ) - -print( string.match( "aabaa", "a*" ) ) -print( string.match( "aabaa", "a*", 3 ) ) -print( string.match( "aabaa", "a*b" ) ) -print( string.match( "aabaa", "a*b", 3 ) ) - -print( string.match( "abbaaababaabaaabaa", "b(a*)b" ) ) - -print( string.match( "abbaaababaabaaabaa", "b(a*)()b" ) ) -print( string.match( "abbaaababaabaaabaa", "b(a*)()b", 3 ) ) -print( string.match( "abbaaababaabaaabaa", "b(a*)()b", 8 ) ) -print( string.match( "abbaaababaabaaabaa", "b(a*)()b", 12 ) ) - -print( string.byte("hi", -3) ) - -print( string.gsub("ABC", "@(%x+)", function(s) return "|abcd" end) ) -print( string.gsub("@123", "@(%x+)", function(s) return "|abcd" end) ) -print( string.gsub("ABC@123", "@(%x+)", function(s) return "|abcd" end) ) -print( string.gsub("ABC@123@def", "@(%x+)", function(s) return "|abcd" end) ) -print( string.gsub("ABC@123@qrs@def@tuv", "@(%x+)", function(s) return "|abcd" end) ) -print( string.gsub("ABC@123@qrs@def@tuv", "@(%x+)", function(s) return "@ab" end) ) - -print( tostring(1234567890123) ) -print( tostring(1234567890124) ) -print( tostring(1234567890125) ) - -function f1(s, p) - print(p) - p = string.gsub(p, "%%([0-9])", function (s) return "%" .. (s+1) end) - print(p) - p = string.gsub(p, "^(^?)", "%1()", 1) - print(p) - p = string.gsub(p, "($?)$", "()%1", 1) - print(p) - local t = {string.match(s, p)} - return string.sub(s, t[1], t[#t] - 1) -end - -print( pcall( f1, 'alo alx 123 b\0o b\0o', '(..*) %1' ) ) - -local function badpat() - print( string.gsub( "alo", "(.)", "%2" ) ) -end - -print( ( pcall( badpat ) ) ) - -for k, v in string.gmatch("w=200&h=150", "(%w+)=(%w+)") do - print(k, v) -end - --- string.sub -function t(str) - local i = { 0, 1, 2, 8, -1 } - for ki,vi in ipairs(i) do - local s,v = pcall( string.sub, str, vi ) - print( 'string.sub("'..str..'",'..tostring(vi)..')='..tostring(s)..',"'..tostring(v)..'"' ) - local j = { 0, 1, 2, 4, 8, -1 } - for kj,vj in ipairs(j) do - local s,v = pcall( string.sub, str, vi, vj ) - print( 'string.sub("'..str..'",'..tostring(vi)..','..tostring(vj)..')='..tostring(s)..',"'..tostring(v)..'"' ) - end - end -end -t( 'abcdefghijklmn' ) -t( 'abcdefg' ) -t( 'abcd' ) -t( 'abc' ) -t( 'ab' ) -t( 'a' ) -t( '' ) - -print(string.len("Hello, world")) -print(#"Hello, world") -print(string.len("\0\0\0")) -print(#"\0\0\0") -print(string.len("\0\1\2\3")) -print(#"\0\1\2\3") -local s = "My JaCk-O-lAnTeRn CaSe TeXt" -print(s, string.len(s), #s) - - --- string.format -print(string.format("(%.0d) (%.0d) (%.0d)", 0, -5, 9)) -print(string.format("(%.1d) (%.1d) (%.1d)", 0, -5, 9)) -print(string.format("(%.2d) (%.2d) (%.2d)", 0, -5, 9)) - -print(string.format("(%+.0d) (%+.0d) (%+.0d)", 0, -5, 9)) -print(string.format("(%+.1d) (%+.1d) (%+.1d)", 0, -5, 9)) -print(string.format("(%+.2d) (%+.2d) (%+.2d)", 0, -5, 9)) - -print(string.format("(%+3d) (% 3d) (%+ 3d)", 55, 55, 55)) - -print(string.format("(%-1d) (%-1d) (%-1d)", 1, 12, -12)) -print(string.format("(%-2d) (%-2d) (%-2d)", 1, 12, -12)) -print(string.format("(%-3d) (%-3d) (%-3d)", 1, 12, -12)) - - -print(string.format("(%8x) (%8d) (%8o)", 255, 255, 255)) -print(string.format("(%08x) (%08d) (%08o)", 255, 255, 255)) - -print(string.format("simple%ssimple", " simple ")) - -local testformat = function(message,fmt,...) - local s,e = pcall( string.format, fmt, ... ) - if s then - if string.find(fmt, 'q') then - print(message, e) - end - print( message, string.byte(e,1,#e) ) - else - print( message, 'error', e ) - end -end - -testformat('plain %', "%%") -testformat("specials (%s)", "---%s---", " %% \000 \r \n ") -testformat("specials (%q)", "---%q---", " %% \000 \r \n ") -testformat("specials (%q)", "---%q---", "0%%0\0000\r0\n0") -testformat("controls (%q)", "---%q---", ' \a \b \f \t \v \\ ') -testformat("controls (%q)", "---%q---", '0\a0\b0\f0\t0\v0\\0') -testformat("extended (%q)", "---%q---", ' \222 \223 \224 ') -testformat("extended (%q)", "---%q---", '0\2220\2230\2240') -testformat("embedded newlines", "%s\r%s\n%s", '===', '===', '===') - --- format long string -print("this is a %s long string", string.rep("really, ", 30)) - -local function pc(...) - local s,e = pcall(...) - return s and e or 'false-'..type(e) -end - -local function strtests(name,func,...) - print(name, 'good', pc( func, ... ) ) - print(name, 'empty', pc( func ) ) - print(name, 'table', pc( func, {} ) ) - print(name, 'nil', pc( func, nil ) ) -end - -strtests('lower', string.lower, s ) -strtests('upper', string.upper, s ) -strtests('reverse', string.reverse, s ) -strtests('char', string.char, 92, 60, 61, 93 ) -stringdumptest = function() - return load(string.dump(function(x) return 'foo->'..x end),'bar')('bat') -end -print( 'string.dump test:', pcall(stringdumptest) ) - - --- floating point formats (not supported yet) ---[==[ -local prefixes = {'','+','-'} -local lengths = {'7','2','0','1',''} -local letters = {'f','e','g'} -local fmt, spec, desc -for i,letter in ipairs(letters) do - for k,before in ipairs(lengths) do - for j,prefix in ipairs(prefixes) do - spec = '(%'..prefix..before..letter..')' - fmt = spec..'\t'..spec..'\t'..spec..'\t'..spec..'\t'..spec..'\t'..spec - print(spec, string.format(fmt, 12.34, -12.34, 1/11, -1/11, 300/11, -300/11) ) - for l,after in ipairs(lengths) do - spec = '(%'..prefix..before..'.'..after..letter..')' - fmt = spec..' '..spec..' '..spec..' '..spec..' '..spec..' '..spec - print(spec, string.format(fmt, 12.34, -12.34, 1/11, -1/11, 300/11, -300/11) ) - end - end - end -end ---]==] - -local function fmterr(...) - local r, s = pcall(...) - if r then - return s - else - s = string.gsub(s, "stdin:%d+:%s*", "") - return s - end -end - -print(fmterr(string.find, "ab%c)0(", "%")) -print(fmterr(string.find, "ab%c)0(", "(")) -print(pcall(string.find, "ab%c)0(", ")")) diff --git a/test/lua/tablelib.lua b/test/lua/tablelib.lua deleted file mode 100644 index 8f99ca71..00000000 --- a/test/lua/tablelib.lua +++ /dev/null @@ -1,284 +0,0 @@ -local func = function(t,...) - return (...) -end -local tbl = setmetatable({},{__index=func}) -print( tbl[2] ) - - --- tostring replacement that assigns ids -local ts,id,nid,types = tostring,{},0,{table='tbl',thread='thr',userdata='uda',['function']='func'} -tostring = function(x) - if not x or not types[type(x)] then return ts(x) end - if not id[x] then nid=nid+1; id[x]=types[type(x)]..'.'..nid end - return id[x] -end - -local t = { "one", "two", "three", a='aaa', b='bbb', c='ccc' } - -table.insert(t,'six'); -table.insert(t,1,'seven'); -table.insert(t,4,'eight'); -table.insert(t,7,'nine'); -table.insert(t,10,'ten'); print( #t ) - --- concat -print( '-- concat tests' ) -function tryconcat(t) - print( table.concat(t) ) - print( table.concat(t,'--') ) - print( table.concat(t,',',2) ) - print( table.concat(t,',',2,2) ) - print( table.concat(t,',',5,2) ) -end -tryconcat( { "one", "two", "three", a='aaa', b='bbb', c='ccc' } ) -tryconcat( { "one", "two", "three", "four", "five" } ) -function tryconcat(t) - print( table.concat(t) ) - print( table.concat(t,'--') ) - print( table.concat(t,',',2) ) -end -tryconcat( { a='aaa', b='bbb', c='ccc', d='ddd', e='eee' } ) -tryconcat( { [501]="one", [502]="two", [503]="three", [504]="four", [505]="five" } ) -tryconcat( {} ) - --- print the elements of a table in a platform-independent way -function eles(t,f) - f = f or pairs - all = {} - for k,v in f(t) do - table.insert( all, "["..tostring(k).."]="..tostring(v) ) - end - table.sort( all ) - return "{"..table.concat(all,',').."}" -end - --- insert, len -print( '-- insert, len tests' ) -local t = { "one", "two", "three", a='aaa', b='bbb', c='ccc' } - -print( eles(t), #t ) -table.insert(t,'six'); print( eles(t), #t ) -table.insert(t,1,'seven'); print( eles(t), #t ) -table.insert(t,4,'eight'); print( eles(t), #t ) -table.insert(t,7,'nine'); print( eles(t), #t ) -table.insert(t,10,'ten'); print( eles(t), #t ) -print( '#{}', #{} ) -print( '#{"a"}', #{"a"} ) -print( '#{"a","b"}', #{"a","b"} ) -print( '#{"a",nil}', #{"a",nil} ) -print( '#{nil,nil}', #{nil,nil} ) -print( '#{nil,"b"}', #{nil,"b"}==0 or #{nil,"b"}==2 ) -print( '#{"a","b","c"}', #{"a","b","c"} ) -print( '#{"a","b",nil}', #{"a","b",nil} ) -print( '#{"a",nil,nil}', #{"a",nil,nil} ) -print( '#{nil,nil,nil}', #{nil,nil,nil} ) -print( '#{nil,nil,"c"}', #{nil,nil,"c"}==0 or #{nil,nil,"c"}==3 ) -print( '#{nil,"b","c"}', #{nil,"b","c"}==0 or #{nil,"b","c"}==3 ) -print( '#{nil,"b",nil}', #{nil,"b",nil}==0 or #{nil,"b",nil}==2 ) -print( '#{"a",nil,"c"}', #{"a",nil,"c"}==1 or #{"a",nil,"c"}==3 ) - --- remove -print( '-- remove tests' ) -t = { "one", "two", "three", "four", "five", "six", "seven", [10]="ten", a='aaa', b='bbb', c='ccc' } -print( eles(t), #t ) -print( 'table.remove(t)', table.remove(t) ); print( eles(t), #t ) -print( 'table.remove(t,1)', table.remove(t,1) ); print( eles(t), #t ) -print( 'table.remove(t,3)', table.remove(t,3) ); print( eles(t), #t ) -print( 'table.remove(t,5)', table.remove(t,5) ); print( eles(t), #t ) -print( 'table.remove(t,10)', table.remove(t,10) ); print( eles(t), #t ) -print( 'table.remove(t,-1)', table.remove(t,-1) ); print( eles(t), #t ) -print( 'table.remove(t,-1)', table.remove(t,-1) ) ; print( eles(t), #t ) - --- sort -print( '-- sort tests' ) -function sorttest(t,f) - t = (t) - print( table.concat(t,'-') ) - if f then - table.sort(t,f) - else - table.sort(t) - end - print( table.concat(t,'-') ) -end -sorttest{ "one", "two", "three" } -sorttest{ "www", "vvv", "uuu", "ttt", "sss", "zzz", "yyy", "xxx" } -sorttest( { "www", "vvv", "uuu", "ttt", "sss", "zzz", "yyy", "xxx" }, function(a,b) return b0, returning f2(n-1,n,...)", n-1,n,... ) - return f2(n-1,n,...) -end - -local function f3(n,...) - if n <= 0 then - return sum(...) - end - print( " f3,n-1,n,...", f3,n-1,n,... ) - return pcall(f3,n-1,n,...) -end - -local function all(f) - for n=0,3 do - t = {} - for m=1,5 do - print( "--f, n, table.unpack(t)", f, n, table.unpack(t) ) - print( pcall( f, n, table.unpack(t)) ) - t[m] = m - end - end -end - -all(f1) -all(f2) -all(f3) - - -local function f(x) - -- tailcall to a builtin - return math.abs(x) -end - -local function factorial(i) - local function helper(product, n) - if n <= 0 then - return product - else - -- tail call to a nested Lua function - return helper(n * product, n - 1) - end - end - return helper(1, i) -end - -local result1 = factorial(5) -print(result1) -print(factorial(5)) - -local result2 = f(-1234) -print( result2 ) - -local function fib_bad(n) - local function helper(i, a, b) - if i >= n then - return a - else - -- not recognized by luac as a tailcall! - local result = helper(i + 1, b, a + b) - return result - end - end - return helper(1, 1, 1) -end - -local function fib_good(n) - local function helper(i, a, b) - if i >= n then - return a - else - -- must be a tail call! - return helper(i + 1, b, a + b) - end - end - return helper(1, 1, 1) -end - -local aliases = { - ['1.#INF'] = 'inf', - ['-1.#INF'] = '-inf', - ['1.#IND'] = 'nan', - ['-1.#IND'] = 'nan', -} - -local p = function( s,e ) - print( s, e and aliases[tostring(e)] or e ) -end -p(pcall(fib_bad, 30)) ---p((pcall(fib_bad, 25000))) -p(pcall(fib_good, 30)) -p(pcall(fib_good, 25000)) - -local function fib_all(n, i, a, b) - i = i or 1 - a = a or 1 - b = b or 1 - if i >= n then - return - else - return a, fib_all(n, i+1, b, a+b) - end -end - -print(fib_all(10)) diff --git a/test/lua/upvalues.lua b/test/lua/upvalues.lua deleted file mode 100644 index 2c263dd8..00000000 --- a/test/lua/upvalues.lua +++ /dev/null @@ -1,97 +0,0 @@ - -print( '-------- simple upvalues tests --------' ) -local function simpleupvalues() - function test() - local x = 5 - function f() - x = x + 1 - return x - end - function g() - x = x - 1 - return x - end - print(f()) - print(g()) - return f, g - end - - f1, g1 = test() - print("f1()=", f1()) - print("g1()=", g1()) - - f2, g2 = test() - print("f2()=", f2()) - print("g2()=", g2()) - - print("g1()=", g1()) - print("f1()=", f1()) -end -print( 'simplevalues result:', pcall( simpleupvalues ) ) - - --- The point of this test is that when an upvalue is created, it may --- need to be inserted in the middle of the list, rather than always --- appended at the end. Otherwise, it may not be found when it is --- needed by another closure. -print( '----------- upvalued in middle ------------' ) -local function middleupvaluestest() - local function test() - local x = 3 - local y = 5 - local z = 7 - - local function f() - print("y=", y) - end - - local function g() - print("z=", z) - end - - local function h() - print("x=", x) - end - - local function setter(x1, y1, z1) - x = x1 - y = y1 - z = z1 - end - - return f, g, h, setter - end - - local f, g, h, setter = test() - - h() - f() - g() - - setter("x", "y", "z") - - h() - f() - g() -end -print( pcall( middleupvaluestest ) ) - - -print( '--------- nested upvalues ----------' ) -local function nestedupvaluestest() - local f - do - local x = 10 - function g() - print(x, f()) - end - end - - function f() - return 20 - end - - g() -end -print( 'nestedupvaluestest result:', pcall( nestedupvaluestest ) ) - diff --git a/test/lua/vm.lua b/test/lua/vm.lua deleted file mode 100644 index 25e13bec..00000000 --- a/test/lua/vm.lua +++ /dev/null @@ -1,250 +0,0 @@ - -print( '-------- basic vm tests --------' ) - -print( '-- boolean tests' ) -local function booleantests() - t = true - f = false - n = nil - s = "Hello" - z = 0 - one = 1 - - print(t) - print(f) - - print(not t) - print(not f) - print(not n) - print(not z) - print(not s) - print(not(not(t))) - print(not(not(z))) - print(not(not(n))) - - print(t and f) - print(t or f) - print(f and t) - print(f or t) - - print(f or one) - print(f or z) - print(f or n) - - print(t and one) - print(t and z) - print(t and n) -end -print( 'booleantests result:', pcall( booleantests ) ) - - -print( '------------- varargs' ) -local function varargstest() - function p(a,...) - print("a",a) - print("...",...) - print("...,a",...,a) - print("a,...",a,...) - end - function q(a,...) - print("a,arg[1],arg[2],arg[3]",a,arg.n,arg[1],arg[2],arg[3]) - end - function r(a,...) - print("a,arg[1],arg[2],arg[3]",a,arg.n,arg[1],arg[2],arg[3]) - print("a",a) - print("...",...) - print("...,a",...,a) - print("a,...",a,...) - end - function s(a) - local arg = { '1', '2', '3' } - print("a,arg[1],arg[2],arg[3]",a,arg[1],arg[2],arg[3]) - print("a",a) - end - function t(a,...) - local arg = { '1', '2', '3' } - print("a,arg[1],arg[2],arg[3]",a,arg[1],arg[2],arg[3]) - print("a",a) - print("...",...) - print("...,a",...,a) - print("a,...",a,...) - end - function u(arg) - print( 'arg', arg ) - end - function v(arg,...) - print( 'arg', arg ) - print("...",...) - print("arg,...",arg,...) - end - arg = { "global-1", "global-2", "global-3" } - function tryall(f,name) - print( '---- function '..name..'()' ) - print( '--'..name..'():' ) - print( ' ->', pcall( f ) ) - print( '--'..name..'("q"):' ) - print( ' ->', pcall( f, "q" ) ) - print( '--'..name..'("q","r"):' ) - print( ' ->', pcall( f, "q", "r" ) ) - print( '--'..name..'("q","r","s"):' ) - print( ' ->', pcall( f, "q", "r", "s" ) ) - end - tryall(p,'p') - tryall(q,'q') - tryall(r,'r') - tryall(s,'s') - tryall(t,'t') - tryall(u,'u') - tryall(v,'v') -end -print( 'varargstest result:', pcall( varargstest ) ) - --- The purpose of this test case is to demonstrate that --- basic metatable operations on non-table types work. --- i.e. that s.sub(s,...) could be used in place of string.sub(s,...) -print( '---------- metatable tests' ) -local function metatabletests() - - -- tostring replacement that assigns ids - local ts,id,nid,types = tostring,{},0,{table='tbl',thread='thr',userdata='uda',['function']='func'} - tostring = function(x) - if not x or not types[type(x)] then return ts(x) end - if not id[x] then nid=nid+1; id[x]=types[type(x)]..'.'..nid end - return id[x] - end - local results = function(s,e,...) - if s then return e,... end - return false,type(e) - end - local pcall = function(...) - return results( pcall(...) ) - end - - - local s = "hello" - print(s:sub(2,4)) - - local t = {} - function op(name,...) - local a,b = pcall( setmetatable, t, ... ) - print( name, t, getmetatable(t), a, b ) - end - op('set{} ',{}) - op('set-nil',nil) - op('set{} ',{}) - op('set') - op('set{} ',{}) - op('set{} ',{}) - op('set{}{}',{},{}) - op('set-nil',nil) - op('set{__}',{__metatable={}}) - op('set{} ',{}) - op('set-nil',nil) - t = {} - op('set{} ',{}) - op('set-nil',nil) - op('set{__}',{__metatable='abc'}) - op('set{} ',{}) - op('set-nil',nil) - - - local i = 1234 - local t = setmetatable( {}, { - __mode="v", - __index=function(t,k) - local v = i - i = i + 1 - rawset(t,k,v) - return v - end, - } ) - - local l = { 'a', 'b', 'a', 'b', 'c', 'a', 'b', 'c', 'd' } - for i,key in ipairs(l) do - print( 't.'..key, t[key] ) - end -end -print( 'metatabletests result:', pcall( metatabletests ) ) - --- test tables with more than 50 elements -print( '------------ huge tables' ) -local function hugetables() - local t = { 1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1, - } - print ("#t=",#t,'t[1,50,51,59]', t[1], t[50], t[51], t[59]) - print (table.concat(t,',')) - - local t2= { 0,3,4,7,9,8,12,15,23,5, - 10,13,14,17,19,18,112,115,123,15, - 20,33,24,27,29,28,212,215,223,25, - 40,43,44,47,49,48,412,415,423,45, - 50,53,54,57,59,58,512,515,523,55, - 60,63,64,67,69,68,612,615,623,65, - 70,73,74,77,79,78,72,715,723,75, - } - - print ("#t2=",#t2,'t[1,50,51,59]', t[1], t[50], t[51], t[59]) - print (table.concat(t2,',')) - - local t = { - [2000]='a', [2001]='b', [2002]='c', [2003]='d', [2004]='e', [2005]='f', [2006]='g', [2007]='h', [2008]='i', [2009]='j', - [3000]='a', [3001]='b', [3002]='c', [3003]='d', [3004]='e', [3005]='f', [3006]='g', [3007]='h', [3008]='i', [3009]='j', - [4000]='a', [4001]='b', [4002]='c', [4003]='d', [4004]='e', [4005]='f', [4006]='g', [4007]='h', [4008]='i', [4009]='j', - [5000]='a', [5001]='b', [5002]='c', [5003]='d', [5004]='e', [5005]='f', [5006]='g', [5007]='h', [5008]='i', [5009]='j', - [6000]='a', [6001]='b', [6002]='c', [6003]='d', [6004]='e', [6005]='f', [6006]='g', [6007]='h', [6008]='i', [6009]='j', - [7000]='a', [7001]='b', [7002]='c', [7003]='d', [7004]='e', [7005]='f', [7006]='g', [7007]='h', [7008]='i', [7009]='j', - [8000]='a', [8001]='b', [8002]='c', [8003]='d', [8004]='e', [8005]='f', [8006]='g', [8007]='h', [8008]='i', [8009]='j', - } - - for i=2000,8000,1000 do - for j=0,9,1 do - print( 't['..tostring(i+j)..']', t[i+j] ) - end - end -end -print( 'hugetables result:', pcall( hugetables ) ) - -print( '--------- many locals' ) -local function manylocals() - -- test program with more than 50 non-sequential integer elements - local t0000='a'; local t0001='b'; local t0002='c'; local t0003='d'; local t0004='e'; local t0005='f'; local t0006='g'; local t0007='h'; local t0008='i'; local t0009='j'; - local t1000='a'; local t1001='b'; local t1002='c'; local t1003='d'; local t1004='e'; local t1005='f'; local t1006='g'; local t1007='h'; local t1008='i'; local t1009='j'; - local t2000='a'; local t2001='b'; local t2002='c'; local t2003='d'; local t2004='e'; local t2005='f'; local t2006='g'; local t2007='h'; local t2008='i'; local t2009='j'; - local t3000='a'; local t3001='b'; local t3002='c'; local t3003='d'; local t3004='e'; local t3005='f'; local t3006='g'; local t3007='h'; local t3008='i'; local t3009='j'; - local t4000='a'; local t4001='b'; local t4002='c'; local t4003='d'; local t4004='e'; local t4005='f'; local t4006='g'; local t4007='h'; local t4008='i'; local t4009='j'; - local t5000='a'; local t5001='b'; local t5002='c'; local t5003='d'; local t5004='e'; local t5005='f'; local t5006='g'; local t5007='h'; local t5008='i'; local t5009='j'; - local t6000='a'; local t6001='b'; local t6002='c'; local t6003='d'; local t6004='e'; local t6005='f'; local t6006='g'; local t6007='h'; local t6008='i'; local t6009='j'; - local t7000='a'; local t7001='b'; local t7002='c'; local t7003='d'; local t7004='e'; local t7005='f'; local t7006='g'; local t7007='h'; local t7008='i'; local t7009='j'; - local t8000='a'; local t8001='b'; local t8002='c'; local t8003='d'; local t8004='e'; local t8005='f'; local t8006='g'; local t8007='h'; local t8008='i'; local t8009='j'; - local t9000='a'; local t9001='b'; local t9002='c'; local t9003='d'; local t9004='e'; local t9005='f'; local t9006='g'; local t9007='h'; local t9008='i'; local t9009='j'; - local t10000='a'; local t10001='b'; local t10002='c'; local t10003='d'; local t10004='e'; local t10005='f'; local t10006='g'; local t10007='h'; local t10008='i'; local t10009='j'; - local t11000='a'; local t11001='b'; local t11002='c'; local t11003='d'; local t11004='e'; local t11005='f'; local t11006='g'; local t11007='h'; local t11008='i'; local t11009='j'; - local t12000='a'; local t12001='b'; local t12002='c'; local t12003='d'; local t12004='e'; local t12005='f'; local t12006='g'; local t12007='h'; local t12008='i'; local t12009='j'; - local t13000='a'; local t13001='b'; local t13002='c'; local t13003='d'; local t13004='e'; local t13005='f'; local t13006='g'; local t13007='h'; local t13008='i'; local t13009='j'; - - -- print the variables - print(t0000,'a'); print(t0001,'b'); print(t0002,'c'); print(t0003,'d'); print(t0004,'e'); print(t0005,'f'); print(t0006,'g'); print(t0007,'h'); print(t0008,'i'); print(t0009,'j'); - print(t1000,'a'); print(t1001,'b'); print(t1002,'c'); print(t1003,'d'); print(t1004,'e'); print(t1005,'f'); print(t1006,'g'); print(t1007,'h'); print(t1008,'i'); print(t1009,'j'); - print(t2000,'a'); print(t2001,'b'); print(t2002,'c'); print(t2003,'d'); print(t2004,'e'); print(t2005,'f'); print(t2006,'g'); print(t2007,'h'); print(t2008,'i'); print(t2009,'j'); - print(t3000,'a'); print(t3001,'b'); print(t3002,'c'); print(t3003,'d'); print(t3004,'e'); print(t3005,'f'); print(t3006,'g'); print(t3007,'h'); print(t3008,'i'); print(t3009,'j'); - print(t4000,'a'); print(t4001,'b'); print(t4002,'c'); print(t4003,'d'); print(t4004,'e'); print(t4005,'f'); print(t4006,'g'); print(t4007,'h'); print(t4008,'i'); print(t4009,'j'); - print(t5000,'a'); print(t5001,'b'); print(t5002,'c'); print(t5003,'d'); print(t5004,'e'); print(t5005,'f'); print(t5006,'g'); print(t5007,'h'); print(t5008,'i'); print(t5009,'j'); - print(t6000,'a'); print(t6001,'b'); print(t6002,'c'); print(t6003,'d'); print(t6004,'e'); print(t6005,'f'); print(t6006,'g'); print(t6007,'h'); print(t6008,'i'); print(t6009,'j'); - print(t7000,'a'); print(t7001,'b'); print(t7002,'c'); print(t7003,'d'); print(t7004,'e'); print(t7005,'f'); print(t7006,'g'); print(t7007,'h'); print(t7008,'i'); print(t7009,'j'); - print(t8000,'a'); print(t8001,'b'); print(t8002,'c'); print(t8003,'d'); print(t8004,'e'); print(t8005,'f'); print(t8006,'g'); print(t8007,'h'); print(t8008,'i'); print(t8009,'j'); - print(t9000,'a'); print(t9001,'b'); print(t9002,'c'); print(t9003,'d'); print(t9004,'e'); print(t9005,'f'); print(t9006,'g'); print(t9007,'h'); print(t9008,'i'); print(t9009,'j'); - print(t10000,'a'); print(t10001,'b'); print(t10002,'c'); print(t10003,'d'); print(t10004,'e'); print(t10005,'f'); print(t10006,'g'); print(t10007,'h'); print(t10008,'i'); print(t10009,'j'); - print(t11000,'a'); print(t11001,'b'); print(t11002,'c'); print(t11003,'d'); print(t11004,'e'); print(t11005,'f'); print(t11006,'g'); print(t11007,'h'); print(t11008,'i'); print(t11009,'j'); - print(t12000,'a'); print(t12001,'b'); print(t12002,'c'); print(t12003,'d'); print(t12004,'e'); print(t12005,'f'); print(t12006,'g'); print(t12007,'h'); print(t12008,'i'); print(t12009,'j'); - print(t13000,'a'); print(t13001,'b'); print(t13002,'c'); print(t13003,'d'); print(t13004,'e'); print(t13005,'f'); print(t13006,'g'); print(t13007,'h'); print(t13008,'i'); print(t13009,'j'); -end -print( 'manylocals result:', pcall( manylocals ) ) diff --git a/version.properties b/version.properties deleted file mode 100644 index fa48e2d2..00000000 --- a/version.properties +++ /dev/null @@ -1 +0,0 @@ -version: 3.0.2 \ No newline at end of file diff --git a/wtk.xml b/wtk.xml deleted file mode 100644 index afeaef79..00000000 --- a/wtk.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - WTK_HOME from env ${env.WTK_HOME} - - - - - - - - - - - - - - Using WTK found in ${wtk.home} - - - - - - -