From d1debdf2ec7365380d57bbeff17ef29911c2002b Mon Sep 17 00:00:00 2001 From: James Roseborough Date: Tue, 27 Oct 2009 06:20:40 +0000 Subject: [PATCH] Remove obsolete v 1.0 source files (still available in 1.0 branch). --- build.xml | 4 +- src/core/org/luaj/compiler/DumpState.java | 269 -- src/core/org/luaj/compiler/FuncState.java | 1076 ------- .../org/luaj/compiler/InstructionPtr.java | 37 - src/core/org/luaj/compiler/IntPtr.java | 31 - src/core/org/luaj/compiler/LexState.java | 1904 ------------ src/core/org/luaj/compiler/LuaC.java | 223 -- src/core/org/luaj/lib/BaseLib.java | 504 ---- src/core/org/luaj/lib/CoroutineLib.java | 141 - src/core/org/luaj/lib/DebugLib.java | 824 ------ src/core/org/luaj/lib/IoLib.java | 513 ---- src/core/org/luaj/lib/LBuffer.java | 78 - src/core/org/luaj/lib/MathLib.java | 227 -- src/core/org/luaj/lib/OsLib.java | 344 --- src/core/org/luaj/lib/PackageLib.java | 416 --- src/core/org/luaj/lib/StringLib.java | 1212 -------- src/core/org/luaj/lib/TableLib.java | 210 -- src/core/org/luaj/vm/CallInfo.java | 91 - src/core/org/luaj/vm/DebugNetSupport.java | 22 - src/core/org/luaj/vm/LBoolean.java | 64 - src/core/org/luaj/vm/LClosure.java | 67 - src/core/org/luaj/vm/LDouble.java | 150 - src/core/org/luaj/vm/LFunction.java | 96 - src/core/org/luaj/vm/LInteger.java | 136 - src/core/org/luaj/vm/LNil.java | 80 - src/core/org/luaj/vm/LNumber.java | 104 - src/core/org/luaj/vm/LPrototype.java | 77 - src/core/org/luaj/vm/LString.java | 474 --- src/core/org/luaj/vm/LTable.java | 683 ----- src/core/org/luaj/vm/LThread.java | 182 -- src/core/org/luaj/vm/LUserData.java | 73 - src/core/org/luaj/vm/LValue.java | 363 --- src/core/org/luaj/vm/LWeakTable.java | 112 - src/core/org/luaj/vm/LoadState.java | 298 -- src/core/org/luaj/vm/LocVars.java | 36 - src/core/org/luaj/vm/Lua.java | 360 --- src/core/org/luaj/vm/LuaErrorException.java | 91 - src/core/org/luaj/vm/LuaState.java | 2553 ----------------- src/core/org/luaj/vm/Platform.java | 186 -- src/core/org/luaj/vm/Print.java | 357 --- src/core/org/luaj/vm/UpVal.java | 67 - src/j2me/org/luaj/lib/j2me/Cldc10IoLib.java | 211 -- .../platform/J2meMidp10Cldc10Platform.java | 53 - .../platform/J2meMidp20Cldc11Platform.java | 84 - src/j2se/lua.java | 211 -- src/j2se/luac.java | 185 -- src/j2se/luajapplet.java | 152 - .../org/luaj/lib/j2se/CoerceJavaToLua.java | 93 - .../org/luaj/lib/j2se/CoerceLuaToJava.java | 283 -- src/j2se/org/luaj/lib/j2se/J2seIoLib.java | 203 -- src/j2se/org/luaj/lib/j2se/J2seOsLib.java | 92 - src/j2se/org/luaj/lib/j2se/LuajavaLib.java | 463 --- src/j2se/org/luaj/platform/J2sePlatform.java | 88 - src/sample/org/luaj/sample/LuaJitRunner.java | 89 - src/sample/org/luaj/sample/LuaRunner.java | 87 - src/sample/org/luaj/sample/LuajavaRunner.java | 67 - src/sample/org/luaj/sample/SampleClass.java | 53 - .../org/luaj/sample/SampleJ2seMain.java | 18 - src/sample/org/luaj/sample/SampleMIDlet.java | 42 - .../org/luaj/sample/SampleUserdataMain.java | 69 - .../services/javax.script.ScriptEngineFactory | 1 - src/script/org/luaj/jit/JitPrototype.java | 45 - src/script/org/luaj/jit/LuaJit.java | 718 ----- .../org/luaj/script/LuaScriptEngine.java | 317 -- .../luaj/script/LuaScriptEngineFactory.java | 127 - .../org/luaj/script/ScriptEngineSample.java | 67 - .../java/org/luaj/jit/LuaJitBasicTest.java | 154 - .../java/org/luaj/jit/LuaJitPerfTest.java | 92 - src/test/java/org/luaj/jit/LuaJitTest.java | 21 - src/test/res/autoload.lua | 15 - src/test/res/baselib.lua | 280 -- src/test/res/boolean.lua | 31 - src/test/res/calls.lua | 28 - src/test/res/coercions.lua | 5 - src/test/res/compare.lua | 12 - src/test/res/compile.sh | 8 - src/test/res/coroutines.lua | 97 - src/test/res/debuglib.lua | 227 -- src/test/res/errors.lua | 121 - src/test/res/hugetable.lua | 43 - src/test/res/ids.lua | 36 - src/test/res/iolib.lua | 115 - src/test/res/loops.lua | 22 - src/test/res/manylocals.lua | 31 - src/test/res/math.lua | 7 - src/test/res/mathlib.lua | 87 - src/test/res/metatables.lua | 48 - src/test/res/module.lua | 90 - src/test/res/next.lua | 37 - src/test/res/oslib.lua | 36 - src/test/res/pcalls.lua | 75 - src/test/res/print.lua | 26 - src/test/res/req/subsample.lua | 16 - src/test/res/require.lua | 101 - src/test/res/sample.lua | 7 - src/test/res/select.lua | 31 - src/test/res/setfenv.lua | 61 - src/test/res/setlist.lua | 27 - src/test/res/simplemetatables.lua | 14 - src/test/res/sort.lua | 27 - src/test/res/stack.lua | 46 - src/test/res/standard-tests.zip | Bin 161045 -> 0 bytes src/test/res/strlib.lua | 169 -- src/test/res/swingapp.lua | 29 - src/test/res/table.lua | 224 -- src/test/res/tailcall.lua | 62 - src/test/res/test1.lua | 86 - src/test/res/test2.lua | 80 - src/test/res/test3.lua | 62 - src/test/res/test4.lua | 8 - src/test/res/test5.lua | 20 - src/test/res/test6.lua | 99 - src/test/res/test7-expected.out | 7 - src/test/res/test7.lua | 21 - src/test/res/test8.lua | 12 - src/test/res/test9.lua | 15 - src/test/res/testfloat.lua | 5 - src/test/res/type.lua | 8 - src/test/res/upvalues.lua | 25 - src/test/res/upvalues2.lua | 42 - src/test/res/upvalues3.lua | 14 - src/test/res/varargs.lua | 51 - src/test/res/weaktable.lua | 150 - 123 files changed, 3 insertions(+), 21813 deletions(-) delete mode 100644 src/core/org/luaj/compiler/DumpState.java delete mode 100644 src/core/org/luaj/compiler/FuncState.java delete mode 100644 src/core/org/luaj/compiler/InstructionPtr.java delete mode 100644 src/core/org/luaj/compiler/IntPtr.java delete mode 100644 src/core/org/luaj/compiler/LexState.java delete mode 100644 src/core/org/luaj/compiler/LuaC.java delete mode 100644 src/core/org/luaj/lib/BaseLib.java delete mode 100644 src/core/org/luaj/lib/CoroutineLib.java delete mode 100644 src/core/org/luaj/lib/DebugLib.java delete mode 100644 src/core/org/luaj/lib/IoLib.java delete mode 100644 src/core/org/luaj/lib/LBuffer.java delete mode 100644 src/core/org/luaj/lib/MathLib.java delete mode 100644 src/core/org/luaj/lib/OsLib.java delete mode 100644 src/core/org/luaj/lib/PackageLib.java delete mode 100644 src/core/org/luaj/lib/StringLib.java delete mode 100644 src/core/org/luaj/lib/TableLib.java delete mode 100644 src/core/org/luaj/vm/CallInfo.java delete mode 100644 src/core/org/luaj/vm/DebugNetSupport.java delete mode 100644 src/core/org/luaj/vm/LBoolean.java delete mode 100644 src/core/org/luaj/vm/LClosure.java delete mode 100644 src/core/org/luaj/vm/LDouble.java delete mode 100644 src/core/org/luaj/vm/LFunction.java delete mode 100644 src/core/org/luaj/vm/LInteger.java delete mode 100644 src/core/org/luaj/vm/LNil.java delete mode 100644 src/core/org/luaj/vm/LNumber.java delete mode 100644 src/core/org/luaj/vm/LPrototype.java delete mode 100644 src/core/org/luaj/vm/LString.java delete mode 100644 src/core/org/luaj/vm/LTable.java delete mode 100644 src/core/org/luaj/vm/LThread.java delete mode 100644 src/core/org/luaj/vm/LUserData.java delete mode 100644 src/core/org/luaj/vm/LValue.java delete mode 100644 src/core/org/luaj/vm/LWeakTable.java delete mode 100644 src/core/org/luaj/vm/LoadState.java delete mode 100644 src/core/org/luaj/vm/LocVars.java delete mode 100644 src/core/org/luaj/vm/Lua.java delete mode 100644 src/core/org/luaj/vm/LuaErrorException.java delete mode 100644 src/core/org/luaj/vm/LuaState.java delete mode 100644 src/core/org/luaj/vm/Platform.java delete mode 100644 src/core/org/luaj/vm/Print.java delete mode 100644 src/core/org/luaj/vm/UpVal.java delete mode 100644 src/j2me/org/luaj/lib/j2me/Cldc10IoLib.java delete mode 100644 src/j2me/org/luaj/platform/J2meMidp10Cldc10Platform.java delete mode 100644 src/j2me/org/luaj/platform/J2meMidp20Cldc11Platform.java delete mode 100644 src/j2se/lua.java delete mode 100644 src/j2se/luac.java delete mode 100644 src/j2se/luajapplet.java delete mode 100644 src/j2se/org/luaj/lib/j2se/CoerceJavaToLua.java delete mode 100644 src/j2se/org/luaj/lib/j2se/CoerceLuaToJava.java delete mode 100644 src/j2se/org/luaj/lib/j2se/J2seIoLib.java delete mode 100644 src/j2se/org/luaj/lib/j2se/J2seOsLib.java delete mode 100644 src/j2se/org/luaj/lib/j2se/LuajavaLib.java delete mode 100644 src/j2se/org/luaj/platform/J2sePlatform.java delete mode 100644 src/sample/org/luaj/sample/LuaJitRunner.java delete mode 100644 src/sample/org/luaj/sample/LuaRunner.java delete mode 100644 src/sample/org/luaj/sample/LuajavaRunner.java delete mode 100644 src/sample/org/luaj/sample/SampleClass.java delete mode 100644 src/sample/org/luaj/sample/SampleJ2seMain.java delete mode 100644 src/sample/org/luaj/sample/SampleMIDlet.java delete mode 100644 src/sample/org/luaj/sample/SampleUserdataMain.java delete mode 100644 src/script/META-INF/services/javax.script.ScriptEngineFactory delete mode 100644 src/script/org/luaj/jit/JitPrototype.java delete mode 100644 src/script/org/luaj/jit/LuaJit.java delete mode 100644 src/script/org/luaj/script/LuaScriptEngine.java delete mode 100644 src/script/org/luaj/script/LuaScriptEngineFactory.java delete mode 100644 src/script/org/luaj/script/ScriptEngineSample.java delete mode 100644 src/test/java/org/luaj/jit/LuaJitBasicTest.java delete mode 100644 src/test/java/org/luaj/jit/LuaJitPerfTest.java delete mode 100644 src/test/java/org/luaj/jit/LuaJitTest.java delete mode 100644 src/test/res/autoload.lua delete mode 100644 src/test/res/baselib.lua delete mode 100644 src/test/res/boolean.lua delete mode 100644 src/test/res/calls.lua delete mode 100644 src/test/res/coercions.lua delete mode 100644 src/test/res/compare.lua delete mode 100644 src/test/res/compile.sh delete mode 100644 src/test/res/coroutines.lua delete mode 100644 src/test/res/debuglib.lua delete mode 100644 src/test/res/errors.lua delete mode 100644 src/test/res/hugetable.lua delete mode 100644 src/test/res/ids.lua delete mode 100644 src/test/res/iolib.lua delete mode 100644 src/test/res/loops.lua delete mode 100644 src/test/res/manylocals.lua delete mode 100644 src/test/res/math.lua delete mode 100644 src/test/res/mathlib.lua delete mode 100644 src/test/res/metatables.lua delete mode 100644 src/test/res/module.lua delete mode 100644 src/test/res/next.lua delete mode 100644 src/test/res/oslib.lua delete mode 100644 src/test/res/pcalls.lua delete mode 100644 src/test/res/print.lua delete mode 100644 src/test/res/req/subsample.lua delete mode 100644 src/test/res/require.lua delete mode 100644 src/test/res/sample.lua delete mode 100644 src/test/res/select.lua delete mode 100644 src/test/res/setfenv.lua delete mode 100644 src/test/res/setlist.lua delete mode 100644 src/test/res/simplemetatables.lua delete mode 100644 src/test/res/sort.lua delete mode 100644 src/test/res/stack.lua delete mode 100644 src/test/res/standard-tests.zip delete mode 100644 src/test/res/strlib.lua delete mode 100644 src/test/res/swingapp.lua delete mode 100644 src/test/res/table.lua delete mode 100644 src/test/res/tailcall.lua delete mode 100644 src/test/res/test1.lua delete mode 100644 src/test/res/test2.lua delete mode 100644 src/test/res/test3.lua delete mode 100644 src/test/res/test4.lua delete mode 100644 src/test/res/test5.lua delete mode 100644 src/test/res/test6.lua delete mode 100644 src/test/res/test7-expected.out delete mode 100644 src/test/res/test7.lua delete mode 100644 src/test/res/test8.lua delete mode 100644 src/test/res/test9.lua delete mode 100644 src/test/res/testfloat.lua delete mode 100644 src/test/res/type.lua delete mode 100644 src/test/res/upvalues.lua delete mode 100644 src/test/res/upvalues2.lua delete mode 100644 src/test/res/upvalues3.lua delete mode 100644 src/test/res/varargs.lua delete mode 100644 src/test/res/weaktable.lua diff --git a/build.xml b/build.xml index 4ee9fccd..29caece5 100644 --- a/build.xml +++ b/build.xml @@ -105,7 +105,9 @@ - + + + diff --git a/src/core/org/luaj/compiler/DumpState.java b/src/core/org/luaj/compiler/DumpState.java deleted file mode 100644 index a9ddd59e..00000000 --- a/src/core/org/luaj/compiler/DumpState.java +++ /dev/null @@ -1,269 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.compiler; - -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -import org.luaj.vm.LNumber; -import org.luaj.vm.LPrototype; -import org.luaj.vm.LString; -import org.luaj.vm.LValue; -import org.luaj.vm.LocVars; -import org.luaj.vm.Lua; - - -public class DumpState { - - /** mark for precompiled code (`Lua') */ - public static final String LUA_SIGNATURE = "\033Lua"; - - /** for header of binary files -- this is Lua 5.1 */ - public static final int LUAC_VERSION = 0x51; - - /** for header of binary files -- this is the official format */ - public static final int LUAC_FORMAT = 0; - - /** size of header of binary files */ - public static final int LUAC_HEADERSIZE = 12; - - /** expected lua header bytes */ - private static final byte[] LUAC_HEADER_SIGNATURE = { '\033', 'L', 'u', 'a' }; - - /** set true to allow integer compilation */ - public static boolean ALLOW_INTEGER_CASTING = false; - - /** format corresponding to non-number-patched lua, all numbers are floats or doubles */ - public static final int NUMBER_FORMAT_FLOATS_OR_DOUBLES = 0; - - /** format corresponding to non-number-patched lua, all numbers are ints */ - public static final int NUMBER_FORMAT_INTS_ONLY = 1; - - /** format corresponding to number-patched lua, all numbers are 32-bit (4 byte) ints */ - public static final int NUMBER_FORMAT_NUM_PATCH_INT32 = 4; - - /** default number format */ - public static final int NUMBER_FORMAT_DEFAULT = NUMBER_FORMAT_FLOATS_OR_DOUBLES; - - // header fields - private boolean IS_LITTLE_ENDIAN = false; - private int NUMBER_FORMAT = NUMBER_FORMAT_DEFAULT; - private int SIZEOF_LUA_NUMBER = 8; - private static final int SIZEOF_INT = 4; - private static final int SIZEOF_SIZET = 4; - private static final int SIZEOF_INSTRUCTION = 4; - - DataOutputStream writer; - boolean strip; - int status; - - public DumpState(OutputStream w, boolean strip) { - this.writer = new DataOutputStream( w ); - this.strip = strip; - this.status = 0; - } - - void dumpBlock(final byte[] b, int size) throws IOException { - writer.write(b, 0, size); - } - - void dumpChar(int b) throws IOException { - writer.write( b ); - } - - void dumpInt(int x) throws IOException { - if ( IS_LITTLE_ENDIAN ) { - writer.writeByte(x&0xff); - writer.writeByte((x>>8)&0xff); - writer.writeByte((x>>16)&0xff); - writer.writeByte((x>>24)&0xff); - } else { - writer.writeInt(x); - } - } - - void dumpString(LString s) throws IOException { - final int len = s.length(); - dumpInt( len+1 ); - s.write( writer, 0, len ); - writer.write( 0 ); - } - - void dumpDouble(double d) throws IOException { - long l = Double.doubleToLongBits(d); - if ( IS_LITTLE_ENDIAN ) { - dumpInt( (int) l ); - dumpInt( (int) (l>>32) ); - } else { - writer.writeLong(l); - } - } - - void dumpCode( final LPrototype f ) throws IOException { - final int[] code = f.code; - int n = code.length; - dumpInt( n ); - for ( int i=0; i l ) - errorlimit( l, msg ); - } - - void errorlimit (int limit, String what) { - String msg = (f.linedefined == 0) ? - L.pushfstring("main function has more than "+limit+" "+what) : - L.pushfstring("function at line "+f.linedefined+" has more than "+limit+" "+what); - ls.lexerror(msg, 0); - } - - - int indexupvalue(LString name, expdesc v) { - int i; - for (i = 0; i < f.nups; i++) { - if (upvalues[i].k == v.k && upvalues[i].info == v.u.s.info) { - _assert(f.upvalues[i] == name); - return i; - } - } - /* new one */ - checklimit(f.nups + 1, LUAI_MAXUPVALUES, "upvalues"); - if ( f.upvalues == null || f.nups + 1 > f.upvalues.length) - f.upvalues = realloc( f.upvalues, f.nups*2+1 ); - f.upvalues[f.nups] = name; - _assert (v.k == LexState.VLOCAL || v.k == LexState.VUPVAL); - upvalues[f.nups] = new upvaldesc(); - upvalues[f.nups].k = (byte) (v.k); - upvalues[f.nups].info = (byte) (v.u.s.info); - return f.nups++; - } - - int searchvar(LString n) { - int i; - for (i = nactvar - 1; i >= 0; i--) { - if (n == getlocvar(i).varname) - return i; - } - return -1; /* not found */ - } - - void markupval(int level) { - BlockCnt bl = this.bl; - while (bl != null && bl.nactvar > level) - bl = bl.previous; - if (bl != null) - bl.upval = true; - } - - int singlevaraux(LString n, expdesc var, int base) { - int v = searchvar(n); /* look up at current level */ - if (v >= 0) { - var.init(LexState.VLOCAL, v); - if (base == 0) - markupval(v); /* local will be used as an upval */ - return LexState.VLOCAL; - } else { /* not found at current level; try upper one */ - if (prev == null) { /* no more levels? */ - /* default is global variable */ - var.init(LexState.VGLOBAL, NO_REG); - return LexState.VGLOBAL; - } - if (prev.singlevaraux(n, var, 0) == LexState.VGLOBAL) - return LexState.VGLOBAL; - var.u.s.info = indexupvalue(n, var); /* else was LOCAL or UPVAL */ - var.k = LexState.VUPVAL; /* upvalue in this level */ - return LexState.VUPVAL; - } - } - - void enterblock (BlockCnt bl, boolean isbreakable) { - bl.breaklist.i = LexState.NO_JUMP; - bl.isbreakable = isbreakable; - bl.nactvar = this.nactvar; - bl.upval = false; - bl.previous = this.bl; - this.bl = bl; - _assert(this.freereg == this.nactvar); - } - - // -// void leaveblock (FuncState *fs) { -// BlockCnt *bl = this.bl; -// this.bl = bl.previous; -// removevars(this.ls, bl.nactvar); -// if (bl.upval) -// this.codeABC(OP_CLOSE, bl.nactvar, 0, 0); -// /* a block either controls scope or breaks (never both) */ -// assert(!bl.isbreakable || !bl.upval); -// assert(bl.nactvar == this.nactvar); -// this.freereg = this.nactvar; /* free registers */ -// this.patchtohere(bl.breaklist); -// } - - void leaveblock() { - BlockCnt bl = this.bl; - this.bl = bl.previous; - ls.removevars(bl.nactvar); - if (bl.upval) - this.codeABC(OP_CLOSE, bl.nactvar, 0, 0); - /* a block either controls scope or breaks (never both) */ - _assert (!bl.isbreakable || !bl.upval); - _assert (bl.nactvar == this.nactvar); - this.freereg = this.nactvar; /* free registers */ - this.patchtohere(bl.breaklist.i); - } - - void closelistfield(ConsControl cc) { - if (cc.v.k == LexState.VVOID) - return; /* there is no list item */ - this.exp2nextreg(cc.v); - cc.v.k = LexState.VVOID; - if (cc.tostore == LFIELDS_PER_FLUSH) { - this.setlist(cc.t.u.s.info, cc.na, cc.tostore); /* flush */ - cc.tostore = 0; /* no more items pending */ - } - } - - boolean hasmultret(int k) { - return ((k) == LexState.VCALL || (k) == LexState.VVARARG); - } - - void lastlistfield (ConsControl cc) { - if (cc.tostore == 0) return; - if (hasmultret(cc.v.k)) { - this.setmultret(cc.v); - this.setlist(cc.t.u.s.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.s.info, cc.na, cc.tostore); - } - } - - - - // ============================================================= - // from lcode.c - // ============================================================= - - void nil(int from, int n) { - InstructionPtr previous; - if (this.pc > this.lasttarget) { /* no jumps to current position? */ - if (this.pc == 0) { /* function start? */ - if (from >= this.nactvar) - return; /* positions are already clean */ - } else { - previous = new InstructionPtr(this.f.code, this.pc - 1); - if (GET_OPCODE(previous.get()) == OP_LOADNIL) { - int pfrom = GETARG_A(previous.get()); - int pto = GETARG_B(previous.get()); - if (pfrom <= from && from <= pto + 1) { /* can connect both? */ - if (from + n - 1 > pto) - SETARG_B(previous, from + n - 1); - return; - } - } - } - } - /* else no optimization */ - this.codeABC(OP_LOADNIL, from, from + n - 1, 0); - } - - - int jump() { - int jpc = this.jpc.i; /* save list of jumps to here */ - this.jpc.i = LexState.NO_JUMP; - IntPtr j = new IntPtr(this.codeAsBx(OP_JMP, 0, LexState.NO_JUMP)); - this.concat(j, jpc); /* keep them on hold */ - return j.i; - } - - void ret(int first, int nret) { - this.codeABC(OP_RETURN, first, nret + 1, 0); - } - - int condjump(int /* OpCode */op, int A, int B, int C) { - this.codeABC(op, A, B, C); - return this.jump(); - } - - void fixjump(int pc, int dest) { - InstructionPtr jmp = new InstructionPtr(this.f.code, pc); - int offset = dest - (pc + 1); - _assert (dest != LexState.NO_JUMP); - if (Math.abs(offset) > MAXARG_sBx) - ls.syntaxerror("control structure too long"); - SETARG_sBx(jmp, offset); - } - - - /* - * * returns current `pc' and marks it as a jump target (to avoid wrong * - * optimizations with consecutive instructions not in the same basic block). - */ - int getlabel() { - this.lasttarget = this.pc; - return this.pc; - } - - - int getjump(int pc) { - int offset = GETARG_sBx(this.f.code[pc]); - /* point to itself represents end of list */ - if (offset == LexState.NO_JUMP) - /* end of list */ - return LexState.NO_JUMP; - else - /* turn offset into absolute position */ - return (pc + 1) + offset; - } - - - InstructionPtr getjumpcontrol(int pc) { - InstructionPtr pi = new InstructionPtr(this.f.code, pc); - if (pc >= 1 && testTMode(GET_OPCODE(pi.code[pi.idx - 1]))) - return new InstructionPtr(pi.code, pi.idx - 1); - else - return pi; - } - - - /* - * * check whether list has any jump that do not produce a value * (or - * produce an inverted value) - */ - boolean need_value(int list) { - for (; list != LexState.NO_JUMP; list = this.getjump(list)) { - int i = this.getjumpcontrol(list).get(); - if (GET_OPCODE(i) != OP_TESTSET) - return true; - } - return false; /* not found */ - } - - - boolean patchtestreg(int node, int reg) { - InstructionPtr i = this.getjumpcontrol(node); - if (GET_OPCODE(i.get()) != OP_TESTSET) - /* cannot patch other instructions */ - return false; - if (reg != NO_REG && reg != GETARG_B(i.get())) - SETARG_A(i, reg); - else - /* no register to put value or register already has the value */ - i.set(CREATE_ABC(OP_TEST, GETARG_B(i.get()), 0, Lua.GETARG_C(i.get()))); - - return true; - } - - - void removevalues(int list) { - for (; list != LexState.NO_JUMP; list = this.getjump(list)) - this.patchtestreg(list, NO_REG); - } - - void patchlistaux(int list, int vtarget, int reg, int dtarget) { - while (list != LexState.NO_JUMP) { - int next = this.getjump(list); - if (this.patchtestreg(list, reg)) - this.fixjump(list, vtarget); - else - this.fixjump(list, dtarget); /* jump to default target */ - list = next; - } - } - - void dischargejpc() { - this.patchlistaux(this.jpc.i, this.pc, NO_REG, this.pc); - this.jpc.i = LexState.NO_JUMP; - } - - void patchlist(int list, int target) { - if (target == this.pc) - this.patchtohere(list); - else { - _assert (target < this.pc); - this.patchlistaux(list, target, NO_REG, target); - } - } - - void patchtohere(int list) { - this.getlabel(); - this.concat(this.jpc, list); - } - - void concat(IntPtr l1, int l2) { - if (l2 == LexState.NO_JUMP) - return; - if (l1.i == LexState.NO_JUMP) - l1.i = l2; - else { - int list = l1.i; - int next; - while ((next = this.getjump(list)) != LexState.NO_JUMP) - /* find last element */ - list = next; - this.fixjump(list, l2); - } - } - - void checkstack(int n) { - int newstack = this.freereg + n; - if (newstack > this.f.maxstacksize) { - if (newstack >= MAXSTACK) - ls.syntaxerror("function or expression too complex"); - this.f.maxstacksize = newstack; - } - } - - void reserveregs(int n) { - this.checkstack(n); - this.freereg += n; - } - - void freereg(int reg) { - if (!ISK(reg) && reg >= this.nactvar) { - this.freereg--; - _assert (reg == this.freereg); - } - } - - void freeexp(expdesc e) { - if (e.k == LexState.VNONRELOC) - this.freereg(e.u.s.info); - } - - int addk(LValue v) { - int idx; - if (this.htable.containsKey(v)) { - idx = ((Integer) htable.get(v)).intValue(); - } else { - idx = this.nk; - this.htable.put(v, new Integer(idx)); - final LPrototype f = this.f; - if (f.k == null || nk + 1 >= f.k.length) - f.k = realloc( f.k, nk*2 + 1 ); - f.k[this.nk++] = v; - } - return idx; - } - - int stringK(LString s) { - return this.addk(s); - } - - int numberK(LNumber r) { - if ( r instanceof LDouble ) { - double d = r.toJavaDouble(); - int i = (int) d; - if ( d == (double) i ) - r = LInteger.valueOf(i); - } - return this.addk(r); - } - - int boolK(boolean b) { - return this.addk((b ? LBoolean.TRUE : LBoolean.FALSE)); - } - - int nilK() { - return this.addk(LNil.NIL); - } - - void setreturns(expdesc e, int nresults) { - if (e.k == LexState.VCALL) { /* expression is an open function call? */ - SETARG_C(this.getcodePtr(e), nresults + 1); - } else if (e.k == LexState.VVARARG) { - SETARG_B(this.getcodePtr(e), nresults + 1); - SETARG_A(this.getcodePtr(e), this.freereg); - this.reserveregs(1); - } - } - - void setoneret(expdesc e) { - if (e.k == LexState.VCALL) { /* expression is an open function call? */ - e.k = LexState.VNONRELOC; - e.u.s.info = GETARG_A(this.getcode(e)); - } else if (e.k == LexState.VVARARG) { - SETARG_B(this.getcodePtr(e), 2); - e.k = LexState.VRELOCABLE; /* can relocate its simple result */ - } - } - - void dischargevars(expdesc e) { - switch (e.k) { - case LexState.VLOCAL: { - e.k = LexState.VNONRELOC; - break; - } - case LexState.VUPVAL: { - e.u.s.info = this.codeABC(OP_GETUPVAL, 0, e.u.s.info, 0); - e.k = LexState.VRELOCABLE; - break; - } - case LexState.VGLOBAL: { - e.u.s.info = this.codeABx(OP_GETGLOBAL, 0, e.u.s.info); - e.k = LexState.VRELOCABLE; - break; - } - case LexState.VINDEXED: { - this.freereg(e.u.s.aux); - this.freereg(e.u.s.info); - e.u.s.info = this - .codeABC(OP_GETTABLE, 0, e.u.s.info, e.u.s.aux); - e.k = LexState.VRELOCABLE; - break; - } - case LexState.VVARARG: - case LexState.VCALL: { - this.setoneret(e); - break; - } - default: - break; /* there is one value available (somewhere) */ - } - } - - int code_label(int A, int b, int jump) { - this.getlabel(); /* those instructions may be jump targets */ - return this.codeABC(OP_LOADBOOL, A, b, jump); - } - - 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.codeABx(OP_LOADK, reg, e.u.s.info); - break; - } - case LexState.VKNUM: { - this.codeABx(OP_LOADK, 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.s.info) - this.codeABC(OP_MOVE, reg, e.u.s.info, 0); - break; - } - default: { - _assert (e.k == LexState.VVOID || e.k == LexState.VJMP); - return; /* nothing to do... */ - } - } - e.u.s.info = reg; - e.k = LexState.VNONRELOC; - } - - void discharge2anyreg(expdesc e) { - if (e.k != LexState.VNONRELOC) { - this.reserveregs(1); - this.discharge2reg(e, this.freereg - 1); - } - } - - void exp2reg(expdesc e, int reg) { - this.discharge2reg(e, reg); - if (e.k == LexState.VJMP) - this.concat(e.t, e.u.s.info); /* put this jump in `t' list */ - if (e.hasjumps()) { - int _final; /* position after whole expression */ - int p_f = LexState.NO_JUMP; /* position of an eventual LOAD false */ - int p_t = LexState.NO_JUMP; /* position of an eventual LOAD true */ - if (this.need_value(e.t.i) || this.need_value(e.f.i)) { - int fj = (e.k == LexState.VJMP) ? LexState.NO_JUMP : this - .jump(); - p_f = this.code_label(reg, 0, 1); - p_t = this.code_label(reg, 1, 0); - this.patchtohere(fj); - } - _final = this.getlabel(); - this.patchlistaux(e.f.i, _final, reg, p_f); - this.patchlistaux(e.t.i, _final, reg, p_t); - } - e.f.i = e.t.i = LexState.NO_JUMP; - e.u.s.info = reg; - e.k = LexState.VNONRELOC; - } - - void exp2nextreg(expdesc e) { - this.dischargevars(e); - this.freeexp(e); - this.reserveregs(1); - this.exp2reg(e, this.freereg - 1); - } - - int exp2anyreg(expdesc e) { - this.dischargevars(e); - if (e.k == LexState.VNONRELOC) { - if (!e.hasjumps()) - return e.u.s.info; /* exp is already in a register */ - if (e.u.s.info >= this.nactvar) { /* reg. is not a local? */ - this.exp2reg(e, e.u.s.info); /* put value on it */ - return e.u.s.info; - } - } - this.exp2nextreg(e); /* default */ - return e.u.s.info; - } - - void exp2val(expdesc e) { - if (e.hasjumps()) - this.exp2anyreg(e); - else - this.dischargevars(e); - } - - int exp2RK(expdesc e) { - this.exp2val(e); - switch (e.k) { - case LexState.VKNUM: - case LexState.VTRUE: - case LexState.VFALSE: - case LexState.VNIL: { - if (this.nk <= MAXINDEXRK) { /* constant fit in RK operand? */ - e.u.s.info = (e.k == LexState.VNIL) ? this.nilK() - : (e.k == LexState.VKNUM) ? this.numberK(e.u.nval()) - : this.boolK((e.k == LexState.VTRUE)); - e.k = LexState.VK; - return RKASK(e.u.s.info); - } else - break; - } - case LexState.VK: { - if (e.u.s.info <= MAXINDEXRK) /* constant fit in argC? */ - return RKASK(e.u.s.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.s.info); - return; - } - case LexState.VUPVAL: { - int e = this.exp2anyreg(ex); - this.codeABC(OP_SETUPVAL, e, var.u.s.info, 0); - break; - } - case LexState.VGLOBAL: { - int e = this.exp2anyreg(ex); - this.codeABx(OP_SETGLOBAL, e, var.u.s.info); - break; - } - case LexState.VINDEXED: { - int e = this.exp2RK(ex); - this.codeABC(OP_SETTABLE, var.u.s.info, var.u.s.aux, e); - break; - } - default: { - _assert (false); /* invalid var kind to store */ - break; - } - } - this.freeexp(ex); - } - - void self(expdesc e, expdesc key) { - int func; - this.exp2anyreg(e); - this.freeexp(e); - func = this.freereg; - this.reserveregs(2); - this.codeABC(OP_SELF, func, e.u.s.info, this.exp2RK(key)); - this.freeexp(key); - e.u.s.info = func; - e.k = LexState.VNONRELOC; - } - - void invertjump(expdesc e) { - InstructionPtr pc = this.getjumpcontrol(e.u.s.info); - _assert (testTMode(GET_OPCODE(pc.get())) - && GET_OPCODE(pc.get()) != OP_TESTSET && Lua - .GET_OPCODE(pc.get()) != OP_TEST); - // SETARG_A(pc, !(GETARG_A(pc.get()))); - int a = GETARG_A(pc.get()); - int nota = (a!=0? 0: 1); - SETARG_A(pc, nota); - } - - int jumponcond(expdesc e, int cond) { - if (e.k == LexState.VRELOCABLE) { - int ie = this.getcode(e); - if (GET_OPCODE(ie) == OP_NOT) { - this.pc--; /* remove previous OP_NOT */ - return this.condjump(OP_TEST, GETARG_B(ie), 0, (cond!=0? 0: 1)); - } - /* else go through */ - } - this.discharge2anyreg(e); - this.freeexp(e); - return this.condjump(OP_TESTSET, NO_REG, e.u.s.info, cond); - } - - void goiftrue(expdesc e) { - int pc; /* pc of last jump */ - this.dischargevars(e); - switch (e.k) { - case LexState.VK: - case LexState.VKNUM: - case LexState.VTRUE: { - pc = LexState.NO_JUMP; /* always true; do nothing */ - break; - } - case LexState.VFALSE: { - pc = this.jump(); /* always jump */ - break; - } - case LexState.VJMP: { - this.invertjump(e); - pc = e.u.s.info; - break; - } - default: { - pc = this.jumponcond(e, 0); - break; - } - } - this.concat(e.f, pc); /* insert last jump in `f' list */ - this.patchtohere(e.t.i); - e.t.i = LexState.NO_JUMP; - } - - void goiffalse(expdesc e) { - int pc; /* pc of last jump */ - this.dischargevars(e); - switch (e.k) { - case LexState.VNIL: - case LexState.VFALSE: { - pc = LexState.NO_JUMP; /* always false; do nothing */ - break; - } - case LexState.VTRUE: { - pc = this.jump(); /* always jump */ - break; - } - case LexState.VJMP: { - pc = e.u.s.info; - break; - } - default: { - pc = this.jumponcond(e, 1); - break; - } - } - this.concat(e.t, pc); /* insert last jump in `t' list */ - this.patchtohere(e.f.i); - e.f.i = LexState.NO_JUMP; - } - - 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.s.info = this.codeABC(OP_NOT, 0, e.u.s.info, 0); - e.k = LexState.VRELOCABLE; - break; - } - default: { - _assert (false); /* cannot happen */ - break; - } - } - /* interchange true and false lists */ - { - int temp = e.f.i; - e.f.i = e.t.i; - e.t.i = temp; - } - this.removevalues(e.f.i); - this.removevalues(e.t.i); - } - - void indexed(expdesc t, expdesc k) { - t.u.s.aux = this.exp2RK(k); - t.k = LexState.VINDEXED; - } - - boolean constfolding(int op, expdesc e1, expdesc e2) { - LNumber v1, v2, r; - if (!e1.isnumeral() || !e2.isnumeral()) - return false; - v1 = e1.u.nval(); - v2 = e2.u.nval(); - switch (op) { - case OP_ADD: - case OP_SUB: - case OP_MUL: - case OP_DIV: - case OP_MOD: - r = (LNumber) v2.luaBinOpUnknown(op, v1); - break; - case OP_POW: - r = Platform.getInstance().mathPow( v1, v2 ); - break; - case OP_UNM: - r = (LNumber) v1.luaUnaryMinus(); - break; - case OP_LEN: - return false; /* no constant folding for 'len' */ - default: - _assert (false); - r = null; - break; - } - if (Double.NaN == r.toJavaDouble()) - return false; /* do not attempt to produce NaN */ - e1.u.setNval( r ); - return true; - } - - void codearith(int op, expdesc e1, expdesc e2) { - if (constfolding(op, e1, e2)) - return; - else { - int o2 = (op != OP_UNM && op != OP_LEN) ? this.exp2RK(e2) - : 0; - int o1 = this.exp2RK(e1); - if (o1 > o2) { - this.freeexp(e1); - this.freeexp(e2); - } else { - this.freeexp(e2); - this.freeexp(e1); - } - e1.u.s.info = this.codeABC(op, 0, o1, o2); - e1.k = LexState.VRELOCABLE; - } - } - - void codecomp(int /* OpCode */op, int cond, expdesc e1, expdesc e2) { - int o1 = this.exp2RK(e1); - int o2 = this.exp2RK(e2); - this.freeexp(e2); - this.freeexp(e1); - if (cond == 0 && op != OP_EQ) { - int temp; /* exchange args to replace by `<' or `<=' */ - temp = o1; - o1 = o2; - o2 = temp; /* o1 <==> o2 */ - cond = 1; - } - e1.u.s.info = this.condjump(op, cond, o1, o2); - e1.k = LexState.VJMP; - } - - void prefix(int /* UnOpr */op, expdesc e) { - expdesc e2 = new expdesc(); - e2.init(LexState.VKNUM, 0); - switch (op) { - case LexState.OPR_MINUS: { - if (e.k == LexState.VK) - this.exp2anyreg(e); /* cannot operate on non-numeric constants */ - this.codearith(OP_UNM, e, e2); - 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); - 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()) - this.exp2RK(v); - break; - } - default: { - this.exp2RK(v); - break; - } - } - } - - - void posfix(int op, expdesc e1, expdesc e2) { - 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.s.info == GETARG_B(this.getcode(e2)) - 1); - this.freeexp(e1); - SETARG_B(this.getcodePtr(e2), e1.u.s.info); - e1.k = LexState.VRELOCABLE; - e1.u.s.info = e2.u.s.info; - } else { - this.exp2nextreg(e2); /* operand must be on the 'stack' */ - this.codearith(OP_CONCAT, e1, e2); - } - break; - } - case LexState.OPR_ADD: - this.codearith(OP_ADD, e1, e2); - break; - case LexState.OPR_SUB: - this.codearith(OP_SUB, e1, e2); - break; - case LexState.OPR_MUL: - this.codearith(OP_MUL, e1, e2); - break; - case LexState.OPR_DIV: - this.codearith(OP_DIV, e1, e2); - break; - case LexState.OPR_MOD: - this.codearith(OP_MOD, e1, e2); - break; - case LexState.OPR_POW: - this.codearith(OP_POW, e1, e2); - 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); - } - } - - - void fixline(int line) { - this.f.lineinfo[this.pc - 1] = line; - } - - - int code(int instruction, int line) { - LPrototype f = this.f; - this.dischargejpc(); /* `pc' will change */ - /* put new instruction in code array */ - if (f.code == null || this.pc + 1 > f.code.length) - f.code = LuaC.realloc(f.code, this.pc * 2 + 1); - f.code[this.pc] = instruction; - /* save corresponding line information */ - if (f.lineinfo == null || this.pc + 1 > f.lineinfo.length) - f.lineinfo = LuaC.realloc(f.lineinfo, - this.pc * 2 + 1); - f.lineinfo[this.pc] = line; - return this.pc++; - } - - - int codeABC(int o, int a, int b, int c) { - _assert (getOpMode(o) == iABC); - _assert (getBMode(o) != OpArgN || b == 0); - _assert (getCMode(o) != OpArgN || c == 0); - return this.code(CREATE_ABC(o, a, b, c), this.ls.lastline); - } - - - int codeABx(int o, int a, int bc) { - _assert (getOpMode(o) == iABx || getOpMode(o) == iAsBx); - _assert (getCMode(o) == OpArgN); - return this.code(CREATE_ABx(o, a, bc), this.ls.lastline); - } - - - void setlist(int base, int nelems, int tostore) { - int c = (nelems - 1) / LFIELDS_PER_FLUSH + 1; - int b = (tostore == LUA_MULTRET) ? 0 : tostore; - _assert (tostore != 0); - if (c <= MAXARG_C) - this.codeABC(OP_SETLIST, base, b, c); - else { - this.codeABC(OP_SETLIST, base, b, 0); - this.code(c, this.ls.lastline); - } - this.freereg = base + 1; /* free registers with list values */ - } - -} diff --git a/src/core/org/luaj/compiler/InstructionPtr.java b/src/core/org/luaj/compiler/InstructionPtr.java deleted file mode 100644 index 4393eba8..00000000 --- a/src/core/org/luaj/compiler/InstructionPtr.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.compiler; - -class InstructionPtr { - final int[] code; - final int idx; - InstructionPtr(int[] code, int idx ) { - this.code = code; - this.idx = idx; - } - int get() { - return code[idx]; - } - void set(int value) { - code[idx] = value; - } -} \ No newline at end of file diff --git a/src/core/org/luaj/compiler/IntPtr.java b/src/core/org/luaj/compiler/IntPtr.java deleted file mode 100644 index f196e1ff..00000000 --- a/src/core/org/luaj/compiler/IntPtr.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.compiler; - -public class IntPtr { - int i; - IntPtr() { - } - IntPtr(int value) { - this.i = value; - } -} diff --git a/src/core/org/luaj/compiler/LexState.java b/src/core/org/luaj/compiler/LexState.java deleted file mode 100644 index 41331d42..00000000 --- a/src/core/org/luaj/compiler/LexState.java +++ /dev/null @@ -1,1904 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.compiler; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Hashtable; - -import org.luaj.compiler.FuncState.BlockCnt; -import org.luaj.vm.LDouble; -import org.luaj.vm.LInteger; -import org.luaj.vm.LNumber; -import org.luaj.vm.LPrototype; -import org.luaj.vm.LString; -import org.luaj.vm.LocVars; -import org.luaj.vm.Lua; -import org.luaj.vm.LuaErrorException; - - -public class LexState { - - 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=", "<=", "~=", - "", "", "", "", - }; - - 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_IF=266, - TK_IN=267, TK_LOCAL=268, TK_NIL=269, TK_NOT=270, TK_OR=271, TK_REPEAT=272, - TK_RETURN=273, TK_THEN=274, TK_TRUE=275, TK_UNTIL=276, TK_WHILE=277, - /* other terminal symbols */ - TK_CONCAT=278, TK_DOTS=279, TK_EQ=280, TK_GE=281, TK_LE=282, TK_NE=283, - TK_NUMBER=284, TK_NAME=285, TK_STRING=286, TK_EOS=287; - - 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 == '_'); - // return Character.isLetterOrDigit(c); - } - - private boolean isalpha(int c) { - return (c >= 'a' && c <= 'z') - || (c >= 'A' && c <= 'Z'); - } - - private boolean isdigit(int c) { - return (c >= '0' && c <= '9'); - } - - private boolean isspace(int c) { - return (c <= ' '); - } - - - public LexState(LuaC state, InputStream stream) { - this.z = stream; - this.buff = new byte[32]; - this.L = state; - } - - void nextChar() { - try { - current = z.read(); - } catch ( IOException e ) { - e.printStackTrace(); - current = EOZ; - } - } - - boolean currIsNewline() { - return current == '\n' || current == '\r'; - } - - void save_and_next() { - save( current ); - nextChar(); - } - - void save(int c) { - if ( buff == null || nbuff + 1 > buff.length ) - buff = LuaC.realloc( buff, nbuff*2+1 ); - buff[nbuff++] = (byte) c; - } - - - String token2str( int token ) { - if ( token < FIRST_RESERVED ) { - return iscntrl(token)? - L.pushfstring( "char("+((int)token)+")" ): - L.pushfstring( String.valueOf( (char) token ) ); - } else { - return luaX_tokens[token-FIRST_RESERVED]; - } - } - - private static boolean iscntrl(int token) { - return token < ' '; - } - - 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 ); - } - } - - void lexerror( String msg, int token ) { - String cid = chunkid( source.toString() ); // TODO: get source name from source - L.pushfstring( cid+":"+linenumber+": "+msg ); - if ( token != 0 ) - L.pushfstring( "syntax error: "+msg+" near "+txtToken(token) ); - throw new LuaErrorException(cid+":"+linenumber+": "+msg); - } - - String chunkid( String source ) { - if ( source.startsWith("=") ) - return source.substring(1); - String end = ""; - if ( source.startsWith("@") ) { - source = source.substring(1); - } else { - source = "[string \""+source; - end = "\"]"; - } - int n = source.length() + end.length(); - if ( n > MAXSRC ) - source = source.substring(0,MAXSRC-end.length()-3) + "..."; - return source + end; - } - - void syntaxerror( String msg ) { - lexerror( msg, t.token ); - } - - LString newstring( String s ) { - return L.newTString( LString.valueOf(s) ); - } - - LString newstring( byte[] chars, int offset, int len ) { - return L.newTString( LString.newStringNoCopy(chars, offset, len) ); - } - - void inclinenumber() { - int old = current; - LuaC._assert( currIsNewline() ); - nextChar(); /* skip '\n' or '\r' */ - if ( currIsNewline() && current != old ) - nextChar(); /* skip '\n\r' or '\r\n' */ - if ( ++linenumber >= MAX_INT ) - syntaxerror("chunk has too many lines"); - } - - void setinput( LuaC L, int firstByte, InputStream z, LString source ) { - this.decpoint = '.'; - this.L = L; - this.lookahead.token = TK_EOS; /* no look-ahead token */ - this.z = z; - this.fs = null; - this.linenumber = 1; - this.lastline = 1; - this.source = source; - this.nbuff = 0; /* initialize buffer */ - this.current = firstByte; /* read first char */ - this.skipShebang(); - } - - private void skipShebang() { - if ( current == '#' ) - while (!currIsNewline() && current != EOZ) - nextChar(); - } - - - - /* - ** ======================================================= - ** LEXICAL ANALYZER - ** ======================================================= - */ - - - boolean check_next(String set) { - if (set.indexOf(current) < 0) - return false; - save_and_next(); - return true; - } - - void buffreplace(byte from, byte to) { - int n = nbuff; - byte[] p = buff; - while ((--n) >= 0) - if (p[n] == from) - p[n] = to; - } - - boolean str2d(String str, SemInfo seminfo) { - double d; - str = str.trim(); // TODO: get rid of this - if ( str.startsWith("0x") ) { - d = Long.parseLong(str.substring(2), 16); - } - else - d = Double.parseDouble(str); - seminfo.r = LDouble.numberOf(d); - return true; - } - - // - // TODO: reexamine this source and see if it should be ported differently - // - // static void trydecpoint (LexState *ls, SemInfo *seminfo) { - // /* format error: try to update decimal point separator */ - // struct lconv *cv = localeconv(); - // char old = this.decpoint; - // this.decpoint = (cv ? cv->decimal_point[0] : '.'); - // buffreplace(ls, old, this.decpoint); /* try updated decimal separator */ - // if (!luaO_str2d(luaZ_buffer(this.buff), &seminfo->r)) { - // /* format error with correct decimal point: no more options */ - // buffreplace(ls, this.decpoint, '.'); /* undo change (for error message) */ - // luaX_lexerror(ls, "malformed number", TK_NUMBER); - // } - // } - // - /* - void trydecpoint(String str, SemInfo seminfo) { - NumberFormat nf = NumberFormat.getInstance(); - try { - Number n = nf.parse(str); - double d = n.doubleValue(); - seminfo.r = new LDouble(d); - } catch (ParseException e) { - lexerror("malformed number", TK_NUMBER); - } - } - */ - - void read_numeral(SemInfo seminfo) { - LuaC._assert (isdigit(current)); - do { - save_and_next(); - } while (isdigit(current) || current == '.'); - if (check_next("Ee")) /* `E'? */ - check_next("+-"); /* optional exponent sign */ - while (isalnum(current) || current == '_') - save_and_next(); - save('\0'); - buffreplace((byte)'.', decpoint); /* follow locale for decimal point */ - String str = new String(buff, 0, nbuff); -// if (!str2d(str, seminfo)) /* format error? */ -// trydecpoint(str, seminfo); /* try to update decimal point separator */ - str2d(str, seminfo); - } - - int skip_sep() { - int count = 0; - int s = current; - LuaC._assert (s == '[' || s == ']'); - save_and_next(); - while (current == '=') { - save_and_next(); - count++; - } - return (current == s) ? count : (-count) - 1; - } - - void read_long_string(SemInfo seminfo, int sep) { - int cont = 0; - save_and_next(); /* skip 2nd `[' */ - if (currIsNewline()) /* string starts with a newline? */ - 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", '['); - } - } - 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; - } - 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) - seminfo.ts = newstring(buff, 2 + sep, nbuff - 2 * (2 + sep)); - } - - void read_string(int del, SemInfo seminfo) { - 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 '\n': /* go through */ - case '\r': - save('\n'); - inclinenumber(); - continue; - case EOZ: - continue; /* will raise an error next loop */ - 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; - } - default: - save_and_next(); - } - } - save_and_next(); /* skip delimiter */ - seminfo.ts = newstring(buff, 1, nbuff - 2); - } - - int llex(SemInfo seminfo) { - nbuff = 0; - while (true) { - switch (current) { - case '\n': - case '\r': { - inclinenumber(); - 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(); - if (sep >= 0) { - 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; - } - } - case '<': { - nextChar(); - 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 '"': - 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 { - read_numeral(seminfo); - return TK_NUMBER; - } - } - case EOZ: { - return TK_EOS; - } - default: { - if (isspace(current)) { - LuaC._assert (!currIsNewline()); - nextChar(); - continue; - } else if (isdigit(current)) { - read_numeral(seminfo); - return TK_NUMBER; - } else if (isalpha(current) || current == '_') { - /* identifier or reserved word */ - LString ts; - do { - save_and_next(); - } while (isalnum(current) || 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 (+ - / ...) */ - } - } - } - } - } - - void next() { - lastline = linenumber; - if (lookahead.token != TK_EOS) { /* is there a look-ahead token? */ - t.set( lookahead ); /* use this one */ - lookahead.token = TK_EOS; /* and discharge it */ - } else - t.token = llex(t.seminfo); /* read next token */ - } - - void lookahead() { - LuaC._assert (lookahead.token == TK_EOS); - lookahead.token = llex(lookahead.seminfo); - } - - // ============================================================= - // from lcode.h - // ============================================================= - - - // ============================================================= - // from lparser.c - // ============================================================= - - static class expdesc { - int k; // expkind, from enumerated list, above - static class U { // originally a union - static class S { - int info, aux; - } - final S s = new S(); - private LNumber _nval; - public void setNval(LNumber r) { - _nval = r; - } - public LNumber nval() { - return (_nval == null? LInteger.valueOf(s.info): _nval); - } - }; - final U u = new U(); - final IntPtr t = new IntPtr(); /* patch list of `exit when true' */ - final IntPtr f = new IntPtr(); /* patch list of `exit when false' */ - void init( int k, int i ) { - this.f.i = NO_JUMP; - this.t.i = NO_JUMP; - this.k = k; - this.u.s.info = i; - } - - boolean hasjumps() { - return (t.i != f.i); - } - - boolean isnumeral() { - return (k == VKNUM && t.i == NO_JUMP && f.i == NO_JUMP); - } - - public void setvalue(expdesc other) { - this.k = other.k; - this.u._nval = other.u._nval; - this.u.s.info = other.u.s.info; - this.u.s.aux = other.u.s.aux; - this.t.i = other.t.i; - this.f.i = other.f.i; - } - } - - boolean hasmultret(int k) { - return ((k) == VCALL || (k) == VVARARG); - } - - /*---------------------------------------------------------------------- - name args description - ------------------------------------------------------------------------*/ - - /* - * * prototypes for recursive non-terminal functions - */ - - void error_expected(int token) { - syntaxerror(L.pushfstring(LUA_QS(token2str(token)) + " expected")); - } - - boolean testnext(int c) { - if (t.token == c) { - next(); - return true; - } else - return false; - } - - void check(int c) { - if (t.token != c) - error_expected(c); - } - - void checknext (int c) { - check(c); - next(); - } - - void check_condition(boolean c, String msg) { - if (!(c)) - syntaxerror(msg); - } - - - void check_match(int what, int who, int where) { - if (!testnext(what)) { - if (where == linenumber) - error_expected(what); - else { - syntaxerror(L.pushfstring(LUA_QS(token2str(what)) - + " expected " + "(to close " + LUA_QS(token2str(who)) - + " at line " + where + ")")); - } - } - } - - LString str_checkname() { - LString ts; - check(TK_NAME); - ts = t.seminfo.ts; - next(); - return ts; - } - - void codestring(expdesc e, LString s) { - e.init(VK, fs.stringK(s)); - } - - void checkname(expdesc e) { - codestring(e, str_checkname()); - } - - - int registerlocalvar(LString varname) { - FuncState fs = this.fs; - LPrototype f = fs.f; - if (f.locvars == null || fs.nlocvars + 1 > f.locvars.length) - f.locvars = LuaC.realloc( f.locvars, fs.nlocvars*2+1 ); - f.locvars[fs.nlocvars] = new LocVars(varname,0,0); - return fs.nlocvars++; - } - - -// -// #define new_localvarliteral(ls,v,n) \ -// this.new_localvar(luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n) -// - void new_localvarliteral(String v, int n) { - LString ts = newstring(v); - new_localvar(ts, n); - } - - void new_localvar(LString name, int n) { - FuncState fs = this.fs; - fs.checklimit(fs.nactvar + n + 1, FuncState.LUAI_MAXVARS, "local variables"); - fs.actvar[fs.nactvar + n] = (short) registerlocalvar(name); - } - - void adjustlocalvars(int nvars) { - FuncState fs = this.fs; - fs.nactvar = (short) (fs.nactvar + nvars); - for (; nvars > 0; nvars--) { - fs.getlocvar(fs.nactvar - nvars).startpc = fs.pc; - } - } - - void removevars(int tolevel) { - FuncState fs = this.fs; - while (fs.nactvar > tolevel) - fs.getlocvar(--fs.nactvar).endpc = fs.pc; - } - - void singlevar(expdesc var) { - LString varname = this.str_checkname(); - FuncState fs = this.fs; - if (fs.singlevaraux(varname, var, 1) == VGLOBAL) - var.u.s.info = fs.stringK(varname); /* info points to global name */ - } - - void adjust_assign(int nvars, int nexps, expdesc e) { - FuncState fs = this.fs; - int extra = nvars - nexps; - if (hasmultret(e.k)) { - /* includes call itself */ - extra++; - if (extra < 0) - extra = 0; - /* last exp. provides the difference */ - fs.setreturns(e, extra); - if (extra > 1) - fs.reserveregs(extra - 1); - } else { - /* close last expression */ - if (e.k != VVOID) - fs.exp2nextreg(e); - if (extra > 0) { - int reg = fs.freereg; - fs.reserveregs(extra); - fs.nil(reg, extra); - } - } - } - - void enterlevel() { - if (++L.nCcalls > LUAI_MAXCCALLS) - lexerror("chunk has too many syntax levels", 0); - } - - void leavelevel() { - L.nCcalls--; - } - - void pushclosure(FuncState func, expdesc v) { - FuncState fs = this.fs; - LPrototype f = fs.f; - if (f.p == null || fs.np + 1 > f.p.length) - f.p = LuaC.realloc( f.p, fs.np*2 + 1 ); - f.p[fs.np++] = func.f; - v.init(VRELOCABLE, fs.codeABx(Lua.OP_CLOSURE, 0, fs.np - 1)); - for (int i = 0; i < func.f.nups; i++) { - int o = (func.upvalues[i].k == VLOCAL) ? Lua.OP_MOVE - : Lua.OP_GETUPVAL; - fs.codeABC(o, 0, func.upvalues[i].info, 0); - } - } - - void open_func (FuncState fs) { - LuaC L = this.L; - LPrototype f = new LPrototype(); - if ( this.fs!=null ) - f.source = this.fs.f.source; - fs.f = f; - fs.prev = this.fs; /* linked list of funcstates */ - fs.ls = this; - fs.L = L; - 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.nlocvars = 0; - fs.nactvar = 0; - fs.bl = null; - f.maxstacksize = 2; /* registers 0/1 are always valid */ - //fs.h = new LTable(); - fs.htable = new Hashtable(); - } - - void close_func() { - FuncState fs = this.fs; - LPrototype f = fs.f; - this.removevars(0); - fs.ret(0, 0); /* final return */ - f.code = LuaC.realloc(f.code, fs.pc); - f.lineinfo = LuaC.realloc(f.lineinfo, fs.pc); - // f.sizelineinfo = fs.pc; - f.k = LuaC.realloc(f.k, fs.nk); - f.p = LuaC.realloc(f.p, fs.np); - f.locvars = LuaC.realloc(f.locvars, fs.nlocvars); - // f.sizelocvars = fs.nlocvars; - f.upvalues = LuaC.realloc(f.upvalues, f.nups); - // LuaC._assert (CheckCode.checkcode(f)); - LuaC._assert (fs.bl == null); - this.fs = fs.prev; -// L.top -= 2; /* remove table and prototype from the stack */ - // /* last token read was anchored in defunct function; must reanchor it - // */ - // if (fs!=null) ls.anchor_token(); - } - - /*============================================================*/ - /* GRAMMAR RULES */ - /*============================================================*/ - - void field(expdesc v) { - /* field -> ['.' | ':'] NAME */ - FuncState fs = this.fs; - expdesc key = new expdesc(); - fs.exp2anyreg(v); - this.next(); /* skip the dot or colon */ - this.checkname(key); - fs.indexed(v, key); - } - - void yindex(expdesc v) { - /* index -> '[' expr ']' */ - this.next(); /* skip the '[' */ - this.expr(v); - this.fs.exp2val(v); - this.checknext(']'); - } - - - /* - ** {====================================================================== - ** Rules for Constructors - ** ======================================================================= - */ - - - static class ConsControl { - expdesc v = new expdesc(); /* last list item read */ - expdesc t; /* table descriptor */ - int nh; /* total number of `record' elements */ - int na; /* total number of array elements */ - int tostore; /* number of array elements pending to be stored */ - }; - - - void recfield(ConsControl cc) { - /* recfield -> (NAME | `['exp1`]') = exp1 */ - FuncState fs = this.fs; - int reg = this.fs.freereg; - expdesc key = new expdesc(); - expdesc val = new expdesc(); - int rkkey; - if (this.t.token == TK_NAME) { - fs.checklimit(cc.nh, MAX_INT, "items in a constructor"); - this.checkname(key); - } else - /* this.t.token == '[' */ - this.yindex(key); - cc.nh++; - this.checknext('='); - rkkey = fs.exp2RK(key); - this.expr(val); - fs.codeABC(Lua.OP_SETTABLE, cc.t.u.s.info, rkkey, fs.exp2RK(val)); - fs.freereg = reg; /* free registers */ - } - - void listfield (ConsControl cc) { - this.expr(cc.v); - fs.checklimit(cc.na, MAX_INT, "items in a constructor"); - cc.na++; - cc.tostore++; - } - - - void constructor(expdesc t) { - /* constructor -> ?? */ - FuncState fs = this.fs; - int line = this.linenumber; - int pc = fs.codeABC(Lua.OP_NEWTABLE, 0, 0, 0); - ConsControl cc = new ConsControl(); - cc.na = cc.nh = cc.tostore = 0; - cc.t = t; - t.init(VRELOCABLE, pc); - cc.v.init(VVOID, 0); /* no value (yet) */ - fs.exp2nextreg(t); /* fix it at stack top (for gc) */ - this.checknext('{'); - do { - LuaC._assert (cc.v.k == VVOID || cc.tostore > 0); - if (this.t.token == '}') - 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 - this.recfield(cc); - break; - } - case '[': { /* constructor_item -> recfield */ - this.recfield(cc); - break; - } - default: { /* constructor_part -> listfield */ - this.listfield(cc); - break; - } - } - } while (this.testnext(',') || this.testnext(';')); - this.check_match('}', '{', line); - fs.lastlistfield(cc); - InstructionPtr i = new InstructionPtr(fs.f.code, pc); - LuaC.SETARG_B(i, luaO_int2fb(cc.na)); /* set initial array size */ - LuaC.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. - */ - 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); - } - - - /* }====================================================================== */ - - void parlist () { - /* parlist -> [ param { `,' param } ] */ - FuncState fs = this.fs; - LPrototype 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(); - if (LUA_COMPAT_VARARG) { - /* use `arg' as default name */ - this.new_localvarliteral("arg", nparams++); - f.is_vararg = LuaC.VARARG_HASARG | LuaC.VARARG_NEEDSARG; - } - f.is_vararg |= LuaC.VARARG_ISVARARG; - break; - } - default: this.syntaxerror(" or " + LUA_QL("...") + " expected"); - } - } while ((f.is_vararg==0) && this.testnext(',')); - } - this.adjustlocalvars(nparams); - f.numparams = (fs.nactvar - (f.is_vararg & LuaC.VARARG_HASARG)); - fs.reserveregs(fs.nactvar); /* reserve register for parameters */ - } - - - void body(expdesc e, boolean needself, int line) { - /* body -> `(' parlist `)' chunk END */ - FuncState new_fs = new FuncState(); - open_func(new_fs); - new_fs.f.linedefined = line; - this.checknext('('); - if (needself) { - new_localvarliteral("self", 0); - adjustlocalvars(1); - } - this.parlist(); - this.checknext(')'); - this.chunk(); - new_fs.f.lastlinedefined = this.linenumber; - this.check_match(TK_END, TK_FUNCTION, line); - this.close_func(); - this.pushclosure(new_fs, e); - } - - int explist1(expdesc v) { - /* explist1 -> expr { `,' expr } */ - int n = 1; /* at least one expression */ - this.expr(v); - while (this.testnext(',')) { - fs.exp2nextreg(v); - this.expr(v); - n++; - } - return n; - } - - - void funcargs(expdesc f) { - FuncState fs = this.fs; - expdesc args = new expdesc(); - int base, nparams; - int line = this.linenumber; - switch (this.t.token) { - case '(': { /* funcargs -> `(' [ explist1 ] `)' */ - if (line != this.lastline) - this.syntaxerror("ambiguous syntax (function call x new statement)"); - this.next(); - if (this.t.token == ')') /* arg list is empty? */ - args.k = VVOID; - else { - this.explist1(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; - } - } - LuaC._assert (f.k == VNONRELOC); - base = f.u.s.info; /* base register for call */ - if (hasmultret(args.k)) - nparams = Lua.LUA_MULTRET; /* open call */ - else { - if (args.k != VVOID) - fs.exp2nextreg(args); /* close last argument */ - nparams = fs.freereg - (base + 1); - } - f.init(VCALL, fs.codeABC(Lua.OP_CALL, base, nparams + 1, 2)); - fs.fixline(line); - fs.freereg = base+1; /* call remove function and arguments and leaves - * (unless changed) one result */ - } - - - /* - ** {====================================================================== - ** Expression parsing - ** ======================================================================= - */ - - void prefixexp(expdesc v) { - /* prefixexp -> NAME | '(' expr ')' */ - switch (this.t.token) { - case '(': { - int line = this.linenumber; - this.next(); - this.expr(v); - this.check_match(')', '(', line); - fs.dischargevars(v); - return; - } - case TK_NAME: { - this.singlevar(v); - return; - } - default: { - this.syntaxerror("unexpected symbol"); - return; - } - } - } - - - void primaryexp(expdesc v) { - /* - * primaryexp -> prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | - * funcargs } - */ - FuncState fs = this.fs; - this.prefixexp(v); - for (;;) { - switch (this.t.token) { - case '.': { /* field */ - this.field(v); - break; - } - case '[': { /* `[' exp1 `]' */ - expdesc key = new expdesc(); - fs.exp2anyreg(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); - break; - } - case '(': - case TK_STRING: - case '{': { /* funcargs */ - fs.exp2nextreg(v); - this.funcargs(v); - break; - } - default: - return; - } - } - } - - - void simpleexp(expdesc v) { - /* - * simpleexp -> NUMBER | STRING | NIL | true | false | ... | constructor | - * 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"); - fs.f.is_vararg &= ~LuaC.VARARG_NEEDSARG; /* don't need 'arg' */ - 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.primaryexp(v); - return; - } - } - this.next(); - } - - - int getunopr(int op) { - switch (op) { - 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; - } - } - - static class Priority { - final byte left; /* left priority for each binary operator */ - - final byte right; /* right priority */ - - public Priority(int i, int j) { - left = (byte) i; - 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) */ - }; - - 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' - */ - int subexpr(expdesc v, int limit) { - int op; - int uop; - this.enterlevel(); - uop = getunopr(this.t.token); - if (uop != OPR_NOUNOPR) { - this.next(); - this.subexpr(v, UNARY_PRIORITY); - fs.prefix(uop, v); - } else - this.simpleexp(v); - /* expand while operators have priorities higher than `limit' */ - op = getbinopr(this.t.token); - while (op != OPR_NOBINOPR && priority[op].left > limit) { - expdesc v2 = new expdesc(); - int nextop; - this.next(); - fs.infix(op, v); - /* read sub-expression with higher priority */ - nextop = this.subexpr(v2, priority[op].right); - fs.posfix(op, v, v2); - op = nextop; - } - this.leavelevel(); - return op; /* return first untreated operator */ - } - - void expr(expdesc v) { - this.subexpr(v, 0); - } - - /* }==================================================================== */ - - - - /* - ** {====================================================================== - ** Rules for Statements - ** ======================================================================= - */ - - - boolean block_follow (int token) { - switch (token) { - case TK_ELSE: case TK_ELSEIF: case TK_END: - case TK_UNTIL: case TK_EOS: - return true; - default: return false; - } - } - - - void block () { - /* block -> chunk */ - FuncState fs = this.fs; - BlockCnt bl = new BlockCnt(); - fs.enterblock(bl, false); - this.chunk(); - LuaC._assert(bl.breaklist.i == NO_JUMP); - fs.leaveblock(); - } - - - /* - ** 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) */ - expdesc v = new expdesc(); - }; - - - /* - ** 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; - int extra = fs.freereg; /* eventual position to save local variable */ - boolean conflict = false; - for (; lh!=null; lh = lh.prev) { - if (lh.v.k == VINDEXED) { - if (lh.v.u.s.info == v.u.s.info) { /* conflict? */ - conflict = true; - lh.v.u.s.info = extra; /* previous assignment will use safe copy */ - } - if (lh.v.u.s.aux == v.u.s.info) { /* conflict? */ - conflict = true; - lh.v.u.s.aux = extra; /* previous assignment will use safe copy */ - } - } - } - if (conflict) { - fs.codeABC(Lua.OP_MOVE, fs.freereg, v.u.s.info, 0); /* make copy */ - fs.reserveregs(1); - } - } - - - void assignment (LHS_assign lh, int nvars) { - expdesc e = new expdesc(); - this.check_condition(VLOCAL <= lh.v.k && lh.v.k <= VINDEXED, - "syntax error"); - if (this.testnext(',')) { /* assignment -> `,' primaryexp assignment */ - LHS_assign nv = new LHS_assign(); - nv.prev = lh; - this.primaryexp(nv.v); - if (nv.v.k == VLOCAL) - this.check_conflict(lh, nv.v); - this.assignment(nv, nvars+1); - } - else { /* assignment . `=' explist1 */ - int nexps; - this.checknext('='); - nexps = this.explist1(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 cond() { - /* cond -> exp */ - expdesc v = new expdesc(); - /* read condition */ - this.expr(v); - /* `falses' are all equal here */ - if (v.k == VNIL) - v.k = VFALSE; - fs.goiftrue(v); - return v.f.i; - } - - - void breakstat() { - FuncState fs = this.fs; - BlockCnt bl = fs.bl; - boolean upval = false; - while (bl != null && !bl.isbreakable) { - upval |= bl.upval; - bl = bl.previous; - } - if (bl == null) - this.syntaxerror("no loop to break"); - if (upval) - fs.codeABC(Lua.OP_CLOSE, bl.nactvar, 0, 0); - fs.concat(bl.breaklist, fs.jump()); - } - - - void whilestat (int line) { - /* whilestat -> WHILE cond DO block END */ - FuncState fs = this.fs; - int whileinit; - int condexit; - BlockCnt bl = new BlockCnt(); - this.next(); /* skip WHILE */ - whileinit = fs.getlabel(); - condexit = this.cond(); - fs.enterblock(bl, true); - this.checknext(TK_DO); - this.block(); - fs.patchlist(fs.jump(), whileinit); - this.check_match(TK_END, TK_WHILE, line); - fs.leaveblock(); - fs.patchtohere(condexit); /* false conditions finish the loop */ - } - - void repeatstat(int line) { - /* repeatstat -> REPEAT block UNTIL cond */ - int condexit; - FuncState fs = this.fs; - int repeat_init = fs.getlabel(); - BlockCnt bl1 = new BlockCnt(); - BlockCnt bl2 = new BlockCnt(); - fs.enterblock(bl1, true); /* loop block */ - fs.enterblock(bl2, false); /* scope block */ - this.next(); /* skip REPEAT */ - this.chunk(); - this.check_match(TK_UNTIL, TK_REPEAT, line); - condexit = this.cond(); /* read condition (inside scope block) */ - if (!bl2.upval) { /* no upvalues? */ - fs.leaveblock(); /* finish scope */ - fs.patchlist(condexit, repeat_init); /* close the loop */ - } else { /* complete semantics when there are upvalues */ - this.breakstat(); /* if condition then break */ - fs.patchtohere(condexit); /* else... */ - fs.leaveblock(); /* finish scope... */ - fs.patchlist(fs.jump(), repeat_init); /* and repeat */ - } - fs.leaveblock(); /* finish loop */ - } - - - int exp1() { - expdesc e = new expdesc(); - int k; - this.expr(e); - k = e.k; - fs.exp2nextreg(e); - return k; - } - - - void forbody(int base, int line, int nvars, boolean isnum) { - /* forbody -> DO block */ - BlockCnt bl = new BlockCnt(); - FuncState fs = this.fs; - int prep, endfor; - this.adjustlocalvars(3); /* control variables */ - this.checknext(TK_DO); - prep = isnum ? fs.codeAsBx(Lua.OP_FORPREP, base, NO_JUMP) : fs.jump(); - fs.enterblock(bl, false); /* scope for declared variables */ - this.adjustlocalvars(nvars); - fs.reserveregs(nvars); - this.block(); - fs.leaveblock(); /* end of scope for declared variables */ - fs.patchtohere(prep); - endfor = (isnum) ? fs.codeAsBx(Lua.OP_FORLOOP, base, NO_JUMP) : fs - .codeABC(Lua.OP_TFORLOOP, base, 0, nvars); - fs.fixline(line); /* pretend that `Lua.OP_FOR' starts the loop */ - fs.patchlist((isnum ? endfor : fs.jump()), prep + 1); - } - - - void fornum(LString varname, int line) { - /* fornum -> NAME = exp1,exp1[,exp1] forbody */ - FuncState fs = this.fs; - int base = fs.freereg; - this.new_localvarliteral(RESERVED_LOCAL_VAR_FOR_INDEX, 0); - this.new_localvarliteral(RESERVED_LOCAL_VAR_FOR_LIMIT, 1); - this.new_localvarliteral(RESERVED_LOCAL_VAR_FOR_STEP, 2); - this.new_localvar(varname, 3); - this.checknext('='); - this.exp1(); /* initial value */ - this.checknext(','); - this.exp1(); /* limit */ - if (this.testnext(',')) - this.exp1(); /* optional step */ - else { /* default step = 1 */ - fs.codeABx(Lua.OP_LOADK, fs.freereg, fs.numberK(LInteger.valueOf(1))); - fs.reserveregs(1); - } - this.forbody(base, line, 1, true); - } - - - void forlist(LString indexname) { - /* forlist -> NAME {,NAME} IN explist1 forbody */ - FuncState fs = this.fs; - expdesc e = new expdesc(); - int nvars = 0; - int line; - int base = fs.freereg; - /* create control variables */ - this.new_localvarliteral(RESERVED_LOCAL_VAR_FOR_GENERATOR, nvars++); - this.new_localvarliteral(RESERVED_LOCAL_VAR_FOR_STATE, nvars++); - this.new_localvarliteral(RESERVED_LOCAL_VAR_FOR_CONTROL, nvars++); - /* create declared variables */ - this.new_localvar(indexname, nvars++); - while (this.testnext(',')) - this.new_localvar(this.str_checkname(), nvars++); - this.checknext(TK_IN); - line = this.linenumber; - this.adjust_assign(3, this.explist1(e), e); - fs.checkstack(3); /* extra space to call generator */ - this.forbody(base, line, nvars - 3, false); - } - - - void forstat(int line) { - /* forstat -> FOR (fornum | forlist) END */ - FuncState fs = this.fs; - LString varname; - BlockCnt bl = new BlockCnt(); - fs.enterblock(bl, true); /* scope for loop and control variables */ - 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"); - } - this.check_match(TK_END, TK_FOR, line); - fs.leaveblock(); /* loop scope (`break' jumps to this point) */ - } - - - int test_then_block() { - /* test_then_block -> [IF | ELSEIF] cond THEN block */ - int condexit; - this.next(); /* skip IF or ELSEIF */ - condexit = this.cond(); - this.checknext(TK_THEN); - this.block(); /* `then' part */ - return condexit; - } - - - void ifstat(int line) { - /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] - * END */ - FuncState fs = this.fs; - int flist; - IntPtr escapelist = new IntPtr(NO_JUMP); - flist = test_then_block(); /* IF cond THEN block */ - while (this.t.token == TK_ELSEIF) { - fs.concat(escapelist, fs.jump()); - fs.patchtohere(flist); - flist = test_then_block(); /* ELSEIF cond THEN block */ - } - if (this.t.token == TK_ELSE) { - fs.concat(escapelist, fs.jump()); - fs.patchtohere(flist); - this.next(); /* skip ELSE (after patch, for correct line info) */ - this.block(); /* `else' part */ - } else - fs.concat(escapelist, flist); - fs.patchtohere(escapelist.i); - this.check_match(TK_END, TK_IF, line); - } - - void localfunc() { - expdesc v = new expdesc(); - expdesc b = new expdesc(); - FuncState fs = this.fs; - this.new_localvar(this.str_checkname(), 0); - v.init(VLOCAL, fs.freereg); - fs.reserveregs(1); - this.adjustlocalvars(1); - this.body(b, false, this.linenumber); - fs.storevar(v, b); - /* debug information will only see the variable after this point! */ - fs.getlocvar(fs.nactvar - 1).startpc = fs.pc; - } - - - void localstat() { - /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ - int nvars = 0; - int nexps; - expdesc e = new expdesc(); - do { - this.new_localvar(this.str_checkname(), nvars++); - } while (this.testnext(',')); - if (this.testnext('=')) - nexps = this.explist1(e); - else { - e.k = VVOID; - nexps = 0; - } - this.adjust_assign(nvars, nexps, e); - this.adjustlocalvars(nvars); - } - - - boolean funcname(expdesc v) { - /* funcname -> NAME {field} [`:' NAME] */ - boolean needself = false; - this.singlevar(v); - while (this.t.token == '.') - this.field(v); - if (this.t.token == ':') { - needself = true; - this.field(v); - } - return needself; - } - - - void funcstat(int line) { - /* funcstat -> FUNCTION funcname body */ - boolean needself; - expdesc v = new expdesc(); - expdesc b = new expdesc(); - this.next(); /* skip FUNCTION */ - needself = this.funcname(v); - this.body(b, needself, line); - fs.storevar(v, b); - fs.fixline(line); /* definition `happens' in the first line */ - } - - - void exprstat() { - /* stat -> func | assignment */ - FuncState fs = this.fs; - LHS_assign v = new LHS_assign(); - this.primaryexp(v.v); - if (v.v.k == VCALL) /* stat -> func */ - LuaC.SETARG_C(fs.getcodePtr(v.v), 1); /* call statement uses no results */ - else { /* stat -> assignment */ - v.prev = null; - this.assignment(v, 1); - } - } - - void retstat() { - /* stat -> RETURN explist */ - FuncState fs = this.fs; - expdesc e = new expdesc(); - int first, nret; /* registers with returned values */ - this.next(); /* skip RETURN */ - if (block_follow(this.t.token) || this.t.token == ';') - first = nret = 0; /* return no values */ - else { - nret = this.explist1(e); /* optional return values */ - if (hasmultret(e.k)) { - fs.setmultret(e); - if (e.k == VCALL && nret == 1) { /* tail call? */ - LuaC.SET_OPCODE(fs.getcodePtr(e), Lua.OP_TAILCALL); - LuaC._assert (Lua.GETARG_A(fs.getcode(e)) == fs.nactvar); - } - first = fs.nactvar; - nret = Lua.LUA_MULTRET; /* return all values */ - } else { - if (nret == 1) /* only one single value? */ - first = fs.exp2anyreg(e); - else { - fs.exp2nextreg(e); /* values must go to the `stack' */ - first = fs.nactvar; /* return all `active' values */ - LuaC._assert (nret == fs.freereg - first); - } - } - } - fs.ret(first, nret); - } - - - boolean statement() { - int line = this.linenumber; /* may be needed for error messages */ - switch (this.t.token) { - case TK_IF: { /* stat -> ifstat */ - this.ifstat(line); - return false; - } - case TK_WHILE: { /* stat -> whilestat */ - this.whilestat(line); - return false; - } - case TK_DO: { /* stat -> DO block END */ - this.next(); /* skip DO */ - this.block(); - this.check_match(TK_END, TK_DO, line); - return false; - } - case TK_FOR: { /* stat -> forstat */ - this.forstat(line); - return false; - } - case TK_REPEAT: { /* stat -> repeatstat */ - this.repeatstat(line); - return false; - } - case TK_FUNCTION: { - this.funcstat(line); /* stat -> funcstat */ - return false; - } - case TK_LOCAL: { /* stat -> localstat */ - this.next(); /* skip LOCAL */ - if (this.testnext(TK_FUNCTION)) /* local function? */ - this.localfunc(); - else - this.localstat(); - return false; - } - case TK_RETURN: { /* stat -> retstat */ - this.retstat(); - return true; /* must be last statement */ - } - case TK_BREAK: { /* stat -> breakstat */ - this.next(); /* skip BREAK */ - this.breakstat(); - return true; /* must be last statement */ - } - default: { - this.exprstat(); - return false; /* to avoid warnings */ - } - } - } - - void chunk() { - /* chunk -> { stat [`;'] } */ - boolean islast = false; - this.enterlevel(); - while (!islast && !block_follow(this.t.token)) { - islast = this.statement(); - this.testnext(';'); - LuaC._assert (this.fs.f.maxstacksize >= this.fs.freereg - && this.fs.freereg >= this.fs.nactvar); - this.fs.freereg = this.fs.nactvar; /* free registers */ - } - this.leavelevel(); - } - - /* }====================================================================== */ - -} diff --git a/src/core/org/luaj/compiler/LuaC.java b/src/core/org/luaj/compiler/LuaC.java deleted file mode 100644 index 406d0189..00000000 --- a/src/core/org/luaj/compiler/LuaC.java +++ /dev/null @@ -1,223 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.compiler; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Hashtable; - -import org.luaj.vm.LPrototype; -import org.luaj.vm.LString; -import org.luaj.vm.LValue; -import org.luaj.vm.LoadState; -import org.luaj.vm.LocVars; -import org.luaj.vm.Lua; -import org.luaj.vm.LuaErrorException; -import org.luaj.vm.LoadState.LuaCompiler; - - -/** - * Compiler for Lua - */ -public class LuaC extends Lua implements LuaCompiler { - - /** Install the compiler so that LoadState will first - * try to use it when handed bytes that are - * not already a compiled lua chunk. - */ - public static void install() { - LoadState.compiler = new LuaC(); - } - - protected static void _assert(boolean b) { - if (!b) - throw new LuaErrorException("compiler assert failed"); - } - - public static final int MAXSTACK = 250; - static final int LUAI_MAXUPVALUES = 60; - static final int LUAI_MAXVARS = 200; - static final int NO_REG = MAXARG_A; - - - /* OpMode - basic instruction format */ - static final int - iABC = 0, - iABx = 1, - iAsBx = 2; - - /* OpArgMask */ - static final int - OpArgN = 0, /* argument is not used */ - OpArgU = 1, /* argument is used */ - OpArgR = 2, /* argument is a register or a jump offset */ - OpArgK = 3; /* argument is a constant or register/constant */ - - - static void SET_OPCODE(InstructionPtr i,int o) { - i.set( ( i.get() & (MASK_NOT_OP)) | ((o << POS_OP) & MASK_OP) ); - } - - static void SETARG_A(InstructionPtr i,int u) { - i.set( ( i.get() & (MASK_NOT_A)) | ((u << POS_A) & MASK_A) ); - } - - static void SETARG_B(InstructionPtr i,int u) { - i.set( ( i.get() & (MASK_NOT_B)) | ((u << POS_B) & MASK_B) ); - } - - static void SETARG_C(InstructionPtr i,int u) { - i.set( ( i.get() & (MASK_NOT_C)) | ((u << POS_C) & MASK_C) ); - } - - static void SETARG_Bx(InstructionPtr i,int u) { - i.set( ( i.get() & (MASK_NOT_Bx)) | ((u << POS_Bx) & MASK_Bx) ); - } - - static void SETARG_sBx(InstructionPtr i,int u) { - SETARG_Bx( i, u + MAXARG_sBx ); - } - - static int CREATE_ABC(int o, int a, int b, int c) { - return ((o << POS_OP) & MASK_OP) | - ((a << POS_A) & MASK_A) | - ((b << POS_B) & MASK_B) | - ((c << POS_C) & MASK_C) ; - } - - static int CREATE_ABx(int o, int a, int bc) { - return ((o << POS_OP) & MASK_OP) | - ((a << POS_A) & MASK_A) | - ((bc << POS_Bx) & MASK_Bx) ; - } - - // vector reallocation - - static LValue[] realloc(LValue[] v, int n) { - LValue[] a = new LValue[n]; - if ( v != null ) - System.arraycopy(v, 0, a, 0, Math.min(v.length,n)); - return a; - } - - static LPrototype[] realloc(LPrototype[] v, int n) { - LPrototype[] a = new LPrototype[n]; - if ( v != null ) - System.arraycopy(v, 0, a, 0, Math.min(v.length,n)); - return a; - } - - static LString[] realloc(LString[] v, int n) { - LString[] a = new LString[n]; - if ( v != null ) - System.arraycopy(v, 0, a, 0, Math.min(v.length,n)); - return a; - } - - static LocVars[] realloc(LocVars[] v, int n) { - LocVars[] a = new LocVars[n]; - if ( v != null ) - System.arraycopy(v, 0, a, 0, Math.min(v.length,n)); - return a; - } - - static int[] realloc(int[] v, int n) { - int[] a = new int[n]; - if ( v != null ) - System.arraycopy(v, 0, a, 0, Math.min(v.length,n)); - return a; - } - - static byte[] realloc(byte[] v, int n) { - byte[] a = new byte[n]; - if ( v != null ) - System.arraycopy(v, 0, a, 0, Math.min(v.length,n)); - return a; - } - - public int nCcalls; - Hashtable strings = new Hashtable(); - - /** Utility method to invoke the compiler for an input stream - */ - public static LPrototype compile(InputStream is, String string) throws IOException { - return new LuaC().compile(is.read(), is, string); - } - - /** Compile source bytes into a LPrototype. - * - * Try to compile the file, and return the Prototype on success, - * or throw LuaErrorException on syntax error or I/O Exception - * - * @param firstByte the first byte from the InputStream. - * This can be read by the client and tested to see if it is already a binary chunk. - * @param stream InputStream to read from. - * @param name Name of the chunk - * @return null if the first byte indicates it is a binary chunk, - * a LPrototype instance if it can be compiled, - * or an exception is thrown if there is an error. - * @throws IOException if an I/O exception occurs - * @throws LuaErrorException if there is a syntax error. - */ - public LPrototype compile(int firstByte, InputStream stream, String name) throws IOException { - LuaC compiler = new LuaC(); - return compiler.luaY_parser(firstByte, stream, name); - } - - /** Parse the input */ - private LPrototype luaY_parser(int firstByte, InputStream z, String name) { - LexState lexstate = new LexState(this, z); - FuncState funcstate = new FuncState(); - // lexstate.buff = buff; - lexstate.setinput( this, firstByte, z, new LString(name) ); - lexstate.open_func(funcstate); - /* main func. is always vararg */ - funcstate.f.is_vararg = LuaC.VARARG_ISVARARG; - funcstate.f.source = new LString("@"+name); - lexstate.next(); /* read first token */ - lexstate.chunk(); - lexstate.check(LexState.TK_EOS); - lexstate.close_func(); - LuaC._assert (funcstate.prev == null); - LuaC._assert (funcstate.f.nups == 0); - LuaC._assert (lexstate.fs == null); - return funcstate.f; - } - - public LString newlstr(char[] chars, int offset, int len) { - return newTString( LString.valueOf( new String(chars,offset,len) ) ); - } - - public LString newTString(LString s) { - LString t = (LString) strings.get(s); - if ( t == null ) { - t = LString.newStringCopy(s); - strings.put( t, t ); - } - return t; - } - - public String pushfstring(String string) { - return string; - } - -} diff --git a/src/core/org/luaj/lib/BaseLib.java b/src/core/org/luaj/lib/BaseLib.java deleted file mode 100644 index eefc57b1..00000000 --- a/src/core/org/luaj/lib/BaseLib.java +++ /dev/null @@ -1,504 +0,0 @@ -/** - * - */ -package org.luaj.lib; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintStream; - -import org.luaj.vm.CallInfo; -import org.luaj.vm.LClosure; -import org.luaj.vm.LFunction; -import org.luaj.vm.LNil; -import org.luaj.vm.LString; -import org.luaj.vm.LTable; -import org.luaj.vm.LValue; -import org.luaj.vm.Lua; -import org.luaj.vm.LuaState; -import org.luaj.vm.Platform; - - - -public class BaseLib extends LFunction { - - public static InputStream STDIN = null; - public static PrintStream STDOUT = System.out; - - private static final String[] NAMES = { - "base", - "print", - "pairs", - "getmetatable", - "setmetatable", - "type", - "pcall", - "ipairs", - "error", - "assert", - "loadfile", - "tonumber", - "rawequal", - "rawget", - "rawset", - "getfenv", - "setfenv", - "select", - "collectgarbage", - "dofile", - "loadstring", - "load", - "tostring", - "unpack", - "xpcall", - "next", - "_inext", // not public - }; - - private static final int INSTALL = 0; - private static final int PRINT = 1; - private static final int PAIRS = 2; - private static final int GETMETATABLE = 3; - private static final int SETMETATABLE = 4; - private static final int TYPE = 5; - private static final int PCALL = 6; - private static final int IPAIRS = 7; - private static final int ERROR = 8; - private static final int ASSERT = 9; - private static final int LOADFILE = 10; - private static final int TONUMBER = 11; - private static final int RAWEQUAL = 12; - private static final int RAWGET = 13; - private static final int RAWSET = 14; - private static final int GETFENV = 15; - private static final int SETFENV = 16; - private static final int SELECT = 17; - private static final int COLLECTGARBAGE = 18; - private static final int DOFILE = 19; - private static final int LOADSTRING = 20; - private static final int LOAD = 21; - private static final int TOSTRING = 22; - private static final int UNPACK = 23; - private static final int XPCALL = 24; - private static final int NEXT = 25; - private static final int INEXT = 26; - - private static LFunction next; - private static LFunction inext; - - public static void install(LTable globals) { - for ( int i=1, n=NAMES.length; i 1 ) - STDOUT.print( "\t" ); - STDOUT.print( vm.tostring(-1) ); - vm.poplvalue(); - } - STDOUT.println(); - return 0; - } - case IPAIRS: { - LTable t = vm.checktable(1); - vm.pushfunction( inext ); - vm.pushlvalue( t ); - vm.pushinteger( 0 ); - return 3; - } - case PAIRS: { - LTable t = vm.checktable(1); - vm.pushfunction( next ); - vm.pushlvalue( t ); - vm.pushnil(); - return 3; - } - case INEXT: { - int i = vm.checkint(2) + 1; - LTable t = vm.checktable(1); - LValue v = t.get(i); - if ( !v.isNil() ) { - vm.pushinteger(i); - vm.pushlvalue(v); - return 2; - } - return 0; - } - case NEXT: { - LTable t = vm.checktable(1); - LValue k = vm.topointer(2); - vm.resettop(); - t.next(vm,k,false); - return -1; - } - case GETMETATABLE: { - vm.checkany(1); - if ( ! vm.getmetatable(1) ) { - vm.pushnil(); - return 1; - } else { - vm.getfield(-1,LValue.TM_METATABLE); - if ( vm.isnil(-1) ) - vm.pop(1); - } - return 1; - } - case SETMETATABLE: { - LTable t = vm.checktable(1); - LValue v = vm.checkany(2); - vm.argcheck(v.isTable() || v.isNil(), 2, "table or nil expected"); - t = t.luaSetMetatable(v); - vm.pushlvalue(t); - return 1; - } - case TYPE: { - LValue v = vm.checkany(1); - vm.pushlstring( v.luaGetTypeName() ); - return 1; - } - case PCALL: { - vm.checkany(1); - int n = vm.gettop(); - int s = vm.pcall( n-1, Lua.LUA_MULTRET ); - if ( s == 0 ) { // success, results are on stack - vm.pushboolean( true ); - vm.insert( 1 ); - return -1; - } else { // error, error message is on the stack - vm.pushboolean( false ); - vm.insert( -2 ); - return 2; - } - } - case XPCALL: { - LValue errfun = vm.checkany(2); - vm.settop(1); - int s = vm.xpcall( 0, Lua.LUA_MULTRET, errfun ); - if ( s == 0 ) { // success, results are on stack - vm.pushboolean( true ); - vm.insert( 1 ); - return -1; - } else { // error, error message is on the stack - vm.pushboolean( false ); - vm.insert( 1 ); - return 2; - } - } - case ERROR: { - vm.error(vm.optstring(1,null), vm.optint(2,-1)); - return 0; - } - case ASSERT: { - if ( ! vm.toboolean(1) ) - vm.error( vm.optstring(2,"assertion failed!") ); - return -1; - } - - case LOADFILE: - loadfile(vm, vm.optstring(1,null)); - return -1; - - case TONUMBER: { - int base = vm.optint(2, 10); - if (base == 10) { /* standard conversion */ - vm.checkany(1); - LValue v = vm.tolnumber(1); - vm.pushlvalue(v); - return 1; - } else { - if ( base < 2 || base > 36 ) - vm.argerror(2, "base out of range"); - LString s = vm.checklstring(1); - vm.pushlvalue( s.luaToNumber(base) ); - return 1; - } - } - case RAWEQUAL: { - LValue a = vm.checkany(1); - LValue b = vm.checkany(2); - vm.pushboolean(a == b); - return 1; - } - case RAWGET: { - LTable t = vm.checktable(1); - LValue k = vm.checkany(2); - vm.pushlvalue( t.get( k ) ); - return 1; - } - case RAWSET: { - LTable t = vm.checktable(1); - LValue k = vm.checkany(2); - LValue v = vm.checkany(3); - t.put( k, v ); - vm.pushlvalue(t); - return 1; - } - case GETFENV: { - LValue f = getfunc(vm, true); - vm.pushlvalue(f.luaGetEnv(vm._G)); - return 1; - } - case SETFENV: { - LTable t = vm.checktable(2); - if ( vm.isnumber(1) && vm.tointeger(1) == 0 ) { - vm._G = t; - } else { - LValue f = getfunc(vm, false); - if ( (!(f instanceof LClosure)) || ! f.luaSetEnv(t) ) - vm.error( "'setfenv' cannot change environment of given object" ); - vm.pushlvalue(f); - return 1; - } - } - case SELECT: { - vm.checkany(1); - int n = vm.gettop(); - if ( vm.isnumber(1) ) { - int index = vm.tolnumber(1).toJavaInt(); - if ( index < 0 ) - index += n; - if ( index <= 0 ) - vm.argerror( 1, "index out of range" ); - if ( index >= n ) - return 0; - else { - return n-index; - } - } else if ( vm.checkstring(1).equals( "#" ) ) { - vm.pushnumber( n - 1 ); - return 1; - } else { - vm.typerror(1,"expected number or '#'"); - return 0; - } - } - case COLLECTGARBAGE: { - String s = vm.optstring(1, "collect"); - int result = 0; - if ( "collect".equals(s) ) - System.gc(); - else if ( "count".equals(s) ) { - Runtime rt = Runtime.getRuntime(); - long used = rt.totalMemory() - rt.freeMemory(); - result = (int) (used >> 10); - } else { - vm.argerror(2,"gc op"); - } - vm.pushnumber(result); - return 1; - } - case DOFILE: - dofile(vm); - return -1; - case LOADSTRING: - loadstring(vm, vm.checklstring(1), vm.optstring(2,"(string)")); - return -1; - case LOAD: - load(vm); - return -1; - case TOSTRING: { - LValue v = vm.checkany(1); - vm.pushlvalue( v.luaAsString() ); - return 1; - } - case UNPACK: { - LTable list = vm.checktable(1); - int n = vm.gettop(); - int i = vm.optint(2,1); - int j; - if ( n >= 3 ) { - j = vm.checkint(3); - } else { - j = list.luaLength(); - } - vm.resettop(); - vm.checkstack(j+1-i); - for ( int k=i; k<=j; k++ ) - vm.pushlvalue(list.get(k)); - return -1; - } - default: - LuaState.vmerror( "bad base id" ); - return 0; - } - } - - private static LValue getfunc (LuaState vm, boolean opt) { - if ( vm.isfunction(1) ) - return vm.tofunction(1); - else { - int level = opt? vm.optint(1, 1): vm.checkint(1); - vm.argcheck(level >= 0, 1, "level must be non-negative"); - vm.argcheck(level-1 <= vm.cc, 1, "invalid level"); - CallInfo ci = vm.getStackFrame(level-1); - if ( ci == null || ci.closure == null ) - return LNil.NIL; - return ci.closure; - } - } - - - public static void redirectOutput( OutputStream newStdOut ) { - STDOUT = new PrintStream( newStdOut ); - } - - public static void restoreStandardOutput() { - STDOUT = System.out; - } - - // closes the input stream, provided its not null or System.in - private static void closeSafely(InputStream is) { - try { - if ( is != null && is != STDIN ) - is.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - // closes the output stream, provided its not null or STDOUT - private static void closeSafely(OutputStream os) { - try { - if ( os != null && os != STDOUT ) - os.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - // return true if loaded, false if error put onto the stack - /** Load a chunk from an input stream, leaving it on the stack if successful, - * then close the input stream if it is not STDIN - * - * @param vm LuaState to load into - * @param is input stream to load from - * @return true if loaded and only item on stack, false if nil+error put onto stack - */ - static boolean loadis(LuaState vm, InputStream is, String chunkname ) { - try { - vm.resettop(); - if ( 0 != vm.load(is, chunkname) ) { - setErrorResult( vm, "cannot load "+chunkname+": "+vm.topointer(-1) ); - return false; - } else { - return true; - } - } finally { - closeSafely( is ); - } - } - - - /** Load a file into a chunk given a filename, leaving it on the stack if successful - * - * @param vm LuaState to load into - * @param fileName file to load, or null to use STDIN - * @return true if loaded and only item on stack, false if nil+error put onto stack - */ - private static boolean loadfile( LuaState vm, String fileName ) { - InputStream is; - - String script; - if ( fileName != null ) { - script = fileName; - is = Platform.getInstance().openFile(fileName); - if ( is == null ) { - setErrorResult( vm, "cannot open "+fileName+": No such file or directory" ); - return false; - } - } else { - is = STDIN != null? STDIN: new ByteArrayInputStream(new byte[0]); - script = "-"; - } - - // use vm to load the script - return loadis( vm, is, script ); - } - - // if load succeeds, return 0 for success, 1 for error (as per lua spec) - private void dofile( LuaState vm ) { - String filename = vm.optstring(1,null); - if ( loadfile( vm, filename ) ) { - vm.call(0, 0); - } else { - vm.error( vm.tostring(-1) ); - } - } - - // return true if loaded, false if error put onto stack - private boolean loadstring(LuaState vm, LString string, String chunkname) { - return loadis( vm, string.toInputStream(), chunkname ); - } - - // return true if loaded, false if error put onto stack - private boolean load(LuaState vm) { - LFunction chunkPartLoader = vm.checkfunction(2); - String chunkname = vm.optstring(3,"=(load)"); - - // load all the parts - LClosure c = (LClosure) chunkPartLoader; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - while ( true ) { - setResult(vm,c); - if ( 0 != vm.pcall(0, 1) ) { - setErrorResult(vm, vm.tostring(2)); - return false; - } - LValue v = vm.topointer(2); - if ( v.isNil() ) - break; - LString s = v.luaAsString(); - s.write(baos, 0, s.length()); - } - - // load the chunk - return loadis( vm, new ByteArrayInputStream( baos.toByteArray() ), chunkname ); - - } catch (IOException ioe) { - setErrorResult(vm, ioe.getMessage()); - return false; - } finally { - closeSafely( baos ); - } - } -} diff --git a/src/core/org/luaj/lib/CoroutineLib.java b/src/core/org/luaj/lib/CoroutineLib.java deleted file mode 100644 index 6f465810..00000000 --- a/src/core/org/luaj/lib/CoroutineLib.java +++ /dev/null @@ -1,141 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.lib; - -import org.luaj.vm.LFunction; -import org.luaj.vm.LTable; -import org.luaj.vm.LThread; -import org.luaj.vm.LuaState; - -public class CoroutineLib extends LFunction { - - private static final String[] NAMES = { - "install", - "create", - "resume", - "running", - "status", - "wrap", - "yield", - "wrapped" - }; - - private static final int INSTALL = 0; - private static final int CREATE = 1; - private static final int RESUME = 2; - private static final int RUNNING = 3; - private static final int STATUS = 4; - private static final int WRAP = 5; - private static final int YIELD = 6; - private static final int WRAPPED = 7; - - public static void install( LTable globals ) { - LTable lib = new LTable(0,6); - for ( int i=1; i<=YIELD; i++ ) - lib.put(NAMES[i], new CoroutineLib(i)); - globals.put("coroutine",lib); - PackageLib.setIsLoaded("coroutine", lib); - } - - private final int id; - private final LThread thread; - - public CoroutineLib() { - this.id = 0; - this.thread = null; - } - - private CoroutineLib( int id ) { - this.id = id; - this.thread = null; - } - - public String toString() { - return NAMES[id]+"()"; - } - - private CoroutineLib( int id, LThread thread ) { - this.id = id; - this.thread = thread; - } - - public int invoke( LuaState vm ) { - switch ( id ) { - case INSTALL: { - install(vm._G); - return 0; - } - case CREATE: { - LFunction c = vm.checkfunction(1); - vm.pushlvalue( new LThread( c, c.luaGetEnv(vm._G) ) ); - return 1; - } - case RESUME: { - LThread t = vm.checkthread(1); - t.resumeFrom( vm, vm.gettop()-1 ); - return -1; - } - case RUNNING: { - LThread r = LThread.getRunning(); - if ( r != null ) { - vm.pushlvalue( r ); - } else { - vm.pushnil(); - } - return 1; - } - case STATUS: { - vm.pushstring( vm.checkthread(1).getStatus() ); - return 1; - } - case WRAP: { - LFunction c = vm.checkfunction(1); - vm.pushlvalue( new CoroutineLib(WRAPPED,new LThread(c, c.luaGetEnv(vm._G))) ); - return 1; - } - case YIELD: { - LThread r = LThread.getRunning(); - if ( r == null ) { - vm.error("main thread can't yield"); - return 0; - } - r.yield(); - return -1; - } - case WRAPPED: { - LThread t = this.thread; - t.resumeFrom( vm, vm.gettop() ); - if ( vm.toboolean(1) ) { - vm.remove(1); - return -1; - } else { - vm.error( vm.tostring(2) ); - return 0; - } - } - default: { - LuaState.vmerror( "bad coroutine id" ); - return 0; - } - } - } -} diff --git a/src/core/org/luaj/lib/DebugLib.java b/src/core/org/luaj/lib/DebugLib.java deleted file mode 100644 index 2c6e8d96..00000000 --- a/src/core/org/luaj/lib/DebugLib.java +++ /dev/null @@ -1,824 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2009 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.lib; - - -import org.luaj.vm.CallInfo; -import org.luaj.vm.LBoolean; -import org.luaj.vm.LClosure; -import org.luaj.vm.LFunction; -import org.luaj.vm.LInteger; -import org.luaj.vm.LNil; -import org.luaj.vm.LPrototype; -import org.luaj.vm.LString; -import org.luaj.vm.LTable; -import org.luaj.vm.LValue; -import org.luaj.vm.Lua; -import org.luaj.vm.LuaErrorException; -import org.luaj.vm.LuaState; -import org.luaj.vm.UpVal; - -public class DebugLib extends LFunction { - - private static final String[] NAMES = { - "debuglib", - "debug", - "getfenv", - "gethook", - "getinfo", - "getlocal", - "getmetatable", - "getregistry", - "getupvalue", - "setfenv", - "sethook", - "setlocal", - "setmetatable", - "setupvalue", - "traceback", - }; - - private static final int INSTALL = 0; - private static final int DEBUG = 1; - private static final int GETFENV = 2; - private static final int GETHOOK = 3; - private static final int GETINFO = 4; - private static final int GETLOCAL = 5; - private static final int GETMETATABLE = 6; - private static final int GETREGISTRY = 7; - private static final int GETUPVALUE = 8; - private static final int SETFENV = 9; - private static final int SETHOOK = 10; - private static final int SETLOCAL = 11; - private static final int SETMETATABLE = 12; - private static final int SETUPVALUE = 13; - private static final int TRACEBACK = 14; - - /* maximum stack for a Lua function */ - private static final int MAXSTACK = 250; - - private static final LString LUA = new LString("Lua"); - private static final LString JAVA = new LString("Java"); - private static final LString JAVASRC = new LString("[Java]"); - private static final LString QMARK = new LString("?"); - private static final LString GLOBAL = new LString("global"); - private static final LString LOCAL = new LString("local"); - private static final LString METHOD = new LString("method"); - private static final LString UPVALUE = new LString("upvalue"); - private static final LString FIELD = new LString("field"); - private static final LString NOSTRING = new LString(""); - - public static void install( LuaState vm ) { - LTable debug = new LTable(); - for (int i = 1; i < NAMES.length; i++) - debug.put(NAMES[i], new DebugLib(i)); - vm._G.put("debug", debug); - PackageLib.setIsLoaded("debug", debug); - } - - private final int id; - - public DebugLib() { - this.id = INSTALL; - } - - private DebugLib( int id ) { - this.id = id; - } - - public String toString() { - return NAMES[id]+"()"; - } - - public int invoke( LuaState vm ) { - switch ( id ) { - case INSTALL: - install(vm); - return 0; - case DEBUG: - return debug(vm); - case GETFENV: - return getfenv(vm); - case GETHOOK: - return gethook(vm); - case GETINFO: - return getinfo(vm); - case GETLOCAL: - return getlocal(vm); - case GETMETATABLE: - return getmetatable(vm); - case GETREGISTRY: - return getregistry(vm); - case GETUPVALUE: - return getupvalue(vm); - case SETFENV: - return setfenv(vm); - case SETHOOK: - return sethook(vm); - case SETLOCAL: - return setlocal(vm); - case SETMETATABLE: - return setmetatable(vm); - case SETUPVALUE: - return setupvalue(vm); - case TRACEBACK: - return traceback(vm); - default: - LuaState.vmerror( "bad package id" ); - return 0; - } - } - - // j2se subclass may wish to override and provide actual console here. - // j2me platform has not System.in to provide console. - protected int debug(LuaState vm) { - return 0; - } - - protected int gethook(LuaState vm) { - LuaState threadVm = optthreadvm(vm, 1); - LValue hook = threadVm.gethook(); - int mask = threadVm.gethookmask(); - int count = threadVm.gethookcount(); - vm.pushlvalue(hook!=null? hook: LNil.NIL); - vm.pushstring("" - +((mask&LuaState.LUA_MASKCALL)!=0? "c": "") - +((mask&LuaState.LUA_MASKRET) !=0? "r": "") - +((mask&LuaState.LUA_MASKLINE)!=0? "l": "")); - vm.pushinteger(count); - return 3; - } - - protected LuaState optthreadvm(LuaState vm, int index) { - if ( ! vm.isthread(index) ) - return vm; - LuaState threadVm = vm.checkthread(index).vm; - vm.remove(index); - return threadVm; - } - - protected int sethook(LuaState vm) { - LuaState threadVm = optthreadvm(vm, 1); - LFunction func = vm.isnoneornil(1)? null: vm.checkfunction(1); - String str = vm.optstring(2,""); - int count = vm.optint(3,0); - int mask = 0; - for ( int i=0; i= 0 ) - lines.put(1, LInteger.valueOf(line)); - } - break; - } - } - } - return 1; - } - - protected int getlocal(LuaState vm) { - LuaState threadVm = optthreadvm(vm, 1); - int level = vm.checkint(1); - int local = vm.checkint(2); - StackInfo si = getstackinfo(threadVm, level, 1)[0]; - CallInfo ci = (si!=null? si.luainfo: null); - LPrototype p = (ci!=null? ci.closure.p: null); - LString name = (p!=null? p.getlocalname(local, ci.currentpc()): null); - if ( name != null ) { - LValue value = threadVm.stack[ci.base+(local-1)]; - vm.pushlvalue( name ); - vm.pushlvalue( value ); - return 2; - } else { - vm.pushnil(); - return 1; - } - } - - protected int setlocal(LuaState vm) { - LuaState threadVm = optthreadvm(vm, 1); - int level = vm.checkint(1); - int local = vm.checkint(2); - LValue value = vm.topointer(3); - StackInfo si = getstackinfo(threadVm, level, 1)[0]; - CallInfo ci = (si!=null? si.luainfo: null); - LPrototype p = (ci!=null? ci.closure.p: null); - LString name = (p!=null? p.getlocalname(local, ci.currentpc()): null); - if ( name != null ) { - threadVm.stack[ci.base+(local-1)] = value; - vm.pushlvalue( name ); - } else { - vm.pushnil(); - } - return 1; - } - - protected int getmetatable(LuaState vm) { - LValue object = vm.topointer(1); - LValue mt = object.luaGetMetatable(); - if ( mt != null ) - vm.pushlvalue( object.luaGetMetatable() ); - else - vm.pushnil(); - return 1; - } - - protected int setmetatable(LuaState vm) { - LValue object = vm.topointer(1); - try { - if ( ! vm.isnoneornil(2) ) - object.luaSetMetatable(vm.checktable(3)); - else - object.luaSetMetatable(null); - vm.pushboolean(true); - return 1; - } catch ( LuaErrorException e ) { - vm.pushboolean(false); - vm.pushstring(e.toString()); - return 2; - } - } - - protected int getregistry(LuaState vm) { - vm.pushlvalue( new LTable() ); - return 1; - } - - private static LString findupvalue(LClosure c, int up) { - if ( c.upVals != null && up > 0 && up <= c.upVals.length ) { - if ( c.p.upvalues != null && up <= c.p.upvalues.length ) - return c.p.upvalues[up-1]; - else - return new LString( "."+up+"" ); - } - return null; - } - - protected int getupvalue(LuaState vm) { - LFunction func = vm.checkfunction(1); - int up = vm.checkint(2); - vm.resettop(); - if ( func.isClosure() ) { - LClosure c = (LClosure) func; - LString name = findupvalue(c, up); - if ( name != null ) { - vm.pushlstring(name); - vm.pushlvalue(c.upVals[up-1].getValue()); - return 2; - } - } - vm.pushnil(); - return 1; - } - - protected int setupvalue(LuaState vm) { - LFunction func = vm.checkfunction(1); - int up = vm.checkint(2); - LValue value = vm.topointer(3); - vm.resettop(); - if ( func instanceof LClosure ) { - LClosure c = (LClosure) func; - LString name = findupvalue(c, up); - if ( name != null ) { - c.upVals[up-1].setValue(value); - vm.pushlstring(name); - return 1; - } - } - vm.pushnil(); - return 1; - } - - protected int traceback(LuaState vm) { - LuaState threadVm = optthreadvm(vm, 1); - String message = "stack traceback:\n"; - int level = vm.optint(2,1); - if ( ! vm.isnoneornil(1) ) - message = vm.checkstring(1)+"\n"; - String tb = DebugLib.traceback(threadVm, level); - vm.pushstring(message+tb); - return 1; - } - - // =================== public utilities ==================== - - /** - * @param callinfo the CallInfo to inspect - * @param up the 1-based index of the local - * @return { name, value } or null if not found. - */ - public static LValue[] getlocal(LuaState vm, CallInfo ci, int local) { - LPrototype p = (ci!=null? ci.closure.p: null); - LString name = (p!=null? p.getlocalname(local, ci.currentpc()): null); - if ( name != null ) { - LValue value = vm.stack[ci.base+(local-1)]; - return new LValue[] { name, value }; - } else { - return null; - } - } - - /** - * @param c the LClosure to inspect - * @param up the 1-based index of the upvalue - * @return { name, value, isclosed } or null if not found. - */ - public static LValue[] getupvalue(LClosure c, int up) { - LString name = findupvalue(c, up); - if ( name != null ) { - UpVal u = c.upVals[up-1]; - LValue value = u.getValue(); - boolean isclosed = u.isClosed(); - return new LValue[] { name, value, LBoolean.valueOf(isclosed) }; - } - return null; - } - - /** - * Get a traceback as a string for an arbitrary LuaState - */ - public static String traceback(LuaState vm, int level) { - StackInfo[] s = getstackinfo(vm, level, 10); - StringBuffer sb = new StringBuffer(); - for ( int i=0; i=0? getobjname(vm, caller, stackpos): null); - } - public int currentline() { - return luainfo!=null? luainfo.currentline(): -1; - } - public String tracename() { - if ( caller == null ) - return "main chunk"; - if ( func != null ) - return func.toString(); - LString[] kind = getfunckind(); - if ( kind == null ) - return "function ?"; - return "function "+kind[0].toJavaString(); - } - } - - - /** - * @param level first level to report - * @return array StackInfo with countlevels items, some may be null! - */ - private static StackInfo[] getstackinfo(LuaState vm, int level, int countlevels) { - StackInfo[] si = new StackInfo[countlevels]; - int i = 0; - LClosure prevclosure = null; - for (int j=vm.cc; j>=0; --j) { - - CallInfo ci = vm.calls[j]; - LFunction f = ci.currentfunc(vm); - - // java, or tailcall? - if ( f != null && (! f.isClosure() || f!=prevclosure) ) { - if ( (level--) <= 0 ) { - si[i++] = new StackInfo( vm, ci, ci.currentfunca(vm), null, f); - if ( i >= countlevels ) - return si; - } - } - - // add the lua closure - if ( (level--) <= 0 ) { - if (j>0 && vm.calls[j-1].currentfunc(vm) == ci.closure) { - CallInfo caller = vm.calls[j-1]; - int callera = caller.currentfunca(vm); - si[i++] = new StackInfo( vm, caller, callera, ci, ci.closure); - } else { - si[i++] = new StackInfo( vm, null, -1, ci, ci.closure); - } - if ( i >= countlevels ) - return si; - } - prevclosure = ci.closure; - } - - return si; - } - - // look up a function in the stack, if it exists - private static StackInfo findstackinfo(LuaState vm, LFunction func) { - for (int j=vm.cc; j>=0; --j) { - CallInfo ci = vm.calls[j]; - int instr = ci.closure.p.code[ci.currentpc()]; - if ( Lua.GET_OPCODE(instr) == Lua.OP_CALL ) { - int a = Lua.GETARG_A(instr); - if ( func == vm.stack[ci.base + a] ) - return new StackInfo(vm, ci, a, null, func); - if ( func == ci.closure ) - return new StackInfo(vm, (j>0? vm.calls[j-1]: null), 0, ci, null); - } - } - return new StackInfo(vm, null, -1, null, func); - } - - // return LString[] { name, namewhat } if found, null if not - private static LString[] getobjname(LuaState L, CallInfo ci, int stackpos) { - LString name; - if (ci.isLua()) { /* a Lua function? */ - LPrototype p = ci.closure.p; - int pc = (ci.pc > 0 ? ci.pc - 1 : 0); // currentpc(L, ci); - int i;// Instruction i; - name = p.getlocalname(stackpos + 1, pc); - if (name != null) /* is a local? */ - return new LString[] { name, LOCAL }; - i = symbexec(p, pc, stackpos); /* try symbolic execution */ - lua_assert(pc != -1); - switch (Lua.GET_OPCODE(i)) { - case Lua.OP_GETGLOBAL: { - int g = Lua.GETARG_Bx(i); /* global index */ - // lua_assert(p.k[g].isString()); - return new LString[] { p.k[g].luaAsString(), GLOBAL }; - } - 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(L, ci, b); /* get name for `b' */ - break; - } - case Lua.OP_GETTABLE: { - int k = Lua.GETARG_C(i); /* key index */ - name = kname(p, k); - return new LString[] { name, FIELD }; - } - case Lua.OP_GETUPVAL: { - int u = Lua.GETARG_B(i); /* upvalue index */ - name = u < p.upvalues.length ? p.upvalues[u] : QMARK; - return new LString[] { name, UPVALUE }; - } - case Lua.OP_SELF: { - int k = Lua.GETARG_C(i); /* key index */ - name = kname(p, k); - return new LString[] { name, METHOD }; - } - default: - break; - } - } - return null; /* no useful name found */ - } - - private static LString kname(LPrototype p, int c) { - if (Lua.ISK(c) && p.k[Lua.INDEXK(c)].isString()) - return p.k[Lua.INDEXK(c)].luaAsString(); - else - return QMARK; - } - - private static boolean checkreg(LPrototype pt,int reg) { - return (reg < pt.maxstacksize); - } - - private static boolean precheck(LPrototype pt) { - if (!(pt.maxstacksize <= MAXSTACK)) return false; - lua_assert(pt.numparams + (pt.is_vararg & Lua.VARARG_HASARG) <= pt.maxstacksize); - lua_assert((pt.is_vararg & Lua.VARARG_NEEDSARG) == 0 - || (pt.is_vararg & Lua.VARARG_HASARG) != 0); - if (!(pt.upvalues.length <= pt.nups)) return false; - if (!(pt.lineinfo.length == pt.code.length || pt.lineinfo.length == 0)) return false; - if (!(Lua.GET_OPCODE(pt.code[pt.code.length - 1]) == Lua.OP_RETURN)) return false; - return true; - } - - private static boolean checkopenop(LPrototype pt,int pc) { - int i = pt.code[(pc)+1]; - switch (Lua.GET_OPCODE(i)) { - case Lua.OP_CALL: - case Lua.OP_TAILCALL: - case Lua.OP_RETURN: - case Lua.OP_SETLIST: { - if (!(Lua.GETARG_B(i) == 0)) return false; - return true; - } - default: - return false; /* invalid instruction after an open call */ - } - } - - //static int checkArgMode (LPrototype pt, int r, enum OpArgMask mode) { - private static boolean checkArgMode (LPrototype pt, int r, int mode) { - switch (mode) { - case Lua.OpArgN: if (!(r == 0)) return false; break; - case Lua.OpArgU: break; - case Lua.OpArgR: checkreg(pt, r); break; - case Lua.OpArgK: - if (!(Lua.ISK(r) ? Lua.INDEXK(r) < pt.k.length : r < pt.maxstacksize)) return false; - break; - } - return true; - } - - - // return last instruction, or 0 if error - private static int symbexec(LPrototype pt, int lastpc, int reg) { - int pc; - int last; /* stores position of last instruction that changed `reg' */ - last = pt.code.length - 1; /* - * points to final return (a `neutral' - * instruction) - */ - if (!(precheck(pt))) return 0; - for (pc = 0; pc < lastpc; pc++) { - int i = pt.code[pc]; - int op = Lua.GET_OPCODE(i); - int a = Lua.GETARG_A(i); - int b = 0; - int c = 0; - if (!(op < Lua.NUM_OPCODES)) return 0; - if (!checkreg(pt, a)) return 0; - switch (Lua.getOpMode(op)) { - case Lua.iABC: { - b = Lua.GETARG_B(i); - c = Lua.GETARG_C(i); - if (!(checkArgMode(pt, b, Lua.getBMode(op)))) return 0; - if (!(checkArgMode(pt, c, Lua.getCMode(op)))) return 0; - break; - } - case Lua.iABx: { - b = Lua.GETARG_Bx(i); - if (Lua.getBMode(op) == Lua.OpArgK) - if (!(b < pt.k.length)) return 0; - break; - } - case Lua.iAsBx: { - b = Lua.GETARG_sBx(i); - if (Lua.getBMode(op) == Lua.OpArgR) { - int dest = pc + 1 + b; - if (!(0 <= dest && dest < pt.code.length)) return 0; - if (dest > 0) { - /* cannot jump to a setlist count */ - int d = pt.code[dest - 1]; - if ((Lua.GET_OPCODE(d) == Lua.OP_SETLIST && Lua.GETARG_C(d) == 0)) return 0; - } - } - break; - } - } - if (Lua.testAMode(op)) { - if (a == reg) - last = pc; /* change register `a' */ - } - if (Lua.testTMode(op)) { - if (!(pc + 2 < pt.code.length)) return 0; /* check skip */ - if (!(Lua.GET_OPCODE(pt.code[pc + 1]) == Lua.OP_JMP)) return 0; - } - switch (op) { - case Lua.OP_LOADBOOL: { - if (!(c == 0 || pc + 2 < pt.code.length)) return 0; /* check its jump */ - break; - } - case Lua.OP_LOADNIL: { - if (a <= reg && reg <= b) - last = pc; /* set registers from `a' to `b' */ - break; - } - case Lua.OP_GETUPVAL: - case Lua.OP_SETUPVAL: { - if (!(b < pt.nups)) return 0; - break; - } - case Lua.OP_GETGLOBAL: - case Lua.OP_SETGLOBAL: { - if (!(pt.k[b].isString())) return 0; - break; - } - case Lua.OP_SELF: { - if (!checkreg(pt, a + 1)) return 0; - if (reg == a + 1) - last = pc; - break; - } - case Lua.OP_CONCAT: { - if (!(b < c)) return 0; /* at least two operands */ - break; - } - case Lua.OP_TFORLOOP: { - if (!(c >= 1)) return 0; /* at least one result (control variable) */ - if (!checkreg(pt, a + 2 + c)) return 0; /* space for results */ - if (reg >= a + 2) - last = pc; /* affect all regs above its base */ - break; - } - case Lua.OP_FORLOOP: - case Lua.OP_FORPREP: - if (!checkreg(pt, a + 3)) return 0; - /* go through */ - case Lua.OP_JMP: { - int dest = pc + 1 + b; - /* not full check and jump is forward and do not skip `lastpc'? */ - if (reg != Lua.NO_REG && pc < dest && dest <= lastpc) - pc += b; /* do the jump */ - break; - } - case Lua.OP_CALL: - case Lua.OP_TAILCALL: { - if (b != 0) { - if (!checkreg(pt, a + b - 1)) return 0; - } - c--; /* c = num. returns */ - if (c == Lua.LUA_MULTRET) { - if (!(checkopenop(pt, pc))) return 0; - } else if (c != 0) - if (!checkreg(pt, a + c - 1)) return 0; - if (reg >= a) - last = pc; /* affect all registers above base */ - break; - } - case Lua.OP_RETURN: { - b--; /* b = num. returns */ - if (b > 0) - if (!checkreg(pt, a + b - 1)) return 0; - break; - } - case Lua.OP_SETLIST: { - if (b > 0) - if (!checkreg(pt, a + b)) return 0; - if (c == 0) - pc++; - break; - } - case Lua.OP_CLOSURE: { - int nup, j; - if (!(b < pt.p.length)) return 0; - nup = pt.p[b].nups; - if (!(pc + nup < pt.code.length)) return 0; - for (j = 1; j <= nup; j++) { - int op1 = Lua.GET_OPCODE(pt.code[pc + j]); - if (!(op1 == Lua.OP_GETUPVAL || op1 == Lua.OP_MOVE)) return 0; - } - if (reg != Lua.NO_REG) /* tracing? */ - pc += nup; /* do not 'execute' these pseudo-instructions */ - break; - } - case Lua.OP_VARARG: { - if (!((pt.is_vararg & Lua.VARARG_ISVARARG) != 0 - && (pt.is_vararg & Lua.VARARG_NEEDSARG) == 0)) return 0; - b--; - if (b == Lua.LUA_MULTRET) - if (!(checkopenop(pt, pc))) return 0; - if (!checkreg(pt, a + b - 1)) return 0; - break; - } - default: - break; - } - } - return pt.code[last]; - } - -} diff --git a/src/core/org/luaj/lib/IoLib.java b/src/core/org/luaj/lib/IoLib.java deleted file mode 100644 index 7804d713..00000000 --- a/src/core/org/luaj/lib/IoLib.java +++ /dev/null @@ -1,513 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2008 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.lib; - -import java.io.ByteArrayOutputStream; -import java.io.EOFException; -import java.io.IOException; - -import org.luaj.vm.LFunction; -import org.luaj.vm.LNil; -import org.luaj.vm.LString; -import org.luaj.vm.LTable; -import org.luaj.vm.LUserData; -import org.luaj.vm.LValue; -import org.luaj.vm.LuaState; - - -abstract -public class IoLib extends LFunction { - - protected interface File { - public void write( LString string ) throws IOException; - public void flush() throws IOException; - public boolean isstdfile(); - public void close() throws IOException; - public boolean isclosed(); - // returns new position - public int seek(String option, int bytecount) throws IOException; - public void setvbuf(String mode, int size); - // get length remaining to read - public int remaining() throws IOException; - // peek ahead one character - public int peek() throws IOException, EOFException; - // return char if read, -1 if eof, throw IOException on other exception - public int read() throws IOException, EOFException; - // return number of bytes read if positive, false if eof, throw IOException on other exception - public int read(byte[] bytes, int offset, int length) throws IOException; - } - - - /** - * Create a function stub with a specific index (factory method) - */ - abstract protected IoLib newInstance( int index ); - - /** - * 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; - - /** - * Open a file in a particular mode. - * @param filename - * @param 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; - - - public static final String[] NAMES = { - "io", - "__index", - "close", - "flush", - "input", - "lines", - "open", - "output", - "popen", - "read", - "tmpfile", - "type", - "write", - "close", - "flush", - "lines", - "read", - "seek", - "setvbuf", - "write", - }; - - private static final int INSTALL = 0; - private static final int IO_INDEX = 1; - private static final int IO_CLOSE = 2; - private static final int IO_FLUSH = 3; - private static final int IO_INPUT = 4; - private static final int IO_LINES = 5; - private static final int IO_OPEN = 6; - private static final int IO_OUTPUT = 7; - private static final int IO_POPEN = 8; - private static final int IO_READ = 9; - private static final int IO_TMPFILE = 10; - private static final int IO_TYPE = 11; - private static final int IO_WRITE = 12; - private static final int FILE_CLOSE = 13; - private static final int FILE_FLUSH = 14; - private static final int FILE_LINES = 15; - private static final int FILE_READ = 16; - private static final int FILE_SEEK = 17; - private static final int FILE_SETVBUF = 18; - private static final int FILE_WRITE = 19; - - private static File INPUT = null; - private static File OUTPUT = null; - private static File ERROR = null; - - private static LTable FILE_MT; - - protected void initialize( LTable globals ) { - LTable io = new LTable(); - for ( int i=IO_INDEX; i<=IO_WRITE; i++ ) - io.put(NAMES[i], newInstance(i)); - io.luaSetMetatable(io); - FILE_MT = new LTable(); - for ( int i=FILE_CLOSE; i<=FILE_WRITE; i++ ) - FILE_MT.put(NAMES[i], newInstance(i)); - FILE_MT.put("__index", FILE_MT); - INPUT = null; - OUTPUT = null; - ERROR = null; - globals.put( "io", io ); - PackageLib.setIsLoaded("io", io); - } - - private final int id; - - protected IoLib() { - id = 0; - } - - protected IoLib( int id ) { - this.id = id; - } - - public LString luaAsString() { - return new LString(toJavaString()); - } - - public String toJavaString() { - return "io."+toString(); - } - - public String toString() { - return NAMES[id]+"()"; - } - - private File input(LuaState vm) { - return INPUT!=null? INPUT: (INPUT=ioopenfile(vm,"-","r")); - } - - private File output(LuaState vm) { - return OUTPUT!=null? OUTPUT: (OUTPUT=ioopenfile(vm,"-","w")); - } - - private File error(LuaState vm) { - return ERROR!=null? ERROR: (ERROR=ioopenfile(vm,"-","w")); - } - - public LValue __index(LuaState vm, LValue table, LValue key) { - String k = key.toJavaString(); - if ( "stdout".equals(k) ) - return touserdata(output(vm)); - else if ( "stdin".equals(k) ) - return touserdata(input(vm)); - else if ( "stderr".equals(k) ) - return touserdata(error(vm)); - else - return LNil.NIL; - } - - public int invoke( LuaState vm ) { - File f; - int n; - try { - switch ( id ) { - /* Load the table library dynamically */ - case INSTALL: - initialize(vm._G); - return 0; - case IO_CLOSE: - f = vm.isnoneornil(1)? - output(vm): - checkfile(vm,1); - checkopen(vm, f); - ioclose(vm,f); - break; - case IO_FLUSH: - checkopen(vm,output(vm)); - OUTPUT.flush(); - vm.pushboolean(true); - return 1; - case IO_INPUT: - INPUT = vm.isnoneornil(1)? - input(vm): - vm.isstring(1)? - ioopenfile(vm,vm.checkstring(1),"r"): - checkfile(vm,1); - setresult(vm, INPUT); - break; - case IO_LINES: - INPUT = vm.isnoneornil(1)? - input(vm): - ioopenfile(vm,vm.checkstring(1),"r"); - checkopen(vm, INPUT); - vm.pushlvalue(lines(vm,INPUT)); - return 1; - case IO_OPEN: - setresult(vm, rawopenfile(vm.checkstring(1), vm.optstring(2,"r"))); - break; - case IO_OUTPUT: - OUTPUT = vm.isnoneornil(1)? - output(vm): - vm.isstring(1)? - ioopenfile(vm,vm.checkstring(1),"w"): - checkfile(vm,1); - setresult(vm, OUTPUT); - break; - case IO_POPEN: - setresult(vm, openProgram(vm.checkstring(1),vm.optstring(2, "r"))); - break; - case IO_READ: - checkopen(vm, INPUT); - ioread( vm, INPUT ); - break; - case IO_TMPFILE: - setresult(vm, tmpFile()); - break; - case IO_TYPE: - f = optfile(vm,1); - if ( f != null ) - vm.pushstring(f.isclosed()? "closed file": "file"); - else - vm.pushnil(); - return 1; - case IO_WRITE: - checkopen(vm, output(vm)); - iowrite( vm, OUTPUT ); - break; - case FILE_CLOSE: - f = checkfile(vm,1); - ioclose(vm, f); - break; - case FILE_FLUSH: - f = checkfile(vm,1); - f.flush(); - vm.pushboolean(true); - return 1; - case FILE_LINES: - f = checkfile(vm,1); - vm.pushlvalue(lines(vm,f)); - return 1; - case FILE_READ: - f = checkfile(vm,1); - vm.remove(1); - ioread(vm, f); - break; - case FILE_SEEK: - f = checkfile(vm,1); - vm.remove(1); - n = f.seek(vm.optstring(1,"cur"),vm.optint(2, 0)); - vm.pushinteger(n); - return 1; - case FILE_SETVBUF: - f = checkfile(vm,1); - vm.remove(1); - f.setvbuf(vm.checkstring(1),vm.optint(2, 1024)); - vm.pushboolean(true); - return 1; - case FILE_WRITE: - f = checkfile(vm,1); - vm.remove(1); - iowrite( vm, f ); - break; - default: - LuaState.vmerror( "bad io id" ); - } - } catch ( IOException ioe ) { - seterrorresult(vm,ioe); - } - return -1; - } - - private static void ioclose(LuaState vm, File f) throws IOException { - if ( f.isstdfile() ) - seterrorresult(vm,"cannot close standard file"); - else { - f.close(); - setsuccessresult(vm); - } - } - - private static void setsuccessresult(LuaState vm) { - vm.resettop(); - vm.pushboolean(true); - } - - private static void seterrorresult(LuaState vm, IOException ioe) { - String s = ioe.getMessage(); - seterrorresult(vm, "io error: "+(s!=null? s: ioe.toString())); - } - - private static void seterrorresult(LuaState vm, String errortext) { - vm.resettop(); - vm.pushnil(); - vm.pushstring(errortext); - } - - private LValue lines(LuaState vm, final File f) { - return new LFunction() { - public boolean luaStackCall(LuaState vm) { - vm.resettop(); - try { - vm.pushlvalue(freadline(f)); - } catch (IOException e) { - seterrorresult(vm,e); - } - return false; - } - }; - } - - private static void iowrite(LuaState vm, File f) throws IOException { - for ( int i=1, n=vm.gettop(); i<=n; i++ ) - f.write( vm.checklstring(i) ); - vm.resettop(); - vm.pushboolean(true); - } - - private static void ioread(LuaState vm, File f) throws IOException { - int i,n=vm.gettop(); - for ( i=1; i<=n; i++ ) { - if ( vm.isnumber(i) ) { - vm.pushlvalue(freadbytes(f,vm.tointeger(i))); - } else { - String format = vm.checkstring(i); - if ( "*n".equals(format) ) - vm.pushnumber(freadnumber(f)); - else if ( "*a".equals(format) ) - vm.pushlvalue(freadall(f)); - else if ( "*l".equals(format) ) - vm.pushlvalue(freadline(f)); - else - vm.typerror( i, "(invalid format)" ); - } - } - for ( i=1; i<=n; i++ ) - vm.remove(1); - } - - private static File checkfile(LuaState vm, int index) { - File f = (File) vm.checkudata(index, File.class); - checkopen( vm, f ); - return f; - } - - private File optfile(LuaState vm, int index) { - Object u = vm.touserdata(index); - return (u instanceof File? (File) u: null); - } - - private static File checkopen(LuaState vm, File file) { - if ( file.isclosed() ) - vm.error("attempt to use a closed file"); - return file; - } - - private static void setresult(LuaState vm, File file) { - vm.settop(0); - vm.pushlvalue(touserdata(file)); - } - - private static LUserData touserdata(File file) { - return new LUserData(file, FILE_MT); - } - - private File ioopenfile(LuaState vm, String filename, String mode) { - try { - return rawopenfile(filename, mode); - } catch ( Exception e ) { - vm.error("io error: "+e.getMessage()); - return null; - } - } - - private File rawopenfile(String filename, String mode) throws IOException { - boolean isstdfile = "-".equals(filename); - boolean isreadmode = mode.startsWith("r"); - if ( isstdfile ) { - return isreadmode? - wrapStdin(): - wrapStdout(); - } - 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 LValue freadbytes(File f, int count) throws IOException { - byte[] b = new byte[count]; - int r; - if ( ( r = f.read(b,0,b.length) ) < 0 ) - return LNil.NIL; - return new LString(b, 0, r); - } - public static LValue freaduntil(File f,int delim) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - int c; - try { - while ( true ) { - c = f.read(); - if ( c < 0 || c == delim ) - break; - baos.write(c); - } - } catch ( EOFException e ) { - c = -1; - } - return ( c < 0 && baos.size() == 0 )? - (LValue) LNil.NIL: - (LValue) new LString(baos.toByteArray()); - } - public static LValue freadline(File f) throws IOException { - return freaduntil(f,'\n'); - } - public static LValue freadall(File f) throws IOException { - int n = f.remaining(); - if ( n >= 0 ) { - return freadbytes(f, n); - } else { - return freaduntil(f,-1); - } - } - public static Double 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? Double.valueOf(s): null; - } - 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/lib/LBuffer.java b/src/core/org/luaj/lib/LBuffer.java deleted file mode 100644 index bcbec925..00000000 --- a/src/core/org/luaj/lib/LBuffer.java +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.lib; - -import org.luaj.vm.LString; - -public class LBuffer { - - private byte[] bytes; - private int length; - - public LBuffer( int initialCapacity ) { - bytes = new byte[ initialCapacity ]; - length = 0; - } - - public void append( byte b ) { - ensureCapacity( length + 1 ); - bytes[ length++ ] = b; - } - - public void append( LString str ) { - final int alen = str.length(); - ensureCapacity( length + alen ); - str.copyInto( 0, bytes, length, alen ); - length += alen; - } - - public void append( String str ) { - final int alen = LString.lengthAsUtf8( str ); - ensureCapacity( length + alen ); - LString.encodeToUtf8( str, bytes, length ); - length += alen; - } - - public void setLength( int length ) { - ensureCapacity( length ); - this.length = length; - } - - public LString toLuaString() { - return new LString( realloc( bytes, length ) ); - } - - public void ensureCapacity( int minSize ) { - if ( minSize > bytes.length ) - realloc( minSize ); - } - - private void realloc( int minSize ) { - bytes = realloc( bytes, Math.max( bytes.length * 2, minSize ) ); - } - - private static byte[] realloc( byte[] b, int newSize ) { - byte[] newBytes = new byte[ newSize ]; - System.arraycopy( b, 0, newBytes, 0, Math.min( b.length, newSize ) ); - return newBytes; - } -} diff --git a/src/core/org/luaj/lib/MathLib.java b/src/core/org/luaj/lib/MathLib.java deleted file mode 100644 index cffa5c1b..00000000 --- a/src/core/org/luaj/lib/MathLib.java +++ /dev/null @@ -1,227 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.lib; - -import java.util.Random; - -import org.luaj.vm.LDouble; -import org.luaj.vm.LFunction; -import org.luaj.vm.LTable; -import org.luaj.vm.LuaState; -import org.luaj.vm.Platform; - - -public class MathLib extends LFunction { - - public static final String[] NAMES = { - "math", - - // irregular functions - "max", - "min", - "modf", - "ceil", - "floor", - "frexp", - "ldexp", - "random", - "randomseed", - - // 2 argument, return double - "atan2", - "fmod", - "pow", - - // single argument, return double - "abs", - "acos", - "asin", - "atan", - "cos", - "cosh", - "deg", - "exp", - "log", - "log10", - "rad", - "sin", - "sinh", - "sqrt", - "tan", - "tanh", - }; - - private static final int INSTALL = 0; - - // irregular functions - public static final int MAX = 1; - public static final int MIN = 2; - public static final int MODF = 3; - public static final int CEIL = 4; - public static final int FLOOR = 5; - public static final int FREXP = 6; - public static final int LDEXP = 7; - public static final int RANDOM = 8; - public static final int RSEED = 9; - public static final int LAST_IRREGULAR = RSEED; - - // 2 argument, return double - public static final int ATAN2 = 10; - public static final int FMOD = 11; - public static final int POW = 12; - public static final int LAST_DOUBLE_ARG = POW; - - /* Math operations - single argument, one function */ - public static final int ABS = 13; - public static final int ACOS = 14; - public static final int ASIN = 15; - public static final int ATAN = 16; - public static final int COS = 17; - public static final int COSH = 18; - public static final int DEG = 19; - public static final int EXP = 20; - public static final int LOG = 21; - public static final int LOG10 = 22; - public static final int RAD = 23; - public static final int SIN = 24; - public static final int SINH = 25; - public static final int SQRT = 26; - public static final int TAN = 27; - public static final int TANH = 28; - - private static Platform platform; - - public static void install( LTable globals ) { - LTable math = new LTable(); - for ( int i=1; i LAST_DOUBLE_ARG ) { - vm.pushlvalue( platform.mathop(id, vm.checknumber(1) ) ); - return 1; - } else if ( id > LAST_IRREGULAR ) { - vm.pushlvalue( platform.mathop(id, vm.checknumber(1), vm.checknumber(2) ) ); - return 1; - } else { - switch ( id ) { - case INSTALL: - install( vm._G ); - return 0; - case MAX: { - int n = vm.gettop(); - double x = vm.checkdouble(1); - for ( int i=2; i<=n; i++ ) - x = Math.max(x, vm.checkdouble(i)); - vm.pushnumber( x ); - return 1; - } - case MIN: { - int n = vm.gettop(); - double x = vm.checkdouble(1); - for ( int i=2; i<=n; i++ ) - x = Math.min(x, vm.checkdouble(i)); - vm.pushnumber( x ); - return 1; - } - case MODF: { - double x = vm.checkdouble(1); - double intPart = ( x > 0 ) ? Math.floor( x ) : Math.ceil( x ); - double fracPart = x - intPart; - vm.pushnumber( intPart ); - vm.pushnumber( fracPart ); - return 2; - } - case CEIL: - vm.pushnumber( Math.ceil( vm.checkdouble(1) ) ); - return 1; - case FLOOR: - vm.pushnumber( Math.floor( vm.checkdouble(1) ) ); - return 1; - case FREXP: { - long bits = Double.doubleToLongBits( vm.checkdouble(1) ); - vm.pushnumber( ((bits & (~(-1L<<52))) + (1L<<52)) * ((bits >= 0)? (.5 / (1L<<52)): (-.5 / (1L<<52))) ); - vm.pushinteger( (((int) (bits >> 52)) & 0x7ff) - 1022 ); - return 2; - } - case LDEXP: { - double m = vm.checkdouble(1); - int e = vm.checkint(2); - vm.pushnumber( m * Double.longBitsToDouble(((long)(e+1023)) << 52) ); - return 1; - } - case RANDOM: { - if ( random == null ) - random = new Random(1); - switch ( vm.gettop() ) { - case 0: - vm.pushnumber(random.nextDouble()); - return 1; - case 1: { - int m = vm.checkint(1); - vm.argcheck(1<=m, 1, "interval is empty"); - vm.pushinteger(1+random.nextInt(m)); - return 1; - } - default: { - int m = vm.checkint(1); - int n = vm.checkint(2); - vm.argcheck(m<=n, 2, "interval is empty"); - vm.pushinteger(m+random.nextInt(n+1-m)); - return 1; - } - } - } - case RSEED: - random = new Random( vm.checkint(1) ); - return 0; - default: - LuaState.vmerror( "bad math id" ); - return 0; - } - } - } -} diff --git a/src/core/org/luaj/lib/OsLib.java b/src/core/org/luaj/lib/OsLib.java deleted file mode 100644 index 591b58c9..00000000 --- a/src/core/org/luaj/lib/OsLib.java +++ /dev/null @@ -1,344 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2009 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.lib; - -import java.io.IOException; - -import org.luaj.vm.LFunction; -import org.luaj.vm.LString; -import org.luaj.vm.LTable; -import org.luaj.vm.LValue; -import org.luaj.vm.LuaState; - -/** - * Base implementation of OsLib, with simplified stub functions - * for library functions that cannot be implemented uniformly - * on J2se and J2me. - * - * This can be installed as-is on either platform, or extended - * and refined to be used in a complete J2se implementation. - */ -public class OsLib extends LFunction { - public static String TMP_PREFIX = ".luaj"; - public static String TMP_SUFFIX = "tmp"; - - /** - * Create a function stub with a specific index. - * This is a factory method so that subclasses can - * use install(LTable,OsLib) to install themselves. - */ - protected OsLib newInstance( int index ) { - return new OsLib(index); - } - - public static final String[] NAMES = { - "os", - "clock", - "date", - "difftime", - "execute", - "exit", - "getenv", - "remove", - "rename", - "setlocale", - "time", - "tmpname", - }; - - private static final int INSTALL = 0; - private static final int CLOCK = 1; - private static final int DATE = 2; - private static final int DIFFTIME = 3; - private static final int EXECUTE = 4; - private static final int EXIT = 5; - private static final int GETENV = 6; - private static final int REMOVE = 7; - private static final int RENAME = 8; - private static final int SETLOCALE = 9; - private static final int TIME = 10; - private static final int TMPNAME = 11; - - /** - * Install the os library using the OsLib class as a factory - */ - public static void install( LTable globals ) { - install(globals, new OsLib()); - } - - /** - * Initialize the os libaray using the subblied instance as a factory. - * @param factory instance to use as a factory for function stubs. - */ - public static void install( LTable globals, OsLib factory ) { - LTable os = new LTable(); - for ( int i=CLOCK; i<=TMPNAME; i++ ) - os.put(NAMES[i], factory.newInstance(i)); - globals.put( "os", os ); - PackageLib.setIsLoaded("os", os); - } - - private static final long t0 = System.currentTimeMillis(); - private static long tmpnames = t0; - - private final int id; - - protected OsLib() { - id = 0; - } - - protected OsLib( int id ) { - this.id = id; - } - - public LString luaAsString() { - return new LString(toJavaString()); - } - - public String toJavaString() { - return "os."+toString(); - } - - public String toString() { - return NAMES[id]+"()"; - } - - public int invoke( LuaState vm ) { - LValue v; - long t,t2; - int c; - String s; - try { - switch ( id ) { - case INSTALL: - install(vm._G, this); - return 0; - case CLOCK: - vm.pushnumber(clock()); - return 1; - case DATE: - s = vm.optstring(1, null); - t = vm.optlong(2,-1); - vm.pushlvalue( date(s, t==-1? System.currentTimeMillis(): t) ); - return 1; - case DIFFTIME: - t2 = vm.checklong(1); - t = vm.checklong(2); - vm.pushnumber(difftime(t2,t)); - return 1; - case EXECUTE: - c = execute(vm.optstring(1, null)); - vm.pushinteger(c); - return 1; - case EXIT: - exit(vm.optint(1, 0)); - return 0; - case GETENV: - s = getenv(vm.checkstring(1)); - vm.pushstring(s); - return 1; - case REMOVE: - remove(vm.checkstring(1)); - vm.pushboolean(true); - return 1; - case RENAME: - rename(vm.checkstring(1), vm.checkstring(2)); - vm.pushboolean(true); - return 1; - case SETLOCALE: - s = setlocale(vm.optstring(1,null), vm.optstring(2, "all")); - if ( s != null ) - vm.pushstring(s); - else - vm.pushnil(); - return 1; - case TIME: - t = time(vm.isnoneornil(1)? null: vm.checktable(1)); - vm.pushnumber(t); - return 1; - case TMPNAME: - vm.pushstring(tmpname()); - return 1; - default: - LuaState.vmerror( "bad os id" ); - return 0; - } - } catch ( IOException e ) { - vm.pushnil(); - vm.pushstring(e.getMessage()); - return 2; - } - } - - /** - * @return an approximation of the amount in seconds of CPU time used by - * the program. - */ - 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(long t2, long t1) { - return (t2 - t1) / 1000.; - } - - /** - * 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. - * - * If format starts with '!', then the date is formatted in Coordinated - * Universal Time. After this optional character, if format is the string - * "*t", then date returns a table with the following fields: year - * (four digits), month (1--12), day (1--31), hour (0--23), min (0--59), - * sec (0--61), wday (weekday, Sunday is 1), yday (day of the year), - * and isdst (daylight saving flag, a boolean). - * - * If format is not "*t", then date returns the date as a string, - * formatted according to the same rules as the C function strftime. - * - * 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. - */ - protected LValue date(String format, long time) { - return LString.valueOf( new java.util.Date(time).toString() ); - } - - /** - * 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 int execute(String command) { - return 0; - } - - /** - * 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 null if the variable is not defined. - * @param varname - * @return - */ - 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 null; - } - - /** - * 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 long time(LTable table) { - return System.currentTimeMillis(); - } - - /** - * 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() { - return TMP_PREFIX+(tmpnames++)+TMP_SUFFIX; - } -} diff --git a/src/core/org/luaj/lib/PackageLib.java b/src/core/org/luaj/lib/PackageLib.java deleted file mode 100644 index 57061895..00000000 --- a/src/core/org/luaj/lib/PackageLib.java +++ /dev/null @@ -1,416 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.lib; - -import java.io.InputStream; -import java.io.PrintStream; -import java.util.Vector; - -import org.luaj.vm.CallInfo; -import org.luaj.vm.LBoolean; -import org.luaj.vm.LFunction; -import org.luaj.vm.LString; -import org.luaj.vm.LTable; -import org.luaj.vm.LValue; -import org.luaj.vm.Lua; -import org.luaj.vm.LuaState; -import org.luaj.vm.Platform; - - -public class PackageLib extends LFunction { - - public static String DEFAULT_LUA_PATH = "?.lua"; - - public static InputStream STDIN = null; - public static PrintStream STDOUT = System.out; - public static LTable LOADED = null; - - private static final LString _M = new LString("_M"); - private static final LString _NAME = new LString("_NAME"); - private static final LString _PACKAGE = new LString("_PACKAGE"); - private static final LString _DOT = new LString("."); - private static final LString _EMPTY = new LString(""); - private static final LString __INDEX = new LString("__index"); - private static final LString _LOADERS = new LString("loaders"); - private static final LString _PRELOAD = new LString("preload"); - private static final LString _PATH = new LString("path"); - private static final LValue _SENTINEL = _EMPTY; - - private static final String[] NAMES = { - "package", - "module", - "require", - "loadlib", - "seeall", - "preload_loader", - "lua_loader", - "java_loader", - }; - - private static final int INSTALL = 0; - private static final int MODULE = 1; - private static final int REQUIRE = 2; - private static final int LOADLIB = 3; - private static final int SEEALL = 4; - private static final int PRELOAD_LOADER = 5; - private static final int LUA_LOADER = 6; - private static final int JAVA_LOADER = 7; - - // all functions in package share this environment - private static LTable pckg; - - public static void install( LTable globals ) { - for ( int i=1; i<=REQUIRE; i++ ) - globals.put( NAMES[i], new PackageLib(i) ); - pckg = new LTable(); - for ( int i=LOADLIB; i<=SEEALL; i++ ) - pckg.put( NAMES[i], new PackageLib(i) ); - LOADED = new LTable(); - pckg.put( "loaded", LOADED ); - pckg.put( _PRELOAD, new LTable() ); - LTable loaders = new LTable(3,0); - for ( int i=PRELOAD_LOADER; i<=JAVA_LOADER; i++ ) - loaders.luaInsertPos(0, new PackageLib(i) ); - pckg.put( "loaders", loaders ); - pckg.put( _PATH, new LString(DEFAULT_LUA_PATH) ); - globals.put( "package", pckg ); - setIsLoaded( "package", pckg ); - } - - /** Allow packages to mark themselves as loaded */ - public static void setIsLoaded(String name, LTable value) { - LOADED.put(name, value); - } - - public static void setLuaPath( String newLuaPath ) { - pckg.put( _PATH, new LString(newLuaPath) ); - } - - private final int id; - - private PackageLib( int id ) { - this.id = id; - } - - public String toString() { - return NAMES[id]+"()"; - } - - public int invoke( LuaState vm ) { - switch ( id ) { - case INSTALL: - install(vm._G); - return 0; - case MODULE: - return module(vm); - case REQUIRE: - return require(vm); - case LOADLIB: - return loadlib(vm); - case SEEALL: { - LTable t = vm.checktable(1); - LTable m = t.luaGetMetatable(); - if ( m == null ) - t.luaSetMetatable(m = new LTable()); - m.put(__INDEX, vm._G); - return 0; - } - case PRELOAD_LOADER: { - return loader_preload(vm); - } - case LUA_LOADER: { - return loader_Lua(vm); - } - case JAVA_LOADER: { - return loader_Java(vm); - } - default: - LuaState.vmerror( "bad package id" ); - return 0; - } - } - - - // ======================== Module, Package loading ============================= - /** - * module (name [, ...]) - * - * Creates a module. If there is a table in package.loaded[name], this table - * is the module. Otherwise, if there is a global table t with the given - * name, this table is the module. Otherwise creates a new table t and sets - * it as the value of the global name and the value of package.loaded[name]. - * This function also initializes t._NAME with the given name, t._M with the - * module (t itself), and t._PACKAGE with the package name (the full module - * name minus last component; see below). Finally, module sets t as the new - * environment of the current function and the new value of - * package.loaded[name], so that require returns t. - * - * If name is a compound name (that is, one with components separated by - * dots), module creates (or reuses, if they already exist) tables for each - * component. For instance, if name is a.b.c, then module stores the module - * table in field c of field b of global a. - * - * This function may receive optional options after the module name, where - * each option is a function to be applied over the module. - */ - public static int module(LuaState vm) { - LString modname = vm.checklstring(1); - int n = vm.gettop(); - LValue value = LOADED.luaGetTable(vm, modname); - LTable module; - if ( ! value.isTable() ) { /* not found? */ - - /* try global variable (and create one if it does not exist) */ - module = findtable( vm._G, modname ); - if ( module == null ) - vm.error( "name conflict for module '"+modname+"'" ); - LOADED.luaSetTable(vm, modname, module); - } else { - module = (LTable) value; - } - - - /* check whether table already has a _NAME field */ - LValue name = module.luaGetTable(vm, _NAME); - if ( name.isNil() ) { - modinit( vm, module, modname ); - } - - // set the environment of the current function - CallInfo ci = vm.getStackFrame(0); - ci.closure.env = module; - - // apply the functions - for ( int i=2; i<=n; i++ ) { - vm.pushvalue( i ); /* get option (a function) */ - vm.pushlvalue( module ); /* module */ - vm.call( 1, 0 ); - } - - // returns no results - return 0; - } - - /** - * - * @param table the table at which to start the search - * @param fname the name to look up or create, such as "abc.def.ghi" - * @return the table for that name, possible a new one, or null if a non-table has that name already. - */ - private static LTable findtable(LTable table, LString fname) { - int b, e=(-1); - do { - e = fname.indexOf(_DOT, b=e+1 ); - if ( e < 0 ) - e = fname.m_length; - LString key = fname.substring(b, e); - LValue val = table.get(key); - if ( val.isNil() ) { /* no such field? */ - LTable field = new LTable(); /* new table for field */ - table.put(key, field); - table = field; - } else if ( val.luaGetType() != Lua.LUA_TTABLE ) { /* field has a non-table value? */ - return null; - } else { - table = (LTable) val; - } - } while ( e < fname.m_length ); - return table; - } - - private static void modinit(LuaState vm, LTable module, LString modname) { - /* module._M = module */ - module.luaSetTable(vm, _M, module); - int e = modname.lastIndexOf(_DOT); - module.luaSetTable(vm, _NAME, modname ); - module.luaSetTable(vm, _PACKAGE, (e<0? _EMPTY: modname.substring(0,e+1)) ); - } - - /** - * 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.loaders array. By changing this array, - * we can change how require looks for a module. The following explanation is based on the - * default configuration for package.loaders. - * - * 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 C loader - * using the path stored in package.cpath. If that also fails, it tries an all-in-one loader - * (see package.loaders). - * - * Once a loader is found, require calls the loader with a single argument, modname. - * If the loader returns any value, require assigns the returned value to package.loaded[modname]. - * If the loader returns no 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 signals an error. - */ - public int require( LuaState vm ) { - LString name = vm.checklstring(1); - LValue loaded = LOADED.luaGetTable(vm, name); - if ( loaded.toJavaBoolean() ) { - if ( loaded == _SENTINEL ) - vm.error("loop or previous error loading module '"+name+"'"); - vm.pushlvalue( loaded ); - return 1; - } - - /* else must load it; iterate over available loaders */ - LValue val = pckg.luaGetTable(vm, _LOADERS); - if ( ! val.isTable() ) - vm.error( "'package.loaders' must be a table" ); - LTable tbl = (LTable) val; - Vector v = new Vector(); - for ( int i=1; true; i++ ) { - LValue loader = tbl.get(i); - if ( loader.isNil() ) { - vm.error( "module '"+name+"' not found: "+v ); - } - /* call loader with module name as argument */ - vm.pushlvalue(loader); - vm.pushlstring(name); - vm.call(1, 1); - if ( vm.isfunction(-1) ) - break; /* module loaded successfully */ - if ( vm.isstring(-1) ) /* loader returned error message? */ - v.addElement(vm.tolstring(-1)); /* accumulate it */ - vm.pop(1); - } - - // load the module using the loader - LOADED.luaSetTable(vm, name, _SENTINEL); - vm.pushlstring( name ); /* pass name as argument to module */ - vm.call( 1, 1 ); /* run loaded module */ - if ( ! vm.isnil(-1) ) /* non-nil return? */ - LOADED.luaSetTable(vm, name, vm.topointer(-1) ); /* _LOADED[name] = returned value */ - LValue result = LOADED.luaGetTable(vm, name); - if ( result == _SENTINEL ) { /* module did not set a value? */ - LOADED.luaSetTable(vm, name, result=LBoolean.TRUE ); /* _LOADED[name] = true */ - } - vm.pushlvalue(result); - return 1; - } - - public static int loadlib( LuaState vm ) { - vm.checkstring(1); - vm.pushnil(); - vm.pushstring("dynamic libraries not enabled"); - vm.pushstring("absent"); - return 3; - } - - - private int loader_preload( LuaState vm ) { - LString name = vm.tolstring(1); - LValue preload = pckg.luaGetTable(vm, _PRELOAD); - if ( ! preload.isTable() ) - vm.error("package.preload '"+name+"' must be a table"); - LValue val = preload.luaGetTable(vm, name); - if ( val.isNil() ) - vm.pushstring("\n\tno field package.preload['"+name+"']"); - else - vm.pushlvalue(val); - return 1; - } - - private int loader_Lua( LuaState vm ) { - String name = vm.tostring(1); - InputStream is = findfile( vm, name, _PATH ); - if ( is != null ) { - String filename = vm.tostring(-1); - if ( ! BaseLib.loadis(vm, is, filename) ) - loaderror( vm, filename ); - } - return 1; - } - - private int loader_Java( LuaState vm ) { - String name = vm.tostring(1); - Class c = null; - LValue v = null; - try { - c = Class.forName(name); - v = (LValue) c.newInstance(); - vm.pushlvalue( v ); - } catch ( ClassNotFoundException cnfe ) { - vm.pushstring("\n\tno class '"+name+"'" ); - } catch ( Exception e ) { - vm.pushstring("\n\tjava load failed on '"+name+"', "+e ); - } - return 1; - } - - private InputStream findfile(LuaState vm, String name, LString pname) { - Platform p = Platform.getInstance(); - LValue pkg = pckg.luaGetTable(vm, pname); - if ( ! pkg.isString() ) - vm.error("package."+pname+" must be a string"); - String path = pkg.toJavaString(); - int e = -1; - int n = path.length(); - StringBuffer sb = null; - name = name.replace('.','/'); - 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 = p.openFile(filename); - if ( is != null ) { - vm.pushstring(filename); - return is; - } - - // report error - if ( sb == null ) - sb = new StringBuffer(); - sb.append( "\n\tno file '"+filename+"'"); - } - - // not found, push error on stack and return - vm.pushstring(sb.toString()); - return null; - } - - private static void loaderror(LuaState vm, String filename) { - vm.error( "error loading module '"+vm.tostring(1)+"' from file '"+filename+"':\n\t"+vm.tostring(-1) ); - } -} diff --git a/src/core/org/luaj/lib/StringLib.java b/src/core/org/luaj/lib/StringLib.java deleted file mode 100644 index 6e3e983b..00000000 --- a/src/core/org/luaj/lib/StringLib.java +++ /dev/null @@ -1,1212 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.lib; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import org.luaj.compiler.DumpState; -import org.luaj.vm.LClosure; -import org.luaj.vm.LFunction; -import org.luaj.vm.LString; -import org.luaj.vm.LTable; -import org.luaj.vm.LValue; -import org.luaj.vm.Lua; -import org.luaj.vm.LuaState; - - -public class StringLib extends LFunction { - - private static final String[] NAMES = { - "string", - "byte", - "char", - "dump", - "find", - "format", - "gmatch", - "gsub", - "len", - "lower", - "match", - "rep", - "reverse", - "sub", - "upper", - }; - - private static final int INSTALL = 0; - private static final int BYTE = 1; - private static final int CHAR = 2; - private static final int DUMP = 3; - private static final int FIND = 4; - private static final int FORMAT = 5; - private static final int GMATCH = 6; - private static final int GSUB = 7; - private static final int LEN = 8; - private static final int LOWER = 9; - private static final int MATCH = 10; - private static final int REP = 11; - private static final int REVERSE = 12; - private static final int SUB = 13; - private static final int UPPER = 14; - - public static void install( LTable globals ) { - LTable string = LString.getMetatable(); - for ( int i=1; i l) pose = l; - if (posi > pose) return 0; /* empty interval; return no values */ - n = (int)(pose - posi + 1); - if (posi + n <= pose) /* overflow? */ - vm.error("string slice too long"); - vm.checkstack(n); - for (i=0; i=0 && c<256), a, "invalid value"); - bytes[i] = (byte) c; - } - vm.pushlstring( bytes ); - return 1; - } - - /** - * string.dump (function) - * - * 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. - * - * TODO: port dumping code as optional add-on - */ - static int dump( LuaState vm ) { - LFunction f = vm.checkfunction(1); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - DumpState.dump( ((LClosure)f).p, baos, true ); - vm.pushlstring(baos.toByteArray()); - return 1; - } catch (IOException e) { - vm.error( e.getMessage() ); - return 0; - } - } - - /** - * 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 int find( LuaState vm ) { - return str_find_aux( vm, 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. - */ - static int format( LuaState vm ) { - LString fmt = vm.checklstring( 1 ); - final int n = fmt.length(); - LBuffer result = new LBuffer(n); - int arg = 1; - - for ( int i = 0; i < n; ) { - int c = fmt.luaByte( i++ ); - if ( c != L_ESC ) { - result.append( (byte) c ); - } else if ( i < n ) { - if ( ( c = fmt.luaByte( i ) ) == L_ESC ) { - ++i; - result.append( (byte)L_ESC ); - } else { - arg++; - FormatDesc fdsc = new FormatDesc(vm, fmt, i ); - i += fdsc.length; - switch ( fdsc.conversion ) { - case 'c': - fdsc.format( result, (byte)vm.checkint( arg ) ); - break; - case 'i': - case 'd': - fdsc.format( result, vm.checkint( arg ) ); - break; - case 'o': - case 'u': - case 'x': - case 'X': - fdsc.format( result, vm.checklong( arg ) ); - break; - case 'e': - case 'E': - case 'f': - case 'g': - case 'G': - fdsc.format( result, vm.checkdouble( arg ) ); - break; - case 'q': - addquoted( result, vm.checklstring( arg ) ); - break; - case 's': { - LString s = vm.checklstring( arg ); - if ( fdsc.precision == -1 && s.length() >= 100 ) { - result.append( s ); - } else { - fdsc.format( result, s ); - } - } break; - default: - vm.error("invalid option '%"+(char)fdsc.conversion+"' to 'format'"); - break; - } - } - } - } - - vm.pushlstring( result.toLuaString() ); - return 1; - } - - private static void addquoted(LBuffer buf, LString 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; - case '\r': - buf.append( "\\r" ); - break; - case '\0': - buf.append( "\\000" ); - break; - default: - buf.append( (byte) c ); - break; - } - } - buf.append( (byte) '"' ); - } - - private static final String FLAGS = "-+ #0"; - - private static 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; - private int precision; - - public final int conversion; - public final int length; - - public FormatDesc(LuaState vm, LString 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 ) - vm.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 ) ) - vm.error("invalid format (width or precision too long)"); - - zeroPad &= !leftAdjust; // '-' overrides '0' - conversion = c; - length = p - start; - } - - public void format(LBuffer buf, byte c) { - // TODO: not clear that any of width, precision, or flags apply here. - buf.append(c); - } - - public void format(LBuffer 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(LBuffer buf, double x) { - // TODO - buf.append( String.valueOf( x ) ); - } - - public void format(LBuffer buf, LString s) { - int nullindex = s.indexOf( (byte)'\0', 0 ); - if ( nullindex != -1 ) - s = s.substring( 0, nullindex ); - buf.append(s); - } - - public static final void pad(LBuffer buf, char c, int n) { - byte b = (byte)c; - while ( n-- > 0 ) - buf.append(b); - } - } - - /** - * 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 int gmatch( LuaState vm ) { - LString src = vm.checklstring( 1 ); - LString pat = vm.checklstring( 2 ); - vm.pushlvalue( new GMatchAux(vm, src, pat) ); - return 1; - } - - static class GMatchAux extends LFunction { - private final int srclen; - private final MatchState ms; - private int soffset; - public GMatchAux(LuaState vm, LString src, LString pat) { - this.srclen = src.length(); - this.ms = new MatchState(vm, src, pat); - this.soffset = 0; - } - public int invoke(LuaState vm) { - vm.resettop(); - for ( ; soffset=0 ) { - int soff = soffset; - soffset = res; - ms.push_captures( true, soff, res ); - return -1; - } - } - vm.pushnil(); - return 1; - } - } - - - /** - * 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 int gsub( LuaState vm ) { - LString src = vm.checklstring( 1 ); - final int srclen = src.length(); - LString p = vm.checklstring( 2 ); - LValue repl = vm.topointer( 3 ); - int max_s = vm.optint( 4, srclen + 1 ); - final boolean anchor = p.length() > 0 && p.charAt( 0 ) == '^'; - - LBuffer lbuf = new LBuffer( srclen ); - MatchState ms = new MatchState( vm, 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 ) { - n++; - ms.add_value( lbuf, soffset, res, repl ); - } - if ( res != -1 && res > soffset ) - soffset = res; - else if ( soffset < srclen ) - lbuf.append( (byte) src.luaByte( soffset++ ) ); - else - break; - if ( anchor ) - break; - } - lbuf.append( src.substring( soffset, srclen ) ); - vm.pushlstring( lbuf.toLuaString() ); - vm.pushinteger( n ); - return 2; - } - - /** - * 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 int len( LuaState vm ) { - vm.pushinteger( vm.checklstring(1).length() ); - return 1; - } - - /** - * 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 int lower( LuaState vm ) { - vm.pushstring( vm.checkstring(1).toLowerCase() ); - return 1; - } - - /** - * 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 int match( LuaState vm ) { - return str_find_aux( vm, false ); - } - - /** - * string.rep (s, n) - * - * Returns a string that is the concatenation of n copies of the string s. - */ - static int rep( LuaState vm ) { - LString s = vm.checklstring( 1 ); - int n = vm.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 ); - } - vm.pushlstring( bytes ); - return 1; - } - - /** - * string.reverse (s) - * - * Returns a string that is the string s reversed. - */ - static int reverse( LuaState vm ) { - LString s = vm.checklstring(1); - int n = s.length(); - byte[] b = new byte[n]; - for ( int i=0, j=n-1; i l ) - end = l; - - vm.resettop(); - if ( start <= end ) { - LString result = s.substring( start-1 , end ); - vm.pushlstring( result ); - } else { - vm.pushstring( "" ); - } - return 1; - } - - /** - * 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 int upper( LuaState vm ) { - vm.pushstring(vm.checkstring(1).toUpperCase()); - return 1; - } - - /** - * This utility method implements both string.find and string.match. - */ - static int str_find_aux( LuaState vm, boolean find ) { - LString s = vm.checklstring( 1 ); - LString pat = vm.checklstring( 2 ); - int init = vm.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 && ( vm.toboolean( 4 ) || pat.indexOfAny( SPECIALS ) == -1 ); - - if ( fastMatch ) { - int result = s.indexOf( pat, init ); - if ( result != -1 ) { - vm.pushinteger( result + 1 ); - vm.pushinteger( result + pat.length() ); - return 2; - } - } else { - MatchState ms = new MatchState( vm, s, pat ); - - boolean anchor = false; - int poff = 0; - if ( pat.luaByte( 0 ) == '^' ) { - anchor = true; - poff = 1; - } - - int soff = init; - vm.resettop(); - do { - int res; - ms.reset(); - if ( ( res = ms.match( soff, poff ) ) != -1 ) { - if ( find ) { - vm.pushinteger( soff + 1 ); - vm.pushinteger( res ); - ms.push_captures( false, soff, res ); - } else { - ms.push_captures( true, soff, res ); - } - return -1; - } - } while ( soff++ < s.length() && !anchor ); - } - vm.pushnil(); - return 1; - } - - private 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 LString SPECIALS = new LString("^$*+?.([%-"); - private static final int MAX_CAPTURES = 32; - - 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; - - private static final byte[] CHAR_TABLE; - - static { - CHAR_TABLE = new byte[256]; - - for ( int i = 0; i < 256; ++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 <= '@' ) ) { - 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[0x0C /* '\v' */ ] |= MASK_SPACE; - CHAR_TABLE['\f'] |= MASK_SPACE; - }; - - private static class MatchState { - final LString s; - final LString p; - final LuaState vm; - int level; - int[] cinit; - int[] clen; - - MatchState( LuaState vm, LString s, LString pattern ) { - this.s = s; - this.p = pattern; - this.vm = vm; - this.level = 0; - this.cinit = new int[ MAX_CAPTURES ]; - this.clen = new int[ MAX_CAPTURES ]; - } - - void reset() { - level = 0; - } - - private void add_s( LBuffer lbuf, LString 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) news.luaByte( i ); - if ( !Character.isDigit( (char) b ) ) { - lbuf.append( b ); - } else if ( b == '0' ) { - lbuf.append( s.substring( soff, e ) ); - } else { - push_onecapture( b - '1', soff, e ); - lbuf.append( vm.topointer( -1 ).luaAsString() ); - vm.pop( 1 ); - } - } - } - } - - public void add_value( LBuffer lbuf, int soffset, int end, LValue repl ) { - switch ( repl.luaGetType() ) { - case Lua.LUA_TSTRING: - case Lua.LUA_TNUMBER: - add_s( lbuf, repl.luaAsString(), soffset, end ); - return; - - case Lua.LUA_TFUNCTION: - vm.pushlvalue( repl ); - int n = push_captures( true, soffset, end ); - vm.call( n, 1 ); - break; - - case Lua.LUA_TTABLE: - // Need to call push_onecapture here for the error checking - push_onecapture( 0, soffset, end ); - LValue k = vm.topointer( -1 ); - vm.pop( 1 ); - vm.pushlvalue( ((LTable) repl).luaGetTable( vm, k ) ); - break; - - default: - vm.error( "bad argument: string/function/table expected" ); - return; - } - - repl = vm.topointer( -1 ); - if ( !repl.toJavaBoolean() ) { - repl = s.substring( soffset, end ); - } else if ( ! repl.isString() ) { - vm.error( "invalid replacement value (a "+repl.luaGetTypeName()+")" ); - } - vm.pop( 1 ); - lbuf.append( repl.luaAsString() ); - } - - int push_captures( boolean wholeMatch, int soff, int end ) { - int nlevels = ( this.level == 0 && wholeMatch ) ? 1 : this.level; - for ( int i = 0; i < nlevels; ++i ) { - push_onecapture( i, soff, end ); - } - return nlevels; - } - - private void push_onecapture( int i, int soff, int end ) { - if ( i >= this.level ) { - if ( i == 0 ) { - vm.pushlstring( s.substring( soff, end ) ); - } else { - vm.error( "invalid capture index" ); - } - } else { - int l = clen[i]; - if ( l == CAP_UNFINISHED ) { - vm.error( "unfinished capture" ); - } - if ( l == CAP_POSITION ) { - vm.pushinteger( cinit[i] + 1 ); - } else { - int begin = cinit[i]; - vm.pushlstring( s.substring( begin, begin + l ) ); - } - } - } - - private int check_capture( int l ) { - l -= '1'; - if ( l < 0 || l >= level || this.clen[l] == CAP_UNFINISHED ) { - vm.error("invalid capture index"); - } - return l; - } - - private int capture_to_close() { - int level = this.level; - for ( level--; level >= 0; level-- ) - if ( clen[level] == CAP_UNFINISHED ) - return level; - vm.error("invalid pattern capture"); - return 0; - } - - int classend( int poffset ) { - switch ( p.luaByte( poffset++ ) ) { - case L_ESC: - if ( poffset == p.length() ) { - vm.error( "malformed pattern (ends with %)" ); - } - return poffset + 1; - - case '[': - if ( p.luaByte( poffset ) == '^' ) poffset++; - do { - if ( poffset == p.length() ) { - vm.error( "malformed pattern (missing ])" ); - } - if ( p.luaByte( poffset++ ) == L_ESC && poffset != p.length() ) - poffset++; - } while ( 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 'w': res = ( cdata & ( MASK_ALPHA | MASK_DIGIT ) ) != 0; break; - case 'x': res = ( cdata & MASK_HEXDIGIT ) != 0; break; - case 'z': res = ( c == 0 ); break; - 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 ) { - 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() ) - vm.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 ( p.luaByte( poffset ) != '[' ) { - vm.error("Missing [ after %f in pattern"); - } - int ep = classend( poffset ); - int previous = ( soffset == 0 ) ? -1 : s.luaByte( soffset - 1 ); - if ( matchbracketclass( previous, poffset, ep - 1 ) || - matchbracketclass( s.luaByte( soffset ), 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; - } - } - } - - 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 ) { - vm.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 && - LString.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 ) { - vm.error( "unbalanced pattern" ); - } - if ( s.luaByte( soff ) != p.luaByte( poff ) ) - return -1; - else { - int b = p.luaByte( poff ); - int e = p.luaByte( poff + 1 ); - int cont = 1; - while ( ++soff < s.length() ) { - 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/lib/TableLib.java b/src/core/org/luaj/lib/TableLib.java deleted file mode 100644 index 0dbdd3f2..00000000 --- a/src/core/org/luaj/lib/TableLib.java +++ /dev/null @@ -1,210 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.lib; - -import java.io.ByteArrayOutputStream; - -import org.luaj.vm.LFunction; -import org.luaj.vm.LNil; -import org.luaj.vm.LString; -import org.luaj.vm.LTable; -import org.luaj.vm.LValue; -import org.luaj.vm.LuaState; - - -public class TableLib extends LFunction { - - public static final String[] NAMES = { - "table", - "concat", - "foreach", - "foreachi", - "getn", - "insert", - "maxn", - "remove", - "sort", - }; - - private static final int INSTALL = 0; - private static final int CONCAT = 1; - private static final int FOREACH = 2; - private static final int FOREACHI = 3; - private static final int GETN = 4; - private static final int INSERT = 5; - private static final int MAXN = 6; - private static final int REMOVE = 7; - private static final int SORT = 8; - - public static void install( LTable globals ) { - LTable table = new LTable(); - for ( int i=1; i= 0 ) { - LValue v = vm.stack[base + a]; - if ( v.isFunction() ) - return (LFunction) v; - } - return null; - } - - /** - * @param vm - * @return register of the current function executing, or null - */ - public int currentfunca(LuaState vm) { - int i = closure.p.code[currentpc()]; - int op = Lua.GET_OPCODE(i); - if ( op == Lua.OP_CALL || op == Lua.OP_TAILCALL ) - return Lua.GETARG_A(i); - return -1; - } - - /** - * Get current program counter or instruction being executed now. - */ - public int currentpc() { - return pc>0? pc-1: 0; - } - -} diff --git a/src/core/org/luaj/vm/DebugNetSupport.java b/src/core/org/luaj/vm/DebugNetSupport.java deleted file mode 100644 index 36f7e082..00000000 --- a/src/core/org/luaj/vm/DebugNetSupport.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.luaj.vm; - -import java.io.IOException; - -public interface DebugNetSupport { - - /** - * Starts the networking for debug support. - * @throws IOException - */ - public abstract void start() throws IOException; - - /** - * Shuts down the networking for the debug support. - */ - public abstract void stop(); - - /** - * Disconnect all connected clients. - */ - public abstract void disconnect(); -} \ No newline at end of file diff --git a/src/core/org/luaj/vm/LBoolean.java b/src/core/org/luaj/vm/LBoolean.java deleted file mode 100644 index d04d4691..00000000 --- a/src/core/org/luaj/vm/LBoolean.java +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - - -public final class LBoolean extends LValue { - - public static final LBoolean TRUE = new LBoolean("true",true); - - public static final LBoolean FALSE = new LBoolean("false",false); - - private final String m_sname; - private final LString m_name; - private final boolean m_value; - - private LBoolean( String name, boolean value ) { - this.m_sname = name; - this.m_name = new LString( name ); - this.m_value = value; - } - - public final String toJavaString() { - return m_sname; - } - - public final LString luaAsString() { - return m_name; - } - - public final boolean toJavaBoolean() { - return m_value; - } - - public final int toJavaInt() { - return m_value? 1: 0; - } - - public final static LBoolean valueOf(boolean value) { - return value? TRUE: FALSE; - } - - public int luaGetType() { - return Lua.LUA_TBOOLEAN; - } -} diff --git a/src/core/org/luaj/vm/LClosure.java b/src/core/org/luaj/vm/LClosure.java deleted file mode 100644 index 4d9dc60f..00000000 --- a/src/core/org/luaj/vm/LClosure.java +++ /dev/null @@ -1,67 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - - - -public class LClosure extends LFunction { - public LPrototype p; - public UpVal[] upVals; - public LTable env; - - - /** - * Construct using a prototype and initial environment. - * @param p - * @param env - */ - protected LClosure(LPrototype p, LTable env) { - this.p = p; - this.env = env; - upVals = new UpVal[p.nups]; - } - - // called by vm when there is an OP_CALL - // in this case, we are on the stack, - // and simply need to cue the VM to treat it as a stack call - public boolean luaStackCall(LuaState vm) { - vm.prepStackCall(); - return true; - } - - /** Set the environment if a thread, or closure, and return 1, otherwise return 0 */ - public boolean luaSetEnv(LTable t) { - this.env = t; - return true; - } - - /** Get the enviroment for this closure */ - public LTable luaGetEnv(LTable d) { - return env; - } - - /** Returns true if this is a lua closure, false otherwise */ - public boolean isClosure() { - return true; - } - -} diff --git a/src/core/org/luaj/vm/LDouble.java b/src/core/org/luaj/vm/LDouble.java deleted file mode 100644 index 3e00c5e2..00000000 --- a/src/core/org/luaj/vm/LDouble.java +++ /dev/null @@ -1,150 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - - -public class LDouble extends LNumber { - - private final double m_value; - - public static LDouble valueOf(double value) { - return new LDouble(value); - } - - /** Convert to LNumber, using LInteger if possible */ - public static LNumber numberOf(double z) { - int iz = (int) z; - return (z==iz? (LNumber) LInteger.valueOf(iz): (LNumber) new LDouble(z)); - } - - public LDouble(double value) { - this.m_value = value; - } - - public int hashCode() { - if ( m_value == 0 ) { - return 0; - } else { - int iz = (int) m_value; - if ( iz == m_value ) return iz; - long bits = Double.doubleToLongBits( m_value ); - return ((int) (bits >> 32)) + ((int)bits); - } - } - - public String toJavaString() { - if ( Double.isNaN(m_value) ) - return "nan"; - if ( Double.isInfinite(m_value) ) - return (m_value>0? "inf": "-inf"); - if ( m_value == 0.0 ) { - long bits = Double.doubleToLongBits( m_value ); - return ( bits >> 63 == 0 ) ? "0" : "-0"; - } - long l = (long) m_value; - if ( (m_value == (double) l) && (m_value <= Long.MAX_VALUE) && (m_value >= Long.MIN_VALUE) ) { - return Long.toString( l ); - } else { - return Double.toString( m_value ); - } - } - - // return true if value survives as an integer - public boolean isInteger() { - return ( (double) ( (int) m_value ) ) == m_value; - } - - // binary operations on integers, first dispatch - public LValue luaBinOpUnknown(int opcode, LValue lhs) { - return lhs.luaBinOpDouble( opcode, this.m_value ); - } - - // binary operations on mixtures of doubles and integers - public LValue luaBinOpInteger(int opcode, int rhs) { - return luaBinOpDoubleDouble( opcode, m_value, (double) rhs ); - } - - // binary operations on doubles - public LValue luaBinOpDouble(int opcode, double rhs) { - return luaBinOpDoubleDouble( opcode, m_value, rhs ); - } - - public static LValue luaBinOpDoubleDouble( int opcode, double lhs, double rhs ) { - switch ( opcode ) { - case Lua.OP_ADD: return LDouble.numberOf( lhs + rhs ); - case Lua.OP_SUB: return LDouble.numberOf( lhs - rhs ); - case Lua.OP_MUL: return LDouble.numberOf( lhs * rhs ); - case Lua.OP_DIV: return LDouble.numberOf( lhs / rhs ); - case Lua.OP_MOD: return LDouble.numberOf( lhs - Math.floor(lhs/rhs) * rhs ); - case Lua.OP_POW: return Platform.getInstance().mathPow( LDouble.numberOf(lhs), LDouble.numberOf(rhs)); - } - LuaState.vmerror( "bad bin opcode" ); - return null; - } - - public int toJavaInt() { - return (int) m_value; - } - - public long toJavaLong() { - return (long) m_value; - } - - public float toJavaFloat() { - return (float) m_value; - } - - public double toJavaDouble() { - return m_value; - } - - // binary compares on integers, first dispatch - public boolean luaBinCmpUnknown(int opcode, LValue lhs) { - return lhs.luaBinCmpDouble( opcode, this.m_value ); - } - - // binary compares on mixtures of doubles and integers - public boolean luaBinCmpInteger(int opcode, int rhs) { - return luaBinCmpDoubleDouble( opcode, m_value, (double) rhs ); - } - - // binary compares on doubles - public boolean luaBinCmpDouble(int opcode, double rhs) { - return luaBinCmpDoubleDouble( opcode, m_value, rhs ); - } - - // compare two doubles - public static boolean luaBinCmpDoubleDouble( int opcode, double lhs, double rhs ) { - switch ( opcode ) { - case Lua.OP_EQ: return lhs == rhs; - case Lua.OP_LT: return lhs < rhs; - case Lua.OP_LE: return lhs <= rhs; - } - LuaState.vmerror( "bad cmp opcode" ); - return false; - } - - /** Arithmetic negative */ - public LValue luaUnaryMinus() { - return new LDouble( -m_value ); - } -} diff --git a/src/core/org/luaj/vm/LFunction.java b/src/core/org/luaj/vm/LFunction.java deleted file mode 100644 index 33133707..00000000 --- a/src/core/org/luaj/vm/LFunction.java +++ /dev/null @@ -1,96 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - - -abstract -public class LFunction extends LValue { - - public String toJavaString() { - return "function: "+hashCode(); - } - - public boolean isFunction() { - return true; - } - - public int luaGetType() { - return Lua.LUA_TFUNCTION; - } - - /** - * Set up a Java invocation, and leave the results on the stack - * starting at base. The default implementation for LFunction - * delegates to the VM which provides convenience. - */ - public boolean luaStackCall(LuaState vm) { - vm.invokeJavaFunction( this ); - return false; - } - - /** - * Called to invoke a JavaFunction. - * - * The implementation should manipulate the stack - * via the VM Java API in the same way that lua_CFunctions - * do so in standard lua. - * - * Arguments to the function will be in position 1-n. - * Return values can be pushed onto the stack, and will be - * copied down to the appropriate location by the calling LuaState. - * - * - * @param lua the LuaState calling this function. - * @return number of results pushed onto the stack. - */ - public int invoke( LuaState lua ) { - return 0; - } - - /** - * Process lua tag method __index when it points to a function. - * Default method calls the function using the vm. - * - * @param vm - * @param table - * @param key - * @return - */ - public LValue __index(LuaState vm, LValue table, LValue key) { - return vm.luaV_call_index(this, table, key); - } - - /** - * Process lua tag method __newindex when it points to a function - * Default method calls the function using the vm. - * - * @param vm - * @param table - * @param key - * @param val - */ - public void __newindex(LuaState vm, LValue table, LValue key, LValue val) { - vm.luaV_call_newindex(this, table, key, val); - } - - -} diff --git a/src/core/org/luaj/vm/LInteger.java b/src/core/org/luaj/vm/LInteger.java deleted file mode 100644 index 2cb50f62..00000000 --- a/src/core/org/luaj/vm/LInteger.java +++ /dev/null @@ -1,136 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - - -public class LInteger extends LNumber { - private final int m_value; - - /* local cache of commonly used LInteger values */ - private static final int INTS_MIN = -16; - private static final int INTS_MAX = 32; - private static final LInteger s_ints[] = new LInteger[1+INTS_MAX-INTS_MIN]; - static { - for ( int i=INTS_MIN; i<=INTS_MAX; i++ ) - s_ints[i-INTS_MIN] = new LInteger(i); - } - - /** Get an LInteger corresponding to a particular int value */ - public static LInteger valueOf(int n) { - if ( n >= INTS_MIN && n <= INTS_MAX ) - return s_ints[n-INTS_MIN]; - return new LInteger(n); - } - - /** use LInteger.valueOf() instead */ - private LInteger(int value) { - this.m_value = value; - } - - public final int hashCode() { - return hashCodeOf( m_value ); - } - - public static int hashCodeOf( int v ) { - return v; - } - - public int toJavaInt() { - return m_value; - } - - public long toJavaLong() { - return m_value; - } - - public float toJavaFloat() { - return m_value; - } - - public double toJavaDouble() { - return m_value; - } - - public LString luaAsString() { - return LString.valueOf(m_value); - } - - public String toJavaString() { - return String.valueOf(m_value); - } - - public boolean isInteger() { - return true; - } - - // binary operations on integers, first dispatch - public LValue luaBinOpUnknown(int opcode, LValue lhs) { - return lhs.luaBinOpInteger( opcode, this.m_value ); - } - - // binary operations on integers - public LValue luaBinOpInteger(int opcode, int rhs) { - switch ( opcode ) { - case Lua.OP_ADD: return LInteger.valueOf( m_value + rhs ); - case Lua.OP_SUB: return LInteger.valueOf( m_value - rhs ); - case Lua.OP_MUL: return LInteger.valueOf( m_value * rhs ); - case Lua.OP_DIV: - case Lua.OP_MOD: - case Lua.OP_POW: - return LDouble.luaBinOpDoubleDouble(opcode, m_value, rhs); - } - LuaState.vmerror( "bad bin opcode" ); - return null; - } - - // binary operations on mixed integer, double - public LValue luaBinOpDouble(int opcode, double rhs) { - return LDouble.luaBinOpDoubleDouble(opcode, (double) m_value, rhs ); - } - - // binary compare for integers, first dispatch - public boolean luaBinCmpUnknown(int opcode, LValue lhs) { - return lhs.luaBinCmpInteger( opcode, this.m_value ); - } - - // unsupported except for numbers - public boolean luaBinCmpInteger(int opcode, int rhs) { - switch ( opcode ) { - case Lua.OP_EQ: return m_value == rhs; - case Lua.OP_LT: return m_value < rhs; - case Lua.OP_LE: return m_value <= rhs; - } - LuaState.vmerror( "bad cmp opcode" ); - return false; - } - - // unsupported except for numbers - public boolean luaBinCmpDouble(int opcode, double rhs) { - return LDouble.luaBinCmpDoubleDouble(opcode, (double) m_value, rhs ); - } - - /** Arithmetic negative */ - public LValue luaUnaryMinus() { - return LInteger.valueOf( -m_value ); - } - -} diff --git a/src/core/org/luaj/vm/LNil.java b/src/core/org/luaj/vm/LNil.java deleted file mode 100644 index bf2ede16..00000000 --- a/src/core/org/luaj/vm/LNil.java +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - - -public final class LNil extends LValue { - public static final LNil NIL = new LNil(); - - public final LString luaAsString() { - return luaGetTypeName(); - } - - public boolean isNil() { - return true; - } - - public boolean toJavaBoolean() { - return false; - } - - public int luaGetType() { - return Lua.LUA_TNIL; - } - - public int toJavaInt() { - return 0; - } - - public String toJavaString() { - return "nil"; - } - - public Byte toJavaBoxedByte() { - return null; - } - - public Character toJavaBoxedCharacter() { - return null; - } - - public Double toJavaBoxedDouble() { - return null; - } - - public Float toJavaBoxedFloat() { - return null; - } - - public Integer toJavaBoxedInteger() { - return null; - } - - public Long toJavaBoxedLong() { - return null; - } - - public Short toJavaBoxedShort() { - return null; - } - -} diff --git a/src/core/org/luaj/vm/LNumber.java b/src/core/org/luaj/vm/LNumber.java deleted file mode 100644 index 4aa550d1..00000000 --- a/src/core/org/luaj/vm/LNumber.java +++ /dev/null @@ -1,104 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - -import java.io.ByteArrayOutputStream; - - -abstract -public class LNumber extends LValue { - - /** Compare for equivalence by using lua op comparator */ - public boolean equals(Object o) { - if ( ! ( o instanceof LValue) ) - return false; - LValue v = (LValue) o; - return this.luaBinCmpUnknown(Lua.OP_EQ, v ); - } - - public int luaGetType() { - return Lua.LUA_TNUMBER; - } - - /** - * Returns false by default for non-LNumbers, but subclasses of LNumber must - * override. - */ - public abstract boolean isInteger(); - - /** - * In lua all numbers are strings ! - */ - public boolean isString() { - return true; - } - - /** Convert to a Byte value */ - public Byte toJavaBoxedByte() { - return new Byte(toJavaByte()); - } - - /** Convert to a boxed Character value */ - public Character toJavaBoxedCharacter() { - return new Character(toJavaChar()); - } - - /** Convert to a boxed Double value */ - public Double toJavaBoxedDouble() { - return new Double(toJavaDouble()); - } - - /** Convert to a boxed Float value */ - public Float toJavaBoxedFloat() { - return new Float(toJavaFloat()); - } - - /** Convert to a boxed Integer value */ - public Integer toJavaBoxedInteger() { - return new Integer(toJavaInt()); - } - - /** Convert to a boxed Long value */ - public Long toJavaBoxedLong() { - return new Long(toJavaLong()); - } - - /** Convert to a boxed Short value */ - public Short toJavaBoxedShort() { - return new Short(toJavaShort()); - } - - /** Convert to a number if possible, or nil otherwise */ - public LValue luaToNumber() { - return this; - } - - /** Write as a string */ - public void luaConcatTo(ByteArrayOutputStream baos) { - luaAsString().luaConcatTo( baos ); - } - - /** Returns true if this is or can be made into a number */ - public boolean isNumber() { - return true; - } -} diff --git a/src/core/org/luaj/vm/LPrototype.java b/src/core/org/luaj/vm/LPrototype.java deleted file mode 100644 index 67eef1e7..00000000 --- a/src/core/org/luaj/vm/LPrototype.java +++ /dev/null @@ -1,77 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - - - -/* -** Function Prototypes -*/ -public class LPrototype { - public LPrototype() { - } - public LClosure newClosure(LTable env) { - return new LClosure(this,env); - } - - /* constants used by the function */ - public LValue[] k; - public int[] code; - /* functions defined inside the function */ - public LPrototype[] p; - /* map from opcodes to source lines */ - public int[] lineinfo; - /* information about local variables */ - public LocVars[] locvars; - /* upvalue names */ - public LString[] upvalues; - public LString source; - public int nups; - public int linedefined; - public int lastlinedefined; - public int numparams; - public int is_vararg; - public int maxstacksize; - - /** Get the name of a local variable. - * - * @param number the local variable number to look up - * @param pc the program counter - * @return the name, or null if not found - */ - public LString getlocalname(int number, int pc) { - int i; - for (i = 0; i=0||i>=j)? - b: - (b<-32||i+1>=j)? - (((b&0x3f) << 6) - | (m_bytes[i++]&0x3f)): - (((b&0xf) << 12) - | ((m_bytes[i++]&0x3f)<<6) - | (m_bytes[i++]&0x3f)) - ); - } - return new String(c,0,n); - } - - /** - * Construct a string from the given byte array. - * - * new LString(b) is identical to new LString(b, 0, b.length) - */ - public LString(byte[] bytes) { - this( bytes, 0, bytes.length ); - } - - /** - * Construct a string from the given byte array and range. For efficiency, - * the byte array is not copied. Lua strings are immutable so the bytes must - * not be modified after the string is constructed. - */ - public LString(byte[] bytes, int off, int len) { - if ( off < 0 || len < 0 || off+len > bytes.length ) - throw new IndexOutOfBoundsException(); - this.m_bytes = bytes; - this.m_offset = off; - this.m_length = len; - this.m_hash = hashBytes( bytes, off, len ); - } - - public static LString newStringCopy(LString src) { - return newStringCopy( src.m_bytes, src.m_offset, src.m_length ); - } - - public static LString newStringCopy(byte[] buf, int off, int len) { - byte[] b = new byte[len]; - System.arraycopy( buf, off, b, 0, len ); - return new LString( b, 0, len ); - } - - public static LString newStringNoCopy(byte[] buf, int off, int len) { - return new LString( buf, off, len ); - } - - /** - * Count the number of bytes required to encode the string as UTF-8. - */ - public static int lengthAsUtf8(String string) { - int n = string.length(); - int b = n; - char c; - for ( int i=0; i= 0x80 ) { - ++b; - if ( c >= 0x800 ) - ++b; - } - } - return b; - } - - /** - * Encode the given Java string as UTF-8 bytes, writing the result to bytes - * starting at offset. The string should be measured first with lengthAsUtf8 - * to make sure the given byte array is large enough. - */ - public static void encodeToUtf8(String string, byte[] bytes, final int startOffset) { - final int n = string.length(); - for ( int i=0, j=startOffset; i>6) & 0x1f)); - bytes[j++] = (byte) (0x80 | ( c & 0x3f)); - } else { - bytes[j++] = (byte) (0xE0 | ((c>>12) & 0x0f)); - bytes[j++] = (byte) (0x80 | ((c>>6) & 0x3f)); - bytes[j++] = (byte) (0x80 | ( c & 0x3f)); - } - } - } - - public boolean isString() { - return true; - } - - public boolean equals(Object o) { - if ( this == o ) - return true; - if ( o != null && o instanceof LString ) { - LString s = (LString) o; - if ( m_hash == s.m_hash && m_length == s.m_length ) { - if ( m_bytes == s.m_bytes && m_offset == s.m_offset ) - return true; - if ( equals( m_bytes, m_offset, s.m_bytes, s.m_offset, m_length ) ) { - if ( m_bytes.length < s.m_bytes.length ) { - s.m_bytes = m_bytes; - s.m_offset = m_offset; - } else { - m_bytes = s.m_bytes; - m_offset = s.m_offset; - } - return true; - } - } - } - return false; - } - - public int compareTo( LString o ) { - final byte[] a = this.m_bytes; - final byte[] b = o.m_bytes; - int i = this.m_offset; - int j = o.m_offset; - final int imax = i + m_length; - final int jmax = j + o.m_length; - - if ( a == b && i == j && imax == jmax ) - return 0; - - while ( i < imax && j < jmax ) { - if ( a[i] != b[j] ) { - return ( ( (int)a[i] ) & 0x0FF ) - ( ( (int)b[j] ) & 0x0FF ); - } - i++; - j++; - } - - return m_length - o.m_length; - } - - public int hashCode() { - return m_hash; - } - - public int length() { - return m_length; - } - - public LString substring( int beginIndex, int endIndex ) { - return new LString( m_bytes, m_offset + beginIndex, endIndex - beginIndex ); - } - - public int charAt( int index ) { - if ( index < 0 || index >= m_length ) - throw new IndexOutOfBoundsException(); - return luaByte( index ); - } - - /** Java version of strpbrk, which is a terribly named C function. */ - public int indexOfAny( LString accept ) { - final int ilimit = m_offset + m_length; - final int jlimit = accept.m_offset + accept.m_length; - for ( int i = m_offset; i < ilimit; ++i ) { - for ( int j = accept.m_offset; j < jlimit; ++j ) { - if ( m_bytes[i] == accept.m_bytes[j] ) { - return i - m_offset; - } - } - } - return -1; - } - - public int indexOf( byte b, int start ) { - for ( int i = m_offset + start; i < m_length; ++i ) { - if ( m_bytes[i] == b ) - return i; - } - return -1; - } - - public int indexOf( LString s, int start ) { - final int slen = s.length(); - final int limit = m_offset + m_length - slen; - for ( int i = m_offset + start; i <= limit; ++i ) { - if ( equals( m_bytes, i, s.m_bytes, s.m_offset, slen ) ) { - return i; - } - } - return -1; - } - - public int lastIndexOf( LString s ) { - final int slen = s.length(); - final int limit = m_offset + m_length - slen; - for ( int i = limit; i >= m_offset; --i ) { - if ( equals( m_bytes, i, s.m_bytes, s.m_offset, slen ) ) { - return i; - } - } - return -1; - } - - public static LString valueOf( double d ) { - return new LString( String.valueOf( d ) ); - } - - public static LString valueOf( int x ) { - return new LString( String.valueOf( x ) ); - } - - public static LString valueOf(String s) { - return new LString( s ); - } - - /** - * Write the specified substring of this string to the given output stream. - */ - public void write( OutputStream os, int offset, int len ) throws IOException { - if ( offset < 0 || len < 0 ) - throw new IndexOutOfBoundsException(); - if ( offset + len > m_length ) - throw new IndexOutOfBoundsException(); - - os.write( m_bytes, m_offset+offset, len ); - } - - public void write(OutputStream os) throws IOException { - write(os, 0, m_length); - } - - /** - * Copy the bytes of the string into the given byte array. - */ - public void copyInto( int strOffset, byte[] bytes, int arrayOffset, int len ) { - System.arraycopy( m_bytes, m_offset+strOffset, bytes, arrayOffset, len ); - } - - /** - * Produce an InputStream instance from which the bytes of this LString can be read. - * Underlying byte array is not copied. - */ - public ByteArrayInputStream toInputStream() { - // Well, this is really something. - // Javadoc for java versions 1.3 and earlier states that if reset() is - // called on a ByteArrayInputStream constructed with the 3-argument - // constructor, then bytes 0 .. offset will be returned by the next - // calls to read(). In JDK 1.4, the behavior improved, so that the - // initial mark is set to the initial offset. We still need to - // override ByteArrayInputStream here just in case we run on a - // JVM with the older behavior. - return new ByteArrayInputStream( m_bytes, m_offset, m_length ) { - public synchronized void reset() { - pos = Math.max( m_offset, mark ); - } - }; - } - - public boolean luaBinCmpUnknown(int opcode, LValue lhs) { - return lhs.luaBinCmpString(opcode, this); - } - - public boolean luaBinCmpString(int opcode, LString rhs) { - switch ( opcode ) { - case Lua.OP_EQ: return equals(rhs); - case Lua.OP_LT: return compareTo(rhs) < 0; - case Lua.OP_LE: return compareTo(rhs) <= 0; - } - LuaState.vmerror( "bad cmp opcode" ); - return false; - } - - public LValue luaBinOpDouble( int opcode, double m_value ) { - return luaToNumber().luaBinOpDouble( opcode, m_value ); - } - - public LValue luaBinOpInteger( int opcode, int m_value ) { - return luaToNumber().luaBinOpInteger( opcode, m_value ); - } - - public LValue luaBinOpUnknown( int opcode, LValue lhs ) { - return luaToNumber().luaBinOpUnknown( opcode, lhs ); - } - - public LValue luaUnaryMinus() { - return luaToNumber().luaUnaryMinus(); - } - - public LValue luaToNumber() { - return luaToNumber( 10 ); - } - - public LValue luaToNumber( int base ) { - if ( base >= 2 && base <= 36 ) { - String str = toJavaString().trim(); - if ( ( base == 10 || base == 16 ) && ( str.startsWith("0x") || str.startsWith("0X") ) ) { - base = 16; - str = str.substring(2); - } - try { - long x = Long.parseLong(str, base); - if (x < Integer.MIN_VALUE || x > Integer.MAX_VALUE) - return new LDouble((double) x); - else - return LInteger.valueOf((int) x); - } catch ( NumberFormatException nfe ) { - if ( base == 10 ) { - try { - return LDouble.numberOf( Double.parseDouble( str ) ); - } catch ( NumberFormatException nfe2 ) { - } - } - } - } - - return LNil.NIL; - } - - public LString luaAsString() { - return this; - } - - /** Built-in opcode LEN, for Strings and Tables */ - public int luaLength() { - return m_length; - } - - public int luaGetType() { - return Lua.LUA_TSTRING; - } - - public LTable luaGetMetatable() { - synchronized ( LString.class ) { - return s_stringMT; - } - } - - /** - * Get the metatable for all string values. Creates the table if it does not - * exist yet, and sets its __index entry to point to itself. - * - * @return metatable that will be used for all strings - */ - public static synchronized LTable getMetatable() { - if ( s_stringMT == null ) { - s_stringMT = new LTable(); - s_stringMT.put( TM_INDEX, s_stringMT ); - } - return s_stringMT; - } - - public static boolean equals( LString a, int i, LString b, int j, int n ) { - return equals( a.m_bytes, a.m_offset + i, b.m_bytes, b.m_offset + j, n ); - } - - public static boolean equals( byte[] a, int i, byte[] b, int j, int n ) { - if ( a.length < i + n || b.length < j + n ) - return false; - while ( --n>=0 ) - if ( a[i++]!=b[j++] ) - return false; - return true; - } - - private static int hashBytes( byte[] bytes, int offset, int length ) { - // Compute the hash of the given bytes. - // This code comes right out of Lua 5.1.2 (translated from C to Java) - int h = length; /* seed */ - int step = (length>>5)+1; /* if string is too long, don't hash all its chars */ - for (int l1=length; l1>=step; l1-=step) /* compute hash */ - h = h ^ ((h<<5)+(h>>2)+(((int) bytes[offset+l1-1] ) & 0x0FF )); - return h; - } - - public int luaByte(int index) { - return m_bytes[m_offset + index] & 0x0FF; - } - - public void luaConcatTo(ByteArrayOutputStream baos) { - baos.write( m_bytes, m_offset, m_length ); - } - - /** Returns true if this is or can be made into a number */ - public boolean isNumber() { - return ! this.luaToNumber().isNil(); - } - - -} diff --git a/src/core/org/luaj/vm/LTable.java b/src/core/org/luaj/vm/LTable.java deleted file mode 100644 index 409e0cdc..00000000 --- a/src/core/org/luaj/vm/LTable.java +++ /dev/null @@ -1,683 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - -import java.util.Vector; - -import org.luaj.vm.LFunction; -import org.luaj.vm.LInteger; -import org.luaj.vm.LNil; -import org.luaj.vm.LString; -import org.luaj.vm.LValue; -import org.luaj.vm.Lua; -import org.luaj.vm.LuaErrorException; -import org.luaj.vm.LuaState; - -/** - * Simple implementation of table structure for Lua VM. Maintains both an array - * part and a hash part. Does not attempt to achieve the same performance as the - * C version. - * - * Java code can put values in the table or get values out (bypassing the - * metatable, if there is one) using put() and get(). There are specializations - * of put() and get() for integers and Strings to avoid allocating wrapper - * objects when possible. - * - * remove() methods are private: setting a key's value to nil is the correct way - * to remove an entry from the table. - * - * - */ -public class LTable extends LValue { - - protected Object[] array; - protected LValue[] hashKeys; - protected Object[] hashValues; - private int hashEntries; - private LTable m_metatable; - - private static final int MIN_HASH_CAPACITY = 2; - private static final LValue[] NONE = {}; - - - /** Construct an empty LTable with no initial capacity. */ - public LTable() { - array = NONE; - hashKeys = NONE; - } - - /** - * Construct an empty LTable that is expected to contain entries with keys - * in the range 1 .. narray and nhash non-integer keys. - */ - public LTable( int narray, int nhash ) { - if ( nhash > 0 && nhash < MIN_HASH_CAPACITY ) - nhash = MIN_HASH_CAPACITY; - array = new Object[narray]; - hashKeys = new LValue[nhash]; - hashValues = new Object[nhash]; - } - - public boolean isTable() { - return true; - - } - /** Get capacity of hash part */ - public int getArrayCapacity() { - return array.length; - } - - /** Get capacity of hash part */ - public int getHashCapacity() { - return hashKeys.length; - } - - /** - * Return total number of keys mapped to non-nil values. Not to be confused - * with luaLength, which returns some number n such that the value at n+1 is - * nil. - * - * @deprecated this is not scalable. Does a linear search through the table. Use luaLength() instead. - */ - public int size() { - int count = 0; - for ( int i=array.length; --i>=0; ) - if ( array[i] != null ) - count++; - for ( int i=hashKeys.length; --i>=0; ) - if ( hashKeys[i] != null ) - count++; - return count; - } - - /** - * Generic put method for all types of keys, but does not use the metatable. - */ - public void put( LValue key, LValue val ) { - if ( key.isInteger() ) { - int pos = key.toJavaInt() - 1; - int n = array.length; - if ( pos>=0 && pos<=n ) { - if ( pos == n ) - expandArrayPart(); - array[pos] = normalizePut(val); - return; - } - } - hashSet( key, normalizePut(val) ); - } - - /** - * Method for putting an integer-keyed value. Bypasses the metatable, if - * any. - */ - public void put( int key, LValue val ) { - int pos = key - 1; - int n = array.length; - if ( pos>=0 && pos<=n ) { - if ( pos == n ) - expandArrayPart(); - array[pos] = normalizePut(val); - } else { - hashSet( LInteger.valueOf(key), normalizePut(val) ); - } - } - - /** - * Utility method for putting a string-keyed value directly, typically for - * initializing a table. Bypasses the metatable, if any. - */ - public void put( String key, LValue val ) { - hashSet( LString.valueOf(key), normalizePut(val) ); - } - - /** - * Utility method for putting a string key, int value directly, typically for - * initializing a table. Bypasses the metatable, if any. - */ - public void put( String key, int val ) { - hashSet( LString.valueOf(key), LInteger.valueOf(val) ); - } - - /** - * Expand the array part of the backing for more values to fit in. - */ - private void expandArrayPart() { - int n = array.length; - int m = Math.max(2,n*2); - arrayExpand(m); - for ( int i=n; i0 && ikey<=array.length ) - return normalizeGet(array[ikey-1]); - } - return normalizeGet(hashGet(key)); - } - - - - /** Utility method for retrieving an integer-keyed value */ - public LValue get( int key ) { - return normalizeGet( key>0 && key<=array.length? - array[key-1]: - hashGet(LInteger.valueOf(key)) ); - } - - /** Check for null, and convert to nilor leave alone - */ - protected LValue normalizeGet(Object val) { - return val==null? LNil.NIL: (LValue) val; - } - - /** - * Return true if the table contains an entry with the given key, - * false if not. Ignores the metatable. - */ - public boolean containsKey( LValue key ) { - if ( key.isInteger() ) { - int ikey = key.toJavaInt(); - if ( ikey>0 && ikey<=array.length ) - return null != array[ikey-1]; - } - return null != hashGet(key); - } - - /** - * Return true if the table contains an entry with the given integer-valued key, - * false if not. Ignores the metatable. - */ - public boolean containsKey( int key ) { - return (key>0 && key<=array.length? - array[key-1] != null: - (hashKeys.length>0 && hashKeys[hashFindSlot(LInteger.valueOf(key))]!=null)); - } - - private static final int MAX_KEY = 0x3fffffff; - - /** - * Try to find a boundary in table `t'. A `boundary' is an integer index - * such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). - */ - public int luaLength() { - - // find `i' and `j' such that i is present and j is not - int i = 0; - int j = array.length; - if (j<=0 || containsKey(j)) { - if ( hashKeys.length == 0 ) - return j; - for ( ++j; containsKey(j) && j < MAX_KEY; j*=2 ) - i = j; - } - - // binary search - while ( j - i > 1) { - int m = (i+j) / 2; - if ( ! containsKey(m) ) - j = m; - else - i = m; - } - return i; - } - - /** Valid for tables */ - public LTable luaGetMetatable() { - return this.m_metatable; - } - - /** Valid for tables */ - public LTable luaSetMetatable(LValue metatable) { - if ( m_metatable != null && m_metatable.containsKey(TM_METATABLE) ) - throw new LuaErrorException("cannot change a protected metatable"); - if ( metatable == null || metatable.isNil() ) - this.m_metatable = null; - else if ( metatable.luaGetType() == Lua.LUA_TTABLE ) { - org.luaj.vm.LTable t = (org.luaj.vm.LTable) metatable; - LValue m = t.get(TM_MODE); - if ( m.isString() && m.toJavaString().indexOf('v')>=0 ) { - LTable w = new LWeakTable(this); - w.m_metatable = t; - return w; - } - this.m_metatable = t; - } else { - throw new LuaErrorException("not a table: "+metatable.luaGetTypeName()); - } - return this; - } - - public String toJavaString() { - return "table: "+id(); - } - - public int luaGetType() { - return Lua.LUA_TTABLE; - } - - /** - * Helper method to get all the keys in this table in an array. Meant to be - * used instead of keys() (which returns an enumeration) when an array is - * more convenient. Note that for a very large table, getting an Enumeration - * instead would be more space efficient. - * - * @deprecated this is not scalable. Does a linear search through the table. - */ - public LValue[] getKeys() { - int n = array.length; - int o = hashKeys.length; - LValue k; - Vector v = new Vector(); - - // array parts - for ( int pos=0; pos n ) - return LNil.NIL; - - LValue removed = get(ikey); - LValue replaced; - do { - put(ikey, replaced=get(ikey+1)); - ikey++; - } while ( ! replaced.isNil() ); - return removed; - } - - /** - * Returns the largest positive numerical index of the given table, - * or zero if the table has no positive numerical indices. - * (To do its job this function does a linear traversal of the whole table.) - * @return LValue that is the largest int - */ - public LValue luaMaxN() { - int n = array.length; - int m = hashKeys.length; - int r = Integer.MIN_VALUE; - - // array part - for ( int i=n; --i>=0; ) { - if ( array[i] != null ) { - r = i+1; - break; - } - } - - // hash part - for ( int i=0; i r ) - r = k; - } - } - - return LInteger.valueOf( r == Integer.MIN_VALUE? 0: r ); - } - - // ----------------- sort support ----------------------------- - // - // implemented heap sort from wikipedia - // - public void luaSort(LuaState vm, LValue compare) { - heapSort(luaLength(), vm, compare); - } - - private void heapSort(int count, LuaState vm, LValue cmpfunc) { - heapify(count, vm, cmpfunc); - for ( int end=count-1; end>0; ) { - swap(end, 0); - siftDown(0, --end, vm, cmpfunc); - } - } - - private void heapify(int count, LuaState vm, LValue cmpfunc) { - for ( int start=count/2-1; start>=0; --start ) - siftDown(start, count - 1, vm, cmpfunc); - } - - private void siftDown(int start, int end, LuaState vm, LValue cmpfunc) { - for ( int root=start; root*2+1 <= end; ) { - int child = root*2+1; - if (child < end && compare(child, child + 1, vm, cmpfunc)) - ++child; - if (compare(root, child, vm, cmpfunc)) { - swap(root, child); - root = child; - } else - return; - } - } - - private boolean compare(int i, int j, LuaState vm, LValue cmpfunc) { - LValue a = get(i+1); - LValue b = get(j+1); - if ( a.isNil() || b.isNil() ) - return false; - if ( ! cmpfunc.isNil() ) { - vm.pushlvalue(cmpfunc); - vm.pushlvalue(a); - vm.pushlvalue(b); - vm.call(2, 1); - boolean result = vm.toboolean(-1); - vm.resettop(); - return result; - } else { - return b.luaBinCmpUnknown( Lua.OP_LT, a ); - } - } - - private void swap(int i, int j) { - LValue a = get(i+1); - put(i+1, get(j+1)); - put(j+1, a); - } - - /** - * Leave key,value pair on top, or nil if at end of list. - * @param vm the LuaState to leave the values on - * @param indexedonly TODO - * @param index index to start search - * @return true if next exists, false if at end of list - */ - public boolean next(LuaState vm, LValue key, boolean indexedonly ) { - - int n = array.length; - int m = (indexedonly? -1: hashKeys.length); - int i = findindex(key, n, m); - if ( i < 0 ) - vm.error( "invalid key to 'next'" ); - - // check array part - for ( ; i 0 ) { - int slot = hashFindSlot( key ); - hashClearSlot( slot ); - } - } - - protected void hashClearSlot( int i ) { - if ( hashKeys[ i ] != null ) { - - int j = i; - int n = hashKeys.length; - while ( hashKeys[ j = ( ( j + 1 ) % n ) ] != null ) { - final int k = ( ( hashKeys[ j ].hashCode() )& 0x7FFFFFFF ) % n; - if ( ( j > i && ( k <= i || k > j ) ) || - ( j < i && ( k <= i && k > j ) ) ) { - hashKeys[ i ] = hashKeys[ j ]; - hashValues[ i ] = hashValues[ j ]; - i = j; - } - } - - --hashEntries; - hashKeys[ i ] = null; - hashValues[ i ] = null; - - if ( hashEntries == 0 ) { - hashKeys = NONE; - hashValues = null; - } - } - } - - protected boolean checkLoadFactor() { - // Using a load factor of 2/3 because that is easy to compute without - // overflow or division. - final int hashCapacity = hashKeys.length; - return ( hashCapacity >> 1 ) >= ( hashCapacity - hashEntries ); - } - - protected void rehash() { - final int oldCapacity = hashKeys.length; - final int newCapacity = ( oldCapacity > 0 ) ? 2 * oldCapacity : MIN_HASH_CAPACITY; - - final LValue[] oldKeys = hashKeys; - final Object[] oldValues = hashValues; - - hashKeys = new LValue[ newCapacity ]; - hashValues = new Object[ newCapacity ]; - - for ( int i = 0; i < oldCapacity; ++i ) { - final LValue k = oldKeys[i]; - if ( k != null ) { - final Object v = oldValues[i]; - final int slot = hashFindSlot( k ); - hashKeys[slot] = k; - hashValues[slot] = v; - } - } - } -} diff --git a/src/core/org/luaj/vm/LThread.java b/src/core/org/luaj/vm/LThread.java deleted file mode 100644 index 4cdff1ce..00000000 --- a/src/core/org/luaj/vm/LThread.java +++ /dev/null @@ -1,182 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - - - -/** - * Implementation of lua coroutines using Java Threads - */ -public class LThread extends LValue implements Runnable { - - private static final boolean USE_JAVA_THREADS = true; - - private static final int STATUS_SUSPENDED = 0; - private static final int STATUS_RUNNING = 1; - private static final int STATUS_NORMAL = 2; - private static final int STATUS_DEAD = 3; - private static final String[] NAMES = { - "suspended", - "running", - "normal", - "dead" }; - - private int status = STATUS_SUSPENDED; - - public final LuaState vm; - private Thread thread; - - static LThread running; - public LThread(LFunction c, LTable env) { - vm = new LuaState(env); - vm.pushlvalue(c); - } - - public int luaGetType() { - return Lua.LUA_TTHREAD; - } - - public String toJavaString() { - return "thread: "+hashCode(); - } - - // Set the environment if a thread, or closure, and return 1, otherwise return 0 - public boolean luaSetEnv(LTable t) { - vm._G = t; - return true; - } - - public String getStatus() { - return NAMES[status]; - } - - public static LThread getRunning() { - return running; - } - - public void run() { - synchronized ( this ) { - try { - vm.execute(); - } finally { - status = STATUS_DEAD; - this.notify(); - } - } - } - - public void yield() { - synchronized ( this ) { - if ( status != STATUS_RUNNING ) - vm.error(this+" not running"); - status = STATUS_SUSPENDED; - if ( USE_JAVA_THREADS ) { - this.notify(); - try { - this.wait(); - status = STATUS_RUNNING; - } catch ( InterruptedException e ) { - status = STATUS_DEAD; - vm.error(this+" "+e); - } - } - } - } - - // This needs to leave any values returned by yield in the coroutine - // on the calling vm stack - // @param vm - // @param nargs - // - public void resumeFrom(LuaState vm, int nargs) { - - synchronized ( this ) { - if ( status == STATUS_DEAD ) { - vm.resettop(); - vm.pushboolean(false); - vm.pushstring("cannot resume dead coroutine"); - return; - } - - // set prior thread to normal status while we are running - LThread prior = running; - try { - // set our status to running - if ( prior != null ) - prior.status = STATUS_NORMAL; - running = this; - status = STATUS_RUNNING; - - // copy args in - if (this.vm.cc < 0) { - vm.xmove(this.vm, nargs); - this.vm.prepStackCall(); - } else { - this.vm.resettop(); - vm.xmove(this.vm, nargs); - } - - // execute in the other thread - if ( USE_JAVA_THREADS ) { - // start the thread - if ( thread == null ) { - thread = new Thread(this); - thread.start(); - } - - // run this vm until it yields - this.notify(); - this.wait(); - } else { - // run this vm until it yields - while (this.vm.cc >= 0 && status == STATUS_RUNNING) - this.vm.exec(); - } - - // copy return values from yielding stack state - vm.resettop(); - if ( this.vm.cc >= 0 ) { - vm.pushboolean(status != STATUS_DEAD); - this.vm.xmove(vm, this.vm.gettop()); - } else { - vm.pushboolean(true); - this.vm.base = 0; - this.vm.xmove(vm, this.vm.gettop()); - } - - } catch ( Throwable t ) { - status = STATUS_DEAD; - vm.resettop(); - vm.pushboolean(false); - vm.pushstring("thread: "+t); - if ( USE_JAVA_THREADS ) { - this.notify(); - } - - } finally { - // previous thread is now running again - running = prior; - } - } - - } -} diff --git a/src/core/org/luaj/vm/LUserData.java b/src/core/org/luaj/vm/LUserData.java deleted file mode 100644 index 21ac2afc..00000000 --- a/src/core/org/luaj/vm/LUserData.java +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - - -public class LUserData extends LValue { - - public final Object m_instance; - public LTable m_metatable; - - public LUserData(Object obj) { - m_instance = obj; - } - - public LUserData(Object obj, LTable metatable) { - m_instance = obj; - m_metatable = metatable; - } - - public String toJavaString() { - return String.valueOf(m_instance); - } - - public boolean equals(Object obj) { - return (this == obj) || - (obj instanceof LUserData && this.m_instance == ((LUserData) obj).m_instance); - } - - public int hashCode() { - return System.identityHashCode( m_instance ); - } - - public int luaGetType() { - return Lua.LUA_TUSERDATA; - } - - public LTable luaGetMetatable() { - return m_metatable; - } - - public Object toJavaInstance() { - return m_instance; - } - - public boolean luaBinCmpUnknown( int opcode, LValue lhs ) { - if ( opcode == Lua.OP_EQ ) - return lhs.equals( this ); - return super.luaBinCmpUnknown( opcode, lhs ); - } - - public boolean isUserData() { - return true; - } -} diff --git a/src/core/org/luaj/vm/LValue.java b/src/core/org/luaj/vm/LValue.java deleted file mode 100644 index cfad9c8f..00000000 --- a/src/core/org/luaj/vm/LValue.java +++ /dev/null @@ -1,363 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - -import java.io.ByteArrayOutputStream; - - -abstract -public class LValue { - - /** Metatable tag for intercepting table gets */ - public static final LString TM_INDEX = new LString("__index"); - - /** Metatable tag for intercepting table sets */ - public static final LString TM_NEWINDEX = new LString("__newindex"); - - /** Metatable tag for intercepting table sets */ - public static final LString TM_METATABLE = new LString("__metatable"); - - /** Metatable tag for setting table mode */ - public static final LString TM_MODE = new LString("__mode"); - - private static final int MAXTAGLOOP = 100; - - protected void conversionError(String target) { - throw new LuaErrorException( "bad conversion: "+luaGetTypeName()+" to "+target ); - } - - private static LValue arithmeticError( Object type ) { - throw new LuaErrorException( "attempt to perform arithmetic on ? (a "+type+" value)" ); - } - - protected static LValue compareError( Object typea, Object typeb ) { - throw new LuaErrorException( "attempt to compare "+typea+" with "+typeb ); - } - - private LValue indexError(LuaState vm, LValue nontable) { - vm.error( "attempt to index ? (a "+nontable.luaGetTypeName()+" value)" ); - return LNil.NIL; - } - - public String id() { - return Integer.toHexString(hashCode()); - } - - /** Return true if this value can be represented as an "int" */ - public boolean isInteger() { - return false; - } - - /** Return true if this value is LNil.NIL, false otherwise */ - public boolean isNil() { - return false; - } - - // perform a lua call, return true if the call is to a lua function, false - // if it ran to completion. - public boolean luaStackCall(LuaState vm) { - vm.error("attempt to call "+this); - return false; - } - - // unsupported except for numbers - public LValue luaBinOpUnknown(int opcode, LValue lhs) { - return arithmeticError(luaGetTypeName()); - } - - // unsupported except for numbers - public LValue luaBinOpInteger(int opcode, int m_value) { - return arithmeticError(luaGetTypeName()); - } - - // unsupported except for numbers - public LValue luaBinOpDouble(int opcode, double m_value) { - return arithmeticError(luaGetTypeName()); - } - - // unsupported except for numbers, strings, and == with various combinations of Nil, Boolean, etc. - public boolean luaBinCmpUnknown(int opcode, LValue lhs) { - if ( opcode == Lua.OP_EQ ) - return lhs == this; - compareError(lhs.luaGetTypeName(), luaGetTypeName()); - return false; - } - - // unsupported except for strings - public boolean luaBinCmpString(int opcode, LString rhs) { - if ( opcode == Lua.OP_EQ ) - return false; - compareError(luaGetTypeName(), "string"); - return false; - } - - // unsupported except for numbers - public boolean luaBinCmpInteger(int opcode, int rhs) { - if ( opcode == Lua.OP_EQ ) - return false; - compareError(luaGetTypeName(), "number"); - return false; - } - - // unsupported except for numbers - public boolean luaBinCmpDouble(int opcode, double rhs) { - if ( opcode == Lua.OP_EQ ) - return false; - compareError(luaGetTypeName(), "number"); - return false; - } - - /** Dispatch a settable operation. - * Default method delegates back to the vm for metatable processing. - */ - public void luaSetTable(LuaState vm, LValue key, LValue val) { - vm.luaV_settable(this, key, val); - } - - - /** Dispatch a gettable operation. - * Default method delegates back to the vm for metatable processing. - */ - public LValue luaGetTable(LuaState vm, LValue key) { - return vm.luaV_gettable(this, key); - } - - /** Get the value as a LString - */ - public LString luaAsString() { - return new LString(toJavaString()); - } - - /** Override standard toString with lua String conversion by default */ - public String toString() { - return toJavaString(); - } - - /** Arithmetic negative */ - public LValue luaUnaryMinus() { - return arithmeticError(luaGetTypeName()); - } - - /** Built-in opcode LEN, for Strings and Tables */ - public int luaLength() { - throw new LuaErrorException( "attempt to get length of ? (a "+luaGetTypeName()+" value)" ); - } - - /** - * Valid for all types: get a metatable. Only tables and userdata can have a - * different metatable per instance, though, other types are restricted to - * one metatable per type. - * - * Since metatables on non-tables can only be set through Java and not Lua, - * this function should be overridden for each value type as necessary. - * - * @return null if there is no meta-table - */ - public LTable luaGetMetatable() { - return null; - } - - /** Valid for tables - * @param the new LTable, or null or LNil.NIL to reset the metatable to none - * @return this if unchanged, or new LTable if copied using weak table - */ - public LTable luaSetMetatable(LValue metatable) { - throw new LuaErrorException( "cannot set metatable for "+this.luaGetTypeName()); - } - - /** Valid for all types: return the int value identifying the type of this value */ - abstract public int luaGetType(); - - - /** Valid for all types: return the type of this value as an LString */ - public LString luaGetTypeName() { - return LString.LTYPENAMES[luaGetType()]; - } - - - /** Convert to a Java String */ - public String toJavaString() { - return null; - } - - /** Return value as a boolean */ - public boolean toJavaBoolean() { - return true; - } - - /** Return value as a byte */ - public byte toJavaByte() { - conversionError("number"); - return 0; - } - - /** Return value as a char */ - public char toJavaChar() { - conversionError("number"); - return 0; - } - - /** Return value as a double */ - public double toJavaDouble() { - conversionError("number"); - return 0; - } - - /** Return value as a float */ - public float toJavaFloat() { - conversionError("number"); - return 0; - } - - /** Return value as an integer */ - public int toJavaInt() { - conversionError("number"); - return 0; - } - - /** Return value as a long */ - public long toJavaLong() { - conversionError("number"); - return 0; - } - - /** Return value as a double */ - public short toJavaShort() { - conversionError("number"); - return 0; - } - - /** Convert to a Boolean value */ - public Boolean toJavaBoxedBoolean() { - conversionError("Boolean"); - return null; - } - - /** Convert to a Byte value */ - public Byte toJavaBoxedByte() { - conversionError("Byte"); - return null; - } - - /** Convert to a boxed Character value */ - public Character toJavaBoxedCharacter() { - conversionError("Character"); - return null; - } - - /** Convert to a boxed Double value */ - public Double toJavaBoxedDouble() { - conversionError("Double"); - return null; - } - - /** Convert to a boxed Float value */ - public Float toJavaBoxedFloat() { - conversionError("Float"); - return null; - } - - /** Convert to a boxed Integer value */ - public Integer toJavaBoxedInteger() { - conversionError("Integer"); - return null; - } - - /** Convert to a boxed Long value */ - public Long toJavaBoxedLong() { - conversionError("Long"); - return null; - } - - /** Convert to a boxed Short value */ - public Short toJavaBoxedShort() { - conversionError("Short"); - return null; - } - - /** Convert to a Java Object iff this is a LUserData value */ - public Object toJavaInstance() { - conversionError("instance"); - return null; - } - - /** Set the environment if a thread, or closure, and return true, otherwise return false */ - public boolean luaSetEnv(LTable t) { - return false; - } - - /** Get the environment of the object if it is a closure, or d if not a closure. - * @param d global environment to return if this is not a closure - */ - public LTable luaGetEnv(LTable d) { - return d; - } - - - /** Convert to a number if possible, or nil otherwise */ - public LValue luaToNumber() { - return LNil.NIL; - } - - /** Dereference a potentially weak reference, and return the value */ - public LValue toStrongReference() { - return this; - } - - /** Concatenate this value to a ByteArrayOutputStream */ - public void luaConcatTo(ByteArrayOutputStream baos) { - throw new LuaErrorException( "attempt to concatenate "+luaGetTypeName() ); - } - - /** Return true if this is a lua string, meaning it is - * either a LString or LNumber,since all numbers are - * convertible to strings in lua - */ - public boolean isString() { - return false; - } - - /** Return true if this is a LTable */ - public boolean isTable() { - return false; - } - - /** Return true if this is a LFunction */ - public boolean isFunction() { - return false; - } - - /** Returns true if this is an LUserData */ - public boolean isUserData() { - return false; - } - - /** Returns true if this is or can be made into a number */ - public boolean isNumber() { - return false; - } - - /** Returns true if this is a lua closure, false otherwise */ - public boolean isClosure() { - return false; - } -} diff --git a/src/core/org/luaj/vm/LWeakTable.java b/src/core/org/luaj/vm/LWeakTable.java deleted file mode 100644 index fccd6a84..00000000 --- a/src/core/org/luaj/vm/LWeakTable.java +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2008 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.vm; - -import java.lang.ref.WeakReference; - -import org.luaj.vm.LNil; -import org.luaj.vm.LValue; - -public class LWeakTable extends LTable { - - public LWeakTable() { - super(); - } - - public LWeakTable(int narray, int nhash) { - super(narray, nhash); - } - - public LWeakTable(LTable copy) { - super( copy.array.length, copy.hashKeys.length ); - for ( int i=0, k=1, n=copy.array.length; i> 52) & 0x7ffL) - 1023; - - if ( e >= 0 && e < 31 ) { - long f = bits & 0xFFFFFFFFFFFFFL; - int shift = 52 - e; - long intPrecMask = ( 1L << shift ) - 1; - if ( ( f & intPrecMask ) == 0 ) { - int intValue = (int)( f >> shift ) | ( 1 << e ); - return LInteger.valueOf( ( ( bits >> 63 ) != 0 ) ? -intValue : intValue ); - } - } - - double value = Double.longBitsToDouble(bits); - return LDouble.numberOf( value ); - } - - LNumber loadNumber() throws IOException { - if ( luacNumberFormat == DumpState.NUMBER_FORMAT_INTS_ONLY ) { - return LInteger.valueOf( loadInt() ); - } else { - return longBitsToLuaNumber( loadInt64() ); - } - } - - void loadConstants(LPrototype f) throws IOException { - int n = loadInt(); - LValue[] values = new LValue[n]; - for ( int i=0; i>1); /* `sBx' is signed */ - - public static final int MASK_OP = ((1<> POS_OP) & MAX_OP; - } - - public static int GETARG_A(int i) { - return (i >> POS_A) & MAXARG_A; - } - - public static int GETARG_B(int i) { - return (i >> POS_B) & MAXARG_B; - } - - public static int GETARG_C(int i) { - return (i >> POS_C) & MAXARG_C; - } - - public static int GETARG_Bx(int i) { - return (i >> POS_Bx) & MAXARG_Bx; - } - - public static int GETARG_sBx(int i) { - return ((i >> POS_Bx) & MAXARG_Bx) - MAXARG_sBx; - } - - - /* - ** Macros to operate RK indices - */ - - /** this bit 1 means constant (0 means register) */ - public static final int BITRK = (1 << (SIZE_B - 1)); - - /** test whether value is a constant */ - public static boolean ISK(int x) { - return 0 != ((x) & BITRK); - } - - /** gets the index of the constant */ - public static int INDEXK(int r) { - return ((int)(r) & ~BITRK); - } - - public static final int MAXINDEXRK = (BITRK - 1); - - /** code a constant index as a RK value */ - public static int RKASK(int x) { - return ((x) | BITRK); - } - - - /** - ** invalid register that fits in 8 bits - */ - public static final int NO_REG = MAXARG_A; - - - /* - ** R(x) - register - ** Kst(x) - constant (in constant table) - ** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x) - */ - - - /* - ** grep "ORDER OP" if you change these enums - */ - - /*---------------------------------------------------------------------- - name args description - ------------------------------------------------------------------------*/ - public static final int OP_MOVE = 0;/* A B R(A) := R(B) */ - public static final int OP_LOADK = 1;/* A Bx R(A) := Kst(Bx) */ - public static final int OP_LOADBOOL = 2;/* A B C R(A) := (Bool)B; if (C) pc++ */ - public static final int OP_LOADNIL = 3; /* A B R(A) := ... := R(B) := nil */ - public static final int OP_GETUPVAL = 4; /* A B R(A) := UpValue[B] */ - - public static final int OP_GETGLOBAL = 5; /* A Bx R(A) := Gbl[Kst(Bx)] */ - public static final int OP_GETTABLE = 6; /* A B C R(A) := R(B)[RK(C)] */ - - public static final int OP_SETGLOBAL = 7; /* A Bx Gbl[Kst(Bx)] := R(A) */ - public static final int OP_SETUPVAL = 8; /* A B UpValue[B] := R(A) */ - public static final int OP_SETTABLE = 9; /* A B C R(A)[RK(B)] := RK(C) */ - - public static final int OP_NEWTABLE = 10; /* A B C R(A) := {} (size = B,C) */ - - public static final int OP_SELF = 11; /* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */ - - public static final int OP_ADD = 12; /* A B C R(A) := RK(B) + RK(C) */ - public static final int OP_SUB = 13; /* A B C R(A) := RK(B) - RK(C) */ - public static final int OP_MUL = 14; /* A B C R(A) := RK(B) * RK(C) */ - public static final int OP_DIV = 15; /* A B C R(A) := RK(B) / RK(C) */ - public static final int OP_MOD = 16; /* A B C R(A) := RK(B) % RK(C) */ - public static final int OP_POW = 17; /* A B C R(A) := RK(B) ^ RK(C) */ - public static final int OP_UNM = 18; /* A B R(A) := -R(B) */ - public static final int OP_NOT = 19; /* A B R(A) := not R(B) */ - public static final int OP_LEN = 20; /* A B R(A) := length of R(B) */ - - public static final int OP_CONCAT = 21; /* A B C R(A) := R(B).. ... ..R(C) */ - - public static final int OP_JMP = 22; /* sBx pc+=sBx */ - - public static final int OP_EQ = 23; /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ - public static final int OP_LT = 24; /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ - public static final int OP_LE = 25; /* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ - - public static final int OP_TEST = 26; /* A C if not (R(A) <=> C) then pc++ */ - public static final int OP_TESTSET = 27; /* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ - - public static final int OP_CALL = 28; /* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ - public static final int OP_TAILCALL = 29; /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ - public static final int OP_RETURN = 30; /* A B return R(A), ... ,R(A+B-2) (see note) */ - - public static final int OP_FORLOOP = 31; /* A sBx R(A)+=R(A+2); - if R(A) =) R(A)*/ - public static final int OP_CLOSURE = 36; /* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ - - public static final int OP_VARARG = 37; /* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ - - - public static final int NUM_OPCODES = OP_VARARG + 1; - - - - /*=========================================================================== - Notes: - (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, - and can be 0: OP_CALL then sets `top' to last_result+1, so - next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. - - (*) In OP_VARARG, if (B == 0) then use actual number of varargs and - set top (like in OP_CALL with C == 0). - - (*) In OP_RETURN, if (B == 0) then return up to `top' - - (*) In OP_SETLIST, if (B == 0) then B = `top'; - if (C == 0) then next `instruction' is real C - - (*) For comparisons, A specifies what condition the test should accept - (true or false). - - (*) All `skips' (pc++) assume that next instruction is a jump - ===========================================================================*/ - - - /* - ** masks for instruction properties. The format is: - ** bits 0-1: op mode - ** bits 2-3: C arg mode - ** bits 4-5: B arg mode - ** bit 6: instruction set register A - ** bit 7: operator is a test - */ - - public static final int OpArgN = 0; /* argument is not used */ - public static final int OpArgU = 1; /* argument is used */ - public static final int OpArgR = 2; /* argument is a register or a jump offset */ - public static final int OpArgK = 3; /* argument is a constant or register/constant */ - - public static final int[] luaP_opmodes = { - /* T A B C mode opcode */ - (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_MOVE */ - (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgN<<2) | (iABx), /* OP_LOADK */ - (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC), /* OP_LOADBOOL */ - (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_LOADNIL */ - (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABC), /* OP_GETUPVAL */ - (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgN<<2) | (iABx), /* OP_GETGLOBAL */ - (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgK<<2) | (iABC), /* OP_GETTABLE */ - (0<<7) | (0<<6) | (OpArgK<<4) | (OpArgN<<2) | (iABx), /* OP_SETGLOBAL */ - (0<<7) | (0<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABC), /* OP_SETUPVAL */ - (0<<7) | (0<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_SETTABLE */ - (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC), /* OP_NEWTABLE */ - (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgK<<2) | (iABC), /* OP_SELF */ - (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_ADD */ - (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_SUB */ - (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_MUL */ - (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_DIV */ - (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_MOD */ - (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_POW */ - (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_UNM */ - (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_NOT */ - (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_LEN */ - (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgR<<2) | (iABC), /* OP_CONCAT */ - (0<<7) | (0<<6) | (OpArgR<<4) | (OpArgN<<2) | (iAsBx), /* OP_JMP */ - (1<<7) | (0<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_EQ */ - (1<<7) | (0<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_LT */ - (1<<7) | (0<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_LE */ - (1<<7) | (1<<6) | (OpArgR<<4) | (OpArgU<<2) | (iABC), /* OP_TEST */ - (1<<7) | (1<<6) | (OpArgR<<4) | (OpArgU<<2) | (iABC), /* OP_TESTSET */ - (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC), /* OP_CALL */ - (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC), /* OP_TAILCALL */ - (0<<7) | (0<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABC), /* OP_RETURN */ - (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iAsBx), /* OP_FORLOOP */ - (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iAsBx), /* OP_FORPREP */ - (1<<7) | (0<<6) | (OpArgN<<4) | (OpArgU<<2) | (iABC), /* OP_TFORLOOP */ - (0<<7) | (0<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC), /* OP_SETLIST */ - (0<<7) | (0<<6) | (OpArgN<<4) | (OpArgN<<2) | (iABC), /* OP_CLOSE */ - (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABx), /* OP_CLOSURE */ - (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABC), /* OP_VARARG */ - }; - - public static int getOpMode(int m) { - return luaP_opmodes[m] & 3; - } - public static int getBMode(int m) { - return (luaP_opmodes[m] >> 4) & 3; - } - public static int getCMode(int m) { - return (luaP_opmodes[m] >> 2) & 3; - } - public static boolean testAMode(int m) { - return 0 != (luaP_opmodes[m] & (1 << 6)); - } - public static boolean testTMode(int m) { - return 0 != (luaP_opmodes[m] & (1 << 7)); - } - - /* number of list items to accumulate before a SETLIST instruction */ - public static final int LFIELDS_PER_FLUSH = 50; - - // type constants - - public static final int LUA_TINT = (-2); - public static final int LUA_TNONE = (-1); - public static final int LUA_TNIL = 0; - public static final int LUA_TBOOLEAN = 1; - public static final int LUA_TLIGHTUSERDATA = 2; - public static final int LUA_TNUMBER = 3; - public static final int LUA_TSTRING = 4; - public static final int LUA_TTABLE = 5; - public static final int LUA_TFUNCTION = 6; - public static final int LUA_TUSERDATA = 7; - public static final int LUA_TTHREAD = 8; - public static final int LUA_TVALUE = 9; - - public static final String[] TYPE_NAMES = { - "nil", - "boolean", - "lightuserdata", - "number", - "string", - "table", - "function", - "userdata", - "thread", - "value", - }; - -} diff --git a/src/core/org/luaj/vm/LuaErrorException.java b/src/core/org/luaj/vm/LuaErrorException.java deleted file mode 100644 index a0e8d041..00000000 --- a/src/core/org/luaj/vm/LuaErrorException.java +++ /dev/null @@ -1,91 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - -/** - * RuntimeException that is thrown and caught in response to a lua error. - * This error does not indicate any problem with the normal functioning - * of the Lua VM, but rather indicates that the lua script being interpreted - * has encountered a lua error, eigher via LuaState.error() or lua error() calls. - * - */ -public class LuaErrorException extends RuntimeException { - - private static final String DEFAULT_MESSAGE = "lua error"; - - /** - * Construct a LuaErrorException with the default message. - */ - public LuaErrorException() { - this(DEFAULT_MESSAGE); - } - - /** - * Construct a LuaErrorException in response to a Throwable that was caught - * and with the default message. - */ - public LuaErrorException(Throwable cause) { - this(DEFAULT_MESSAGE+": "+cause); - } - - /** - * Construct a LuaErrorException with a specific message. - * - * @param message message to supply - */ - public LuaErrorException(String message) { - this(null, message, -1); - } - - /** - * Construct the message around a specific vm and with a particular level of debug info - * @param vm - * @param message - * @param level 0 for no message, >=1 for current call or above, -1 for most recent lua call - */ - public LuaErrorException(LuaState vm, String message, int level) { - super( addLineInfo( vm, message, level ) ); - } - - /** - * Append line info as per level - * @param vm - * @param message - * @param level - * @return - */ - private static String addLineInfo(LuaState vm, String message, int level) { - // add position information - if ( vm == null ) { - if ( LThread.running != null ) - vm = LThread.running.vm; - else - vm = LuaState.mainState; - if ( vm == null ) - return message; - } - if ( level > 0 ) { - message = vm.getFileLine(level); - } - return vm.luaV_call_errfunc( message ); - } -} diff --git a/src/core/org/luaj/vm/LuaState.java b/src/core/org/luaj/vm/LuaState.java deleted file mode 100644 index 1504dee0..00000000 --- a/src/core/org/luaj/vm/LuaState.java +++ /dev/null @@ -1,2553 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.util.Stack; - -import org.luaj.lib.BaseLib; -import org.luaj.lib.CoroutineLib; -import org.luaj.lib.MathLib; -import org.luaj.lib.PackageLib; -import org.luaj.lib.StringLib; -import org.luaj.lib.TableLib; - -/** - *
- *

LuaState

- * - *
- * typedef struct LuaState;
- * 
- * - *

- * Opaque structure that keeps the whole state of a Lua interpreter. The Lua - * library is fully reentrant: it has no global variables. All information about - * a state is kept in this structure. - * - * - *

- * Here we list all functions and types from the C API in alphabetical - * order. Each function has an indicator like this: [-o, +p, - * x] - * - *

- * The first field, o, is how many elements the function pops - * from the stack. The second field, p, is how many elements the - * function pushes onto the stack. (Any function always pushes its results after - * popping its arguments.) A field in the form x|y means the - * function may push (or pop) x or y elements, - * depending on the situation; an interrogation mark '?' means - * that we cannot know how many elements the function pops/pushes by looking - * only at its arguments (e.g., they may depend on what is on the stack). The - * third field, x, tells whether the function may throw errors: '-' - * means the function never throws any error; 'm' means the - * function may throw an error only due to not enough memory; 'e' - * means the function may throw other kinds of errors; 'v' - * means the function may throw an error on purpose. - * - * - */ -public class LuaState extends Lua { - - /* thread status; 0 is OK */ - public static final int LUA_YIELD = 1; - public static final int LUA_ERRRUN = 2; - public static final int LUA_ERRSYNTAX = 3; - public static final int LUA_ERRMEM = 4; - public static final int LUA_ERRERR = 5; - - private static final int LUA_MINSTACK = 20; - private static final int LUA_MINCALLS = 10; - private static final int MAXTAGLOOP = 100; - - // hook function values - private static final int LUA_HOOKCALL = 0; - private static final int LUA_HOOKRET = 1; - private static final int LUA_HOOKLINE = 2; - private static final int LUA_HOOKCOUNT = 3; - private static final int LUA_HOOKTAILRET = 4; - public static final int LUA_MASKCALL = (1 << LUA_HOOKCALL); - public static final int LUA_MASKRET = (1 << LUA_HOOKRET); - public static final int LUA_MASKLINE = (1 << LUA_HOOKLINE); - - public int base = 0; - public int top = 0; - protected int nresults = -1; - public LValue[] stack = new LValue[LUA_MINSTACK]; - public int cc = -1; - public CallInfo[] calls = new CallInfo[LUA_MINCALLS]; - protected Stack upvals = new Stack(); - protected LValue errfunc; - - static LuaState mainState; - public LTable _G; - - // debug hooks - these MUST NOT be initialized, - // so that a later obfuscation step can decide to remove them. - private boolean hooksenabled,inhook; - private int hookmask; - private int hookcount; - private LFunction hookfunc; - private int hookincr; - private int hookline,hookcc; - - protected void debugHooks(int pc) {} - protected void debugAssert(boolean b) {} - - // ------------------- constructors --------------------- - /** - * Creates a new, independent LuaState instance. [-0, +0, - * -] - * - *

- * Returns NULL if cannot create the state (due to lack of - * memory). The argument f is the allocator function; Lua - * does all memory allocation for this state through this function. The - * second argument, ud, is an opaque pointer that Lua simply - * passes to the allocator in every call. - */ - protected LuaState() { - _G = new LTable(); - mainState = this; - } - - /** - * Create a LuaState with a specific global environment. Used by LThread. - * - * @param globals the LTable to use as globals for this LuaState - */ - LuaState(LTable globals) { - _G = globals; - } - - /** - * Performs the initialization. - */ - public void init() {} - - /** - * Perform any shutdown/clean up tasks if needed - */ - public void shutdown() {} - - /** - * Install the standard set of libraries used by most implementations: - * BaseLib, CoroutineLib, MathLib, PackageLib, TableLib, StringLib - */ - public void installStandardLibs() { - PackageLib.install(_G); - BaseLib.install(_G); - CoroutineLib.install(_G); - MathLib.install(_G); - TableLib.install(_G); - StringLib.install(_G); - } - - // ================ interfaces for performing calls - - /** - * Create a call frame for a call that has been set up on - * the stack. The first value on the stack must be a Closure, - * and subsequent values are arguments to the closure. - */ - public void prepStackCall() { - LClosure c = (LClosure) stack[base]; - int resultbase = base; - // Expand the stack if necessary - checkstack( c.p.maxstacksize ); - if ( c.p.is_vararg == 0 ) { - base += 1; - luaV_adjusttop( base+c.p.numparams ); - } else { - /* vararg function */ - int npar = c.p.numparams; - int narg = Math.max(0, top - base - 1); - int nfix = Math.min(narg, npar); - int nvar = Math.max(0, narg-nfix); - - - // must copy args into position, add number parameter - stack[top] = LInteger.valueOf(nvar); - System.arraycopy(stack, base+1, stack, top+1, nfix); - base = top + 1; - top = base + nfix; - luaV_adjusttop( base + npar ); - - // add 'arg' compatibility variable - if ( (c.p.is_vararg & VARARG_NEEDSARG) != 0 ) { - LTable arg = new LTable(nvar,1); - for ( int i=1,j=base-nvar-1; i<=nvar; i++, j++ ) - arg.put(i, stack[j]); - arg.put("n", nvar); - pushlvalue( arg ); - } - } - final int newcc = cc + 1; - if ( newcc >= calls.length ) { - CallInfo[] newcalls = new CallInfo[ calls.length * 2 ]; - System.arraycopy( calls, 0, newcalls, 0, cc+1 ); - calls = newcalls; - } - calls[newcc] = new CallInfo(c, base, top, resultbase, nresults); - cc = newcc; - - stackClear( top, base + c.p.maxstacksize ); - } - - /** - * Execute bytecodes until the current call completes - * or the vm yields. - */ - public void execute() { - for ( int cb=cc; cc>=cb; ) - exec(); - } - - /** - * Put the closure on the stack with arguments, - * then perform the call. Leave return values - * on the stack for later querying. - * - * @param c - * @param values - */ - public void doCall( LClosure c, LValue[] args ) { - settop(0); - pushlvalue( c ); - for ( int i=0, n=(args!=null? args.length: 0); i=0? calls[cc].base: 0); - } - - /** - * Invoke a LFunction being called via prepStackCall() - * @param javaFunction - */ - public void invokeJavaFunction(LFunction javaFunction) { - ++base; - - // call hook - if ( hooksenabled && !inhook ) { - debugCallHooks( ); - } - - int nactual = javaFunction.invoke(this); - - // call hook - if ( hooksenabled && !inhook ) { - debugReturnHooks( ); - } - - - if (nactual < 0) - nactual = top - base; - System.arraycopy(stack, top-nactual, stack, --base, nactual); - luaV_settop_fillabove( base+nactual ); - } - - // ================== error processing ================= - - /** - * Calls a function. [-(nargs + 1), +nresults, e] - * - * - *

- * To call a function you must use the following protocol: first, the - * function to be called is pushed onto the stack; then, the arguments to - * the function are pushed in direct order; that is, the first argument is - * pushed first. Finally you call lua_call; - * nargs is the number of arguments that you pushed onto the - * stack. All arguments and the function value are popped from the stack - * when the function is called. The function results are pushed onto the - * stack when the function returns. The number of results is adjusted to - * nresults, unless nresults is LUA_MULTRET. In this case, - * all results from the function are pushed. Lua takes care that - * the returned values fit into the stack space. The function results are - * pushed onto the stack in direct order (the first result is pushed first), - * so that after the call the last result is on the top of the stack. - * - * - *

- * Any error inside the called function is propagated upwards (with a - * longjmp). - * - * - *

- * The following example shows how the host program may do the equivalent to - * this Lua code: - * - *

-	 * a = f("how", t.x, 14)
-	 * 
- * - *

- * Here it is in C: - * - *

-	 * lua_getfield(L, LUA_GLOBALSINDEX, "f"); // function to be called 
-	 * lua_pushstring(L, "how"); // 1st argument 
-	 * lua_getfield(L, LUA_GLOBALSINDEX, "t"); // table to be indexed 
-	 * lua_getfield(L, -1, "x"); // push result of t.x (2nd arg) 
-	 * lua_remove(L, -2); // remove 't' from the stack 
-	 * lua_pushinteger(L, 14); // 3rd argument 
-	 * lua_call(L, 3, 1); // call 'f' with 3 arguments and 1 result 
-	 * lua_setfield(L, LUA_GLOBALSINDEX, "a"); // set global 'a' 
-	 * 
- * - *

- * Note that the code above is "balanced": at its end, the stack is back to - * its original configuration. This is considered good programming practice. - */ - public void call( int nargs, int nreturns ) { - - // save stack state - int oldbase = base; - int oldcc = cc; - try { - - // rb is base of new call frame - int rb = this.base = top - 1 - nargs; - - // make or set up the call - this.nresults = nreturns; - - if (this.stack[base].luaStackCall(this)) { - - // call hook - if ( hooksenabled && ! inhook ) { - debugCallHooks( ); - } - - // call was set up on the stack, - // we still have to execute it - execute(); - } - - // adjustTop only for case when call was completed - // and number of args > 0. If call completed but - // c == 0, leave top to point to end of results - if (nreturns >= 0) - luaV_adjusttop(rb + nreturns); - - } finally { - this.base = oldbase; - this.cc = oldcc; - } - } - - /** - * Calls a function in protected mode. [-(nargs + 1), - * +(nresults|1), -] - * - * - *

- * Both nargs and nresults have the same - * meaning as in lua_call. If there - * are no errors during the call, lua_pcall - * behaves exactly like lua_call. - * However, if there is any error, lua_pcall - * catches it, pushes a single value on the stack (the error message), and - * returns an error code. Like lua_call, - * lua_pcall always removes the - * function and its arguments from the stack. - * - *

- * The lua_pcall function returns - * 0 in case of success or one of the following error codes (defined in - * lua.h): - * - *

    - * - *
  • LUA_ERRRUN: a - * runtime error.
  • - * - *
  • LUA_ERRMEM: - * memory allocation error. For such errors, Lua does not call the error - * handler function.
  • - * - *
  • LUA_ERRERR: - * error while running the error handler function.
  • - * - *
- */ - public int pcall( int nargs, int nreturns ) { - // save stack state - int oldtop = top; - int oldbase = base; - int oldcc = cc; - try { - // rb is base of new call frame - int rb = this.base = top - 1 - nargs; - - // make or set up the call - this.nresults = nreturns; - if (this.stack[base].luaStackCall(this)) { - - // call hook - if ( hooksenabled ) { - debugCallHooks( ); - } - - // call was set up on the stack, - // we still have to execute it - execute(); - } - - // adjustTop only for case when call was completed - // and number of args > 0. If call completed but - // c == 0, leave top to point to end of results - if (nreturns >= 0) - luaV_adjusttop(rb + nreturns); - - // restore base - this.base = oldbase; - - return 0; - } catch ( Throwable t ) { - this.base = oldbase; - this.cc = oldcc; - closeUpVals(oldtop); /* close eventual pending closures */ - String s = t.getMessage(); - resettop(); - if ( s != null ) - pushstring( s ); - else - pushnil(); - return (t instanceof OutOfMemoryError? LUA_ERRMEM: LUA_ERRRUN); - } - } - - - /** - * Calls a function in protected mode with an error function. - * [-(nargs + 1), +(nresults|1), -] - * - * - *

- * Both nargs and nresults have the same - * meaning as in lua_call. If there - * are no errors during the call, lua_xpcall - * behaves exactly like lua_call. - * However, if there is any error, lua_xpcall - * catches it, pushes a single value on the stack (the error message), and - * tries to call the supplied error function. - * - *

In case of runtime errors, this function - * will be called with the error message and its return value will be the - * message returned on the stack by lua_pcall. - * - *

- * Typically, the error handler function is used to add more debug - * information to the error message, such as a stack traceback. Such - * information cannot be gathered after the return of lua_pcall, - * since by then the stack has unwound. - * - *

- * The return values for - * lua_xpcall are the same as those for - * lua_pcall - */ - public int xpcall( int nargs, int nreturns, LValue errfunc ) { - LValue preverrfunc = this.errfunc; - try { - this.errfunc = errfunc; - return pcall( nargs, nreturns ); - } finally { - this.errfunc = preverrfunc; - } - } - - /** - * Loads a Lua chunk. [-0, +1, -] - * - *

- * If there are no errors, lua_load - * pushes the compiled chunk as a Lua function on top of the stack. - * Otherwise, it pushes an error message. The return values of lua_load are: - * - *

    - * - *
  • 0: no errors;
  • - * - *
  • LUA_ERRSYNTAX: - * syntax error during pre-compilation;
  • - * - *
  • LUA_ERRMEM: - * memory allocation error.
  • - * - *
- * - *

- * This function only loads a chunk; it does not run it. - * - * - *

- * lua_load automatically detects - * whether the chunk is text or binary, and loads it accordingly (see - * program luac). - * - * - *

- * The lua_load function uses a - * user-supplied reader function to read the chunk (see lua_Reader). The - * data argument is an opaque value passed to the reader - * function. - * - * - *

- * The chunkname argument gives a name to the chunk, which is - * used for error messages and in debug information (see §3.8). - */ - public int load( InputStream is, String chunkname ) { - try { - LPrototype p = LoadState.undump(this, is, chunkname ); - pushlvalue( p.newClosure( _G ) ); - return 0; - } catch ( Throwable t ) { - pushstring( t.getMessage() ); - return (t instanceof OutOfMemoryError? LUA_ERRMEM: LUA_ERRSYNTAX); - } - } - - // ================ execute instructions - private LValue RKBC(LValue[] k, int bc) { - return LuaState.ISK(bc) ? - k[LuaState.INDEXK(bc)]: - stack[base + bc]; - } - - private LValue GETARG_RKB(LValue[] k, int i) { - return RKBC(k, GETARG_B(i)); - } - - private LValue GETARG_RKC(LValue[] k, int i) { - return RKBC(k, GETARG_C(i)); - } - - private final void stackClear(int startIndex, int endIndex) { - for (; startIndex < endIndex; startIndex++) { - stack[startIndex] = LNil.NIL; - } - } - - /** execute instructions up to a yield, return, or call */ - public void exec() { - if ( cc < 0 ) - return; - - int i, a, b, c, o, n, cb; - LValue rkb, rkc, nvarargs, key, val; - LValue i0, step, idx, limit, init, table; - boolean back, body; - LPrototype proto; - LClosure newClosure; - - // reload values from the current call frame - // into local variables - CallInfo ci = calls[cc]; - LClosure cl = ci.closure; - LPrototype p = cl.p; - int[] code = p.code; - LValue[] k = p.k; - - this.base = ci.base; - - // loop until a return instruction is processed, - // or the vm yields - while (true) { - debugAssert( ci == calls[cc] ); - - // sync up top - ci.top = top; - - // allow debug hooks a chance to operate - debugHooks( ci.pc ); - if ( hooksenabled && ! inhook ) { - //Print.printState(this, base, top, base+cl.p.maxstacksize, cl, ci.pc); - debugBytecodeHooks( ci.pc ); - } - - // advance program counter - i = code[ci.pc++]; - - // get opcode and first arg - o = (i >> POS_OP) & MAX_OP; - a = (i >> POS_A) & MAXARG_A; - - switch (o) { - case LuaState.OP_MOVE: { - b = LuaState.GETARG_B(i); - this.stack[base + a] = this.stack[base + b]; - continue; - } - case LuaState.OP_LOADK: { - b = LuaState.GETARG_Bx(i); - this.stack[base + a] = k[b]; - continue; - } - case LuaState.OP_LOADBOOL: { - b = LuaState.GETARG_B(i); - c = LuaState.GETARG_C(i); - this.stack[base + a] = (b != 0 ? LBoolean.TRUE : LBoolean.FALSE); - if (c != 0) - ci.pc++; /* skip next instruction (if C) */ - continue; - } - case LuaState.OP_LOADNIL: { - b = LuaState.GETARG_B(i); - do { - this.stack[base + b] = LNil.NIL; - } while ((--b) >= a); - continue; - } - case LuaState.OP_GETUPVAL: { - b = LuaState.GETARG_B(i); - this.stack[base + a] = cl.upVals[b].getValue(); - continue; - } - case LuaState.OP_GETGLOBAL: { - b = LuaState.GETARG_Bx(i); - key = k[b]; - table = cl.env; - val = this.luaV_gettable(table, key); - this.stack[base + a] = val; - continue; - } - case LuaState.OP_GETTABLE: { - b = LuaState.GETARG_B(i); - key = GETARG_RKC(k, i); - table = this.stack[base + b]; - val = this.luaV_gettable(table, key); - this.stack[base + a] = val; - continue; - } - case LuaState.OP_SETGLOBAL: { - b = LuaState.GETARG_Bx(i); - key = k[b]; - val = this.stack[base + a]; - table = cl.env; - this.luaV_settable(table, key, val); - continue; - } - case LuaState.OP_SETUPVAL: { - b = LuaState.GETARG_B(i); - cl.upVals[b].setValue( this.stack[base + a] ); - continue; - } - case LuaState.OP_SETTABLE: { - key = GETARG_RKB(k, i); - val = GETARG_RKC(k, i); - table = this.stack[base + a]; - this.luaV_settable(table, key, val); - continue; - } - case LuaState.OP_NEWTABLE: { - b = LuaState.GETARG_B(i); - c = LuaState.GETARG_C(i); - this.stack[base + a] = new LTable(b, c); - continue; - } - case LuaState.OP_SELF: { - rkb = stack[base + GETARG_B(i)]; - rkc = GETARG_RKC(k, i); - val = this.luaV_gettable(rkb, rkc); - this.stack[base + a] = val; - this.stack[base + a + 1] = rkb; - continue; - } - case LuaState.OP_ADD: - case LuaState.OP_SUB: - case LuaState.OP_MUL: - case LuaState.OP_DIV: - case LuaState.OP_MOD: - case LuaState.OP_POW: { - rkb = GETARG_RKB(k, i); - rkc = GETARG_RKC(k, i); - this.stack[base + a] = rkc.luaBinOpUnknown(o, rkb); - continue; - } - case LuaState.OP_UNM: { - rkb = GETARG_RKB(k, i); - this.stack[base + a] = rkb.luaUnaryMinus(); - continue; - } - case LuaState.OP_NOT: { - rkb = GETARG_RKB(k, i); - this.stack[base + a] = (!rkb.toJavaBoolean() ? LBoolean.TRUE - : LBoolean.FALSE); - continue; - } - case LuaState.OP_LEN: { - rkb = GETARG_RKB(k, i); - this.stack[base + a] = LInteger.valueOf( rkb.luaLength() ); - continue; - } - case LuaState.OP_CONCAT: { - b = LuaState.GETARG_B(i); - c = LuaState.GETARG_C(i); - int numValues = c - b + 1; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - for (int j = b, l = 0; j <= c; j++, l++) { - this.stack[base + j].luaConcatTo( baos ); - } - this.stack[base + a] = new LString( baos.toByteArray() ); - continue; - } - case LuaState.OP_JMP: { - ci.pc += LuaState.GETARG_sBx(i); - continue; - } - case LuaState.OP_EQ: - case LuaState.OP_LT: - case LuaState.OP_LE: { - rkb = GETARG_RKB(k, i); - rkc = GETARG_RKC(k, i); - boolean test = rkc.luaBinCmpUnknown(o, rkb); - if (test == (a == 0)) - ci.pc++; - continue; - } - case LuaState.OP_TEST: { - c = LuaState.GETARG_C(i); - if (this.stack[base + a].toJavaBoolean() != (c != 0)) - ci.pc++; - continue; - } - case LuaState.OP_TESTSET: { - rkb = stack[base + GETARG_B(i)]; - c = LuaState.GETARG_C(i); - if (rkb.toJavaBoolean() != (c != 0)) - ci.pc++; - else - this.stack[base + a] = rkb; - continue; - } - case LuaState.OP_CALL: { - - // ra is base of new call frame - this.base += a; - - // number of args - b = LuaState.GETARG_B(i); - if (b != 0) // else use previous instruction set top - luaV_settop_fillabove( base + b ); - - // number of return values we need - c = LuaState.GETARG_C(i); - - // make or set up the call - this.nresults = c - 1; - if (this.stack[base].luaStackCall(this)) { - - // call hook - if ( hooksenabled && ! inhook ) { - debugCallHooks( ); - } - - return; - } - - // adjustTop only for case when call was completed - // and number of args > 0. If call completed but - // c == 0, leave top to point to end of results - if (c > 0) - luaV_adjusttop(base + c - 1); - - // restore base - base = ci.base; - - continue; - } - - case LuaState.OP_TAILCALL: { - // return hook - if ( hooksenabled && ! inhook ) { - debugTailReturnHooks( ); - } - - // close up values - closeUpVals(base); - - // copy down the frame before calling! - - // number of args (including the function) - b = LuaState.GETARG_B(i); - if (b != 0) // else use previous instruction set top - luaV_settop_fillabove( base + a + b ); - else - b = top - (base + a); - - // copy call + all args, discard current frame - System.arraycopy(stack, base + a, stack, ci.resultbase, b); - this.base = ci.resultbase; - luaV_settop_fillabove( base + b ); - this.nresults = ci.nresults; - --cc; - - // make or set up the call - try { - if (this.stack[base].luaStackCall(this)) { - - // call hook - if ( hooksenabled && ! inhook ) { - debugCallHooks( ); - } - - return; - } - } catch (LuaErrorException e) { - // in case of lua error, we need to restore cc so that - // the debug can get the correct location where the error - // occured. - cc++; - throw e; - } - - // adjustTop only for case when call was completed - // and number of args > 0. If call completed but - // c == 0, leave top to point to end of results - if (ci.nresults >= 0) - luaV_adjusttop(base + ci.nresults); - - // force restore of base, etc. - return; - } - - case LuaState.OP_RETURN: { - // return hook - if ( hooksenabled && ! inhook ) { - debugReturnHooks( ); - } - - // close up values - closeUpVals( base ); - - // number of return vals to return - b = LuaState.GETARG_B(i) - 1; - if (b >= 0) // else use previous instruction set top - luaV_settop_fillabove( base + a + b ); - else - b = top - (base + a); - - // number to copy down - System.arraycopy(stack, base + a, stack, ci.resultbase, b); - debugAssert( ci.resultbase + b <= top ); - luaV_settop_fillabove( ci.resultbase + b ); - - // adjust results to what caller expected - if (ci.nresults >= 0) - luaV_adjusttop(ci.resultbase + ci.nresults); - - // pop the call stack - calls[cc--] = null; - - // force a reload of the calling context - return; - } - case LuaState.OP_FORLOOP: { - i0 = this.stack[base + a]; - step = this.stack[base + a + 2]; - idx = step.luaBinOpUnknown(Lua.OP_ADD, i0); - limit = this.stack[base + a + 1]; - back = step.luaBinCmpInteger(Lua.OP_LT, 0); - body = (back ? idx.luaBinCmpUnknown(Lua.OP_LE, limit) : limit - .luaBinCmpUnknown(Lua.OP_LE, idx)); - if (body) { - this.stack[base + a] = idx; - this.stack[base + a + 3] = idx; - ci.pc += LuaState.GETARG_sBx(i); - } - continue; - } - case LuaState.OP_FORPREP: { - init = this.stack[base + a].luaToNumber(); - limit = this.stack[base + a + 1].luaToNumber(); - step = this.stack[base + a + 2].luaToNumber(); - if ( init.isNil() ) error("'for' initial value must be a number"); - if ( limit.isNil() ) error("'for' limit must be a number"); - if ( step.isNil() ) error("'for' step must be a number"); - this.stack[base + a] = step.luaBinOpUnknown(Lua.OP_SUB, init); - this.stack[base + a + 1] = limit; - this.stack[base + a + 2] = step; - b = LuaState.GETARG_sBx(i); - ci.pc += b; - continue; - } - case LuaState.OP_TFORLOOP: { - cb = base + a + 3; /* call base */ - base = cb; - System.arraycopy(this.stack, cb-3, this.stack, cb, 3); - luaV_settop_fillabove( cb + 3 ); - - // call the iterator - c = LuaState.GETARG_C(i); - this.nresults = c; - if (this.stack[cb].luaStackCall(this)) - execute(); - base = ci.base; - luaV_adjusttop( cb + c ); - - // test for continuation - if (!this.stack[cb].isNil() ) { // continue? - this.stack[cb-1] = this.stack[cb]; // save control variable - } else { - ci.pc++; // skip over jump - } - continue; - } - case LuaState.OP_SETLIST: { - b = LuaState.GETARG_B(i); - c = LuaState.GETARG_C(i); - int listBase = base + a; - if (b == 0) { - b = top - listBase - 1; - } - if (c == 0) { - c = code[ci.pc++]; - } - int offset = (c-1) * LFIELDS_PER_FLUSH; - LTable tbl = (LTable) this.stack[base + a]; - tbl.arrayPresize( offset + b ); - for (int j=1; j<=b; j++) { - tbl.put(offset+j, stack[listBase + j]); - } - continue; - } - case LuaState.OP_CLOSE: { - closeUpVals( base + a ); // close upvals higher in the stack than position a - continue; - } - case LuaState.OP_CLOSURE: { - b = LuaState.GETARG_Bx(i); - proto = cl.p.p[b]; - newClosure = proto.newClosure(cl.env); - for (int j = 0; j < newClosure.upVals.length; j++, ci.pc++) { - i = code[ci.pc]; - o = LuaState.GET_OPCODE(i); - b = LuaState.GETARG_B(i); - if (o == LuaState.OP_GETUPVAL) { - newClosure.upVals[j] = cl.upVals[b]; - } else if (o == LuaState.OP_MOVE) { - newClosure.upVals[j] = findUpVal( base + b ); - } else { - throw new java.lang.IllegalArgumentException( - "bad opcode: " + o); - } - } - this.stack[base + a] = newClosure; - continue; - } - case LuaState.OP_VARARG: { - // figure out how many args to copy - b = LuaState.GETARG_B(i) - 1; - nvarargs = this.stack[base - 1]; - n = nvarargs.toJavaInt(); - if (b == LuaState.LUA_MULTRET) { - b = n; // use entire varargs supplied - luaV_settop_fillabove( base + a + b ); - } - - // copy args up to call stack area - checkstack(a+b); - for (int j = 0; j < b; j++) - this.stack[base + a + j] = (j < n ? - this.stack[base - n + j - 1] - : LNil.NIL); - continue; - } - } - } - } - - public UpVal findUpVal( int target ) { - UpVal up; - int i; - for ( i = this.upvals.size() - 1; i >= 0; --i ) { - up = (UpVal) this.upvals.elementAt( i ); - if ( up.state == this && up.position == target ) { - return up; - } else if ( up.position < target ) { - break; - } - } - - up = new UpVal( this, target ); - this.upvals.insertElementAt( up, i + 1 ); - return up; - } - - public void closeUpVals( int limit ) { - while ( !upvals.empty() && ( (UpVal) this.upvals.lastElement() ).close( limit ) ) { - this.upvals.pop(); - } - } - - public CallInfo getStackFrame(int callStackDepth) { - return calls[cc-callStackDepth]; - } - - private void indexError(LValue nontable) { - error( "attempt to index ? (a "+nontable.luaGetTypeName()+" value)" ); - } - - public static LValue luaV_getmetafield(LValue t, LString tag) { - LTable mt = t.luaGetMetatable(); - if ( mt == null ) - return null; - LValue h = mt.get(tag); - return h.isNil()? null: h; - } - - /** Get a key from a table using full metatable processing */ - public LValue luaV_gettable(LValue table, LValue key) { - LValue h=LNil.NIL,t=table; - for ( int loop=0; loop newTop) - this.stack[--top] = LNil.NIL; - } - - /** Move top down, filling from above */ - private void luaV_settop_fillabove(int newTop) { - while (top > newTop) - this.stack[--top] = LNil.NIL; - top = newTop; - } - - - //=============================================================== - // Lua Java API - //=============================================================== - - /** @deprecated: use LPrototype.source or LPrototype.sourceshort() instead */ - public String getSourceFileName(LString s) { - return getSourceFileName(s.toJavaString()); - } - - /** @deprecated: use LPrototype.source or LPrototype.sourceshort() instead */ - protected String getSourceFileName(String s) { - return LoadState.getSourceName(s); - } - - /** - * Get the file line number info for a particular call frame. - * @param cindex index into call stack, or -1 to get first lua location - * @return - */ - protected String getFileLine(int level) { - LClosure c = null; - for (int j=cc; j>=0; --j) { - CallInfo ci = calls[j]; - LFunction f = ci.currentfunc(this); - if ( f != null && (!f.isClosure() || f!=c) ) { - if ( level != -1 && (level--) <= 0 ) { - return "[Java]: "+f.toString(); - } - } - c = ci.closure; - if ( (level--) <= 0 ) { - return c.p.sourceshort()+":"+ci.currentline(); - } - } - return ""; - } - - /** - * Raises an error. The message is pushed onto the stack and used as the error message. - * It also adds at the beginning of the message the file name and the line number where - * the error occurred, if this information is available. - * - * In the java implementation this throws a LuaErrorException - * after filling line number information first when level > 0. - */ - public void error(String message, int level) { - throw new LuaErrorException( this, message, level ); - } - - /** - * Raises an error with the default level. - */ - public void error(String message) { - throw new LuaErrorException( this, message, -1 ); - } - - /** - * - * Ensures that there are at least extra free stack slots in - * the stack. [-0, +0, -] - * - *

- * It returns false if it cannot grow the stack to that size. This function - * never shrinks the stack; if the stack is already larger than the new - * size, it is left unchanged. - * - */ - public void checkstack(int extra) { - if ( top + extra >= stack.length ) { - int n = Math.max( top + extra + LUA_MINSTACK, stack.length * 2 ); - LValue[] s = new LValue[n]; - System.arraycopy(stack, 0, s, 0, stack.length); - stack = s; - } - } - - /** - * Dereference a tables field. [-0, +1, e] - * - *

- * Pushes onto the stack the value t[k], where - * t is the value at the given valid index. As in Lua, this - * function may trigger a metamethod for the "index" event (see §2.8). - * - */ - public void getfield(int index, LString k) { - pushlvalue( this.luaV_gettable(topointer(index), k) ); - } - - /** - * Look up a global value. [-0, +1, e] - * - *

- * Pushes onto the stack the value of the global name. It is - * defined as a macro: - * - *

-	 * 	 #define lua_getglobal(L,s)  lua_getfield(L, LUA_GLOBALSINDEX, s)
-	 * 	
-	 * 
- */ - public void getglobal(String s) { - pushlvalue( this.luaV_gettable(_G, new LString(s)) ); - } - - /** - * Get a value's metatable. [-0, +(0|1), -] - * - *

- * Pushes onto the stack the metatable of the value at the given acceptable - * index. If the index is not valid, or if the value does not have a - * metatable, the function returns false and pushes nothing on the stack. - * - * @return true if the metatable was pushed onto the stack, false otherwise - */ - public boolean getmetatable(int index) { - LTable mt = topointer(index).luaGetMetatable(); - if ( mt != null ) { - pushlvalue( mt ); - return true; - } - return false; - } - - /** - * Insert the top item somewhere in the stack. [-1, +1, - * -] - * - *

- * Moves the top element into the given valid index, shifting up the - * elements above this index to open space. Cannot be called with a - * pseudo-index, because a pseudo-index is not an actual stack position. - * - */ - public void insert(int index) { - int ai = index2adr(index); - LValue v = stack[top-1]; - System.arraycopy(stack, ai, stack, ai+1, top-ai-1); - stack[ai] = v; - } - - /** - * Test if a value is boolean. [-0, +0, -] - * - *

- * Returns 1 if the value at the given acceptable index has type boolean, - * and 0 otherwise. - * - */ - public boolean isboolean(int index) { - return type(index) == Lua.LUA_TBOOLEAN; - } - - /** - * Test if a value is a function. [-0, +0, -] - * - *

- * Returns true if the value at the given acceptable index is a function - * (either C or Lua), and false otherwise. - * - */ - public boolean isfunction(int index) { - return type(index) == Lua.LUA_TFUNCTION; - } - - /** - * Test if a value is nil [-0, +0, -] - * - *

- * Returns 1 if the value at the given acceptable index is nil, and - * 0 otherwise. - */ - public boolean isnil(int index) { - return topointer(index).isNil(); - } - - /** - * Test if a value is nil or not valid [-0, +0, - * -] - * - *

- * Returns 1 if the the given acceptable index is not valid (that is, it - * refers to an element outside the current stack) or if the value at this - * index is nil, and 0 otherwise. - */ - public boolean isnoneornil(int index) { - Object v = topointer(index); - return v == null || v == LNil.NIL; - } - - /** - * Test if a value is a number [-0, +0, -] - * - *

- * Returns 1 if the value at the given acceptable index is a number or a - * string convertible to a number, and 0 otherwise. - */ - public boolean isnumber(int index) { - return ! tolnumber(index).isNil(); - } - - /** - * Convert a value to an LNumber[-0, +0, -] - * - *

- * Returns an LNumber if the value at the given acceptable index is a number or a - * string convertible to a number, and LNil.NIL otherwise. - */ - public LValue tolnumber(int index) { - return topointer(index).luaToNumber(); - } - - /** - * Test if a value is a string [-0, +0, m] - * - *

- * Returns 1 if the value at the given acceptable index is a string or a - * number (which is always convertible to a string), and 0 otherwise. - */ - public boolean isstring(int index) { - return topointer(index).isString(); - } - - /** - * Test if a value is a table [-0, +0, -] - * - *

- * Returns 1 if the value at the given acceptable index is a table, and - * 0 otherwise. - */ - public boolean istable(int index) { - return topointer(index).isTable(); - } - - /** - * Test if a value is a thread [-0, +0, -] - * - *

- * Returns 1 if the value at the given acceptable index is a thread, and - * 0 otherwise. - */ - public boolean isthread(int index) { - return type(index) == Lua.LUA_TTHREAD; - } - - /** - * Test if a value is a userdata [-0, +0, -] - * - *

- * Returns 1 if the value at the given acceptable index is a userdata - * (either full or light), and 0 otherwise. - */ - public boolean isuserdata(int index) { - return type(index) == Lua.LUA_TUSERDATA; - } - - /** - * Pops n elements from the stack. [-n, - * +0, -] - */ - public void pop(int n) { - for ( int i=0; i[-0, +1, - * m] - */ - public void pushlvalue(LValue value) { - if ( value == null ) - throw new java.lang.IllegalArgumentException("stack values cannot be null"); - try { - stack[top] = value; - } catch ( java.lang.ArrayIndexOutOfBoundsException aiobe ) { - checkstack( LUA_MINSTACK ); - stack[top] = value; - } finally { - ++top; - } - } - - /** - * Pushes a boolean value with value b onto the stack. [-0, +1, -] - * - */ - public void pushboolean(boolean b) { - pushlvalue( LBoolean.valueOf(b) ); - } - - /** - * Pushes a number with value n onto the stack. [-0, +1, -] - */ - public void pushinteger(int n) { - pushlvalue( LInteger.valueOf(n) ); - } - - /** - * Pushes a function onto the stack. [-0, +1, - * m] - * - *

- * This function receives an LFunction and pushes onto the - * stack a Lua value of type function that, when called, - * invokes the corresponding function. - * - * - *

- * Any function to be registered in Lua must follow the correct protocol to - * receive its parameters and return its results - * @see LFunction - */ - public void pushfunction(LFunction f) { - pushlvalue( f ); - } - - - /** - * Push an LString onto the stack. [-0, +1, - * m] - */ - public void pushlstring(LString s) { - pushlvalue(s); - } - - /** - * Push string bytes onto the stack as a string. [-0, +1, - * m] - * - * Pushes the string pointed to by s with size - * len onto the stack. Lua makes (or reuses) an internal copy - * of the given string, so the memory at s can be freed or - * reused immediately after the function returns. The string can contain - * embedded zeros. - */ - public void pushlstring(byte[] bytes, int offset, int length) { - pushlvalue(new LString(bytes, offset, length)); - } - - /** - * Push string bytes onto the stack as a string. [-0, +1, - * m] - * - * Pushes the bytes in byteArray onto the stack as a lua string. - */ - public void pushlstring(byte[] byteArray) { - pushlstring(byteArray, 0, byteArray.length); - } - - /** - * Pushes a nil value onto the stack. [-0, +1, -] - * - */ - public void pushnil() { - pushlvalue(LNil.NIL); - } - - /** - * Pushes a number with value d onto the stack. [-0, +1, -] - * - */ - public void pushnumber(double d) { - pushlvalue(LDouble.numberOf(d)); - } - - /** - * Push a String onto the stack. [-0, +1, m] - * - *

- * Pushes the String s onto the stack. Lua makes (or reuses) - * an internal copy of the given string, so the memory at s - * can be freed or reused immediately after the function returns. The string - * cannot contain embedded zeros; it is assumed to end at the first zero. - */ - public void pushstring(String s) { - if ( s == null ) - pushnil(); - else - pushlstring( LString.valueOf(s) ); - } - - /** - * Push a value from the stack onto the stack. [-0, +1, - * -] - * - *

- * Pushes a copy of the element at the given valid index onto the stack. - */ - public void pushvalue(int index) { - pushlvalue(topointer(index)); - } - - /** - * Do a integer-key table get without metadata calls. [-0, +1, -] - * - *

- * Pushes onto the stack the value t[n], where - * t is the value at the given valid index. The access is - * raw; that is, it does not invoke metamethods. - * @deprecated should get the table and do a raw get instead - */ - public void rawgeti(int index, int n) { - pushlvalue( totable(index).get(n) ); - } - - /** - * Remove an element from the stack. [-1, +0, -] - * - *

- * Removes the element at the given valid index, shifting down the elements - * above this index to fill the gap. Cannot be called with a pseudo-index, - * because a pseudo-index is not an actual stack position. - */ - public void remove(int index) { - int ai = index2adr(index); - System.arraycopy(stack, ai+1, stack, ai, top-ai-1); - poplvalue(); - } - - /** - * Replace an element on the stack. [-1, +0, -] - * - *

- * Moves the top element into the given position (and pops it), without - * shifting any element (therefore replacing the value at the given - * position). - */ - public void replace(int index) { - int ai = index2adr(index); - stack[ai] = poplvalue(); - } - - /** - * Set the value of a table field. [-1, +0, e] - * - *

- * Does the equivalent to t[k] = v, where t - * is the value at the given valid index and v is the value - * at the top of the stack. - * - * - *

- * This function pops the value from the stack. As in Lua, this function may - * trigger a metamethod for the "newindex" event (see §2.8). - */ - public void setfield(int index, LString k) { - LTable t = totable(index); - this.luaV_settable(t, k, poplvalue()); - } - - /** - * Set the value of a global variable. [-1, +0, - * e] - * - *

- * Pops a value from the stack and sets it as the new value of global - * name. It is defined as a macro: - * - *

-	 * 	 #define lua_setglobal(L,s)   lua_setfield(L, LUA_GLOBALSINDEX, s)
-	 * 	
-	 * 
- */ - public void setglobal(String name) { - this.luaV_settable(_G, new LString(name), poplvalue()); - } - - /** - * Get a value as a boolean. [-0, +0, -] - * - *

- * Converts the Lua value at the given acceptable index to a C boolean - * value (0 or 1). Like all tests in Lua, lua_toboolean returns 1 for - * any Lua value different from false and nil; otherwise it - * returns 0. It also returns 0 when called with a non-valid index. (If you - * want to accept only actual boolean values, use lua_isboolean - * to test the value's type.) - * - */ - public boolean toboolean(int index) { - return topointer(index).toJavaBoolean(); - } - - /** - * Get a value as an int. [-0, +0, -] - * - *

- * Converts the Lua value at the given acceptable index to the signed - * integral type lua_Integer. - * The Lua value must be a number or a string convertible to a number (see - * §2.2.1); otherwise, lua_tointeger - * returns 0. - * - * - *

- * If the number is not an integer, it is truncated in some non-specified - * way. - */ - public int tointeger(int index) { - LValue v = tolnumber(index); - return v.isNil()? 0: v.toJavaInt(); - } - - /** - * Get a value as a LFunction. - *


- *

tofunction

- *

- * [-0, +0, -] - * - *

-	 * LFunction tofunction (lua_State *L, int index);
-	 * 
- * - *

- * Converts a value at the given acceptable index to a C function. That - * value must be a function; otherwise, returns NULL. - */ - public LValue tofunction(int index) { - LValue v = topointer(index); - return v.isFunction()? v: LNil.NIL; - } - - /** - * Gets the value of a string as byte array. [-0, +0, - * m] - * - *

- * Converts the Lua value at the given acceptable index to a C string. - * If len is not NULL, it also sets - * *len with the string length. The Lua value must be a - * string or a number; otherwise, the function returns NULL. - * If the value is a number, then lua_tolstring - * also changes the actual value in the stack to a string. (This - * change confuses lua_next when lua_tolstring is applied to - * keys during a table traversal.) - * - * - *

- * lua_tolstring returns a - * fully aligned pointer to a string inside the Lua state. This string - * always has a zero ('\0') after its last character (as - * in C), but may contain other zeros in its body. Because Lua has - * garbage collection, there is no guarantee that the pointer returned by lua_tolstring will be valid - * after the corresponding value is removed from the stack. - */ - public LString tolstring(int index) { - return topointer(index).luaAsString(); - } - - /** - * Convert a value to a double. [-0, +0, -] - * - *

- * Converts the Lua value at the given acceptable index to the C type - * lua_Number (see lua_Number). The Lua value must - * be a number or a string convertible to a number (see §2.2.1); otherwise, lua_tonumber - * returns 0. - * - */ - public double tonumber(int index) { - LValue v = tolnumber(index); - return v.isNil()? 0: v.toJavaDouble(); - } - - /** - * Returns the index of the top element in the stack. [-0, +0, -] - * - *

- * Because indices start at 1, this result is equal to the number of - * elements in the stack (and so 0 means an empty stack). - */ - public int gettop() { - return top - base; - } - - /** - * Set the top of the stack. [-?, +?, -] - * - *

- * Accepts any acceptable index, or 0, and sets the stack top to this - * index. If the new top is larger than the old one, then the new elements - * are filled with nil. If index is 0, then all - * stack elements are removed. - */ - public void settop(int nt) { - int ant = nt>=0? base+nt: top+nt; - if ( ant < base ) - throw new IllegalArgumentException("index out of bounds: "+ant ); - luaV_adjusttop(ant); - } - - - /** - * Set the top to the base. Equivalent to settop(0) - */ - public void resettop() { - luaV_settop_fillabove( base ); - } - - private int index2adr(int index) { - // TODO: upvalues? globals? environment? - int ai = index>0? base+index-1: top+index; - if ( ai < base ) - throw new IllegalArgumentException("index out of bounds: "+ai ); - return ai; - } - - /** - * Get the raw Object at a stack location. [-0, +0, - * -] - * - *

- * Converts the value at the given acceptable index to a generic - * C pointer (void*). The value may be a userdata, a - * table, a thread, or a function; otherwise, lua_topointer - * returns NULL. Different objects will give different - * pointers. There is no way to convert the pointer back to its original - * value. - * - * - *

- * Typically this function is used only for debug information. - */ - public LValue topointer(int index) { - int ai = index2adr(index); - if ( ai >= top ) - return LNil.NIL; - return stack[ai]; - } - - /** - * Get a stack value as a String. [-0, +0, m] - * - *

- * Equivalent to lua_tolstring - * with len equal to NULL. - */ - public String tostring(int index) { - return topointer(index).toJavaString(); - } - - /** - * Get a value from the stack as a lua table. [-0, +0, -] - * - *

- * Converts the value at the given acceptable index to a Lua table - * This value must be a table otherwise, the function returns NIL. - */ - public LTable totable(int index) { - return (LTable) topointer(index); - } - - /** - * Get the Object from a userdata value. [-0, +0, - * -] - * - *

- * If the value at the given acceptable index is a full userdata, returns - * its block address. If the value is a light userdata, returns its pointer. - * Otherwise, returns NULL. - * - */ - public Object touserdata(int index) { - LValue v = topointer(index); - if ( v.luaGetType() != Lua.LUA_TUSERDATA ) - return null; - return ((LUserData)v).m_instance; - } - - /** - * Get the type of a value. [-0, +0, -] - * - *

- * Returns the type of the value in the given acceptable index, or - * LUA_TNONE for a non-valid index (that is, an index to an - * "empty" stack position). The types returned by lua_type - * are coded by the following constants defined in lua.h: - * LUA_TNIL, LUA_TNUMBER, - * LUA_TBOOLEAN, LUA_TSTRING, - * LUA_TTABLE, LUA_TFUNCTION, - * LUA_TUSERDATA, LUA_TTHREAD, and - * LUA_TLIGHTUSERDATA. - */ - public int type(int index) { - return topointer(index).luaGetType(); - } - - /** - * Get the type name for a value. [-0, +0, -] - * - *

- * Returns the name of the type encoded by the value tp, - * which must be one the values returned by lua_type. - */ - public String typename(int index) { - return topointer(index).luaGetTypeName().toJavaString(); - } - - /** - * Exchange values between threads. [-?, +?, -] - * - *

- * Exchange values between different threads of the same global - * state. - * - * - *

- * This function pops n values from the stack - * from, and pushes them onto the stack to. - */ - public void xmove(LuaState to, int n) { - if ( n > 0 ) { - to.checkstack(n); - LuaState ss = (LuaState)to; - ss.checkstack(n); - System.arraycopy(stack, top-n, ss.stack, ss.top, n); - ss.top += n; - } - } - - // ============================= conversion to and from Java boxed types ==================== - - /** - * Push a Java Boolean value, or nil if the value is null. - * @param b Boolean value to convert, or null to to nil. - */ - public void pushboolean(Boolean b) { - if ( b == null ) - pushnil(); - else - pushboolean( b.booleanValue() ); - } - - /** - * Push a Java Byte value, or nil if the value is null. - * @param b Byte value to convert, or null to to nil. - */ - public void pushinteger(Byte b) { - if ( b == null ) - pushnil(); - else - pushinteger( b.byteValue() ); - } - - /** - * Push a Java Character value, or nil if the value is null. - * @param c Character value to convert, or null to to nil. - */ - public void pushinteger(Character c) { - if ( c == null ) - pushnil(); - else - pushinteger( c.charValue() ); - } - - /** - * Push a Java Double as a double, or nil if the value is null. - * @param d Double value to convert, or null to to nil. - */ - public void pushnumber(Double d) { - if ( d == null ) - pushnil(); - else - pushnumber( d.doubleValue() ); - } - - /** - * Push a Java Float value, or nil if the value is null. - * @param f Float value to convert, or null to to nil. - */ - public void pushnumber(Float f) { - if ( f == null ) - pushnil(); - else - pushnumber( f.doubleValue() ); - } - - /** - * Push a Java Integer value, or nil if the value is null. - * @param i Integer value to convert, or null to to nil. - */ - public void pushinteger(Integer i) { - if ( i == null ) - pushnil(); - else - pushinteger( i.intValue() ); - } - - /** - * Push a Java Short value, or nil if the value is null. - * @param s Short value to convert, or null to to nil. - */ - public void pushinteger(Short s) { - if ( s == null ) - pushnil(); - else - pushinteger( s.shortValue() ); - } - - /** - * Push a Java Long value, or nil if the value is null. - * @param l Long value to convert, or null to to nil. - */ - public void pushnumber(Long l) { - if ( l == null ) - pushnil(); - else - pushnumber( l.doubleValue() ); - } - - /** - * Push a Java Object as userdata, or nil if the value is null. - * @param o Object value to push, or null to to nil. - */ - public void pushuserdata( Object o ) { - if ( o == null ) - pushnil(); - else - pushlvalue( new LUserData(o) ); - } - - - /** - * Convert a value to a Java Boolean value, or null if the value is nil. - * @param index index of the parameter to convert. - * @return Boolean value at the index, or null if the value was not a boolean. - */ - public Boolean toboxedboolean(int index) { - return topointer(index).toJavaBoxedBoolean(); - } - - /** - * Convert a value to a Java Byte value, or null if the value is not a number. - * @param index index of the parameter to convert. - * @return Byte value at the index, or null if the value was not a number. - */ - public Byte toboxedbyte(int index) { - return topointer(index).toJavaBoxedByte(); - } - - /** - * Convert a value to a Java Double value, or null if the value is not a number. - * @param index index of the parameter to convert. - * @return Double value at the index, or null if the value was not a number. - */ - public Double toboxeddouble(int index) { - return topointer(index).toJavaBoxedDouble(); - } - - /** - * Convert a value to a Java Float value, or null if the value is not a number. - * @param index index of the parameter to convert. - * @return Float value at the index, or null if the value was not a boolean. - */ - public Float toboxedfloat(int index) { - return topointer(index).toJavaBoxedFloat(); - } - - /** - * Convert a value to a Java Integer value, or null if the value is not a number. - * @param index index of the parameter to convert. - * @return Integer value at the index, or null if the value was not a number. - */ - public Integer toboxedinteger(int index) { - return topointer(index).toJavaBoxedInteger(); - } - - /** - * Convert a value to a Java Long value, or null if the value is nil. - * @param index index of the parameter to convert. - * @return Long value at the index, or null if the value was not a number. - */ - public Long toboxedlong(int index) { - return topointer(index).toJavaBoxedLong(); - } - - // ================= Error Reporting Functions ================= - - /** - * Report an error with an argument. - * - * @param narg Stack index of the bad argument - * @param extramsg String to include in error message - */ - public void argerror(int narg, String extramsg) { - error("bad argument #" + (narg) + " (" + extramsg + ")"); - } - - /** - * Conditionally report an error with an argument. - * - * @param cond boolean condition that generates an error when false - * @param narg Stack index of the bad argument - * @param extramsg String to include in error message - */ - public void argcheck(boolean cond, int narg, String extramsg) { - if ( ! cond ) - argerror(narg,extramsg); - } - - /** - * Report a type error. - * - * @param narg Stack index of the bad argument - * @param typename Name of the type that was expected, such as "string" - */ - public void typerror(int narg, String typename) { - argerror(narg, typename + " expected, got " + typename(narg)); - } - - /** - * Report a type error. - * - * @param narg Stack index of the bad argument - * @param typenum Constant value specifying the type of argument that was expected (i.e. LUA_TSTRING). - */ - public void typerror(int narg, int typenum) { - typerror(narg, TYPE_NAMES[typenum]); - } - - - /** - * Checks whether the function has an argument of any type (including nil) - * at position narg. - * @param narg the argument number - * @return the value at the index - * @throws LuaErrorException if there is no argument at position narg - */ - public LValue checkany(int narg) { - if ( gettop() < narg ) - argerror(narg, "value expected"); - return topointer(narg); - } - - /** - * Checks whether the function argument narg is a function and - * returns this function. - * @see LFunction - * @param narg the argument number - * @throws LuaErrorException if the value is not a function - * @return LFunction value if the argument is a function - */ - public LFunction checkfunction(int narg) { - return (LFunction) checktype(narg, Lua.LUA_TFUNCTION); - } - - /** - * Checks whether the function argument narg is a thread and - * returns this thread. - * @see LThread - * @param narg the argument number - * @throws LuaErrorException if the value is not a thread - * @return LThread value if the argument is a thread - */ - public LThread checkthread(int narg) { - return (LThread) checktype(narg, Lua.LUA_TTHREAD); - } - - /** - * Checks whether the function argument narg is a number and - * returns this number cast to an int. - * @param narg the argument number - * @throws LuaErrorException if the number cannot be converted to an int - * @return int value if the argument is an int or can be converted to one - */ - public int checkint(int narg) { - LValue v = tolnumber(narg); - if ( v.isNil() ) - typerror(narg, Lua.LUA_TNUMBER); - return v.toJavaInt(); - } - - /** - * Checks whether the function argument narg is a number and - * returns this number cast to a LInteger. - * @see LInteger - * @param narg the argument number - * @throws LuaErrorException if the value cannot be converted to an int - * @return LInteger value if the argument is an int or can be converted to one - */ - public LInteger checkinteger(int narg) { - return LInteger.valueOf(checkint(narg)); - } - - /** - * Checks whether the function argument narg is a number and - * returns this number cast to a long. - * @param narg the argument number - * @throws LuaErrorException if the value cannot be converted to a long - * @return long value if the argument is a number or can be converted to long - */ - public long checklong(int narg) { - return checknumber(narg).toJavaLong(); - } - - /** - * Checks whether the function argument narg is a number and - * returns this number cast to a double. - * @param narg the argument number - * @throws LuaErrorException if the value cannot be converted to a double - * @return long value if the argument is a number or can be converted to double - */ - public double checkdouble(int narg) { - return checknumber(narg).toJavaDouble(); - } - - /** - * Checks whether the function argument narg is a number and - * returns this number. - * @see LNumber - * @param narg the argument number - * @throws LuaErrorException if the value cannot be converted to a number - * @return LNumber value if the argument is a number or can be converted to one - */ - public LNumber checknumber(int narg) { - LValue v = topointer(narg).luaToNumber(); - if ( v.isNil() ) - typerror(narg, Lua.LUA_TNUMBER); - return (LNumber) v; - } - - /** - * Checks whether the function argument narg is a string and - * returns this string as a lua string. - * @see LString - * @param narg the argument number - * @throws LuaErrorException if the value cannot be converted to a string - * @return LString value if the argument is a string or can be converted to one - */ - public LString checklstring(int narg) { - LValue v = topointer(narg); - if ( ! v.isString() ) - typerror(narg, Lua.LUA_TSTRING); - return v.luaAsString(); - } - - /** - * Checks whether the function argument narg is a string and - * returns this string as a Java String. - * @param narg the argument number - * @throws LuaErrorException if the value cannot be converted to a string - * @return String value if the argument is a string or can be converted to one - */ - public String checkstring(int narg) { - LValue v = topointer(narg); - if ( ! v.isString() ) - typerror(narg, Lua.LUA_TSTRING); - return v.toJavaString(); - } - - /** - * Checks whether the function argument narg is a table and - * returns this table. - * @see LTable - * @param narg the argument number - * @throws LuaErrorException if the value is not a table - * @return LTable value if the argument is a table - */ - public LTable checktable(int narg) { - return (LTable) checktype(narg, Lua.LUA_TTABLE); - } - - /** - * Checks whether the function argument narg has type - * t and return it as an LValue. - * @param narg the argument number - * @param t the type number to check against - * @return the lua value - * @throws LuaErrorException if the value is not of type t - */ - public LValue checktype(int narg, int t) { - LValue v = topointer(narg); - if ( v.luaGetType() != t ) - typerror(narg, t); - return v; - } - - - /** - * Check that the type of userdata on the stack matches the required type, - * and if so, return the Java Object the userdata value points to. - * - * @param ud - * Stack index of the argument to check - * @param expected - * Class that the userdata is expected to have an instance of. - */ - public Object checkudata(int ud, Class expected) { - Object p = touserdata(ud); - if (expected.isInstance(p)) { - return p; - } - typerror(ud, expected.getName()); - return null; - } - - /** - * If the function argument narg is a number, returns this - * number cast to an int. If this argument is absent or is - * nil, returns d. Otherwise, raises an error. - * @param narg the argument number - * @param d the default value when the argument is nil or not supplied - * @throws LuaErrorException if the value cannot be converted to an int - * @return int value if the argument is an int, or d - */ - public int optint(int narg, int d) { - LNumber n = optnumber(narg,null); - return (n==null? d: n.toJavaInt()); - } - - /** - * If the function argument narg is a number, returns this - * number cast to a lua_Integer. - * If this argument is absent or is nil, returns d. - * Otherwise, raises an error. - * @param narg the argument number - * @param d the default value when the argument is nil or not supplied - * @throws LuaErrorException if the value cannot be converted to an int - * @return int value if the argument is an int, or d - */ - public LInteger optinteger(int narg, int d) { - return LInteger.valueOf(optint(narg,d)); - } - - /** - * If the function argument narg is a number, returns this - * number cast to a long. If this argument is absent or is - * nil, returns d. Otherwise, raises an error. - * @param narg the argument number - * @param d the default value when the argument is nil or not supplied - * @throws LuaErrorException if the value cannot be converted to an number - * @return int value if the argument is an number, or d - */ - public long optlong(int narg, long d) { - LNumber n = optnumber(narg,null); - return (n==null? d: n.toJavaLong()); - } - - /** - * If the function argument narg is a number, returns this - * number. If this argument is absent or is nil, returns - * d. Otherwise, raises an error. - * @param narg the argument number - * @param d the default value when the argument is nil or not supplied - * @throws LuaErrorException if the value cannot be converted to an number - * @return int value if the argument is an number, or d - */ - public LNumber optnumber(int narg, LNumber d) { - LValue v = topointer(narg); - if ( v.isNil() ) - return d; - v = v.luaToNumber(); - if ( v.isNil() ) - typerror(narg, Lua.LUA_TNUMBER); - return (LNumber) v; - - } - - /** - * If the function argument narg is a string, returns this - * string. If this argument is absent or is nil, returns - * d. Otherwise, raises an error. - */ - public LString optlstring(int narg, LString d) { - LValue v = topointer(narg); - if ( v.isNil() ) - return d; - if ( ! v.isString() ) - typerror(narg, Lua.LUA_TSTRING); - return v.luaAsString(); - } - - /** - * If the function argument narg is a string, returns this - * string. If this argument is absent or is nil, returns - * d. Otherwise, raises an error. - */ - public String optstring(int narg, String d) { - LValue v = topointer(narg); - if ( v.isNil() ) - return d; - if ( ! v.isString() ) - typerror(narg, Lua.LUA_TSTRING); - return v.toJavaString(); - } - - /** - * Method to indicate a vm internal error has occurred. Generally, this is - * not recoverable, so we convert to a lua error during production so that - * the code may recover. - */ - public static void vmerror(String description) { - throw new LuaErrorException( "internal error: "+description ); - } - - /** - * Call a function with no arguments and one return value. - * This may change values in the current stack frame. - * @param function - * @return - */ - public LValue call(LFunction function) { - pushlvalue(function); - call(0,1); - return poplvalue(); - } - - /** - * Call a function with one argument and one return value - * This may change values in the current stack frame. - * @param function - * @param arg0 - * @return - */ - public LValue call(LFunction function, LValue arg0) { - pushlvalue(function); - pushlvalue(arg0); - call(1,1); - return poplvalue(); - } - - /** - * Call an index function with two arguments and one return value - * Values in the current stack frame will be preserved. - * @param function the __index function to call - * @param table the table on which the metadata operation is taking place - * @param key the key used in the index operation - * @return the value that results from the metatable operation - */ - public LValue luaV_call_index(LFunction function, LValue table, LValue key) { - int oldtop = top; - try { - if ( cc >= 0 ) - top = base + this.calls[cc].closure.p.maxstacksize; - pushlvalue(function); - pushlvalue(table); - pushlvalue(key); - call(2,1); - return poplvalue(); - } finally { - top = oldtop; - } - } - - /** - * Call a newindex function with three arguments and one return value - * Values in the current stack frame will be preserved. - * @param function the __newindex function to call - * @param table the table on which the metadata operation is taking place - * @param key the key used in the newindex operation - * @param value the value beting set in the newindex operation - * @return the value that results from the metatable operation - */ - public LValue luaV_call_newindex(LFunction function, LValue table, LValue key, LValue value) { - int oldtop = top; - try { - if ( cc >= 0 ) - top = base + this.calls[cc].closure.p.maxstacksize; - pushlvalue(function); - pushlvalue(table); - pushlvalue(key); - pushlvalue(value); - call(3,1); - return poplvalue(); - } finally { - top = oldtop; - } - } - - - /** - * Call the error function, if any, to possibly modify the message - */ - public String luaV_call_errfunc(String message) { - - // error function runs without hooks - if ( inhook || errfunc == null ) - return message; - - // run the error function - int oldtop = top; - try { - inhook = true; - if ( cc >= 0 ) - top = base + this.calls[cc].closure.p.maxstacksize; - pushlvalue(errfunc); - pushstring(message); - call(1,1); - return poplvalue().toJavaString(); - - } catch ( Throwable t ) { - return "error in error handling: "+t.getMessage(); - - } finally { - top = oldtop; - inhook = false; - } - } - - - // =========================================================================== - // Debug hooks. - // These should be obfuscated out when sethook is never called - // cannot be called from the application. - // - - /** - * Set the hook function. - * - * @param func LFunction to call on the hook event - * @param mask combination of LuaState.LUA_MASKLINE, LuaState.LUA_MASKCALL, and LuaState.LUA_MASKRET - * @param count 0, or number of bytecodes between count events. - */ - public void sethook( LFunction func, int mask, int count ) { - hooksenabled = (mask != 0 || count > 0); - hookfunc = func; - hookmask = mask; - hookcount = count; - } - - /** - * Get the current hook function, if any. - * - * @return LFunction that is set as the current hook function, or null if not set. - */ - public LFunction gethook() { - return hookfunc; - } - - /** - * Get the current hook count. - * - * @return current count, which is # of bytecodes between "count" hook calls - */ - public int gethookcount() { - return hookcount; - } - - /** - * Get the current hook mask. - * - * @return current mask as a combination of - * LuaState.LUA_MASKLINE, LuaState.LUA_MASKCALL, and LuaState.LUA_MASKRET - */ - public int gethookmask() { - return hookmask; - } - - // line number and count hooks - private void debugBytecodeHooks(int pc) { - if ( hookfunc != null ) { - if (hookcount != 0) { - if ( --hookincr <= 0 ) { - hookincr = hookcount; - debugInvokeHook(LUA_HOOKCOUNT, -1); - } - } - if ( (hookmask & LUA_MASKLINE) != 0 ) { - int line = calls[cc].currentline(); - if ( (line != hookline || cc != hookcc) && line >= 0 ) { - hookline = line; - hookcc = cc; - debugInvokeHook(LUA_HOOKLINE, line); - } - } - } - } - - private void debugCallHooks() { - if ( hookfunc != null && ((hookmask & LUA_MASKCALL) != 0) ) { - debugInvokeHook(LUA_HOOKCALL, calls[cc].currentline()); - } - } - - private void debugReturnHooks() { - if ( hookfunc != null && ((hookmask & LUA_MASKRET) != 0) ) { - debugInvokeHook(LUA_HOOKRET, calls[cc].currentline()); - } - } - - private void debugTailReturnHooks() { - if ( hookfunc != null && ((hookmask & LUA_MASKRET) != 0) ) { - debugInvokeHook(LUA_HOOKTAILRET, calls[cc].currentline()); - } - } - - private void debugInvokeHook(int mask, int line) { - if ( inhook ) - return; - int oldtop = top; - int oldbase = base; - int oldcc = cc; - int oldnresults = nresults; - int beyond = (cc>=0? base+calls[cc].closure.p.maxstacksize: top); - try { - inhook = true; - - // adjust base and top to beyond call frame - top = base = beyond; - - // push hook function and arguments - this.pushfunction(hookfunc); - switch ( mask ) { - case LUA_HOOKCOUNT: this.pushstring("count"); break; - case LUA_HOOKCALL: this.pushstring("call"); break; - case LUA_HOOKRET: this.pushstring("return"); break; - case LUA_HOOKTAILRET: this.pushstring("tail return"); break; - default: - this.pushstring("line"); - this.pushinteger(line); - break; - } - - // make or set up the call - this.nresults = 0; - if ( this.stack[base].luaStackCall(this) ) - execute(); - - } catch ( Throwable t ) { - System.err.println("hook exception: "+t); - } finally { - luaV_settop_fillabove(beyond); - cc = oldcc; - base = oldbase; - top = oldtop; - nresults = oldnresults; - inhook = false; - } - } -} diff --git a/src/core/org/luaj/vm/Platform.java b/src/core/org/luaj/vm/Platform.java deleted file mode 100644 index 3ef1cda9..00000000 --- a/src/core/org/luaj/vm/Platform.java +++ /dev/null @@ -1,186 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 LuaJ. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ -package org.luaj.vm; - -import java.io.InputStream; -import java.io.Reader; - -/** - * Singleton to manage platform-specific behaviors. - *

- * Here is the sample code to set up the platform instance and create a new - * LuaState instance. - *

- *    Platform.setInstance(new J2meMidp20Cldc11Platform());
- *    LuaState vm = Platform.newLuaState();
- * 
- */ -abstract public class Platform { - - /** - * When non-null, name of a Java Class that implements LuaState - * and has a default constructor which will be used to construct - * a new lua state using Platform.newLuaState() - * @see newLuaState - */ - public static String LUA_STATE_CLASS_NAME = null; - - /** - * The singleton Platform instance in use by this JVM - */ - private static Platform instance; - - - /** - * Singleton to be used for platform operations. - * - * The default Platform gets files as resources, and converts them to - * characters using the default InputStreamReader class. - */ - public static Platform getInstance() { - if (instance == null) { - throw new RuntimeException("Platform instance is null. Use Platform.setInstance(Platform p) to set the instance first."); - } - - return instance; - } - - /** - * Set the Platform instance. - * - * This may be useful to define a file search path, or custom character - * encoding conversion properties. - */ - public static void setInstance(Platform platform) { - instance = platform; - } - - /** - * Creates a new instance of LuaState. - * - * If Platform.LUA_STATE_CLASS_NAME is not null, this method - * will attempt to create an instance using a construction such as - * (LuaState) Class.forName(Platform.LUA_STATE_CLASS_NAME).newInstance() - * - * If Platform.LUA_STATE_CLASS_NAME is null or the specified class cannot - * be instantiated for some reason, a new instance of LuaState - * will be created and used. - * - * In either case, the method LuaState.init() will be invoked, followed by - * Platform.installOptionalProperties(LuaState) on the new instance. - * - * @return a new instance of LuaState initialized via init() and installOptionalProperties() - * - * @see LUA_STATE_CLASS_NAME - * @see LuaState - */ - public static LuaState newLuaState() { - Platform p = Platform.getInstance(); - LuaState vm = null; - if (LUA_STATE_CLASS_NAME != null) { - try { - vm = (LuaState) Class.forName(LUA_STATE_CLASS_NAME).newInstance(); - } catch (Exception e) { - System.out.println("Warning: no debug support, " + e); - } - } - - if (vm == null) - vm = new LuaState(); - - vm.init(); - p.installOptionalLibs(vm); - - return vm; - } - - /** Get the name of the platform - */ - abstract public String getName(); - - /** - * Return an InputStream or null if not found for a particular file name. - * - * @param fileName - * Name of the file to open - * @return InputStream or null if not found. - */ - abstract public InputStream openFile(String fileName); - - /** - * Create Reader from an InputStream - * - * @param inputStream - * InputStream to read from - * @return Reader instance to use for character input - */ - abstract public Reader createReader(InputStream inputStream); - - /** - * Returns the value for the given platform property. - * - * @param propertyName - * Property name - * @return Property value - */ - abstract public String getProperty(String propertyName); - - /** - * Install optional libraries on the LuaState. - * @param vm LuaState instance - */ - abstract protected void installOptionalLibs(LuaState vm); - - /** - * Compute math.pow() for two numbers using double math when available. - * @param lhs LNumber base - * @param rhs LNumber exponent - * @return base ^ exponent as a LNumber, throw RuntimeException if not implemented - */ - abstract public LNumber mathPow(LNumber base, LNumber exponent); - - /** - * Compute a math operation that takes a single double argument and returns a double - * @param id the math op, from MathLib constants - * @param x the argument - * @return the value as an LNumber - * @throws LuaErrorException if the id is not supported by this platform. - */ - abstract public LNumber mathop(int id, LNumber x); - - /** - * Compute a math operation that takes a two double arguments and returns a double - * @param id the math op, from MathLib constants - * @param x the first argument as an LNumber - * @param y the second arugment as an LNumber - * @return the value as an LNumber - * @throws LuaErrorException if the id is not supported by this platform. - */ - abstract public LNumber mathop(int id, LNumber x, LNumber y); - - - /** Throw an error indicating the math operation is not accepted */ - public LNumber unsupportedMathOp() { - throw new LuaErrorException("math op not supported on "+getName()); - } - -} diff --git a/src/core/org/luaj/vm/Print.java b/src/core/org/luaj/vm/Print.java deleted file mode 100644 index 5855ad32..00000000 --- a/src/core/org/luaj/vm/Print.java +++ /dev/null @@ -1,357 +0,0 @@ -package org.luaj.vm; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; - - - - - -public class Print extends Lua { - - /** opcode names */ - private static final String STRING_FOR_NULL = "null"; - public static PrintStream ps = System.out; - - private static final String[] luaP_opnames = { - "MOVE", - "LOADK", - "LOADBOOL", - "LOADNIL", - "GETUPVAL", - "GETGLOBAL", - "GETTABLE", - "SETGLOBAL", - "SETUPVAL", - "SETTABLE", - "NEWTABLE", - "SELF", - "ADD", - "SUB", - "MUL", - "DIV", - "MOD", - "POW", - "UNM", - "NOT", - "LEN", - "CONCAT", - "JMP", - "EQ", - "LT", - "LE", - "TEST", - "TESTSET", - "CALL", - "TAILCALL", - "RETURN", - "FORLOOP", - "FORPREP", - "TFORLOOP", - "SETLIST", - "CLOSE", - "CLOSURE", - "VARARG", - null, - }; - - - static void printString(PrintStream ps, final LString s) { - final byte[] bytes = s.m_bytes; - final int off = s.m_offset; - - ps.print('"'); - for (int i = 0, n = s.m_length; i < n; i++) { - int c = bytes[i+off] & 0x0FF; - if ( c >= ' ' && c <= '~' && c != '\"' && c != '\\' ) - ps.print((char) c); - else { - switch (c) { - case '"': - ps.print("\\\""); - break; - case '\\': - ps.print("\\\\"); - break; - case 0x0007: /* bell */ - ps.print("\\a"); - break; - case '\b': /* backspace */ - ps.print("\\f"); - break; - case '\f': /* form feed */ - ps.print("\\f"); - break; - case '\r': /* carriage return */ - ps.print("\\r"); - break; - case '\n': /* newline */ - ps.print("\\n"); - break; - case 0x000B: /* vertical tab */ - ps.print("\\v"); - break; - default: - ps.print('\\'); - ps.print(Integer.toString(1000 + c).substring(1)); - break; - } - } - } - ps.print('"'); - } - - static void printValue( PrintStream ps, LValue v ) { - if ( v instanceof LString ) - printString( ps, v.luaAsString() ); - else if ( v instanceof LInteger ) { - ps.print( v.toJavaInt() ); - } else if ( v instanceof LDouble ) { - double d = v.toJavaDouble(); - if ( d == ((int)d) ) - ps.print( (int) d ); - else - ps.print( d ); - } else if ( v instanceof LFunction ) { - ps.print(v.getClass().getName()); - } else { - ps.print( String.valueOf(v) ); - } - } - - static void printConstant(PrintStream ps, LPrototype f, int i) { - printValue( ps, f.k[i] ); - } - - public static void printCode(LPrototype f) { - int[] code = f.code; - int pc, n = code.length; - for (pc = 0; pc < n; pc++) { - printOpCode(f, pc); - ps.println(); - } - } - - public static void printOpCode(LPrototype f, int pc) { - printOpCode(ps,f,pc); - } - - public static void printOpCode(PrintStream ps, LPrototype f, int pc) { - int[] code = f.code; - int i = code[pc]; - int o = GET_OPCODE(i); - int a = GETARG_A(i); - int b = GETARG_B(i); - int c = GETARG_C(i); - int bx = GETARG_Bx(i); - int sbx = GETARG_sBx(i); - int line = getline(f, pc); - ps.print(" " + (pc + 1) + " "); - if (line > 0) - ps.print("[" + line + "] "); - else - ps.print("[-] "); - ps.print(luaP_opnames[o] + " "); - switch (getOpMode(o)) { - case iABC: - ps.print( a ); - if (getBMode(o) != OpArgN) - ps.print(" "+(ISK(b) ? (-1 - INDEXK(b)) : b)); - if (getCMode(o) != OpArgN) - ps.print(" "+(ISK(c) ? (-1 - INDEXK(c)) : c)); - break; - case iABx: - if (getBMode(o) == OpArgK) { - ps.print(a + " " + (-1 - bx)); - } else { - ps.print(a + " " + (bx)); - } - break; - case iAsBx: - if (o == OP_JMP) - ps.print( sbx ); - else - ps.print(a + " " + sbx); - break; - } - switch (o) { - case OP_LOADK: - ps.print(" ; "); - printConstant(ps, f, bx); - break; - case OP_GETUPVAL: - case OP_SETUPVAL: - ps.print(" ; "); - if ( f.upvalues.length > b ) - printValue(ps, f.upvalues[b]); - else - ps.print( "-" ); - break; - case OP_GETGLOBAL: - case OP_SETGLOBAL: - ps.print(" ; "); - printConstant( ps, f, bx ); - break; - case OP_GETTABLE: - case OP_SELF: - if (ISK(c)) { - ps.print(" ; "); - printConstant(ps, f, INDEXK(c)); - } - break; - case OP_SETTABLE: - case OP_ADD: - case OP_SUB: - case OP_MUL: - case OP_DIV: - case OP_POW: - case OP_EQ: - case OP_LT: - case OP_LE: - if (ISK(b) || ISK(c)) { - ps.print(" ; "); - if (ISK(b)) - printConstant(ps, f, INDEXK(b)); - else - ps.print("-"); - ps.print(" "); - if (ISK(c)) - printConstant(ps, f, INDEXK(c)); - else - ps.print("-"); - } - break; - case OP_JMP: - case OP_FORLOOP: - case OP_FORPREP: - ps.print(" ; to " + (sbx + pc + 2)); - break; - case OP_CLOSURE: - ps.print(" ; " + f.p[bx].getClass().getName()); - break; - case OP_SETLIST: - if (c == 0) - ps.print(" ; " + ((int) code[++pc])); - else - ps.print(" ; " + ((int) c)); - break; - case OP_VARARG: - ps.print( " ; is_vararg="+ f.is_vararg ); - break; - default: - break; - } - } - - private static int getline(LPrototype f, int pc) { - return pc>0 && f.lineinfo!=null && pc (" + f.code.length + " instructions, " - + f.code.length * 4 + " bytes at " + id(f) + ")\n"); - ps.print(f.numparams + " param, " + f.maxstacksize + " slot, " - + f.upvalues.length + " upvalue, "); - ps.print(f.locvars.length + " local, " + f.k.length - + " constant, " + f.p.length + " function\n"); - } - - static void printConstants(LPrototype f) { - int i, n = f.k.length; - ps.print("constants (" + n + ") for " + id(f) + ":\n"); - for (i = 0; i < n; i++) { - ps.print(" " + (i + 1) + " "); - printValue( ps, f.k[i] ); - ps.print( "\n"); - } - } - - static void printLocals(LPrototype f) { - int i, n = f.locvars.length; - ps.print("locals (" + n + ") for " + id(f) + ":\n"); - for (i = 0; i < n; i++) { - ps.println(" "+i+" "+f.locvars[i].varname+" "+(f.locvars[i].startpc+1)+" "+(f.locvars[i].endpc+1)); - } - } - - static void printUpValues(LPrototype f) { - int i, n = f.upvalues.length; - ps.print("upvalues (" + n + ") for " + id(f) + ":\n"); - for (i = 0; i < n; i++) { - ps.print(" " + i + " " + f.upvalues[i] + "\n"); - } - } - - public void printFunction(LPrototype f, boolean full) { - int i, n = f.p.length; - printHeader(f); - printCode(f); - if (full) { - printConstants(f); - printLocals(f); - printUpValues(f); - } - for (i = 0; i < n; i++) - printFunction(f.p[i], full); - } - - private static void format( String s, int maxcols ) { - int n = s.length(); - if ( n > maxcols ) - ps.print( s.substring(0,maxcols) ); - else { - ps.print( s ); - for ( int i=maxcols-n; --i>=0; ) - ps.print( ' ' ); - } - } - - public static void printState(LuaState state, int base, int top, int max, - LClosure cl, int pc) { - - // print opcode into buffer - PrintStream previous = ps; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ps = new PrintStream( baos ); - printOpCode( cl.p, pc ); - ps.flush(); - ps.close(); - ps = previous; - format( baos.toString(), 40 ); - - ps.print( " b,t=(" ); - format( String.valueOf(base), 3 ); - ps.print( "," ); - format( String.valueOf(top), 3 ); - ps.print( ") " ); - - // print stack - int i=0; - for ( ; i= limit ) { - value = state.stack[ position ]; - state = null; - return true; - } else { - return false; - } - } - - public boolean isClosed() { - return state == null; - } -} diff --git a/src/j2me/org/luaj/lib/j2me/Cldc10IoLib.java b/src/j2me/org/luaj/lib/j2me/Cldc10IoLib.java deleted file mode 100644 index 80048159..00000000 --- a/src/j2me/org/luaj/lib/j2me/Cldc10IoLib.java +++ /dev/null @@ -1,211 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2008 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.lib.j2me; -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.lib.BaseLib; -import org.luaj.lib.IoLib; -import org.luaj.vm.LString; -import org.luaj.vm.LTable; - -/** - * Implementation of the lua io library based on CLDC 1.0 and StreamConnection. - * - * Seek is not supported. - */ -public class Cldc10IoLib extends IoLib { - - public static void install( LTable globals ) { - new Cldc10IoLib().initialize(globals); - } - - public Cldc10IoLib() { - super(); - } - - public Cldc10IoLib(int index) { - super(index); - } - - protected IoLib newInstance(int index) { - return new Cldc10IoLib(index); - } - - protected File wrapStdin() throws IOException { - return new FileImpl(BaseLib.STDIN); - } - - protected File wrapStdout() throws IOException { - return new FileImpl(BaseLib.STDOUT != null? BaseLib.STDOUT: System.out); - } - - 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 static final class FileImpl implements 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 toString() { - 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(LString 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/j2me/org/luaj/platform/J2meMidp10Cldc10Platform.java b/src/j2me/org/luaj/platform/J2meMidp10Cldc10Platform.java deleted file mode 100644 index c84d3f25..00000000 --- a/src/j2me/org/luaj/platform/J2meMidp10Cldc10Platform.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.luaj.platform; - -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; - -import javax.microedition.midlet.MIDlet; - -import org.luaj.vm.LNumber; -import org.luaj.vm.LuaState; -import org.luaj.vm.Platform; - -public class J2meMidp10Cldc10Platform extends Platform { - protected MIDlet midlet; - - public String getName() { - return "j2me"; - } - - public J2meMidp10Cldc10Platform(MIDlet midlet) { - this.midlet = midlet; - } - - public Reader createReader(InputStream inputStream) { - return new InputStreamReader(inputStream); - } - - public InputStream openFile(String fileName) { - if (!fileName.startsWith("/")) - fileName = "/" + fileName; - InputStream is = this.getClass().getResourceAsStream(fileName); - return is; - } - public String getProperty(String key) { - return midlet.getAppProperty(key); - } - - protected void installOptionalLibs(LuaState vm) { - vm.installStandardLibs(); - } - - public LNumber mathPow(LNumber base, LNumber exponent) { - return unsupportedMathOp(); - } - - public LNumber mathop(int id, LNumber x, LNumber y) { - return unsupportedMathOp(); - } - - public LNumber mathop(int id, LNumber x) { - return unsupportedMathOp(); - } -} diff --git a/src/j2me/org/luaj/platform/J2meMidp20Cldc11Platform.java b/src/j2me/org/luaj/platform/J2meMidp20Cldc11Platform.java deleted file mode 100644 index d6df7dd6..00000000 --- a/src/j2me/org/luaj/platform/J2meMidp20Cldc11Platform.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.luaj.platform; - -import javax.microedition.midlet.MIDlet; - -import org.luaj.lib.MathLib; -import org.luaj.vm.LDouble; -import org.luaj.vm.LNumber; - -public class J2meMidp20Cldc11Platform extends J2meMidp10Cldc10Platform { - public J2meMidp20Cldc11Platform(MIDlet midlet) { - super(midlet); - } - - public LNumber mathPow(LNumber base, LNumber exp) { - return LDouble.numberOf(dpow(base.toJavaDouble(),exp.toJavaDouble())); - } - - public LNumber mathop(int id, LNumber la, LNumber lb) { - double a = la.toJavaDouble(); - double b = lb.toJavaDouble(); - double z = 0; - switch ( id ) { - default: return unsupportedMathOp(); - //case MathLib.ATAN2: z = - // b>0? Math.atan(a/b): - // b<0? (a>=0? Math.PI-Math.atan(a/-b): -Math.PI-Math.atan(a/-b)): - // (a>0? Math.PI/2: a<0? -Math.PI/2: 0); - // break; - case MathLib.FMOD: z = a - (b * ((int)(a/b))); break; - case MathLib.POW: z = dpow(a, b); break; - } - return LDouble.numberOf(z); - } - - - public LNumber mathop(int id, LNumber lx) { - double x = lx.toJavaDouble(); - double z = 0; - switch ( id ) { - default: return unsupportedMathOp(); - case MathLib.ABS: z = Math.abs(x); break; - //case MathLib.ACOS: z = Math.acos(x); break; - //case MathLib.ASIN: z = Math.asin(x); break; - //case MathLib.ATAN: z = Math.atan(x); break; - case MathLib.COS: z = Math.cos(x); break; - //case MathLib.COSH: z = (Math.exp(x) + Math.exp(-x)) / 2; break; - case MathLib.DEG: z = Math.toDegrees(x); break; - //case MathLib.EXP: z = Math.exp(x); break; - //case MathLib.LOG: z = Math.log(x); break; - //case MathLib.LOG10: z = Math.log10(x); break; - case MathLib.RAD: z = Math.toRadians(x); break; - case MathLib.SIN: z = Math.sin(x); break; - //case MathLib.SINH: z = (Math.exp(x) - Math.exp(-x)) / 2; break; - case MathLib.SQRT: z = Math.sqrt(x); break; - case MathLib.TAN: z = Math.tan(x); break; - //case MathLib.TANH: { - // double e = Math.exp(2*x); - // z = (e-1) / (e+1); - // break; - //} - } - return LDouble.numberOf(z); - } - - public static double dpow(double a, double b) { - if ( b < 0 ) - return 1 / dpow( a, -b ); - double p = 1; - int whole = (int) b; - for ( double v=a; whole > 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/j2se/lua.java b/src/j2se/lua.java deleted file mode 100644 index dc1bd649..00000000 --- a/src/j2se/lua.java +++ /dev/null @@ -1,211 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2008 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. -******************************************************************************/ - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - -import org.luaj.compiler.LuaC; -import org.luaj.lib.DebugLib; -import org.luaj.platform.J2sePlatform; -import org.luaj.vm.LFunction; -import org.luaj.vm.LString; -import org.luaj.vm.LTable; -import org.luaj.vm.Lua; -import org.luaj.vm.LuaState; -import org.luaj.vm.Platform; - - -/** - * lua command for use in java se environments. - */ -public class lua { - private static final String version = Lua._VERSION + " Copyright (C) 2009 luaj.org"; - - private static final String usage = - "usage: java -cp luaj-j2se.jar lua [options] [script [args]].\n" + - "Available options are:\n" + - " -e stat execute string 'stat'\n" + - " -l name require library 'name'\n" + - " -i enter interactive mode after executing 'script'\n" + - " -v show version information\n" + - " -- stop handling options\n" + - " - execute stdin and stop handling options"; - - private static void usageExit() { - System.out.println(usage); - System.exit(-1); - } - - public static void main( String[] args ) throws IOException { - - // new lua state - Platform.setInstance(new J2sePlatform()); - LuaC.install(); - LuaState vm = Platform.newLuaState(); - DebugLib.install(vm); - - // process args - boolean interactive = (args.length == 0); - boolean versioninfo = false; - boolean processing = true; - try { - // stateful argument processing - for ( int i=0; i= args.length ) - usageExit(); - // input script - defer to last stage - break; - case 'l': - if ( ++i >= args.length ) - usageExit(); - loadLibrary( vm, args[i] ); - break; - case 'i': - interactive = true; - break; - case 'v': - versioninfo = true; - break; - case '-': - if ( args[i].length() > 2 ) - usageExit(); - processing = false; - break; - default: - usageExit(); - break; - } - } - } - - // echo version - if ( versioninfo ) - System.out.println(version); - - // input script processing - processing = true; - for ( int i=0; i "); - System.out.flush(); - String line = reader.readLine(); - if ( line == null ) - return; - processScript( vm, new ByteArrayInputStream(line.getBytes()), "-", null, 0 ); - } - } -} diff --git a/src/j2se/luac.java b/src/j2se/luac.java deleted file mode 100644 index 55afbd83..00000000 --- a/src/j2se/luac.java +++ /dev/null @@ -1,185 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2008 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. -******************************************************************************/ - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.luaj.compiler.DumpState; -import org.luaj.compiler.LuaC; -import org.luaj.platform.J2sePlatform; -import org.luaj.vm.LPrototype; -import org.luaj.vm.Lua; -import org.luaj.vm.LuaState; -import org.luaj.vm.Platform; -import org.luaj.vm.Print; - - -/** - * luac command for use in java se environments. - */ -public class luac { - private static final String version = Lua._VERSION + "Copyright (C) 2008 luaj.org"; - - private static final String usage = - "usage: java -cp luaj-j2se.jar luac [options] [filenames].\n" + - "Available options are:\n" + - " - process stdin\n" + - " -l list\n" + - " -o name output to file 'name' (default is \"luac.out\")\n" + - " -p parse only\n" + - " -s strip debug information\n" + - " -e little endian format for numbers\n" + - " -i number format 'n', (n=0,1 or 4, default="+DumpState.NUMBER_FORMAT_DEFAULT+")\n" + - " -v show version information\n" + - " -- stop handling options\n"; - - private static void usageExit() { - System.out.println(usage); - System.exit(-1); - } - - private boolean list = false; - private String output = "luac.out"; - private boolean parseonly = false; - private boolean stripdebug = false; - private boolean littleendian = false; - private int numberformat = DumpState.NUMBER_FORMAT_DEFAULT; - private boolean versioninfo = false; - private boolean processing = true; - - public static void main( String[] args ) throws IOException { - new luac( args ); - } - - private luac( String[] args ) throws IOException { - // new lua state - Platform.setInstance(new J2sePlatform()); - LuaC.install(); - LuaState vm = Platform.newLuaState(); - - // process args - try { - // get stateful args - for ( int i=0; i= args.length ) - usageExit(); - output = args[i]; - break; - case 'p': - parseonly = true; - break; - case 's': - stripdebug = true; - break; - case 'e': - littleendian = true; - break; - case 'i': - if ( args[i].length() <= 2 ) - usageExit(); - numberformat = Integer.parseInt(args[i].substring(2)); - break; - case 'v': - versioninfo = true; - break; - case '-': - if ( args[i].length() > 2 ) - usageExit(); - processing = false; - break; - default: - usageExit(); - break; - } - } - } - - // echo version - if ( versioninfo ) - System.out.println(version); - - // open output file - OutputStream fos = new FileOutputStream( output ); - - // process input files - try { - processing = true; - for ( int i=0; i=0? path.substring(0,i+1): path; - } - - private boolean callFunction( String name ) { - try { - vm.getglobal( name ); - if ( ! vm.isfunction(-1) ) { - vm.pop(1); - return false; - } - else { - vm.pushlvalue( lthis ); - vm.call( 1, 0 ); - return true; - } - } catch ( Throwable t ) { - System.err.println(name+"():"); - t.printStackTrace( System.err ); - return true; - } - } - - public synchronized void start() { - super.start(); - callFunction( "start" ); - } - - public synchronized void stop() { - callFunction( "stop" ); - super.stop(); - } - - public synchronized void destroy() { - callFunction( "destroy" ); - super.destroy(); - } -} diff --git a/src/j2se/org/luaj/lib/j2se/CoerceJavaToLua.java b/src/j2se/org/luaj/lib/j2se/CoerceJavaToLua.java deleted file mode 100644 index 4080ddcc..00000000 --- a/src/j2se/org/luaj/lib/j2se/CoerceJavaToLua.java +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.lib.j2se; - -import java.util.HashMap; -import java.util.Map; - -import org.luaj.vm.LBoolean; -import org.luaj.vm.LDouble; -import org.luaj.vm.LInteger; -import org.luaj.vm.LNil; -import org.luaj.vm.LString; -import org.luaj.vm.LValue; - - -public class CoerceJavaToLua { - - public static interface Coercion { - public LValue coerce( Object javaValue ); - }; - - private static Map COERCIONS = new HashMap(); - - static { - Coercion boolCoercion = new Coercion() { - public LValue coerce( Object javaValue ) { - Boolean b = (Boolean) javaValue; - return b.booleanValue()? LBoolean.TRUE: LBoolean.FALSE; - } - } ; - Coercion intCoercion = new Coercion() { - public LValue coerce( Object javaValue ) { - Number n = (Number) javaValue; - return LInteger.valueOf( n.intValue() ); - } - } ; - Coercion charCoercion = new Coercion() { - public LValue coerce( Object javaValue ) { - Character c = (Character) javaValue; - return LInteger.valueOf( c.charValue() ); - } - } ; - Coercion doubleCoercion = new Coercion() { - public LValue coerce( Object javaValue ) { - Number n = (Number) javaValue; - return LDouble.numberOf( n.doubleValue() ); - } - } ; - Coercion stringCoercion = new Coercion() { - public LValue coerce( Object javaValue ) { - return new LString( javaValue.toString() ); - } - } ; - 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( Float.class, doubleCoercion ); - COERCIONS.put( Double.class, doubleCoercion ); - COERCIONS.put( String.class, stringCoercion ); - } - - public static LValue coerce(Object o) { - if ( o == null ) - return LNil.NIL; - Class clazz = o.getClass(); - Coercion c = (Coercion) COERCIONS.get( clazz ); - if ( c != null ) - return c.coerce( o ); - return LuajavaLib.toUserdata( o, clazz ); - } - -} diff --git a/src/j2se/org/luaj/lib/j2se/CoerceLuaToJava.java b/src/j2se/org/luaj/lib/j2se/CoerceLuaToJava.java deleted file mode 100644 index 9cae61d3..00000000 --- a/src/j2se/org/luaj/lib/j2se/CoerceLuaToJava.java +++ /dev/null @@ -1,283 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.lib.j2se; - -import java.lang.reflect.Array; -import java.util.HashMap; -import java.util.Map; - -import org.luaj.vm.LBoolean; -import org.luaj.vm.LDouble; -import org.luaj.vm.LInteger; -import org.luaj.vm.LNumber; -import org.luaj.vm.LString; -import org.luaj.vm.LTable; -import org.luaj.vm.LUserData; -import org.luaj.vm.LValue; -import org.luaj.vm.LuaErrorException; - - -public class CoerceLuaToJava { - - public static interface Coercion { - public Object coerce( LValue value ); - public int score( LValue value ); - }; - - private static Map COERCIONS = new HashMap(); - private static Coercion OBJECT_COERCION; - - static { - Coercion boolCoercion = new Coercion() { - public Object coerce(LValue value) { - return value.toJavaBoolean()? Boolean.TRUE: Boolean.FALSE; - } - public int score(LValue value) { - if ( value instanceof LBoolean || value.isNil() ) - return 0; - if ( value instanceof LNumber ) - return 1; - return 4; - } - }; - Coercion byteCoercion = new Coercion() { - public Object coerce(LValue value) { - return new Byte( value.toJavaByte() ); - } - public int score(LValue value) { - if ( value instanceof LInteger ) - return 1; - if ( value instanceof LNumber ) - return 2; - return 4; - } - }; - Coercion charCoercion = new Coercion() { - public Object coerce(LValue value) { - return new Character( value.toJavaChar() ); - } - public int score(LValue value) { - if ( value instanceof LInteger ) - return 1; - if ( value instanceof LNumber ) - return 2; - return 4; - } - }; - Coercion shortCoercion = new Coercion() { - public Object coerce(LValue value) { - return new Short( value.toJavaShort() ); - } - public int score(LValue value) { - if ( value instanceof LInteger ) - return 1; - if ( value instanceof LNumber ) - return 2; - return 4; - } - }; - Coercion intCoercion = new Coercion() { - public Object coerce(LValue value) { - return new Integer( value.toJavaInt() ); - } - public int score(LValue value) { - if ( value instanceof LInteger ) - return 0; - if ( value instanceof LNumber ) - return 1; - if ( value instanceof LBoolean || value.isNil() ) - return 2; - return 4; - } - }; - Coercion longCoercion = new Coercion() { - public Object coerce(LValue value) { - return new Long( value.toJavaLong() ); - } - public int score(LValue value) { - if ( value instanceof LInteger ) - return 1; - if ( value instanceof LNumber ) - return 2; - return 4; - } - }; - Coercion floatCoercion = new Coercion() { - public Object coerce(LValue value) { - return new Float( value.toJavaFloat() ); - } - public int score( LValue value ) { - if ( value instanceof LNumber ) - return 1; - if ( value instanceof LBoolean ) - return 2; - return 4; - } - }; - Coercion doubleCoercion = new Coercion() { - public Object coerce(LValue value) { - return new Double( value.toJavaDouble() ); - } - public int score(LValue value) { - if ( value instanceof LDouble ) - return 0; - if ( value instanceof LNumber ) - return 1; - if ( value instanceof LBoolean ) - return 2; - return 4; - } - }; - Coercion stringCoercion = new Coercion() { - public Object coerce(LValue value) { - return value.toJavaString(); - } - public int score(LValue value) { - if ( value instanceof LUserData ) - return 0; - return 1; - } - }; - Coercion objectCoercion = new Coercion() { - public Object coerce(LValue value) { - if ( value instanceof LUserData ) - return ((LUserData)value).m_instance; - if ( value instanceof LString ) - return value.toJavaString(); - if ( value instanceof LInteger ) - return new Integer(value.toJavaInt()); - if ( value instanceof LDouble ) - return new Double(value.toJavaDouble()); - if ( value instanceof LBoolean ) - return Boolean.valueOf(value.toJavaBoolean()); - if ( value.isNil() ) - return null; - return value; - } - public int score(LValue value) { - if ( value instanceof LString ) - return 0; - return 0x10; - } - }; - COERCIONS.put( Boolean.TYPE, boolCoercion ); - COERCIONS.put( Boolean.class, boolCoercion ); - COERCIONS.put( Byte.TYPE, byteCoercion ); - COERCIONS.put( Byte.class, byteCoercion ); - COERCIONS.put( Character.TYPE, charCoercion ); - COERCIONS.put( Character.class, charCoercion ); - COERCIONS.put( Short.TYPE, shortCoercion ); - COERCIONS.put( Short.class, shortCoercion ); - COERCIONS.put( Integer.TYPE, intCoercion ); - COERCIONS.put( Integer.class, intCoercion ); - COERCIONS.put( Long.TYPE, longCoercion ); - COERCIONS.put( Long.class, longCoercion ); - COERCIONS.put( Float.TYPE, floatCoercion ); - COERCIONS.put( Float.class, floatCoercion ); - COERCIONS.put( Double.TYPE, doubleCoercion ); - COERCIONS.put( Double.class, doubleCoercion ); - COERCIONS.put( String.class, stringCoercion ); - COERCIONS.put( Object.class, objectCoercion ); - } - - - /** Score a single parameter, including array handling */ - private static int scoreParam(LValue a, Class c) { - if ( a instanceof LUserData ) { - Object o = ((LUserData) a).m_instance; - if ( c.isAssignableFrom(o.getClass()) ) - return 0; - } - Coercion co = (Coercion) COERCIONS.get( c ); - if ( co != null ) { - return co.score( a ); - } - if ( c.isArray() ) { - Class typ = c.getComponentType(); - if ( a instanceof LTable ) { - return scoreParam( ((LTable)a).get(1), typ ); - } else { - return 0x10 + (scoreParam(a, typ) << 8); - } - } - return 0x1000; - } - - /** Do a conversion */ - public static Object coerceArg(LValue a, Class c) { - if ( a instanceof LUserData ) { - Object o = ((LUserData) a).m_instance; - if ( c.isAssignableFrom(o.getClass()) ) - return o; - } - Coercion co = (Coercion) COERCIONS.get( c ); - if ( co != null ) { - return co.coerce( a ); - } - if ( c.isArray() ) { - boolean istable = (a instanceof LTable); - int n = istable? a.luaLength(): 1; - Class typ = c.getComponentType(); - Object o = Array.newInstance(typ, n); - for ( int i=0; i nargs? 0x4000: 0x8000); - for ( int i=0; i= 0 && index < Array.getLength(instance) ) - vm.pushlvalue( CoerceJavaToLua.coerce( Array.get(instance, index) ) ); - else - vm.pushnil(); - return false; - } - } - final String s = key.toJavaString(); - vm.resettop(); - try { - Field f = clazz.getField(s); - Object o = f.get(instance); - vm.pushlvalue( CoerceJavaToLua.coerce( o ) ); - } catch (NoSuchFieldException nsfe) { - if ( clazz.isArray() && key.equals(LENGTH) ) { - vm.pushinteger( Array.getLength(instance) ); - } else { - vm.pushlvalue( new LMethod(clazz,s) ); - } - } catch (Exception e) { - throw new LuaErrorException(e); - } - return false; - } - }); - mt.put( LValue.TM_NEWINDEX, new LFunction() { - public boolean luaStackCall(LuaState vm) { - Object instance = vm.touserdata(2); - LValue key = vm.topointer(3); - LValue val = vm.topointer(4); - if ( key instanceof LInteger ) { - if ( clazz.isArray() ) { - vm.resettop(); - Object v = CoerceLuaToJava.coerceArg(val, clazz.getComponentType()); - int index = key.toJavaInt()-1; - if ( index >= 0 && index < Array.getLength(instance) ) - Array.set(instance, key.toJavaInt()-1, v); - else - throw new LuaErrorException("array bounds exceeded "+index); - vm.resettop(); - return false; - } - } - String s = key.toJavaString(); - try { - Field f = clazz.getField(s); - Object v = CoerceLuaToJava.coerceArg(val, f.getType()); - f.set(instance,v); - vm.resettop(); - } catch (Exception e) { - throw new LuaErrorException(e); - } - return false; - } - }); - classMetatables.put(clazz, mt); - } - return new LUserData(obj,mt); - } - - private static final class LMethod extends LFunction { - private final Class clazz; - private final String s; - private LMethod(Class clazz, String s) { - this.clazz = clazz; - this.s = s; - } - public String toString() { - return clazz.getName()+"."+s+"()"; - } - public boolean luaStackCall(LuaState vm) { - try { - // find the method - Object instance = vm.touserdata(2); - ParamsList params = new ParamsList( vm ); - Method meth = resolveMethod( clazz, s, params ); - - // coerce the arguments - Object[] args = CoerceLuaToJava.coerceArgs( params.values, meth.getParameterTypes() ); - Object result = meth.invoke( instance, args ); - - // coerce the result - vm.resettop(); - vm.pushlvalue( CoerceJavaToLua.coerce(result) ); - return false; - } catch (Exception e) { - throw new LuaErrorException(e); - } - } - } - - private static Map consCache = - new HashMap(); - - private static Map consIndex = - new HashMap(); - - private static Constructor resolveConstructor(Class clazz, ParamsList params ) { - - // get the cache - Map cache = (Map) consCache.get( clazz ); - if ( cache == null ) - consCache.put( clazz, cache = new HashMap() ); - - // look up in the cache - Constructor c = (Constructor) cache.get( params ); - if ( c != null ) - return c; - - // get index - Map index = (Map) consIndex.get( clazz ); - if ( index == null ) { - consIndex.put( clazz, index = new HashMap() ); - Constructor[] cons = clazz.getConstructors(); - for ( int i=0; i0? args[0]: "/swingapp.lua"); - System.out.println("loading '"+script+"'"); - - // load the file - InputStream is = LuajavaRunner.class.getResourceAsStream( script ); - LPrototype p = LoadState.undump(state, is, script); - - // create closure and execute - LClosure c = p.newClosure( state._G ); - state.doCall(c, new LValue[0]); - - } -} diff --git a/src/sample/org/luaj/sample/SampleClass.java b/src/sample/org/luaj/sample/SampleClass.java deleted file mode 100644 index 1771a67f..00000000 --- a/src/sample/org/luaj/sample/SampleClass.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.sample; - -public class SampleClass { - - public Object o; - public String s; - public String t; - - public SampleClass() { - } - - public SampleClass(String a, String b) { - s = a; - t = b; - } - - public String getS() { - return s; - } - - public void setS(String s) { - this.s = s; - } - - public void setObj(Object o) { - this.o = o; - } - - public Object getObj() { - return o; - } -} diff --git a/src/sample/org/luaj/sample/SampleJ2seMain.java b/src/sample/org/luaj/sample/SampleJ2seMain.java deleted file mode 100644 index a28b3f10..00000000 --- a/src/sample/org/luaj/sample/SampleJ2seMain.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.luaj.sample; -import org.luaj.platform.*; -import org.luaj.vm.*; - -public class SampleJ2seMain { - - public static void main(String[] args) { - String script = (args.length>0? args[0]: "src/test/res/swingapp.lua"); - Platform.setInstance( new J2sePlatform() ); - LuaState vm = Platform.newLuaState(); - // uncomment to install the debug library - // org.luaj.lib.DebugLib.install(vm); - org.luaj.compiler.LuaC.install(); - vm.getglobal( "dofile" ); - vm.pushstring( script ); - vm.call( 1, 0 ); - } -} diff --git a/src/sample/org/luaj/sample/SampleMIDlet.java b/src/sample/org/luaj/sample/SampleMIDlet.java deleted file mode 100644 index cee1ef5d..00000000 --- a/src/sample/org/luaj/sample/SampleMIDlet.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.luaj.sample; - -import javax.microedition.midlet.MIDlet; -import javax.microedition.midlet.MIDletStateChangeException; - -import org.luaj.lib.j2me.Cldc10IoLib; -import org.luaj.platform.J2meMidp20Cldc11Platform; -import org.luaj.vm.LuaState; -import org.luaj.vm.Platform; - -public class SampleMIDlet extends MIDlet { - - // the script will be loaded as a resource - private static final String DEFAULT_SCRIPT = "test1.lua"; - - protected void startApp() throws MIDletStateChangeException { - // get the script as an app property - String script = this.getAppProperty("script"); - if ( script == null ) - script = DEFAULT_SCRIPT; - - // set up the j2me platform. files will be loaded as resources - Platform.setInstance( new J2meMidp20Cldc11Platform(this) ); - LuaState vm = Platform.newLuaState(); - - // extend the basic vm to include the compiler and io packages - org.luaj.compiler.LuaC.install(); - Cldc10IoLib.install(vm._G); - - // run the script - vm.getglobal( "dofile" ); - vm.pushstring( script ); - vm.call( 1, 0 ); - } - - protected void destroyApp(boolean arg0) throws MIDletStateChangeException { - } - - protected void pauseApp() { - } - -} diff --git a/src/sample/org/luaj/sample/SampleUserdataMain.java b/src/sample/org/luaj/sample/SampleUserdataMain.java deleted file mode 100644 index 992b9b11..00000000 --- a/src/sample/org/luaj/sample/SampleUserdataMain.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.luaj.sample; -import org.luaj.lib.j2se.CoerceJavaToLua; -import org.luaj.platform.*; -import org.luaj.vm.*; - -/** - * Program that illustrates how userdata is mapped into lua using - * LuaJava's automated coercion - */ -public class SampleUserdataMain { - - public static class MyData { - public int x = 7; - public String y = "seven"; - public int xx[] = new int[] { 11, 22, 33, }; - public String yy[] = new String[] { "aa", "bb" }; - public int xxx[][] = new int[][] { {444, 555}, {666, 777} } ; - public String yyy[][] = new String[][] { { "ccc", "ddd" }, { "eee", "fff" } }; - public void initScalars( int newx, String newy ) { - x = newx; - y = newy; - } - public void initArrays( int[] newxx, String[] newyy ) { - xx = newxx; - yy = newyy; - } - public void initMatrices( int[][] newxxx, String[][] newyyy ) { - xxx = newxxx; - yyy = newyyy; - } - public int getx() { return x; } - public String gety() { return y; } - public int[] getxx() { return xx; } - public String[] getyy() { return yy; } - public int[][] getxxx() { return xxx; } - public String[][] getyyy() { return yyy; } - } - - public static void main(String[] args) { - Platform.setInstance( new J2sePlatform() ); - LuaState vm = Platform.newLuaState(); - org.luaj.compiler.LuaC.install(); - - // test script - vm.getglobal( "loadstring" ); - vm.pushstring( "local mydata = ...\n" + - "print( 'mydata', mydata )\n" + - "print( 'mydata.x, mydata.y', mydata.x, mydata.y )\n" + - "print( 'mydata:getx()', mydata:getx() )\n" + - "print( 'mydata:getxx()', mydata:getxx()[1], mydata:getxx()[2] )\n" + - "print( 'mydata:getxxx()', mydata:getxxx()[1][1], mydata:getxxx()[1][2] )\n" + - "print( 'mydata:getyyy()', mydata:getyyy()[1][1], mydata:getyyy()[1][2] )\n" + - "mydata:initScalars(3,'pqr')\n" + - "mydata:initArrays({55,66},{'abc','def'})\n" + - "mydata:initMatrices({{44,55},{66}},{{'qq','rr'},{'ss','tt'}})\n" + - "print( 'mydata:getx()', mydata:getx() )\n" + - "print( 'mydata:getxx()', mydata:getxx()[1], mydata:getxx()[2] )\n" + - "print( 'mydata:getxxx()', mydata:getxxx()[1][1], mydata:getxxx()[1][2] )\n" + - "print( 'mydata:getyyy()', mydata:getyyy()[1][1], mydata:getyyy()[1][2] )\n" + - ""); - vm.call( 1, 2 ); - System.out.println("load result: "+vm.tostring(-2)+", "+vm.tostring(-1)); - vm.settop(1); - - // load argument to test script - vm.pushlvalue( CoerceJavaToLua.coerce(new MyData()) ); - vm.call( 1, 0 ); - } -} diff --git a/src/script/META-INF/services/javax.script.ScriptEngineFactory b/src/script/META-INF/services/javax.script.ScriptEngineFactory deleted file mode 100644 index 9c755ea1..00000000 --- a/src/script/META-INF/services/javax.script.ScriptEngineFactory +++ /dev/null @@ -1 +0,0 @@ -org.luaj.script.LuaScriptEngineFactory \ No newline at end of file diff --git a/src/script/org/luaj/jit/JitPrototype.java b/src/script/org/luaj/jit/JitPrototype.java deleted file mode 100644 index 1acb5c38..00000000 --- a/src/script/org/luaj/jit/JitPrototype.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.luaj.jit; - -import org.luaj.vm.LClosure; -import org.luaj.vm.LNil; -import org.luaj.vm.LPrototype; -import org.luaj.vm.LTable; -import org.luaj.vm.LValue; -import org.luaj.vm.LuaState; - -abstract -public class JitPrototype extends LPrototype { - - protected LPrototype p; - - public JitPrototype() { - super(); - } - - protected void unimplemented() { - throw new RuntimeException("unimplemented"); - } - - protected void setLuaPrototype(LPrototype lp) { - this.p = lp; - } - - public LClosure newClosure(LTable env) { - return new JitClosure(this, env); - } - - protected static final class JitClosure extends LClosure { - private final JitPrototype jp; - public JitClosure(JitPrototype jitPrototype, LTable env) { - super( jitPrototype.p, env ); - this.jp = jitPrototype; - } - public boolean luaStackCall(LuaState vm) { - jp.jitCall(vm,env,this); - return false; - } - } - - public abstract void jitCall( LuaState vm, LTable env, JitClosure jcl ); - -} diff --git a/src/script/org/luaj/jit/LuaJit.java b/src/script/org/luaj/jit/LuaJit.java deleted file mode 100644 index 5542b786..00000000 --- a/src/script/org/luaj/jit/LuaJit.java +++ /dev/null @@ -1,718 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.jit; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintStream; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -import javax.tools.JavaCompiler; -import javax.tools.JavaFileObject; -import javax.tools.StandardJavaFileManager; -import javax.tools.StandardLocation; -import javax.tools.ToolProvider; -import javax.tools.JavaCompiler.CompilationTask; - -import org.luaj.compiler.LuaC; -import org.luaj.vm.LPrototype; -import org.luaj.vm.LValue; -import org.luaj.vm.LoadState; -import org.luaj.vm.Lua; -import org.luaj.vm.LuaState; -import org.luaj.vm.Print; -import org.luaj.vm.LoadState.LuaCompiler; - -public class LuaJit extends Lua implements LuaCompiler { - - private static LuaC luac; - - public static void install() { - luac = new LuaC(); - LoadState.compiler = new LuaJit(); - } - - private static int filenum = 0; - - private static synchronized String filename() { - return "LuaJit"+(filenum++); - } - - public LPrototype compile(int firstByte, InputStream stream, String name) throws IOException { - return jitCompile( luac.compile(firstByte, stream, name) ); - } - - public static LPrototype jitCompile( LPrototype p ) { - try { - final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - if (compiler == null) { - System.err.println("no java compiler"); - return p; - } - - // write the file - String name = filename(); - new File("jit").mkdirs(); - File source = new File("jit/"+name+JavaFileObject.Kind.SOURCE.extension); - PrintStream ps = new PrintStream(new FileOutputStream(source)); - writeSource(ps, name, p); - ps.close(); - - // set up output location - Iterable dest = Arrays.asList(new File[] { new File("bin") }); - StandardJavaFileManager fm = compiler.getStandardFileManager( null, null, null); - fm.setLocation(StandardLocation.CLASS_OUTPUT, dest); - - // compile the file - Iterable compilationUnits = fm.getJavaFileObjects(source); - CompilationTask task = compiler.getTask(null, fm, null, null, null, compilationUnits); - boolean success = task.call(); - - // instantiate, config and return - if (success) { - // compile sub-prototypes - if ( p.p != null ) { - for ( int i=0, n=p.p.length; i TESTS = new HashSet(); - static { - TESTS.add( OP_TEST ); - TESTS.add( OP_EQ ); - TESTS.add( OP_LT ); - TESTS.add( OP_LE ); - TESTS.add( OP_TESTSET ); - } - - private static boolean istest(int instr) { - int opcode = Lua.GET_OPCODE(instr); - return TESTS.contains(opcode); - } - - private static boolean isjump(int instr) { - if ( OP_JMP != Lua.GET_OPCODE(instr) ) - return false; - return true; - } - - private static boolean isbackwardjump(int instr) { - return isjump(instr) && (LuaState.GETARG_sBx(instr) < 0); - } - - private static boolean isforwardjump(int instr) { - return isjump(instr) && (LuaState.GETARG_sBx(instr) > 0); - } - - private static boolean isloopbottom(int instr) { - return isbackwardjump(instr) || OP_FORLOOP == Lua.GET_OPCODE(instr); - } - - private static String append( String s, String t ) { - return (s==null? t: t==null? s: s+t); - } - - private static void assertTrue(boolean b) { - if ( ! b ) - throw new RuntimeException("assert failed"); - } - - private static String[] extractControlFlow( int[] code ) { - int n = code.length; - String[] s = new String[n]; - - for ( int pc=0; pc 0 ) { - ps.print( "\tprivate LValue k0" ) ; - for (int ik=1; ik> POS_OP) & MAX_OP; - a = (i >> POS_A) & MAXARG_A; - - switch (o) { - default: - ps.println( "\t\tunimplemented();"); - break; - case LuaState.OP_MOVE: { - b = LuaState.GETARG_B(i); - ps.println( "\t\ts"+a+" = s"+b+";" ); - continue; - } - case LuaState.OP_LOADK: { - b = LuaState.GETARG_Bx(i); - ps.println( "\t\ts"+a+" = k"+b+";" ); - continue; - } - case LuaState.OP_LOADBOOL: { -// b = LuaState.GETARG_B(i); -// c = LuaState.GETARG_C(i); -// this.stack[base + a] = (b != 0 ? LBoolean.TRUE : LBoolean.FALSE); -// if (c != 0) -// ci.pc++; // skip next instruction (if C) -// continue; - b = LuaState.GETARG_B(i); - c = LuaState.GETARG_C(i); - ps.println( "\t\ts"+a+" = LBoolean."+(b!=0? "TRUE": "FALSE")+";" ); - if ( c != 0 ) - throw new java.lang.UnsupportedOperationException("can't jit compile LOADBOOL with c != 0"); - break; - } - case LuaState.OP_LOADNIL: { - b = LuaState.GETARG_B(i); - ps.print("\t\t"); - for ( int j=a; j<=b; j++ ) - ps.print("s"+j+"="); - ps.println("LNil.NIL;"); - break; - } - case LuaState.OP_GETUPVAL: { - //b = LuaState.GETARG_B(i); - //this.stack[base + a] = cl.upVals[b].getValue(); - //continue; - b = LuaState.GETARG_B(i); - ps.println("\t\t\ts"+a+" = jcl.upVals["+b+"].getValue();"); - break; - } - case LuaState.OP_GETGLOBAL: { - b = LuaState.GETARG_Bx(i); - ps.println("\t\ts"+a+" = vm.luaV_gettable(env, k"+b+");"); - break; - } - case LuaState.OP_GETTABLE: { - b = GETARG_B(i); - cs = GETARG_RKC_jit(i); - ps.println("\t\ts"+a+" = vm.luaV_gettable(s"+b+", "+cs+");"); - break; - } - case LuaState.OP_SETGLOBAL: { - b = LuaState.GETARG_Bx(i); - ps.println("\t\tvm.luaV_settable(env, k"+b+", s"+a+");"); - break; - } - case LuaState.OP_SETUPVAL: { - b = LuaState.GETARG_B(i); - ps.println("\t\t\tjcl.upVals["+b+"].setValue(s"+a+");"); - break; - } - case LuaState.OP_SETTABLE: { - bs = GETARG_RKB_jit(i); - cs = GETARG_RKC_jit(i); - ps.println("\t\tvm.luaV_settable(s"+a+", "+bs+", "+cs+");"); - break; - } - case LuaState.OP_NEWTABLE: { - b = GETARG_B(i); - c = GETARG_C(i); - ps.println("\t\ts"+a+" = new LTable("+b+","+c+");"); - break; - } - case LuaState.OP_SELF: { - bs = GETARG_RKB_jit(i); - cs = GETARG_RKC_jit(i); - ps.println("\t\ts"+a+" = vm.luaV_gettable((s"+(a+1)+"="+bs+"), "+cs+");"); - break; - } - case LuaState.OP_ADD: - case LuaState.OP_SUB: - case LuaState.OP_MUL: - case LuaState.OP_DIV: - case LuaState.OP_MOD: - case LuaState.OP_POW: { - bs = GETARG_RKB_jit(i); - cs = GETARG_RKC_jit(i); - ps.println("\t\ts"+a+" = "+cs+".luaBinOpUnknown("+o+","+bs+");"); - break; - } - case LuaState.OP_UNM: { - bs = GETARG_RKB_jit(i); - ps.println("\t\ts"+a+" = "+bs+".luaUnaryMinus();"); - } - case LuaState.OP_NOT: { - bs = GETARG_RKB_jit(i); - ps.println("\t\ts"+a+" = ("+bs+".toJavaBoolean()? LBoolean.TRUE: LBoolean.FALSE);"); - break; - } - case LuaState.OP_LEN: { - bs = GETARG_RKB_jit(i); - ps.println("\t\ts"+a+" = LInteger.valueOf("+bs+".luaLength());"); - } - case LuaState.OP_CONCAT: { - b = LuaState.GETARG_B(i); - c = LuaState.GETARG_C(i); - ps.println("\t\tbaos = new ByteArrayOutputStream();"); - for (int j = b; j <= c; j++) - ps.println("\t\ts"+j+".luaConcatTo( baos );"); - ps.println("\t\ts"+a+" = new LString( baos.toByteArray() );"); - ps.println("\t\tbaos = null;"); - break; - } - case LuaState.OP_JMP: { - break; - } - case LuaState.OP_EQ: - case LuaState.OP_LT: - case LuaState.OP_LE: { - bs = GETARG_RKB_jit(i); - cs = GETARG_RKC_jit(i); - ps.println( "\t\tif ( "+(a==0?"!":"")+" "+cs+".luaBinCmpUnknown("+o+", "+bs+") )" ); - break; - } - case LuaState.OP_TEST: { - c = LuaState.GETARG_C(i); - ps.println( "\t\tif ( "+(c!=0?"!":"")+" s"+a+".toJavaBoolean() )" ); - break; - } - case LuaState.OP_TESTSET: { -// rkb = GETARG_RKB(k, i); -// c = LuaState.GETARG_C(i); -// if (rkb.toJavaBoolean() != (c != 0)) -// ci.pc++; -// else -// this.stack[base + a] = rkb; -// continue; - bs = GETARG_RKB_jit(i); - c = LuaState.GETARG_C(i); - ps.println( "\t\tif ( "+(c!=0?"!":"")+" "+bs+".toJavaBoolean() )" ); - ps.println( "\t\t\ts"+a+" = "+bs+";" ); - ps.println( "\t\telse" ); - break; - } - case LuaState.OP_CALL: { - // - //// ra is base of new call frame - //this.base += a; - // - //// number of args - //b = LuaState.GETARG_B(i); - //if (b != 0) // else use previous instruction set top - // top = base + b; - // - //// number of return values we need - //c = LuaState.GETARG_C(i); - // - //// make or set up the call - //this.nresults = c - 1; - //if (this.stack[base].luaStackCall(this)) - // return; - // - //// adjustTop only for case when call was completed - //// and number of args > 0. If call completed but - //// c == 0, leave top to point to end of results - //if (c > 0) - // adjustTop(base + c - 1); - // - //// restore base - //base = ci.base; - // - //continue; - - b = LuaState.GETARG_B(i); - c = LuaState.GETARG_C(i); - - // copy call to vm stack - ps.println( "\t\tvm.stack[base+"+a+"] = s"+a+";" ); - - // number of args - if (b > 0) { // else use previous instruction set top - for ( int j=1; j 0 ) - for ( int j=0; j 0. If call completed but - // c == 0, leave top to point to end of results - if (this.nresults >= 0) - adjustTop(base + nresults); - - // force restore of base, etc. - return; - } - */ - case LuaState.OP_RETURN: { - //// number of return vals to return - //b = LuaState.GETARG_B(i) - 1; - //if (b == -1) - // b = top - (base + a); - // - //// close open upvals - //closeUpVals( base ); - // - //// number to copy down - //System.arraycopy(stack, base + a, stack, ci.resultbase, b); - //top = ci.resultbase + b; - // - //// adjust results to what caller expected - //if (ci.nresults >= 0) - // adjustTop(ci.resultbase + ci.nresults); - // - //// pop the call stack - //--cc; - // - //// force a reload of the calling context - //return; - // number of return vals to return - if ( Lua.GET_OPCODE(code[pc-1]) == Lua.OP_RETURN ) - break; - - if ( p.is_vararg != 0 ) - ps.println( "\t\tbase -= nvarargs;" ); - else - ps.println( "\t\tbase -= 1;" ); - - b = LuaState.GETARG_B(i); - if (b > 0) { - for ( int j=1; j toMerge) { - for ( Iterator it=toMerge.entrySet().iterator(); it.hasNext(); ) { - Map.Entry e = (Map.Entry) it.next(); - put( e.getKey(), e.getValue() ); - } - } - public Object remove(Object javakey) { - LValue key = toLua(javakey); - Object result = toJava(env.get(key)); - env.put(key, LNil.NIL); - return result; - } - public boolean containsValue(Object value) { - throw new java.lang.UnsupportedOperationException( - "containsValue() not supported for LuaBindings"); - } - public Set> entrySet() { - throw new java.lang.UnsupportedOperationException( - "entrySet() not supported for LuaBindings"); - } - public boolean isEmpty() { - throw new java.lang.UnsupportedOperationException( - "isEmpty() not supported for LuaBindings"); - } - public Set keySet() { - throw new java.lang.UnsupportedOperationException( - "keySet() not supported for LuaBindings"); - } - public int size() { - throw new java.lang.UnsupportedOperationException( - "size() not supported for LuaBindings"); - } - public Collection values() { - throw new java.lang.UnsupportedOperationException( - "values() not supported for LuaBindings"); - } - } - - // ------ convert char stream to byte stream for lua compiler ----- - - private final class Utf8Encoder extends InputStream { - private final Reader r; - private final int[] buf = new int[2]; - private int n; - - private Utf8Encoder(Reader r) { - this.r = r; - } - - public int read() throws IOException { - if ( n > 0 ) - return buf[--n]; - int c = r.read(); - if ( c < 0x80 ) - return c; - n = 0; - if ( c < 0x800 ) { - buf[n++] = (0x80 | ( c & 0x3f)); - return (0xC0 | ((c>>6) & 0x1f)); - } else { - buf[n++] = (0x80 | ( c & 0x3f)); - buf[n++] = (0x80 | ((c>>6) & 0x3f)); - return (0xE0 | ((c>>12) & 0x0f)); - } - } - } -} diff --git a/src/script/org/luaj/script/LuaScriptEngineFactory.java b/src/script/org/luaj/script/LuaScriptEngineFactory.java deleted file mode 100644 index edda67e7..00000000 --- a/src/script/org/luaj/script/LuaScriptEngineFactory.java +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2008 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.script; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import javax.script.ScriptEngine; -import javax.script.ScriptEngineFactory; - -/** - * - * @author jim_roseborough - */ -public class LuaScriptEngineFactory implements ScriptEngineFactory { - - private static final String FILEEXT = ".lua"; - - private static final String [] MIMETYPES = { - "text/plain", - "text/lua", - "application/lua" - }; - - private static final String [] NAMES = { - "lua", - "luaj", - }; - - private ScriptEngine myScriptEngine; - private List extensions; - private List mimeTypes; - private List names; - - public LuaScriptEngineFactory() { - myScriptEngine = new LuaScriptEngine(); - extensions = Collections.nCopies(1, FILEEXT); - mimeTypes = Arrays.asList(MIMETYPES); - names = Arrays.asList(NAMES); - } - - public String getEngineName() { - return getScriptEngine().get(ScriptEngine.ENGINE).toString(); - } - - public String getEngineVersion() { - return getScriptEngine().get(ScriptEngine.ENGINE_VERSION).toString(); - } - - public List getExtensions() { - return extensions; - } - - public List getMimeTypes() { - return mimeTypes; - } - - public List getNames() { - return names; - } - - public String getLanguageName() { - return getScriptEngine().get(ScriptEngine.LANGUAGE).toString(); - } - - public String getLanguageVersion() { - return getScriptEngine().get(ScriptEngine.LANGUAGE_VERSION).toString(); - } - - public Object getParameter(String key) { - return getScriptEngine().get(key).toString(); - } - - public String getMethodCallSyntax(String obj, String m, String... args) { - StringBuffer sb = new StringBuffer(); - sb.append(obj + ":" + m + "("); - int len = args.length; - for (int i = 0; i < len; i++) { - if (i > 0) { - sb.append(','); - } - sb.append(args[i]); - } - sb.append(")"); - return sb.toString(); - } - - public String getOutputStatement(String toDisplay) { - return "print(" + toDisplay + ")"; - } - - public String getProgram(String ... statements) { - StringBuffer sb = new StringBuffer(); - int len = statements.length; - for (int i = 0; i < len; i++) { - if (i > 0) { - sb.append('\n'); - } - sb.append(statements[i]); - } - return sb.toString(); - } - - public ScriptEngine getScriptEngine() { - return myScriptEngine; - } -} diff --git a/src/script/org/luaj/script/ScriptEngineSample.java b/src/script/org/luaj/script/ScriptEngineSample.java deleted file mode 100644 index b3de44a1..00000000 --- a/src/script/org/luaj/script/ScriptEngineSample.java +++ /dev/null @@ -1,67 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2008 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.script; - -import javax.script.Bindings; -import javax.script.Compilable; -import javax.script.CompiledScript; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineFactory; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; - -public class ScriptEngineSample { - - public static void main(String [] args) { - ScriptEngineManager sem = new ScriptEngineManager(); - ScriptEngine e = sem.getEngineByExtension(".lua"); - ScriptEngineFactory f = e.getFactory(); - System.out.println( "Engine name: " +f.getEngineName() ); - System.out.println( "Engine Version: " +f.getEngineVersion() ); - System.out.println( "LanguageName: " +f.getLanguageName() ); - System.out.println( "Language Version: " +f.getLanguageVersion() ); - String statement = f.getOutputStatement("\"hello, world\""); - System.out.println(statement); - try { - e.eval(statement); - - e.put("x", 25); - e.eval("y = math.sqrt(x)"); - System.out.println( "y="+e.get("y") ); - - e.put("x", 2); - e.eval("y = math.sqrt(x)"); - System.out.println( "y="+e.get("y") ); - - CompiledScript cs = ((Compilable)e).compile("y = math.sqrt(x); return y"); - Bindings b = e.createBindings(); - b.put("x", 3); - System.out.println( "eval: "+cs.eval(b) ); - System.out.println( "y="+b.get("y") ); - - e.eval("\n\nbogus example\n\n"); - } catch (ScriptException ex) { - ex.printStackTrace(); - } - } - -} diff --git a/src/test/java/org/luaj/jit/LuaJitBasicTest.java b/src/test/java/org/luaj/jit/LuaJitBasicTest.java deleted file mode 100644 index 2b72dbdb..00000000 --- a/src/test/java/org/luaj/jit/LuaJitBasicTest.java +++ /dev/null @@ -1,154 +0,0 @@ -package org.luaj.jit; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; - -import junit.framework.TestCase; - -import org.luaj.compiler.LuaC; -import org.luaj.lib.BaseLib; -import org.luaj.platform.J2sePlatform; -import org.luaj.vm.LClosure; -import org.luaj.vm.LPrototype; -import org.luaj.vm.LuaState; -import org.luaj.vm.Platform; - -/** - * Simple test cases for lua jit basic functional test - */ -public class LuaJitBasicTest extends TestCase { - - static { - Platform.setInstance(new J2sePlatform()); - LuaC.install(); - } - - public void testPrintHelloWorld() throws IOException { - stringTest( "print( 'hello, world' )" ); - } - - public void testArgPassing() throws IOException { - stringTest( - "local function f(a,b)\n" + - " print('a',a,'b',b)\n" + - " return 'c','d'\n" + - "end\n" + - "print( 'f1', f(123) )\n" + - "print( 'f2', f(456,789) )\n" + - "print( 'f3', f(12,34,56) )\n" ); - } - - public void testForInDoEnd() throws IOException { - stringTest( - "local t = {abc=123,def=456}\n" + - "for k,v in pairs(t) do\n" + - " print( 'k,v', k, v )\n" + - "end"); - } - - public void testForIEqualsDoEnd() throws IOException { - stringTest( - "print 'starting'\n" + - "for i=1,5,2 do\n" + - " print( 'i', i )\n" + - "end"); - } - - public void testRepeatUntil() throws IOException { - stringTest( - "local i=7\n" + - "repeat\n"+ - " print(i)\n"+ - "until i\n"); - } - - public void testWhileDoEnd() throws IOException { - stringTest( - "local i=4\n" + - "while i>0 do\n"+ - " print( i )\n"+ - " i = i-1\n"+ - "end\n"); - } - - public void testForIEqualsDoBreakEnd() throws IOException { - stringTest( - "print 'starting'\n" + - "for i=1,5,2 do\n" + - " print( 'i', i )\n" + - " break\n" + - "end"); - } - - public void testRepeatUntilBreak() throws IOException { - stringTest( - "local i=7\n" + - "repeat\n"+ - " print(i)\n"+ - " break\n"+ - "until i\n"); - } - - public void testWhileDoBreak() throws IOException { - stringTest( - "local i=4\n" + - "while i>0 do\n"+ - " print( i )\n"+ - " i = i-1\n"+ - " break\n"+ - "end\n"); - } - - public void testIfThenEnd() throws IOException { - stringTest( - "if a then\n" + - " print(1)\n" + - "end\n" + - "print(2)\n" ); - } - - public void testIfThenElseEnd() throws IOException { - stringTest( - "if a then\n" + - " print(1)\n" + - "else\n" + - " print(2)\n" + - "end\n" + - "print(3)\n" ); - } - - public void testIfThenElseifElseEnd() throws IOException { - stringTest( - "if a then\n" + - " print(1)\n" + - "elseif b then \n" + - " print(2)\n" + - "else\n" + - " print(3)\n" + - "end\n" + - "print(4)\n" ); - } - - private void stringTest(String program) throws IOException { - InputStream is = new ByteArrayInputStream(program.getBytes()); - LPrototype p = LuaC.compile(is, "program"); - String expected = run( p ); - LPrototype q = LuaJit.jitCompile( p ); - assertTrue(p!=q); - String actual = run( q ); - assertEquals( expected, actual ); - } - - private static String run(LPrototype p) { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - BaseLib.redirectOutput(outputStream); - LuaState vm = Platform.newLuaState(); - LClosure c = p.newClosure(vm._G); - vm.pushlvalue(c); - vm.call(0, 0); - return outputStream.toString(); - } - -} diff --git a/src/test/java/org/luaj/jit/LuaJitPerfTest.java b/src/test/java/org/luaj/jit/LuaJitPerfTest.java deleted file mode 100644 index 5df2faf8..00000000 --- a/src/test/java/org/luaj/jit/LuaJitPerfTest.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.luaj.jit; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -import junit.framework.TestCase; - -import org.luaj.compiler.LuaC; -import org.luaj.lib.BaseLib; -import org.luaj.platform.J2sePlatform; -import org.luaj.vm.LClosure; -import org.luaj.vm.LPrototype; -import org.luaj.vm.LuaState; -import org.luaj.vm.Platform; - -public class LuaJitPerfTest extends TestCase { - - static { - Platform.setInstance(new J2sePlatform()); - LuaC.install(); - } -// -// public void testFannkuch() throws IOException { -// timedFileTest( "fannkuch.lua" ); -// } -// -// public void testMandelbrot() throws IOException { -// timedFileTest( "mandelbrot.lua" ); -// } - - public void testNbody() throws IOException { - timedFileTest( "nbody.lua" ); - } -// -// public void testForLoop() throws IOException { -// timedTest( "for loop", -// "local sum=0\n" + -// "for i=1,10000,1 do\n" + -// " sum = sum + i\n" + -// "end"); -// } -// - - private void timedFileTest(String filename) throws IOException { - File file = new File("src/test/perf/"+filename); - int len = (int) file.length(); - byte[] b = new byte[len]; - DataInputStream dis = new DataInputStream( new FileInputStream( file ) ); - dis.readFully(b); - dis.close(); - timedTest( filename, new String(b) ); - - } - - private void timedTest(String testName, String script) throws IOException { - System.out.println("---- "+testName+" ----"); - InputStream is = new ByteArrayInputStream(script.getBytes()); - LPrototype p = LuaC.compile(is, "script"); - int plain = timeTrial( "plain", p ); - LPrototype q = LuaJit.jitCompile( p ); - assertTrue(p!=q); - int jit = timeTrial( "jit", q ); - System.out.println("plain="+plain+" jit="+jit+" ratio="+(double)jit/(double)plain); - assertTrue( "jit faster than plain", jit > plain ); - } - - private static int timeTrial(String type, LPrototype p) { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - BaseLib.redirectOutput(outputStream); - LuaState vm = Platform.newLuaState(); - LClosure c = p.newClosure(vm._G); - int globalCount = 0; - for ( int i=0; i<5; i++ ) { - int localCount = 0; - long t1 = System.currentTimeMillis() + 1000; - while ( t1 > System.currentTimeMillis() ) { - vm.pushlvalue(c); - vm.call(0, 0); - localCount++; - } - System.out.println(type+": "+(localCount)); - System.out.flush(); - globalCount += localCount; - } - return globalCount; - } -} diff --git a/src/test/java/org/luaj/jit/LuaJitTest.java b/src/test/java/org/luaj/jit/LuaJitTest.java deleted file mode 100644 index 9fbd1915..00000000 --- a/src/test/java/org/luaj/jit/LuaJitTest.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.luaj.jit; - -import java.io.IOException; - -import org.luaj.jit.LuaJit; -import org.luaj.vm.LPrototype; -import org.luaj.vm.CompatibiltyTest; -import org.luaj.vm.LuaState; - -/** - * Suite of standard tests, but using the LuaJit compiler - * for all loaded prototypes. - */ -public class LuaJitTest extends CompatibiltyTest { - - protected LPrototype loadScript( LuaState state, String name ) throws IOException { - LPrototype p = super.loadScript(state, name); - return LuaJit.jitCompile(p); - } - -} diff --git a/src/test/res/autoload.lua b/src/test/res/autoload.lua deleted file mode 100644 index 341c939a..00000000 --- a/src/test/res/autoload.lua +++ /dev/null @@ -1,15 +0,0 @@ --- Clear out builtin math package -math = nil - -local function autoload(table, key) - local pkg = require(key) - table[key] = pkg - return pkg -end - -setmetatable(_G, { __index = autoload } ) - --- local result = math.sqrt(9.0) --- print("x=", result) -print("square root of 9.0 is ", math.sqrt(9.0)) -print("square root of 4.0 is ", math.sqrt(4.0)) diff --git a/src/test/res/baselib.lua b/src/test/res/baselib.lua deleted file mode 100644 index f68e572b..00000000 --- a/src/test/res/baselib.lua +++ /dev/null @@ -1,280 +0,0 @@ --- unit tests for functions in BaseLib.java -package.path = "?.lua;src/test/res/?.lua" -require 'ids' - --- 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") - --- 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 --- loadfile --- loadstring -local lst = "print(3+4); return 8" -local chunk, err = loadstring( lst ) -print( 'loadstring("'..lst..'")', id(chunk), err ) -print( 'loadstring("'..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',bb='bbb'}) do print('pairs3',k,v)end -for k,v in pairs({aa='aaa',bb='bbb','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() ) - --- getfenv, setfenv: tested in setfenv.lua --- 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")', id(rawset(s,"aa","www"))) -printtables() -print( 'pcall(rawset,s,"cc","xxx")', id(rawset(s,"cc","xxx"))) -printtables() -print( 'pcall(rawset,t,"bb","yyy")', id(rawset(t,"aa","yyy"))) -printtables() -print( 'pcall(rawset,t,"dd","zzz")', id(rawset(s,"dd","zzz"))) -printtables() - -printtables() -print( 's["ee"]="ppp"' ); s["ee"]="ppp" -printtables() -print( 's["cc"]="qqq"' ); s["cc"]="qqq" -printtables() -print( 's["bb"]="rrr"' ); t["bb"]="rrr" -printtables() -print( 's["dd"]="sss"' ); t["dd"]="sss" -printtables() -print( 's["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"})) ) - --- unpack -print( 'pcall(unpack)', pcall(unpack) ); -print( 'pcall(unpack,nil)', pcall(unpack,nil) ); -print( 'pcall(unpack,"abc")', pcall(unpack,"abc") ); -print( 'pcall(unpack,1)', pcall(unpack,1) ); -print( 'unpack({"aa"})', unpack({"aa"}) ); -print( 'unpack({"aa","bb"})', unpack({"aa","bb"}) ); -print( 'unpack({"aa","bb","cc"})', unpack({"aa","bb","cc"}) ); -local t = {"aa","bb","cc","dd","ee","ff"} -print( 'pcall(unpack,t)', pcall(unpack,t) ); -print( 'pcall(unpack,t,2)', pcall(unpack,t,2) ); -print( 'pcall(unpack,t,2,5)', pcall(unpack,t,2,5) ); -print( 'pcall(unpack,t,2,6)', pcall(unpack,t,2,6) ); -print( 'pcall(unpack,t,2,7)', pcall(unpack,t,2,7) ); -print( 'pcall(unpack,t,1)', pcall(unpack,t,1) ); -print( 'pcall(unpack,t,1,5)', pcall(unpack,t,1,5) ); -print( 'pcall(unpack,t,1,6)', pcall(unpack,t,1,6) ); -print( 'pcall(unpack,t,1,7)', pcall(unpack,t,1,7) ); -print( 'pcall(unpack,t,0)', pcall(unpack,t,0) ); -print( 'pcall(unpack,t,0,5)', pcall(unpack,t,0,5) ); -print( 'pcall(unpack,t,0,6)', pcall(unpack,t,0,6) ); -print( 'pcall(unpack,t,0,7)', pcall(unpack,t,0,7) ); -print( 'pcall(unpack,t,-1)', pcall(unpack,t,-1) ); -print( 'pcall(unpack,t,-1,5)', pcall(unpack,t,-1,5) ); -print( 'pcall(unpack,t,-1,6)', pcall(unpack,t,-1,6) ); -print( 'pcall(unpack,t,-1,7)', pcall(unpack,t,-1,7) ); -print( 'pcall(unpack,t,2,4)', pcall(unpack,t,2,4) ); -print( 'pcall(unpack,t,2,5)', pcall(unpack,t,2,5) ); -print( 'pcall(unpack,t,2,6)', pcall(unpack,t,2,6) ); -print( 'pcall(unpack,t,2,7)', pcall(unpack,t,2,7) ); -print( 'pcall(unpack,t,2,8)', pcall(unpack,t,2,8) ); -print( 'pcall(unpack,t,2,2)', pcall(unpack,t,2,0) ); -print( 'pcall(unpack,t,2,1)', pcall(unpack,t,2,0) ); -print( 'pcall(unpack,t,2,0)', pcall(unpack,t,2,0) ); -print( 'pcall(unpack,t,2,-1)', pcall(unpack,t,2,-1) ); -t[0] = 'zz' -t[-1] = 'yy' -t[-2] = 'xx' -print( 'pcall(unpack,t,0)', pcall(unpack,t,0) ); -print( 'pcall(unpack,t,2,0)', pcall(unpack,t,2,0) ); -print( 'pcall(unpack,t,2,-1)', pcall(unpack,t,2,-1) ); -print( 'pcall(unpack,t,"3")', pcall(unpack,t,"3") ); -print( 'pcall(unpack,t,"a")', pcall(unpack,t,"a") ); -print( 'pcall(unpack,t,function() end)', pcall(unpack,t,function() end) ); - --- _VERSION -print( '_VERSION', type(_VERSION) ) diff --git a/src/test/res/boolean.lua b/src/test/res/boolean.lua deleted file mode 100644 index 5209a69d..00000000 --- a/src/test/res/boolean.lua +++ /dev/null @@ -1,31 +0,0 @@ -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) diff --git a/src/test/res/calls.lua b/src/test/res/calls.lua deleted file mode 100644 index a7a988de..00000000 --- a/src/test/res/calls.lua +++ /dev/null @@ -1,28 +0,0 @@ -local function f(x) - -- tailcall to a builtin - return math.sin(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 function truncate(x) - local s = tostring(x) - return (#s<6 and s) or string.sub(s,1,6)..'...' -end -local result2 = f(math.pi) -print(truncate(result2)) -print(truncate(f(math.pi))) diff --git a/src/test/res/coercions.lua b/src/test/res/coercions.lua deleted file mode 100644 index 9db03f32..00000000 --- a/src/test/res/coercions.lua +++ /dev/null @@ -1,5 +0,0 @@ -print("5.0"+3.1) -print(4+"7.5") -print(3.14*" 2.75") -print("-33"/"11") -print(-"-5") diff --git a/src/test/res/compare.lua b/src/test/res/compare.lua deleted file mode 100644 index 6840009b..00000000 --- a/src/test/res/compare.lua +++ /dev/null @@ -1,12 +0,0 @@ -if 2 < 5 then - print("OK!") -else - print("Something is not right") -end - -print(2 < 5) -print(2 <= 5) -print(2 == 5) -print(2 ~= 5) -print(2 > 5) -print(2 >= 5) diff --git a/src/test/res/compile.sh b/src/test/res/compile.sh deleted file mode 100644 index eb930f15..00000000 --- a/src/test/res/compile.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -TESTS=`echo *.lua` -for x in $TESTS -do - echo compiling $x - luac -l -o ${x}c ${x} - lua ${x}c -done diff --git a/src/test/res/coroutines.lua b/src/test/res/coroutines.lua deleted file mode 100644 index 7b92dfca..00000000 --- a/src/test/res/coroutines.lua +++ /dev/null @@ -1,97 +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(...) - echo('(echocr) first args', unpack(arg,1,arg.n)) - local a = arg - while true do - a = { echo( '(echoch) yield returns', coroutine.yield( 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) diff --git a/src/test/res/debuglib.lua b/src/test/res/debuglib.lua deleted file mode 100644 index a3e52a77..00000000 --- a/src/test/res/debuglib.lua +++ /dev/null @@ -1,227 +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.getfenv, debug.setfenv' ) -f = function(a) - return 'f:'..tostring(a)..'|'..tostring(b) -end -s,e,g = pcall( debug.getfenv, f ) -print( s, type(e), type(g), (e==G), pcall( f, 'abc' ) ) -s,e,g = pcall( debug.setfenv, f, {b='def'} ) -print( s, type(e), type(g), (e==G), pcall( f, 'abc' ) ) -s,e,g = pcall( debug.getfenv, f ) -print( s, type(e), type(g), (e==G), pcall( f, 'abc' ) ) - - -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 -do lvl=1,1 - for lcl=3,7 do - print( pcall( f, lvl, lcl, '#' ) ) - end -end -do lvl=2,3 - for lcl=0,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 ) -local s4,x4,y4 = pcall( debug.getmetatable, b ) -local s5,x5,y5 = pcall( debug.setmetatable, a, nil ) -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 ) -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(arg) 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, "" ) ) - --[[ - for i=1,3 do - printinfo( 'debug.traceback("msg")', debug.traceback('msg') ) - printinfo( 'debug.traceback("another",'..i..')', debug.traceback('another',i) ) - end - --]] - 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', ... ) -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") ---]] - - \ No newline at end of file diff --git a/src/test/res/errors.lua b/src/test/res/errors.lua deleted file mode 100644 index 05092851..00000000 --- a/src/test/res/errors.lua +++ /dev/null @@ -1,121 +0,0 @@ --- object ids -package.path = "?.lua;src/test/res/?.lua" -require 'ids' - --- 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 -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,'-') end )) -end --- concatsuite(strconcat) -concatsuite(tblconcat) - --- pairs -print( 'a(pairs(nil))', a(function() return id(pairs(nil,{})) end) ) -print( 'a(pairs(a)) ', a(function() return id(pairs(a,{})) end) ) -print( 'a(pairs(s)) ', a(function() return id(pairs(s,{})) end) ) -print( 'a(pairs(t)) ', a(function() return id(pairs(t,{})) end) ) -print( 'a(pairs(true))', a(function() local b = true; return id(pairs(b,{})) end) ) - --- setmetatable -function sm(...) - return id(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(setmetatable(t*)) ', a(function() return sm(t,{__metatable={}}) end) ) -print( 'a(setmetatable(t)) ', a(function() return sm(t,{}) end) ) -t = {} -print( 'a(setmetatable(t)) ', a(function() return sm(t,{}) end) ) -print( 'a(setmetatable(t*)) ', a(function() return sm(t,{__metatable='some string'}) end) ) -print( 'a(setmetatable(t)) ', a(function() return sm(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/src/test/res/hugetable.lua b/src/test/res/hugetable.lua deleted file mode 100644 index 566e03cb..00000000 --- a/src/test/res/hugetable.lua +++ /dev/null @@ -1,43 +0,0 @@ --- test tables with more than 50 elements - -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 diff --git a/src/test/res/ids.lua b/src/test/res/ids.lua deleted file mode 100644 index a1ca7283..00000000 --- a/src/test/res/ids.lua +++ /dev/null @@ -1,36 +0,0 @@ --- utility to give tables and functions uniform ids for testing -ids = {} - --- return unique id for the value, independent of object id -function id(obj) - if not obj or type(obj) == 'number' or type(obj) == 'string' or type(obj) == 'boolean' then - return obj - end - local v = ids[obj] - if v then - return v - end - table.insert(ids,obj) - ids[obj] = type(obj)..'.'..tostring(#ids) - return ids[obj] -end - --- return key-value pairs sorted by keys -function spairs(unsorted) - local keys = {} - for k,v in pairs(unsorted) do - table.insert(keys,k) - end - table.sort(keys) - local lookup = {} - for i,k in ipairs(keys) do - lookup[k] = i; - end - local iterator = function(tbl,key) - local i = lookup[key] - local j,k = next(keys,i) - if not j then return nil end - return k,unsorted[k] - end - return iterator, table, nil -end \ No newline at end of file diff --git a/src/test/res/iolib.lua b/src/test/res/iolib.lua deleted file mode 100644 index 5a309beb..00000000 --- a/src/test/res/iolib.lua +++ /dev/null @@ -1,115 +0,0 @@ --- simple io-library tests -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.\n") ) -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\r\n\t 678910 more\naaaaaa\rbbb\nthe 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)) -end - -local h,s = io.open("abc.txt", "a") -print( 'h', io.type(h), s ) -print( 'write', h:write('\nmore text\neven more text\n') ) -print( 'close', h:close() ) - -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))) ) - -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:write", a:read(7) ) -print( "b:write", b:read(7) ) ---]] - -local pcall = function(...) return ( pcall(...) )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/src/test/res/loops.lua b/src/test/res/loops.lua deleted file mode 100644 index 431374c8..00000000 --- a/src/test/res/loops.lua +++ /dev/null @@ -1,22 +0,0 @@ --- This script tests the "generic" for loop with a script iterator. - -local function stuff() - local function i(o) - if o.counter > 3 then - return nil - else - local v = o.counter - o.counter = v + 1 - return v - end - end - return i, { counter=1 } -end - -local function testfor() - for x in stuff() do - print(x) - end -end - -testfor() diff --git a/src/test/res/manylocals.lua b/src/test/res/manylocals.lua deleted file mode 100644 index c45179c5..00000000 --- a/src/test/res/manylocals.lua +++ /dev/null @@ -1,31 +0,0 @@ --- 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'); diff --git a/src/test/res/math.lua b/src/test/res/math.lua deleted file mode 100644 index 13dc6b8d..00000000 --- a/src/test/res/math.lua +++ /dev/null @@ -1,7 +0,0 @@ -local mathClass = luajava.bindClass("java.lang.Math") - -local function sqrt(x) - return mathClass:sqrt(x) -end - -return { sqrt = sqrt; pi = mathClass.PI } diff --git a/src/test/res/mathlib.lua b/src/test/res/mathlib.lua deleted file mode 100644 index 49d47be0..00000000 --- a/src/test/res/mathlib.lua +++ /dev/null @@ -1,87 +0,0 @@ -print( math.sin( 0.0 ) ) -print( math.cos( math.pi ) ) -print( math.sqrt( 9.0 ) ) -print( math.modf( 5.25 ) ) - -local aliases = { - ['0']='', - ['-0']='', - ['nan']='', - ['inf']='', - ['-inf']='', - ['1.#INF']='', - ['-1.#INF']='', - ['1.#IND']='', - ['-1.#IND']='', -} - -local function normalized(x) - local s = tostring(x) - return aliases[s] or s -end - --- binary ops -function binops( a, b ) - local sa = tostring(a) - local sb = tostring(b) - print( sa..'+'..sb..'='..normalized(a+b) ) - print( sa..'-'..sb..'='..normalized(a-b) ) - print( sa..'*'..sb..'='..normalized(a*b) ) - print( sa..'^'..sb..'='..normalized(a^b) ) - print( sa..'/'..sb..'='..normalized(a/b) ) - print( sa..'%'..sb..'='..normalized(a%b) ) - return '--' -end -print( pcall( binops, 2, 0 ) ) -print( pcall( binops, 2.5, 0 ) ) -print( pcall( binops, -2.5, 0 ) ) -print( pcall( binops, 2, 1 ) ) -print( pcall( binops, 5, 2 ) ) -print( pcall( binops, -5, 2 ) ) -print( pcall( binops, 16, -2 ) ) -print( pcall( binops, -16, -2 ) ) -print( pcall( binops, 256, 0.5 ) ) -print( pcall( binops, 256, 0.25 ) ) -print( pcall( binops, 256, 0.625 ) ) -print( pcall( binops, 256, -0.5 ) ) -print( pcall( binops, 256, -0.25 ) ) -print( pcall( binops, 256, -0.625 ) ) -print( pcall( binops, -256, 0.5 ) ) -print( pcall( binops, 0.5, 0 ) ) -print( pcall( binops, 0.5, 1 ) ) -print( pcall( binops, 0.5, 2 ) ) -print( pcall( binops, 0.5, -1 ) ) -print( pcall( binops, 0.5, -2 ) ) -print( pcall( binops, 2.25, 0 ) ) -print( pcall( binops, 2.25, 2 ) ) -print( pcall( binops, 2.25, 0.5 ) ) -print( pcall( binops, 2.25, 2.5 ) ) -print( pcall( binops, -2, 0 ) ) - --- random tests -print("Random tests") -local function testrandom(string,lo,hi) - local c,e = loadstring('return '..string) - for i=1,5 do - local s,e = pcall(c) - print( string, s and type(e) or e, (e>=lo) and (e<=hi) ) - 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 diff --git a/src/test/res/metatables.lua b/src/test/res/metatables.lua deleted file mode 100644 index e18be17d..00000000 --- a/src/test/res/metatables.lua +++ /dev/null @@ -1,48 +0,0 @@ -package.path = "?.lua;src/test/res/?.lua" -require 'ids' - --- 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,...) -local s = "hello" -print(s:sub(2,4)) - -local t = {} -function op(name,...) - local a,b = pcall( setmetatable, t, ... ) - print( name, id(t), id(getmetatable(t)), id(a), a and id(b) or type(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 \ No newline at end of file diff --git a/src/test/res/module.lua b/src/test/res/module.lua deleted file mode 100644 index cce7ddfa..00000000 --- a/src/test/res/module.lua +++ /dev/null @@ -1,90 +0,0 @@ - - --- unit tests for module() function -local ids = {} -local function id(obj) - if not obj or type(obj) == 'number' or type(obj) == 'string' then - return obj - end - local v = ids[obj] - if v then - return v - end - table.insert(ids,obj) - ids[obj] = type(obj)..'.'..tostring(#ids) - return ids[obj] -end - --- module tests -local pr = print -local pkg = package -local g = _G -local md = module -local rq = require -local sa = package.seeall -local gfe = getfenv -local gmt = getmetatable -local function envs() - return id(gfe(0)), id(gfe(1)), id(gfe(2)), - id(gmt(gfe(0))), id(gmt(gfe(1))), id(gmt(gfe(2))) -end -local function trymodule(name) - pr( '_G['..name..']', id(g[name]) ) - pr( 'pkg.loaded['..name..']', id(pkg.loaded[name]) ) - pr( 'envs', envs() ) - md(name) - pr( 'envs', envs() ) - pr( 'status,result', status, result ) - pr( '_G['..name..']', id(g[name]) ) - local t = pkg.loaded[name] - pr( 't=pkg.loaded['..name..']', id(t) ) - pr( 't._M, t._NAME, t._PACKAGE', id(t._M), id(t._NAME), id(t._PACKAGE) ) - pr( 'rq('..name..')', id( rq(name) ) ) - pr( 'print', id(print) ) - pr( 'seeall(t)', sa(t) ) - pr( 'print, _G['..name..']', id(print), id(g[name]) ) -end -trymodule('abc.def.ghi') -trymodule('abc.def.ghi') -trymodule('abc.def') -trymodule('abc.def.lmn') -trymodule('abc.def') -trymodule('abc') -package.loaded['opq.rst'] = {} -trymodule('opq.rst') -trymodule('opq.rst') -uvw = { xyz="x1y1z1" } ---print( "uvw", id(uvw) ) ---print( "uvw.xyz", id(uvw.xyz) ) ---print( "uvw.abc", id(uvw.abc) ) -print( pcall( trymodule, 'uvw.xyz' ) ) -print( pcall( trymodule, 'uvw' ) ) -print( pcall( trymodule, 'uvw.abc' ) ) -print( "uvw", id(uvw) ) -print( "uvw.xyz", id(uvw.xyz) ) -print( "uvw.abc", id(uvw.abc) ) - -function f() - module( 'fff', package.seeall ) - a = 'aaa' - print( a ) - end -f() -f() -print( a ) -print( getfenv(f)['a'] ) -print( a ) - --- do metatables work with package.loaded and require? -print( 'setting metatable for package.loaded' ) -print( 'package.loaded.mypreload', package.loaded.mypreload ) -print( 'setmetatable') -pcall( setmetatable, package.loaded, { __index={mypreload=12345}}) -print( 'package.loaded.mypreload', package.loaded.mypreload ) -print( "require, 'mypreload'", pcall( require, 'mypreload' ) ) -print( 'package.loaded.mypreload', package.loaded.mypreload ) -print( 'resetting metatable for package.loaded' ) -print( 'setmetatable') -pcall( setmetatable, package.loaded, nil ) -print( "require, 'mypreload'", (pcall( require, 'mypreload' )) ) -print( 'package.loaded.mypreload', package.loaded.mypreload ) diff --git a/src/test/res/next.lua b/src/test/res/next.lua deleted file mode 100644 index 36465713..00000000 --- a/src/test/res/next.lua +++ /dev/null @@ -1,37 +0,0 @@ - --- call with arg 'true' to turn on error messages -local messages = select(1,...) -function mpcall(...) - if messages then return pcall(...) - else return (pcall(...)) end -end - --- unit tests for the next() function -function checkvalues(tag, tbl) - local values = {} - local index,value = next(tbl,nil) - while index do - table.insert( values, tostring(index).."="..tostring(value) ) - index,value = next(tbl,index) - end - table.sort( values ) - print( tag, "values: {"..table.concat(values,",").."}" ) -end -function donexts(tag,tbl,count) - checkvalues(tag,tbl) - print( tag, '--- -1', 'pcall( next, tbl,-1 )', mpcall( next, tbl,-1 ) ) - print( tag, '--- 0', 'pcall( next, tbl,0 )', mpcall( next, tbl,0 ) ) - print( tag, '---"a"', 'pcall( next, tbl,"a" )', mpcall( next, tbl,"a" ) ) - print( tag, '--- 10', 'pcall( next, tbl, 10 )', mpcall( next, tbl, 10 ) ) -end -donexts( 'next1', {}, 2 ) -donexts( 'next2', {'one', 'two', 'three' }, 5 ) -donexts( 'next3', { aa='aaa', bb='bbb', cc='ccc', [20]='20', [30]='30'}, 7 ) -donexts( 'next4', {'one', 'two', 'three', aa='aaa', bb='bbb', cc='ccc', [20]='20', [30]='30'}, 9 ) -donexts( 'next5', {'one', 'two', 'three', [-1]='minus-one', [0]='zero' }, 7 ) - -print( 'pcall(next)', mpcall(next) ) -print( 'pcall(next,nil)', mpcall(next,nil) ) -print( 'pcall(next,"a")', mpcall(next,"a") ) -print( 'pcall(next,1)', mpcall(next,1) ) - diff --git a/src/test/res/oslib.lua b/src/test/res/oslib.lua deleted file mode 100644 index a728c17c..00000000 --- a/src/test/res/oslib.lua +++ /dev/null @@ -1,36 +0,0 @@ --- simple os-library tests --- these can't really be compared to C meaningfully, --- because they are so highly os-dependent. -local lib = "org.luaj.lib.j2se.J2seOsLib" --- local lib = "org.luaj.lib.OsLib" -print( 'require "'..lib..'"', pcall( require, lib ) ) -print( 'os', os ~= nil ) -print( 'os.clock()', pcall( os.clock ) ) -print( 'os.date()', pcall( os.date ) ) -print( 'os.difftime(123000, 21250)', pcall( os.difftime, 123000, 21250 ) ) -print( 'os.execute("hostname")', pcall( os.execute, 'hostname' ) ) -print( 'os.execute("")', pcall( os.execute, '' ) ) -print( 'os.getenv()', pcall( os.getenv ) ) -print( 'os.getenv("bogus.key")', pcall( os.getenv, 'bogus.key' ) ) -print( 'os.getenv("java.runtime.version")', pcall( os.getenv, 'java.runtime.version' ) ) -local s,p = pcall( os.tmpname ) -local s,q = pcall( os.tmpname ) -print( 'os.tmpname()', s, p ) -print( 'os.tmpname()', s, q ) -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 ) ) -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(123)' ) --- print( pcall( os.exit, -123 ) ) -print( 'failed to exit' ) diff --git a/src/test/res/pcalls.lua b/src/test/res/pcalls.lua deleted file mode 100644 index 689b0e64..00000000 --- a/src/test/res/pcalls.lua +++ /dev/null @@ -1,75 +0,0 @@ - --- sample lua function that returns values in reverse order -local function lc(a,b,c) - return c,b,a -end - --- sample lua function that throws a lua error -local function le(a,b,c) - error( 'sample error', 0 ) -end - --- function that does a plain call to the underlying function -local function cp(f,a,b,c) - global = f(a,b,c) - return global -end - --- function that does a tail call to the underlying function -local function ct(f,a,b,c) - return f(a,b,c) -end - --- wrap pcall to be more useful in testing -local pc = pcall -local pcall = function(...) - local s,c = pc(...) - return s, type(c) -end - --- lua calls -print( 'lc(22,33,44)', lc(22,33,44) ) -print( 'pcall(lc,22,33,44)', pcall(lc,22,33,44) ) -print( 'pcall(le,22,33,44)', pcall(le,22,33,44) ) -print( 'cp(lc,22,33,44)', cp(lc,22,33,44) ) -print( 'pcall(cp,lc,22,33,44)', pcall(cp,lc,22,33,44) ) -print( 'pcall(cp,le,22,33,44)', pcall(cp,le,22,33,44) ) -print( 'ct(lc,22,33,44)', ct(lc,22,33,44) ) -print( 'pcall(ct,lc,22,33,44)', pcall(ct,lc,22,33,44) ) -print( 'pcall(ct,le,22,33,44)', pcall(ct,le,22,33,44) ) - -print( "assert(true,'a','b','c')", assert( true, 'a', 'b', 'c' ) ) -print( "pcall(assert,true,'a','b','c')", pcall(assert, true, 'a', 'b', 'c' ) ) -print( "pcall(assert,false,'a','b','c')", pcall(assert, false, 'a', 'b', 'c' ) ) - --- more error, pcall tests -print( 'pcall(error)', pcall(error) ) -print( 'pcall(error,"msg")', pcall(error,"msg") ) -print( 'pcall(error,"msg",1)', pcall(error,"msg",1) ) -print( 'pcall(error,"msg",2)', pcall(error,"msg",2) ) -local function le(level) - error("msg",level) -end -function ge(level) - error("msg",level) -end -for i = 0,4 do - print( 'pcall(le,i)', i, pcall(le,i) ) - print( 'pcall(ge,i)', i, pcall(ge,i) ) -end - --- xpcall tests -local function goodfunction() return 'from good function' end -local function badfunction() error( 'from bad function') end -local function goodhandler(msg) return '-->'..msg..'<--' end -local function badhandler(msg) error( 'from bad handler' ) end -print( 'xpcall(error,goodhandler)', ( xpcall(error,goodhandler) ) ) -print( 'xpcall(goodfunction,goodhandler)', ( xpcall(goodfunction,goodhandler) ) ) -print( 'xpcall(badfunction,goodhandler)', ( xpcall(badfunction,goodhandler) ) ) -print( 'xpcall(goodfunction,badhandler)', ( xpcall(goodfunction,badhandler) ) ) -print( 'xpcall(badfunction,badhandler)', ( xpcall(badfunction,badhandler) ) ) -print( 'xpcall(goodfunction,nil)', ( xpcall(goodfunction,nil) ) ) -print( 'xpcall(badfunction,nil)', ( xpcall(badfunction,nil) ) ) -print( 'xpcall(goodfunction)', ( pcall( function() return xpcall(goodfunction) end ) ) ) -print( 'xpcall(badfunction)', ( pcall( function() return xpcall(badfunction) end ) ) ) - diff --git a/src/test/res/print.lua b/src/test/res/print.lua deleted file mode 100644 index 664ecd5b..00000000 --- a/src/test/res/print.lua +++ /dev/null @@ -1,26 +0,0 @@ --- print uses tostring under-the-hood! - -local function f() - print() - print('abc') - print(123) - print(true) - print('abc',123,true) -end - -local function g() - local fenv = {tostring=function(x) - return '*'..type(x)..'*' - end} - package.seeall(fenv) - f() - print('setfenv', pcall(setfenv, 0, fenv), {}, f ) - f() -end - -local s,c = pcall( coroutine.create, g ) -print('create', s, s and type(c) or c) -print('resume', pcall( coroutine.resume, c ) ) -f() - - diff --git a/src/test/res/req/subsample.lua b/src/test/res/req/subsample.lua deleted file mode 100644 index a53ed885..00000000 --- a/src/test/res/req/subsample.lua +++ /dev/null @@ -1,16 +0,0 @@ --- helper file for require() tests -require 'ids' -print( 'in subsample (before module statement)' ) -print( 'env', id(getfenv()), '_G', id(_G), '_NAME', _NAME, '_M', id(_M), '_PACKAGE', _PACKAGE ) -module( 'req.subsample', package.seeall ) - -print( 'in subsample (after module statement)' ) -print( 'env', id(getfenv()), '_G', id(_G), '_NAME', _NAME, '_M', id(_M), '_PACKAGE', _PACKAGE ) -function h() - print 'in subsample.h' - print( 'env', id(getfenv()), '_G', id(_G), '_NAME', _NAME, '_M', id(_M), '_PACKAGE', _PACKAGE ) -end -print 'loading subsample.lua' -h() -return 'return value from subsample', 'second return value from subsample' - diff --git a/src/test/res/require.lua b/src/test/res/require.lua deleted file mode 100644 index f7fd6dd0..00000000 --- a/src/test/res/require.lua +++ /dev/null @@ -1,101 +0,0 @@ --- unit tests for require() function -package.path = "?.lua;src/test/res/?.lua" -require 'ids' - --- tests on require -package.path='?.lua;src/test/res/?.lua' -function f( name ) - print( module( 'testmod', package.seeall ) ) - print( 'before', id(sample), id(bogus), id(_G[name]) ); - local status,result = pcall( require, name ) - if status then - print( 'pcall(require,"'..name..'")', status, id(result) ) - print( 'after', id(sample), id(bogus), id(_G[name]) ); - else - print( 'pcall(require,"'..name..'")', status ) - end -end -f('sample') -print( 'main', id(sample), id(bogus), id(custom), id(req) ); -f('sample') -print( 'main', id(sample), id(bogus), id(custom), id(req) ); -f('bogus') -print( 'main', id(sample), id(bogus), id(custom), id(req) ); -f( 'req.subsample' ) -print( 'main', id(sample), id(bogus), id(custom), id(req) ); - --- custom loader chain -local pl = package.loaders -for i=1,3 do - print( i,id(package.loaders[i]) ) -end -function loader1( ... ) - print ('in loader1', ...) - return "loader1 didn't find anything" -end -function loader2( name, ... ) - print ('in loader2', ...) - if name ~= 'custom' then - message = "name is not 'custom'" - print ('loader2 is returning', message ) - return message - end - table = {} - result = function() - print( 'in loader function, returning', id(table) ) - return table - end - print ('loader2 is returning', id(result) ) - return result -end -function loader3( ... ) - print ('in loader3', ...) - return nil -end -package.loaders = { loader1, loader2, loader3 } -f( 'bogus' ) -print( 'main', id(sample), id(bogus), id(custom), id(src) ); -f( 'custom' ) -print( 'main', id(sample), id(bogus), id(custom), id(src) ); - --- good, and bad lua samples -function g(name) - print( name, pcall(f,name) ) -end -package.loaders = { function(...) - print( 'in success loader', ... ) - return function(...) - print( 'in success chunk', ... ) - end -end } -pcall( g, 'require-sample-succeed' ) -package.loaders = { function(...) - print( 'in loader-error loader', ... ) - error( 'sample error thrown by loader-error loader') - return function(...) - print( 'in loader-error chunk', ... ) - end -end } -pcall( g, 'require-sample-loader-error' ) -package.loaders = { function(...) - print( 'in chunk-error loader', ... ) - return function(...) - error( 'sample error thrown by chunk-error function') - print( 'in chunk-error chunk', ... ) - end -end } -pcall( g, 'require-sample-chunk-error' ) - --- good, and bad java samples ---[[ (needs to be moved to different test suite) -package.loaders = pl -function g(name) - print( name, pcall(f,name) ) - print( 'main', id(org) ); -end -pcall( g, 'org.luaj.vm.require.RequireSampleClassCastExcep') -pcall( g, 'org.luaj.vm.require.RequireSampleLoadLuaError') -pcall( g, 'org.luaj.vm.require.RequireSampleLoadRuntimeExcep') -pcall( g, 'org.luaj.vm.require.RequireSampleSuccess') -pcall( g, 'org.luaj.vm.require.RequireSampleSuccess') ---]] \ No newline at end of file diff --git a/src/test/res/sample.lua b/src/test/res/sample.lua deleted file mode 100644 index 712560f7..00000000 --- a/src/test/res/sample.lua +++ /dev/null @@ -1,7 +0,0 @@ --- helper file for require() tests -module( 'sample', package.seeall ) -function h() - print 'in sample.h' -end -print 'loading sample.lua' - diff --git a/src/test/res/select.lua b/src/test/res/select.lua deleted file mode 100644 index 86c0abe6..00000000 --- a/src/test/res/select.lua +++ /dev/null @@ -1,31 +0,0 @@ --- Parts of this test are commented out because it looks like --- there is a problem with our argument passing, particularly in the --- presence of the VARARG instruction. - ---[[ local function f(...) -print("arg count:", select('#', ...)) -end - -local function g(...) - local a, b, c = select(2, ...) - print(a, b, c) -end -]]-- - -print((select(1, "a", "b", "c"))) -print( select(1, "a", "b", "c")) - -print((select(2, "a", "b", "c"))) -print( select(2, "a", "b", "c")) - -print((select(3, "a", "b", "c"))) -print( select(3, "a", "b", "c")) - -print((select(4, "a", "b", "c"))) -print( select(4, "a", "b", "c")) - -print( select("#") ) -print( select("#", "a") ) -print( select("#", "a", "b") ) --- f("hello", "world") --- g(1, 2, 3, 4, 5, 6, 7) diff --git a/src/test/res/setfenv.lua b/src/test/res/setfenv.lua deleted file mode 100644 index 492c2b46..00000000 --- a/src/test/res/setfenv.lua +++ /dev/null @@ -1,61 +0,0 @@ --- object ids -package.path = "?.lua;src/test/res/?.lua" -require 'ids' - -local id = id -local setfenv = setfenv -local print = print -local pcall = pcall -local create = coroutine.create -local resume = coroutine.resume -local seeall = package.seeall - --- unit tests for getfenv, setfenv -local function f3(level,value) - if value then - local t = {abc=value} - seeall(t) - setfenv( level, t ) - end - return abc -end -local function f2(...) - local r = f3(...) - return abc,r -end -local function f1(...) - local r,s = f2(...) - print( ' ....... f1 returning ',abc,r,s ) - return abc,r,s -end -local function survey(msg) - print('-------',msg) - print( ' _G,f1,f2,f3', id(_G),id(f1),id(f2),id(f3) ) - print( ' envs._G,f1,f2,f3', id(getfenv()),id(getfenv(f1)),id(getfenv(f2)),id(getfenv(f3)) ) - print( ' vals._G,f1,f2,f3', abc,getfenv(f1).abc, getfenv(f2).abc, getfenv(f3).abc ) - print( ' pcall(f1)', pcall(f1) ) -end - -survey( 'before') -setfenv(f1,{abc='ghi'}) -setfenv(f2,{abc='jkl'}) -setfenv(f3,{abc='mno'}) -survey( 'after') -print( 'abc,f1(1,"pqr")', abc,f1(1,"pqr") ) -print( 'abc,f1(2,"stu")', abc,f1(2,"stu") ) -print( 'abc,f1(3,"vwx")', abc,f1(3,"vwx") ) -survey( 'via f1()' ) - -local c = create( function() - survey( 'coroutine-thread-before') - print( 'f1(3,"abc")', f1(3,"567") ) - survey( 'coroutine-thread-1') - print( 'f1(2,"abc")', f1(2,"456") ) - survey( 'coroutine-thread-2') - print( 'f1(1,"abc")', f1(1,"345") ) - survey( 'coroutine-thread-3') - print( 'f1(0,"abc")', f1(0,"234") ) - survey( 'coroutine-thread-after') -end ) -print( 'resume', resume(c) ) -survey( 'post-resume') diff --git a/src/test/res/setlist.lua b/src/test/res/setlist.lua deleted file mode 100644 index 2a9ebbce..00000000 --- a/src/test/res/setlist.lua +++ /dev/null @@ -1,27 +0,0 @@ --- This file attemps to test that the setlist instruction works - -local list = { 1, 2, 3 } - --- for now, can't just do: --- for x, y in pairs( list ) do --- since our tables don't iterate over keys in the same order --- as regular Lua. - -print( #list ) -for i = 1, 3 do - print("list[", i, "]=", list[i]) -end - -local function printList( l ) - for i = 1, #l do - print(i, "->", l[i] ) - end -end - -printList( { "a", "b", "c" } ) - -local function foo() - return "d", "e", "f", "g" -end - -printList( { foo() } ) diff --git a/src/test/res/simplemetatables.lua b/src/test/res/simplemetatables.lua deleted file mode 100644 index 0a9c05e1..00000000 --- a/src/test/res/simplemetatables.lua +++ /dev/null @@ -1,14 +0,0 @@ --- The purpose of this test case is to check --- that certain simple metatable operations work properly -t = { b='bbb' } -t.__index = t -u = {} -setmetatable( u, t ) -u.c = 'ccc' - -print( 't.a', t.a ) -print( 'u.a', u.a ) -print( 't.b', t.b ) -print( 'u.b', u.b ) -print( 't.c', t.c ) -print( 'u.c', u.c ) diff --git a/src/test/res/sort.lua b/src/test/res/sort.lua deleted file mode 100644 index 39fc2b51..00000000 --- a/src/test/res/sort.lua +++ /dev/null @@ -1,27 +0,0 @@ --- concat -print( '-- sort tests' ) -local function tryall(cmp) - local function try(t) - print( table.concat(t,'-') ) - if pcall( table.sort, t, cmp ) then - print( table.concat(t,'-') ) - else - print( 'sort failed' ) - end - end - try{ 2, 4, 6, 8, 1, 3, 5, 7 } - try{ 333, 222, 111 } - try{ "www", "xxx", "yyy", "aaa", "bbb", "ccc" } - try{ 21, 23, "25", 27, 22, "24", 26, 28 } -end -local function comparator(a,b) - return tonumber(a)v^Cn+v~5n?wx@0TYumPMcTd~4ZQHhO`_B3AiKAE#wK8`-R7GU2Sh;g= zc_~mZR3IQAD4@048@6WD&W>?VAfPWuARq`JG$2J0!9Ox0D$3A6py!|IqFp=bqAG4+ zK&POmpj9d|wi_IXT@PxoP7sF5%z$hd{a}mxrt5=_tk@ z*w{W6NgjdA1b!VU$6Pm1c>VM+iAk($!{m=t3dt5m*(E*=1G}Cw)LO#7mdLH0 z`z_bY%lH2-a~v!SNui`i-gQiN-~A|O_un1WG_=qrpceJ{$m%{gO}rXXz@$-jG?}nq zv}vIt1vFgN5bpD-k$CXvyECw)#3QxVXVJ;15o54bF*Ofm)3VxUclnwCOMs`5enVRh zlKzpVU75aegQ!G~S0POm_f9{1B|y)Jt*J==64bO+m_5tmJ;vpaoF3N+5bHzJr8v#E z7o89mzuwfRjhM9u4v$w*leRT+Vf0rrYKs)V-8=i982PyRm>k`bX=tNv?Y#F77bd>` z4paWwaAWLhD{HmO6SpDwaoarJ&~Tmc2%V~Id(>)e?PxPgzd@*wq7*!@32I1294hI# zRfw$&*iE5~=sB+7Gc7yTa2WMsc&$`SlPIP+?QKvVd)g?cJ6}!fGAp=X7#}QEaWSbP zRuso8l22)ylwSjq;=y9Mp^04t;8bXBn}j0iq}{r0*IjNHX1FlC;b-umSCl#v^P4l_ zk+>L9C)6=H%!xX=?>r;sxM$3ruBh}CJaLRx_6c&Q^{a5){mvSDP_JKSYj$(G*w;o7 zHCGREQav&6O<@mdjBnB~HD#lQJNm^q{p~|`fT!Js(#PZN^ZI!7btTedQbza3vyJ34 zeG;HWgZ9F4JFjL+9`7M5D~R6DDb!`<%83?OGxo4l)JfnrM}KDQh)(s+mkn`vmFB*t z88ZGf?zjyx{+Y{3Df|ooeF>C~4ASIYNhtremsIg7xQ9tri+;zE|1Sx!w)bEmdFl5M z1Ooy}g#iMB{3ikWR#tRY&iemP17eWK|5)z+w+1w+O4%N;A$DJ=MKwXu-> zc0I-k*PfEHk1$X~qy&c*3MgiPiTrqmB1pts(#{UR_>;h$yiG;spo`dVJ+nxFHH`=< zX;A8O)YND2Nc^?XnzoX0maxn&3ehrjCx2%nt^G#RptEyoWZ%sCIadB%vETzZT%gD%&i;wB(im*LA#UT+p_6dQ_PTH;x=v%txaIfKoeh86PR=qnYD9A;rQj~J|I!K1UOjd)vyo!4-s@9Bo{R16}(53gMPB4H5KemcI8oclqK3N;6CrZ}hx& zRIjWs#MOH%B)A}qVo&FtJJLkPjPPYNJnr{58f!3gTcI!JbTj~{s2SaRMe z>Xalb8h-2(cbvg{WqM-MfPl&t7{t!}!rydHa=~ghPMP>>U`kMd%Z@j3`xB3zbS7#` zhOz>)?7i@gzd_{Nv6){LIB!TIPG(TiM9@yhGbbG!`T-$vkh68+cL<3}cc9O|mCtAO zsI|b`M-2L11H&wrR>Vp@=5$`>zZ?zXpI8*;&tkA1IR^Lt6t7ZLkWWY)vw_8H7?F0!#%mz?W|l1Us4_NLT$c@>Yz)>;aFFEcJ9*qH&kjsk;rLB3A?Fa z1x9{?;w?3j;r5w;qMhLFw!Y9OIteh`M=zp(4aQs1Sr(%Qk4rpV(VNonMW9^hl5I&# zu>4vyUqeiOq*H>BCq~8IbOm7U;M@NUtp-VL=-6h(=`|8Mk!`IEmtJ23n8pT(Xy& z;yW9N=IS_NA#3Z;XAgFCX9daAFFoDxQSpm2cflahjC`Pq2Y>f#ur=2~VeQIxkvU-Agqb7;FmwJU3~Ti4_6r%f`(33Rh_P zU(OV9sc-}Z4Bd$IJT!YhAejP#U_m3m2tvF3yli%3DqerY;n@TFsJ2=+AoEG{;@z^$ z8^@jzIE5gbsJBE6uk`aPk z={I8|XrDB7E}s?+(RNyut-P;8IJQ#MAu=EI|1CW>|DN^V|0Bp`8NPT& znvxUsv615qEbd2)S8_#JClataWKg%tPQxq7zW?QrR>ZBaRc`e==tnlWXp<@)V_&{d z1MT$y;a-@`=XDQKp{)L0!N{G|NUH9C{#Gzdg#LUD-b_*|Kq0TC(b+W0H_wN zygbsXu>J{(FM|uTmIp<}p(25MPfdZM9Ftqsp-CxG=;}c(BE3K$?7^{*mUwIh#$&8r zS>(v^q^g|h6g%ulah2BI4~kvDw>_#~cE@>}FuZ!+G9Y@77*U*LZcW}jZY+yGO&Ww3 zjwrHfw+zwrlTj9v{D(xAfQ$zuLMCJLYTmk8O@lSTfO1=I+5SxI&g*V#V#o_!Oo8W@ zXnIOLh}XuLtZ{eYn-^rm$XV*yPnp+2%>%Z{oRcp<WzpK(WLPvV4807(x3)QfcRK_)QVQsjk7>X`=v1Jw|G>gU3xy1g$jsklKfBEQFTs` zO7;yboD-hb%0ftlMrZ^YoJ=YQ>=vn8OMC~i#(vDv8pVeG6Wr+A5F}zuw_LK)ild(R zkFl_x@QwqgF+Oc75()%uZ>|!A->1r3p8+e>D+?;)=j5&_pEEgcPIIR&M`sNX^_X#B z`|m{qdm^qtX}vhi+X0u|uVb~m*G$?IecWmMoPO}ld9}HGK@1t-9oSQd%CH5i0tr!r zQB*ZGq$^5gigzCiY!9);j}IRF-vq4-S%R?4e_v(@r{bvW@p&`w?ijdP>erMSgAL|J zc11XFi0kA-v!s*U9L9OgOlJh&Sx7wV`X2{|5LGp^YK(#QGZFTz(jvI;6E~M4lH;(- ztz$AwTF*CHu+^+UMc@#%&)^k)*?$^KungS(x_|zfvE6>Ds_c}L zcOKFIQQd=PFP?>rUjExBK7+76i_6x?l&k~O11IBKf};pCtd42e-x`1F4Ife{Z`=iH z3SuQq#%2zF5rQ8fkgq~C4r2n!a_wLya6!n&uPMr(E?Z)BJ~r5}2P8?KyLU8^x{4}; zbDCUKT2mcHjYJs-N+rMoY?WO$RlEDnh3Xu_0~ZXdxe}z@4B5^!D;wK{&3#*G$5(~5 z5~+{xHwNCvBwX7befE<{AE1Zn;?GO7+UB3-tUs6X812pHi0J0{iN@YzvV4^qmo>w+ z$T5qz>1VY_H*}Jbfj4g1b1A{XuoH>q0~|=enj0m=`RfRGx7XoHg>>xZfnO{(PaS-( z?AoqlDtpCRb}PHbr(Q$gtrCsrXBpgfSza>|a~*^mC^|D)0i*rEcrYb3uZvO*VCkNi zk|LaW=&TC;gBbxUf)C68*_#rX(d9&OPumF4K_Xv3=9xsZTCrWmXcx3CYR(hfW+Uab zZUkEPhFee{s8^RcbyRnKs_t6SeuKBEuGvc^Q|j2tWqq!{uR}6f{@^!rhHH1(<5J!u z+YD)0R%H0BgYyjH(aItyR_K zYsENxFtqiJId}(Jmk|Y)r)O!m@xC(WqpWaFhXeL+)4XjsW8pxmqzWA!hlh6DOYQCE zTbsXRiE>Gu`Y0ZBZhnyo7dNA{0;sj!VCleTvDAz*Ufl>jM{wOO39vJaS3Vw)x91+L zv1@m~qZxLlWS{jK{@xpS98hKw*@1WRq_G?vN3y|7zx9zcL z84w#P4fVVbB*HUuqm|92TJC@BsK8* z*&DE@e54y#U0TzD^FsaDb3_ljA^`EdSQSSMr88f=baV6!yWx|wa}-J1u5(uNTknnqxkJuKp=J?v788|_>IdS zgDCO1P&~D!CwN*q!WSdOpM96O6C%>Gar9b!gE(Lkn=lSOpfoRo`@r>%R3Jzvb zt>}Z9ozw9IhO#_zjS$~2iZ-c%v4u#Nba4aL$es|fnX@>AiMo-Q7rKp}qg2VacY!qz zNzC)+mVN4B$k^Eld(KbYvJv|Vqc1dM;4x)$l>--cX429Q{DBM9xW*bzH5$T{xLq4_ z(0c-j%}+Ul!G^XGaD9;d!z1~SYDtQ%|8!ZCj%ZwyL6B)!b?u2hUt4*ld~#M_jVBM< z%Kg6ENMUzG9Y;gv;aeW@;K5#1zXqbyhvocjDidO{b`{phh6>pNu)k-hFrBqElU+ z4(picH8j}JEt{YNSPm|b9A&OCV`OlB$Cfs)pzuvww|Gb$ZL^G@tgh+kYn_%RQymme ziNo7xga*!1={;2Q*d#mr30Caoig+{LwlFirH80^&Tfae^g8d5(k3q3Bg~eSA&=ren z$pIHmjQJqDnrtUBHJe4W#uy&IMdSb0M}EXNL4FO9b>Ef~uYR`3!9eJCnbB}z^Hp|9 zuhon!?#UA_6a|SAapp4fb!iPeYU=PSZ4)SJr0RmKIosokUMp!FJ<}`2ZR))`1807j zS8NZvIIhp&tmW!CJG(3#mc1Xe0d8ev<>Ts(R~P{;PzD==)4(nYdn$iei67HH>q=J5OTJ-FGylwnIa zp1|JnDW(gCi~4lFR!G7PS=r?ZD9T$6rbj*_A=)_4Z;yDVcSsbC3iL)D(U1O6f^Nz!r{BI42T0 zTyGUwnf($yN9Z%OqHu(E<@%PZ&cH%EK|xCxYX80Kx%Xpv{p@;QbwH z;$>Kq2KFVAE@bsub4rsbxQv-iDGuqI4dkG$ab1Ge5hSSaSfYZTj~}=^Pnft__>kCY zqG2XXb=z>|a&!c?3R)zClWsl%t2b_5Xi(_v{*6~&%dlKQ4zAeOD$Jj*5Ct=2R^nhB zpK)in%j%CYy2BXS&2+uZ&uL{fwBI6BLv+0Pe=AvuqVH^)y>S$98S_^Y=3i+Jdbb4hkR@Otc)L^=H7YNJOp@oPeBJqiJq;^1CHw@G6of*M>4cSGlF2cILZkw3H{>eP3Q!=1W0P%pisNUj&jKdn8E6@ zqt+f3hCCs{;PFc2@%>`?a@5PZG~rg_t!>qO$(M+(pX+=8Y$M|UBiR+t6NUMuM%H2Y zD_!y5l*Yeh&gruJ*<_@(F8#q+m@1z@n>-niAf9X+dA1hz5dcD5SIjOOWF*Llw-%rz8s?B77PbBqLZPjfX6bOVbk5> ztIZ76F>$EU#i%eyW=E1Rav)=f?Mt^pBTl9hfi%}}{g@-LA~?N|;rTl4vu+HJO(Q%y zxz+NdJSA+QLBoihU7%^(K01S}9ICNQk8?q3{iv+5XYAJ9**fW`EE;RvIcsUF=}eu* zoKK`2W{ZDIo>tfgB_BcBdUR19QYE`6S`$98d=qo{D|{AX0VYkAoQuiNLQUl3bO{@JR?eB=T>n3By>2f5--ng-4q> ziXDz8aUZrFNMWUsYd%GZ!+)DZCraVAN<5O=&9tZ$m242P8{ZQQnF>sKbFYI?f{!t; z$Vp#V%L2Sx>2pj*=2T67W!{itFx``xjL337H<)7vBXY!FrILZ1N~=9mL7ZC2X#lx^ z?pTDA!Rw8@+5e7S`Sfy`^aC>lHBqX##31{74$WrVlUDam<`n)RjPdC0;E>1=h6Mxg za1vdt$%$d3&puhH{R9yT<;88p>D7@ zdgii;o!s+PZ-K_xVRhrfr>8pun(L;#{Z`8RjNTTy-)RG9r{>u{E$B|K6-TRez>d$< ze1(<;!}BMiSgFEijLV(e)*rcaPMokXiQ`k^Q@+<|{6B)alXEkY0SmfptIVo-z|pJ} z!)AlBr3?*j~saQzW%u*0vZl>HV0KsCdx)afj?gx)8=c99lB>j8X9VuPksW zwZL;*fEU+^+F46ePG(Z*?;P?AGUx!yjX$7ze0W784nBD|E=eibGF6=yF%3o0vxdvt zDIQur>)YgIL@rVkaNpo@*FdM+?0hl^IQ^|=J8&8@FZwMDz{Kx^x@p+)L+ODjfoq_I;xxRYCgs(5MfXBb8{gS*`y9%g<% z-?lP*e?Fd$aGJsJ-EAAK0pYR6>CqyZ^BsbgO%lworP+mGgrB8SQI2+amRGn3G76?A ze~%83#Fkf&gjL51Y*MGvzIto#FUyEbuhP8sBajoB2G~pm^w7@xblUfaF0+`?_9d$C zgR|A2k1{%utGOw7N~}qxmL5CoSXQP;$6-c_cb z3s10`$rrmrl4=GJWoBC648ZtZ=yTXLN_fHv7$hGMT9y6s)?pw~(*{;wruNO;DN5U% zU`*AAAgP3{O*=bs#h2)4a@I$q7v<$%);XzmsuO))&&LP2Eb6y=32Pclr)u-&=HPC$ z2b}iPHd{)in4n(?=ks!&Bkz^ks(L7*YMr}^&b;!@{e-w2{^l)xXr%fXB$CZ%-*p9y z;YFQjrS`2Etm85Qqx30mbF)DISlOQpl3fNj@+$RQx&B%+q=tNb;&T_bph0dVeoR> z31*cE@n~P)Y1dXR=D~`jDM`Y{Z&IU5V!%D?mf&zPLN<@)Q=RE4SS`p2$dXQU$S*=Z zlFSV#he5LRjNfCM6f4A!v_U?o+Xw#^VwI4&vTS;KrYHmwS9!_sKjdj3N>5*)NLGj+ z;G3G~y~Op9zM)_T%yaYg*cj!z10nJ7d9v373eEa)MtISJ4!72#M!evC#k5-%U_WGY zI_mWGC^zi1+UGcD(P~&c8(T-C7voGlV-e)MHUMJYfl#;?fiRT0_IC+5d>f6JeF^MvrcY|Y1MwHHhQqJqrvrqV1{SrxY9 z)ORxOcSPL0azW3QuLNGB9^+kGvH7l=f8F@GWBoi@m#UwS96Zvox&$KmoDfaHw=qc1zIML?qo4H zhNq67V0!9zVh&y`TVWgHISFS!(c;)*$C&lm@MHu@Pc)mUltj{Rckt`fw7ES3>rE>W z)1bN{TTc57B-KvUlD)Aw{6$6TeNnzrRnVl827Vg5XLXTaiaFDej+n@9oUbev7Gjg|& zTzr(2!8{C~@|ayYHfBNZxX%(Pw4pcWg6mw#UiKcObAm;ez#-mQf}jp zNTs9676%~V%S?J2U}ixHYKGQ|9HT)K6Gaeq=Hc~tUi^o=(~`@^l|_+wOvVr<`Jurr_$F7m1OG?%$RvZ` zLa~bFZYHzow55-uNjufh-Q8w=vx+K9zs-F6ScH~Bk?(aqRTC|B^+lrvu1F~kVrP>G zDzuOD2XaPh8wp=GY^zM?q>{nHhF?zd;N&=PNoBawGUzmw&h_eV51iY?dMejl^qGnt z?JMnvTA3{C%ul49;&1dRQNg1MPk9>mVr{^1h0{>L<)?m|b#lI$+HCzjQ@G>Z@yiUz zsC#pz?rKEqHkw3YaU9Ry@Jju$+6uCPj%xlbay*&=j;YGj zeYJXWFDjxdK|sS6E4=jCM{q^yPI;vS-t!_PX`J@R-vT?>1sLszff5MBGtXOAz~c z1LHk@sSd58jC;!wovT$Po8+dM0@#*D11y<&jPRS@^bKbIouOxtKpW3L?n{bB?_N8x z`EwQV+{wXYq7Cs$A$Jm{uayr^-4D*rO+Dv`fEGvR2{U*{Vosi{a#Ai2-uf!BiS#Ky zfKi)M=)kYSx6SvJ%KGvkDSHO7a?y0*9>rVs2al zsVR9%K+W9pnAw;LOTAJ`SDKX<$BVwK@^2Bq_mGAr)k`IhCm{%&^fZ14h6+2$9bTjn z^+>R+RNg#BA;;5P$9#;!wv1zf^ItcyI?m8Mrp&1{6yvrA4HY=*mP3+@=8F9Vn+86f zNOpQ%h{*l&%N;QfnwszMDm|eD`FXB|-pSPmI@=V%GZ<(wu+gwm%Z*v@ zb(-@yucs>SCAnMh?3nX%{$Y7kY~RtEZ4|;R$`I?nb9w^q^zL%qDxmOJBY0?wICDUL zju$SUI@U<#EIarcH%9E>qR7vI5!Bx$*!zWTMj3g#&cC2*AOf>bIFGsy_z~!))mZM+()Rf!sxwFFj`j!+4al8|s`=zB)4$b>5%A~~>fORj+(prQO@cP>c_jqfnb8hq zI?xfNYzqX>w@b12M&2oaMD0~8XD&?#N0pL&*@6C&d4p_Z4Sb~%n9V}BJ-1F|xy79z z{b4)5-ocQct||Cl;p}i9BY?$K zgEk$RizTCREW9oi)Oqm`Cz>YiFrPm1(?5=alHD(3jcKCcSWpmGuz|dLt0)-L%zAXi|gN@Q!eLW~L_6^0F2j!Ku+0Xkrx|G?#0fvQ{9PMV76+%4CCq>@@^Ck!fb3 zur0cR6!Qf01K2&a3Rjw31)s;hycx$sR@vb8g09N$SFMil$2#;dJ{w;l7iOs8DYnE< zjToTWK$Cq0Zz8=~T|nm~KZK(aKWr6kVRxFWyhe-84tssP)f>dX%ryWNA1Z++znwRE z-Rj=P99ERi6a>pi6}ZG&OkrI(1QCYM>>Jo)w6nA=##6Q0lWbl&N(Q$C9bjf;E7bfk zTj=3QqT+pzk0lfx%R(fVjDrYW1_tH0gYIa!e>dg*I)v#dz3LI>x2iP`oqHL6@ zXr-hk)Mwf?Luhw}R$LEM4u%wag|1_NhjT%cqp8aS!R468lfxC+)TAkZvehCE>x?1Z z&x9rH7XuOwj01tvqBjd%JLwZTf0Wm*czOvjxK@@&4|97>4?Gp3@>?l@rt-&leI7L9 zpSL*fbJNcZGV={jZicQC*t}X?Y*(TVrXKU8swle-`E?omGW#ux)y|@FHFFya+gIJ2 zWS}5nzeeUMMc=pSiMhoXLc}mmW;2r`wblj0$W6n|{afl?;(bwzo4oj(0{ddqo=Cte z)Nq&|M>uyx1WQR3S*|k3g6qtJx))8>7G4R@%GM9PHLi&nh0EX!h_Yly1vN`Q<}{{& zJ6MBR9e2E$a27sT5;AQ}zgTmxJi|?n+We#VHIrD9T}hjtJ~hyiUkn~j$K8YBbeAeI zS_)A@tvk@&8#*eq09#P0dWq=3Y{Z??71rb8*1mBN4?f_q=~|p_r_-FzLrlWJW<>*k z(*dp_?Mcm*jpeZB8}*cs>3uzX`yL)Pz_%}PV4s|GI<0arPfYVq@a5yBfINhvm*vKI znjY>00Ch&ejOfBuHXz8;5VUN10DOmz(#r#jPFY(|*>;Oqd8gd-)to78l8fXsQ$Hh$O+FH!Vc;}uxQ}iiiIgX$K zI#5aVs^7!j2u{p)21FkSr^2Ei%K6v&UsO{SBzhkd~fKT*v31gH6O*yQnrYd2%`by78YmC!Z(LBR2r zr_?4gBeXIUNofG33%HU!f#4iX0p@F(*hEZvf~Qwc$)u6k%PFTk(|gBno8{{|4NvZd zOex{D=jSJU-Bd+UkkGS8p!&x@HdDwceBHv@2|yrQSx>(I?U8N&6-aPG*yv~d^T>|) z|9^pmfw}2_8RUfjW01GfbZj?=v4U^jsG)#^U63RQ5qb{J^C>_YWir6TBeYxT1SBf{ zo~2)0SK}3hd~8f`-U#=Z`+xeuFqjT&XLDxq-ZV5!w2YYZonV}7o$*ZZAC^2YvVLrR z4!k-0xb<-JT_f=87_EKV@n1iD>3{Df?cCRA99&-=@7oRysZ{q=tlj62xITQjb4|W| zx$)h^yqT<zOi}Jk zAz-L=U;2LYvAQ@i(@hs&ICOkkH?KKpG-pz<(zqgSvrXtV@dA!qC&F8#e0#!IbcWz; znYCv^9r=zAK5s8w(+SvI)!v34B&}Q4HW~{vCT8ebG@7MfXIvNTQ*}3cwzqx`c($)x zCoBNEJzi~QIdX4%j5}TKp5L51au3%@w$q_r8bKdA-&YtrUvIIx-gn-}Z#{1v-9Aqi z=ED_@^AC+Zn%~C!UD?kaJXKdZ-*%(LBgWA)HLi{+fJdU4nwp$cs+6w<!!;k?oPb5eEs!c8+Q~@3&YL zh571(h~{EzGp+TQW;qKf%ey+s^D+2)mGG|m{3>&t^_1pWRG|<)@a4C>8C=POAA7lzn9>VAm6JL4mM-U6Jj7q zWv=_39F!o9JVvGrWrRaD7|((%T92uKD?u!1B^-?Dk|zW;Mu_y=AE`I(6RC$z8A_Lc z>QC$;5|4w}r8r*Rg>djFT%OSGD2_debx?FAQWG#mjWQVncsOO4w4a+fw2YtyjDb>I zM!+uWVU0Fu7(OAo1iAvc2D(1FIlBFF`U&goOt>flq9xo@`Z?>eW%Y_4r~#67ytRsD zc&=EdNViC@NWaJ+8kVlbxQCP$6Z(~=BdfLW#=J`-FYR|&$7lysr+8<2Q`nu@smQs= zrO36&t;oH|qsX(!>r%C{K(1Hd;o{4?iRh}3(uH-t5FPt(` z%|kn_8oZ1yJX{}=cD9epecJeWvr?~~x7eNa%&YG;q~xwuq-q>$ z03J=AQ}dRamZ^XXK+9u$QR>v!{Kc2A`3P^T8oES#Sa(Ud`#6h2n#uUQ3-y%BtMs~) z`)|=_1?4D!8tWw z8=vR*i<(l=>8rXLtt)N*Gj=z>E)|(N4dCi@dY<1aYDk5r&+2k=JG(3zkTU&83*j2X zD*rJ&0GH?4?fjZlXzDh=qx123{-CHO6`#JV>(TA(s%S*YmY(-wenTque}@CRVBN4T zje95b=s^Jxo>;d`s}p{yeE^6~*k`6)2~`y01%S8mOLe@7H7%Qx|>p0^mk=8KtnXe002tu#)_jR zSU~`)3NFp6NR$~5;T?r)u}&%@(^fdzNFq~=OS$dcQ&d@&nuPWgAj&_5qnr*`#C6P? zK$zeU78_OYk4EXmD=3e2LLlKXh2+K&Ee>{yB7!mbrT<-d_2&ygxMcMBM|b_XhhLZmPruxaCl z^v(IsBQ+CPK-7BAW~7t;s$Y#j5UlPBCzp%$E-qxVZb2#QL+Ch zk6!59T!ZO-G37BUTW&}m7-V1w`Mc8UhaLi6$w2jw=K7%w4Y5Uob>g2{`rNMFwa$~s$xH8=;R~5o7?hnnPEGE{Gw~`0S z#mR~0=;grj3-V+6!h9FmrbD>(jRFGv&$LR!o)fw~JsKVOdv*V9KRx|-wsVDvf3eWB zj50CalS^>2ad}kbq&kXLia>=p1$7{J~^!1 zfLtaaaAD&xn22#qG~8sta+|N9m{_w;%;JDzCRuPf<6M~had9;1eA)M5NU{-k_B$eTf>QTIXSF=EvX* zS=LUsx@^s_d#10M3a5n;mNe3xsFM|T+u@Qa7M(Sr_nEVXdkp^QLNyO8ex3Z1M!$>_ zYad?@{Ozm~ch`r8ldjH=&2DvDgLFR6asDOARO@kr4Acr@%3@vRc_q4RH)BJI&>elc zPwCsFAC@fLlk1ZSUfGw9g%gYo^>~aow~sx;=I&oTGC3m?q2mKY1iC)2uT)#}kzVaO z*Asx{7thb+@a&t1#5SI>gM{X@=1z+gxfSC8^^cOFzKIhlwiyIN@0;u&HL~u{_lb$e zkA#|5T>6F|p#QeDcK>Xx_(6d28q~k8BTOJ5=zpnS!+$*oj{jwB6aN`o`~Ok-TZK8{ zu)%RZT_a$R046Ls5qh~bxQE*i$~(zv+@Tl;HMS|An?lT-r1Ji9W#jjoaIHG6T!ktH z>hWWXr!o1wb!W^_tqgDD*N$!-|OalzVX;N6_pFi zSN%O&2gmiBmHI6D0HWLnLrAWh(@n$oz?G9_=dg`7$;$_7NK$;Xon`Wz1rB zfCUMFAyiUNJ0YcFTvgJp7y}*L6>-(KD<)V2g4QLPZ}NJpNIyu=VX88R*R+H27fcgm zQX@yAvY8%|7EmHebJQMTkp;|m1<0B?*m@DiOUlIDJKv>v?zP}k(EdQmK2VH6KBG~t zX~ZP=P2cV*ZG|bWh+k(27w$D2CBQ|Z_I%DFxSKKU#JpgozAfMAQ32ugAVlsHAi4q{ z5RoupI-@W28hBs~(~Q&;)Bua$j?wflV$6HVh(cxE{(Vff{wPr3PbzbkEeh-?K0>s0 zDCH9W37x}4M^55;@lj5@cQa7>SB*bbR&vQ+yoOnWJ*Kiy2kN5A#}u9hBMkb-XuG^7 zopejcM(aIU5uawuhq-)@aW1X)4D4UQc*<`Z@N2L?RO8N4>qJ(ahI1|XhtTEiF^I{}dL7LI#CH8wydN?Cy zx`7fu)*8!;sJX~^Y8px5+K3J;KE@^fdB z85GVFfB2bP%l|fWOz4qfmN9VQUr=^9g=I|#DN87aFc7{jI*(yLrA&CGe!UxG$~lg0 zJNT=hma`x}MB=-XUvyJYw4Pmq0*y3d!(EctnNJaQ6uA!(larUB?WZtlqRNgbTW@=Q zyn5gl8oFT-ceFn%5YX#J|E~)~^QMFOcF}=GUQMacuM)Fn^)E`37qdz;kcH?rl87wx zD+jt^Weof8EQ`hdsJ5QpGF38K;p-3GoXE0@QIo|utP`eu%2|E;V>0AUd}@I=+A=y6 zj=AK}{)S_&-`3kmwb5xpf4+N7dEbqwxdhD2oJ8zj!hNdkV7izdV(wOMqp`B>na9lV zY@JF3tyruZW7rg+na>fk^3_aTa(EuGdqgQeXLfyUOoVZJTsI@WX@6kzTx`oNlZqA6 zMa=FTm<${Aa+ZVXfvTtOAl0^8Hh zRY#~ZO)Aepq*gX&IQap;8gLbjwnGwg4_Q$IXWr5U|E7Md8gPGIDz(ba*|5Rvk)*VdDS+=fPV;`A&G*x?GCVd{T!e7Z?p zxyG~F9CRzHv3f+Fexy^ig7}Mht}#ihnb-_+YCc(w`#D2T7CoMW37CDabWL)&@O1wU zk+93PD}koCFIPY!w%V|~!i0Y*IMdUVE*6{TCAk8lTve|`H>3FqVBay1?j!IyGjMQm ziPhf8Laat!8@pGc+Q=tGJOHapoE+5w_c8~qoV?~BTA!V8OdR}{_1o3P&a(TF+=Ktr zqca1KFr^k6>q?YtUJ7AD!>0FYMYCGCRERGL`lb|3gQ4X!kfWL)SWPr-lG$sljMEED zr4l$sDUGLelLXm0BuMEVoK{nqr@HP^xOXOBWnoPT%`#gtAfM7#5qN5-DA;aI8S#P3 z0vS)GYkW`)nlC>a!O&GvGwI@Qq&B0 zNW)QX%bqYx7J!enA`bCu#((1%rG~4=2P2`cb>@pv7ZQVW;lPpr3MMt4P2wc+p0Cin zd5Tv1K0NucYmjACTZ)3Eu0r65awF7w^-4v_&%NTC32}R#wN-7E^4N-=V?fqN2}(TI z5GwA3gHNPXv6q(@wRDIpS%}iG%=~r<;!OzW>n5hA_ zFsFdotFz{{KcQ)m0D?2U2e)q@J^JsB0A05q(En|UW`m#~yFq|}T>iCU!~cgVGBY-` zbkaAlGX5`Tl=ROTIsFf3l&rF0lgWVSeL^iNZk9KJ+^m>`{k~2xxBjtRo%AqPjk60&&6 zkN{MT6&p@F2NEq!234kbB!z%r7Ra!KOZe|)tTYJDkZrcGl+=P=V@5wWf75%-vM_@Km(ItaQDrxp!i3(|o2&*3cg z<-9U)bFI}Oh@j%N#faGaYS9d@2roQ)sR6IG zo#_r8w&`uNML5UShbq)&MJ$*D4XtT4`D1z6_84C7yM4C#Au9933LnlqEnEsuP+P0N zG8{H^*zd%E{jRFfUSKZ>m#yor#X{3Um#qNTP@<`(YbG8FcFI0{OX$@$`AHlM^25s^ zr6zDS2{@m9u?|MvWGYHNc1*vO;KK-)LGB3EtuK(wq{o#*C1k-s`EPMT~b-$QS>k7tsFSnLy~0 z>rei_R5uGT5YVsxSpHVFj?NDMz4nv;4_Yt7+c_zq8(F&G0xDvV5kGJNVtRY9^o zxn9ZVF0i6A0we$wMg&U0PCi#+#yI3JfLY2AWSS8B{61~WM zDXG&yzu8m)a12NDFy36r65F3--KEv6FLiTNdzV_Hx@n}4b%+(2wcLb>B0%KV+1YQH znM$+vn%$#Kx5gKW2JRqA^GK75^~+c4T3@BWN!z7^qZh_&`im8hb7q5;+I=et%WH=z z`|7Omm6{LS-}~Xw2|qUxa$u+V1(|JpAxZ3sh{ko#pPQl|9Ul1qn;5{ zzy%=#rho!i3)R%lu0e4iB#41V0oGB1(4EZ+v5m*{y4P1ws+f)oH|N}GCN+LCRB4aM z@};_3Dx3~NS^l801BqPb-g>~ATxP00en+kv;oT|Rwc~ntczKV!;mFO$makV@^YM~X zn$a4sodSxFLE)^{O_oFgk?Q(>$i- z4KfJTq{XGtsE9~RIC=v%Vc5X%0INlxUN;NdOgub;zAytMVfPh)4;XokxEmJ|b^FXy zFT6u0l2DHUlxPA;J97#rKo*ju^@Chb*}lkvEORUM`4arY}I-c-gmR z_4d~T#^y@HS-9-xOQAD_Z_b+35>^En21<;%NIVZn>SG$0sxZp|N#c?kP$C(O)Jcxu zOjHK`P#88fg^2x?3ibYeNg23XxIo_K!BYLJw*XSPx%n|HdFnmj#n6#}M4Zh1RFb{}+$KMC2&noXNSXKNI)Oj_xrP#*23vlH zW?H!kCMJbtNbD|rz*hNL+V;X z+6sA*DJq_nafDg|6B(bQ0MTE-piUdlgc*7+FsUfn(JIg45R+D{PC)kNR%`dphHaTA zCb>U6KgG9gTZ_F+B6l4aH97!>bDT74TnIr}|2lux=l}e1$9`cMTb>FbS%uzEk#zB< za-WoJuu8CU!Izg>s-$mA`CuI=vT1@*A$yj^4OFue-Qq2Ihnsu6NlEd19ckXeqN1I1 zJ`1T}hbYA$z@;cIvx02pr`?z&(Wsih`8n+Z`cf7Ww)4 zv`~;&jac;YS8#taXX~#9F2<4)dz7spnD5SK~oSV4`Ap+SgsCp zJCBcE3z2)2^gy1tWkl-=R)$80)A%|ldlb1K)kRe{l#4j14qij7v`M6UKYD?|9to@< zpa3+9rXMDkMl!0Qi-B08n2n7jJ3Z(A?{?~6(}EkMtVqBHkILCaI##DQ~Q_ttfXPsY zXN1V`Z*}GNM%)JQk0hVEYuGJtJwNp*3X&LoU>iQjwQ3Pf}JX zMHHIgM~=)@WL@*H#Iy)0)>M^lutIhuEE3{@cnJz;IxTmMN(0?!DsA{cs4tPfR*fP= z?}?v9z03h7{p-4tmK%tyrl~nGeYFvp$(}TsRC<_nXpPCf0nw&Rf9caxiPi{v|BR#i zjv{lkPn@By$_*&{N`NRG)Jb(rZUSc64h~HaAZw|6!Sh@_(qqKC_6D1te2~<7PU3Ww z;q>M09n6(9d4Vb6;<#=HP7D8Iww2pRg1n&*$3H3eiwK~tQqq7tY!e=M6s4D2 zv(ti^_m10+TS(=^bhFY)6cUnTQ~l!;BoY!8u$gwG$j4W-Sy2aKubsWPR5Sa(s$vx# zEk+@3!kdDeY*jaT_gTP1QcWD;ewKi7x(0hVz z7zEi-IjExSyC{_%Q5}nUu#p3zi6^X0xZo>;6qB`h9I@EVZRu38XE76S4AV~Z4#-K0 zPgQ90<(qFCmm=g10VuKo^W$1{<{ zMVttcD6Q9qBT*fip4I$%(AOtEL$oDr)cd$IEV2V}l(d6I)Zc{;QGgKb*Y9T@yMB5M)fG+) z`u1&7xL4)NS@?4{E{5_;(vWChO}lSkzq@dD(qZpu4&hK08hum?50CkReS%QzYPlcL zigd57V`fTx0uKwc$TSchvn$L$P7%}-pqKx+JCRwqsUiJswdgrno|V#KlPCPj8iuE- zvHnq6u`u=om%fTBZ%hm+`U31{7ANZtr||zRdcv!L&K)ESOQpva%H zRLb&;!a<(mMLV^lr<>4p*<;d!(&4ggcza1mKZ3Is8G9;Ys@_wcBkM@p%ks1At;9tm3f6>9z@qwB(l z_1CR+N|B0N_^KQQAO_mT68MS6V&MJ-`xcHkyoeODu4Dd0@|)Z!m(RC|a1?(aq_`UK zH&|t)gvzOlG#oR|!#}M!J|2(PZ=&B&Rfb%^O~t`ECKWKJ8yL&kLbjLe9t5$%>z%)i ztxWGFTf7fjuzGy~{Dau#h`DHE)2l5nGO$$azq@84%P{~$YydFpDjZ5*gE+MX-2 zySK%{tM*-P+V}XQc0%3gRh_s`(S+ys&rf?0T5)r~2&tja z6RU)WN_zue+#Ig|F<8kkS6g#I%AKH1Kg*O>50+TJ0ZWdnWs1I~l40^TAQxQP>(MHz zRs&X%$t;XB*>#-eWxZ5!hKvJUhU}?Cx&MJY5RLdiI)2Uf&(ZY%AI|$fd`lAXlx^@Y zW~Tz?KiOOV_}1R!zi^xOzu>l3-Bx~E0^#RQpRp?B26P+&uH0WFiFm`USeC6EPT2<2Pd~RLPhd0>i^ImC}x{bB2W|Hf9aSb6>>O${fPh) zSV3S6VTd8)s+XW--y^VUxDB2u3j{0!0N~l&i8mMbOpb5#h1x^%q+=SIj^4osIkrWj zH>16S)*+|>1ri9otsO}nLaH%2O03q>{0ljRz~EAp*z>_9K9u)NNCcs2KKB!G<*aB5 zJ6Fsb8dFAqs5(D{=m*RD$bLwO&b;^M z;H*o!rLGGWnzISm)nqubkUuCSYCTDJIqWC5O7xo+scUKYVu+4d4>^P_ zBe!b+qvWzCkjkffxdQ0Bx+06lwq(r;8PAxDF7qR<=g;=(XP0swkj<~WMP?SIrbdbQ zlvPGHQ1-5dob$_504av+JShs;i}_|F|N6u#FmgGW*y5^PXJG*F4f!+zxF8CMBZ7uJ zP)GVVe9oMF@BD|ld9I-@uhlqk!6J^Da5*sl8ub8M&gw5TEfI z9_Xu6dDJfKW8vVx#1Nu2PX6}X$}6Sd?B$orzu)mRp-$}T>221uplV|;A=?co%nbA; zlzI$lFt8Nuf2$DZQ^&geJJyhGn^y27Z+Ay89L@vSl}Rl5&qYoH%QN8FbPaq>sx5Ur zEU(T+3#Fi7W`54sF|yLut)Kz5AGB`nhS_ikUi9DIG&_tcEkU>Ov_0AuDp$E|tRS&# z`LRY*uq?c8nvaVTYvdQ+_538Sr8M)vWM6t&K02>{*}HN03T3tQ`Yx6fs={7IJX_LH z9vt6t!{;9Tl&bk;|FZPOK=s82!E^$}TZsDA+f_!ti(*&*U=8fC2={IRSlukNaQX<@ zf5R<&`<7m+58~I@Rl380{4L! zm-4;OK{z`=>qTHXprn*iXR2hNiC2pZKK;G(Gk1@oa45GkbKC#ED+ih>F`29$ zyC^5}tMewwt;q9Pv!O${@ggoX*~Im{^c7b>8=!B_j~Y=N=x@#esi{?ib1O;imL&D* z!?_sEmF-fAsn`raLKrKtU$7F>)rh7I=FGF-K*(oXlB(heyRZ+lMVZ+;$qA#bj9z>j z3**BX3t$@9p@9!6WNKzOn;xa*3tN$mh{+X|=yx3vbs5gcqRELV0r}L9QrpRsWD}-* z`6WmPjUX3~A_9xJ@|?H^*;iLP4hI=Z+|+}9#MFxl9(#RL$Q-0HAU&ACYj|vmqlF~- znwiMi^t5Gzva^pYhyxS8KVP5L80$iE2qi6v6O{Q1+H0c-l_@%q)s?qzK)%S5M9MVD zwPt1qo`x>8<2`!VeB)FrxtD_8pEf#+Ne$+0K`8-p;aAlzcKVkVp5MEF@Av38vZ{D^ zOWzqEynF07yhC_%gHd&4JoV8(zneGIR|{X`-U;Qg9I3ENinSsUWyJM7`}xp5cfhQb zBYSpgLIxF~v}4W<32hW3t@;r!Ey;sy9YHk60T8)Gr_MPyVEQE+Ml$ zP&e|XYAUOgZVY7>#p)+%^wwD{c8%sY5~Sk!_T&kIfRaQSQD>bC!wGz$LGOD^qR$%Z z9XZTiYD5t|`&ar^ex)|%ctV*xAH_h4p)gCqk{P?EVA5|BB(-?X{!*u`TceM@3f6vJ zS>dw?ucJj_2t8stOdfbcQwmp~2w?EcNYud>@5sNV!jJlCw}7H;eDr#eVPzUjh`S{$ ztSVgj*j3O?AJdwTPG4Kg8?!bjYXXZ0cytPVkxBkVF;_p-j<^6?53NODKglwL`5GyI zJCWd(E|`Z{at^wPAz%j41*u&`5q4%UW<0XUf+o=l`I#eViZg0V&}HbMjcO4n1@11O zl8ERlMI4U2%!=w2F@9oL`mJ` zLAlnz1pW5BaYSmnrlKg9>SN`ti#V>3FAW2lEcB#UzZ(N=zyLbXn>LgMr5qgti9M>D zNG}uhSeew_WeNZ&ajc2?oRyOTD|T`eaf4spGze6~-eOyeGjJ6{YgJ^a@ z<|my!?xC9skZO(Hu52oCh;PWP>5WZg8*|obx#?Xcz?DgEFO584uE4cOB6T`YIx6_^ zm%gY!eOh1IyyKqXPTuv`aO%h284jW|GO?v_Inlyj)V-vXrz()R;Lg2Te~K&Ii{Fax zbIT>hV;VQ!dv{x)J&!aNx$QYn@?}LzdVjiaja^P7Hjt9dWMT&FY~2&_oLwO(jG^!T z98g`iB5?U@D>QGqMRRjc-A7Ll`>#BXoISuL$H5beVARrh<0mMXq*w=%aO?h2UQL|t zD6vRXyhRoq56nr>KXOdA7?ZYy!JRWooK5V@&1sxYEG9{g%e8v9Saw}N4CiId6iOy! z*xA+KeeJLLEAZ6IFPa_>OW^16P*c-KkZ6%IeG;i)^DsHuQBQh=mMM|N{6PI#hP{-oLjEW`A`FqW??7$Pb;D zx$uX1M&#%m|L1jiyc?f^fVKZ@qT(t+6}v~Ojqq|yeR6C9s?7-lTA5;uev$_lR2Za9 zHmvhjil>si-O*piUBg+0(~84lX4pn;*sx;x(W7h>Wl}@ZpmjnHwyur2vS{6FFOQKj zzWhNqoC)0j#*p*ks)ER6P?3Enwjs_tq?=%Hm}T?ZmGPPwECbvq{`1u2F&taaN%f*# zO^!Q-dC%A~@9ks%nDh+V>hkziw|PT%N7twNs_-!}AiDg_r?aAG|I=(WK0U+qcaEuk zD%&E(?rt{xVrPNY>hDbH8Czvb(GM%e_!+K^$v}DaKhJ{k2CyiCvbX9pzn9QH`{@<_T-SPYoJXRmt`Kwpqgo!+(Ze~*A-_q~kVMYWLe`si4t>1or zuNSindTgipJls??Qz5wu(N@%!-++r+QG>puW4PV*LoozEB_#0pWskcxBKan9#nktK zcKlxvdJT8Wh~{ytg^;3)djcm3W_s>72yWxS;9KQZNRP(R;BO2Rd*&W4WzJH`V7k{E zs@vfuo&aawt^q?@vogp#7SUreJC-gVjGkEUH(&<0$x0T@NG82LE=CSs>BIei2#Cs= z{pVst-(v2(#+1(0nNJlgnF8)0pl#@SZ`lPymGi)?a-0bQ{zF|T_ajfP0UJsxJ5Agf zE0v%04f+S2v`gvBzhf26);(~bB1eC2ofUnc?uWZSAMpP|;oF*-6va zh1JrTkJx3}U}c45&SEnn(gxEL2h2=eZQJ9PBvduF}R49=`b z!-)FG{j4M2f05=>g2{h{_?di8&W-Jgq8>UO;)}R(nRhk|5LDh0R{B7r5H{x1+s?!m z`+c1J`vd*|f`n=7VP-TO000O5|49=z`R_Sr#y@~?`X8gKTC8ciZHa$NJr{&y1el8< z6r0@{jw!j4aLyY5-V>t%MIf|MB^b*8vP9uvi9eg2H}*HGuE4Y5Cns;n8fabB)zwwk zyFWj&SRHpwM5o;TyrwkqY^(KnHP!UQc+4d!BeH60Ht1@yqXu-gj#qVXs)8Q7;;P4H zr~8zj^Q;>?Ha6D~!?3)P*o{T!;!H-B)WG4mH_%$EPwBo>wLnDg;UO}%ziQq!7n?Jp zrF!Ct%T86(${TN_HeOqg;ZNI)FGbwSNg!BL;f(_D8ju;#ShUYNv;(^2AH)V?RCWaT1b85M5x|m&=YF;_IHj3* z%E&;6Vd9CvVnHwwBDW||+bl~-1l~IL1;8||{tT!n;-uFJc*EUkChhj+k?83+t~e%` zJLI1o3tFj@Mnqk5aYxhE_zy*ExrzvOjg6TN2GE^UEj9=g6x^ zg}ju3-fTbx0lYDJ0*yBNW6WZV+uv65`qC3=1N~*( z(CX2OIK(Nz0FgWXY9P6l7jhX_pPg@G->`n^SK?j>My-(62h}S0d8Mxm_^$M2C41|R z6crHrxr2+5@&RZDDKgr#0M8nlafa@1$?Y_I#`L}srFU?=RnHws{J|1Wv3G@tg|RR; zIpj3CC21mwe##Xgo87l;W^)$7_*@&^;S+}9$VuckKY15YQ=@^^T2}^CPD<>^D*$9X zHoJ_t8+jIf=>IG|B*xa+~T5p4CLbCY@AL$8ZZNb(Btc$~xL9=`6i)ykaaQ z@!}S}f%l-_vl-=0QJBoayu2vzhA4&VDdr=iqY^#AH}EuJ0+~I>yLsfhv|N~$G8+3w zC{h1f=t`(0xK>ep3(r}4N6pt!d;RdhV!$qJD<`OFY14^AU9=!HaZ|Uxd4ws%gwRhX zGLoS|93LHJjvYInm;MX;_kN$J_v2$rXbIpr8ruH59}^l;?vt?Zs98a2Ouf2P1L;G0 z1J*CbG)75suqkjSAi>Sx5KJic?Rr(I2Kf_%WfJyezBW*dhIKWZ0ie08CBrBik~bkN zh`*u##E60!0)<8!&^@Z6h8VK2JO9)n^*6%J{X|oh|JagS`#gIL2_#-QLQKNo8oPyt zso#iv@YEk9O*DnsnI;NbyF0c%7j z!W;5-aRHIwJJ+Vfym+1jYEpu9r6Tuo3eP(=nv+jWilF;tFWfO zRYtjFMyMml$qonZ46>@sSk4-HBa((LP~&*V5!*ZM=ihxo{E>Zh^xc6X;NSUtr$y}` zyYgmq(Nwr4%EUD}kjFM@Nu_dq_`#J+jpRJc(^!e?tpYmvf~Aa+Z?v8*+xj3Jg(Q1+ z6k{|v&80wWwIN5)#mXTJX)bW?-uzHv%AO9BL)a}WNzJZbbSaSoVH*>22fQ2JHQz

Cnt0WB{4mNoZHSIO?Fh(kReyxXTL&1SHYv>)!gJAfFzu=Y7 zpt3;@d~ zK!{nL_Ytue*frca(opN0I$l-q8y+@~GnP3y2_*j-n+JeOF8Y=-@Ol!=q9f3LM4+7` zV)7<4W|jU00$B0qUAMjv#x4FUiqED2h8ZQkH`DSC`J7;sV4V3}a=5e1iL5;Xo<~rM zQP3fyWOi^dOmZDoUUH$9= z01bBBlfD@?!N+CvUax>D2;1|5xmCjw7BM6I>@!!27xoo1K`kTuqIl=H?O+JqE|^Qb z>zLFBy||W^H=fy1HC2TNgkkPFQafYUI;%dHo|HaE)6)CX8OubL<~>7mFs3;eaz8!$ z!TSgP$7PQt0m4+g*D+Bs_OX(%*Q1LB>1&K>A|$}D;h||F{{WqJ$Q!BiuL;2FUgxGV z;lM`k3_Iv;=8Qc|yZCl?$r9laoqF9`mBJ-eTc;1dT_d`el7d5LHt5-! zSR{%Sj7%v*BG9V~qoml=;aav|Zv>euxHopcg&3HrGTDUB{-2S1C%~* ztv(EQUpmZ<%eRRqWg1x94av|^Bmf?VrBkO^Dy`2)^hZ0Y0di5gTq+Z>19eMc;V-1t z>da1E@@9tnSfR8xklC`edxWqdgMLSfEd}oSI>TbT2BXXnrFuym{BpFUXs*p zX$t#r3V0ss8_6XUygvwrX4fP}8Sd`r8IXQ>GT|I)SCN58x0EE4gQ{42v5L34G3#9k zTTv5!gG8g>yeEw=$2ZJ>q5`(W1}^tx3v{B#qv#jZ54;S4SKS{?mE*TetJ(gw8la#ays}WzIu)!hW(&&zh`(=|!EGwcRuo+W!Q-)tj|A{9 z`u2R>8%4!wN3Bmc0qbE0BxlK;z=kK(tKXsB;3~|bEl-i=91f4|a4o-2H(UC!zr|{C zO)uNl4eP-Jj01L+ZS_?)^=yjMiL~)}HNGh-$4`;rcC`4;IzYl5Env9%5O32qKVyo} z+m>E8$A|h{61Vi(TFu@bk9N4k;W_ymh|iq-Eg2KF*m0@}S>LJ&c6ea5(vHfR0w2^; z%f(n)z_=t_Q^iJhDpKGxOinKHW?e``O4p^o&(jnJaAHN4^6)&61MLB|8!k16ZjArH zZ!5b7ny?`AVrp17#n@M@ZHjSC)J~*6^?+8(GT=k+U zJcOW+H&q*YtWAvQ>PS>P#>+Vj7ligsJUx`d7R>3c7zY&Td|<(D7V z*h7oB5_N>phD6_m!#8~o@O@(4F>f;B_Q65WAI!(xR5>nSpU8&KH+ zgpLs9w`H;_7(g4QLYg{r#21ZfqbBd9m^g{%q=IJj>~C;m)R>-a6_Z=k2N{p-^XR$< zoQtBHnQr1Py#qB;_UsZ;<=R!bc3@TlN-b7vTA2BKHK>#el0Xmlx@@js@j#ZjM5+jf zu9v3shJR?{$#whtMnT+-7SAuT_uBM# zm6N54g`3!4pH(K$HvHA;0U&oIlSBL+u5cJgv5#|As;w<8gcfHcgkThSvw3AfIwWr% zbuIW=qF*7Xn>z)yEXd)G)dM~eO;{~PK0<*FHWR#tsF3S*C6Z07bef|LjS-d5Tq_4| zyQAulji-2t#e@TyMXIgS$iOByu^r22&Da{FIlSn5tHDtsn=bS&n6rHfa0!(RTzt<< zO=S?IQ`n7C`7Se857FiOQY(Q)@ye{3zE|dx3D}?3Bk@H317dt>PuQpA)o7}%oRM9P zmy;-J{A{?DyT?cWZ)BvWU!ec?u+INvc$od%jq5)duKMpborWNoUaH`Bk)?_N-q@_9RZ~MJE z$xF+wB@CGWQe@4ChH6c@n`xQV-AYpxbE{bsO>~n}&m_riwP`MDRBcp^SZ0M_7xq} zR{Fp8>8HJyo663nefB>iNMEUEKC`KzaT zUU`GKLu&U`XyIV0cvngRJszo3=ALCH=3vDB;c>9C;iBGOU0dWkk6d47=bUf;&d$hO zxKnj^7t2LEQCak8^X%-<&0{$S$QpTgc53i69i~!INuBJepYi47_yp?y5^B_MsNELY zH&*xN+vzu~oxP?fbYtoo&hY$AUc)MeGGk1sXvoo3vL_Z+cXmwc=FIbdCKNAbKOr8l zQbq%sJ$Vb$M%|*jS^U1T-@(mMHYi0~6R8gpotttit_W}RZbu$d@#VElQTKVpNh;V& zkQnbQkX15|zGa=XgcZ=)$b^y-bUa%4#zx|{?2#)~v20SD$O+%|RwF7L=0IM(^`>%5 zQjStji4r;A(Z1Q}4-u^Rg3uf}@ar=Hc(mK*D<`Nq(;61>(jD9cjLXGGix=tKw+yvDSq9Zf+{yRS{S*Tjv~U;Ccg_jz81NN26zvTQy?S9ANZOPmC|;cYFad$_bNvI3o~MSp%aIm9Y}#`2l4K8l!1M=)V|JH-&S*u+<> zM*U^#K)lgW)jDwSCAjnpTfjUJ4miFf5;FFz(FuJ(_UAP3i3Pi}?3XC}AmgnIeC=jW zyg%GMu3k99hYmhA3Ju{!n+ki9h$}hI32+GIHV?;$Ult+9JN84Lt%&DA^nAw7<7ep} z>j(Bj5>D&nJ5^?i$j`@h@_vuW_cEKFnRG=se><0bfeyv)wY+E1=m%R1KN5Z|yom;F z^vQ%l@vqt-7ax3k9o`j;AquNUTZ!Or}$S= zl8yuE*dPoHzBG$8`o}$9H~o)?Bb{a$pA(b6ynmk}Rieul?-_p<)L3BqkJOcGF(!>@ z+c^*}KbJ2}lpZhi#@Z}WUiT^E^S>T~@|pwl5?A9^n5C122|CK{m|{2DRvPx5jJ-6^1NUpn_JWtQSy>o4DS2hg%LZE$ccm6fX2nah18LxVIgsB$ z)mpT8o-Q)GkRE5b?{R>)W$ld|^}gA!M2WrbjeFr5ilQ}yBgWws@8}C$Y*if~_7vst zQX@uLd{ki3wIr~kxHV7)mzoM9O)1woOSNU*2aVfi(I+tWXZb7+JCg4mS@5R^-1Aod zc=L3(RbzkMSMaL8-dp^=+p1eDd?82POt$yP&|G!GIx=Y*?;x|zV)c+1o%s`V+DB7b z73n>vMLVf)ZgU&R_c0LK)Sur+4f#bqLjECj89r6bZp`1Pse|4E$#q@L3C-?k8a!@J(`a)oU;2hmfEzDpFLE=ur@oBXQc}xt`)<(w*@pr| zn(S~NvdIlKH2*f_D2J=rxNe&uS@4Cmw;5&i*}tM)LiPmvQVh(VwITPVDBY>b2q8)yb@FDDl=-}FH!4fyAEyU zr7Ez%L%4f8F_Ah~tu(Q| zaNhfRcYOX~*i9_dm&8+I7VStLTh;4?3&awZ4-nWaS`8LtpU(<^^0DB^b3 z^niA2Upx7?NcNdAoL9tN+U!4LHR#!LfBOz$Hjx(pM@a-C}KjNS&WXl=MM?mr zH$ZE5U>O$UANsZJis~sUOyoI#X)28{0Vxj=dExFZ^f_b8j*J ztO(EXn~yO^6b~H&vA>Z29BbH)nDKh5@Ec#}n&BVtt%B@J(5uUE-HU4f~`K+;~sLt!1vNtDem!U$y7#v96kI?&OI( zTH`>sdH>Ma#B)gss^VsI0#+pGSjcrXe1rAc* z_GXy|op5JeT%i+PM(}C-DWac|U97_bzyLuvQUq};R+*m9JS-18h&h*d+Px;7cWli- z^MZ3-l#X~mE8?lWWr>^E8P#9WZ1uppI9a1VP>(Oi*cb zmkV$@ZCX4=0dy^YpHqIK?LG)9zTae{EAvGn4i^8UU~?wS4I>6E&V)Nq&Wi5EFqN_9 zU?6oN1DpL&I4>qiMHBj1f*{^7If3fqqdw5s)g+KVJ#_@Odi)fEX+l%*{Dqz&d&nwt zt|`}W^pQuS;(BU>#WF5Fs7L4Evl2^d7D5UmQ)Uvg@EHMQmX*B$`^CX9f1E67wsEm% zu=!a8x2N>FL*>|fRChw-n?c|9==jsqB)H##W$JkfVczyq#M8v{pofxew$9(F{PC$o zXEc8N0+kofPWlQU#|RK9L#arv;hk_J+c})MtMl1D8v~;-Dv0>{h_{TULk~J9m0I;3@Je!$dbHO})V>84fmQ-V} z-2gz6%q&ToJiY6Dg0Rpp^j!^%#tNF?57*A$Q9nC=s^EA$x&VH5%=BYTKH!Mv5FMj# zMgS0K1Gf0Q;|{T#>XkvpB@+}F=szIDi+EJihke;jS*L>&gRwyZbbj* zU-+Y_%V78_j@!{DQZU0>Hb#Vyk${!xo=8#BoKO?^PVa2-PRNfldAuZ;*4`WPU++Xpr)-+d;-a(Cva9 z)<+{oZnWVSUO3uOqF)w$8J{qAX*`0iFR?QkTY}!sePcu=F+3hSBFiT}Iee*+gTp|7 zcePeGzq=vJu=qEw*~?q@_^rLL$otqb8_CV0Lr|6u_oXuuY%|j9>%z3y(5^_)tq9Ps#SafAPAfOCQJ}zJ z_`}n}aRoO*yJifmr#wI0A|bnCey+n0uSn6Z$j}YuJK~y@16l76MNrcr#7BOZ^hzxH zAfYZ1KuBMHigyRdxvHiL-Ne_B9O_#2QPa;@-^l_m70yrvPuZs9 z7Ic;WaOlB~&aVC}_T-kYk>?;B55F2llLM=#F7INhq7)~}NWBZns{5OtmlKI+Fo*lf zE!1<^_y@*1p>5?872fS>l?+TY5r%cMlF2z%>Q6d`?ZyO&Ua29%*HL#Mw%(?A8TMTf zC10U>Ca`V}n47|)Y(x0{fRHSuOFF~M1hQV7X`}DoxWT);TY(Ll+JQd{XBrzHVBnXZ z-HP=;hNJB)vF=iZ`o~c11@4X_gHnk5CPy7?mYws769J$11QyJDMp#=^ak!fIKtq1=xx0KxctK***rV1EuDmJ52msgoEdDo-`r8RXy!;3 zYl-Htw|zZ46jhN|-9bS1Jhp73cGNs~?32FE*%29$z6D+jLI?a(n!HsWd!9E*bQTch zTWQSk^6}l_KGQ-%#o_1w_p-P}SSY9DieYdhdtjgkge?$-oGaH#nu>$vTRQ=nd4-a6 zlq7xNge##5L<)^E^@6ak6y!TJsJ}765GiJZ%6l%Z;2ZaASG8t`0Y!C_M7^!>a}*@s zMg?((f?8=+#zYxo(!6h~=EY|@iqm2nD>|_ptYVJL>t)Pob)GbMl@_9)@o1gw-;O#{ zKm@5#5REsHkj;k2ZkbHtGIv%4v?sPQt>T4l5gX}-PtCIKMq}!IFy7Tq0DbgwCZAhv zd&AwwvTb~X+3AO*_kmZmH!`X{uB{di7+%~dX0i1HF1`2Qq5AgwoOk|EqIJfD?%*13&xU2bXx8mA7KzCUHC6j-^{N{38nDVbj&zp@)B)4j5T@2|8OU?4LSfsNu&|8AD;BTWWEm z6Ung2>~yQB+YEJ2A#M}a&1opXtkLq@o>P;)^Cn+jni*XI>7$1}JQaSthUYx4=vfk| z6kJRyKVpIxt-{hza1AIS_Z>=7`5}04vSR!=X%e3Idx%kmRNBsoWp$Cr5`?^Zu~De8 z1|McTgH*9Sgj9%rN*b7$=_)**){-VEeu{G0ATPLVM((uyum!$8D?q_NkLx+wh2~>H z2~PSOmuU|63T{VVZNHWbT;EQk14)Aq@9Ys^lri`+KmX&z*X19nA=M-cuKXi4`+ql% z|H(Zuv$Qe&uUg9fU!b;%wQYAi_R{$k1qm2jqMjz{c}tSk3J=RBt6+m(u?tjrY9+q3 zU?h~N<zby14lNw~X)p-! z{!)yju6h5iy*Z?uxiQ{}G6zXKNs1s82Dz&9h%vojLA+Z_zv9KDJ1=@hY?qBP=jrMF z{mADMCZqY&>q`o51r7VgGt>Ev#cM^lg?jr!Uel zT~w)qEnXSycUuqL?YKtimjMh<-)Zb019}h4(S5)V>t*NaEBoQpOQgAx&mEckDmK*W zUKEOMHvR(31Ww-0e_3V$+ynGW3~nA#AX*9570LKAYdmb-aQlZ`vL#nz4i)UXbVjsF z9Ba^=5YL}|A%4X-HZz~Ly;JRuNwcBbAeMIqv;%)m!`GImNQ_m|b5@5XBWNO8rLZ@FPHzpCD=60+c&LN0mUJ2z3 zte%`gGLZ9Vw>WM_OvxyeP}!JbsDoXAS2pR)qKxQ3f|i}?p0$)iekChUZj4?_=iBg! ziJ0K7FOa;C6ibMVnP#2Z_Q7any+q|lZ4-r7l2}?3Y)U7 zsEXx1joM3uJg93~bSVD|z6?TJqdI+xe8K{Cr~aidg{n`L5Fc6G7_z2KsR9iRp;blq zHt+sMwF-AAuWL7*w^ES!THeN>USnLh4C&!Y1tm@vZh$sJzn(CwL=dGlQbPj)TDi z4BOOOFJNPfBto;)0O<;Od5z))5VFcTbUnJVvoNFTIzlJpqmQn(x_NgjwpyuJkz0Di zX5d{PT5{5dju;3Ebr%0Br)pta+_kwyJ)5d`=EA%XUMc>-w*wYYo0Oqpe-cPyEuBws z$r$(-;#MY^FWbmU0c9Y-vSLY@JjpoW?i}iMvKyb*#l`={<(a4KI6|sXKP+Y-UvR<| zhJ)5;#`jm<3XYFpK|RN&6;NzhiA=*dW@L%8!#MjZ)_I;mw zj2n0|p564JLfov4c}tGf9Q4=nVt=q=ZMOnt{hERCA%nF6`ZmZdD;Gd<_z>J^$x>mh z8}}3r8%_|-L%`pUTr6A@Z5N93sp()-Q zC^`M~$aN&=@oOP?a^^bBhw{N^puDU7i$|v`b_q;%WNHh=3$UY!l9i6S3vQ#w%-Prn zHn?v-%OlD{m2HjMb@~#n1YP!z$TGKTl?Cyp;!*~bO6{nvsV5y5tSzR4R>U#-)X!0+ z9yM|3&vxb=QOE;#+iX~hZ}3LwyS)+(bV&=A-X&Z6g>PFvP z3AFj~UQW0cXjT2zp8j@>l#|12{#;$X$Yw<2s$F&49#fVjwbdCRy0JQcQiG}hK;R_q zKIP)4hXn|aW~EAsY*>p|3>t8w2CNygss}3De=dPzmD!G$lLz=WQ>&2OyvtxQfhn6c zxyX_Bn!*#6Bwt2?^qDbVCdF*ZczSY#@wsRYLZb#n<@9>h1c-{Stlkf~y|zM}tA_T; z79)zL{lcii-Df>_X0B|T05r77|L69h4BxQLT7EK>^g zm9j;{%~nqUB8vM{F!Eac`iy&O&q zGCG20AUjT4=E7h4So!^(s^E7&*Xn-pZ#)V@Ox*9hmAIsQF!USLZmzMc$&{u=t4|86 zcuwdXLqPa#-2*H;G`Q)if zxYGGmpmT*iJT0QR#qk|?qItr0rU$sIR^A2<4|4CPGgxA(DjdHf#TfqE-JP8QmcTYr z{u1Ja+-zjJpBdCedmZ;HXfGUyRAm^L$h325-)W7T-F@qyyD;#<=E;*2^rnMdhg>ow zsEJ7}fBJX8zO*;cnSEG73dFB+AReiM>)f9pBvAc!(g(TRy8h+OwtnWETL?&_1h$so z^o}4tlag}*bIS)0S1c&V{BsTuA?93R@;uW8`i4@7ceb>PVuyhyEE=lO;Vdss=rJ{R zPXbUtaLlZ_O3;0V5PE;BKuQl*kPnk>3Yg0b9DwZeyNj30QPgLsn;2akU9X$4!&F&b zKC2U}DOP9UP)>{hB73rs%Gn3=M=~1)Fd0v!|BtJ0V2(xInvQMTwr$(CwPV}1?H${; zZQI$gcbt4V^?r5lsrw72YU-J_db)dc1K3$OTTqR=h@sa3%OOXD{nQY@{4MWee#^Uk z!J2)R_xXq&yI21@`(wTIAz1Zdqf}qVf-}Xb$u<1e(bD5O#m`f=;zzlf=3!$D4tj+O z{diK*@~kXMB4x#WGm*p9qCMJXR;eF0r|%+Q81h9ZyEbmYp_O|<{#DnmaB{dtX5>F@HgR*oHJnN>-FzVD}V1dw!jzqf3?Pc@L(LCWWnH%)@X+Pe|}kW z z?3(S_hK&!Vpj2xyON^uij1l|x{tTKanfj?dC8kcQB-M^|q)JVkc2*qA7;lbrM`*LN zWe!alt^G--p`kkkANDiRqM-fz||6=bGWE zc#qb^bHZg%`;$SD?%!Bz=k}<53|fU>ch#d)8ldt(ATXd1EWX;gNe$eahOR>o*VfqY zAF_BmW1~SAWU4A}oKQ#c#qrJ2d!V>*xs(+{)Ban`VJGE%Oh@fu#X3qWfm`A6gc;0`-I|TlS*l-V}{!F`C}lrhSPl1$i_yuBrg$Wm6Sq4m`%GzO7tne`R2Z#hk)_WGf=zZC zK6sf%*a)N%@rmJp!Qe??(!CGi5OWre(86AXg!#@7P_Gc+lqFd6dOtoUYyGB68SDxE zqHNsJyqk^%LD5AQ3Mg{a?48mcv0|G>Za1P@OvaaB!MM7~n4WWW17BcVsiC12+Sjq$U!P{MrH%7;PKO~vPYC4_zva^7% zXDzUUXc-`~YzrR&embUBhQwxxWV~r=;vyn$ZQXYt3QA-N+1FAWVFW4A{TjA1y$6aN zC4wpE_SpViLh6_zCOE7RDMe=){HJ&`Ibtv53h2 zx{GfFmk{ad{Q`|+*BAS+;3rin7+iF{iFOt_50}-Pls-cg!;|x5>)bNT<@M_M)pvOL zB%qGZOjY0+zVLxi>oplA1DAsQaClk*1MH0M5nx^}@-eC#)-5yS$U18dunVT{o^Jp2 z7TPxfDUPNj(kRtpA8I3_r>0>W;L4>Z+dzwGlswkFBL&9Uv_B0Z65oje{7W`kWz=j! zcb7>msYTt2>d}{&5jTLDn4GCW+0lH9DL&6xftaI#d*f2l0JY!%b2?aQqpsXUz9D%@ z7)P7@CVFwV(NP;Ie;@pb%X1`o;ctR$l!jzus@NQtt7&aq+%MiyGGZ-JJB45`zN$y9 zFaFpceS?>)rm5qOgP}TBUVAPhdSk6V!{kJKdSA-x1PTy;H7Vy15v(>nzaEFrM1AH9uWmLTgjgho7VOE18hr)}s(o2dt*G^r*v0ZLiH5TyK% z#NNv1S@34V{ssV<)ObxxVVSARa-E2E&yAK>_;CJ<3h+2sgK)?d2}sf~68|BRI(RI5 zzeMNQ@0U$~2UvXajP4tHr#o1NW}N<$GlQw{8GZmJ3(3z3N2&Co0gZR1(7adT-==&#;FePDdvV_# z$?rY89W;2gWzNVWEiVqE{RuVuq5Q6XOIJ7YSG%t7^x6IbhIq~~()fUL*aOJq9^-Oo z0l7x&lA{LN06mtWFswKkz`<`@)~|NLdUjoDdCaOYfb@C$u=SgxEzAz<3D$p5UmRlO zu=N1e^Dn@wdpDu2eE+;GXXIgZriAAzGxZkgWzXTv7UDzF}4H{d?j)1eE%Uy0P0+Gwu>W#YP z#lmr~Ta(YQ#M}&5p-xmS+*@8BS6DF`PS#ru+3q85%rlLCmxR_TGmDzq`K(g9!pBKL zK6FtY#&FykXDAIfv$i^$JI6CUJ#fzMVJ=Z5mLxs%!ZstN5(%xl_RjlhFg{n;pz4dg+0Y%8(LiFy_g{8r<+$4|@IFib>J+C^@Er_9dme zdxdQL-k;sdW%svohg zT)ipgztvvc9^Ye$`Sq0ww)SL*Td;2kKMB-b?=4{=KzB0DfYFkV)ws&9L?H5lcXYBB za&4;Q9`4^neOX4n4tEjZzy5V}?DB(s$YVJy0YL!(u&@9CV1BqTYfEQSN5g-`0O$M< z0=m-NjNN2I@S*E95-=fztOp%Wvtf$?YVv>xETov@%RCQEw5-L-aFnoY%p&+){gO1N zm{4;?A1|bMo6`z)$(SVM#DSeY>@Ii42CHtcDQ-28E^lTM9MafMZU~hvooumUslwjG zVuG|IVyL)^2D7YYve967+@@AU4?(2pHnX;ec!f1VkVqKw7oU31w?+tD`t`@=P|I>a zd>f~eAt!JE?+R7psYba&#q}0G7)=L62*jjIi*W=v;q=cDEYDua!bLnZB~-m2IqTT6(nvHyT^9{ijR2|D^&bSGi*8BKU>W)!rh zdkD=4l=IoKg`+rK(=&plqY5ZdL0nZ<{8-u51hp0x6Kp<4bi9Pz|0rui87RGAOPm;ulklVoD}m24xg6(a_B#5P|eg|-pF zJUf>hD<(de{i|olMz&{tv^Q}_1>$`1)}jH=AX>?yu|ku@D?{z>T$Lv*?_g3hRfo;B z|NIjFLjqzIz_MRF|B=Ag;M}`!#|YFVoP44)n?B8KuaE29ai@4@&aIp~d6yr2+%DyF zlP`+xXB!7UTCHl!Th;kkaxk^tdJ7<`Kp&E=Fc12tqsE|u}$_ftZ`<(4(oiq=-+%@_Pc!s{HPdEF8Q~1wf zNAL~97Mv_o+1f9Ap%9|m{Uw$RK}@O4_{gR(WWn60KBGECty0v)+Mo?J@QAi-e|9lD zT7I%$DQb)Ab0bSoKF63Ra!_;b`LbTfYe!p=Y0=ywepy2dER@PM1Ll}Q7W~RKS#;*u zrs}Cy>4uYTP-s?-)=4{Lv?`-^)7&;piEz2r8CyI)0ioGn0rZFhXe7YGh z8J9!?eQV;rwMHdE=s;mq|Fo4p!VF@MvKo#DQV3%cW8!JfL>Lo~7w~%RcD=eoAac%7 zoN9$L`occGNhD5Va-Bs zz!Y&qY9a30w0KdP+tjOPEwR9apaRkl2nrXvXEk+FioR~VCS9aK+W_iem$(bVwYTsi za-F!gTzgLYP2PK|t8y61dFA&P0q5*y0a0)$7UNclgoxW;e>fgNo1NeR;x%B4cn|4HA~txf35TBDmot)loGS!O--;kHhEN2_dDxVZ zbHwYLv*0x1mNT}({XBlCJTfPS*it*g3HtjJ0;2A(5XGzb0hx8&`_~vTj~gUcqTKD? zG^=KX@*rWZ7yNDK!BT)J%{+ZyuR3_L_SjOYf+i3sezU*H47%>J4i!l=WzwS@Th02* zRADA0V240~m?=gH)_T`3hfYZ@>CC@rCUji;_j7G4?n$KInUxPFkT82HGKBJ)Sm9Wd zC%a4Zv0PV#h=vR+ta)G@n+1sOB=tB zsQ#XKeBik?e(!F#%rLg1^)A_TFF)!*mJ*Ut&$NksM3l$)5QUDfHd^->8_K^$uuq)$ z5Qb3mR=ozHtmQyUf(AnFsFb$gW2mgFixNJwq05pvV#-EWpGVjQJi=b+hn+~Nc6)Ts z+4n)lc4P3DQA9f%fsk63h#r=OrC&NIWP$T-c-IX649*;NO?5`y;&SP7jJ&qa z))lv6I0CEa1oW{6clO{jZGeop5)m4r>hg?OzVdo}-n9sQZ+SH+ay+Y$=05w zmo@s6K=u9q6R2zqEp7k9HwnL{iv8Qy-mL!P68mRfsKa2;kdUPstPkTYRJ7)9ko6bx zY6=NXHqok-s3b^rQDpA!U@9S*RwL&Nbc}gU@7v?;@;pFAFO?{f&sEbVV6;p2IXH-k%(EF)OsZ(&oz};C7ba;1g|tOEB;3INHMiD8QOOO`vnK!0E4cW ztB8;t0tWb|iS1F}5zH0;cmjgCXY6E|(zbV)&uG5B-Th}e5d|j`Am3KXIe%c1HJ2}^ zQY-L}TxW&9FtDoHFr|bFxPZ|aWkV>94ASHi8Eqm+9N?XX-|qx?R*roe@=fCL>Akhe z#I7)j+Wcb@)N)#u9Mrhe3dy;Z7IDrkTz(f+px9!O*O;S| zZ{I)~hjNBZjHXu+H0Nsvt;@5W#edS)k<2r5n_-rxVeo%`*)mz&4rW+J9L;;a9_c=? zJQ&U8Rzl1Jlh%TntQtb8U>%`KPmBRy=0R#}TW0$RE}PdvRfcF70w-H?VK~tl$!SmY zf+yH0EZmFP51ChBG0{C)dNeY}+(k0|ZbT>rhM zf&p~cyy>wUy|&84Dfyd-h7S4|t!~9eumm(m7!e6{7lz-t*+Ko?-e`wQ3Uekw*po*h z!gvJ2VpYQeC0Y3xk{<0G=6t%*StSR+obOB8mus zenIyoICogNZ7l?a`xJ(37}#ZoH@U!TASfcwqqZTs%Di#u)=hr~ZUXvc-xhCbxo#bM zvS%!3lcwMZ!wGZqgIREE(fW?Ed$WBg=1Yv{d%yFlV-I4n2$Yp31?INEA3`|#=qj^U zfmX*VF?-tJYx1!==~y;*f=@!700?{SJ5V|kJ9-|v98)B& zmi>;nRKr{|bUd)h88=$&KoX`RTe;rE&)ePe`yy<&fgyPR0<8CUR7z{mR>!X~yx2j23A4 z&y1@XekIeIASnS1Xi_iiGR;t~AeVfbg){Zh)YXnmHwv+Yb|dqt zp2%=3#J&e@D?k)(!u9Jl4Tj4${NZ((mWsGupHWtceh+x~nA6`VvmNTs`SdrfO zKMpa<^R3@kXQsvXmH1O!<6MpfJo)LoqQRe-UVNNnN>*xVipO2%PeL3;>%be%q zU-=YnKbVQKHP_}H3;=)^_5U*XYz&<({xbm!eh|~Y!_})b{$boKB>K~VDO6KC z%GxroG;kVGBks$u#Fy5m4J;;|itIml|Awr>)qe3>*6@&Ynu3b$bOw{XU8BDBh~G#k zONdt&<#CPJ6J5dvkQq#oM&2+KapH2mLno3z6kkg$Y-IhpWWaob;0cCuTwUOv&+i}8V=E1K?#7rg9PA1#@i31eH??1(3o8_>Pa8) zeUv{I%Ag_CfznJzPp)0($@h4Id3TM3+HhIUwrcEXAb*ZL9XLO&K>Q(FkjP(gfBRl$ z2o_v)P*8w_pYr3YZ&qfSybE4y=5;9$)^#Pprk;tQ5XMZfGmo$UBycQGXd^70w62o7 zQyh-ZZw|d_jzZExUxWj9qn;@`wQ>^vB8H(lfV6ITI|I89t{%p%Z2T#VL@;Z22D<{P zM4a%6CQzZhysn4shgV~aMP-x4ORA7N)YM}gyfW?xM}3h zHU4!^KnK^Y`zV4|Jr=bb?gMG>O2pFys-A0##{pWuIM6xP>(`Gd-kGtvnyGhCJXCv}ySCv; z#CaB7b#+?>f+L%j(lGqGCo0rk3)k0sNmw6*jWD`Q79eb>hE75+WG6&<0D(S20-nN2 z$s7~!bcM{0J)wEn2v>``r3>08+!WGzBGTl?6g5qB@I$WZ?nF>RN%-qwDH*S$Ww%b4 zGEtQfRqTcqs6Ts-*zCArDO18Gmag8vpI`V4ay=r219KiG2eBCbfV+PH~pG=&)X#Cc-R2MtS0T z-4!Hen6_arMR(bzuWCm1TR)ySzrs?# z3r^(oG0@K6yK7$3`1faCi>Klg_+&M!9zxn-0~96kRN_jF6Rmb~VY-zc=Jf?~Joc`C&{ArO+`cpQj{m7i9~zgD%WZ_Z27=T* z2)0=6;jj=ce^S3r?r=QGi70L7N^eBx_oZRE)O3sV*u0q9JLH>|PFJFLU2-8Ax@zva zN{31IovXZxG#0B|lMk7Pep z=mstkoP+UE#mAmzZLvrx5#*y_nO_eg&hBPv@{LYh;S@0P8^xg}+#waYcVeSwhLc~S zt2j(b?7_%?{$(L7$3Nk|M8HwvY?a|2%{<0o2lW@{lPJKSx;d2fUMUirDj|Me@({C` zFTtB$HLEl$b0AH?IgI$|y6&n3p4GFqD}_F0k>+vCuIX28OdM>?bx zdhjP@C6(v%Q4&oz^uMsh?+Z)q1k_Hp=(g{BfgOEYlDb%p!e0>B_kE&HRQ*K+=YMz4 z#aq)%=Abu&4aZWdfy8jce@OF^u5x^w4ks~lPvSua17x9Av-BlENeb0xfBzVvprUP@ zmXbvX!*Z9J0zr@dMA~bLd7M4QLPg?OPzQAzmtn-6n|L}06`Iq%g&E=%d#P=4st6(K z2dKblRb2cLJF|m2h&h()z!h$|pr`C8{R37xq)Tetm_mDxQF#mnVEJLABdV;NuUBZI zKmRHr{%32>@+S>y{jdy{Kldg7G&9(mx;wiXI{s&I7XHuTY}S-aI^aP2If$rD zR6l@Mv`H4*#$``!DC_p>US=y!Qjr zQ*!NZ*aQyy8-noXMy0fKQ10?UT{S<+_>TGo^wO+m8}D({FL5nIiWwdisCBnS=5Rm= zQ190DJjS9dCSpmW)$NT&YkEFk%p6bvu;3sL(Vs$Z+M{Mg&HuywZ5^qC z6}lQXVj6s$Tp5L@BVF*@HI%xoNpa5-P*;l!e8ojBv2P?k5ZrEk)Ujwg>EP>&U zz^$4vF$36%c1d+)=q6aoDgp_|j*x8rta#z}vo$v^Ro@EBh(X3joX$9x(&yk1Ms^nu zIOW8G#B&hZ`|bGBuMQdBI$*X01UJ_ErH7D*k%_>c`K?@j%NVy#aKI_$ISZ=m(+b;9 zSpxEkbYY7h@n+J5@TDx$rgtNVSI(bv*PKwi7GqZ0@?eT}PqS&SfmJ8X(pq8`2+w$+ z4h(QLYuX2;^@KMPDDne)i-aF-@-CQu_5EY0>Fjo-QqW}w#fp(H!7Ye zZ766L8NQKKWP?b7D+5J#Ca4$lXMl!7(C+~%VM@6Us(M%uNnYN0@6mE*%~>RmARlGh zJr&AEXX#}g{HunGFaS7jBR~#z2jFJhBsM3NY1I#?O&%`9R6!nf`DI}^n_YnKE*F6^ z3IT2v+xoaT`x%{4;rkT!2%-YOmp-4gdp<>PH4ji)P&8+Xa6T$85;XdrSE?hK4lJ}hqM`hJbf#J{8FJfwOAsNAJ};f9_`@bacZk(=tk z6&&mP$5<=Dn(%ydn{;(KZ%zfu3df)&OmZ@of?PzK zYB;PTs`7_gSh(~Z&P=>*V~{a2#5GHRmlUE!7oHUS(v zG4?ccq4CE>dKQ0Jj6z-HLH~jw&fXb&ydsY8!W)Pzh(lno99`E}Bv(QxpD89ouK|Cv zQV&J5EI@C{H-yxmk zG&kk(X%VB1cs5#7DKs&F=X3RH;NEL!(2)RF3|S{C*r$x3yfiD{GW>_cuU7XKzNoG- z_&HN*vSVO=-UB*&?_HURJ^IhYbcr^i#GE16aAr1O^!85AP3jv7ZXSku_C8EwDyEDe z6d}mBg#Nt7xUgD!1W8zuxttAyW;k)a-^ZA2G`}>bj z6`XEJUQ~H$%n{=R5Y9}jq53y&yPUMR1Yw`xY?-)F`=CP|5%*N@owfI0Pa~0a(VpDA zT1R1f95w0Uui3~+{nw}$;x+vY)?RqEu~#GvNB^YKoa)I_G{H` zWX-r=vWpra?eIwY0B0%5N$lz++BN&t9{mow;+}=;m&>)qkY{cLG`l$=dJcmGW{e{L zP1zG00lDk>8edJ!cM!NJZYc>~A+N&ttfEB01lyT$`-&0V4hW@IKXJc0iDV7eHx^Xmd^1UIZF-Fgo;7pxhN!ze`~JeG-@1>M7a@GqZN+zh>rzS#{U@5rsj>5I@+ zfi?m#k808&7b~1220isXO$m9(2bvTaiFDwaw}z~Io({`7c# zsjbc}%j;Z^WA59GDqm3&d8v@AcEx&>{TM9apblIhyAj3>G5iq2`F{Fik{jC@WO}J# z9%8;7#(P@-Kn$$jfnuNkjyMXusmMNY?x;kM zJA3CqF~hUmS{S^+Hs{Yu2QJd5n}j`Cpo}<*RCvlG;Ye!k8n@zg?%t$hx*OTSsM-ys zE)2Q$9YeW#Wl(lFiUpF_meWL%3Q()Cv(GI#=g~8=@dKew69&5lf+bdoYiECa1Nm;n z5G?1OC>U&@RfIM)!8IL~zw=Axg{OZND%i>sgSb;&@3Y&JoJz14m**=xC@ComT^OW-^SL}_3XC7LWt{6od!_u zgE|e>`(*7W>g`v7(Kh%L^0LOn!~MzS&@jT%@K`j^ zaTAhoY~Uswj|g9w%XZ@Dr7r_MJvG(ebYilB*O&kNsttJ1|1Y2I{)0ao%NLutikTge2+HO+<>4(imX(N)*LLrn&Wfn}e55zSviwEepb*=B4a4w-# zVl&QMichX4nTdPS1LK^sv0Qc1Dq$}HGeg^^&vju9feHI73)S8*7%uhJCYhEPHwG*UXG7UX+xH1!QTkIf- zRZLx#xcgrlVjjN(h*@kWjBJso5ov*-vG*-c!c_`bMLSabAQe6yq22?}Pzb6AiM4#7 zt=PxH8;8qA%tB&iEON)3m9+V{NE7iHJsifX%xb?n5~ovW%dl%51$_R1zdDFc7NWiT zDz!UZq)5D+NF-Y`)nwCIm)%50sPouFR!WSFubF|2L67rAdkq}ohvE`IA@iG)fy8Qn zO{B1J5P@(ZiH-{>1@dF#FNTo@j%8IP(a0;i_|9+eqBu@arC7bK>a`uCKfloBU1$cp z=O}ixN#-SLcj_yaH!jZ$O@?K!HY1~{GvKMy8D|ZAz+b*E8Z(LnZ1jsb0>0$Hl+8_O8&`U%OwY`=sK*BfMO3R4j=~}}RaaJY{W*4I)rl;HamMtvwdfo<{mJn}uc17q#W_H5oAO+xI!s|cz-0;0>kkGgspra?HCt?K=N1-jQfZkp zKu~F}w4{*5u%V+ngjXMT$+Yq7C$V>P>im9@Yf-@5~0M7IbFCE-iKBD-p4%%+F%#0236Ym2p64V~AC5(vS z0v{o}YeJJhAgoFh`@&c*RBsSaM=}n*yK(opzwA6^ddZk6H`P)*wO=m!H8vkFbn?fL z)k=QIb_DPcK6?e9i25st&Z{{gNsxtk7Y+UF)a?VH9^fSOz@O4wPS-iNPXs@s#tRYP zsD_Ba{(_e&r#yrmPA$Y+l5~H-8l7aGfok*+T?X2|`gUSI5)!>BX1tX;n*g_y5#$r9 zU?gRUvnfr7I5qy*}Yfyl7Bpm-TPy8ODfU|t}v`>3?5Wnz7Dk2G=F z;K49u>@dc%TH~NKbw0Z9zbE^{VO~Qgsvb>8W<`b9GllX+}Q&`(5`~NZ$`xzFTGs z|$a;knQu%btT2_RcWxlfQ6cV}_V{wF+J5!+U{lqNU%TzZ;0 zpj6)a{dGMRgqJ(%A^|5Viz%36&yAmb`l)52{NYNZ4b#Xy=-U0ZviqbB2%c4LV~Y**Z3QxM~bA@>yf z=)gEd`<&b*|1jh|#@Z2k$qgU!9gD;6RanfAM>A(@JDOM}`$40%1Hp16%Q&H>L%6XL zvX0ZQ`H;d1$cYi@9DT858?0#XLwHR@Ks`;f==<0sP)qoTeA59WSwD&A2XntI3sdTw}H1v=qx%)dOPcPN69*ET_CvgUnscR1dbsy$nzl7vNBA zP`cI3OZd;4O#RH1xj`B4Y*5Wrn^<6D)`qn*xbOhOz3n-y%?dKMi-ddB8uJ*NR!I>W zO#a=uR+66BCiHmEM*8lctJi}GYQ{@#P|xT86k1^uaoR^QPvhUyg8z7obs#S_$C?4G{jTxK`%lh(Lyem+DYHu4e9fh z&+bF+$A88+aj|VEJtG3^9riw9Bg=yc#|J1jgd(}=O|bJdQCuD;e`oE~sfTds$Wq-k zWn0>y*Qlmp*~)l3<7ft1sL1}!0YwNSdP6MN12ig~)kFEY2S`vb!@{>cyhoA>1&=Ud zn4#=MVp}K=BI9m-phfTR;c!vPIm>MsVjtMU8;l2c$Pz1M_(t?x#<-EU zWuNR1jV)*G{$*5a#@#>|@2x+Bl88e;gvYnt^9dvNA=f)n!z7LNib4yHd4@PGu6PRkO z-M(IXUAwZEF_95sY5TR-QTAJUVBcP?SH7wbRJ~i$1ht+;Afn9f-cjiJN8o84mYYLU z4BBLl0(zkW00)i$VU(EzLzpchG_R2RZhEZB>cVu>RB39eiLJGYYyZw9^7z5##~MYbNk3)QUO#HfLFdK)gU*Xp z6zw(`5PY9&IYfm>GLZ#ad!kPa7n&?{TBI(F)d`Vt>N3}s*peacjGyIQPf;MMuA1N| zbq=_9x1YDo>8lp_?iW0Y&G(|85RI#J&IhP}7o<-fz!~)y$Y2OSa`KG~@Db=ekO5ME zE?8;kvk*KvizHwaInk4)OqnfQXpnqFmkOt2Jpw_T7CqIo;Z104{n3Vd$%C^)t_YIE z;FU4xmvyFe9wK}rAvfuPls*|8Xwiqwm@KxHMfIM<%=pzF?oI(duext})~T8BN)cr- zsj-P)F!H4VAWdJT)O@e;b_L)klVUIoTo^u@=Ww%@u^YzSeRK%VIygaNsa*18{&)=-rEzqBC!MTh z1y-5RHoN7sJT^2UWz#SPW1T<9?KtN+7kqim<1@K@>p!!y;68H=#032gebq~=rctfg zff46+VMG6wImcYq^9L2mF>Y$l`Ks}SgNK4YEH`jq3ED7)dE=_+FN!nVx&K$w^x{`X z$CfqV0*XoZEiA+@(ZR1h>ro9#D)Jx*`EbvKqS13LRr<8NJ6!Cg%}9IH{@qeV@#KYSIVGpPY{SEF__C zW`fX@Am{D@YeP)< zM3h@wU5M%vlBvh(8da8<;+MpHWwxr8Hi}nwequH11^n+nP0yd#489c7mi_aRbJ71# z0r_diva~h-ui3Kfe;#y>#(e9+&A8=%r}E}Z&*sslF4e_k$f;2a1&BNm z@0lY-Ui?-#)CrUqNVSR+YVVg<;i_*lq_mgiBQwREERD=Bi16vqMsg3-Lrq=G=3tkg z1ZeW@8sxMalZo+=-|J-f#s~?*)uazUEO?!mE2ynSYRCf%{E9o;h%7;xSiq@p@t46yhE>c)CTfV)zRpMX=rz zFd9=KOE>Mw66r~s*+sE4Pnw5^s3mw7?pOk4D6?Uva|KjhjdKH^G@wjg`YLc$ZHB_8 zl8+j-Am-RjEEUU@oq)};UneY8*KhM&l? zi6>96<$MIRBo0Ojxi3=e+fve#PGSw5{c=byI$x@h^+*)73I5=ZLW|VjFa&l+UO;Ck zGfRYJG`Pb{;8qC`i~POGJxmPapt2f(eSh)jb%3@k1=#U0!ul4Oqgy*}s%rufQ7Gzz z#Uj-mSnDc%7;S=Vs+$d5I-t%gHi>#?&aJflQvM$2mrCAB#e2vAxbM4TYQGO$+Bne2 zT=&bqMFVQ`1OF8BF%AAdj6q^)euk#5Qc_={O!149@0(IV{DCacCXgHa1Bo$> zRmR-PKVGA{7S92lK~v$>+x4Z?y?HW8$+m-$o zlgN-O44cQ-Bn5oIY%>ku2GJQMrqHRT%y(==Bmrib?q=Oe)7Q!yZQVh1$(?#AJiE1O zv_)h{u(q(9mqz^XNo|z#x9#&LF2_beDxFSh<9pJQrOIkuJlmj5_zt4afY|I4C_*&c z>V^J>;q$eMfhh}y+qh(B&CqjqqYhyG)O+f0GPvL&dy5VV2x!fT-A)xv44n87xOTgd zMTIvzuzLZ#fA8#c!ZVC|1)4j-l&Uh?(1{n`5=f`CUw9$)xJJRGdELr*fuIrS|BYtwGrTC#LQxwy{(-gp^xet_DvU)&0$npMpVlkHhFBJA zE85>uv$N1 zHwqS_c+iRHK=^EX<4e%sra9NycByAK=+;*_T(hP)pZA92@5Ya_Nf`>-i|temfh|Rh zYfEpZx6VtN8(u3xzu(Bf4MRV#7Q-hvP(unwFt6>^uCr26D)lUZgVyDT@rVBDY&#$6 zH_lG1rn10ssuzwWb*rew%ZKTEX6uuIw&DTTk#~!jRa{h zv`k~jxi&M7)MSA5Bc=u7s8K`{olPzC$AbrC=+`c?*_PWm* zdrKFEWR5_86uiaHeIA+Vm9n{Z8x~B*vXm_!>eShSPalU?iJzQn2 z+Uf0nKAoC+uvEt{jBJWU5qfPl-?n{|Bj6{?B4dQIn3_;6m9sRmX8a9~uzx@TYRAS#4~K`T{_S zk+DxN>lc)4D;D~A#>3zAm~K)^Fst*?+x2j=q23O=&~x!Ap1tk0HuchLByjhNxdj1o zRs|RISQOP~#hOrX3@;1^1!%ZX*$n%ft%OQQ3qYv5KCV~0kRMBEfq8S~tVrdUC<&1w z$u6_E>I&yk`6)Yz+=WTzBebi0)2>n>fU_iQfJg{jB5%V_+_I3~qAk|85~)ahd3P($+4JQGkFLd805!rk zgZ4bYlmtTq`&uruMSzsH)#wQ5g|U01inoQxR$RqBtOFEHltm7$Rp}K6wX4VJY3<;? zLQF67n?U&GFISV_Zf>G67b2Tyvc%)PfU_DXVw-F+?Th=VzG#BF+7^0nkZ zU?nayHnZmWc_7;2T1G8L2o@kuZhzc!g_=TtFAz)?CL{-NypGKQg;&3&q770yJ911B zaaiD>WxA}|bFpR0&D*#=fl9)#rG_`j6*5x?{5-;_tGF`{CJKq!gav^)r#8zACZnNh z-7ZG+@HrhQDD6Zx+(fpet67{mmy!~rKnmnC{s0T?eA6*qgI^roy=^k5zCyX|q*dd9 zQ{A=^LAwjrP5=kf7K$wT=&8yU$`-Qm44fnWPtA?8Lal z+7*#|Ka{v8+e6Ul`{V4)S7 zvA}H;oO$sbXUV0UEVXk&*ldAqY^K5-`ulzC5sN}>=q6%YQlX`kT00mA~20n+hU?tvZES|{%MAGOWrp_>zgX~^NVMXOn;fQT_c-ZJxvSyRg2$#r<(A6@0&&C z=YJSi`2A}ey+wdSntyF$@*gPvFG`TRnX{L%)qnSm+W*}*)Z`LMIFWikG*Xe2V}&*O zL0rp62`mtOG6@qW+hmPVs-yB+^Q_cMzHd|@Kw4O7X7Q3UF+cwJsGSJ27H({1>Ac@- zK<&mT#XW&EVA2b@_^hEMV|DN%J1+}s-_mlZPq4Je7I1C1aND@E3I5Qw)dxvTn1iMp zIM6lY)dZLPwIAKbUHcKDo7;yfM5d#-W>jt1`v`40pU^fml9P;E_Yk;)7R(!U>KO(Q z&o|p~692XoyoZ(&FU?GJ6`g{fM3RbbqFpvE-<;c@NuS@B)tuR%(IW1U^Vrf;I(z{W zpgYL&Xb+|M%c?(w>T%9%$B(7349V(Lz5$y3mRm8a0Og~@RZf1M@KLF-TL5h|=4fYy z--y>7w?rf9)Cx|npm@WVPP#i-KG!`=sUI`^Z=7Th@>H>HRmeyKi|hn={NsuM*bsZRt|`^r_W8zz5Cf`Sd# zJEQLdTYw7?y-B6I#vg9BzV-_~Mf?-BoB1_-FF1@$`;Vr*G@OL>8(-jq9%PDHO^H5x zr(8~12_`D+TwU2$esG-P?sd%I#_)N@&uN$^V4jDw^db9p{frCLfHGh`!ntS@SE}9n z*LIeViJ`;mv%@-jy2)nC0rjxq@!y;P&&F@&hMQE!rj&Gcwqv}>Pn}_l#o>n!vGrFu zkl@9x9Z&C7OYp#tL%;ox`TV=^hF#X`>AvuvLk#7=Xy*UgqZrxR{?~9eQB#Em0=4;< zLm`=zEw1JX26PH~3Yw<*}P$B)K#chdw zkc<&(Mv8kHM}~WLhbk(9K}*X$lacWl@^w}K;~Sx~X*tV%6XDY~)94h@2qNSd<;Su+V5igiAlspi(?q)o<2bS2^AHd`yqb3!shlZd)L3+9nffxqRmQT;ahBIJYd)t>w<%r76uK4xH$$k zFC9Au>q#ZAai;V{I>B=V7Q=9<>`Ziz2nkd7 zuruzv32!p?M0{SJ9fcRj7a zy&^rNGBam#qTCHNPU3ZGJfP};Y_++lS79l`HXqh-iz!dIdp@B!6FlZr{OS2aEv-F* zH!ks~xl0qY#nrk=tPMwpui8a{c@WvbpX=?dzHgn88#D#xL#gMwn>$xoNq0H>t2t-R zH(Zpe0>Ms_jnAWjBVSXOkYR=g#_V{PwwU|*Vw&AwCX`7ld5+jKO15wEC6|9d*XTl! z$?#n80;Kh8|E3Q`A7SQ2(`12izzMf&Is8FmF=(1C#k1tD9Z);AA7wu?WdE`z0egUp zvU%&qD@dzVlW)u5#m_Ad{T>8{lTvF`|j1BiIJv@55xFHVS7yv5enC6HZljNM&;yY z>wJ}Tlrm}Me9cPAEmO#BMOf2}@(jIp=)aYG3ROhf)#2P9@*}d{fY1pNv&vfk4GhpB zmLPsct7)~GfUDwaP zpxG|lW!?&{E1S#Rkwk38%iI;L3Z6dg{nYKJ!jtYz*}WHEIUAT)e}>!727$Noi+b_% zDzp5?Ft-*$=?OG3{Zj~|L@Q6Mu{wpM!*m8Q6@EXl4!_DxN9!yO0L$|7GWESp-SR;1 zE0Y!#V%-FlT|3KM${7s!W)E zBy7Z=E+49g%Tdg9Wy8v&PfkVmL7GgVV0ShJNKB=H970sk8WR7w;r<4@wh&OnE=^&> z`{~0__w+$}b(ng$ASDQ*tj)#it-1np?lRZRKc|uSY+a8s)UwvEGbDnUL4}r8uvr!8 zVy3NyC{V@_cX*M=M^c48Ll_?KTBWj1Dg9Aj21M5-qb8b1kxqu&;=AnLf#=19NDdiS zN9epe{D@v*aO&*4?H~L^bO5tc19a9UGjAvZtRWVO{TPwgC8YccvwAkPvq++Q>5pg@SvFj*HnRe@6jNAt3nNo3bOM~pI*r& zkjME3_lvUU>|>cL>rw!&;0yVjg<%q}G(LFF5QG3q!;YA(F%&wdKb~R7_6hsNA(p=- zBOKMI;y^IE2ua*PYA|F}%$)%7H<&ioWk38AbJ2Dchmf9*Jl9m@uZLj{bbT(MXQZYG zLvhdz8_EK<5$cqxcG7Lsr)b8iCsAdCXL~Vu)i5Z&`j8p$Q_-Z6$*70ZE;=2~lq43e ziEUW~A}4Qn6qO=!%q+qobodtORM=w(a#e+DX^1IwZ+q%Qf2y)Q?sFpc43#H`m?}5; zCp{7GQi|GA2XsCvxm~A7*0jA|DLIvsp5DWlzA$(!QD3N4q%lHZ&Ab?!a6yT4DtHCL z;ARS-lfM}VLiSKz@b%W7a>Exmbp(O!2m@?k7dU-Sk(vv)ZQ%|DKpgUcHr4Xh;3l-!`#B)!@6MvaEE$P1L@y-i<4lQp)qz!En0Vje*^tq>t`Z~ zb{9G)b;~+`FnwOlQq_);^f{v=hSML#L|5zA(qCz@jnYX_9uX9ur!G#vBT4QV-d!-I zh0gef5F%UU(&bgLOWoN59Ee>02vw|AJz1|;B#67d0|X23P#52jzrP7g^T!ghBdkY3 zzejIxfk;TS_ui1j9$Mx|`+o?n-MMZx{^UeH)^xysvLo>Q@P5Ku6`Z$$zxrK2pH+}> z`@=@`XD|JkTa4En)0%C$e^Lw zwfmcx1_Je+HJDATGsrXIw*|5{$jX$dkOsbFe%0BuoD%+6#$bH?$)@q8r?p{*>+_F(!V_*yJ+r# zKdb10e>EE(e=-Y^zXOU06^~86hLCa?KB@eUWpHsBLI~k|JG{#;h!=Kq1@AoNcT9|n zHeEvUIg8~k&`CbGgQR6I;CKmva1r4aY%f@U z(NYhG|Ax;WnQ7LO;ybPty{F@coGJp^SC{^WnBq4>oX`8S$Lbp1`mQ-)NzUwS7pFR* zi4}gsO8C#apiQ9qX<3_5x&!*MxNKp;24J}_te2g)>#F+Tt;H|zZe|axzMm(5Cmx_Z z;fC&CwLNzChsV&y=5YnL_w|>I&6*$Nxg})Paw3!CUETH^GxwQ-%?b4Di~Cryd#^)9 z&c0GE{=^IZ&b^`zjlfs94g#C0um&ctv>D{M!D*y=>@J3I&GoNxKj^nT0|JeTSq6re zoV7Jv=9@z8Hv}lM>$G#~b84{wlJl})@5(~`)et|mb>E5_ne=+k`$p=j2_O6?F}X+f zBZ|u{srY78rvV>dii_U@YnvC~h?bW?2}@ZPKuydYHt%xYHrv}` zYYp??2cCwwEp1KFUmlI~UbjhBuzNKo{o!B0qZpk|3r)~OMRb?A^p67%q0L3yt9hX| zvPN69pUrAIPL0$!wrYme;5s3XbMy;az~0sskaiPNRq5R^jN1vlXr)Gw!KU8Sc11JNObnNx|yikcf&i`N)TS8VdA+?_Ut^>q2Dn9M3ZGaU~$*Ou<}>&4DFz2v&jl6+UT zeY-9~OKB!io!{W6f?Gx(yyv?Rh+lpVe!d2-lSx2%H!=C%m%U;Jm*C|9*z*(E1uh>4 zctn=?VD9TGl2cj_hFa>6)95ETJEY7(?fNx`ukFzf?p=~LP}&*s!peflUW`xg1gB@B zfagUy%w|qktBJ@!19WC$Rkcw(OEIK1#H|Y;S0fIPKB)Jvoqdw7L(-zT=5hX9f0WGe(QBF z!fU6J1D6q$7m|zGFk}X+7j~!SYm&AmD*Mq7-dG`+F?!>l(xQH^5)-_S9S4s4*nU$! z0roSMZ>jlpDZjo|v~K88@$G*Zz79Yw#O+S)tmfhMMFv%+m8B-)iU&N~JekN&gz+Z5 z;Txv2d7dFwyG>Y-55E{cYVXqafMm3q$H3Ezt8NPhGhs~F4>}C=D#8^IB40@m83phM zwo542=<^D;PFRirX1or{5ftqcY3M%}I3T#O-{gTkdSdz{k{zQfj6B@=^DOY80mYD`PGxdt-WWumAFZ zI=vdy_J**u;{HXa33GUbj_cRM#=Oyv9@}aNn@=mKR=G8)MlAC?%~01CnXQs01N&Kr z`GoXg>pqiZJI4N4R?nV4yr&)YKPTOL=OWip9;MapOnCXjzCqw$^?BtU%T4#<2JlB7 z&h`1<#^>OtZ#wfIcesobVg{PuY!kV^ zeM^sUC38ULsUOzG22mju@OVRNX%6x=yTmhfGzHj73XVR4o`$)R z`=JRQOE@oL@P>BL*-Uz3-13|j{KdY3DxmPnO}-}&k>0lnvTF>*zG{r!8v8=adG&FM z)!;d`$v^2=pHQeQWV9`{zYd)h#noEj(~*m61_K08KkjHZzlf-|Shq~q+}s71&w8aW z(Ypk{MGws_(Yf^&TW(c@Q_o&8Ggzu1a1s2-cKozgY#D5=NZ#pPw_<;m7##_g#zb^F z2n;a~d3NkIb{N`?`@L2A!_$u7+KC`H+;g-~lFh4oO`|!hBF^xh=P)RCGh+$ML#;1T z#2jiT*ihFxe$J~4^V757Ew0F#z4`=(^xV|PXwQ0rmwu^aQ4m%*M1`8llzNu zl>7vjLds`Y$!3CYiTW+1ah@nzUU<$N&I`|q0x0_3|NK-hc{FMqOPxSDL(J!1qygYD z_xdl06DBpq5W7(V#`bs3EhD(vN%cO>8pmBV{uo)G&~ZFi<9o6V>evE$qXpNzY&`8x zPWXg0pl^-E(|eNKd1v;je-HnQB9Hko#fpmj9TKU9!8fCp0Ggt7MerL*q61iFdPsVXiHa zdiRTe=pJ!EfDrVj;Zes+WlGG!xHtCPQKIu{S1Y9cbDfdky@)X6ejH-nv9|Fb)1y^v z1k10!__NM)yt(C$QH_b?wXITu=kJr+lO{?3EpMRrslx9YjuWhBzfFR^ffx1e9og|d zp;)*ptUd;#h)U@Ir(Ee_=lbj6SNH|DXQDkS-x~voI43^tw1y7Me~!AnmFI08nAP(U zJIa!~G4jwJgtjugsJpVMD?y~TGDB@(wjr@NryQvLFcHaQZm^Fwf0R!l?|wRGoa^rO zLh#P49NxTh;t?L5iZEY#IGEOJieFX)5#NkN2+I|fFJu;@Pu0+0yMlL{<98oGpB|=} z{f9>a5bF*I0R4phQ9iosX%nF~9TnIT3r7SFD<6&G@^8JwOL#I#HVy3^MwA_ZF){l) zzL$FZubF3qVS=L?qI$8P2OoLT#9_Wq6Nff{$Q@QxUlBD-L0;=rkwE0b&9s63x3n9? z7tgBJ!rVF2qaVtPJbZN%3i%8!>(cd7s3ZB?RYN2boph2d_gRX-l+gcXx!l&hUT* zl`p3G*jn$vaJy4?b22#OnD@>JmkI2udtH$+c(o5lNz}c}&xd-Z_*`KJxX!4Ci3jHV zG*Vj{C;2I#hRAiyBpu!dx6(aN#RZA3g_v9#vSIp1l00FITSyH@#PiQeoN_9B7hFq0 zg{`G}&quQ2y$C|BvAB*mBL*Jsv!@8^k9@{y{FevSl>n+(FH%tfk=n@YI)9|U1p{Jo z8ZEa9N;LfV*5?+l3pGUyw&dURc-o7xE~l^#6mHzz#r^$ZySK|zfQ-=_j^0y^>@%BJ z`Yxs1*QAg>?HEE#7Ugp4?{6bV+aIM9yq`nnt(JLnZ}dI=6ygB2_1{Bdbn7D@;%AHn zVcPTS{#GpS|BTn?wT#P`(6$19FHHFo{;gvC@RQSnCY1Db>Wo4dZfXqDf@(pXGo&}~1_t@PWS(Sf6FKq=mKNTx#HjI=a2g3xQoztpV921N&?_=14KRQJqxOEW$&{_za! z(u%~VkHo^iu&heoDL0v$%AeiSjXR~4zm(pyl=mT`{;zyHM{a*I2YhwdM6dQ@r=Pre zA-=KDA}4R;u2PULX82R@{b%=van{~ui-p!`m=3Y8y12u&_L0u_Fsg$cGU?v*>{g-| zDsYB((8(#7{sL-B!-_Vs4wrT%e0huJvEEY$Z=!t(%VIH5ZtTtAUSCYY88zUp(99o& zEgMXy{S7wb{0*R{yN}UoMcCI)URvgbLmhbX8~ZX|X-Ar;tU=mR<(CziNBW?m-eLg6 zhW6?LNBa1i!2&`u#)QlqttS!OV2~J?_yBxxY{;AD7R5LPRx7@C^ z2f7=ck<8wiW)YnRYrlpUjONFf-{Hd`ojB}-!VCWpmc#7{6}l|uI9@%6rBqBx4$V(S zEWThv@=;sS7(0Ob;C5WR`h`p^CB%FKUZ&!HE?piaCggTQVxEwN=T%jn16rS^+27Of z;otAw9~0P@mjhnP75J&2wER|v`_bPe8s97tecQg6?q+`W1`-a)@V(^bO|FLDUEQsy z{D@?@$E}Q<=rw-vjUi)4^1mIYEDF0wmZaiJ0ae;+(>4a6fXrGTh zDmy(&5a18AJ%B<$l>x8RX!Oi~GL$s$;n0yMQ`SH|A{ zdq%M3C?Kq-5HH9$kI+xa&FuoQz+Yr9>_oUtae|>GhfS5^LiOul@?E6q+cASG7i#{- zVh^VD^o(T@V+M6;&7ami`#lJP&-O82T;YSZgyLcZG3WhP`sn58r_IKxWDP1e>dXlz zWHCue9@H}j)L0iVtvTl3<>n1b3FsGaDDI1f{vuNeR|7Uwrf+ zgMHG&%M3Ze%Ri{n?hz-smyB>hc*`WkGPHE)`tl?%B^3#fr#W--BE16}JF~tdCW9jK z&nnJQlV&wxCZ;vm@p^20dZ_}Qh zc(z$#PlPRqB1lodoGB*Rg0k!q=6y3D!=;1#p6e_u=4@zMKWAR}wEY$-ZVs@F%}_d_ zfqa`XF40NG{zvK8u$eMm0t|5ia2^DM+aA0mg|4^p6kjayyExo8B9J0ri{T1vFyF0 zATOPGx}`USP^#9C;7mXh)-ipK)L1V{FmRj{Ijm?ZQ9b*mSU1=(1lH;eInv*!j1*rR z@b(hD#q@`VTE2SbbN9gmDMfYz3K00Cx63KDq(?%@-5}062*SlBGqeVYhe$mS8{0Nb zK@i#MhMb_weEGiw?By!_n4!t!`$x1iXAHdc*rP`;y{O!|CQ6 z0HfZ51CUR29rPJIGF4VaG<^xpR-Z&W|2sA#TV<@3^vFF~BLIa>mG@!P26jD&x(N41}3 zFgjJhZ1TVC;ehb5R=qaA=f%6bM(+9JP<8rtdb`*~AmR9h&xMfJ+&PnV`gTx)vd4pd zV>|Hp+C2Zg+N_Wu@RG~MMc_vqouuy%@C=o4={!(cKwxcKLY%@o>NfUA5b7wtHOqwH zpvLF%rGg{GPt@UE`^A<0Y`!F;Rd6k<>Q4@TbR2d1Xv&&5JrJpp0l;V;hOD4KBslqU z&GVq&o15e~c6F%&JWBwwAp(MaoLK985B~_ATf35*h z5{mteMW3~UZ#Z;~khK%W29~9@jUE?nDJrJXB`Sw z*@G=F-MhxSYI@J&r{BF*8hg>-zt@9#y5#zDd4rZ*Ojxzq<$>%HiL?i zC;sI~pKrU{0WEDsj;p}Ifsd#Mgm?EW%iGD?+rt%SmT4v1`=}fY9-0OQS`3d|OMJ&p z2{dCoJg)Fm8d?~_fdTGr|Wmm_%A?u*fMe}D?M~^Z?mX1{*PVy#umu>qzmn)?bl31KKD!qOq?Hz1o-7?n)tbsO-+Z?_By&1kiOXwLsm6idk#l zZ=!p10Cu-xo7FP8o2*F9ayagY6mUB8un1m7;c>*(CQp%rsp1etd_Ku>MoU6pOzJS} zbERq6HW!vBh^l%>cCxPTj!Qy&x+z-cP)*b%Q>1P^nD62n@r14IdJdt6%E3pCWY!Fw zijRISt-a@xA9DwTaL*g)h5M3=hhgMEm@zYqMEFzkNHK-Jl!)cj(&kz_U8GiM&Jc(G zl5R9R8dP7Pjw>VNmfMZ}aw-(Wm;eVChP4$4T~}btr^Tn`$|q))p)th4mK}qqWi~my zZ5}cDXh+Qq+$We5s-@gV;CLqpx|SFgC3TPI6hxo|0^7qBJQ<(~KRE1_Puc@*ojGfN z-te+9kl}BuCtL?z|7!H3`)UMjTi1Es&@pyczcjMxjUbbEg%k=QB~b8qSR6}rUo9x> z_R2Yh-d^2BZM8D3k$U{BGrEo%a835>#m~=Z|D*^S7r>3Rr@S>ph^(}=+Fi?g8|crR zvLWrdYob2=)36IPbEVY7`?%=o7y8kqOPEJBZ?3+~O)O8*XxP!GUQj;^uz7h?=HH_( zaA=)xAA5>AGDgr3d=j+Bq`k@YF|=q*TVPg=xEh5=pqX38fD7?)s52amt|^feG@0K7 zGd@_QpxvzxIff^Qx5T(}lxAUL{Ae7{Uy2hO!lynw5K@U-t3=(^1I4YDWLMC=3uL~h|v@6_JN3FaM5llOR{KN{Kl zZ>xm+Ogj?ZWv{#0XHWB` z1RJlWkpC{lRaF{f{mqAmq>PIIU+n;J7Dbg6?ea}1O$8?ck^S(!&@13P{O1|Adc?8+ ziTKqAj%G&NrN}&C)S1f$87$868DgB*jH0OT{A#GUtZ~ReLaTjd*X2O06sh?I_M*1+ zQJdQe$K4CtnWiBVSx)pa|CmQIkKSNR(c4JthaVomv@4-qCacaVeQ*kcH@ZwNE-Dg8 zZ!531W!FLtXv;~YY0E)sh7)#i>PaQ55KaUfs0+oc(394UG6TgA28+mn z1c$TY+_XrN)6OIlb(q8EVvo7ar^{KR(6y}-Xr?$cDl|8=Hk~>n^91DqWnv@fBR&VC z7eRdbQ$X7Bblh>2=HD1HO-W1~4plyf3e#fJ9AdOnVgq6C5M1-tZ;Va150b&Ob=dzR zgkK+;JY36aDf{sKV3Lu;C@t+9mU^)iE$+pkGhogaef3|%g%$5JnHX= zt2xg&sT%WlV2ScTKpWNq%Lb(Yd?up#pam4srjna#*JN+j1i44(Z}F=NTL>_eK`265 zjmu;_2zN3~a_7zSs~{YynCPDaV_w&1b9_wf{iHzHxn?UlTsLN;XM$8s?IXwgkn9Dn zRcOSMQx1ok$h7AAKotH&NUz1g-foPY5ExKmye&lZGfjbDFLvnQ5ejYN#-No@;nZtf z0+13LWe~F)dx8m_LJDASXZCCCalQeLeJ()WEO9KcXli&;J9Mu-;=9WN%xCo@&gr@k zzTc~8K&WnKgl7H82Z^VB*r+lZ51}67F+F{|2Mg=;_)(KW;1D~6Tyi}Pzl zeNgEOVV^lDA*h?5AkVDxv8lq|A6>YqY5Yh;sOvyo$x&yb;Qq*eE2WK^t@f%5h-MDx!7?eT^AaK{1C7E$m7CQ zD70oXQi}sjghd#wT-khSvNA4%05>Qg(?{@SRLgn#&3>|!AsiVS(tXq4mIk5>eCci+R7%6zy|_# zvkS*J#;+j~qg56RGFaaBz%2EfW4qJ-OJdd1D>0g21J-H=&7_>kj~pjjk@_%~`lO!L zc0o(+Bag0yDqL4bZBYS?VN=&ys+(DI8q6i2y`0o`?G8OzQ zGurJ^O!&{3LH}j?`4T(=HE+C$5(Wa`07Aq;R1}3xX98neffYWK+Uy2D9oj;>JUs)LOXvb6(F;j)B8EO1se z0}}9-RRhpOnPw9d!j8qj%_5FXzy&Zu&A=6sg2>f%6cK{*o9G$HCOEy66+t?djkRyn*Pzx>(6+L{j0Ue}HrgLP@4#;9iS? zap7N+fpg$G)&plDj^QS8gQp`LVGf-|`fMlA!*#KP>#>?<6YJFn)zlnYi40%|*}`o( zjxfckWTZk+Vl z_tTht4Gtk8daMT!;XP~NKG5|M_v5JFvcd~+Z(*YhtY6cB9nufhaQsn&+e!WFZzEuO z^uh&j0=d7@1`0%OUywdYz<$8K%MSL4JjWA%LicwPdn#`Gh%QGn2&a*F0wtl0bF-0F z(u?L28)1&n_)RB*azi+e(8<990SMScDb$XcLkBpD@ieJU=r62cM<4?(END1vg*}xp z=Ge}~;TyRM;m2t4BuR>vjqB3#$G&qYbINnfQ714o!j45mG(n^le-hopQb(#_YS>NT zDeNY+!w}>vL^FiNhr3{W2NP*4wh{^C>xnR>e67H2aey%s0(-*!;WJ_rh2S%+*Q*Yi zkR9J32hefqY6jTn{*dhBz;8)RwB}xLuDQ57+5_3EVl6qU0P(PG&vcF^Zt)9Vt9Hm7 z*u%eoIXVFS2Kdj>M?u1QIfC(yc!?UdL!=7e1dj{fasr^kDA;&My*3jqrfz8~7(wz` zj^AM5GK}hh8Bz~MVJ@4cU+jCR?}ih5Fp>$wj>pw*QTHp<8Vn9I2I|pvR|4<%D1U!2 zo8Erjpt4GEF3<#+)3K5$18EF8&!o{p^V?{oe^ag zF{Uh&-a*ernQ>NvG^3Bql|FEGd{{~W$)G#h0AK&n)C*!Wlf-RUeP$=wcUXN^|311Q z&sq3ULz|R&%rJ@>At=x6zlX7H?j?JF^@+QpHKH| zx^C!g9eMR3bQG}2xS})g%k1{p+TE1+{7N5bCZY;0#Y*NQ@}ej8L3h*x`Aj6W3Q70s zRqJZPvY=m5KbtZp(on~MWulhrUdBGPDNBL6&?C&gKEhdN9yLX6<<`4__P?QBi)kmH zSf?EPQ3qD=qmg%rYH$97qD`L^Z5JRx1(6LI@ERZnfrKOo!VD^YSJ z{pr5d6Aoks$+D1ZRb5LGc3>Oh7t(}k6KN9Y#?QZ52H9jv9!V3)SpRcHTSqROvWg(v zp#QvV9%$X0y>SijT8P^&eG=pxk&@&BI#IHC*dsH@@iJ>To0QJr?V-dM{PC5r~dc~CS$o*JC;dTp&ycLdp( z*HDh^uD-OXltk97ja;$3>anJcO~z;kO4Jf6fm_j%=U&c|M|H)T+TElf49y-o&;mxr zYms^8stsdzma6>z1<398(eTmGo|LMd0r<=Xd_VNh1?a!f>-GmQyF`YXX(6AJ67!_Y z1H>VGBq&%^KUmt#heU}|580L4<%o}w%5;lCpm7`}Q*UK?5ZsWtpl?YhDgn)G1-&2z zC2zUtue!5uxs(-U?vfOv5 z%~CVr99)NQo(F?3m~&3i%zUhpHyBXDlKRe=FL+ME!updGa~$c_9XBP9o8$;JObJ6Q zTIVS0ksF)HNQHO9qU@O-T6lI(&`e8Aih?XGc_sxnvMX%l-65z7LTwgFC2olfo$B6i z+LYJqRID}O&m8~SHsB(k=*7PaF^yM3yIDjd3N6xx-6UX}MPtAU7zx&*Shmz)z6vw! z{p0UaMR>k^!v9Yu{xY0Tzx-=@xy;fCrCD9Bzg|HKi}HpI*?95+UMba?P^i~j-~~~M zdQrXEU=t_3EnHARrEzfAI4_pc7%3e7xVbu?{N$gHH?=qwKW>;Uq}LKwMDXeF$v6)| zrFDy(Fei$G(emKCe46>3;&maXSdMatE!&w?*yRMlz1Y`#RF*J?01zr`;rvS)a~>-D z(9)h@O$s+PKlz#xvGjSjU!mTyaO;+w2Zz8c=7bGhwg--~#-U9j@|=z1vfY%!h$KPi zutyD0AErNAH9ColdZbClT5Uuh4cjdw+UF^M`GtHfVR0dASg+%tgG>i*gB&9a^r0NfVIqbb z%P*cgPu?9@>hqsPNY|?*;0=OS|Nc^q{*itX-ylrkR=Y+oUB{FL7WK z)=DggTs3;mA~)G)uGp)Vr}fzU1`C)Pwb@S~iN}gpJIVTz=1XWSN*bq>jTs52MoibS zF+oicoAj&9uo-2Y)yF%I7oyg!eb__90Ghuv0_Q48tUl!zj0Y63z6foDP zbZ_&APEVxF^D@2&*W;=zI`caU&&lW{KKsPt5Y8Fp|+G<2UK{bu_M0c-5XC z5x`utxYb^}*a;R45Bk-}trYMswXFjp?>puC{PAy}1WCGr?bpwm?4jGr6W;jqqbfDF29(Z|3@dni7m~ZsXD}Yb)Fxn{Ot!AoYJ_Uzlkz zKl=a8r6!_rO(?{651%#!SB=wtVSk)W~^ ztqBR;(HcB%Fpc_5Cha#mW<*V{>`)WLGZgS<_nP_&Di~c)<~oZC>hIxWjl;Nu2EEPs zUHHP}_S>$p;XOD4^X{m`ubV2B7SU~}t*Nt%+@A2+-O1=_`sB7Xp_hy^XkG273+Y0> z>BS$YCNp^_O)qFQHV|eQw`7L;QJSbluM=4t$Z{7?_bobU*`xS$f#;!Lx}{;c9Wf^k zvDifvFI}TevdK=aOS64rg{erC+$ly}rj+}^f6idi5AMQT!Vm5)seAXJoS!0a89Tu| zYs&LH>^q}GX{;(01@~fPM6~#{2(99MVkDY~$QQNbU(=)&$K2vNMH=_Uc{i!zG1{Yt zc#+uZ#2zlv=j5{Xw)<6XXZ5}0*Xtf~_Lf__K%J!drub2xvV={ehKHG~5_&V?G|OB$ z*URWhkS&yp^lvf^Fz13(kpN>u@1iPi&qI$F*>Jm+*7BS{aY2+_l*$_y{Aw3)V^t2s z2VF`46iYw1W*GvtamGf_p z!(59~cWdTYvgCPiC_zIW!{jr)cn$h%2r6{%A>G@?cW=_Z^G1Cq+~&diVmdxE_-YJrX-#mQ5isN2FvNY$9mSVjdl+5Y(66=Y?gpEZAT!t} zc>v{DEGzHa68+t^pyZloU>Mh2%f_=P5<-agDvs6lT2!}T-Wxs9#B5v4e`Uub<={9@ zJY+MSF%a#Wc-`uf)!hyEx>Xk0hQ0RYPH00J`;h8hQ0>E0p%eHk9AA4perlH1t^6%4 zNH0WxANhqm@yF9BWooShwWfp{G2bDz>`i#0vm{rg?>Y0UX^N|UhirH+zB{0>r{$xy zBIMM}Lyzs-EMsjT(CZLj()~6>Gog9x!6f(UMSGIz`04w}kVxXvJ;)DO$4pNnxzfSJ z^ND!+?cRUMI!+zA27PFU(LP-OS3I5@W&v{c+?W6{)rd&|Ti%aHS%EE(z%!n>IP5>V_ z^dimnlF&6T(A&aCiOJAm&0yqb_R^}!=}_qT3Gt5bYK~{*zx6%3f&K4lMITJ-cW?mf z4oBUQTocW9I6Sm?p&Ox)m$Z`WG=+D!@UXx+(C~sb%ZKd0%flbYtHX}SJ-|1neOKR~ zwqY--{smx!o&tw-1=B2<3{wOsfd@ok&yKoSl^}p9%Z2&-zq*&RngQ$L5HDv5!{I>w z`Vj?X!DLex4fDG|vwW)YFNu`)C9jtl)Q0txn2m@>_C5OqR2B5b4(!k$x1G1aA433) zZOHFeA9i`c3CNnCh9}@f3OtiBjOHE*7QJ^R{!mR~eNJ0Og@Cun$VNWS9G|wPyyS2< z658jWpGcy;kf_-8P_|H)nmLV;7!M(Ro#H|l+0COvSf^KJct7-sJQ|UPM{vODNStbx z7$K@(!@s@w!#d=g37uX8tOCik!fa>6NbW-uR0g7rkCQn@4`E>}A03!~8w+JR%XLr; z%e4%q#p!w(w)fdmERSYZW5i$c?IJI>bZoNaF|zWRlb1@*NTFQBBo}%BUWO3hB^W$) zM+iTGXv9Wxw1hEq8y5yg=0VGge_hncgvAe$3nE4C1`b>UtbglT77Fw%?q|Xgcw~6Q zZC>-25#2ff?h;_+?p9=InBhS?XSDqU-`5;rftbbgk~sPxlHd7@@h@6xTyw;tyJl}U zEdkT=OgkxnOCYR6YV$+enDeo_P|N7kg`0ypox%n*`t4HG-}KT{f&L?CGD$bRh8>9o z6?Fp-ieq?(XjH?(Pik(75yZ?C#xj?~Qo-UPLzWXVzC=R%KOJM-+c$ z{W;qvd(5LkjyxQs%%Lr7JtPvyP{Wls|FxOLT{2QsrW~vqvk(bO(n3 zC%rkLT;Afa1c+j$5D{V4aMJvW3;@pPqoRdXSDb85baZsMZMN{&yd~`Hs|FH&JRXPh0BD57*p0j5ao#^ajWYHTaPSQS!TM z-;mJP@`6=@FV?)c621}e=e1b-vT!c;rI%mr_3wSv!WNOGvrGy z;8DiX7~TA<%WbtbQ;4Bhv6P9r(kC_E?Ojp`-T2)aGi&R zBUYnlJD}M-IQnypKwlj}lbX(yY-Wn?Z0ijNJ44Z6Fr`EtAA{X7@CQ%KgqgU6U8pBR zOzmwZfhBg741&v=T;sxIz1NP<%Z`__bRR#jr&a-c5uL@wn$4Kw+hySf4FotHZ))S2YK}mt6zgp^{2oKW?Yl|a=7X8oN`-1V zHV)ps?CXr}io$>x$_)7a;>@P(rQxL_J6$6NWr=6)Xt&2XY62Wifu$n$P4V(p@b3g*YzQ3m!>{K)v@ z@!7HiMJY0DEjqd*c{6lEKFxbs{ZOy6o%8JkJN#Df(7wu(1s8h~-onGR3R`v2u>qE4Aa0&1$HKCoUFLYOD^w;ly+5 zwtrmv>~X%FIbrCV4wrb1wW|(4^`2{mRD3CSs~0?VFUUXk!b%ye9l}D2J$mwM)Y&?t zh|(pIKOS#{apiZ5w=rMvQxWIX3^24D5sY`E0jh>#xfMdc4r-~w|1>RIM$p61J$u=> z!RclT4?OeN@-cIbV+y${m%74!dNa=CL;84BNvK2kIGgS1?JC7}ig%;9!Q~9I$8`&E zMjOGLhJxn3Lu%<)DZ7A-J$K7P^}H`+H{)q_i@3X(3^=v|?)KgeRsk2=J(jKsJb{A* z3n3$d6IgIv!~~<7F9YlbBDS*t{}YGRy9tnA#@+vuy6oRMix zlgcW2I@!`qIv^PsPd23_aK~Ua;nw&2E&zs%f$r#J&i-81MFoo$3tykDS}Y?WGsZ^b zbxQ6Z*1CsGN7z=%+5(CKgui!vJx2D?&U%xIM*INsZ|CLDx^{3_N{^s@;^6m3kd3{p z%{7dlc8A;NR$?lO={#=^#9u10`aUO_sd5X9aW3U+gsD~{K7XU84xQ^v{mq31m|7?4 zQ zc1cUO#+H&fzsqbG_qu@r8@x+lE_ugv5;@w$Cd8z9?MpVp%_gnA(_0FAHRu#X`9=wT_3?&v z#fs_Ago0Ycdcf5}rjj5K?!9S+6*0Bk#idi5axq;reQQCm`0Q*dNHO$?MogWdEzJ5# z2ev6$X0f7#R5RU>-EW<@4f=HVTa)@3KgS(Uhy={_{3cwaU^&(&jOKjCAt{w}dS5Bv zWGf^LRR3&?YC}&lOR}o-tzOKzKE#FI*eATXP|W%}YMNw5Ja*O6b{uS%#5OuY)|D;H z%)6nAc6*s~5Se5e;yKcfoCyDhPoNX>T)VrYUosZlZEjzh;O` zPfU9wBzI4w$Mp~5cT>1`XPnm+md6{wRZ_PBd(R>Jdn?>K1(;tMP&WMW$KX~&2xB8y zlUTe?_ZhA|YV)3Gf!O#HQBd!?Uk}_Cz-2#fV~G?=PE>I7yK*#6$h0BC_gMs6u-k-Rla- z;_Ue-_cvez4^1Fe_n#pd$24pR8K#-`O*oo9vi{+s5qd|zo%*E)h&k9GS6w1ztxw)q zj;1H~*$P!hBVefo!?PBvj z=C6nQhYBG(^!1ZIn<_BZax`8a_cW9yNIL^aUyB5H*sDp6PnVWI^s3M<+%fGB)eM_Z z?$OA!zZoD%!uY@3L%yhYzq4<5wVX(G)oJVs`_D84Whk8rgTm;GIcKJ zPPr7cX=7@q!d+h;X;wQKasBAGXYfFO8mcS#_@igtf*kGk=8u88nZ92w2~SaO1#e?+ zC8VPFKK74Ld~DMTiSQa$;hq)pHmR#74O$63nRwO7uP8x3n(>1-Go|GSW)*J8dDkxS zMAIK`6vdb2Xz{hSR|IwK(GF|g4Lz-^ihA^-U4+WYiM~p&a_% z2)dD*`Jk=PO~HSjh5lDArGKV*`QK-u3sT{{;};eNFQs5UrP0y+_$vMxDOd91teFY+ z(@%mn;TI*Ve#2aBV>GtapcZWm4BCpu0{_Gd=OW$>C#BC#|9qO`x2f3nbkCs%P`a6HR4J=zm2f&?{yxY zBqSv^(IzFu2Up_`HEQEXQ;$)Lx#eSA%22DY3$3g`Vr*~=0ZAd_O9+e4(gVWu1r>pL zkO@*q%B~k*#qeOMHw7hAz}ZJR=BZlC#DM|002pL-*GYgwnyz=pE;?YT>-0yRr z2VjG#R9ID426MtVP}E)@6#+0PDy}_DVh@Naul-DbUx*s6f9%B`kTqWS>;bwR=cn#f21(GEh|^d}(3Ij9xZhI&F0c#EI+d

sj2Q)bC?vjCYU24l^sqPZc!oXXf_Bctsuha7L~9L|5L-sc_v3cRb8#oR(5X z3At2evYEpUqm>RWm`4RT#FZwr!tkb)&E~X53HfAZwrj$$BGk-oGyz0JW#5On1`vj* zou;?|S=dG2k5FQoYP7qzv*--czRbIe^-)skvk0fWP!vlIK9R^C zhA{qH&oVQ=aXMrdFGRVT(kQtqQNhJjfaBkMp?%FdW9 zaG&MBi6e0T-vSTZ|F=j3_y0=(iH|HY-YMjr<7fubJK^4s)-h8VMbbM6;f&Wt_C(=~ zbe-dg58=89Q(p|s!WruZlDK!q@PUA+M-~b16xz;lOoM|kMyG)!7+`_0x5Z}z-2Nnw zoiRQjAoGz$!8?Vqa~#XyAe`}LAW0lppyX|VVSqc31ido`0R#j*)(UxRQGs3(H24z6 zh%k^OwlhWo1jIbnN_uP2b<%w?_!7<-K9EGdGlm8Pgg(}O^VXv2q{B2wqYB1SFnH<)s<0ue!TV+ls=yDbfC6ga*ey-b*4PF;15Mqv(pzuy&0M8>U)$0*EgvP7T|1+RF%p%yO4`~6%2JX7IS363tF^3%1! z&Uhv36-L(ppG~Yg-nmrj=7`K)Qv`YjPZg@~p5tV#(%;EIjMN~;u!^NDv)0XH1=cp% zETi2!^JUMDq>_Q-4p5)XK{3&4)c1=jSvZ~odCW53y*mVXgf7HOe}@1Oh=B-VDwYh4 zTW5|LK>!0#laf|EH~Q)qj|t6^MrwhpwRfIGb8_;RCax)jAbL{k4&V5aiDQWry+Y8K zZB8woLdu?|3v`2qXmId!XxY=}cge~S!!ql?+8*8KfNBXgg{6{*70UE^6vv_L2Vq^cD1Oiln0JM$zM1T~W+-R0I z*)9-c6)56(6uY-}peAgAz6MR8CJ@XK$bUqE2>3w+pco1=Z5-bcfdGOaK(uwo1;Ddo z?yn)t0ufSzJf>LW&H0(Rro4li)CFo%m8={0n+B-UcA!p!=K05@bJLt3Xp+1W=S>~^ zRo}HLh-c6FfEWY;7(8zZAPO1r+_?{95Q08$=Gd?9?imLsMqaS*jO9&2ykPFb==83R zg(br`5%lGd7cZKdVjd9~gvV1ExE@N#p~vLt#b1U`>n3}_$4d@6?yS~NhSV`aPc~&V zg>3Ud?I144I_O?JPlAX$ORzTlQuxy6X@qPYBxe}g5sx(9ThIPix%x5`#fsHRH=V2< z;%N|fH6}-Z)V(nW6T)0t@4w-xAo#72CgXTOMKzpkZBku;Rx;t=aL<3h|7Oqr3!eDz z=2U%$tYhl<+ndZP$lKcA?1g{98~+Vwv;@IzP}=ntRox||o;r%w(w=>&+kB{Fbi8tX zsApK%hixCM@W}9HDA&85`O9)gom`7g_i84{OG!3~Usgevzpv!rlC2XyV(wi~Bhu+; zH4USkC+)(P6T2xG<=qAde2uQ4O0itB%9>xJ>~NKSi*yaHtykFql(Yt`F8K4h7H3@R zij{iiIYiT|=h(>Ebf-d#Uk5CyocXKb0x zyfbTcY4SNt;mqAcq#v^ESLV)&##G6nysQ=pKp6;k)bN$7?Y`K zl`hc$)=^dhXd0FU$}1CxD5ODmOFhpEd3btBSm`85XV5M$tgkGry876dYXr+!rL9$7 zT9)X!$v6$AHk{h3l?c}sUMEWz{NzntQ!5?qidsnUQUu(G?*(}3A;MZ!QLEur*lM>m zD(9Ef)wPJGf_4+FwAU(CsNED!HAyv`Ql%Fjl{u^I&cCad{#PSY;(s7b_b@%-GMjDdO}LTn-~=z8Xp-S9v`h5qFSz~ zvg$&xt)3L*`I)%xRqMWF(_g3DEs*hTN}7^C@2!)c+qSX{28l~*ecAfVa$ zExyl2Q>4Tl=_H@$h?_81oc<4k!z7OCWVRzr0&8))@IE4qxgvMq=s!$f66%W6#rElF z%$2yqN3~QZa~=O-65YqAIaK5h9_3b@3>uYdQGB}pm%&4IGS87P;ifoUVxMo4JKE`A zs;pyP5{}X=;<{@M;BnDWde}exPAx=YdLp(!HL&oi|+f3V3*(i#0k^hhSNOpr3 z{xV=mFjP}u^N?&`|2fgYvRL*ZvOgumH6z+{Z^L&d_-lbn7l85mqwRjmX2X*JE8ymW zpqdy!6)FJ-DIR|*Lm&keq(Fld`hHX)3)Cnu>2L=qMeQG?{NM95We9dIwOV6YDV7|v{DL+)&XYRqa_`%lvd*dC-OVE+SPr371zKaIQ$ zzYNI*bp##J4(9?k27c~e;m_|c>aX8D%rOs62U`!>2yqXF4DJa|x|H)j7>g}Xn7$~& zQi0)u(}L6c+jdiQb9CEw>vs!x8+9uQ5oI5krK4mcD}u2>s6%LjZTQRi+xTzzclZbT z_xb1f3kV@`n3;gP_(No)R-;Wr9Kl#aSVNw{oSjoWO&lRvJXzH{7E2(vbg8zrwW(Q# zl&%Zv&#kuKw^j@JzD_na)GleO=KFWQRBCNCwwAf*tpTmPI90wO1t`DcX z=YFtrMVx;CXBqqNrMXaribP*0Yp!uNADR0#>$Ry*V` zmPC4eHs*bNT*Rbil9km~{DRat5H9ZQ4eDrG{G=T|Q~_i2d82B82bYRWbB1}kr%(jSPdD(yFsVx8RHsXJA; zC!gX^&8E(>hKiQ!DS@V^ric&v_C>79 zV~y7jc=y@!EM}_aJ?(mR>(&Gs;*Y9Qm|qn z48QQPL={+m-G!sR?MQY#N`++odQ9n`LLX#A8)QTutU?={i3>5HjMyTJ*rJHoB9GY0 z`u0j}^vY~>OA#SR9w7))$&Fswjb7=EUipn)cgb=Yjb2%eUTKY9d5!p-(12M#f!4k5 z3`TsHkk`;Z-epufgj9ozr9KC~3{3kvr1pn=m`BKB=b;TA{dDl`N~z zT>i<-V3eN0G)Nf%2e+I4lbP8lJ&nl{eb58WM7cLPooP}5TLo?Dc^9Jo9IqobcO^4KXqW8|<~e#R(Z2mMr%#b!kx1i} zxxwl1zmh$6XnR=e4tabWoUiG{w%SP58;k47G?I(eSV>83aJXD27SYYQLO|xIu{I{H zC)6{y#3$v8mIRwi#W-T%MDF5JX={rsH^>EknIPi-d^^m5@>HBb;o^f~sQlIb5=w3c z(k3SR&BuvvQh&W*?-@?8gOhd3d&&Ez!(;1u@O@;SQu48LO9U^33R^xhB4SH`B_(%Z zYz??8poF0?;$KYq6*b`-zgRA8;NGn~33ueXMJyYY6yh+Ng8}6;&&=VhPO7UIY5qmt zuN$+FpQ#!kj~X}ddlvdV5a;oz8GZfMJ;r(|b;@&0=Pd5y zv;+W5A1D(CoSd`?9~a;JO2lZ3a8$I%B;@j}f>^D7y-!){^Xue2PFO;9{_h^+8wk?$ zq#}@xC1GxOnL2@)2*6y0T1I>gPbf<4_Uz z3Ff-Sl6e?1 z9;K56#u)(hG-VdtnwaezmS!;b?Zil)aizOz{15eW^pnb1qr**6Mir^X-c9w3hf(+8 zwgDmFMQICvKl4UmX4~`d-U=>tt=&o$J#LE_qye)9oTT>~}Isf@*%7{KqeApFs(R^e=4^gWWCiM5=|) z@itM~*L={jS>Yv(wx&%x5^eS(dI$v}@auLfqEF@w)vWA0_Uv#fqajlu-;{ zZg0f%%5co}92iF;JvYMN)L5cZ-qL;%p*D5p?j$}-VQ`c_ma`8n#5qZ}Vk_yw*N>FL zSr>SzO}5GkB!nr^3pO`}X<)_PGH-H-c#h0coX}eLTEe9cbo_kD`(avk^(qnj@nWg~ zejhSXA5ruD(5yGsoq#aZaYFC-(e*Wos**O(xK@alQ^U8@p_XBvVtfNq#wjSt3zp#%)=5m4U32Le0m8yPo>2; zIoTNvk+;j0%aHQZA7%#-`zCDA1wVBr(uvhu@5Rq16q<%kQjvGiL$$TDXpPXD?ju4C zEgmp;1jTOG=@Tw~knc$^np8uXgpj!U@?Jm7v%zo?m9t}A!viQIS; zP-G#vA0)phE7u~2KwGmJxp(uL*{bOtwMYsk)AD$9dffl4EzlA;&R6g$ppR$RW@uDK z$uxI3Y(As?`cTd2z(~I9xxrlsVQ|u^zJcY9{~kH4HLf?PdqMjrqudzHN6C)1Vq43( zvGj#gdZ$FYCWhhZs!Y{)zvU1Cb@+fEN~N$#*)ibhtKf9g{5tfw-ZuN-I*zcfH;)LT z$h!vsvZu<%@~k#w_Gyo!6|wUWp&2Xp7I`zA@y8`Ei8y0o;|$B-8XtA+l>zuW9ew|I zg(3`ENyM?avp%%5FK8a?8mHRrJ86$0wG4!mnBTgkDMK~*j>AK;O|jhR2aD$yqzNZ~ zj$BY-zMg&$mg1KquKCd}sEhF`{P(Afn+9SBma+$@GSZS8EN!b`va1HDT`w zM)+5AWtKq?w#9*`I?h3!!7o+YExd!5=bB4nF#+4(%cX~oPcFuowaS(UOn9~E9)XG;KQ{*LD{xQ**x7gGZgqDfNQWG)!fg`Sqo{^lo95+ z@vX!PcBnASWA9dTzW;qYBH#5%JYuQL+yVA(lCB@-NUp$y()n!9U3{E2Q;(PV-E90K zdUJr&1hNNjp+5Xm*sxH!IjVV4r7QdcZepNI#VpEhApTf`bDnaLZ2^r(80F)gzk$)< zu+F!$A5$+vP3UlTI5yV+Yk;^<_<)OUqN*-~zgfT?Se4e52keunFY0AzNQ8+(zo-EC z4e)3bbb-M^!mV94W;yeXqX$_aUi=y0DvZH~GT-s!O3k~J-_&Er9oi>9%xf`xS9c?( z?@{3ER+PqxhGql_hv6mKCY}u8-LqYT?)|Q}Y@Z*Cz$b2k!}uzlT<_qs9;etVeM=?Z z(_dSfL}yrpm&b#t3>_OJGa9|`Xft}*Ll24$B@{lx(eJIyg3IKdh+W$SgSXWNx8E?| zAUmy%a351*4_z02e`sTNwbu7=T8+w^C}36(eN~vhQFzuxXOjUw3mmx3#?FjvNw(Dp zv^j_i4E!0^xpx*wOZ(ad8I7I-47I*6-RU>AbtmCX#8b$3JpNhg_gi~s{?VNR#hAfc zHk~_z*hip<$a|cx+w`3d2Nw@-B;RpQlxx41G_kUvczKUPBACVF`YFv%+KDjBAD6O0 z9K9qb2JxxFy*~B(D!TS{=={~s{bqh96qH?FIn;t%dMj#MPzMVF|D zWqo=jHEEG>Tx~cWnVDf-4L_DWs8^$~ia7pg^!OB|b8}ITvJs%{OvY!C{2CQ>&FX9Z_jY zwIx2>E5{cu_80|nWsmY%(eInCIwT3$gm?rKhK#5UEPL&m(P+0~W>IvlD@J--}_8KjLAIWL`0jM3c`oRbJ>I<#P-pfPKb6P*U|VYgcBnpx^L?vw^gLjd zRkMF&P9a~Mf^`+HsCVK6oS@z^q2=`5iz-Lrdmea^jVlHg(FI(XYX6(c<2Mg%H~IK8 zUCtWWk`?A)QS#=KYH6H;1uNc5a6(KBqk%PG>K^3RYj)wxZImb5VQ-#Ksy&CDLJvCp zz1A29dhc1>=fwdT?Dm0q2J*n~tn>y!D_lW1>OmdgR3x%YutAK{Qb`fYy*!j$* ziYb|=hD#Qxb;hL9SRn<`d-+TYxqA|2I^8~&(~YX9v%BHxk*Ft8voMxlK@WZm5x6!e z?mua!m>Wk`)h`AkEq~CJ5P7zAGKRN?u>P@6SmPhsBZYbO7<#Mt^wrFQaVn?e+KO9e zjR(E)>~0QbdwNu=4642dnIU8MapKUkK7Tomj4`vkqrqjoiD!LLf^D0ui2n}?V)t6gZ3Bl8{k~*>t*Jl$lOsl-ZJp77UREkDX#GHs za}t?`AyS;DYi@(_OcgR%K(lcjZzFOSO2aaurrG*K`b$oEz$RIZDwbxs)c3Q19%8R? z6@kf3?w++-LXAT`&e&;2ddjFg*I*KXcX=q0oxj3-52R`eiypcl9G|JWJ$eZg?ZTyX zzOZyHTaJN-Yc|3`%9dE;3SyY@oNND*hTW$UTZXb(GHbbPrXQ%7BQacwb@s? z`9`W<(Ofpeu9$8UnjX_2*WR#Sc_ZoOjz%u4A5d>iYql%yOFWo9;&p4(2LL%rBj`-O zp(+YSv}t~FNB80wO)o#37wTpC;j&~0VPJM4Am(APfuE_H4=lwfzp_<2KiOgl+36mx zVn*&IpVp;|)r3gtlyRb5@QZnYT)1!c8PO8yY~=E;f+1Av1ZtoF*27})Ohpf<@}q@b zKeQ6`7Gt|NX#@=iM)(a^7VWiY2^!Cov($`$fWR$%NCSs6p0dYfT@R7B%Y)G^*iLav zuEDGcLA>HBS{LiIftz&1Z!xz-!)LwBky9K_Jts!lM0vCadWt^IPL_s7;05J-Jy_vy zkg$H5uzsqr22SG(hnw_;2}nBk&n6@d2u$mvF1=cYI0w2hC#n_i43zL|CP83_Hc|wy zUUZnH@ABr2#ZTj;cEzb&2ZKBaTovvoO#)TuBz#h|QfLP8x||;~af|$FL%B34%)*c%s#09;PjUHUq*R|(@%!vx=<9jSm^ZlCdU^c8K zc<0NH-z-V$R=Za2QKI)Lu1!eGNIhFXS$FNHb2GUxIL;e{UV}z7z7a@2GO}`QAwlzK z%3R&jpZqL+hmc(5Bk=XX-CE_zsyqh{tbZY(Tj;Khv6Vs8W!W9Gt)wO&+R$ah`OSTB zqkixJ?+2L>X4&VimR88}@N0ji0{nx>=~2D6L!ZOnveX_b=ET$iE^R?ByHnK4$SqD@ zqj8iO1GI*4!sx0Pbr2#tUne8q8dRxLoF=mtq3yHStP;S30_nB=l8@qc;x1LD7OH*u z;0M-O)bf;uSQRDo;!V1FoF18*jMg`Vi&cIr6MFQPT$`pIm+EPP6dh^5moB>>tW24) zg*XcTQ7X$>!fqb=@%>5x`P~D_d+NI_e=Pe9C=E43r$PegZoA`|r^{fN^<$N%Eze&K zkcYJMU%t^d5vg}~G>Xi-=8XCi+IjkT&K7jN3ytP|8!daQm6VVwor2aOL3Asuu=*wF z6i-l)e9ke0y@XTEv(K<1Wb0n>Ye7yVFqp4le*e!&!rad#!kn5#J{gsF_CGAEv}}^| zhsG9`PJaZ~8w}_oj(AYpr2DH-=})1iEOaP2u$QIp3n{86wmoMT0O5LaJA>@iYdz68 zWcba1t&Sys9U4W@>8&n#d^Y>Cnx>Ai<~$f=jcrM2fqG=`M_l`&z$}((z+4vi1;oF z{S#I6Vccc3Sra+K`5p`H3UsZ#r2whzPYc%kZn)t80VY-!7t}UDR1@9pjG6A2e`@ujD&d%ciBlh?QdEP?P?cq@05RCVBd*! z*{OH{voj!7x7=QHxyrB->ZlcBebm{$l=MSnZT@z}D7OuJ+TT?P`OygTPVg8F^ElRT^g|LINw!OFN#%{aVA9d?bN*@qX`@Q`O_6O6MQy)Cu-1%G`R zi~xCa3yhOJfM3qg4sv~GTOIbi{<%r}m7v@F+k8yBq#84^sIJA?>;x<_N02f7J?8AYt8s%LWYGTE`0;|Ro-uD^(U9CJ*~Xy- zs&(*l&~E&pCDTRyuTkwjK!vjwt&ARO(wNF$AApGgBVHYS=R3;(+yqm}{qYb44F-mb z4B80$YZL4{z{JYg$k-b2_mSuSy%Uz8p<{_E{vsuC0=~eetwS6gLz@c$fA@)Wh=MDKu z3YfAUslKYK)wb(d5f0hf(z{V7>OQCu8Pj8E_I=xQ{N5vpEsIT9ztQdR1?s$OYzzcW?H5RQHXUSdumcZg0HP{Sp{Vj;B@x) zZ%RVxp7$!zNtd8uoQ%E=p{w<(0=BuvQUzs!toClonyO$kv85|{A1jrmhDwGBZLKi)MU64N@Ga8$ zV}bzs3BxSbMhf~yT3}{OhTo!HNY`Q=vW+RPBk5Y+gcK_Ius-gA&KJFOy!@e}%AZ|~ zHgZOj$2V3L&~`xM_%<0^FY3{TZ>@_uGuE`aS|2mv{RNVybK&7R9+O2i824aaD%eB; zKJYIF=&%@@?r@u)aL7?Y3<0mmT>18zeU0^eq`Qz6$;S{ zz0H0g8lt}X>c$$6dUSSf6q1Uh@z2YYOUO-g8amaPrs>^!jVk+<6KA4LcHJ1%Z_f1I z>0&i6MwcUuto_9CrLiU*6??=;QtNQxO${ZrXti8u8VI_CFB--s(p03^9mjjphrf*O zE`c&rel&!Vzx2o1=N$~D_O6F?pIm|BVjiTH3el2ACt0MknIZec%=-gE_nbmP@#|s{ z)#ox&c>81CQgP1ST+HYTByo%2IZL-$WD}oJqw*;HFAJyx=PHI#(84djeTmJ-KrXBnZBZ;BHSE9Yb8}1gfzc$BWTX*Elf=l^oadG6aK$nA%KOgb2 zXd&5e=ZVKDN`?GwhI3nOXA@sJqAdQyaA3{xvKGxCvBE}`Ky1*dW&vR!NTkQgU9M`s zsZZEsMXy;gox4tximf9k<=0Y}_>dm^M}MMM#$4$mP$Y-T3s*2%lWs7^*W`wg=&l7r zK!poM7ds%F)SeoeBt?MJEt5nj}Kx2Q~9!J0Vp@{n( z_pVWJ`burl`7*dQVzwY<^odn$Ed}>fMK*E)RmDR|mrC1+IT`Jr6epu}`N_|9U(LsUCDHMO*E z8$TtWTyamy>{|?kpy`NQZ%f<-6)NbT^8k_Hq$um%#vWE=_3WDdK=H7T+m}UnOU2v z*|Pjh%`DP!qwlT|IAQ{oM@ez7BtJRYWs$+gOS$}o8c2HkAVcg!LGtwznCS5qK-l?-`sBfue#tvL{m0j) z)LIz$*eE!fLq4NB$OQ;~1Q8q2Ms+?9ulC;GIU3f{SbbIb9FJ}JUa;@R?ryireQv+w zfYyr{*i^smRV-*J=WKxMr3&1B%>~it_22^o-j?O3bUAvW26l`Z4jZo1GI;8}pWi8z^-1I)KO zITpWZddNl7hkWT+98x~jUAvJyFOI`)nFnvkXDa;dc$`O#wl=NYMHDBmG>v++dy={c zC)qC^zIdW0^Ydgt?TFr02$}tstReGVrFL>tE9!)VJpPjX;CP|Gk&#-Z;Rx(Rmhupg zFfKN%`*YmnH!UPi-9l-C+(LOx=^i`g4KqD^RH-LEQUj4jvl&2af+kycfNw~-c4jjw zv;2Yz_C-N>S#{tNOGQM!FhSs~?=j=^s)8>x@t>dWb}1GK${~2xu!5LYF>=lI@NXK# z;gW5)@T-H_WKnn;;i(M2mT7-A&esni=ynzyneZ)io8YlAXO1qYmeW_cHV5Tkzve-^ zNlKntCOpYlK|eyrmnGL}qTf39B#;m9>daQ=OT{nJG3Xc%=bV#-rt7*TZ{jX4q>_g^ zkUf_riju(S8{%0li z@BHd?-mHgOjoMbpfkE8Xfd^mahdpoTYO4w>TIDzq65kND27I~nR%ixk#2!P;xz7aA z6Yojy!rkMvOo)hTUif7amrCIu{Ieh!AZlFnmMkGN(-jGA~y?;jorJUxe)=X--cf;hMm;oZsn@g7vp7W5)cJFLXa4&cfEo==s~Cc zj`JN4sJ@T<9ClSIAREZ)=6LhPYis($sugD8kv=n-#;%W58|YB;g$JQpWg(y<`z1*x zkq!{&On%y_sV#Bl6mu~MSaMA{PHa;<8zZ^zv7^;OV_ewOGuzOk1{lx@>n8@>HBC4U zm&TePIhG4Y!S6MnEY~Zal#VIW0(C_ktEZZ;z=yASOiP4e!s6mqyL}~zH6MQO;*mGqun#-3n#_q;gxe-wojR)^0bjd9;TSr#~Q zCM*eVM7FpBb!j!-$eZw-l5{W2;|sdmTVLMX5?Oys{AnA)^eq^#*>&fd z*_AdIJ1YN_5h=Vll3H;qc+7M1aOH^t7`=jYt1J6?jXl^qsW&du8YXyXL+{LTT6sdG zBVi47aahOme#lqETbhM?R8?i?%8SQeUvcbq+Njay5w(_0talRN+nTZ{d=%ibeq~dz z;F})Xb9e`bQ>~tk*}s`U%1>wys~&IHxO@?HyZs^G9=F~nAspO_5Zo3|w2rsb?%KC& zwwQzDhN3pM{25zNV3oCHXIco~1Kr-QTL1igzi<2$Yi#mY5dU4U<)%e_fw0Lo(<|&N zi^DRRJipHOEnTfPHdkzBh}&A=L}nQta%6zt_0^~tP7;3tW_p59I9k2=HjB5subG{o zk(1moVPzQyksI9FjQH@0F3RtL&^V92hPOY=$p&fBD+tZ=90v5yD|N2i)01w){lFr7@_a(YDHN zfYDAsReocS(CGqNGLr8TqE!3fSS7qSJV5?|sPZez{Nf=8e9pusYx^*xkz$n!L zsUdkLqr7!5X=Px94ut9+QH56oQw85q>yM$GwZ-L3C39n22zD)Rh!H3#Q#zu7(`)Dh zW?B!ltjh@E&Ky3hMrI?XYeTf?)++qDRVivu{M`{;+1!5bwVUTdR{6OA^!gm;cDXUK zPTmV;6L#=3jC#%DOyb7sx?e)ZZ_}-1njwv<=yM05XP-BgUk39v-la(|#r3N)`xSW) zj|BByj!?|ff7;u0J5Vp;N~^LqwHR!)Zu_EWeYjg4qHB9lm$M-`gg)?o8?4aQtayEA zlV7Xu6E`MW09zwvsV0A}JQ5IO@M>aun20H2=&kayN_xoo*n-fR(~p3&ZirsroAa^u zYcz>M<2~{bybXLqXr#9z+&F~nitS$^Z1og0snt;Sa?-DL!CyNb^;PRckvXK6Z(V^h zKP)oG8X^4Vz}!{M#qVXw)J&v}jh~f)pPrnSr6c0x8(@4;I((4+7GFYit?DDq8J%{J zC17-8GbiE;l=XG+c6i;BCFG{pmQUwm|Jvg0ZyK;6=kq%Vxd??R#v`e8vb3hE z8=1qTADyAV6dcxVV*Wn}7_=Qvdk>eiZ)c&|yUnP38tj9CKk3p7kX0o)%7t!Z>gp8h z%z&@2k6IOB=)vrlH`=7=H&4KUc5&@?dyeUi9jEV^^ZU@U4i>_7nwr{NX;~TLOKk_I z_=Sb$GpTz$PK6l`hT8?K9urO?dGa)?bmJ@3d4*b${OtU7$yuDZkLgAAXe=kUUqUZ)sDRkMsHvcfYdtlqxG1|K@U#7YrHSmKSsZXIUKJZuKk6Todssb{ z7R~3cS_zc2jnin`+GjB8EcoQ)mtU1^bdVT4VC!OWJqtu?U(PiPs%^9gZcn&#EVl;5 zC*0^R$11PfORw>}bzVxSJngqBT*fr^g^jn#W81A`p!0zb0MXn(4Z?q`2WM# zIfQ8f1ZQ~69UK45j&0kvZQHhO+qUf;?bx<$E1NtyBst{Lm%4Ocs=B+rdcXC|3U5lF z@S^g1VWND*lKTpJ+a%*s*Mf>tj@zAu%C9+~)h!##cCJ@u3F|O>xPL|!Vj%5F5Tb&! zl>rC9m!gdaNKjI)nqNF+>$$+*5y?4M!1K#|yB_C?9}l^*^%<;&G+WkCA^dRM^X@w& zyyTjS0BIjNK%z%9=dNex^uG(vJ>oiA@5?je0sA7dH%IcaQl9Ajuy0mgUS8G;$nG16 z!+Jh9VJh>z{|U+L7dFVJ$vot<)a#dQz73w1+|cV@z&{2nA;u7R9Ah z=`xhvNkq#VNB>P*K!d+ICg}!0FNhM7J1v+V44C!nhroQ54~)c7VdmRFXEd%cpEMi- zSA}Rd&}-#01lqYqsQyHmnb5Z-^(~}-UA!cKnl0E4(*0`0o5LS-o@^P%F2uUQNO3<6 z><3TiYi;aZJb2_9%#@X`9O*7zG#A0fiW9vR=O+ab&PF2)JC%hw8;I$bUWqwwvk=Wp zRq7Iu`&VZ`YUgfKM83D)m{^vpI~y}QjPP81(b^Be?ndXvp3Vbe*60FU_SW6ea6w?} zWE}910B1iN16$S2Fc809$sGwyVX$Y*UKM!*#J<&U`MXDI56CLoI;tH&jkE$)&sB1iih96jQ)Y6x}o}zOQydqmtXeS11aOZ ze)(X1hl0BBn%%PDjvX!O7$7|rjv%?T~Hr4pRZd;^!=eCX3$&O7i zPEJg*c|4VNLC3&bG8Ejxr?7sEZgAy6hnGYPuoc96M zxfk=UI4TMP#-~n%Clc;i#D{Lfg9CpmlazRlcOKn?32 za^s%8>re6Tuqb^?J!7#6nfPqNG%!lunu`Bcl6Ze{6x_z+v zpLt-nqWbIQ92sxhtjEk(NKToiHR7c0Wb&A4Wyip_jXZ`zg6axHqUcsOA5%;q&XiXH@RzQ7||`%?t#tjo_^pI zv^suBQGP{E?Mk6QC($|{n8gAf^gMu|aG|oPts(F%Ne~p=?nFcGJmt6Zblqvab@lsK z?3_e?$(O0t`o*0dn=mcR-bq`?ba6C6J3H2+iwB;Aq5Lz4!mL=NZ=Hz{cXJlpT)mH= zIpR|kJB-dBg|4V}p(p5!0fpZ%_z4=Jqe4CGkMf;xzrq49+!sf z8o+aVJ0%Hq_Q6_vB5MLlPtkpyM(d+W*5k(3H2FmMzUG|3|v_y`X zBi0{?M2aARb}c&1g6mcaLPB8?jUgP-UlbR%4i^rB`-4%$dnN^@aM^<~3waSm^5f6G zGd+3T*3{JHl!f`)@G`Z%b#2{uljVLjTdo2hMo3j@Wboy8C4|v}FzhIsy9N3BgS|u> z<5_|*tm+&eA~wvip3!bc{G6i59rg#BmrdvfD~v)+;Z7wtc|C~%&PROEYSPL+Y<81q zOrdfcgL5s+AiLcUo26lGs&M7Zd`1Sv%a%fmyvquuEJUP)sc)WNU@a6B zj4Kob2gi_XMLr|%>t8TPKWq<5#Jt-?BosZ5X=5HeqAqmsD+U7wMEbTMRty-01?Erl z>?rZ@A)=DEG@Qa=(W;n4I2H_dt|>am!*MVPt%$_Dy zg#cx2b&NUBhVGb1OVBJr|Is=CNc7EWMLE$e6$y)1de0>9K0tlW+}w`~z@HD~r)_R3 zi{(FmDH4NzoLDe1h6XA>VU3pW3&!%N3;Sh#uQvd4a_Hw&K{yVMd(PeRR3kDM#~o=- zN~jK`JN7iDpbdE2|EtBV0NltGm&|fWin~#dSsJEI|qjH&Ud`T90^q@R9 z`SdekKu$)jAX{;lXlEQA0LXDcKDM9Z_*cv%qQ;m%;u?04_hB&RrIEOB2k$*6VsRsZ z8DH#qQt!c>b6}hxeo}c7dFYw5X(@db=%nc}loM!jDb##ae1}f4dUXTwpLtYjsR76H zLpB3VbbS}$BZy_pa(+rs>wNAE$ln?rG7UML9$lJuow1xA^`3X0afWvOp@=aA@QP$% zBxR$)r02$-hmWX^ng`JZO-R{Mr`;gFRCmS&Z$B$wS$novPI5Rl<* zh@=}Sg6Y=BA@!Pr_+u_Yx3*C@-JD=@tzKcf;~bw|H;CW;gBR}Xm5q4t#w)Dr3F|Gn z$vg9lwd1ZOR*nCd3>Zf(S~@Gcojj4AU8Ea5I!R9MX7?0yM)z|e?2?IC$~#!?w6$~2 zqODXp2~*un59EF7{LLYkrLXH|h#^ z4s~QsRYiCqn5|v&WFO)BYFiuDu||~#FOJ+HEh3JNN*9Iyrsy#QbR26AtFD~4b@m=7 zg7pl$`QcVT0s(1b00BY&XZyv@ z`2Xp>l&Ejn;fNsS@#I~3Hj2Am4%dE11)&ZkE~pA||xluzku9={n+K9!8gO^jE?6{|1tS1fr#9KLo-7 zfe&;e=8I+>Do;E56*@=d$@_}w+;Fe%J2vKQ2&GM&zF(n!hg_fWPX% zMJ6zUVk{8&%jm%Ya$OdCg(~JEW#sAat|vj>jDJ@K@DJ}j6f430%oxKQEk8$Kivog; zH^$d1yWFD7u%?h_`i4Be&nBU{QwK!e{wnww%o@+M!5qi1c^{htADcqtSG2V+baab( zlAk8*;ltPgCNJ*>6l=gI*xOMC$n^{zd)_EJ{$UAztb@bfFzWXKmRkz^MnZghYOPf; zb5JY`q3)!BQSFChB_2ZBze7WqZ8m!|+`L}594a;~f2&mLnZ~MXRc0>&>8NMBJ%}8h z3g=Qz=252J+af7NF>e_vtWTmHMQXr=41bJ2`aq;8^^^|v;7cv^~5CRuwb zzNJ&

DB1%s&Qm(S?zucvmPVrz*i#IvCz(Tep+Rii<>x4~y-0gmnKSmZO^(8F)%k zPKQJ?t9C3^)_S=!g7qM-E>ceZ)tDA(B6c|Yg{$0#K(nH2Nk2A!N&mGAVb6-m-J?6g zgYTTHi;t{98R7g)?C&j)nT&kzT2z9`A6?D7^7PEIA{HX5sS(kes`gx&;GLJMmI-Iq zqY>wM>Y*@6U(#M@xOo)6@W{Py!q9cOy>jb-;xOT${#zD+rD-F-hKuurEwdSB8lI~?sW+A3H_t(=PxDN>b2ROVh~Mp-z`G6I_Mka z;9e{%>F2EYr*+ASCQeZk^4(bbk=1a6e4Pd%Zmv?gGDXu!!*-jCgJQhrYuS-qL+o=N z^~G(MA5wRdMEs>hXV=8&Kus7m%zThJF`EuV zn>X7NV%{&O!4~TFu)0;r!&QYa`#y(a(S3r@UP|ht7A` zX(Uc}U5^Ugl&(I_Cv2@Iu$X3atr;wT_B|34w`SqqX2U zWENmN=MwLkOipElvL#`-*3$Mn38u(}pSkCJNo#TDs|RJDn;f>{>+!YF(t>T-K%n`B!7?s$10SiOU|@H_ivm~U+alzF&InDTJn0{RouzX@kf5Tm+) zL{N6tc{lw%}lh#>+Pzf)MND1m$!{*IsSn^7DxFQN6fqd%%*mtBVdp(@4U zgg8T&x1%MOrXU2`KF_hEUaViQBRYRbU9 z7na3wRYq6fmfcY5pxHsr&zYQmRQfc7b}Dk2`n&5``WXLPsW>3QS5#(#f%jeB92EoB zJIB};z!%wa{1rh=k?FI5z8HDq+GoM@oc*mIt7@0Q^~mG#u6&4qrvUkSlxn}UuliX) z^{8-acdN>JoqEqe&KEF708fiyXSJTbJHR z=1av`Ne1adNZvzQo)#|VPkJ_o0ad-ap;nvC8Vdnh=22zF5Cn@jY#xTvOW(L2XxOI z#7y%#mP@>s9VZ<H1og!%*#8A@Ehs5wsW-HN$I`6c=3<2VpC7N0=G#ikex*yB?x>* zD_bN4*tk2A6U>EretBXssuJ9&0V>>o$Lc=J6Yh0X`au`H9Oe71raFWw|A@?D%>4wK zQE)BanraLw>l*e+)<<2zzab-kaT9!W03H*W&)1n4UBo)5*I^`znl7`oIrD)Uf+`Z2c>gVX1%IOA%4TNBbuo;iNH@<(uQNC+Kp?z%-C zJOSPqx4mHN*xQ1blDRbdhn)`CEet)j3biogFM6G2iE_%h;SLE58 z0XEQ@N)2i*5uJywFt2qHzl@t7<(~Rz8TpMqNDea^SGH7}+L~q7ve4(-FU9AK%ba>l zAvY-MRxbT>Y#!y6srV^=ae>XzSfcT*3fM*RLb`HnBtW7Me>M+v zGTu*-dek}b<^IBi#V{KFCe3EPA4!fpzF?3NpT#B0w^?E4G_aSY$lNF}$MRg)2ZTnU zp~$r52R$eybB;a9yyKnxx`n?VapR0{0~{IwIz@9HX{HIvlBB!w54}U+2APz7H+*OD z??nG*6I*yl*?Oml!WNAh}OeqHMUAcREDC zK^$Q=a}h0cOU8BQC$5$4Jml`%>WLTBWDr=9q27z!6bAy2NA6+V)lqM*u#l?r1GEN4zS>zc=*jrB)|`QAr*F3Pzd=oTzX{mFA6w z&gSc`GDUV2fXGmWe*sUSGjRbi7)}UnWKwUZEr2t0tG;-!xXUcfZST>?G2E|d8MV45 zOsazd)QWGezr7AvK6Jmy(hPR6x7EHPGve8#S?rXz*qHFnv&-TYLVHynJHUMLFT|9u zMfAL{LvIdrG%J!QYBSWCEE%^Xtun~<9;xaGwU0?=Yu|CE!jphGlgS~NH2EVZFhIyS2;miMjz!;^0Ni6UjtsB(CVbw}7~ReoFFD9(I<_ULl40F{<7c>=5*rv3 zdhQ6PWd4elWXttA#FSj)EN*j5<~ZPA$aQWNI>f22bHj~4Arso8>%{cm4oyK&qd3|% z*47ix{fVfyCKwe&2N@+3T2knWQ@t&JOdcDEf0`hts~EWnH-vn^p5{|@4jaPa zcUMoHbSnX1CieL=jg$xVfxP8$)J|BQ{c;Sa!dq=_3)_(ZoJ!|8hld(WLBt1{SD)%I z(bO^iYui41YXlyXtAf{*EoU1GHXZSsQj^;{>K?=wDzAFOiS!}lyO9QF2pq%MDQx-C zte*isoUoo(Mp{Ix6k9`B+r9Gk$ahQZ7lBftXBnkD@D)n(GLAF{4EmQ@y$nWM{EZl{ ztGD*fjbf|j=t6@T2tO>bswL)UQzyEbV!ddh(pL7qH1=L-I<%9fT}J2EGumOdBJGAW z243h6;}?%M4D05OlpbdPRv&gY1S7I$!&fI;S4utND#&5OTKVk1a-^_zhf!-Djr;i~ zupyh)3IH>Y8|T146!hK?WBJpkK#&lbjln^$!P4z`kS%Ra?{w`D(d)c0!~ zfjz#VK|Y=e^%J4xuY$1`4#DzLwRQ<#rQ>banybqtY2WKhbKBHv*+qCf&d<{@-p^Gr zyr17q9+@#+GQr3%%2V*LLGT*rSsXk;5~J&7$7N&dr4pTkhiPWI@R*Tx*%N2C=uJfn z9rBNI?2=3B>Ob!J18?27V;AhwXKF0xaiO8yNa%?MdkyvW?9|+~A~Kd(aq%ulb!*xV zwyb&C=@W5iWv2Jz1IDax--qP%5YeC=hXJw1j-IB}Tshftcp@JtVgvL{u<)N)U`nif z)7IKkaxy_&@tive6HVcAMGJF>0wk~I_lU5&f6dy5$`n2)6X0`{LI@pg6~!zY>Dela zKJ539Y@EXID$X)4-N(icnT(-bN8V|ceA)uOWDJSBJbSyzdkcs0R-bh8DWf@34PyE02&73i3rlTQ~hTcMp2){NZ z&gW44w{d_n4E2KwQQ$|$9f(y!>a{CVcvOx_62KuR6kGr>=r~WFl5?Dd*vp_NRp|XQ zu9ZAD2g%Tl8GLK-NLm8SgL&+@aynNAczfu=We)GBWEzTUnzN~MXB)9nRi{4KF0DBW zjE(p9p&?beE+&;VJuVkpU2^w&tovds1G@nG-}~3ei8%0(eE1NtU_yhBzK+RJpJ>>$ zP`n1u6aL5G%$vv`<0@sW7;Gw~A+@R)Kks**ixoR!xlk(`v$><1yF@g%?x3;E9xH&m zYp~nGXWH-Iy6uK2esa?FX}5!9Up+Z}1GhY+NO#FM4wpWJ`xTs!yJJH;17LncL(9+9 z9*_P)Cm*MM=!4?cbs~kGMyfAE=d7RR3%=3yi*jXy%Dkw-J@5!#4#=+*yUIA+DG~Y3Ub(`__WXLb^v_qqv#<`Qny` z+KjsZs={aQ#FgE|r@mC;b3ScTaEdrjgTMBu1?I!gpDpG?pW}n{wv>AGYXp7(=5-PK zf(2GD1lZrtK2&xg+lCk6dSe&oJry9fw zB$SmdU#|i_FP2CxexRegT7qDf8WI)Mn~VM9uJgej2Czze&w*a^O?uqY@*z5|7JFGB z9P?C5yWtk5epcX(fcSX{`t6l{>(D%^nfpon zkg7keedL9(@~+Ga@le05utiJ&_bwm0x#jE_*i_fD>Z(nsSnWNS_2X#w+hnEz^Ey)x zouHjT?SNusO;siv4m*fI;EDNt;5dlqi=Ve~j`0Dc5w?R0F+^PW@n&MCWzL0OjN#S( zMr4GdsOaKL-LExu+%oTYS~g_(^-6q-fNtk&4qoU#iw54C0_g^&7dgOSA?3b5WQU8t zN$qxJ@{F+7=@V%LL8_IISrH5QS#AI1Zq%&k%R2U^~$L@EQRV!k*9Mo{0J#0p8zg*fNXV6e0#zaaf>J8OdP zf6%vYzD>fox~Z&$<`lQYV1 z-Ll(@!?0l6gOB^&Ka&_gL_*+ptWlx!zXNsm&dH4ms?j>W3^ zd?HsLrPrG5;=b}nCqMs#EB~M1CC5@={#1M*ASYuWAjp5e<;MTRUeodaP?w4|t*miZ zTzK7FpCuAd@sR-$t*S68>y1SGEq*NuOihQhA{vgGeX8LUol=ezHqs6eM~VsZsGUMd zs1)o|c_6^Jt>V~EI*$pxdZ*Kp#l$PFT57&6)d!p)FpqK%UF7HgaPt{k1a1_6uMxw% z@K0Q3cuqD)C%=`PI`W7NGEJimg^gvR0Xdly3SSI(ehku!VT#zh>cT|m&|1hc`P|BT zt^!ySB_fY;;>b~ov!25xc$JYoiHDskCDpU zG2y^-MsS#3HTBW$t)~g(QYa?P3;7Lg$cac^^2YLfN1M!^)B(PrUqOUd$Y-7L21uph zIjoGXlI*hSo&btYumC!Vp^>rRVz|=+<4%h>z2WfH!Bw(wb+;vWjm=gxwSRghU8%)e z?{`y2Ybrq@)B@;L_-YF{6BEc=?I462H`J2(I^T z%U9NeFpF_4m=4?IV5A}y0+BkQN7~a1#-aEQ2oB678yt%;6U31ekT^`6cw_C7Dk`I0 z{58Rya;H{DFRicO@FLo_vX*OWxruc&+5_&N-}&>AK04X`kB#@dpP}U#t;na zN(m67(jz<}?!89#*(Qh&Gtd==q+<`cB&P(P7cRCxyveIlJec6GM8G`8Ileg-;Gdi@ zJJoy2omT9F3=vP8QhB-+Z3)K_q0I|0U)zkh%{geqq72F`qPsZ;-vJEp0wbloW37O~ z{AmGPt!4|roWC=%>RhQaaIYR8#bP%_mO-b!mLkcDZIMc{o|=dFLKh}%n~FU8gH3b5 zy;Us~9M}Ga#j3}+hvtili(V_CAhjJ{=af(z(&__eFg@*rq4sfFi8N?#qtR3@zK%vP zUHhUe^z7>FRD%|h*p>5`=}u6cL*K8*uB*eyt*noltxdc7Dcpg_nlYIg<1$UGneqn( z_dnjVvMtY%mTYK0G>`DUI-ik<=WNNkrZKUc{9>B4=4d*R4&}59itMIvkbQ(pqR-st zuP%2J-2zG{RA@5g6fp(%LM~fe=SGm^+Pe(4HkW@oT`S$YLmg@GYGeh+km!;qN3zXg zpw&i+8$P;n!qF(+gA3LR!=HFJsG?{OGim32cSKrIig?uX3R&0pAT4euR%`G5R<0C1 z7>KU1qg=^)NFjtY&Y1srlwc(Hs+?+t^j78Hd35FP zy=j2UxZ^P|ZxFlM(>qegZvS7V}1pD}?te@jP z9)MC{2G?TX^$lv*xX@`5pmi5L&SQbZKJ2y%3~gMFfyj&(Fm3J(Lr%Xh4`>0WPk>S2 zHt}9KVPn82oMz_E>Y<3nXQz31~_j$}?Y&hF7 ztHJhp4Cb6bC(mytm_}y$rc&2uW)kxzi{~-5;#gs>+l+NVXQKr2V*F$3!xhs@k3~67 zVNyYF%(!nfRwa}SqMcfX)@ftEN*zH+9l@>}p9DoJWla*N?w)%yoH7r~elzL-q z=8UYH(M4C>16+m@cChZTU8V+W6L&8Twx)*1U7=)+*WV+Jo*1jCpf5{Q;WxDDnr)=a z*DJ+J@)FujXidbD7{@?lDtu}dFaLld+%Rwe8Jww88w?RwxdxR6uefMakhSJy}&-` z3D!IOe(WHCG~LxDoPh8;zN%&OCrpuc&IW zmQ6{wg`O7rEts1kuRW-2q1NL5DmEd)088voCaIgt&fEz4Z(6pdI8jDL^?sqh!dOH1 z_Or5N3G>+{K8Lk8L=IN?Ye0~@x*|NSd6y=OcNg2+Vn$ehJWTmi2pv}}g`s#cYIQ>7 zXl}~JuF_n!7}k%dhv-t@sL`y{TseWchV{z`kax89UC#Y#*)w!IvCm2_q$Ed|C4)7G z=5*KnZLN@W)wx_epu3CeSC$f5ol(8(1l>MOYs|CudBC<6)=*cl0_k*8xONY+>60ON zFCAQpraG3SXir7?PlWMHx64ucORnt2@@GH~;CQMZ&mt8!e2#X`m+!-_XE4|gwQCMG zwMIQLV;Xrj=G*W}r5}q}p*5(zke*5k=AI>$TO-t|YTykowY607Px5A;{X!W{zA9KYX=c#t= zxE=H2{eBA`1aHC(2&ZjaTqq3h?FB$dH!dK;hS2FT8^d45{A#9p?J7Cjk&i^SVSWgY zg<3|tTB9_#&?#oeQilKSj?(i5;cc%@xfXS*r|D5p75J@U(q*m&iZG(JhR~e{iPyq} zx7G?ar?0sx43G+ zG)E4~S{2Q_UVY{+=XQtXYVq2Py^%F!=f(oqF>9y@YwH~Rs0o0`?q7B972ctt%k|K{ zi{q>tHLB!o9CQeG03W#+NoczsTTho8Ne~J}NbGV%gdGyV2IadnW1hNYY!+b+x^Qa!f5MGIC8U6U7K+Z&328bD$vSU-z8?rs-2hNET`5lLYzx1g{ z(@9jx{X|oV1Ea_2!+gJnj=SxBa%uXs&RCKy7fTwE69$aZzflKa-+!FN_0M3F>*L%_ z>kbLKyb^brX_+{y9McKR4-OjObQEL8GjB9Htz+KLXuM|$J#3k5 z9>-Vm9{{I!t6UM;m^DHppXVd_gBqk$iDyk%mWOJ!lvCRABfm?;ntHDCg;r{18p~Zd zI-67RW?4j>74q`ytHBIN#eQv#=ZPOED@f8q|g=kBjAC55Wj^UA>kZWVMSf zQy$IY<~ap^#OEME-)*r8-hi9|<3O^Qz~gDdDDu(6+nF$92A3~&Lf${U&b}NeJqL82 zNu3Ga$V^&qGPyKq8LZNHjzp(V27<;huq#l$;q-k+qu?};FEzuzUV7E$-GLlwvl}s4 z-tS`3Y`a{g;dr)E`4IzJ9yPLf@(*1g`n>fRzVXYLk~7^G1mF;9&ne`U~6fVNmmcSpa^_re7!VS|-t_tZk1CZ7tz7TTX$O&!aWSEvM7L`BuDNv~n-hMe1%F z^ya!W&jJ;BT}3}<~wuL4CXVeN4TGpH-^oDnaqHKqs>+2?Xq6^?(`L+ zEK2R$M~)}ERLSNeMO$vZR2)B%C~m!3L(v%wWKC&5xT3sC+Urc3qQq*JA7#O^%R9pg zb~RNdG?l+Zl$Ml}(*!zHQ?wZON+_LcUIS$-u+gGvrKEB^CoMX;;}>twOx0;04{3ip zeU@K9mtrk4o>S>^U>7_q z6#u*_R;Zu9EY~R7ie^DKO1(LO7q3mMC+hiR_MX0(j)7M1MS_Pt7M9p5SfJGqC7x2N z?kX&LkeIG)Gz+(udnaVwrjq#@0{3nJm-!vDRFM}d`=#&U)nLmevNHj*QcJuj*C}^~ z+Tf-EqV4wE~wNqBdomJ zQr44LDbcF^;jAsZ*%b&GIxydWSkLOe{@@?=$zO1yQYH68ve1zD0jc1U<-zO|kW-V& zFV%Wn4&|{;gUkUweUF~~^6$^JRisCMUSWn=Hf3ERU8;Xp`tn!=bq*`aeNb+nZu_v0 z*BcQ2p*+Jh4YNXTn*+)--QAG9z`CsgE`|KbV__I{S6{^Tu0zZzza8=I#!A| zp{mDAEs@oTrp0mE9ioKld{{@8E;dpb56VF#X(QpXuAHM zT|)q}NV~m5ZMTj?shhRz9vsLTa-O+3A#P(fj<7MX4)P2tSPA`$`}Z%;{?NGeE;89s&b&dsme;}LI+mp71<*~2PLKw znuEj5wSo|R;c=_1@K?pU?qaw&VfGtP$F$$#f7B?CsaQG|ei=n(&fK~xO(0ZxQ392< z^)n$r={-p!7V1wrdzvnuh|~$l$uCyD&6GoSOFxk6=auMjZ*=P9SMqW?lK5#8huplk z9Oc9@es|Q@3J~^tlHHQ2D2;&r^})FPC`PZv%yVUbsWu#bCUZkWs_tbcR6Eu3<|!Cp zJLAEG*^z`3oDAHhBg1_%S+GzjAy7kX%R~G$@uxugfMK(F(3+{-YlmPDd(_hS2yHkG zHWyJ|T0x;^)56NHxnE`PF6SPT)Z55|1dQ>~ExNrunJDGavFdT2>gYWz9&p%yb>GM+ z>jzCCY&?76eQE;r_JL}@?5?!++qvIn;eDd-w(-2?*zCH2-g<2SeFXM#nveQM2U=z7 zEmWoJb=6m}_ExY~+@BECmA1+&4Ktv94Oc*`9G@Tn`%TnZ%1=L~>O=6s+o(gj<&S8V< ztuk+NE`sKDZiN)2y}5mLLI-1fP}-#)_F!smGaPe)Jc4-;TocJy z7Q_X!a>aDEDiC*(Srr9ie8LR6M@Q7J>rgev>SNKl!XfyBKT=|`obx2#j$NRma`A1n z89QB{HSa+G%*#*D%BB1BN;Q>sDkZ%IHi-0g zRAyJs)t~RnuRqU6^!0)C79$V%`<@Bt;70}M``u}9$6I!H@~}+g>+E)=XMMGFeZunT z#VU<;Nmn&XqtCTN^tRJ%&<1;P zWn6LAie1dCS z0I7lIDFaInLqB>1$nRNcZe;fY1h;UBEcDz`z=zZ1!X@C5Y<<8AlvqWQ3&KR(TC^U? z!RFtZTg?FQo3B_-O8)C58p$TPI_&8Yr?ma7HW8${i_KkFPy1Qkeg@CiUbK`^lRCyt zDpn0CTey{)_W5d{^d*GyD%Q{EaXXFvdIH$h>GzV^{Q~%x(e1r4>;&8&+(0_hhfrWj z``UD?D&271ht!=!Qos-E#t-Mw60??}t_Ww0^DDVLrP^ zvxI940jtH!pJW++wkfCYdpiu|X9KZ=fN#s%+$%j#447>!(zP<|yQj3vS9*~%!`NW! za~ZQxTtC?9)sCVVBz&nRo0{WO_HKWoQ*Kk##5h)9LVRy{7v^Ka==IC_8au9L!NF&D0RR&;A)&dnqfc6Ya?y0chrB*Owsb>gAPJPB*}k;La_A@+e~d|U?LllR zs8!=Zly#}}6H?{bM4Oauckn679vXG7s7NY=&l%S4ROQ-S1ijtiy3h(Np^_o|^g zV06Umu``3)%oJQd5>|{aLSfv)k})@`TQaf?hI|e}$5a;|%DmH5j`j<*;;Pv`t`c3~ z)JIPs>;%_75q6V4dR2&J<|JZ;yz3sLTHh2GC!4no)V?Htqs!(L0pgQ!$XQ&r^Vtco zqsWM(MT79ZX!B-wN+Xkq3A3YLS(nyT8j`NYFLYG0lS96{!{6bR(kf8ebt8~O%-l%N z*qXW0ih3hj-jykpAIIye4i}GdBKz z(YH6ZTNWBr&Q?LmE`NDFE29|&>@OG+P3m&srPp}p%n3WZ?tACIS@bj{9iTSrVU(0s zQPETE5U|`#j&x5iX-R6SXPgP>80|qjqH|0ZGurx3RJYlI(yO%FoFs*9&3`U@I zgP$Ct7H6yCsnWqGg?LRIj3M#CFFbLuENSg(^gQJ@f3qal^wMe?uD5rbz9Mja!n8x7 z*bZWF+-*z1ed;~=9_2D(0MI1EV6`_)Ll4T^{&oiE>D3QNAuVsQO2ss$!liGiPH)oXiU< zBw_XwT^CCI%ZM5KKA4C}o%XGX+EH975etf76t?(ide~Ek#08+2=gxZE?36zBPpqJ% zY`9o{?zNz_G)c^nlPhdu8^a%e9O%^ zfI3NVtQ+FdJ`FQesSFbC4O4!LK=yK;9&!t|vY1g$f_#4{4mpN^S zS;P?caIVZr9z9M$; zPvI4m5&VYFHMNZOos`gY*WAP+b$Sws)tD^B7n-UFQ1F}A80BYlq_-ug-fP^Ux4o>Y z^@#*Bk#TiWF~l6$ZPQWU`!Fi2>hC@=RgQaF(9bRX^n+d5ncqB=7iEe;5#i?IEmL!@ zK{m0+IqQSU@?k8{PpZoI!@rg#mI`dOz=u`;07D+2YjRFE*%HBW6S*|6lt*&BGgTyr zavDNM+imn2U1;`2+YcAoZ_UWxYw-M}IFEuv>hxj%sk9@J{8k9{Xf1r|W(mkGQZjSS z!xq)Lq9m#>120mA zC#MSWlLZvjT-eBRb?ZBWD}uhAi)r`mw?N!l~75y4tPw)q?G|$VaC!|&M|cu=3wlBsGaPO zhN}JBFCA9JL_cBR3UO?l&jIQL*iH=az{)*g-chsyY4mE+Mj?*9J_z%9$ zsk^eU(b7RBso1tFwpDS(wr$(0*tS)%tsUF8tsOf#Io&-*e|;|cX00*aU$EXe=X##N zxJ?zNO4;6wpSDCxCHgw(OQkzQXdA|@FL-U_KVGDkG zV6CQ@H-b1twMUI;tSYNA^DGg?3nx@>3VWFwX`P`hBLA(o;AfH!_K zUx^2M63Z0rhvKp8!o{y-eGrzJ%!-O)nk-2>WyPx(+nY)=B7 z44-|$1pe%VLi1_{6BZxTQS;`2YWwj9IEuYi*pq}LLT7P9K`Pzuqw($nRLzzZC*C_@ zdct;7nRpL@6aBdT51wK|S)w52T!!$ou?*p3q+db$$Y1Np0unk^AKCj(%;x1% ztcwt3+4;(;<_OvQNiT?k(i;Z|H;ddI$B3F`GWp7xxr+SDS63Q)`SwHBH(@S5HP15t zj>_8deAX@bLvN3dsH={$uGJ^Gv@-WHPt}~N>*o%W+;l{Wv#yoLR@>*$@2x~*LhWSe zPX-_5%O~a9ChhXytB@z1y61V#&X0Ib)k?SDtL5)HgeKR^Cijd~Eh9OT8lY}#C3?N) zg@Zof6Ju`a2@9QK52?Gxv-D1Nj#$jCg51-5`79OJ-_gXWl4Qouq^9XEZPo)B{h2&E zcrY`P9I|6u61w;d#rRK<%Cjw!H;FLR%hrX;_!TC^zcsOAc9Uu`*vC9ZL#v(>wncil zcf5-NaV@!B*=I<1u&$JtXhPYYLu3x`{{bJY{Ozx#X>M@Kuy z{}{zP{f|yRThq!O_q)@FrTq<4V7yxYN2{a=T{Oi1Cvm~))Ih;5{ZGY+tYzbj7_`U) zQwe%1Wh4Mt9-O906Ou4xw(J~x)x5Ye<$P-*;br4|C{Lp68rWYlw}s){5(k2_eR0C? z1B*lp9vRKj?Y1ZST6KDJ>a>^Er!224uHzi9>ozk`{)bQW^ZugK_AMzN5#zOD#X4o# zLp54UKOs471Z2^fu{4n&3X6X8Cr*+6Jg+nNf=yu@QR!&YnQAVaN$#TT3XXrdBk6$~ zXk3QYQXxW$LmLz1$y z^5mTpWVq)0rIr#p>&#k58al6a%Hh_o+8a9K-q#T;wG8VLUOaeQ1XO#OuLXVb*}NHkdVM#yD;2^qkIlpBUObna(q6Bp@vc37x<{mr zx>Katcemq<9V5^mZ`_xedD%WT?FbnJ5BCBQzKA+dGO-@7gu*?c)j=g62^hzYJ-n$d z{Hbq?-7AQMkK-(2dRLA^L`MA8Q)ii*CU|P5xO~pPM>keU3e%x>oDj1e5N6;GIEWC{ zMBk?tr_E{oU~gN91YlpJKYrI%a-kDdK#k9dH;>Kj>v*Sak$l6`;f((>q|HXH%9Uo< z5S5HTJ^0ogm7dah;vZk`AAxisWV?aJtx3bbHM0M1Fh>l00P*bE?uNX$8)F@v4YAVS z0fDYUwtL*u}GD@FQb$>4nNypuAUfQhWF zSLRR-jBogp>7)D-rOQ1SE`74kws#UjW0Cwn6WKG#xw!{l?mIY|WU^&LZG)#5@w;+` zrY4faY8Y)4MF!va(JXv2=RN&C{Osx{JYYVmd;CnD{Mkzo=5+L3=Vz~ku0)%K zGf*`I{`^^w?{(4b!7Siq{~;h`5K5qbv27ReBL4Gkgf)J-ekWK6%>n^w`trd#3^FrK zc_f?!a`umE;rt{f>G27!&@!5{j38!gr2c36h3}%+)C9k16YUbaS6m~{$b-g#^id5B ze-8e8$sUK#J23BHf32Z1mnXb$R`828Z1LQSYU zd_mI#Y1%q+#w539Bm%CD=D?VE&D%*yECS&}w7^=K-=;VRc{Vg6^fvA)F>=RrDBJLC zwz;stUzzKBQ}&RP(1v)O-0^N7)HlvG^FZ4WFYckr4x^Y+CYIsa#H_8MA*K;S>$@*o zTh>?w{CztPI*|`x`TEie z%_k(DVM@!xxi}hkdcd%#2XK|(G zn4+iWzm{!WKES6nHJ{i`^u=+o4D}^p8q(h7lyj%j%L=+wFpWvz-$hWNCohgT7$~x@ zDK_ObP!EPEERMibM{r=nN6)aWl)-@&Rnzj!GP6-H<<@RBRjWqB)C7OiDnGENSu`+V zGCN-H>r^_-iP!RG8dgwg9;RH{2oJLW#vqMftFwNf;#rB(!*YHN}F zRNHoj;C!&S7ao@b6%4{QAK@>~f%y9|Hu!Evbox64a$$h}5fLwAM|v&+ivg{5njEBa zRt^f1Y%A$!if)vE6ZBRT>jp%V=>jMfV{*{tOjtiwk|@J;W` zzut^b2EbJ3QLiy>@Z=|EOPO5h;Wrb7`fs>AHnhAP8qvLqcm84t%=JbVTA)c?$QVi^ zb&{qhlnQw;?_eL`_vOEooO!V?#cNQ^orb4n$u{{oiWqgP4{b>dI7Z@|5ofcPiycPj zFdB28o*dBGVNuFrp~H^lvk_WV5iG%Y+=@*w+A4FEl%bi%3fzq}R#-G94vn9lX(m7n zC31$2nk5L-4mqV^WxCTx3v944v48Rs6=A?ViU#iqC5x&tR96vKbk1lNSvn>=O=>#w z>XT6NP%!6jn0=AcsLE*Ib*g&_J7v*1e62*bQ7ao+7`1^N%ZPS5lc$RJ?P==|XhI{> zt%&!qQr&T0FzH3bNJUHZOAd&1Zyc{uDE=rB7e%@JSzBj998#GtB7F%rQ^;&Ljd|x$ zv_f9N8d|}~ulx%m^@Rw&OgoomXXgL|ZZ!ENgYuWH=79saH#)YYNP74JT+E-ZPXcsMbP zJ(P*UC+rx-+|gS3Qyk*P_C30Z9-Zsf@|N2$;xNhsO3wxA+<{=880Vb2lJ=5C)X-ed zrp(e39s8GQaaEl|n{H_*SnG21U@Iq59flK=t_)T=ptg2%dfazp$XI=<#gyW-QhNZx z%hp69g(%Fqx>h}D)1wKGrZ_?8pFJbFp9;m}V(ZxZqRG}T=7Zz}HoNJ3`*+2@fcSG<+T2VmLk8^z^D5Ts{kEy0sSA61IFSA*ggv z8WtA2A>IS%9Q5#pcB6v{tG&!Wf?_%A1Ie8NqlG5oj;p&&B1F4S7G$y|sj5={_&HXn z)2#o>%|^@=;h{3af3DO|cs5-WreXF5@-ZXs4_SDn#~$elr{GoKsCbj3*)14pHqb zp87xUPz3cD>{8+Pu0_JGxLoMw0Is5w0_vob0|QnWVwre&jzTTO{et?!_}8qxDn{q% zWe;Njzc&IDuZ2#Hb;q*Sg^U0mo>W%>?@9Yf*Z_WdZBk7yF&6cy`6kbiUPpFDCAy+n z>u4baQ_5H7X!)uV1)cqCuRr_U(U4nsvu<+ha6y>N!m=lzuXaH#O|e2vWk@zcq{c$D z{mA=;7ak_}!&YUT%#>O;@rQq{zqOxHQW6`)f0FC9J6M?=1!Gu46o*5_#OQNyG&oI) zWU(ODsj&-54`+9$nk=fshpF*YwE6}M*LRo@A8G90ZfxxJp>{+gUe%W5r5C2iD}t1$ zbemx55D-yPl|+Q^A4ydC@8KxU3OH1|?_#T7;gUk+&c1aJqTR<#_Jc>|V;7ohRN>y*UW0>K7;>9$BkzU)c$!NtC&(?2)X z(u2EK9d^FGi0(8flHe)bgpm+nhx#E1@$Tp=zweOxQ8@0;uaSTrs+a-Vmo?rEGJ6`q zy;WbvSqwg290WfhfshT0DxAMd-Vdh^^xXe=gKx(UH2-#t1)3F3mG&X4?O(Q&%7WYe zxbPLP462q6i)}$e9TcuCq+Uo`v7`FC&}@i5Kl1>p&P}$Yb|h6*rFB&C&#acPNL6Ml z=DmgbcFE2)!0p2B4ah^#DR@b$g08wDwWwLvOs}Hxba^B1L^rl67ioB(ik5b|1kRuj zI>qf0>ep;xV=G6iHE6va9wxq+%Dvdk-&3=bL&<&zv(y=IT=C0kYOl{}8rABmk+elS zR$LBgV>Ee0hv?}p6`+ic+JPpTVXHBN9p4}6?%_w(}`Fj^zA$#tml`0W1NRD^LDR6H1l!q z4Sl*qy51({|Cyz<^C%vm0bxt(l28S(q1SPO+2}s&XCsW@fBy%iJ>n4mYQzIrLjdmc z04DMM^-%OYetN$X1H(fBa=br$6?YS1HYF7>wZT6x*q_^MfM@K_9>ID<8u?7NP&=ss z%k4W(pwI6Jzzok%7$5|q?lxpkIdG8vnT^o*gBTdnckKZeVYsU+_m_j7uZm))-|q?lP|@3olifHE_xFgz7XKKWg@0S zaflYWEw}f6H;|xHE2UbjE-4S{!@>5_m3h)17qNMC?ecOrC{(OG(c-14M}{U?Nd?(6 zt|-d1GK%+wn_Nq8waV->B;3%Gdn0WT-<|g_Mc~)?rDb3@#HU-Q?~&88V=}v++q$1u z+hhv8H*VF}tTE`s*J3aEgBzdexbfe>NdoX|ck>F3)N7XWdX3ZA8AgI|kYdVSFZSPM z<4;sBtBR+b1lQ1QgI`YhkF-acN!vTvKz=O!nZq}@c54e@m%DeK36K;YQYS*->pw6( z{~c7g2U+?vpn-rWDE^jmKe?`ZEqy4e3&pC=p0$v zAxHqlbu>nt2}Xmlv?UU$1+B8NM7-FLEao=072Y~q9EPO-Hw*pbbm&w-$8qhbGoFpP zS*lNQ4kDRifU9)FQ-+R})wS*V^d^RBlP+rmVXC3Z zQV9k^*+s*blKwhz;tV4hJKN0-sc$sq0>X`_KLKvO2QpzW^8?O$3h;n+(Cd$?UOfnL zGKGWW_RRqTU@w8Lv((ZL*Za3~i~6iH<>PMK$bv3;06N-0`8I-zj(fR5asZytJ3^%a zj=}WhLDysgnhHa3-!7+oW|C=^U8I!FsQ_|=e9QDoqeZ#~#D4iIY1q|%x~S{`Urqa; zK72n1gG%H4X7)oF3A(d*m)j#|+gtH}DNPb+H3}k+H!<$!BBN8{-tEgy@4~cA85SdE zv0yS{tQV&`+8_jDG(c^sQq zDLNg@&KdCl-~F@2@Rd_5G!QeJ{-P)C2!QE<__#SJsa1PDZMeO>4?dHl(HN@e#QTph zCyXc9$Dsz(sPjcaucpvB|DD}e=qzyZ-?>OI{n_$?n-su~w(qYsXGDE=>E8Q+l4ue> zO=~4QH+%xVkx%8M6I=qm)0=w26E@j8pw2oDFUbe(aD@|vqi{fYgu$>KLb#JF-~;e` zn{jgvn$bBa>wtEv&CZlPwB4yKy_nVv3U)Oe!P_V-dOzpMMb#VvQ{1K*pdVyq&tuSc z8J=h=M>0$xMVl7t)MlMYg-g zWCafex!BR04Z>1Z`94v4b^qq9)@>eI6Hw8%)U31ZLJzIFVxrYt zpGs~?^zI)X=9KN!1xtEFl#a&}mfCCM_dhZy5(1xDun22cxzNl~CN=wNKxx+l?omt? zKiFqe;k$cwaBMoqi`X}&U!&Nk*~;LbI()=X;$mfwX14K~iBFx(b$`tqz<=+(LKq^? z@+$vv?|zE-fXv?`ax=Q(HnbubX9C1pSDo@mVJk7~r(rU(D^Bf3ymNDsUydzaGnuzb zV@KZa*gmo*o=%T#8hv1SdJ_mReb@rnDgVlF4jbsY?RuY3Weq%cnpWPy(Vv11{T%m_ zo`buqJC1k=HGd)-(kE8j!gw5lIq@uH(t&VimT;vLPX&_ZNuAjKS&o#bx6)|eQg5za z&PtRlIs4M6Ll8OZie}pp@NQ}Tno0ZmSJC~2-oC|2r_-{}DJj&&kG6zoGm!RaXDW~5ZzJ0?!^JF?*$Q0;nPZ97P!1?PH8r@3p22zrwNu{5r*<{Xvj7iq z`LvklCUsk0tu+~<9-<56CXRX(JP~h#7o}tz&>^+cfRDO>w|#Q8r8*}}e?NuY)meeOLW#^0oc9R~5p%&j3elgP;p=gd@Vf+ulx0g<;qF zX{O3wZ{E3J%uRBN1XzL|tA&_((so6O#EiBBAuw&5+ixeYAC+Kzm=M}X}rI28UiOFoqnRWNFFf$I_nOSD>&liR(EUz z?;K_A#EtBoLoE?|WGBh3W;?Kw(}@3y$PU^A;sRCwhN1=bIFz0jRg-Rp30!Pm8t#I= zahS^@@&WBMCs>GOZqksCy#3sm<*GPy&@;jj6{EUTXGNe^_bCdLk44vM?ymgkxK0!n zwu+G_Xg_^gIYszsquPZz`mn>y9*&;zm*z<*d~F-9{!|IBi22pzu~`aj7H+LC$JjJO zntYZ9)ClPdE9Cy(d-x02fdLl=tyx|gIjs6(y}DS@tZMnbMrZm3|Ds8MFT{B`^A_BV zsp-g4VDNtR$c_iByPaD1VOw?X72WZ9V_J;T|te$5BNDl{w5`3$com$jI8&yz+E zsU-ZBDV1|%{APgwpQ7py*NK+g=Q?jQskzAJ+}Es;<7~DIf0#E^^^%;A5_md;Hwjst zw~pYCX~k?6*X2(#krgqI7aOPq-Zh3wH=@&r#oDS3LK`(cKlXX7V$W|qpKH8cnnj44 z!-j5@l?4tZ7){8RjC4$t2|zP?RN9l8g_*t6z>GU_tO!zUUP*t}xf5Rc1$$3ZduijhAnyO;!o`5+{ROnel}@aHxbg|>znvc$XrKnLEuM=zY9S()Udetd{FxC!ohD# z&MFgY=Sm9i;*yfNMC^@O=2AVB$MJg%T7T@QK3iIx%j9(NQgazNju2o$dub0 z$mPh$>^!YY55oT*$V3T{c=#GJvJo43Wqa$;WLEb0v660f81)?&xln(YtY#&aiO=cf z$VOZCEb|0L`^Lt?moO{#(@$U)Kpk5B>DH$5m5&F%J$zb*ug5erD?pT0D~5y&o#U~U z=aY%=cSM7$m?fe1mP`S#=ceIpcZow1UJmr`mxj)dwPa&sr{&)R?rWE%JFsrFsbpHk z%(Sl=DTL>sFw5($&`zR6H2B<8{6G$(e!JZif6B#T|Em*IE~sLG{~=HHVJ)IfUokKR z@%kE2iqlTzX0PgKtil1icl1iaYcgv~7t(R70x@il9TXWa&K~!=17Ls^)OUZ$)}DYB zp67A9T4hY1l9r2s=1;e`07(r7j#3k0(jIDx{oxi@AT?2LkIL|;5IsG%glKG_D(TA? z2;@8CM#Bi&U~B9sAM|NC`BMKak7b%3@0uQ;v398Rda4X4jGu{E=WvJTUAYG3x!{cA zm%syEMWF!sTY{2dDY0=fa^)b%0bwlGD}MrYiKt-2U;LK%KIan()}J@anO|d36B0OV zlFR)5iSsjuk&UPnXUu51=wImgKOKJZMk3d!@sq7mf77)C@DOQlxlT0L?&GAr(p>dC zSuAe;VpTM!ivxSnabz=*pzrvv$<9QcQr=mRyz(|FR|QbrVocOs7ROr$#LM z^If40V@kLro`oI-@`1+a@22RyDiC@#fu;EiJ%|6=?Nm!l=uUFB{7iomivT1!3sU$66LH6=aeHv?a~FJoVqFOg5jHHLo-eLc)R$e)V~n2WwH?;SNUeou7s zJ&)Xm_;BZSHirXs1~NfYjdG?+DX+&p|h7;@e;IelswA0V8(*5+Nl-Km9He)%Y@Q*;PQv;CpQLbHR#9)!so$SJecOL@EV++dH*n-YV z>4PiOgX;iaVK`epX|YM%v!&6$@l)fcA3?zNzs~DluvYmLMYA53;s!uw3PgxROwOKw6Je{zZ>M+`OV>`w`S~NkEF}=S)%^$2^UNALkf5qH} zKy%A6GM1?GEvj%bmg;8)!1G`D4JCq)`dvE@EZjPKV0LRrfgIGaTh|M{ilWYb?D*G& zNY_D~oB8W~$(ptit-&8!c?e^iO&G}@xb+u0AUEq9BxZYd#3vjr_gbr74H~3Z_1c(o zexZ1@P@iQzpL5Et!WUv$fv3b@pLH;wWiX#@FrUQ;pG~0h8{?@>a!C)M-y}ihmn7-P zB=VY6II2*iiM)%Pak!)gtRz16#D8jfsSUypM$%w(%;rq_Vkdp=uNcGj1t#oJXR6@8 zPYG<14uS>vtQc#uX9I0DS@};OFBu;Tz@N9SIrngcrPIRvcc9jg(1w%JF~)PBw8)H!;Qfs;;sF0I*gEnSfHJ%QbL0@c_|%OfQ@)EX84LPz6Cm4 zeO#+Xuo|&$LiZ12EP4)i3^cbO^iwDX%{+~G1wK!LnBey~^9)Qep9EW0p}j49);0+L z90STMx+ zV3$7TO1F{3ym)=)KY4_)U=4Wxh9gl}>01WJmj#@n4^`v18wb~QKt5J7cFz&{mO=V@ z1mDoG0V`;ty4V0}SgSZARg8~|fC(5)-rXz&~);O|!v;8zpyCI37P3DhG*`Kkg65Winr z?0n%2K)C=;a>@{-A$-QG>?+PTnZ@&|{vJUhtC=g9tEi**al!9_QTSHS*(R`Y3q70v zppOAS4h&c9B+L&KyVz?4wetGYXdF(uvU!&Xdb?t;paIxGwM*@NKscy3lp#16P;(J? zV8=y-@*5!AWl{M+@2Rb0e(MGO)Xm#gg=$&u#Yb*!0Np?j=)e^LDt>NpKO5qck=9m$ zdQ*Y*%n$`WJv}W0z}aT>z!5{@EJ1>hSC9e1pflMO??=B&Yhevvakb)b(6-Ill2NP% z#4w&M=|2XNiRv-m#>JP$oT0m&+zJXeTY*C@U2K^rVG%#hz1*d zUn;&jb+Dx-5eF3;ipw|*&P+QL{{?k!{mjoGL@8fY{1;iKW%Cj35Lus@^9A*PaiRYm zHr_&OwDNz4jmBaiATZynC{qh-lmE{sYBB>h33t)M|I5SjL9+)?B8IhF>kHCc2PzB_ zBv#*8@|Y2NX$``Kds)3iQ%{2}5qat8$eR!cS8O4hNntU^$5a%{YLS>j;ZtOzcwb9~ zTT9HFkoL<#CZAPijm&0l9u;TqYm0|8+LZjVQf4}Q`i0l&>uvk%>)P+j%goe`VVmt+ z=fbIg_6C3k=?-5}W^Hn?qyVe(d-q(0B-+j10|!3)Co22vBNP4j7IHT2D7DtYWcdnI zme=C_ekklFTzF(EXD>0wQo3M*bT2`K;fQp^1E=veQP(|C#t=?_sHplhXxi8mI5Ugj zo!t+~XBM9hxPyEBVGYU~`PYXUa{w~3cX}7X^mGM8e8|+nI^}t=&e|8fk>NKMr|cLA zum8umPbbcSyFAxUANGza0NR(!K0~^=-heRPfEH$`@4p|~U~w#2ocTMf566zDXug|JkX>1io#yr~S18f%E&8`t^X@GH}YlT97+D@Eb`rrQ5e_#r(C zO+E#oy$UTym5|YEH5z*f)7%i4QKN4iXxLvh@h!d5M%WkBpi`?0_}O`z28#oB6%H~L zbfW6Y<`SE_&7W~R8><(*zcC%l{)Fn5vBYMp*4>uN{V=QTR`a$*px`lh9m1|P>FLsP z+{Q}Adbf5Tdi-D_10Gjtd8;d%pAHx(8Tkw%e9u_6S{P!Z+=Cn}d{p*Ykre@wL=G>n zJv_-cn3i8RZFwj4UkRHEllUArU*2nX-s|^PfhJF4rxF_=`d$n<)bK< zlw3?+-bl5+hZOLjdO7)GxS@0Ce;X>k7z}l74c?kRjjTCkc_KqZ5SPFnLb*l@E9D6i zz8UDr>-`mmG&#QJQ=qzOJfX5q4=yvLz8?MB(H`RoFBd4I=*!B+Ooo}$GsoqBn_`?$ z`?%0Ue7M5bhPa>h6NiHyWRB0?1{K%|y=|YZ$S}HXrcAea*Gpx;^3q1>!R`lD9Nr}b zynH3Vfr^7MCOc2t9AyK#x!;SV@Ce>8LyYcR`pg&uK4?$>kDUvQiNVHQ2=@e*3I zvJZr^2D1tfurA|XCgw7(4I)o=vBe)Ex*p1(v;HNYqfpWYKvq-51Q@g~Yi0=%{(wLh zN^Z~Uy)n@4c>AGpg~pNX$I#I(dvmpQcgrw)w7stC^x3`H^gTsA1BPrDqdztZL2rXjHN@fE+fWWq@JP(kiFvtT=Rff-xsi zFp4zMg&EtYIu|3;Wyo0re^;Y?SjyTr3aacBak@BA;IA1ie}_GRanzn3%sp4GPC4JP zpvuhz70KIJ;N|xm&SeXQ6b}-=ej`Hoz~LXFiTD+ zIAi8Vo&ZPKWa`a`)he_+k2WB>O@WKO6vc-i!KpgJqt}ci?oP2K|3?aFc-P-$pX96y zWS~aaP1ET?ieO1S9Pe|E&}+{A6SLO<|5t>FHGe1*Ga-of6m*sES#GJ#rm1bqMgH{P zE~hEO!kEA|6SK#h9M4xS!6W3MX9u{oqiyu{2>(9bsLKX-Y+_`x4I;kf9N8D_nyq@i*v4%(zHAD|MVdq*;|XQZ>FT9zH{Ed~2jCS7DAC-LADkw!2hv*1Pf6ZjBq0&kd!PM^#RE zrMNK9%2;EaE^=osP(5Pa@r3g3XbUHqry5?e{jcesqlq}ovr}xcopVUpDCk4PVmi)A$D)g~r2?kH(W;kgFv zDt<@%lCsxsoje(2YTJxLc>4ixjM+?|m&h&wc~#17mB~+IaaCnBY0gd^3d_(NkK}no z*xJ`9eG-v^@xXM-51h5ph!@@=g~2vuIi6yiD^Lvw4`beWGXGVgp+riyu3@q6Tn9v+ z6J7<~6y>?;*&CFlu*x+Y4{y1rYvLAq;A;Y&ONN{#w==?TFvxRX z7KD{-98)UFQPjXMgQ-Aj*5ibl8Q)@xJzgMB$_O%dj}YLnzgxN&f>W+q@BreSAC_;2 z7F`ugO%K}O;^{9)R=%K_ST`OoadIJdFw2zUiQ`Yq5w|{Ade5Bv9KyTc*Q^Hi1LNfk z7NuG@0;uhDmY9qJz7ciH+9l<>hAGFK0y9tX?fm}gKzLm zUWf7>fcA`VdjAa%8x_wvrHDpdC*IX%M8Ya;LyFF8;?s6v&`r70PE${DbaiCkOR?!l znej6!>R1@bUDeAhOZxJ%0ThO97veT{hKK8My+;27TZU1t#9fQ-euIlolu7Bj? zR5)Op^Bs~cQjLC0*q(S{T~h-Wl&gQ0(JKb!rZnb4oHP+L*esDG8{nTb|A{GDqgKZ@ z6o^bP_AZUDF?NW53smYDeyW}MISC$J=8CX904s_;(%IVEmy87GK^*H7ycX7>3l&ckZ^dfZ}CW{YySxNP~s1`DdOgApS;nxDOT^bYMx}_T9-#IBss%PFOfvf$F}<} zJiu8xgiN*FV&UF|9=FkiJr(Kv6Wt&zyL8@G`K3JJ=@C^(T_Z+V(?O1V^sr*ygLqs} zATZ68tffqN>9#)f8h-tR*(3Oo!X#iafw&s`+G*-Q2b^%_aFX1s&USKQXJEDWF|(*L z6nF^r30^+U3S+3$xcVe$&ZV=rFMrfLO!97aEpKk{mGmw2EeFnxDmC3Gv8HOq;0<%u zF6&jS*qB*8zD~7oK0-P^7Hwki6(7@wIl&B5366OS>>WUB)ho9|ZWv+y(&&$M70R;qIbe7Xv|Me6sZ zvV67`538H<*7AGI)!uqRBY9oDpH>36*v|O`A215H3>UQKRIV2^N7k1?ADxQ)(EkBh zcW6kjI5^Xy2Iq;|f$aD)#YQ*aTPr0$cFxg$lO;z`)S+&V6Q}6E);;&8vv$Z74;wj@ zq^C(J)kTM+9^|~AG5H+mqlxfrP3D!|{Ne69IKWIHs?}5W^dV{=Z8i7g&JashxG2;N z4^n9C!MaA6#>>GD7e^tT?XOejF6Zf6L9Bgyp13z>9o4ppu*TVBZMMJ@@jea^ru`Iw z8Q@2mz3+85#-Za(8!sDB|NBf@4hrCK&U#!xW66k;r6ic$%as%vvRGiPS7v=B=JTbC z4^3b~Q72@J1CmUvp{0YjVP{I53BN|XM#pA&{X(8?EWB|zid``eXOcfMd3Y%su*B#u zj7Q|TpNJ;k+utfv=Pj3*OROV9b!QvZLJdzh_H_I^@>^SEPeNKoba)PmWOQ}})Fx$g zB>$wJC7voJ*6P9C&%4z14m8)*DLmGaOhb9VTyh#)is3Z6w%w8Q!nNip1lO*8t9N0z z1f}ess;?32y2yHONph4}BU%yaE6kG>`M!>LXiSY+h(`aqCWayfk)yNBpS)#hCQ;$Q zMn${BP%gj7(e(rox`8IV_j}mah2CLLd)I^1>t(yGK&5rhJG$$|h9=o%@1QDr`r;su z*{sc>lpo7$nQ3{uR^jPs84@yQqG|ef-Bmi58K%2Dc)N82jcyNTO;*Dwb;@LiK0v{Z z-qAna%n55f+Z}#in$2XW;Rnt?&duOQXE3hWuL1or@VK3v?%X(XUWkKpiLC}*C!rUg zJDXlB3y5|GUa<@P{VcOZsh+(^^n$z2WGT1JPqhl6VuGDX**{0amU?Hs-xalz4t`Y# z+?l6-$Dad(wBZXsC*gE-a&U?;tuHCs23=O%3w`=!vh^mU+ zI7xm<%ZYVKOyG_(wV8P=W$9g_@_$ghyJ5h7g+BSZsC+^l=jK;z)r0LF7P)t17Knq{ z?ud(-Q8domL0aW_0P)RmPZ`hKLard^(B&8IA?^6CGf2>DlADn6m=T(|8`|I_NYCe!(`#lLIK^L4HE8UTrn;PJ9%=>4ZbC zz7w0P+*j@YTD!vj!?ltmzJ=LoH?8A#UBVPEkWAuIL8=Qf2Ql+RZ`cx62re7hDs!(# z7I|ziDq24QAcstO+F_2YWOZnR;KgX`8z_g^(E(9&F?bLK=D3AdbTHb-SLzU*)7i^l zR$l^KaB#Oo*>P4X>jnqlDQsCCln|RUi1zJfiJI-sdoN*kVmw+KVEMrV2&_4fS&`2G z`k1cHyUUm(vf#oxD>m^RG8+vbS4|^6d@C%7UUaq7B-boV8$nNcL{DzJf~apDz<|hu zAdGNYe}%{>4gF4V1z2hI9e+^@I+P9&f_4yo;{YmHX)Q9__`jkEng_eEL>2)HU=mu! zM_}#)B%!p9>ib~<+b4a6e9!inF(hZa# z96~lA4~6eHth!<3S_g!%WrVUFC=vPIEy~Y^=rTii#mPT52YoD2UE+xpi?mgFeHUqa)-;s&-V*;i?e15l{+W~$oKyYw@MnI3% z`!MhOKX3tdAS&vYMZgy`PzhC_0pOSEzCQ4!xr0fu#RQZ>1vK?P_<#BRRwptveho_E;mK(RaP7lxlRB+yaVriJ2S0#qY6tmCyX09E*{lLMC&&FQU$;BFbfbb0A# zI+WTGSJ=4Rhx#5l+#i31WCfhq60a?B^k1W zEp=~RPj^0@oDQxaZ)$dYsg?s-og7JV#O8qkx2Wo6Tia@dda({}ti?l$!uB+5a@cky zE1BORMh*;1p?G0Kg`HhtQhQbA>J`(r#Wh$&LmKjPA5zUo zk&G?4`OC?ujSMpO9&2mcfSS=E<1TY^nSPpjro(M^I6S#tHxna@X)C&qShg+J`;whE z&B*sRf&Vvp1PLzqnScrc0>Sma0n27a^wus0Mk>nCAmIOV<5;B$>#RNK@p;Uzir7;} zhbM@lx0&vjbC2%6@8MADDhkJKwK4}mvo5z*Gszl`hGu3hqUN^llALo`7H$W zbOCj}vfj3$kAhsmrFK-+-Cw;(_S!xD3oCYZF|{svNaPX6WnZW$Vd zVBVs4lQYM$+_w zwV8NLTGaA}`mLi8$?0vUCC*2(;?Jm-+HcS=!XLR%y;V~JY;&NJ1n;d919TaE`%{5m zP#b<=yp+EQp{5;kFN9V@|H|Ev90hD&7kw{={ObNZ+EGc1JW?6>BI}9V&_3PGUbnTq z5%UU$>S2&j_^h%YmX#t!Do{9pakmE^8hteEyL_G^ujWLXKiSr`@<~aZ^!Dx5`>e#0 zFNn?-4Ex;P0SBN5o&(&M_?0>NNZyG5-EE;z=YMgU*4&LSnAmXVOlrzK<9U^e8+X{P z;g25we)OQp4b~kb|D)E;2Ens559^8#rxn3KH?R4AY-172c>$UkJ8Te3yL&p1%G|t- zgB`4?h%mu{z%vmSdN@U2Z0JyiM>G75_uAww#=WmcnB`$vhv`doEcn2>x4o%Hzr_>6 zJ2Z$Sp-cQ^ejN82FT!g&`Hp8@vFgLytZ{4w!q{`(+*OsErzu*@UZ@2w8zcAdET(TN z8PYK4O7Z2gglSMyoV3*+i38u)Ts02jQ7(=Pw$avOoy4ng&J|bQ>3=t553cYya+Max zxg4ws(@UwVdqJb*GLQ{eUASG_4B#$VIxx{;?2Td^1$Sdu8}!;zK;{PcNYT{s&%XB$5z#pEKjU@m!luh+Wj~uITC?!)7R+x$d;=CuIc~ICn|~0ljv_ zsSvbL8`P&Y5A!ui&rx#%eCw{DpB8)9hZxobv_jqun}#1UF{7=8z_*$?&xFzwcV(yj zzqRB-y>IlZ(0GUi!s2KJkJ)9k`TbUq$qH~e6e2irz%hHlLXf%c;q*1%*30T*z7>&e?io3oJ z5r>_*6#lWDgf`}Rdte`4vG&(qh(GyC92JNmk3b^`pRq%sYOO7@XXwBxvmb^84Daqdr2ZXft%hVm{)bu=p%`-?YpOH_XdhNdxQzGU$&lw9aHlbcw)xqN z1RMn)s;n(rC?IIMj49#lT6Z_>t>UzUxEUa|z?vFVzS*d?UIom%sS+Kn+ zGg5AFQitYWr-uG*7kALQP{RjW0s1X3r zhl%7WDe>)OkG%>^1w*z!!T!>A8>D0wnU@94xr2Qv4bQ#lp7BQX1cDKJ`{mHpq~i?L zN?q>WVqzPv4e5afSHDzDA7^-6HlDO`_L-(Yqwzc7yU!RW9H{@QxVo#{BO&uvnLrK& z(f!_?)4k}$qmXwl_B{RK!u8cqqbQZY6l&IOLk{_JWDQ8o>GSC7R=m$hXfaEqINRFh z-3r5To>wej5x6(Qw>+Ptfb@5gUJ_F=dvzg;h`HZj^QdM*Wv}K-_(p1a2qwMCxL`1o zAfD3*4Q(mnq8Y>~t040qCv^%+q1wDnV+h?lkgkOgA^#I4YX7b_vZ@ z^WEQDbo&z&#>v^4n3P?c#Aa~nhyTHyYvxPT;sQK(-shG+1XgXjm5y=hJKb{-uhv{g z(N)VhEW7T%oSM4$dpnkNd3c|-zAob9#cT5caN&+OkzLjO+t|)aF9wYqvxw?Fd`(VF zO2;1bsa~0rSYA|p_~wFTPJw~r_9kwv^Df*QZpA*0O+ED)|EOBoN|8;(F39Yfr8r4o z%+mmAnOUB;>#qB1(`S84etYjUG%Ko*kjEc&-Cg@5xGc50^>wr5M2|;;p?(X8_RiMJ zskoJ)$PKB#Y*J@cV4yym^m!VoIGQC-*A~j5j%+VaHnLbCDz06Pl4%kc`Pq-9u^@ww z1sB$c+kP;HP@2EUJqhiMXr4(X6y~Pi2y4WrZ+~m#eNoYiU?+@!eVH8fQz#gR(KJY`F}YHsJ7ix;Lm{P}m%FgEx&yVI@IS-pk45x9#siO!aiuHY}=ON%va z!MlHB032QY&X^6E+Ky0xu&r{8;ikcraIwiC{sJcd=_eZegh&H@KW1m#TKTq1H$$|b z*&)%U-THm1LUNX4tp$;D0Ky>dyMO{jxV-_}A{}LFFW~{|`Ub=Rmm09rh3*+4nM$Rlolu=_2YF&!WK%?rN}V zGw$xno5$EHfpKY=-8V3=9;s;Lgs>aIF0$(U4}~gzkqg9}$BeTcTNg1T75G`xhCHud zO|_VH_XqliPZj9ZLi=KU>TbmVG|`2<60eH%k(xS|sc+{fG=&s5}Qg>>_0&#>d=J? z(GK9#V;GEovZEV;?ZY=#hnm=xDt_%wYgX^mG$KX^K;!W`SUHJ#)XwzXrBEPO3oL{q zynI*r6ISHjYgm8nPZ3Av1`?d!$#^nlJBlb*fT2I?`IFH%DA-c9TLX*8&qdGrpA!S% zQR6eNGQp9^6K{ZlZ;n$S^@!IB{f<`K231lhe_7@Q8Bzm$Mk<8K7xU06)S^^HSZcZ_ zT92+n_)cVoDg4!t8l2bG*$qNd7$#ApmV_5gRxDRPl+J=Qzc?k$Dp*zzuZNXj2H|i8 zS^6E7yfnN)kqS7&!V<&YE^SsG1t{xX za4Yi(?hdN(mazN!T~j_>zN+2ATN@@&le?VVSqzXm)sj)KGjvhA`^r3XrorMX`%BqR86n7-+m`2u*?@uXIKvqn1IL*jBI;(Juv4iwlT9_Exl6*rah#96U`x zNQem~fGb7=#<61%sXMm5I|KS!DP~{;yVa_uw%?XA-SxGH5Fk z)_pQ)jop5!*#vpL)G2k43epl<5EHB`iS<@^OKYe8R``>j#S!Lg0cUX;yZgNxlJw0T zj7;n%8MD7+5GR?dyM9L`HvFKw=euC>^|MDLlO@6Ylq7p+$#tO@Xh!R5-y?7f0rY6m zW8wlrIqZI-e=2wksJ0~dAxO|A)d+ zLvDEyUsJh&j1&0hjdGhb|zdgKmS#z^>V+Q!kK1Ko?Tp_dsJfbeDi3IcvW+ z`YiCFpPmxCua{_FnlN23A+YQmXr^&UrcTADZ30g#tag4_efaH#?|xz@&O@L*+$(Lc zPi~aA#KBXG?kSEBFQTU8&lBNHBJE+`>yS;F_7~Oxt7QJs*nP=dQPavikrRl*5u`%#;6UrZbgEt{ra$h#3*z3p_O^zjJ8NxdVRoz zRtsdd_g`sM>3H4|rKIJTA>15uL;+JvZ4XFAu%^y_)9T?H`r5W@P( zLOF<5@7ZZ%Ttdl=z}4RhS+!C0o`n&ywvp1+Z-vZGpvrj!J&eE=g%KHB4@Vu_QEy=O zxT07JpvoZ$^v@??&M_vnlBGQaa$@w%Pm9VSX|cT1%LKP_O1-yYWgFu(!2T#=zMIAf zt0-CypM6J_lN5f{g;EtoVc{?xNb2e*oNojlg|*hZt5HJWp@r!R0S=KFPfydCOgEGy z-%-mL&{UJFB9yB`ooj|zhY_hvBqTqf2YtGkQ_St=cHsQSp8M6AOk&KwxDCXT%p7;$ zRYle13`CA4_d#B2OTDUcfe*J4G>8K1p`_(Beo?ch`>S2!J1Yjc=S!&B9CtEPf3fyg zxRhSH>MVjAjkHbWyYL<+N;WjALKpNQU%bmz>_kyY?S^G$8a*rOY18$QSBw7hKw$Ve zC73(#8sf$NW8>KcT_(xzJ5R2_A-@X@Ph@a zAj@5XBBIvwUYjSNngC5a`je)$v;!3`l9U&-&WJIO3fZsKrmncD>Lp`qqGZ#4ZaiK(2W;EkXHb$_l=d@`O*HM}%9I*& zt6c6&eNFOih|q$Zxk2#_Efm9a~CLNv}gq(#jvvrU&*>RZt%6FK}=W{u}LRB?ip$M+5<_0DK)=ixXSZf^BZ`G{_ z9jSzkL6O99%z>qG28^@Xi3x){FZ*#qEki=6hDlQ*{d}YjG#sjMLog7*+&NZ6s0u;Vy3Vm4fJ!8D9MXy64F@^^_HWS$j)J`nT zc~%WzC*}*jY#t#zqFe?pdi{p^d<{&+AyY;U!j;g4f1=zBa3cdJmkQ8Q6c!Exxj`lo z3Z-#jCjd!uL#7CYXxP7xi37$-e6%T!1B zlN90jGrWgK`34TN;aeU{T#8)RpD$Zaa}`@*#P@Qn;B#&yKHL}Jn{6n;!8jlR8*?fU z;m;AllUu=nmTHjGtH`!W_LAa?LVN=HDfHbr4=;y zYQ78Le)LObxUx3-V6|SHtpZNwPE3MLa4vG4O3p?D0tYUYuV`v=J0txL{b@;8b8|y` zU90}ORS(rwZ_^V;5R8_*X9o<~g)ucvav+BleUHekzY6K$c`*Bw4*KIH2$^6_wKj99V#wRz=e z%D>H&@E&`RO+KA`Q=!$XXkk=Imc`UbETt^p^ZqfC7ip|nBw@-^5eYSe^+I3w!&1X? z6Jv$i$Xj!+KL7wTZ$*E7Pgx)6cQ7NZe#imH6N&gItFIqKPZouwyjP&n$P&Cp&0D3~ zXSLj$&eWogIS(~vMc9cI$UB-S1~}-=9hYE9OmDxMybhVmK2OccR|A^iyxFWMMjxxa z2VG5h&^De2G1M#4S!j>~d#gi8$&b~(D@YZ{)wqvd`f>+)-|olw`r~dN4*z%sKm3(a0TAqo^Q3g;O1^~BG$Jls?m-9 zyzA6hfQ4vY6tGLKI4gUCuhB=3wEHM(*IA`|zSIUbp=*}un6j@>)JMH}V>-p()8@(> z@`QHQ=(69QAalSyj)Sq{(z>GHJ2)%Cf99OZ|KzF66F#f0$k$gpxr&n>v7ydJ{Pc>R zAR(Ga)0=1_Zqu<(IlD36y_B^6yvNNp76Y^)TySpl5q`hlNSwp=Qg_cvsT?(mE{r;? z-fjC#(W})P^H|5QtaG3~xdn_h#qW{*Za?}3SfU}mXTGrMUbNE%Ry;PC=HqtF5Ik=C zpe>`DY@7H}?r?^=tmg7}Okn+@P}bc=D!>E(BV-(pwseLf4KaG#L%=s?FP3q_Q^X(|)$qCYL7Fy^$D2HPkN$aB> z-uBbv^|%OKAm3=0V)moiIPoiCb4ZQcL7*z1$Vs<$WPy|yr(kjWGuS~2oR5n(xvz+O z^n?CA3OS>TyKT=84CApRLao{R@c-IO z3_fOD2m1mbWmx~$G{x4zcodmV^|_H zOhX*!b+B8$W~^vAw14E461@jbYmau3tUBA&ot*9(coit?yx(e#)mUqtV9 zz&(*o1e>3M^iWhoweO9f*6T4^zO=8E%q_-qx+l^>bS4v{2+uUUrD&dt#;fvV za+Evw#N|qLM&;ZULH~~!>6}QnfU5SK{wS9N9hz11VcdQzgjy!YCWnqW%fsKk!B}m{ z9_Y?Qv%lzmScwCGBx8{A`zj3xT5AalSatl1*kmkQZUaxjhuD^%EkA*2d;`q~FYq_N zO)AoVl$XxrRIoql&={)@7i8q>K(<%*S%?<%KfI3LUBawC!VI%fy8&dECZH&yV3s6M zXY_1CHfR)lcP|mAFXLG^arhnIiYNT-{6KY&LS~=qwkAR~>$$pzKt8ERtTX#Scb-?s zmoTrtO>T*j;8(7m9XVcc-Ia)rM>{!a)}E_TYtw>XZ} zhTlSccUu$fDU`q2ux>6>Co;Fm%r!WI4;@f`v^8HGC(&>2*~((Ooh9xuV-@+LV-A6& zm*ah3rDe_nA-YnN?%`ic3JV0~jk@+e2%qNg{s3PP7chYzs5Y-SWuwhf>*ODcC&_Bz zF&1B}6H;;A*TgScW{dq2-NVnu`QZw+CH!;=yTT+IJ8n0=ImgA+RI~j)m(^dfTykWg zsT-C_Cvhhn{+JK?i1?{;kml2@BTEw02e)H?fFn4)<=XYBc*yj0iB7t+y+8O8C*I!l zSo?WE>zZ`X$lSfdN{FG>Fmm+#^A**MyveJyxIscf_?C^m+luK@==l;OT8x$YC@m;q zKUs}-uWJHxBjL?BL}Unw$$}#pIS!nMU=$_DUBwzwZSFDgw?EvLO3xBwQ_m~j<#=5} zU|o=T1U2K?9!SG2>d_qpR=8yc8}$)T${B2Ogj(%Z&b$iUI?C_Yf4ZNoE3-2JC?F_qEy~{GOR=yj1ZY>Nl^2Q^+b&_BInxaHhpFn2i4s7#H%bi7<+BJn zZSS~DbzSZ3E%z`qLZ8cYhy-3N+$V>s2uM|E9P}o6FUytO@j=63a`O_s@alJBk!KI{ z=(7AF`&S$$y(?%PSVA26D77B1azl_l$YTs5NT;Mck-+Cr;<7ZvzW>>Pus7l&)5o1e ziUuHVl$?(iC)*>I_^ZA*m zDzXCeFp+6Oxg};JLed+D6wqPia(I{gjstg=>W#mVT%$8?c$;I597dpbX7@H{BZ3Gj zU3a7> zzf+pA!#~mzw#E6S==>r^P0Vv}j zokHP{?G2j8);R$xvWv_J9A_bteU${&-{LPs%-GzOW6%&FxDH%tLe%)DJb7!8F5*62 zaz7-VQKgfCN5TR|L<%Dzaui`}Vnk|0TDXGv^Wbm{A{ZiN9A!`Tu*C3ylC{HtTLW+t zSi>Jd2w$)2`C`5+f_~2lPm`bED`X%Qs8p1I7T5|%5z)r%RQNa@N z8X#4>c3wU$Yl>#C@%X%{k9M7dh4Q^i(O-UW5mUPaMQocK~TS?6Gf9N+14u>x$)%q}u!Tk<9MOT!^hUg!T*nKq|9!{K!0V7n_?O$`G9ep_ zpW&aJ;XdDrC_;e z5bI&!zkw}M7TTD9A+#;I>wf=Yz_=cZGINiwPp?a8rxy)+gwm8l+DCv@dSU%EDr))yzTx3Ld zddLK%_wE4N(P($eZroMXMhJD07C~!%G9N7n+K5EfYZ5JyEMGc`!Q^0!%n%yx&^3B7 zA60sI#h`#YmQ1XO2dI4orLFG2fxmK$gub_nFq3)a6HZ2WMNpZ}u#xMavP;3?+PMFt zQ+li0%gL2TH8`0wC1o&!rD@jt;GVfGHe!|%ZH#w`ybdHl!JSw{{5LvEv;&PR?_pj? zm?k8uH8yWL@tK0ep_QguNAf1lG3nz>`vz`# zz*0#&_(Af%U9z6RwTV7{9u>Z?uUBvCjcn(i;(%K-}YHjLGlLif!!x#QL$lrHmm>Swy7s7{*B%+b5 z_yLGRUU5w5;hp{K3bd`)lF(KOE2a~(m_&EbHGDoxNnI&ccWc-lCZJ2o#QtQB?LVNn zbU8ix`v4g62JtU+3jgl63@KSg3?Eg0***9Mq>FAy#VC$X5h%6M0x4lya8( zF(XlKPUetxS$&JgbR8QT`y1lS(gp!QSiWMt@=q-90iY?3UVPjYCNT*mulPps-F@eUk$xb$~T;HP^k9AT3xcmtAaoGHHr^(na zYl*aL7+J^?Zo5c{^uF3k671o=+1T){H(!*uaG0WBQIS)YGb6m{Hs@Q-iN(TkX-N3l z^Y6L=TU~+(ceQSnuu0g9)h;sDcJw_a>|NY?_dsN-dM)&5ucKM1ce@>ev`Rcr*KzP^bi==16b=is~ctojlv@V5Yy^;18NAWs+_izb$A;?cKC*|H^~hx|j;h$*Guo-mLoh{TYKMmrco4Tx->)svO{j0=gU`W=xP?HY7n%K;Akh)?hM`>wf8*SRpu@D zPmRgDip)7bIa6=($EO9rhIt)*n414O-vPR#Rn z9^$}t!o6CA4nE#H>fAdDK&L1Ef~$7P(N$?g8S1@n;81Gf9eugkspdPeCj-n1&R&vB z!AW8^o#-Qe8Mc7ybG2-EbU7=p{YRw3+d*K{^hyIX5!pElZ)MrZsp(!jb#!AZN9i%P zekTj`FdV13yTn|5AT_Nhc2b_NY!+-1?)LDJ*_&xJ+uxwFp=d0JgCmKXOp_eGEQRvE z4MvZ+HH8U}8Z3a~x`u1lL9q^F`hyk{SFtdQ`SGnXAVCCOOiDg*h2`H+0&ZV>9UpQu zddf+JODV517L=TiPSVygC1OM_2i9s zVcA^1y_wWpz1@S;S-4HQ!}l%TxTf3)rM6lrT12leFiaFllEsmuy>eRE^IIjtbT-5# z9TfWX(iJz1(5z$rwkx7gHkwdmk0Qq#K<4cSOxOHXIsDT-j$grc6E?^L8}x{N1&icA ze7kEOLxfk{uWV4#5I$5*}Fcx)QDMHnx#TVQk%`XQ`R2 z0Ia@w&te*p2(lye^S7JHe1;R^I*e}O5|Q9!PG{FpS;DEK03Ke$f6*(OK-w1MJ;_2l zQD}>HG(-tsrd~f7)ot&=n|Fxn%7W%PX8sqmfVN!%|?q`aAX5{=D%;v?tupVLPB`4dLlI zfeYABzbERRM1ri#t~0%FCg_**-ZCCGFQ4p?T4`{84Dv1GYisMSa7&_ZbS8`99&Wwn zLvRI)SIQ*e+~jPF$xmsC!?@Da7(yx!?g!Zq0^PNsg08cPo^@n0rh%b8eXuayE5f<` zRcJ?}pN>`fV5!)HW?@kPBIZsATe8&JSrG7k*03|;nL+%uklUYNsi&0Rr6PBOb!6`L z$`g0h#nWq$5Qw=9Go~fe1(xOpekR^|I;64=$?}Tg1xSzRlp{#Q-(9+RoYh#ZzDPZk zb`7@>(rh1-?fPYKEhPu5m@#&SDU@teOJLH|(fv%FW39|MJ2t?hI$+?F1h8DF{%lF@ zQ2%%_`M6eeeptiLc53?b$$3TVbIgcW@J-?DfoL~uhyukwa%jtQJzC>@x!nCs?e+hx zd=F*5XDuI%e+WmxS0;81=vGkM@o!$14wh}c3{d~y6T4o~dk{M~#lZ8D4>SKIgE^*a z?G6iwfK_kC{mJqkF(o*$eTy~Hv_;Ti?)b@Rl4GRHwZjABz+$e8XyNo>P_I~*5IQAm zQ)rwUm%X-MS~x0QgJUw_{CUdre%@qCTp*r4tWIM(l!~CG+mLav)43KrCDjW1uVp>h zhB_$PeFd)V#mXq0d!_T=`A$89$zwweTTt|afNzb!8SlEXVD}o)hx$wZ1JH8JCiP%8 zt`_6h$UDkdzkmsx3vY-E4=?N`oBv^)^$$= zSCEVyl_}ff*>~Unr@`2)O`PdvV`%#?D@sM%Mq|UQMKiX=g0mQ7qb>IeMfS8ED^a1u z>`TDu?7d`My$b3>ELZY=Sffv9&%-=O&xL7Yw}k1O%a5{SYt`;h-!>`uD3!MWq=sdC zHfQg|8PjSf5v|?F-N#201FG|2fsyYg@!~3@skj_?QLZ4a-&9M_@6oEbl&k&CsY1%E zk{SW%&)s;fQXnXhaBk+JDk5I>p7d^m`Dyztj^oSgk+l)B}4W8nkaV2>l~Fd@cnqw5x9TJQ+~Tn3pTgKSC|OsDh!AU!jP~z z6M?bjb1w1K`Idwursh;+^htWAXh>UFGUO`0e78RO!N+#iMajzhvN^U3xftX3|Lz z{?h*&6M>}$3ulkcOd2s2hi&=Prj+%G)77aIonm3gn*dbL>M!_J3PIAC= zE?@aZVT^UL%gBpVUWc%ocTqxSZ@tD@n`n_bTYnzze#wnTEM4x-y^alWuWG!L{1Mr| zL#vM1m%`@G46=RUwe9* z&w3t=JPt!U%tvlbdgB-ps(jG8gyUpw*30j4M|x2jNCf}BFScVfh=qW22v-MZ-nPdR zdpb)I(_@CyJ_h|+GvHZ?g%}|~9{&YUKMdZ6xb%MKii}wJjs6bPrRO6@_ty!k+BkSS zTd)6R+UIHiI5M12sY7;}XqqaSb9%xt;%2ywJbw6R1+ml}g-Aw_@hpKH<%@T(?^h&S z8f5Ucr-4SAAa$q@I$>@ecpBMj$l+fkBS~9ZxB|@(V}Ro{fm9GJC$iikVcznhl(ns+ zj-%lVUh>x4L$dmbRG}4hVdzTi{RJq80OM~f z{R9A2R!?);SuTw_5+u)~Wa1mFMWw2Bxth7F-Mo&4<(R}{uI*LNAjc8b=VUeN8k3Pm zGaWTxJ8z)o&!G^+?F2=Wsj%&;NB#G&DJV&w#pFV_xux7KG-BM#qk-?@&xzaiNkEH! z>*f*Xk$tfuqEQFFEJpO&W^TEUyXv!RXMt7Xh2d(ygFu*)!hPmWsU4VIK3rf?dEQJ# z20oF&4!Id*3E;fr;FxmrpZe!T5hk&Ln?)k;MLM*>-<#g?l9#DhA}i|*5Ak0DPwRR) z9j%8TK;yriixybr@AkX&lj&>x*w{x^haQYVN-xPJaBPeP=Te6A2*UTup|j>Rbsi>V&W#k;de9fS2Q-%if-`Q{4zI$1JS z^ERJSDJV~!`1GXP7W3Z(ZWD(7O$9P{V++~3O`Uu*r)R}$Flf?}G2vaPouZSPKR?z< z`Sfv9lsCNgJ*n7U6!gAdxaKoY=#ZNw4Cauipk6vF7A9!EB>A2Q&@qOeo}Cl36Z$*^ z)T5k{N=|dN@$KqsNFAN1DynGZmD82BCnxF87b+%9+z4O9JU)zS!j2>1qeB+mmAX`} zc*(MEiqs-BB|1@YxXenP@_RIt+s;^k#b156;TU3b^Axq#drvD^UN3GN|1{u!c)zD zHLqStPfFwP6E!@?pUaMPH@op zD64W=;}ysD3x_nVsNd zK}|IhW9T4zVXiDPdqyyuP7=T=f*3zo#L_i%9veyPw-DU#8{jjlV2dzfJN%$EaK|y8 z+$G4BWLr+ds-v%X9Yt>82rc<;m-&)cn0whe|_El?5-BL%3!%# zqkj{GWjX+XaB>C1zlWnrejnm@T!*CsT%qmk^Lq|JQVn&N(!a65VuJiA@|l=W9lK`D zmUt!ScfLb=E&Y*eq7<~s2p)+OLyM}hil)SE>RqY$n_ksoQ20;|_Nk<|#uQ)jt}}6W zhNCRoZOUL`p#?zK&D2x86A4W*qRPW7v|)eFy1u#i2z1P^9$R;X7E@mOQ;D5J&h`Rd z<;VPG)lyQ35UtcoD$xH2wb4C^^AD5ee`kB2kzoYOalT3@buci*FSgg-%+uA~$oaok zQBuGE{$~}{pyTUGu;A8pIWg`xYygmNlMC<&Sre$R(YZ%cZ!Gbz$V`E1* zOsDpT5dF_thE^p$5BZ)Fgk8ma7)0@NfxKcy3gv$0Srt7xI-i~6Z1!9;i&B&S9UXfp z5wgKW$K}M?l&}If#0HCc+Ef8EVg+%U)QkYV*6D9VuKj?dv2X=OKkT*n zwM?(LA&+2-8X@6^ARN;Iz!8>nJ()6~kRS69&qMEjSUGEw$qWbg1%N%oBx!Y9sZuU~ z!#5LOmJ8nRJvc97{6-Dy*rT}G9fKB(@J*9Zcs)IBKSN&fAzccLyg6VJYL=W^EYtpd za+dzmHDH_j?xA;WWlsDo;M9=9wT2K3L&Sn7K(w&=``>AVzY#Swgq%(SGS52|$hpDx z^5E^WgqSX^zij7a@ErYSE%|t$&-RkQOyYVZMEhSSbTg7DBI|IdWzleOezMgn;B+H| zMU3wSZfA%P4&qwAl_iGXRNYG zl%yf)<)frexIe%fcsJ0;n|#fw$2=S8n9Ct2m(cdoJPP)R1O}W@=4qsMMKZz& zxJAYAg{213mf-WRR8Ypb+{vJJ>3B^WrHzzK$^^lbekcAa(SO8u&6$VXFt9_+0Vdrn zyD@=M;BKKV?Oz)ciW0HwOK0599MDVKOi1)B-u=Cy?Z_u{zJHHZ zKT^x7y%Myr87uedALFO>o);r73%S!27%u_>Dr4>C4oH z#6v!#bw2dCOAWJ{AdR2z;4(dgl*^=k4`E)LQ!LMdLRh2adZcLLN8~3(m7p*#3QO>8 zH5|WGD7rE;G3rWOI5UMkqs+<|6jzO;AHsQDtjw{V<3DIR8ozsIF&o|#7<7m zv_qlOmXq{|ifT5|4gWMPis0KjZTxp52d*u9Yic1!h0y*>)_pQh8V2D|)-xEpysuz>@pB zXI>7yHFO+wTSbq>x`A1}q=A5;F7w(D6&RuRjIM1M!Ide(6z~^~;ww*9ZL@I?!~Bcq zCZ~<5X@)V9Jv$`@V)*T0_jED@=9UE9w?RH7w$UcS=*E0ttFV0EnwS2{l{hOiUNX&J z^wjy*BE52Q2*tlN$X)k$08t6kTQzlqoXKKqNHZmpto(8Ui$?7$eEx9?0;+tq=1 zJ^S((_0pJVo>p_hCG*A!?z(EFN#;kG14C$r?kD;(?Ih8_`rR8pBB!<1kIhhVyHdpE1AE+z~LPiMOI| zLkC~Oycx-NfPSsAGt%s`HzJD;q3|QNOj0QBp0g^;8ZTySls#Wg)%Aynz98>>X?&d3 zHHqTIu9m3HL^k0b!|~xXvIK-La+l6!pPS@0^^0DX>*UNsX8HB686z);(mPGn21}|a zvuJ9BG4b55;A-_V9U!KS^(vOr#~2RIT6?eSHJZkx?ke(@Uh^dp!+t*YZl}$7e)YM8 ze^CcPUWa>tEn{ZHUA^U2NSGfGf0yet%T}vMEOA$^c~?$zic|cQdR6~0Le}4dtvx5P z!BG*tJ$h@nfN43kdFZKicNru8A*EU5yf9uWbNW(_+r4YV#D3`|vH5aiY=$@r{6P^2r zjpfCUh!-;b%t)CoVzZnp0Ah~p{>|#)&?!P6z-vtsJ#1~Nm%ej(4@FYpLOvN3!G(1s zMCQRell*(EG8K3{J9s&aj`|{kNW=Zie-kg6dEZ{(xSY$jfoef^$@Eq+$aSIkJs##< ze1^n;J)Bpd*MReizF(2IL6P$yL-NHJkSOwINvOHOLVMV_FME@B`HKBOT4;e)qI)*KvChU$lhXPnuletRRoC-uJ8QDl zz*I(YD7H?n9f@d3?9#0t4+@0c(R$43$O3jk+`p;4LzyiPxZthkKt`bIwK(f4^WF}b}H;Ir`MtF z4Z@Y2G~}bgNbd5WgwSm13J#rhkg-nd?FsYJfTe(I+K>qblLyA)Ak9G^4*|+%u-@zh zGZ3ILi18kpgV%%8+s$FPpE7nQ?iu&5zJaJm$Yi%KU3!|SchA(@*qOV&z=pNaja;C% zEc!x7!>y22RBugkNJMohr+Vvvk~4$1@}5o^C0CLq`EQz3JQ*GB2ApduY@13VpU9AM z@9+_FJmmSp&9l##{M!qsbO(a~Kg8;_$zA)l+nmXX6Ck#j$|K&Ql}PuHi_h=SgkxTw1XuYh3*1-5U+R~=7CC;Y4>hZt4g)mEHHy!pZ z%^L6z3A7(UR9i?z>?I9EM=Tr%uGVV`W=D5V+}g^ta}2}}+WOTv=1IIsWyvedm1z5a zI(#0>`m1J0JzxsMhNyJaXqF($Tc+s4GU zZQHhO+qlC!nw)u`=g)b+s`FKK?H^s$S2gyo?tQIZYjNTPM2b@;KeWZf#@&v3rm88M zJQOrE)Bfvj>%_rAG|iqsHn!3O-~C2P7xW#pZ-xyYOX4m^2Pu0mdkg8!gnuq|*0rR( zS+{4~nyhY<*Rz$pJ*QWyuL=w|N3}Q$$GfL}v$6DQk8ZxM#9T)ff0Zi+*~DscRmnkg z=8d#*m-uUO3iltCzGk=OdX}OjUEZZ5s_VAD@ws<`9P(Y&waQoBwjoVv9JcM;VAZks?lbD-w~?#hGuc32hS(p}=@tgswLyv|i& z5hR_v#DuQNWNSWydyLeK$2&`MY>J;ibUT(wOaqri9ayd+6CguaC^k=fJm*03$Jn>T zEpWmhw@h`(@nQ2uo7iO8nBuEMfCs$29)ZEhbg5FjWqc-Psu#24IYWl~ieDW}Rz-8q z4WaiGNkXPmW>5h>Y}JtF@#ToFm{e@B^tT~#T^7^Sc{_&zOfDVR@iuMEe!QjO*X`{S zP~`lk@`ZU1cv0|I9nwJ+M15^w%%^>{h0wK*EANJyNHu3ibGC9u z{U@^7Kmh#o5xcEc$GsQDmDHJ{yT(Js=E=$5ObYYrXeUkbUj{ODKq#D*Apsv|2z@IQ zeYXT#5Kxx^JwgNs$`?~MHk=J$Y-acAX+);kMr)2`G}`eCXDJ5DPCX&S#W~6GlSM18 z1xym1V!kIl9wl$roC>B}F+e{^Yabsn36g#-@SjhbwAQ)HJ>%TxWbGj&WMBt_?`_-V z{x1+#*ZUg~gwD&vo-(%*Q;9Rxi@B*A>a+2!1cwa8j;N(av_tNASH-!#6Gd|H{8=6R zTQWZoN@MAAR&`E@mn!MzgNpzHqgNLY|Lfp1|J4!aTKcL#q6pD1i*W`v%PpiiQgLMz z5@U7o#&KOaz_EIroe9nPLYq%CF=Yss2#?0)|a;2ntH3W=UQ*!L2d z-_4=FZg&Gn_k~;mO^wmJS(^=s!s%Lrwu)klcD|1I@C>v2;L<`?Zkwg>R2>{rAHM#R zY3}Nyz>*1cT*!~aLer(Ks zEof~JAlR=d18!hjVs9fsMiwk=@;IW>H6~ng_rvC|i7G{oVvy_XM))2b4SARQUb14! zy6#rWI`L=GqOSJsB*9lAomhYMw5x8NbhI_YjT&MlkCPT95BAEkD0ys)Y}y;KyrUJv-W68y=DN{j%s-ushzXv zp!izhJL>k!@(K0y#&&y5psJIOkf3U+?whB4h>bH?|~_)&0Ph* zh+FbNCV_^@ZIl|eZvWtpGPOe1INSf{tciS;*+UU!D0?4-E4bKpaFb)`Co>tpz7bl? zRQo`F@Uqjf^umYNg%HGa0q(-YR6sWm|Z5? zHBVZd>ZgMTihEwyUu#3nq5gP)2oSp;`{Kj0pxZjoZEXFNS^YJS`xNSs?C)WC2M59#IfHMnfh_;^!$gE&!s<_j zl4J(~;5a4J2Hy~`D?;;L8E`@5fxC9Y4oUuSTM;Tn5Eo%00I{`7a;@(IEx!@T7vS>9 zpX29N7~4{7@F(zTk>Xn<>s=-5-6bPo-^zq~2>YTx{8qvA-1fei5dR_rwj60kW1tccK^3FY zAOucNHXo_A5NZ($71@k_IXR}M8yVMv=t3&6+KZ9fVg8qm`>`x)mvt}nZhBjaf|b)5 z+-?)L`eq0HLKauHVJ*!jvhYLzvRz8iCLwqB?lFaQJ63RB31^&>qMoC}TNFJJX`2jU zm7@b!dZ-xPj`A8WAqbbczO|6%+dS*J_6^0$s<&p3(A6SEyTFea9fT7dWL2%BE^eHzl84?u`7%%0^Ei2i3+UB5ap%C8Av=Vl_35Q+xLQ zPt}uqqJ=x*Ir!Acl7RvxmDl(d2N@vyqVRovC|42T@sU&erVX()-BL(h=nMpb*&z0e zi!#E}j0~0G(y2@#W6WouFlWKIJL)XuCuEaoDc#lLePnPJEkd>WHa~wa#|XOqke8YVq2yC>PU+2OS<;j6S!(T;I=&+3%+2boA#YQvxvPJRm8@Io#}+t2E3|p@ z7^9?1MF4#~6(lNyVNvn>zT4nQgIXWW!jFX2kQh|z_5`r1W`+f<1U*c*tp6??Ct0Uh z@oNbCe|n_KL%o2OF#E$>@;?i=s2On@{?t%!F8b51xSz(CWI>t4RS*l9_}`{; zb)h|^|5@}4+=yM23va``|3-QjDvT3-mtB|t@B8AHb`G8J7v&}GzfJqd-$jZuqWS(o zasLT@lW38^h#%$E7>fLC)J$^4S6GYDOARYQbngH$h>c&fCfUq9?k7%Kw$vbg=z@gB;b`x(@%qb%77?ph7>osYI&Z&E1J0$V6i4 z#eeB2*)aFxNVF@i#u@l2gv^D6QEVggr4$O$NA!@2S(5&JuC_c$7v-LkIbj@ezURLQ zKop#e)?&6yHaBaw)mqJ2CS)jTx6Jq=lwWyYcOiczK%~m5y@&63_c`BooMn68>V|K+ zyUltgvMsUURwRU9U;J*E;0~in>phFZ4F_wF+7hMbuq57w)-6QJ4TgN`z+p!_M5D}c z`t^HYMQ#fRQmQDRW(hi-*7BOPepunM!-a?UZZHoGm>~0S2jASSa4sr> zo?d}C4#kDt&x3{Ym&cDj;J*q!y%|rN zKfaOBuvQNiQH!r;wz*Xvw|lGD?on}Xb|ZW~_ZoRUD-s0fe;-G7E{%0&%>|E~eA-s# zz`b!tRl5h{tRBw^(Bs;y*4+`WmHFO3aNb*uw{NVrdH6cjV?GdFpWgP-Z$o?WBVUhr z9Jdtr=0fr3-SaXf;C)|w=gT}^kd1t?|+;jHm92Yv>CEnuh-tVm$$w$BXGMc+^Kf?e*B*)XqLFp4jcQ3{o=UZ0r!5b z?y40|N7WCKze5tlfaS3Sd|W_vZ2rJW&A-EV*LU7qkaWIi{XPF2JK8BduNt%rf9}=N zpQ-cy^G25#b^b+(uQyGL2wroyPJQC1z;W}oUdgxq>Y2p{gv8~J1U;81ykhO2Szqb1 zzSa2+rIMzRuvv_fM>qH!M9J7MJ9z#`ld+W>> zqESyI9xlXh-y26hJ7k@iL>-!y(^2}!Gmd_G8oPtl_ibV17lMEu=;R*jbI7~SuV^(F z#CSEnU!2?7ZnU*Wc$XGku$fyjca~kYKAY6O?t%B+)pxBE_%v`>)xYKUZ-gaw$E3Pa zhSC9T@U{m;Bfp^+QkNVc;0<)sCH+w)lteD&q;mM=S2fSodF(H$T&zU@Nv86ffWvZq zUmBb7IfgsIhLvmZh|MGmYl|?d^aN z*s7y%Tl_I<(dw!Uj4_$fK!=SkxIpF>CjryP#u{5uA3ZFj@a^l?l6d~aa8s;Bs{jU5 zTmpF`J;j*KQ~-H(L-yc(@Shwb{sjVp3kcqus(e@X&!qcDpQ&7hhpd`maj*M}$iOa< z4d)7hyyvyUx~wVubZ_XL!AI*7eTd@EWtulcwi;;)s0=K0mo*EicmhcSecF+DO0lL4 zKg);C#JN5;$5f0?l=+kZhWi%8L!2)niRQ)Fu>42jb)m_!j1>-|x?v3(N@p)hpG_%~ z_R;YBtFWrk%IX9;V7c-poE?(2`lfIApL0R=3HA$7q2un>d9eXe^^IB3?K5fJCm|_R zH>d;W0_dCH?e=b%O#a}Hf-=FdjRYxH{)*&Ud509k!s7@LuUGzvQ(NH#v7%<~u7v@>mk}IHQ}N2!|hgRcBcaEgpwh zMh^Z`&de%K z*_Lv2@qN?MM>94>o8x>mC@Nda_Ub3Dht3=n^DW#VbA9P_qMuSN_SaW{85Y_duheg- z2*0k><9 z>X>?*(%+=V=f4Gx1(Xw}zDN7EoiuNc)*kbGuJv!5($lIeIgxpninBLF?w&g`}-n_gTl`w{GmCr6hK^3U~1e);dO^50zK%}+^x7P0w2_`7cQ zdQpDuU>EL1KBxcE2J6&*SLkx+v&^^xVNV{@5J1@4I>F+C;7E5qO&t+EqS*Q5-m|B{ zjuB@3s+;FcKf}4Nf~o}#p3(t#h{IvBaDWG@4plNAJhlgRT0bc;+b;?MeNKSsMTS+} zmqxMRUmPbGwm3REHZHO(QBgcGbPwJ)m!4DH{vj)fXQU2*pNJi|oESKa<0FzGfmbbK!zrKI z_%W)APHiId`{mTrGckjO&NicIs_!_~m&)~3-T3jx)fAn`C|3FS6Fe|!LVbd+j+As& z6^|KD6b`z=6x$WkD{_4<6ZX&eT%qA%kM3kDk#^8E{5XTqi`O3O0EtPr0PWd$q4-dC974_+e*rwIe!!=MdDkDux2$4B<&7`k4UUL0 zEk5n{Z&|y3c#O38x!<39?dxQxECC%5OqepyzxpOo?eVvtRs(VIG(`pWj(zlOy1nrs zWD0>ZONV}fySVh(#xqdIz^Cb9mDK4E$1K@7Gs;p1jU_pbtlW%72JVf9C<~&bs2xuh zPuc9d#JJc`$pq}-F&j5=q_?YrM^xn_6RX4Ve&5+^8!w9Ae?Cc0hxA;7^^&|PSxxMa zf3l_qT@J*IwXDp@-Ib1Xai8ztwWi>_g=HtJklMi+(nw_i7RV%SF9m2u&u(k&?3-^| zk?_Q#vinUa{9a%x==nCpDZasToH-tKN>(hDIr3&CDY;@fZ91kLP1Y=`>5J*Cl#f-i zipFC}%DVr!$(Qe-TD^vB@;gZ;7!z+G!T#I9*h7pOiP0WJl@>8CxkpNWL?GCABe?9) z%1Cps#D7(2;Ii2qbzSP!HIb4x{br|O)Ow_8Zir@y$89}YvTCF-Yr?)V$7nP?OhiM- zgUwSWIF$1YD~-QalR+4*UvgxhxZwpbxliCYn`JW}*RNQYoHeo5d!jap4>idov)-wq z-loL4A0OrDSsvsp7qflH*;l$Zs>fPr7G_A`xn}EqCfrPzJj7Gq0!)!rlt}0`+OsVV9W$I5D}s%0>lDD8VhrHjN_pwzzORd! zi_;f;kB^hHW#m3!tTf-CM{c;N(GdPM9E(f3R2wzT8^3A*JiWnUQs(*_J}j!3y^myU zTyLMyJ~Hao4D;~iCX2&|jpf94a1-Oj=SW?gA)wNz}=>z`!{xcLgmM27vjiDt& z9My1(j8b%P;1Gr?_lH+0a-BIF?|Ib?s97R^1ym_fmC=kyy;n{7N%E}U`QEOA1fy>m zC%_K3#Y!=6$7(=RJv=LWJ(D(&{BJ2``$*IY!!JVj3s%=Ei5rlOe`(BG!mZrJSxK;Ev;+>XFr>?7qM@hoU0DpqeY4VTgE|X0^r&cP)`6jjt&Pq{*tEVAougxkPc6&rHVA7<7ZXpaXPK;? zvZuo>*%*n>8#w;O)P~7znN1?4(z02L%Irgb<1doST8Iu z9A6{w9Si)HEu)_QbSs11Dpy*?@!%JVMCzu-G+uiN!EPA!d+5B2B}RWMhsYmpYqQZ&#?qOb$sar{uHf-HtecpL|-V8Rz{TE@bJbdd-Yz?&?KQCS7p|>KcLsjHris}6ibFs*ra9=;3elqYZj80>xv|!DSKYJX z9yyGWU{nVjl+Z#!N3-E=voyCuWNDpr?A#Yqc^{qtPbA?nA^Va|tfP1;>Q{ zIm0WuA`@GTlOz1s?d9KWalql^-@3wYjC-7veKx#5z%-)${=4LgAw(gwe z=Gu|tk*>z8J(=!SbE@@8fg+hH7t8jBBTYr>frUvk=Ow-qP1b5y&w~u^WlUw-Pcref zNOfdJxy*+p3P?7rhcxBzUbC&I=BvYc(!Og0#Hd27S~yV}y{y%MRuaEb9O_1dEfHmW zo7!M{_WBiQF70Ua)HWs8Q%`x#;okzDYlL9(fNoc-{fuq<$21unK1r7(`uS@oIUns2 zZRMhroQWWL8XrS^z7m;u*noea&6Cet1iEwg2~1#}dBj}J`9gVM4ghPK*Ldp|<+@9+ zo}D9MWK>Kpd@o|YPC2l*W{@$pjz>tfH&rX8Oiw(9%79Dgcxi{kA;)ClZ3)cMT*rx@ zF&#Y&x@veWC{4pSXeVFmIM6^1!b_tdHMMxqB8Ag5oKxL$X{Cu1tdHpa86NVlTNeHP zp~F)ht*L_Vk@^sK=myXY4-8~fpUK~qP-7~PU)=zG) zo)GOOw<$2vy{HOz~=_!5MK!EBh9Sgx-3B5 zQC&IP_47nD>n-*rd8!7<-a}x@b6LaWKa_s&1UDGRBkk}KFWfsTm(~yc@)74-I+em7 z9@>|uPA98b`~F((sR!Zf#8mMa^5*B6*WPY9ro}%(bKg3MUd^C;g;G}WUQf>5WMrAj z+eFu26ku+&@Q@pNs8AQt(unFs;S1j`V$}M_2_shR=ZP_+u#nd44+SZzH;$n(RZYg> zHi-larOaWo&y~A?yPBT>epS@J){smt_WaH;IHF>_Q4#iy6E$|$^`5@lEeop&^ zp!QPkP#(nI7gvW(;e^Dp%T77go;fs>yNN(u#5)!}ska0$aWtiF8VznWVb8jUR-p!D z55_zn$SSmI$T|fzH`-Ra)~e5Obz^*T`-PneJze8HRfCV7nQ`8VLSULa?#ax!^Y0T} z>bZ3HwLnf-Y(#s(OnO1U$aj-;(a-J^w4_Gb#1RO3BShzxMl^^ycIY9Ll zShzz47hpa|E%QBe7H};68TT=)nFs8a{~Un2PaY&(>1P#SuI%4?@^K87eCuET_s0r; z0e{$ysPoUfOMt0Ch_6qmTOsr}ZvQe={02xVX8phby8sA-d&Xf4{BT($s$zGJ)&|^NL6UFxTJB>5>KajU?^d zFLyOHNam>Ms2&)q6%s`s=;DesJc^Um^@u&~9bz-)vU#0nx1DEA0av+qADQ-M%u!qJ zv+esjHTgV3&p|j4>_4qY*v1wPgPcA7Nf^vC{16|(7vRx#KtQzb@^R_f*Fh{;gSrwR z1aB4Eil1Tv@IK7li=rZ0jZuwaQ$WbF3}>0jb?k4m4cI?$CFN@l;z4ptxs1hUrPcRa zCM=@%{rXih?FKLfVMri*t}S zMRA7?7F%o}{vo`P8q^xIak$=n(g|!fv=jv)zRjPaP?}tu+Jr z0_UG}BEg!R>^5iK1+Sp2)?&?!wTt zyN5ajtJTrqO%WG4mHZ;rXJx5W2*P>u3t@lxKo)z$nfVBbe-$8BspieFP&Kvxmje3V zS#;q*zB&ph5RhWz|5C1DEJWX_ly4df(7!7_o)9SJR$O@`^)GR=zVU55X$@iBp&IQ)x_i|qK zF2+HmK7vd|51~NSMs&Wv^*}bePI7iK|LOWqamE_rjy}MX!HOpltOi)KL2cU5dBl*c z)iG0wbNO)S%n2>$^)8TpW&E^p1?R5GmskHW$N=buJuHvPYOmmXa2wjoSmh&;BzzVF*RF}q>O>*(ksK#~Asc_hV-oq{g zcb9{_G?TH%Iac#t%s|%0SKsYCoUgIme4ghcU&wQ+Y)4$y6(xL&uYjU(tumU?Xg#|$ z)h6Wfu#k4IITTW;knFX?cUaSv9HswVc$~}%#A-OJsa)H>_E=JDDT@4hPif?=K}>!w zWM#Eho2oVLN+-C?#afthHY-7mB0`&XT0wVb*IgrtLgl^~5~M{a=Pu+5o#Oif1`077 zE)G*XtTmfn?YeBN;BTQ&@H?TY&@5S)?kwA0MIw3UI$Qxg$e)m}Ilycm&B&9xO(6^~ zw05IUGFWgdZU<@OVP-0 z80Y0!x%@i|;BwTM?zlcu0B9?J7~ce8lPR^*DH9BaHJY*zti@O36o=S{VkS&2VU9CM zTrtV#u7JIrt9P1?-l(_;4@H6T#cI6V3(O&(#~L8pC*EGiDYoLNF`_X)d>8=i9Fn=@#u|#)+jb zpPkM>k4>RC1KdQ+x8QPO9JUx2Tk+Tavm+CLY zdMEKvF?!@#CjofCeZdgDB_Z3y7;b?Zcth|Stz!rOBebCpETME6V@ZNcyt@5TYS_da zV#Pm2e;d6X`wjbW8mMl431p!$%?W92jH~)n;t83W@f?IJ5b%l-j6dHT0mMvx? zclM2(y*jb&;f-8;Lp@Qt(tjxs6cI*_Aom?TG9umh|L+|})nhT;84d(wiQ~VFG-nql zOFQ%bOFjL6bUprWMp}!ewFB-7x`28jzLXom?2u!44wX~#Fqzv;w}`gJMu__2ANBeq zMHpJooF66=k}O;z)b6Nw1itdW%jV(e;pkay%Z9%Ho-@SXQ{fv(TV%1&=e91v;G3l% zNSO27%sUfSsb1^e)WS>mp5JcV@%_VSbGxdl`MD}~!N^b|L=Blis8X!B_4)KJXk{u5 z{Dm7NGC}Sci_rt*ASF>Du|SpWq4R^Oa3QRwDm*6@5g2pbl4*mNVx5k}%s=d$OwXfP z{m+pp-;mp16e-_uJT?>sjC4NIle&X@uc-tN2lbCe%VvEzJ;NHm0o+cl;>{JK8}@7i zt_}n)CD<~XaKko#;6mq_y20c)7>{V9;(t#tJ&%!}k{D_;e*u;f5$oRfB@zgq?ej?X znt^9MZ%85^%-=p{`f+b@W8o1xgI5BlIBA}*1MG)b?mDM{HiA!#=q|{|#l?E4#c|#M zA5^WKwY`ejWKI)1I{q+^__b<0QNo#g(z>PmW3M7~3`MY}Gq>1@X*Fb8-yvVSX~tH@ z)3kFZJGtH*;Hsa3-&t_q`YEmeupVN~EJE|I<-yJ#T?Mw< zlv-s+$egPwXI}U1TUNf(z>bV`sL|22a4(?7>>Q?El-`?S>QvKsrC3}$UGMI7660FM z!ry~Ov93`klv~r;F4||CCfq!5+7s6q2~thHg%#EBZbC5Z=y(P-xMz(2=Q7H zT^;lxI_AxTE=faoLyWh1WjoGt3rw(ELVGxFa2Jr?G2P~^j1m^)piDkxMCTOAW9j6z zzbBegKfdy;qFhB$^wOI!$sPCG%yLH+O&?NCpW$p2{XM>pax~dHHBZ`li|tnSpkKW= z0!JA4a@b$KffcR`5LFf)4tRC47U}=(l2^QpBryMV{ert+8Pa)7b&t7uRtT)S? zm?>Zr_;9^kA6(2i#183QTTji)H0LWqJ-TX~<36IwbYZYX`!sgk^Cr=1u3mr3Uci?(csHf-GO_1dk4s`5_(IY>gxMx*o%rI48$F{&SqPbF zT_@6Ff;kCeFwFeI98FHh?89q1RPX)U@~kuGX-8M;8R<{oUBx&zW1pRFwKvV%);2@Z zm&CrIqn4g4r8QT+m+sYjpK?cP+5&V|v+GZ%2&@AjJOo@?VMG-QH zv);yC@ozk9bs8n(HW_QeOD$BUVJCCvqRsT_vdYSqk=@0$p{algM>;6T8Y+^uoJiBj z+-j@EMi!DqZqm9KV~)=$ z6hy}Z@nN4l1Q zV`F|2A%^sXhd34iZOYh6r9s)PtSV7sq#{dnvXt3jhD_rqqI2y0Z?pH0k0cTz$&-6~ ztI14!)f1<=UvBnttq{lK6(u!FeL@K5_&?`BH~0OC8k2QZi4y9_B1^1-Vmj2_5>`wO z_FsQ$s~xd$({8BHuxCm>BR<7x#lBJv-v9D1)c4aU6n&3MI?_}l;ag??A^1%8VS~mh zRqEybte%)!kTrZsz9K3Nyp(;my{lsi-;~qzJ{mK!f6~h24J|cjWx?&CuE;>EO4@9z zv)>bd+o!DiYyE!2X(n)h@RQti`7$KS^FWnyYGn9VcN?cV&RXP3hEs2Hxy4b$R~Uj3 z0m{1Ia!|FI8ZU`|hZ1wyWH9KIDhJHx&{bC4k8esc@LUf)2tIahcIx%+)btB(Jh4M+np|J{ks4@ zys9xMdvw6DbZF3I>kUnAUAES|hmcA=d-9~JZ0izs)kMY7!~9f)?s%zZb{;BGmLh7!Tc7&TKNJopy-6%u z1^_*Zt_=Zf&_h_<(FyqQg-%|B-l7S3@W}?0qtzYwBf=N%<`5AGq~q!_y}_{S*S3d_ z3rydjHr<00)_Vvh8!Q=Unl<(2Y1@g=iP#Jfq;S=uw=`9a zF<6Ff=D|zjLPmN6Y4^@;H^)e?-bX#kLyiO;aFGUOMn-y_1vkZ1;ZuMQ{}2$_zC%@p zg=hk-cph2{6nqRzl&TQcQCi#0Yn=#f( znI8!jyc%Y00`?8yvy$5O>ju->b`Yb9u<#LSOfjrmDNx*@i*v@+F>`{{Sy$shlYy?m z0l*YnN}BdP+fyLLWz>hPK1F%L__3ojDe(ROksfBG4QPUinV zSuu@0dprsJ@7e3yoV&!t033ZVJ15yCiUMLP+X5n{4gRrMNs@dbt^%COCSNJ~YiAdC z1_srXji~EHr3mQVcoQM(*=fJm z$1ir)y$+w7Nv9ihlvdlgc|Q`Ty>fQz8EbRQRO@ByhkZfFgy7sWl$Z`OJTaC0dBMPr zZrXE*)5o9k(`Vp(;Du6&&5`a`(uylJ;ff?HfjVJmvcaUD{&C4jy=08Z$FNZZ?O(<| zj8$w6ORq{E7-Y#$zEK?fLaAi9d|R`@bCpowz!eOJ0s>X2G7+vp^!92K4kgUz^gHdEhpp3Lv&(0 zg=Is}q0finD(*>v$Wp7yfN&b&1uTzj1*An-jzaJ7rX^$-nA10WDMK>LQsG0;65}>Lh{4XVI<80YML`Cx+32yLo7WQ(tnFUYgM4uhKMki8EihA2c3* z<|q&T_k7d_MU>9Xw@GvhA?(t^7oO`q2)C8IrWfr&P2jVZv7|Ql1$iHO=|xd~u^MAt z>3gEzlKWE&0n1~DwcY6N50P`dK8{DktIxXo1#@$JklpIE;W=biy=5WTXI)3$Jf)LH zw+xJj&Qnp`JB)TVgNSr6nb*gbG@aJQni~Ib5DH%IYg5ann?^9?igSVM9f-1XuFh{H z&n{Z=b7HP_hEpT&?r~zlMk-OA5YvRVK;TX?8%2t1p6y-qJZ}neP!vaM%nZjvTL}oj zxrAmR84DgF7dOcH>Q^h8icRazK%1)Sh85-$>^XQJ*0{Xh^xep(VO(A}f#7S?=fMvk z>^^0Iuc(k2k<}Nd=@`clX4&;@W&TvumtXif$+2X)=vkk!vbajz zVz3>JT&dZ{my^-h2)lyEqL8+0m2`{zQc5;l<3h2Y5hS6UQBV28PWT_Ncp<)GQa;(` zKeiaQYW2X$ni0bhKO3ZP$?*w+Mye|%^sVmCZq2rZaczeRgB>}0JNC36<6%3*tFi4J zalVO`1h!$F+fBxlwH7~W4F-XjB_1ckt=(Bh{x(N`hdnF!?upDV|3prv2u3R2P-bO$ z!vxo|9%DE*pyzGZv~S)u(iQ;o3MQ@XuaZp)`?SJhdq%%_V2MHWwCe--sEawyMHTFH^2 zK_|^Ri_Z*x8j(CETKAN1m7P70t-);>)qHgVtQ%T|+k=tl*)L(A)uztVS>t#%KGN+g zIM%F49oA&_Cuh98J2t5LTwks?+NQ+O=-Pm)o`#mKtqOY7aan64PH&e=O?-lWw=%Fl z&9=(q1e_mau&dnZ%+F4V_l?_snvvtBt z{Q3?ka(*!u66%lQ&#+O@IY}JDjsY}Qp0ma@#(sXtLw3$eq({}uttpvk!gLccbEjcn~o#!K50d8uglfIe1~~k^peTj`_?8l&l#U z*Y-MPA{hG6@yFS+?%mGZ{XW&cd4Jwzqs=(;hQTk0&TaEEzp z3&ftTffBVY_XRye^ZZ*t;x7xS;>52Dy{7UHqbG{3)J9}@#t30fO8 z=ThYEBhC19bM6>2y319Ycnc+sAiSPK1-~zm*zY&qH~6V97kFf4ijrw!B*qwE4A?U3 z5tBG{T+EFQG^Hq+$c$B3G?5lJX%0u5vw-u7H_w@_uLwo+T(`6qaHHM*3#oi(%|EHp z^L+pI>5~m_7mD^O7tdUKS;y5E+t9p{Be}_Gv_HS_rZ@DU5!~ax9k4r;k$?x5XrZ0t zL>)_KQjH~1)i69UJS~O&K)>I$-B1H|c7g)tg_|za4IHKcASkAG9zi#vL9AL3tx(uK z<#`miLUY~Dt?1#G=gc z42$E^8{$Fa`XkNd%T>D4zd{)!YD2D0vo^d+fVEZCDaCn<=DMB!_d~=eds^%IP5=5) z5PQZ=LaGZT*nf)&oUm>JN+vTUu}ipT#)NG`=F=qdOQN6gx!83dZA|q%Sl7fqJrzy( zT*pUKjAqB`urbxO zy}~I#BH?-D-$XuWsI!A;tJv$F+82n- z)hOZf{2kpu3|KbaKac0)fS43HydZYq3pOVJr~EVAM9tR*o4pMwcLP@D-oFODF9S7^ zvVTo*KZ7VH7nmhPJ__Mr2tq-Kim5F56E;s#hedA(y!16( zUl6SB2Du4)+BW!|0Kik9KDda~o-5>>W^sdj1FAs)W)By*hY*oMe1FPt-vzfjxqk!K zZsy#x{B1f2`AA4Yy>(Y2&iXXAY|(1JT-sH!!1q-ZM~?0ILHNJ(x&NoIGXaO{ivsvV zc1eUNjL1&-OQo`tU6!I021C|i#voDIN-3p9S)zncl2BTt?7J33L?W_ODrL|AK4Z*0 z8S!1;@R{E|_nvdlIq$qX@49DP;wWALLCvhhdafS^ci6#one?b&&p~XD_L?HUM4q~% zBgdt3Eo<*^yK)tr^5}Qh;`ZMEZbNHCT9o?v*m9G^CN~Gh_BMv>y+e8?{!9oOQ8!ch9J4ZXRcGrJzlp8dooeKV7J z!1O>@sk>k<7OE3DUN6Dv^&zPAxSloCv4Z0VO1+Z9{tcvI&2&$Y8P)SewIcZ3(9v?j z>DA0bC{0yPv}dj%!T$a8ZN2vOty;k`*^Rrl+I?8RxexV1tS(|@mCi);iW3~n33v`K zU+-faDZ#>wj6a3SnI?MJnbxgFiI;@P^Pbzjx8+IFoHnziOR3;3Eg|1IX5dS>w$M?#@pKko(+ejTn3qM`lQFmtGL87Tj=PzDhdEf>@YdsOnQIb5Zm}l$gm{aIM`eUy{f+T~1pTx? zrCUFWneOKgTF0~4*uG@_aZzBOa@h0Vr73$9hO9mFJH=F@-O7BY$_Ay<(5pWT=$DXtnt2o`xi0i9JKPYnO{xcJyS+azI5(8v|q#~<`q+XZ$rdbXW@(W6-~5`Nvn*tnryTih+Zf?rxTDL!k2tEuNr&wtKoq2KbN zOloQm`5j_WF&s)m2AH(T9k(BS+&qZZlz z{5fBnkNbDp=R9YN9C!HCD~Jnh`l`{XlxS2Mus+;68@)p?y8fO&%j??wmE2G4cuXD` ze3u#R7-+peQ)qW>%H&XGX=fFyM`zoxy$U#>bJGLON}m(8S98ZApGDOdR{DR!@Y86u*sLrgCqEZ}X13qCkptDmmD3DL5X#ApqWQ1B)&2JsSW=84p-q3*O7mJ#*zJ8bb!;9k^ z#tmyt3%>6cQ|lQIqPM$qeTsIyi#JZgcVf1b?b-g230iBuQN^mCT8`!G-rfC@aHIdq zanvnmRui@3el>PBKgMI&gRz%7Z){%mfyY)ls82Jb@$)w<+52T(|E4@La=2uS4uX7F z5kGZ^_VAFy5`6bqGDCFUi*ICE8Cr;J;ZRLav3uoBBh~uf(eK{5od)LHc02L1;A$`; zjrpD-y8NPNU(Bk?)_*7u`yO?0orLl2siBrzN7?kzY*LKd{4c7~jT;r$f5uzz1fjXP zTeQu^59s=ptke~a4y^(W5DunrkpdYkz_EgLQ{#}sP#61Yyg zjeT?W=q+%4OlpDvrb+R3=b zrO;Zpb^Qgy8Jg5&j*k7BN7Z%zM9TA9RItBaq0ya3r=+`%gJ)!0Wf_{KlyCfCmuhsZ zwW+GpS)n|JKf+V1pFE2nD_7W}rK+o!f62-Ceatr1ONaKgeUe$nEhYJ+FNof>#Mq!R zR^M2DQ;lhr&~;k9)%apF(Yx}aMz&o8E!n^KWFNe>RVKqV>PELS!-2HR+8Hs*e5-u^ z@H~^=J#@XRXY9C=Rcf~S-jcFxzm*v(p2ss!XmAg%$KHPKQF2)`FCq6urRG|vV)?af z3?FXf(`9b+QMTB@Rh?KF6~$_PQ+!C=?Y1jnR>!VC164P;W^^RUoJLpELFk#=Jsm}6 zQ}t7^7jnwXB#HyMSbl9}_sU*-`%I_Mu)-rD)(x$t{3h>2SrWM>goT4XdJt+x1R)DA zZ9Tav4En_&o8*^k-M%Z!59M?IFph4E!%a_c53HlNd^N1`XGP=sTZ!?UX1_IhA5}IV zPI+^G+Cyi;;p1`b&FQqSEtEtulS7AQ1zDB;le$K?`v6_qxaB6^*iU;}?5!>Kq;Ak? zx67F|r*${#?7wlu_Ev7V8hd@lQ;gKB_vUe(+XeXPEk9I;uUKcFzoqy}7gml}4)bP5 z^~>*BX`Y7#4XnH>+JBzc^9-)N<5qE~>v`DJuUm=Cmt2)zO`^N+*#zWFPPUlc-mor3 zGAw;v;`oD~whq`g>kE8_qyLPbG%*rVKXs#VH;-1wnJ4xNuJ>&`TKBkJGyh_4*7oR8 zR=SyMEPsCBiw}i&62G=hxCR+KjQP|Qekb{4!F54a72W#&eFOMUz5`7*0-xA4y+&I{ z>Poslq)vI~$KFj-!V->cc+Fb>vR1hH^t)%FE&6Mcb-!#?P2>0H@SpU_>56XaqGz1U zxucycyfO3Bl<-;CV|l0Y32N`}zVw$`tIT=2@bR+D&G9Msn3Mh6Uyl4Gl69Rdt3|-fSZ)40)wnTU)(z@iY+9H{~gKiChHT zRDi|;cjXIiwL4JlZF95+dx<)e&XtO7^heHCc)l5>6$@lg3Hx%DXU*r7hgbODpAY&W zC?x)~hEAgBO4cPm=Erx#&eVOBXXcTR?m6(EQGrzx_qzuxWiDKEJYXVLpL~T^p*7Ng zKJ}QnUqI6-{zB%~3zb+}Gl^H15Bk2x8mNfQ&V)DmX7xeSSYL$b&39Ma8;Z18cg-+Z%gdGmz&$|&`-NaM>3z?Jix(nkRWJt zlZf>K8$1Y(zGOw=s3=O}Zk@FLoe!^dL;rLhpupY%Q~SZBSq>ZmGdBtbFbXHK8RMzo z^z@CTjIFAwjid}@vMhn_Lry#OrG4W4Bo^z`*YD#RcB6O;@1kyK%3Vre>A?e&=T-~` zhr{B?l2h$UR;p%`RNrd`Eu>Y!k{iDW{>cw;aDx{i#t-8~F&T@Iz8JhO*bam8#Q37; zY!A;O4ZckcS;%UIvB&mZxw``(bwGpHg0rg!=HG%=H8u8w`Q51Q6LD$!sb$3U4tlNs zg6Z(VB6M_kfrv6rdOAmGItytLN4ezJ+VmDXwTO#k4d{glg8OX`jVN*kznujQR)mY= z!s1vw6yr07?4|Nd+GB~KVb;&od3MtIL^^WEG2O$>sF+C;wj^)i8h#a6Zt%byBO_I^ zG2V}9e}upe4_fxA&!&HFjkx)s5;C_%HY5lIDHMG_a!(=IU%`Ma;ZK2j17B3eLl?~# zSIue17b&pMGoS}N0|F8N4Sw9UhpR6J2Oo}1@)C=MBzXx56O+1HL)nk7Pb{IsLzvlJ z{{bT0U>(jMxJ->n(&5~{p}^e&SJ;W*QQjT|JPMEX#Gt@KxN&F{-k0F)yp(b`D<(uS z&;T=}C$8DKBN|D){k1*H(%7(6oulYmPC)PL-}iW=1*KXNc+)(m)o)z6f6C&?d1o!f zn9n)>DQU5y_J{W4+JgW4CUTA={fy^yw8Rz{;R7Wt<#9iH2Q%A4OP(g$b~7H2mhUxI zyi}`LRcUuy^SZ!~-r^NK+cgwT4E5U{us46N7rI{ zkKH=d+wI0bFb`7&BE!S8m@!pt!$Q}YZQxw z$F;X%CW6`cTZc?M1}jbsl-XrY6iqU~tApsuVJn@~z8A6uC<|_|)AK}wgQKWTAW2*qf3L?2p`~FPL2uHa!M>mL zoONoQF4&#EQH{QAi&>Rnw!|y5xd>IeiP8$mOV4IQ(WDT-i-HC(J@9~&f7112B=u!$ zEUJuU^cx@+Z&$4)oL)cPy59#d8$p97Yi`T;KgkW7q`FxcI8o8LG#nDCeW`uveV5lr zJM~Gf{mge&V$ChFAs_m*L7pB9XEw9GIIGzGmb6y!b{Asyhwlj!E;}F)@uThn8$B1R zh=`$91o#MAXjw|#$LXgIzPq?%#rm$dyRzrL=}KT-w7%Cc2>HR|mj?}=X42-te~K$7 zNo!uta_X?;?gyGC&gNzgW*e_4ub(`ENSa{NNujZQN*My?Z}$DO149`D8H4^ML%={P z)_yAx7;do8qzV}|CdnW@z+FZR${UAu!J$3zC<#?%C3nfC?QuRr(9rVI5e=s8-Z$k3 zYo0!-0oSH8jIhCgbJV~W@G4Mh2>i-iM?>3KXOAU4L^n7MKmQ*Bb4><#`UEP8jFkjx zfYRO-u(B8_0KFk};IHtdt_J}*`LvTnxlDy38u>H99_TRxY{q3mP}~dw11jH9e z!g=SSMiYQwfpUPiE$2Y!%tvLSREcm^V8MI_8MDwxvp$$($LgJb|>L(b~s7=Xb7yPw;*J-2j{mVoGH z3@blMuuZ50b~gK$oef`xKxif&KRt)gnuz_&5&47RNIp#RoC2Rp+6i0<(p103!wBNB zkaLI|OGp7D8r3eA?gztg1-eD98PODIAzYItBxMOo0HACZ*kSGnZggxAU96a=cOW<- zlK`np01gAdC+k%1i@*mQ0i!{V#JUjpr}=+`+}(;y43WRVwk=$O=#w zpaItb3o9L%wluNIZHzkaEKK6vU4d)K$zR{O~72t%okIvlK^EQ;w(@3!Mv|f6;Paj z>5|+uaWv)kX~-dGc?cAd!gPTPg6Ov`o)Yy+n)#TsJfYTm^o9ml$I~JZusC8`LKK6o zodywfmgj^G$aR2K3}pd-K=LX?&e-oICa{2V3{a2;S35+r5O$VlAP*p> z9FgBB%vd;%7$ni~b@@^%MxMY$$#_IVOBr~GqEN#iA8$#CxyesEA9(I}a!+>r4QJ9DS%`{=S7r#1Jo& z_$+AWu5#us)PRbqg$`s*pORo;1qh@H|1tz*sh*Nh023$*_f#OT&qvnBDIpQow3O9y zz(B?gkOP1(m@)Ta{s$?ehks2C>4h2OxIvl|BnUVmuySD#vKUS&%*K5HL|GdDOB^x< zS-qyDJccO?wd`dOGKh*aB|>sPj93U7q!Cf`_{bVGCFnQ+kt)(a5^ByKSzV?C^aB88 zt@$qqQ9*FrLDrKgAu2WiLQ!4*3qqV$7=o-GQ$k_@grb(b3-50044%a2W)$PDhD| zv?s@je~koLi=(6r0t#hi?k`cudO=p-C?Px1c(27>g!w-LyS^1%N>(ErM~ B7p(vQ diff --git a/src/test/res/strlib.lua b/src/test/res/strlib.lua deleted file mode 100644 index 2d558800..00000000 --- a/src/test/res/strlib.lua +++ /dev/null @@ -1,169 +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( 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 ")) - -specials = "\"specials\": %% \000 \r \n" -print(string.format("%s\n%q\n", specials, specials)) -print(string.format("%%")) -print(string.format("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 ) -strtests('dump', string.dump, function() print('hello, world') end ) - - --- 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/src/test/res/swingapp.lua b/src/test/res/swingapp.lua deleted file mode 100644 index 37775b6d..00000000 --- a/src/test/res/swingapp.lua +++ /dev/null @@ -1,29 +0,0 @@ - -frame = luajava.newInstance( "javax.swing.JFrame", "Texts" ); -pane = luajava.newInstance( "javax.swing.JPanel" ); -borderFactory = luajava.bindClass( "javax.swing.BorderFactory" ) -border = borderFactory:createEmptyBorder( 30, 30, 10, 30 ) -pane:setBorder( border ) -label = luajava.newInstance( "javax.swing.JLabel", "This is a Label" ); - - -layout = luajava.newInstance( "java.awt.GridLayout", 2, 2 ); -pane:setLayout( layout ) -pane:add( label ) -pane:setBounds( 20, 30, 10, 30 ) - -borderLayout = luajava.bindClass( "java.awt.BorderLayout" ) -frame:getContentPane():add(pane, borderLayout.CENTER ) -jframe = luajava.bindClass( "javax.swing.JFrame" ) -frame:setDefaultCloseOperation(jframe.EXIT_ON_CLOSE) -frame:pack() -frame:setVisible(true) - -local listener = luajava.createProxy("java.awt.event.MouseListener", - { - mouseClicked = function(me) - print("clicked!", me) - end - }) - -frame:addMouseListener(listener) diff --git a/src/test/res/table.lua b/src/test/res/table.lua deleted file mode 100644 index a60c479e..00000000 --- a/src/test/res/table.lua +++ /dev/null @@ -1,224 +0,0 @@ -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, maxn -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,"b"}', #{nil,"b"} ) -print( '#{nil,nil}', #{nil,nil} ) -print( '#{"a","b","c"}', #{"a","b","c"} ) -print( '#{nil,"b","c"}', #{nil,"b","c"} ) -print( '#{"a",nil,"c"}', #{"a",nil,"c"} ) -print( '#{"a","b",nil}', #{"a","b",nil} ) -print( '#{nil,"b",nil}', #{nil,"b",nil} ) -print( '#{nil,nil,"c"}', #{nil,nil,"c"} ) -print( '#{"a",nil,nil}', #{"a",nil,nil} ) -print( '#{nil,nil,nil}', #{nil,nil,nil} ) - --- 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 b10 then break end -- exit the loop if the condition is true -end - -for count = 336,330,-2 do print(count) end -- numerical iteration - -function sum(a,b,c,d) -- "sum" method - local d = d or 0 - return a+b+c+d -- return sum -end -print( sum( 1, 2, 3, 4 ) ) -print( sum( 5, 6, 7 ) ) -print( sum( 9, 10, 11, 12, 13, 14 ) ) -print( sum( sum(1,2,3,4), sum(5,6,7), sum(9,10,11,12,13,14), 15 ) ) - - -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") ---]] - - -end \ No newline at end of file diff --git a/src/test/res/test2.lua b/src/test/res/test2.lua deleted file mode 100644 index 3993cbe2..00000000 --- a/src/test/res/test2.lua +++ /dev/null @@ -1,80 +0,0 @@ -function sum(a,b,c,d) -- "sum" method - local d = d or 0 - return a+b+c+d -- return sum -end -print( sum( 1, 2, 3, 4 ) ) -print( sum( 5, 6, 7 ) ) -print( sum( 9, 10, 11, 12, 13, 14 ) ) -print( sum( sum(1,2,3,4), sum(5,6,7), sum(9,10,11,12,13,14), 15 ) ) - -function myfunc(x) - return x*x; -end - -print( myfunc(0.25) ) - -do - local oldMyfunc = myfunc - local k = 55 - myfunc = function (x) - local a = k + oldMyfunc(x) - k = k + 5 - return a - end -end - -print( myfunc(0.1) ) -print( myfunc(0.1) ) - -i = 1 -table = { "west", "south", "east", "north" } -function next() - if ( i >= 4 ) then - i = 0 - end - i = i + 1 - return table[i] -end - -print( next() ) -print( next() ) -print( next() ) -print( next() ) -print( next() ) - -function room1 () - local move = next() - print( "room1 moving", move ) - if move == "south" then return room3() - elseif move == "east" then return room2() - else print("invalid move") - return room1() -- stay in the same room - end -end - -function room2 () - local move = next() - print( "room2 moving", move ) - if move == "south" then return room4() - elseif move == "west" then return room1() - else print("invalid move") - return room2() - end -end - -function room3 () - local move = next() - print( "room3 moving", move ) - if move == "north" then return room1() - elseif move == "east" then return room4() - else print("invalid move") - return room3() - end -end - -function room4 () - print("congratulations!") -end - -room1() - \ No newline at end of file diff --git a/src/test/res/test3.lua b/src/test/res/test3.lua deleted file mode 100644 index 89b9b29d..00000000 --- a/src/test/res/test3.lua +++ /dev/null @@ -1,62 +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") - -function first(...) - return 'abc' -end - -function second( a, b, c ) - return first( a, b, c ) -end - -print( 'second', second() ) - diff --git a/src/test/res/test4.lua b/src/test/res/test4.lua deleted file mode 100644 index ef651b51..00000000 --- a/src/test/res/test4.lua +++ /dev/null @@ -1,8 +0,0 @@ -function Point(x, y) -- "Point" object constructor - return { x = x, y = y } -- Creates and returns a new object (table) -end -array = { Point(10, 20), Point(30, 40), Point(50, 60) } -- Creates array of points -print(array[2].y) -- Prints 40 - - - diff --git a/src/test/res/test5.lua b/src/test/res/test5.lua deleted file mode 100644 index 372b0da1..00000000 --- a/src/test/res/test5.lua +++ /dev/null @@ -1,20 +0,0 @@ - -i = 777 -while i<780 do - print(i) - i = i+1 -end - -a,b = 0,1 -while true do -- infinite loop - print( b ) - a,b = b,a+b - if a>10 then break end -- exit the loop if the condition is true -end - -for count = 336,330,-2 do print(count) end -- numerical iteration - -for key,value in pairs({a=10, 3.14159265358, c="banana" }) -do - print(key, value) -end diff --git a/src/test/res/test6.lua b/src/test/res/test6.lua deleted file mode 100644 index 61ed1001..00000000 --- a/src/test/res/test6.lua +++ /dev/null @@ -1,99 +0,0 @@ -package.path = "?.lua;src/test/res/?.lua" -require 'ids' - -t = { 11, 22, 33, you='one', me='two' } - -print( "---------" ) -for a,b in pairs(t) do - print( id(a), id(b) ) -end -print( "----" ) -print( "t[2]", t[2] ) -print( "t.me", t.me ) -print( "t.fred", t.fred ) -print( "t['me']", t["me"] ) -print( "t['fred']", t["fred"] ) -print( "me", me ) -print( "fred", fred ) -print( "t[me]", t[me] ) -print( "t[fred]", t[fred] ) -function out(t,...) - print(type(t),...) -end --- basic metatable setting -t = { 11, 22, 33, you='one', me='two' } -mt = { __index = out, __newindex = out } -setmetatable(t,mt) -a = t[11] -b = t.one -c = t[1] -d = t.you -t[4] = 'rat' -t[1] = 'pipe' -print( a, b, c, d ) -print( "---------" ) -for a,b in pairs(t) do - print( id(a), id(b) ) -end -print( "----" ) - --- delegate to actual metatable -s = { } -mt = { __newindex = s, __index = _G } -setmetatable(t, mt) -print( t.you ) -x = 'wow' -print( t.x ) -me = 'here' -print( t.me ) -t[5] = 99 -print( "---------" ) -for a,b in pairs(s) do - print( id(a), id(b) ) -end -print( "----" ) - -Vector = {} -Vector_mt = { __index = Vector } - -function Vector:new(x,y) - return setmetatable( {x=x, y=y}, Vector_mt) -end - -function Vector:mag() - return math.sqrt(self:dot(self)) - end - -function Vector:dot(v) - return self.x * v.x + self.y * v.y -end - -v1 = Vector:new(3,4) -print( "---------" ) -for a,b in pairs(v1) do - print( id(a), id(b) ) -end - -print( "----" ) - -v2 = Vector:new(2,1) -print( v2:dot(v1) ) - -print( id(Vector) ) - -print( "=======" ) -for a,b in spairs(Vector) do - print( id(a), id(b) ) -end -print( "----" ) - -print( id(v1), id(v2) ) - -print( id(Vector_mt), id(getmetatable(v1)), id(getmetatable(v2)) ) - -print( "---------" ) -for a,b in pairs(Vector_mt) do - print( id(a), id(b) ) -end -print( "----" ) - diff --git a/src/test/res/test7-expected.out b/src/test/res/test7-expected.out deleted file mode 100644 index a8f9d418..00000000 --- a/src/test/res/test7-expected.out +++ /dev/null @@ -1,7 +0,0 @@ -java.lang.Object@xxxxxx -org.luaj.sample.SampleClass@xxxxxx -Hello -Hello -true -World -Square root of 9 is 3 diff --git a/src/test/res/test7.lua b/src/test/res/test7.lua deleted file mode 100644 index c0597fc5..00000000 --- a/src/test/res/test7.lua +++ /dev/null @@ -1,21 +0,0 @@ -local function fixhash(msg) - return (string.gsub(msg, "@(%x+)", function(s) return "@"..(string.rep("x", 6)) end)) -end - -obj = luajava.newInstance("java.lang.Object") -print( fixhash( tostring(obj) ) ) - -sample = luajava.newInstance("org.luaj.sample.SampleClass") -print( fixhash( tostring(sample) ) ) -sample.s = "Hello" -print( sample.s ) -print( sample:getS() ) - -sample:setObj(obj) -print( obj == sample:getObj() ) - -sample:setS( "World" ) -print( sample.s ) - -math = luajava.bindClass("java.lang.Math") -print("Square root of 9 is", math:sqrt(9.0)) diff --git a/src/test/res/test8.lua b/src/test/res/test8.lua deleted file mode 100644 index 77318f6b..00000000 --- a/src/test/res/test8.lua +++ /dev/null @@ -1,12 +0,0 @@ -t = {} -t[1] = "foo" -t[2] = "bah" -print(t[1]) -print(t[2]) -print(t[3]) - -t[1] = nil -t[2] = nil -print(t[1]) -print(t[2]) -print(t[3]) diff --git a/src/test/res/test9.lua b/src/test/res/test9.lua deleted file mode 100644 index effd1c77..00000000 --- a/src/test/res/test9.lua +++ /dev/null @@ -1,15 +0,0 @@ -local x - -local function g() - local a, b, c - return a, b, c -end - -local function f() - print("hello") -end - -g() -x = ... - -f() diff --git a/src/test/res/testfloat.lua b/src/test/res/testfloat.lua deleted file mode 100644 index 230864df..00000000 --- a/src/test/res/testfloat.lua +++ /dev/null @@ -1,5 +0,0 @@ -local f = luajava.bindClass("java.lang.Float") -print(f:toHexString(0.5)) -print(f:valueOf(0.5)) -print(f:valueOf("0.5")) - diff --git a/src/test/res/type.lua b/src/test/res/type.lua deleted file mode 100644 index 1619c3c4..00000000 --- a/src/test/res/type.lua +++ /dev/null @@ -1,8 +0,0 @@ -print(type(5)) -print(type(3.14)) -print(type("hello")) -print(type(function() return 1 end)) -print(type({})) -print(type(nil)) -print(type(2 < 5)) -print(type(pairs({}))) diff --git a/src/test/res/upvalues.lua b/src/test/res/upvalues.lua deleted file mode 100644 index ea760070..00000000 --- a/src/test/res/upvalues.lua +++ /dev/null @@ -1,25 +0,0 @@ -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()) diff --git a/src/test/res/upvalues2.lua b/src/test/res/upvalues2.lua deleted file mode 100644 index f1c667d9..00000000 --- a/src/test/res/upvalues2.lua +++ /dev/null @@ -1,42 +0,0 @@ --- 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. - -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() diff --git a/src/test/res/upvalues3.lua b/src/test/res/upvalues3.lua deleted file mode 100644 index 2e8e2c03..00000000 --- a/src/test/res/upvalues3.lua +++ /dev/null @@ -1,14 +0,0 @@ -local f - -do - local x = 10 - function g() - print(x, f()) - end -end - -function f() - return 20 -end - -g() diff --git a/src/test/res/varargs.lua b/src/test/res/varargs.lua deleted file mode 100644 index 3be8b527..00000000 --- a/src/test/res/varargs.lua +++ /dev/null @@ -1,51 +0,0 @@ - -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",a,arg) - 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 -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') diff --git a/src/test/res/weaktable.lua b/src/test/res/weaktable.lua deleted file mode 100644 index 60a9140d..00000000 --- a/src/test/res/weaktable.lua +++ /dev/null @@ -1,150 +0,0 @@ - --- normalized printing -function eles(t,f) - f = f or pairs - all = {} - for k,v in f(t) do - if type(v) == 'table' then - v = '{'..tostring(v.v)..'}' - end - table.insert( all, "["..tostring(k).."]="..tostring(v) ) - end - table.sort( all ) - return "{"..table.concat(all,',').."}" -end - -function newtable(t) - return setmetatable(t,{__mode="v"}) -end - -function new(a) - return {v='_'..tostring(a).."_"} -end - --- basic weak-reference table test -local strong = { new('one'), new('two'), a=new('aaa'), c=new('ccc') } -local weak = newtable{ strong[1], new('three'), strong[2], new('four'), - a=new('aaa'), b=new('bbb'), c=new('ccc'), d=new('ddd') } -print( 'before, weak:', eles(weak) ) -print( 'before, strong:', eles(strong) ) -print( 'gc', pcall( collectgarbage, "collect" ) ) -print( 'after, weak:', eles(weak) ) -print( 'after, strong:', eles(strong) ) -print( 'gc', pcall( collectgarbage, "collect" ) ) -print( 'after, weak:', eles(weak) ) -print( 'after, strong:', eles(strong) ) - - - -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( newtable{ "one", "two", "three", a='aaa', b='bbb', c='ccc' } ) -tryconcat( newtable{ "one", "two", "three", "four", "five" } ) -function tryconcat(t) - print( table.concat(t) ) - print( table.concat(t,'--') ) - print( table.concat(t,',',2) ) -end -tryconcat( newtable{ a='aaa', b='bbb', c='ccc', d='ddd', e='eee' } ) -tryconcat( newtable{ [501]="one", [502]="two", [503]="three", [504]="four", [505]="five" } ) -tryconcat( newtable{} ) - --- insert, maxn -print( '-- insert, maxn tests' ) -local t = newtable{ "one", "two", "three", a='aaa', b='bbb', c='ccc' } -print( eles(t) ) -table.insert(t,'six'); print( eles(t) ) -table.insert(t,1,'seven'); print( eles(t) ) -table.insert(t,4,'eight'); print( eles(t) ) -table.insert(t,7,'nine'); print( eles(t) ) -table.insert(t,10,'ten'); print( eles(t) ) - --- remove -print( '-- remove tests' ) -t = newtable{ "one", "two", "three", "four", "five", "six", "seven", [10]="ten", a='aaa', b='bbb', c='ccc' } -print( eles(t) ) -print( 'table.remove(t)', table.remove(t) ); print( eles(t) ) -print( 'table.remove(t,1)', table.remove(t,1) ); print( eles(t) ) -print( 'table.remove(t,3)', table.remove(t,3) ); print( eles(t) ) -print( 'table.remove(t,5)', table.remove(t,5) ); print( eles(t) ) -print( 'table.remove(t,10)', table.remove(t,10) ); print( eles(t) ) -print( 'table.remove(t,-1)', table.remove(t,-1) ); print( eles(t) ) -print( 'table.remove(t,-1)', table.remove(t,-1) ) ; print( eles(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( newtable{ "one", "two", "three" } ) -sorttest( newtable{ "www", "vvv", "uuu", "ttt", "sss", "zzz", "yyy", "xxx" } ) -sorttest( newtable{ "www", "vvv", "uuu", "ttt", "sss", "zzz", "yyy", "xxx" }, function(a,b) return b