From 8322130890328dc567b52a1178b87a712612ba72 Mon Sep 17 00:00:00 2001 From: nillerusr Date: Tue, 3 Oct 2023 20:02:58 +0300 Subject: [PATCH] WIP: port alien swarm and extend engine for asw --- engine/GameEventManager.cpp | 87 +- engine/GameEventManager.h | 21 +- engine/baseclient.cpp | 8 + engine/baseclient.h | 2 + engine/cdll_engine_int.cpp | 9 + engine/cmodel.cpp | 48 +- engine/cmodel_private.h | 2 +- engine/hltvserver.cpp | 10 +- engine/hltvserver.h | 2 + engine/sv_log.cpp | 9 +- engine/sv_log.h | 3 +- engine/vengineserver_impl.cpp | 6 + game/shared/choreoevent.cpp | 26 +- header-list.txt | 9 + public/appframework/iappsystem.h | 1 + public/bittools.h | 46 + public/branchingsingleton.h | 48 + public/cdll_int.h | 4 + public/closedcaptions.cpp | 62 + public/closedcaptions.h | 70 + public/color.h | 8 + public/datacache/iprecachesystem.h | 51 + public/datamap.h | 11 + public/edict.h | 1 + public/eiface.h | 5 + public/engine/ICollideable.h | 2 + public/igameevents.h | 16 +- public/ispsharedmemory.h | 27 + public/networkvar.cpp | 2 +- public/networkvar.h | 286 +- public/networkvar_vector.h | 341 + public/tier0/logging.h | 768 ++ public/tier0/platform.h | 18 + public/tier0/win32consoleio.h | 32 + public/tier2/resourceprecacher.h | 195 + public/tier2/tier2_logging.h | 72 + public/vscript/ivscript.h | 1467 +++ public/vscript/vscript_templates.h | 521 + tier2/tier2_logging.cpp | 123 + vscript/CMakeLists.txt | 125 + .../manifest_vscript/linux64/manifest.txt | 412 + .../ConTEXT/Highlighters/GameMonkey.chl | 219 + .../Crimson Editor/Link/extension.gm | 2 + .../Crimson Editor/Spec/gm.key | 80 + .../Crimson Editor/Spec/gm.spc | 34 + .../PSPad editor/Syntax/GameMonkey Script.INI | 76 + vscript/languages/gm/bin/StripCR.exe | Bin 0 -> 5632 bytes vscript/languages/gm/bin/bison.exe | Bin 0 -> 196096 bytes vscript/languages/gm/bin/flex.exe | Bin 0 -> 181248 bytes vscript/languages/gm/bin/gmd.exe | Bin 0 -> 86016 bytes vscript/languages/gm/bin/gme.exe | Bin 0 -> 438272 bytes vscript/languages/gm/bin/gml.exe | Bin 0 -> 90112 bytes vscript/languages/gm/doc/ChangeLog.txt | 324 + vscript/languages/gm/doc/GameMonkeyFAQ.pdf | Bin 0 -> 155118 bytes .../gm/doc/GameMonkeyGarbageCollection.pdf | Bin 0 -> 115133 bytes .../languages/gm/doc/GameMonkeyLicense.pdf | Bin 0 -> 77591 bytes .../gm/doc/GameMonkeyScriptReference.pdf | Bin 0 -> 221424 bytes vscript/languages/gm/doc/ToDoList.txt | 27 + vscript/languages/gm/doc/gmdoc.html | 308 + vscript/languages/gm/scripts/Bomber.gm | 1689 ++++ vscript/languages/gm/scripts/BomberRun.gm | 691 ++ .../gm/scripts/ScriptDescriptions.txt | 33 + vscript/languages/gm/scripts/benchmarks.gm | 230 + vscript/languages/gm/scripts/gmDoc/gmdoc.cmd | 9 + vscript/languages/gm/scripts/gmDoc/gmdoc.gm | 333 + vscript/languages/gm/scripts/gmDoc/gmdoc.html | 308 + vscript/languages/gm/scripts/gmDoc/gmdoc.txt | 2 + vscript/languages/gm/scripts/gmDoc/gmdoc.xml | 1 + vscript/languages/gm/scripts/minesweeper.gm | 608 ++ vscript/languages/gm/scripts/snake.gm | 696 ++ vscript/languages/gm/src/binds/gmArrayLib.cpp | 413 + vscript/languages/gm/src/binds/gmArrayLib.h | 95 + vscript/languages/gm/src/binds/gmCall.cpp | 17 + vscript/languages/gm/src/binds/gmCall.h | 434 + vscript/languages/gm/src/binds/gmGCRoot.cpp | 215 + vscript/languages/gm/src/binds/gmGCRoot.h | 399 + .../languages/gm/src/binds/gmGCRootUtil.cpp | 33 + vscript/languages/gm/src/binds/gmGCRootUtil.h | 171 + vscript/languages/gm/src/binds/gmHelpers.cpp | 64 + vscript/languages/gm/src/binds/gmHelpers.h | 179 + vscript/languages/gm/src/binds/gmMathLib.cpp | 860 ++ vscript/languages/gm/src/binds/gmMathLib.h | 21 + .../languages/gm/src/binds/gmStringLib.cpp | 1174 +++ vscript/languages/gm/src/binds/gmStringLib.h | 21 + .../languages/gm/src/binds/gmSystemLib.cpp | 986 ++ vscript/languages/gm/src/binds/gmSystemLib.h | 28 + .../languages/gm/src/binds/gmVector3Lib.cpp | 1059 ++ vscript/languages/gm/src/binds/gmVector3Lib.h | 37 + .../gm/src/examples/GameObject/App.cpp | 473 + .../gm/src/examples/GameObject/App.h | 72 + .../gm/src/examples/GameObject/GameObj.cpp | 317 + .../gm/src/examples/GameObject/GameObj.h | 61 + .../gm/src/examples/GameObject/GameObject.dsp | 470 + .../gm/src/examples/GameObject/GameObject.dsw | 33 + .../src/examples/GameObject/GameObject.vcproj | 1383 +++ .../src/examples/GameObject/InputKBWin32.cpp | 102 + .../gm/src/examples/GameObject/InputKBWin32.h | 90 + .../gm/src/examples/GameObject/NetClient.cpp | 356 + .../gm/src/examples/GameObject/NetClient.h | 30 + .../gm/src/examples/GameObject/ReadMe.txt | 10 + .../gm/src/examples/GameObject/ScriptObj.cpp | 326 + .../gm/src/examples/GameObject/ScriptObj.h | 165 + .../gm/src/examples/GameObject/ScriptSys.cpp | 432 + .../gm/src/examples/GameObject/ScriptSys.h | 107 + .../gm/src/examples/GameObject/StdStuff.cpp | 5 + .../gm/src/examples/GameObject/StdStuff.h | 194 + .../gm/src/examples/GameObject/TestGameObj.gm | 44 + .../gm/src/examples/GameObject/main.cpp | 30 + .../gm/src/examples/Minimal/Minimal.dsp | 362 + .../gm/src/examples/Minimal/Minimal.dsw | 33 + .../gm/src/examples/Minimal/Minimal.vcproj | 1059 ++ .../gm/src/examples/Minimal/main.cpp | 78 + vscript/languages/gm/src/gm/bison.hairy | 334 + vscript/languages/gm/src/gm/bison.simple | 688 ++ vscript/languages/gm/src/gm/flex.skl | 1512 +++ vscript/languages/gm/src/gm/gmArraySimple.cpp | 18 + vscript/languages/gm/src/gm/gmArraySimple.h | 333 + vscript/languages/gm/src/gm/gmByteCode.cpp | 134 + vscript/languages/gm/src/gm/gmByteCode.h | 102 + vscript/languages/gm/src/gm/gmByteCodeGen.cpp | 158 + vscript/languages/gm/src/gm/gmByteCodeGen.h | 49 + vscript/languages/gm/src/gm/gmCodeGen.cpp | 1549 +++ vscript/languages/gm/src/gm/gmCodeGen.h | 49 + .../languages/gm/src/gm/gmCodeGenHooks.cpp | 17 + vscript/languages/gm/src/gm/gmCodeGenHooks.h | 101 + vscript/languages/gm/src/gm/gmCodeTree.cpp | 555 ++ vscript/languages/gm/src/gm/gmCodeTree.h | 254 + vscript/languages/gm/src/gm/gmConfig.h | 106 + vscript/languages/gm/src/gm/gmCrc.cpp | 84 + vscript/languages/gm/src/gm/gmCrc.h | 19 + vscript/languages/gm/src/gm/gmDebug.cpp | 741 ++ vscript/languages/gm/src/gm/gmDebug.h | 88 + vscript/languages/gm/src/gm/gmDebugger.cpp | 321 + vscript/languages/gm/src/gm/gmDebugger.h | 114 + .../languages/gm/src/gm/gmFunctionObject.cpp | 286 + .../languages/gm/src/gm/gmFunctionObject.h | 163 + vscript/languages/gm/src/gm/gmHash.cpp | 17 + vscript/languages/gm/src/gm/gmHash.h | 348 + vscript/languages/gm/src/gm/gmIncGC.cpp | 838 ++ vscript/languages/gm/src/gm/gmIncGC.h | 436 + vscript/languages/gm/src/gm/gmIterator.h | 51 + vscript/languages/gm/src/gm/gmLibHooks.cpp | 447 + vscript/languages/gm/src/gm/gmLibHooks.h | 124 + vscript/languages/gm/src/gm/gmListDouble.cpp | 16 + vscript/languages/gm/src/gm/gmListDouble.h | 377 + vscript/languages/gm/src/gm/gmLog.cpp | 120 + vscript/languages/gm/src/gm/gmLog.h | 61 + vscript/languages/gm/src/gm/gmMachine.cpp | 1953 ++++ vscript/languages/gm/src/gm/gmMachine.h | 692 ++ vscript/languages/gm/src/gm/gmMachineLib.cpp | 1223 +++ vscript/languages/gm/src/gm/gmMachineLib.h | 21 + vscript/languages/gm/src/gm/gmMem.cpp | 16 + vscript/languages/gm/src/gm/gmMem.h | 71 + vscript/languages/gm/src/gm/gmMemChain.cpp | 238 + vscript/languages/gm/src/gm/gmMemChain.h | 71 + vscript/languages/gm/src/gm/gmMemFixed.cpp | 17 + vscript/languages/gm/src/gm/gmMemFixed.h | 182 + vscript/languages/gm/src/gm/gmMemFixedSet.cpp | 140 + vscript/languages/gm/src/gm/gmMemFixedSet.h | 258 + vscript/languages/gm/src/gm/gmOperators.cpp | 603 ++ vscript/languages/gm/src/gm/gmOperators.h | 79 + vscript/languages/gm/src/gm/gmParser.cpp | 2021 ++++ vscript/languages/gm/src/gm/gmParser.cpp.h | 51 + vscript/languages/gm/src/gm/gmParser.y | 877 ++ vscript/languages/gm/src/gm/gmScanner.cpp | 2089 ++++ vscript/languages/gm/src/gm/gmScanner.h | 32 + vscript/languages/gm/src/gm/gmScanner.l | 137 + vscript/languages/gm/src/gm/gmStream.cpp | 14 + vscript/languages/gm/src/gm/gmStream.h | 143 + .../languages/gm/src/gm/gmStreamBuffer.cpp | 173 + vscript/languages/gm/src/gm/gmStreamBuffer.h | 76 + .../languages/gm/src/gm/gmStringObject.cpp | 26 + vscript/languages/gm/src/gm/gmStringObject.h | 48 + vscript/languages/gm/src/gm/gmTableObject.cpp | 434 + vscript/languages/gm/src/gm/gmTableObject.h | 143 + vscript/languages/gm/src/gm/gmThread.cpp | 1192 +++ vscript/languages/gm/src/gm/gmThread.h | 879 ++ vscript/languages/gm/src/gm/gmUserObject.cpp | 63 + vscript/languages/gm/src/gm/gmUserObject.h | 37 + vscript/languages/gm/src/gm/gmUtil.cpp | 55 + vscript/languages/gm/src/gm/gmUtil.h | 58 + vscript/languages/gm/src/gm/gmVariable.cpp | 127 + vscript/languages/gm/src/gm/gmVariable.h | 266 + vscript/languages/gm/src/gm/gmfrontend.bat | 16 + vscript/languages/gm/src/gmd/ChildView.cpp | 1076 ++ vscript/languages/gm/src/gmd/ChildView.h | 157 + .../languages/gm/src/gmd/GMLangSettings.cpp | 136 + vscript/languages/gm/src/gmd/GMLangSettings.h | 10 + .../languages/gm/src/gmd/LanguageSettings.cpp | 452 + .../languages/gm/src/gmd/LanguageSettings.h | 101 + vscript/languages/gm/src/gmd/MainFrm.cpp | 150 + vscript/languages/gm/src/gmd/MainFrm.h | 67 + vscript/languages/gm/src/gmd/NetServer.cpp | 388 + vscript/languages/gm/src/gmd/NetServer.h | 29 + vscript/languages/gm/src/gmd/Resource.h | 29 + .../languages/gm/src/gmd/ScintillaEdit.cpp | 1817 ++++ vscript/languages/gm/src/gmd/ScintillaEdit.h | 738 ++ vscript/languages/gm/src/gmd/StdAfx.cpp | 8 + vscript/languages/gm/src/gmd/StdAfx.h | 33 + vscript/languages/gm/src/gmd/gmd.cpp | 138 + vscript/languages/gm/src/gmd/gmd.dsp | 253 + vscript/languages/gm/src/gmd/gmd.dsw | 33 + vscript/languages/gm/src/gmd/gmd.h | 51 + vscript/languages/gm/src/gmd/gmd.vcproj | 563 ++ .../languages/gm/src/gmd/include/Accessor.h | 78 + vscript/languages/gm/src/gmd/include/Face.py | 107 + .../languages/gm/src/gmd/include/HFacer.py | 61 + .../languages/gm/src/gmd/include/KeyWords.h | 74 + .../languages/gm/src/gmd/include/Platform.h | 486 + .../languages/gm/src/gmd/include/PropSet.h | 83 + .../languages/gm/src/gmd/include/SString.h | 377 + .../languages/gm/src/gmd/include/SciLexer.h | 431 + .../languages/gm/src/gmd/include/Scintilla.h | 640 ++ .../gm/src/gmd/include/Scintilla.iface | 1946 ++++ .../gm/src/gmd/include/ScintillaWidget.h | 55 + .../gm/src/gmd/include/WindowAccessor.h | 57 + vscript/languages/gm/src/gmd/res/Toolbar.bmp | Bin 0 -> 1198 bytes vscript/languages/gm/src/gmd/res/bangbang.wav | Bin 0 -> 24120 bytes vscript/languages/gm/src/gmd/res/gmd.ico | Bin 0 -> 1078 bytes vscript/languages/gm/src/gmd/res/gmd.rc2 | 13 + vscript/languages/gm/src/gme/NetClient.cpp | 351 + vscript/languages/gm/src/gme/NetClient.h | 30 + vscript/languages/gm/src/gme/gme.cpp | 493 + vscript/languages/gm/src/gme/gme.dsp | 438 + vscript/languages/gm/src/gme/gme.dsw | 33 + vscript/languages/gm/src/gme/gme.vcproj | 1314 +++ vscript/languages/gm/src/gme/timer.cpp | 30 + vscript/languages/gm/src/gme/timer.h | 27 + vscript/languages/gm/src/gml/gml.dsp | 90 + vscript/languages/gm/src/gml/gml.dsw | 33 + vscript/languages/gm/src/gml/gml.vcproj | 226 + vscript/languages/gm/src/gml/main.cpp | 377 + .../gm/src/platform/ps2cw/gmConfig_p.h | 96 + .../gm/src/platform/win32gcc/gmConfig_p.h | 117 + .../gm/src/platform/win32msvc/gmConfig_p.h | 136 + vscript/languages/gm/vgm/vgm.cpp | 715 ++ vscript/languages/gm/vgm/vgm.h | 17 + vscript/languages/gm/vgm/vgm.vpc | 135 + vscript/languages/gm/vgm/vscript_templates.h | 246 + vscript/languages/lua/lua-5.1.4/COPYRIGHT | 34 + vscript/languages/lua/lua-5.1.4/HISTORY | 183 + vscript/languages/lua/lua-5.1.4/INSTALL | 99 + vscript/languages/lua/lua-5.1.4/Makefile | 128 + vscript/languages/lua/lua-5.1.4/README | 37 + .../languages/lua/lua-5.1.4/doc/amazon.gif | Bin 0 -> 797 bytes .../languages/lua/lua-5.1.4/doc/contents.html | 499 + vscript/languages/lua/lua-5.1.4/doc/cover.png | Bin 0 -> 3305 bytes vscript/languages/lua/lua-5.1.4/doc/logo.gif | Bin 0 -> 4232 bytes vscript/languages/lua/lua-5.1.4/doc/lua.1 | 163 + vscript/languages/lua/lua-5.1.4/doc/lua.css | 41 + vscript/languages/lua/lua-5.1.4/doc/lua.html | 172 + vscript/languages/lua/lua-5.1.4/doc/luac.1 | 136 + vscript/languages/lua/lua-5.1.4/doc/luac.html | 145 + .../languages/lua/lua-5.1.4/doc/manual.css | 13 + .../languages/lua/lua-5.1.4/doc/manual.html | 8801 +++++++++++++++++ .../languages/lua/lua-5.1.4/doc/readme.html | 40 + vscript/languages/lua/lua-5.1.4/etc/Makefile | 44 + vscript/languages/lua/lua-5.1.4/etc/README | 37 + vscript/languages/lua/lua-5.1.4/etc/all.c | 38 + vscript/languages/lua/lua-5.1.4/etc/lua.hpp | 9 + vscript/languages/lua/lua-5.1.4/etc/lua.ico | Bin 0 -> 1078 bytes vscript/languages/lua/lua-5.1.4/etc/lua.pc | 31 + vscript/languages/lua/lua-5.1.4/etc/luavs.bat | 28 + vscript/languages/lua/lua-5.1.4/etc/min.c | 39 + .../languages/lua/lua-5.1.4/etc/noparser.c | 50 + .../languages/lua/lua-5.1.4/etc/strict.lua | 41 + vscript/languages/lua/lua-5.1.4/src/Makefile | 182 + vscript/languages/lua/lua-5.1.4/src/lapi.c | 1087 ++ vscript/languages/lua/lua-5.1.4/src/lapi.h | 16 + vscript/languages/lua/lua-5.1.4/src/lauxlib.c | 652 ++ vscript/languages/lua/lua-5.1.4/src/lauxlib.h | 174 + .../languages/lua/lua-5.1.4/src/lbaselib.c | 653 ++ vscript/languages/lua/lua-5.1.4/src/lcode.c | 839 ++ vscript/languages/lua/lua-5.1.4/src/lcode.h | 76 + vscript/languages/lua/lua-5.1.4/src/ldblib.c | 397 + vscript/languages/lua/lua-5.1.4/src/ldebug.c | 638 ++ vscript/languages/lua/lua-5.1.4/src/ldebug.h | 33 + vscript/languages/lua/lua-5.1.4/src/ldo.c | 518 + vscript/languages/lua/lua-5.1.4/src/ldo.h | 57 + vscript/languages/lua/lua-5.1.4/src/ldump.c | 164 + vscript/languages/lua/lua-5.1.4/src/lfunc.c | 174 + vscript/languages/lua/lua-5.1.4/src/lfunc.h | 34 + vscript/languages/lua/lua-5.1.4/src/lgc.c | 711 ++ vscript/languages/lua/lua-5.1.4/src/lgc.h | 110 + vscript/languages/lua/lua-5.1.4/src/linit.c | 38 + vscript/languages/lua/lua-5.1.4/src/liolib.c | 553 ++ vscript/languages/lua/lua-5.1.4/src/llex.c | 461 + vscript/languages/lua/lua-5.1.4/src/llex.h | 81 + vscript/languages/lua/lua-5.1.4/src/llimits.h | 128 + .../languages/lua/lua-5.1.4/src/lmathlib.c | 263 + vscript/languages/lua/lua-5.1.4/src/lmem.c | 86 + vscript/languages/lua/lua-5.1.4/src/lmem.h | 49 + vscript/languages/lua/lua-5.1.4/src/loadlib.c | 666 ++ vscript/languages/lua/lua-5.1.4/src/lobject.c | 214 + vscript/languages/lua/lua-5.1.4/src/lobject.h | 384 + .../languages/lua/lua-5.1.4/src/lopcodes.c | 102 + .../languages/lua/lua-5.1.4/src/lopcodes.h | 268 + vscript/languages/lua/lua-5.1.4/src/loslib.c | 243 + vscript/languages/lua/lua-5.1.4/src/lparser.c | 1359 +++ vscript/languages/lua/lua-5.1.4/src/lparser.h | 82 + vscript/languages/lua/lua-5.1.4/src/lstate.c | 217 + vscript/languages/lua/lua-5.1.4/src/lstate.h | 169 + vscript/languages/lua/lua-5.1.4/src/lstring.c | 133 + vscript/languages/lua/lua-5.1.4/src/lstring.h | 31 + vscript/languages/lua/lua-5.1.4/src/lstrlib.c | 869 ++ vscript/languages/lua/lua-5.1.4/src/ltable.c | 654 ++ vscript/languages/lua/lua-5.1.4/src/ltable.h | 52 + vscript/languages/lua/lua-5.1.4/src/ltablib.c | 313 + vscript/languages/lua/lua-5.1.4/src/ltm.c | 75 + vscript/languages/lua/lua-5.1.4/src/ltm.h | 54 + vscript/languages/lua/lua-5.1.4/src/lua.c | 392 + vscript/languages/lua/lua-5.1.4/src/lua.h | 388 + vscript/languages/lua/lua-5.1.4/src/luac.c | 200 + vscript/languages/lua/lua-5.1.4/src/luaconf.h | 775 ++ vscript/languages/lua/lua-5.1.4/src/lualib.h | 53 + vscript/languages/lua/lua-5.1.4/src/lundump.c | 227 + vscript/languages/lua/lua-5.1.4/src/lundump.h | 36 + vscript/languages/lua/lua-5.1.4/src/lvm.c | 763 ++ vscript/languages/lua/lua-5.1.4/src/lvm.h | 36 + vscript/languages/lua/lua-5.1.4/src/lzio.c | 82 + vscript/languages/lua/lua-5.1.4/src/lzio.h | 67 + vscript/languages/lua/lua-5.1.4/src/print.c | 227 + vscript/languages/lua/lua-5.1.4/test/README | 26 + .../languages/lua/lua-5.1.4/test/bisect.lua | 27 + vscript/languages/lua/lua-5.1.4/test/cf.lua | 16 + vscript/languages/lua/lua-5.1.4/test/echo.lua | 5 + vscript/languages/lua/lua-5.1.4/test/env.lua | 7 + .../lua/lua-5.1.4/test/factorial.lua | 32 + vscript/languages/lua/lua-5.1.4/test/fib.lua | 40 + .../languages/lua/lua-5.1.4/test/fibfor.lua | 13 + .../languages/lua/lua-5.1.4/test/globals.lua | 13 + .../languages/lua/lua-5.1.4/test/hello.lua | 3 + vscript/languages/lua/lua-5.1.4/test/life.lua | 111 + vscript/languages/lua/lua-5.1.4/test/luac.lua | 7 + .../languages/lua/lua-5.1.4/test/printf.lua | 7 + .../languages/lua/lua-5.1.4/test/readonly.lua | 12 + .../languages/lua/lua-5.1.4/test/sieve.lua | 29 + vscript/languages/lua/lua-5.1.4/test/sort.lua | 66 + .../languages/lua/lua-5.1.4/test/table.lua | 12 + .../lua/lua-5.1.4/test/trace-calls.lua | 32 + .../lua/lua-5.1.4/test/trace-globals.lua | 38 + vscript/languages/lua/lua-5.1.4/test/xd.lua | 14 + vscript/languages/lua/vlua/vec3.cpp | 284 + vscript/languages/lua/vlua/vec3.h | 19 + vscript/languages/lua/vlua/vlua.cpp | 1502 +++ vscript/languages/lua/vlua/vlua.h | 17 + vscript/languages/lua/vlua/vlua.vpc | 122 + .../python/python-2.5.1/include/abstract.h | 1276 +++ .../python/python-2.5.1/include/asdl.h | 45 + .../python/python-2.5.1/include/ast.h | 13 + .../python/python-2.5.1/include/bitset.h | 32 + .../python/python-2.5.1/include/boolobject.h | 36 + .../python-2.5.1/include/bufferobject.h | 33 + .../python/python-2.5.1/include/cellobject.h | 28 + .../python/python-2.5.1/include/ceval.h | 157 + .../python/python-2.5.1/include/classobject.h | 81 + .../python/python-2.5.1/include/cobject.h | 54 + .../python/python-2.5.1/include/code.h | 94 + .../python/python-2.5.1/include/codecs.h | 167 + .../python/python-2.5.1/include/compile.h | 39 + .../python-2.5.1/include/complexobject.h | 58 + .../python/python-2.5.1/include/cstringio.h | 70 + .../python/python-2.5.1/include/datetime.h | 245 + .../python/python-2.5.1/include/descrobject.h | 91 + .../python/python-2.5.1/include/dictobject.h | 141 + .../python/python-2.5.1/include/enumobject.h | 17 + .../python/python-2.5.1/include/errcode.h | 36 + .../python/python-2.5.1/include/eval.h | 25 + .../python/python-2.5.1/include/fileobject.h | 63 + .../python/python-2.5.1/include/floatobject.h | 100 + .../python/python-2.5.1/include/frameobject.h | 81 + .../python/python-2.5.1/include/funcobject.h | 76 + .../python/python-2.5.1/include/genobject.h | 37 + .../python/python-2.5.1/include/graminit.h | 84 + .../python/python-2.5.1/include/grammar.h | 93 + .../python/python-2.5.1/include/import.h | 64 + .../python/python-2.5.1/include/intobject.h | 64 + .../python/python-2.5.1/include/intrcheck.h | 15 + .../python/python-2.5.1/include/iterobject.h | 23 + .../python/python-2.5.1/include/listobject.h | 67 + .../python/python-2.5.1/include/longintrepr.h | 63 + .../python/python-2.5.1/include/longobject.h | 114 + .../python/python-2.5.1/include/marshal.h | 25 + .../python/python-2.5.1/include/metagrammar.h | 18 + .../python-2.5.1/include/methodobject.h | 91 + .../python/python-2.5.1/include/modsupport.h | 133 + .../python-2.5.1/include/moduleobject.h | 24 + .../python/python-2.5.1/include/node.h | 40 + .../python/python-2.5.1/include/object.h | 868 ++ .../python/python-2.5.1/include/objimpl.h | 336 + .../python/python-2.5.1/include/opcode.h | 152 + .../python/python-2.5.1/include/osdefs.h | 55 + .../python/python-2.5.1/include/parsetok.h | 50 + .../python/python-2.5.1/include/patchlevel.h | 40 + .../python/python-2.5.1/include/pgen.h | 18 + .../python/python-2.5.1/include/pgenheaders.h | 42 + .../python/python-2.5.1/include/py_curses.h | 176 + .../python/python-2.5.1/include/pyarena.h | 62 + .../python/python-2.5.1/include/pyconfig.h | 688 ++ .../python/python-2.5.1/include/pydebug.h | 34 + .../python/python-2.5.1/include/pyerrors.h | 334 + .../python/python-2.5.1/include/pyexpat.h | 47 + .../python/python-2.5.1/include/pyfpe.h | 176 + .../python/python-2.5.1/include/pygetopt.h | 17 + .../python-2.5.1/include/pymactoolbox.h | 189 + .../python/python-2.5.1/include/pymem.h | 105 + .../python/python-2.5.1/include/pyport.h | 771 ++ .../python/python-2.5.1/include/pystate.h | 195 + .../python/python-2.5.1/include/pystrtod.h | 18 + .../python/python-2.5.1/include/python-ast.h | 501 + .../python/python-2.5.1/include/python.h | 173 + .../python/python-2.5.1/include/pythonrun.h | 171 + .../python/python-2.5.1/include/pythread.h | 47 + .../python/python-2.5.1/include/rangeobject.h | 28 + .../python/python-2.5.1/include/setobject.h | 93 + .../python/python-2.5.1/include/sliceobject.h | 43 + .../python-2.5.1/include/stringobject.h | 183 + .../python-2.5.1/include/structmember.h | 93 + .../python/python-2.5.1/include/structseq.h | 41 + .../python/python-2.5.1/include/symtable.h | 103 + .../python/python-2.5.1/include/sysmodule.h | 30 + .../python/python-2.5.1/include/timefuncs.h | 23 + .../python/python-2.5.1/include/token.h | 83 + .../python/python-2.5.1/include/traceback.h | 30 + .../python/python-2.5.1/include/tupleobject.h | 57 + .../python/python-2.5.1/include/ucnhash.h | 31 + .../python-2.5.1/include/unicodeobject.h | 1265 +++ .../python-2.5.1/include/weakrefobject.h | 75 + .../python-2.5.1/win32release/python.exe | Bin 0 -> 26624 bytes .../python-2.5.1/win32release/python25.lib | Bin 0 -> 199302 bytes .../python-2.5.1/win32release/python25v.lib | Bin 0 -> 200198 bytes .../python-2.5.1/win32release/python25v.zip | Bin 0 -> 4546978 bytes .../python-2.5.1/win32release/pythonw.exe | Bin 0 -> 27136 bytes vscript/languages/python/readme.txt | 32 + vscript/languages/python/vpython/init.py | 25 + vscript/languages/python/vpython/vpython.cpp | 4968 ++++++++++ vscript/languages/python/vpython/vpython.h | 17 + vscript/languages/python/vpython/vpython.vpc | 51 + vscript/languages/squirrel/COMPILE | 41 + vscript/languages/squirrel/COPYRIGHT | 29 + .../squirrel/DXSquirrel/DXSquirrel.cbp | 253 + .../squirrel/DXSquirrel/DXSquirrel.cpp | 41 + .../squirrel/DXSquirrel/DXSquirrel.h | 3 + .../squirrel/DXSquirrel/DXSquirrel.ico | Bin 0 -> 23558 bytes .../squirrel/DXSquirrel/DXSquirrel.vcproj | 452 + .../squirrel/DXSquirrel/DXSquirrel71.vcproj | 302 + .../squirrel/DXSquirrel/DXSquirrel_Binds.cpp | 35 + .../squirrel/DXSquirrel/DXSquirrel_Binds.h | 11 + .../squirrel/DXSquirrel/DXSquirrel_DX.cpp | 230 + .../squirrel/DXSquirrel/DXSquirrel_Device.cpp | 151 + .../squirrel/DXSquirrel/DXSquirrel_Math.cpp | 532 + .../squirrel/DXSquirrel/DXSquirrel_Mesh.cpp | 37 + .../languages/squirrel/DXSquirrel/ReadMe.txt | 53 + .../languages/squirrel/DXSquirrel/Resource.h | 29 + .../squirrel/DXSquirrel/dxsquirrel.nut | 44 + .../languages/squirrel/DXSquirrel/small.ico | Bin 0 -> 23558 bytes .../languages/squirrel/DXSquirrel/stdafx.cpp | 8 + .../languages/squirrel/DXSquirrel/stdafx.h | 20 + vscript/languages/squirrel/HISTORY | 341 + vscript/languages/squirrel/Makefile | 18 + vscript/languages/squirrel/README | 22 + vscript/languages/squirrel/README_SQPLUS.txt | 16 + vscript/languages/squirrel/Solution Items | 14 + vscript/languages/squirrel/doc/sqdbg.chm | Bin 0 -> 19006 bytes vscript/languages/squirrel/doc/sqdbg.pdf | 494 + vscript/languages/squirrel/doc/sqstdlib2.chm | Bin 0 -> 36875 bytes vscript/languages/squirrel/doc/sqstdlib2.pdf | 1714 ++++ vscript/languages/squirrel/doc/squirrel2.chm | Bin 0 -> 132589 bytes vscript/languages/squirrel/doc/squirrel2.pdf | 6409 ++++++++++++ vscript/languages/squirrel/etc/minimal.c | 63 + vscript/languages/squirrel/etc/test.nut | 4 + .../languages/squirrel/include/sqdbgserver.h | 170 + vscript/languages/squirrel/include/sqrdbg.h | 52 + vscript/languages/squirrel/include/sqstdaux.h | 16 + .../languages/squirrel/include/sqstdblob.h | 20 + vscript/languages/squirrel/include/sqstdio.h | 54 + .../languages/squirrel/include/sqstdmath.h | 15 + .../languages/squirrel/include/sqstdstring.h | 33 + .../languages/squirrel/include/sqstdsystem.h | 15 + vscript/languages/squirrel/include/squirrel.h | 469 + .../languages/squirrel/minimalSqPlus/Makefile | 18 + .../squirrel/minimalSqPlus/minimalSqPlus.cbp | 118 + .../squirrel/minimalSqPlus/minimalSqPlus.cpp | 162 + .../minimalSqPlus/minimalSqPlus.vcproj | 347 + .../minimalSqPlus/minimalSqPlus71.vcproj | 221 + vscript/languages/squirrel/readme_valve.txt | 1 + .../languages/squirrel/samples/ackermann.nut | 23 + vscript/languages/squirrel/samples/array.nut | 29 + vscript/languages/squirrel/samples/class.nut | 49 + .../squirrel/samples/classattributes.nut | 35 + .../languages/squirrel/samples/coroutines.nut | 25 + .../languages/squirrel/samples/delegation.nut | 52 + .../languages/squirrel/samples/fibonacci.nut | 15 + vscript/languages/squirrel/samples/flow.nut | 33 + .../languages/squirrel/samples/generators.nut | 42 + vscript/languages/squirrel/samples/hello.nut | 1 + vscript/languages/squirrel/samples/list.nut | 40 + vscript/languages/squirrel/samples/loops.nut | 32 + vscript/languages/squirrel/samples/matrix.nut | 44 + .../squirrel/samples/metamethods.nut | 115 + .../languages/squirrel/samples/methcall.nut | 61 + .../languages/squirrel/samples/tailstate.nut | 24 + vscript/languages/squirrel/sq/Makefile | 21 + vscript/languages/squirrel/sq/sq.c | 324 + vscript/languages/squirrel/sq/sq.cbp | 129 + vscript/languages/squirrel/sq/sq.vcproj | 458 + vscript/languages/squirrel/sq/sq71.vcproj | 317 + .../languages/squirrel/sqdbg/doc/sqdbg.chm | Bin 0 -> 19006 bytes .../languages/squirrel/sqdbg/doc/sqdbg.pdf | 494 + vscript/languages/squirrel/sqdbg/main.cpp | 95 + vscript/languages/squirrel/sqdbg/makebin.pl | 13 + vscript/languages/squirrel/sqdbg/ps3socket.h | 9 + .../squirrel/sqdbg/serialize_state.inl | 266 + .../squirrel/sqdbg/serialize_state.nut | 277 + vscript/languages/squirrel/sqdbg/sqdbg.cbp | 162 + vscript/languages/squirrel/sqdbg/sqdbg.chm | Bin 0 -> 19006 bytes vscript/languages/squirrel/sqdbg/sqdbg.pdf | 494 + vscript/languages/squirrel/sqdbg/sqdbg.vcproj | 381 + .../languages/squirrel/sqdbg/sqdbg71.vcproj | 251 + .../squirrel/sqdbg/sqdbgWithUnicode.vcproj | 254 + .../squirrel/sqdbg/sqdbgWithUnicode71.vcproj | 254 + .../languages/squirrel/sqdbg/sqdbgserver.cpp | 694 ++ vscript/languages/squirrel/sqdbg/sqrdbg.cpp | 186 + vscript/languages/squirrel/sqdbg/test.nut | 50 + .../squirrel/sqdbg/testscripts/test.nut | 15 + .../sqdbg/testscripts/utils/commons.nut | 33 + .../languages/squirrel/sqdbglib/ReadMe.txt | 21 + .../languages/squirrel/sqdbglib/sqdbglib.cbp | 106 + .../squirrel/sqdbglib/sqdbglib.vcproj | 304 + .../squirrel/sqdbglib/sqdbglib71.vcproj | 203 + vscript/languages/squirrel/sqplus/Makefile | 18 + vscript/languages/squirrel/sqplus/SqPlus.cpp | 298 + .../languages/squirrel/sqplus/SqPlusConst.h | 334 + .../squirrel/sqplus/SquirrelBindingsUtils.cpp | 122 + .../squirrel/sqplus/SquirrelBindingsUtils.h | 151 + .../sqplus/SquirrelBindingsUtilsWin32.cpp | 34 + .../sqplus/SquirrelBindingsUtilsWin32.h | 43 + .../squirrel/sqplus/SquirrelObject.cpp | 640 ++ .../squirrel/sqplus/SquirrelObject.h | 248 + .../squirrel/sqplus/SquirrelObjectImpl.h | 36 + .../languages/squirrel/sqplus/SquirrelVM.cpp | 346 + .../languages/squirrel/sqplus/SquirrelVM.h | 112 + vscript/languages/squirrel/sqplus/sqplus.cbp | 190 + vscript/languages/squirrel/sqplus/sqplus.h | 2028 ++++ .../languages/squirrel/sqplus/sqplus.vcproj | 339 + .../languages/squirrel/sqplus/sqplus71.vcproj | 229 + .../languages/squirrel/sqplus/sqplusWin32.h | 7 + vscript/languages/squirrel/sqstdlib/Makefile | 30 + .../languages/squirrel/sqstdlib/sqstdaux.cpp | 133 + .../languages/squirrel/sqstdlib/sqstdblob.cpp | 254 + .../squirrel/sqstdlib/sqstdblobimpl.h | 108 + .../languages/squirrel/sqstdlib/sqstdio.cpp | 410 + .../languages/squirrel/sqstdlib/sqstdlib.cbp | 166 + .../squirrel/sqstdlib/sqstdlib.vcproj | 666 ++ .../squirrel/sqstdlib/sqstdlib71.vcproj | 503 + .../languages/squirrel/sqstdlib/sqstdmath.cpp | 106 + .../languages/squirrel/sqstdlib/sqstdrex.cpp | 640 ++ .../squirrel/sqstdlib/sqstdstream.cpp | 333 + .../languages/squirrel/sqstdlib/sqstdstream.h | 18 + .../squirrel/sqstdlib/sqstdstring.cpp | 372 + .../squirrel/sqstdlib/sqstdsystem.cpp | 147 + vscript/languages/squirrel/squirrel.workspace | 16 + vscript/languages/squirrel/squirrel/Makefile | 52 + vscript/languages/squirrel/squirrel/sqapi.cpp | 1274 +++ vscript/languages/squirrel/squirrel/sqarray.h | 98 + .../languages/squirrel/squirrel/sqbaselib.cpp | 917 ++ .../languages/squirrel/squirrel/sqclass.cpp | 198 + vscript/languages/squirrel/squirrel/sqclass.h | 165 + .../languages/squirrel/squirrel/sqclosure.h | 139 + .../squirrel/squirrel/sqcompiler.cpp | 1358 +++ .../languages/squirrel/squirrel/sqcompiler.h | 77 + .../languages/squirrel/squirrel/sqdebug.cpp | 119 + .../languages/squirrel/squirrel/sqfuncproto.h | 169 + .../squirrel/squirrel/sqfuncstate.cpp | 571 ++ .../languages/squirrel/squirrel/sqfuncstate.h | 85 + .../languages/squirrel/squirrel/sqlexer.cpp | 479 + vscript/languages/squirrel/squirrel/sqlexer.h | 45 + vscript/languages/squirrel/squirrel/sqmem.cpp | 11 + .../languages/squirrel/squirrel/sqobject.cpp | 712 ++ .../languages/squirrel/squirrel/sqobject.h | 384 + .../languages/squirrel/squirrel/sqopcodes.h | 115 + .../languages/squirrel/squirrel/sqpcheader.h | 19 + .../languages/squirrel/squirrel/sqstate.cpp | 725 ++ vscript/languages/squirrel/squirrel/sqstate.h | 172 + .../languages/squirrel/squirrel/sqstring.h | 31 + .../languages/squirrel/squirrel/sqtable.cpp | 201 + vscript/languages/squirrel/squirrel/sqtable.h | 102 + .../languages/squirrel/squirrel/squirrel.cbp | 324 + .../squirrel/squirrel/squirrel.vcproj | 971 ++ .../squirrel/squirrel/squirrel71.vcproj | 750 ++ .../squirrel/squirrel/squirrellib.cbp | 20 + .../languages/squirrel/squirrel/squserdata.h | 47 + vscript/languages/squirrel/squirrel/squtils.h | 122 + vscript/languages/squirrel/squirrel/sqvm.cpp | 1572 +++ vscript/languages/squirrel/squirrel/sqvm.h | 223 + .../languages/squirrel/testSqPlus/Makefile | 16 + .../squirrel/testSqPlus/testSqPlus.cbp | 126 + .../squirrel/testSqPlus/testSqPlus.cpp | 804 ++ .../squirrel/testSqPlus/testSqPlus.vcproj | 352 + .../squirrel/testSqPlus/testSqPlus71.vcproj | 225 + .../languages/squirrel/testSqPlus2/Makefile | 16 + .../squirrel/testSqPlus2/testSqPlus2.cbp | 138 + .../squirrel/testSqPlus2/testSqPlus2.cpp | 1250 +++ .../squirrel/testSqPlus2/testSqPlus2.vcproj | 351 + .../squirrel/testSqPlus2/testSqPlus271.vcproj | 224 + vscript/languages/squirrel/vsquirrel/init.nut | 655 ++ .../languages/squirrel/vsquirrel/init_nut.h | 688 ++ vscript/languages/squirrel/vsquirrel/test.nut | 44 + .../squirrel/vsquirrel/vsquirrel.cpp | 3548 +++++++ .../languages/squirrel/vsquirrel/vsquirrel.h | 17 + .../squirrel/vsquirrel/vsquirrel.vpc | 180 + vscript/vscript.cpp | 110 + vscript/vscript.vpc | 485 + vscript/vscript_sob.vpc | 460 + vscript/vsi.nul | 2 + vscript/xbox/xbox.def | 3 + wscript | 6 +- 617 files changed, 161164 insertions(+), 220 deletions(-) create mode 100644 header-list.txt create mode 100644 public/appframework/iappsystem.h create mode 100644 public/bittools.h create mode 100644 public/branchingsingleton.h create mode 100644 public/closedcaptions.cpp create mode 100644 public/closedcaptions.h create mode 100644 public/color.h create mode 100644 public/datacache/iprecachesystem.h create mode 100644 public/ispsharedmemory.h create mode 100644 public/networkvar_vector.h create mode 100644 public/tier0/logging.h create mode 100644 public/tier0/win32consoleio.h create mode 100644 public/tier2/resourceprecacher.h create mode 100644 public/tier2/tier2_logging.h create mode 100644 public/vscript/ivscript.h create mode 100644 public/vscript/vscript_templates.h create mode 100644 tier2/tier2_logging.cpp create mode 100644 vscript/CMakeLists.txt create mode 100644 vscript/_vpc_/manifest_vscript/linux64/manifest.txt create mode 100644 vscript/languages/gm/EditorHighlighters/ConTEXT/Highlighters/GameMonkey.chl create mode 100644 vscript/languages/gm/EditorHighlighters/Crimson Editor/Link/extension.gm create mode 100644 vscript/languages/gm/EditorHighlighters/Crimson Editor/Spec/gm.key create mode 100644 vscript/languages/gm/EditorHighlighters/Crimson Editor/Spec/gm.spc create mode 100644 vscript/languages/gm/EditorHighlighters/PSPad editor/Syntax/GameMonkey Script.INI create mode 100644 vscript/languages/gm/bin/StripCR.exe create mode 100644 vscript/languages/gm/bin/bison.exe create mode 100644 vscript/languages/gm/bin/flex.exe create mode 100644 vscript/languages/gm/bin/gmd.exe create mode 100644 vscript/languages/gm/bin/gme.exe create mode 100644 vscript/languages/gm/bin/gml.exe create mode 100644 vscript/languages/gm/doc/ChangeLog.txt create mode 100644 vscript/languages/gm/doc/GameMonkeyFAQ.pdf create mode 100644 vscript/languages/gm/doc/GameMonkeyGarbageCollection.pdf create mode 100644 vscript/languages/gm/doc/GameMonkeyLicense.pdf create mode 100644 vscript/languages/gm/doc/GameMonkeyScriptReference.pdf create mode 100644 vscript/languages/gm/doc/ToDoList.txt create mode 100644 vscript/languages/gm/doc/gmdoc.html create mode 100644 vscript/languages/gm/scripts/Bomber.gm create mode 100644 vscript/languages/gm/scripts/BomberRun.gm create mode 100644 vscript/languages/gm/scripts/ScriptDescriptions.txt create mode 100644 vscript/languages/gm/scripts/benchmarks.gm create mode 100644 vscript/languages/gm/scripts/gmDoc/gmdoc.cmd create mode 100644 vscript/languages/gm/scripts/gmDoc/gmdoc.gm create mode 100644 vscript/languages/gm/scripts/gmDoc/gmdoc.html create mode 100644 vscript/languages/gm/scripts/gmDoc/gmdoc.txt create mode 100644 vscript/languages/gm/scripts/gmDoc/gmdoc.xml create mode 100644 vscript/languages/gm/scripts/minesweeper.gm create mode 100644 vscript/languages/gm/scripts/snake.gm create mode 100644 vscript/languages/gm/src/binds/gmArrayLib.cpp create mode 100644 vscript/languages/gm/src/binds/gmArrayLib.h create mode 100644 vscript/languages/gm/src/binds/gmCall.cpp create mode 100644 vscript/languages/gm/src/binds/gmCall.h create mode 100644 vscript/languages/gm/src/binds/gmGCRoot.cpp create mode 100644 vscript/languages/gm/src/binds/gmGCRoot.h create mode 100644 vscript/languages/gm/src/binds/gmGCRootUtil.cpp create mode 100644 vscript/languages/gm/src/binds/gmGCRootUtil.h create mode 100644 vscript/languages/gm/src/binds/gmHelpers.cpp create mode 100644 vscript/languages/gm/src/binds/gmHelpers.h create mode 100644 vscript/languages/gm/src/binds/gmMathLib.cpp create mode 100644 vscript/languages/gm/src/binds/gmMathLib.h create mode 100644 vscript/languages/gm/src/binds/gmStringLib.cpp create mode 100644 vscript/languages/gm/src/binds/gmStringLib.h create mode 100644 vscript/languages/gm/src/binds/gmSystemLib.cpp create mode 100644 vscript/languages/gm/src/binds/gmSystemLib.h create mode 100644 vscript/languages/gm/src/binds/gmVector3Lib.cpp create mode 100644 vscript/languages/gm/src/binds/gmVector3Lib.h create mode 100644 vscript/languages/gm/src/examples/GameObject/App.cpp create mode 100644 vscript/languages/gm/src/examples/GameObject/App.h create mode 100644 vscript/languages/gm/src/examples/GameObject/GameObj.cpp create mode 100644 vscript/languages/gm/src/examples/GameObject/GameObj.h create mode 100644 vscript/languages/gm/src/examples/GameObject/GameObject.dsp create mode 100644 vscript/languages/gm/src/examples/GameObject/GameObject.dsw create mode 100644 vscript/languages/gm/src/examples/GameObject/GameObject.vcproj create mode 100644 vscript/languages/gm/src/examples/GameObject/InputKBWin32.cpp create mode 100644 vscript/languages/gm/src/examples/GameObject/InputKBWin32.h create mode 100644 vscript/languages/gm/src/examples/GameObject/NetClient.cpp create mode 100644 vscript/languages/gm/src/examples/GameObject/NetClient.h create mode 100644 vscript/languages/gm/src/examples/GameObject/ReadMe.txt create mode 100644 vscript/languages/gm/src/examples/GameObject/ScriptObj.cpp create mode 100644 vscript/languages/gm/src/examples/GameObject/ScriptObj.h create mode 100644 vscript/languages/gm/src/examples/GameObject/ScriptSys.cpp create mode 100644 vscript/languages/gm/src/examples/GameObject/ScriptSys.h create mode 100644 vscript/languages/gm/src/examples/GameObject/StdStuff.cpp create mode 100644 vscript/languages/gm/src/examples/GameObject/StdStuff.h create mode 100644 vscript/languages/gm/src/examples/GameObject/TestGameObj.gm create mode 100644 vscript/languages/gm/src/examples/GameObject/main.cpp create mode 100644 vscript/languages/gm/src/examples/Minimal/Minimal.dsp create mode 100644 vscript/languages/gm/src/examples/Minimal/Minimal.dsw create mode 100644 vscript/languages/gm/src/examples/Minimal/Minimal.vcproj create mode 100644 vscript/languages/gm/src/examples/Minimal/main.cpp create mode 100644 vscript/languages/gm/src/gm/bison.hairy create mode 100644 vscript/languages/gm/src/gm/bison.simple create mode 100644 vscript/languages/gm/src/gm/flex.skl create mode 100644 vscript/languages/gm/src/gm/gmArraySimple.cpp create mode 100644 vscript/languages/gm/src/gm/gmArraySimple.h create mode 100644 vscript/languages/gm/src/gm/gmByteCode.cpp create mode 100644 vscript/languages/gm/src/gm/gmByteCode.h create mode 100644 vscript/languages/gm/src/gm/gmByteCodeGen.cpp create mode 100644 vscript/languages/gm/src/gm/gmByteCodeGen.h create mode 100644 vscript/languages/gm/src/gm/gmCodeGen.cpp create mode 100644 vscript/languages/gm/src/gm/gmCodeGen.h create mode 100644 vscript/languages/gm/src/gm/gmCodeGenHooks.cpp create mode 100644 vscript/languages/gm/src/gm/gmCodeGenHooks.h create mode 100644 vscript/languages/gm/src/gm/gmCodeTree.cpp create mode 100644 vscript/languages/gm/src/gm/gmCodeTree.h create mode 100644 vscript/languages/gm/src/gm/gmConfig.h create mode 100644 vscript/languages/gm/src/gm/gmCrc.cpp create mode 100644 vscript/languages/gm/src/gm/gmCrc.h create mode 100644 vscript/languages/gm/src/gm/gmDebug.cpp create mode 100644 vscript/languages/gm/src/gm/gmDebug.h create mode 100644 vscript/languages/gm/src/gm/gmDebugger.cpp create mode 100644 vscript/languages/gm/src/gm/gmDebugger.h create mode 100644 vscript/languages/gm/src/gm/gmFunctionObject.cpp create mode 100644 vscript/languages/gm/src/gm/gmFunctionObject.h create mode 100644 vscript/languages/gm/src/gm/gmHash.cpp create mode 100644 vscript/languages/gm/src/gm/gmHash.h create mode 100644 vscript/languages/gm/src/gm/gmIncGC.cpp create mode 100644 vscript/languages/gm/src/gm/gmIncGC.h create mode 100644 vscript/languages/gm/src/gm/gmIterator.h create mode 100644 vscript/languages/gm/src/gm/gmLibHooks.cpp create mode 100644 vscript/languages/gm/src/gm/gmLibHooks.h create mode 100644 vscript/languages/gm/src/gm/gmListDouble.cpp create mode 100644 vscript/languages/gm/src/gm/gmListDouble.h create mode 100644 vscript/languages/gm/src/gm/gmLog.cpp create mode 100644 vscript/languages/gm/src/gm/gmLog.h create mode 100644 vscript/languages/gm/src/gm/gmMachine.cpp create mode 100644 vscript/languages/gm/src/gm/gmMachine.h create mode 100644 vscript/languages/gm/src/gm/gmMachineLib.cpp create mode 100644 vscript/languages/gm/src/gm/gmMachineLib.h create mode 100644 vscript/languages/gm/src/gm/gmMem.cpp create mode 100644 vscript/languages/gm/src/gm/gmMem.h create mode 100644 vscript/languages/gm/src/gm/gmMemChain.cpp create mode 100644 vscript/languages/gm/src/gm/gmMemChain.h create mode 100644 vscript/languages/gm/src/gm/gmMemFixed.cpp create mode 100644 vscript/languages/gm/src/gm/gmMemFixed.h create mode 100644 vscript/languages/gm/src/gm/gmMemFixedSet.cpp create mode 100644 vscript/languages/gm/src/gm/gmMemFixedSet.h create mode 100644 vscript/languages/gm/src/gm/gmOperators.cpp create mode 100644 vscript/languages/gm/src/gm/gmOperators.h create mode 100644 vscript/languages/gm/src/gm/gmParser.cpp create mode 100644 vscript/languages/gm/src/gm/gmParser.cpp.h create mode 100644 vscript/languages/gm/src/gm/gmParser.y create mode 100644 vscript/languages/gm/src/gm/gmScanner.cpp create mode 100644 vscript/languages/gm/src/gm/gmScanner.h create mode 100644 vscript/languages/gm/src/gm/gmScanner.l create mode 100644 vscript/languages/gm/src/gm/gmStream.cpp create mode 100644 vscript/languages/gm/src/gm/gmStream.h create mode 100644 vscript/languages/gm/src/gm/gmStreamBuffer.cpp create mode 100644 vscript/languages/gm/src/gm/gmStreamBuffer.h create mode 100644 vscript/languages/gm/src/gm/gmStringObject.cpp create mode 100644 vscript/languages/gm/src/gm/gmStringObject.h create mode 100644 vscript/languages/gm/src/gm/gmTableObject.cpp create mode 100644 vscript/languages/gm/src/gm/gmTableObject.h create mode 100644 vscript/languages/gm/src/gm/gmThread.cpp create mode 100644 vscript/languages/gm/src/gm/gmThread.h create mode 100644 vscript/languages/gm/src/gm/gmUserObject.cpp create mode 100644 vscript/languages/gm/src/gm/gmUserObject.h create mode 100644 vscript/languages/gm/src/gm/gmUtil.cpp create mode 100644 vscript/languages/gm/src/gm/gmUtil.h create mode 100644 vscript/languages/gm/src/gm/gmVariable.cpp create mode 100644 vscript/languages/gm/src/gm/gmVariable.h create mode 100644 vscript/languages/gm/src/gm/gmfrontend.bat create mode 100644 vscript/languages/gm/src/gmd/ChildView.cpp create mode 100644 vscript/languages/gm/src/gmd/ChildView.h create mode 100644 vscript/languages/gm/src/gmd/GMLangSettings.cpp create mode 100644 vscript/languages/gm/src/gmd/GMLangSettings.h create mode 100644 vscript/languages/gm/src/gmd/LanguageSettings.cpp create mode 100644 vscript/languages/gm/src/gmd/LanguageSettings.h create mode 100644 vscript/languages/gm/src/gmd/MainFrm.cpp create mode 100644 vscript/languages/gm/src/gmd/MainFrm.h create mode 100644 vscript/languages/gm/src/gmd/NetServer.cpp create mode 100644 vscript/languages/gm/src/gmd/NetServer.h create mode 100644 vscript/languages/gm/src/gmd/Resource.h create mode 100644 vscript/languages/gm/src/gmd/ScintillaEdit.cpp create mode 100644 vscript/languages/gm/src/gmd/ScintillaEdit.h create mode 100644 vscript/languages/gm/src/gmd/StdAfx.cpp create mode 100644 vscript/languages/gm/src/gmd/StdAfx.h create mode 100644 vscript/languages/gm/src/gmd/gmd.cpp create mode 100644 vscript/languages/gm/src/gmd/gmd.dsp create mode 100644 vscript/languages/gm/src/gmd/gmd.dsw create mode 100644 vscript/languages/gm/src/gmd/gmd.h create mode 100644 vscript/languages/gm/src/gmd/gmd.vcproj create mode 100644 vscript/languages/gm/src/gmd/include/Accessor.h create mode 100644 vscript/languages/gm/src/gmd/include/Face.py create mode 100644 vscript/languages/gm/src/gmd/include/HFacer.py create mode 100644 vscript/languages/gm/src/gmd/include/KeyWords.h create mode 100644 vscript/languages/gm/src/gmd/include/Platform.h create mode 100644 vscript/languages/gm/src/gmd/include/PropSet.h create mode 100644 vscript/languages/gm/src/gmd/include/SString.h create mode 100644 vscript/languages/gm/src/gmd/include/SciLexer.h create mode 100644 vscript/languages/gm/src/gmd/include/Scintilla.h create mode 100644 vscript/languages/gm/src/gmd/include/Scintilla.iface create mode 100644 vscript/languages/gm/src/gmd/include/ScintillaWidget.h create mode 100644 vscript/languages/gm/src/gmd/include/WindowAccessor.h create mode 100644 vscript/languages/gm/src/gmd/res/Toolbar.bmp create mode 100644 vscript/languages/gm/src/gmd/res/bangbang.wav create mode 100644 vscript/languages/gm/src/gmd/res/gmd.ico create mode 100644 vscript/languages/gm/src/gmd/res/gmd.rc2 create mode 100644 vscript/languages/gm/src/gme/NetClient.cpp create mode 100644 vscript/languages/gm/src/gme/NetClient.h create mode 100644 vscript/languages/gm/src/gme/gme.cpp create mode 100644 vscript/languages/gm/src/gme/gme.dsp create mode 100644 vscript/languages/gm/src/gme/gme.dsw create mode 100644 vscript/languages/gm/src/gme/gme.vcproj create mode 100644 vscript/languages/gm/src/gme/timer.cpp create mode 100644 vscript/languages/gm/src/gme/timer.h create mode 100644 vscript/languages/gm/src/gml/gml.dsp create mode 100644 vscript/languages/gm/src/gml/gml.dsw create mode 100644 vscript/languages/gm/src/gml/gml.vcproj create mode 100644 vscript/languages/gm/src/gml/main.cpp create mode 100644 vscript/languages/gm/src/platform/ps2cw/gmConfig_p.h create mode 100644 vscript/languages/gm/src/platform/win32gcc/gmConfig_p.h create mode 100644 vscript/languages/gm/src/platform/win32msvc/gmConfig_p.h create mode 100644 vscript/languages/gm/vgm/vgm.cpp create mode 100644 vscript/languages/gm/vgm/vgm.h create mode 100644 vscript/languages/gm/vgm/vgm.vpc create mode 100644 vscript/languages/gm/vgm/vscript_templates.h create mode 100644 vscript/languages/lua/lua-5.1.4/COPYRIGHT create mode 100644 vscript/languages/lua/lua-5.1.4/HISTORY create mode 100644 vscript/languages/lua/lua-5.1.4/INSTALL create mode 100644 vscript/languages/lua/lua-5.1.4/Makefile create mode 100644 vscript/languages/lua/lua-5.1.4/README create mode 100644 vscript/languages/lua/lua-5.1.4/doc/amazon.gif create mode 100644 vscript/languages/lua/lua-5.1.4/doc/contents.html create mode 100644 vscript/languages/lua/lua-5.1.4/doc/cover.png create mode 100644 vscript/languages/lua/lua-5.1.4/doc/logo.gif create mode 100644 vscript/languages/lua/lua-5.1.4/doc/lua.1 create mode 100644 vscript/languages/lua/lua-5.1.4/doc/lua.css create mode 100644 vscript/languages/lua/lua-5.1.4/doc/lua.html create mode 100644 vscript/languages/lua/lua-5.1.4/doc/luac.1 create mode 100644 vscript/languages/lua/lua-5.1.4/doc/luac.html create mode 100644 vscript/languages/lua/lua-5.1.4/doc/manual.css create mode 100644 vscript/languages/lua/lua-5.1.4/doc/manual.html create mode 100644 vscript/languages/lua/lua-5.1.4/doc/readme.html create mode 100644 vscript/languages/lua/lua-5.1.4/etc/Makefile create mode 100644 vscript/languages/lua/lua-5.1.4/etc/README create mode 100644 vscript/languages/lua/lua-5.1.4/etc/all.c create mode 100644 vscript/languages/lua/lua-5.1.4/etc/lua.hpp create mode 100644 vscript/languages/lua/lua-5.1.4/etc/lua.ico create mode 100644 vscript/languages/lua/lua-5.1.4/etc/lua.pc create mode 100644 vscript/languages/lua/lua-5.1.4/etc/luavs.bat create mode 100644 vscript/languages/lua/lua-5.1.4/etc/min.c create mode 100644 vscript/languages/lua/lua-5.1.4/etc/noparser.c create mode 100644 vscript/languages/lua/lua-5.1.4/etc/strict.lua create mode 100644 vscript/languages/lua/lua-5.1.4/src/Makefile create mode 100644 vscript/languages/lua/lua-5.1.4/src/lapi.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/lapi.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/lauxlib.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/lauxlib.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/lbaselib.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/lcode.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/lcode.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/ldblib.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/ldebug.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/ldebug.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/ldo.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/ldo.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/ldump.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/lfunc.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/lfunc.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/lgc.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/lgc.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/linit.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/liolib.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/llex.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/llex.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/llimits.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/lmathlib.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/lmem.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/lmem.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/loadlib.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/lobject.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/lobject.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/lopcodes.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/lopcodes.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/loslib.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/lparser.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/lparser.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/lstate.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/lstate.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/lstring.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/lstring.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/lstrlib.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/ltable.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/ltable.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/ltablib.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/ltm.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/ltm.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/lua.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/lua.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/luac.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/luaconf.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/lualib.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/lundump.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/lundump.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/lvm.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/lvm.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/lzio.c create mode 100644 vscript/languages/lua/lua-5.1.4/src/lzio.h create mode 100644 vscript/languages/lua/lua-5.1.4/src/print.c create mode 100644 vscript/languages/lua/lua-5.1.4/test/README create mode 100644 vscript/languages/lua/lua-5.1.4/test/bisect.lua create mode 100644 vscript/languages/lua/lua-5.1.4/test/cf.lua create mode 100644 vscript/languages/lua/lua-5.1.4/test/echo.lua create mode 100644 vscript/languages/lua/lua-5.1.4/test/env.lua create mode 100644 vscript/languages/lua/lua-5.1.4/test/factorial.lua create mode 100644 vscript/languages/lua/lua-5.1.4/test/fib.lua create mode 100644 vscript/languages/lua/lua-5.1.4/test/fibfor.lua create mode 100644 vscript/languages/lua/lua-5.1.4/test/globals.lua create mode 100644 vscript/languages/lua/lua-5.1.4/test/hello.lua create mode 100644 vscript/languages/lua/lua-5.1.4/test/life.lua create mode 100644 vscript/languages/lua/lua-5.1.4/test/luac.lua create mode 100644 vscript/languages/lua/lua-5.1.4/test/printf.lua create mode 100644 vscript/languages/lua/lua-5.1.4/test/readonly.lua create mode 100644 vscript/languages/lua/lua-5.1.4/test/sieve.lua create mode 100644 vscript/languages/lua/lua-5.1.4/test/sort.lua create mode 100644 vscript/languages/lua/lua-5.1.4/test/table.lua create mode 100644 vscript/languages/lua/lua-5.1.4/test/trace-calls.lua create mode 100644 vscript/languages/lua/lua-5.1.4/test/trace-globals.lua create mode 100644 vscript/languages/lua/lua-5.1.4/test/xd.lua create mode 100644 vscript/languages/lua/vlua/vec3.cpp create mode 100644 vscript/languages/lua/vlua/vec3.h create mode 100644 vscript/languages/lua/vlua/vlua.cpp create mode 100644 vscript/languages/lua/vlua/vlua.h create mode 100644 vscript/languages/lua/vlua/vlua.vpc create mode 100644 vscript/languages/python/python-2.5.1/include/abstract.h create mode 100644 vscript/languages/python/python-2.5.1/include/asdl.h create mode 100644 vscript/languages/python/python-2.5.1/include/ast.h create mode 100644 vscript/languages/python/python-2.5.1/include/bitset.h create mode 100644 vscript/languages/python/python-2.5.1/include/boolobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/bufferobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/cellobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/ceval.h create mode 100644 vscript/languages/python/python-2.5.1/include/classobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/cobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/code.h create mode 100644 vscript/languages/python/python-2.5.1/include/codecs.h create mode 100644 vscript/languages/python/python-2.5.1/include/compile.h create mode 100644 vscript/languages/python/python-2.5.1/include/complexobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/cstringio.h create mode 100644 vscript/languages/python/python-2.5.1/include/datetime.h create mode 100644 vscript/languages/python/python-2.5.1/include/descrobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/dictobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/enumobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/errcode.h create mode 100644 vscript/languages/python/python-2.5.1/include/eval.h create mode 100644 vscript/languages/python/python-2.5.1/include/fileobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/floatobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/frameobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/funcobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/genobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/graminit.h create mode 100644 vscript/languages/python/python-2.5.1/include/grammar.h create mode 100644 vscript/languages/python/python-2.5.1/include/import.h create mode 100644 vscript/languages/python/python-2.5.1/include/intobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/intrcheck.h create mode 100644 vscript/languages/python/python-2.5.1/include/iterobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/listobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/longintrepr.h create mode 100644 vscript/languages/python/python-2.5.1/include/longobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/marshal.h create mode 100644 vscript/languages/python/python-2.5.1/include/metagrammar.h create mode 100644 vscript/languages/python/python-2.5.1/include/methodobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/modsupport.h create mode 100644 vscript/languages/python/python-2.5.1/include/moduleobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/node.h create mode 100644 vscript/languages/python/python-2.5.1/include/object.h create mode 100644 vscript/languages/python/python-2.5.1/include/objimpl.h create mode 100644 vscript/languages/python/python-2.5.1/include/opcode.h create mode 100644 vscript/languages/python/python-2.5.1/include/osdefs.h create mode 100644 vscript/languages/python/python-2.5.1/include/parsetok.h create mode 100644 vscript/languages/python/python-2.5.1/include/patchlevel.h create mode 100644 vscript/languages/python/python-2.5.1/include/pgen.h create mode 100644 vscript/languages/python/python-2.5.1/include/pgenheaders.h create mode 100644 vscript/languages/python/python-2.5.1/include/py_curses.h create mode 100644 vscript/languages/python/python-2.5.1/include/pyarena.h create mode 100644 vscript/languages/python/python-2.5.1/include/pyconfig.h create mode 100644 vscript/languages/python/python-2.5.1/include/pydebug.h create mode 100644 vscript/languages/python/python-2.5.1/include/pyerrors.h create mode 100644 vscript/languages/python/python-2.5.1/include/pyexpat.h create mode 100644 vscript/languages/python/python-2.5.1/include/pyfpe.h create mode 100644 vscript/languages/python/python-2.5.1/include/pygetopt.h create mode 100644 vscript/languages/python/python-2.5.1/include/pymactoolbox.h create mode 100644 vscript/languages/python/python-2.5.1/include/pymem.h create mode 100644 vscript/languages/python/python-2.5.1/include/pyport.h create mode 100644 vscript/languages/python/python-2.5.1/include/pystate.h create mode 100644 vscript/languages/python/python-2.5.1/include/pystrtod.h create mode 100644 vscript/languages/python/python-2.5.1/include/python-ast.h create mode 100644 vscript/languages/python/python-2.5.1/include/python.h create mode 100644 vscript/languages/python/python-2.5.1/include/pythonrun.h create mode 100644 vscript/languages/python/python-2.5.1/include/pythread.h create mode 100644 vscript/languages/python/python-2.5.1/include/rangeobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/setobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/sliceobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/stringobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/structmember.h create mode 100644 vscript/languages/python/python-2.5.1/include/structseq.h create mode 100644 vscript/languages/python/python-2.5.1/include/symtable.h create mode 100644 vscript/languages/python/python-2.5.1/include/sysmodule.h create mode 100644 vscript/languages/python/python-2.5.1/include/timefuncs.h create mode 100644 vscript/languages/python/python-2.5.1/include/token.h create mode 100644 vscript/languages/python/python-2.5.1/include/traceback.h create mode 100644 vscript/languages/python/python-2.5.1/include/tupleobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/ucnhash.h create mode 100644 vscript/languages/python/python-2.5.1/include/unicodeobject.h create mode 100644 vscript/languages/python/python-2.5.1/include/weakrefobject.h create mode 100644 vscript/languages/python/python-2.5.1/win32release/python.exe create mode 100644 vscript/languages/python/python-2.5.1/win32release/python25.lib create mode 100644 vscript/languages/python/python-2.5.1/win32release/python25v.lib create mode 100644 vscript/languages/python/python-2.5.1/win32release/python25v.zip create mode 100644 vscript/languages/python/python-2.5.1/win32release/pythonw.exe create mode 100644 vscript/languages/python/readme.txt create mode 100644 vscript/languages/python/vpython/init.py create mode 100644 vscript/languages/python/vpython/vpython.cpp create mode 100644 vscript/languages/python/vpython/vpython.h create mode 100644 vscript/languages/python/vpython/vpython.vpc create mode 100644 vscript/languages/squirrel/COMPILE create mode 100644 vscript/languages/squirrel/COPYRIGHT create mode 100644 vscript/languages/squirrel/DXSquirrel/DXSquirrel.cbp create mode 100644 vscript/languages/squirrel/DXSquirrel/DXSquirrel.cpp create mode 100644 vscript/languages/squirrel/DXSquirrel/DXSquirrel.h create mode 100644 vscript/languages/squirrel/DXSquirrel/DXSquirrel.ico create mode 100644 vscript/languages/squirrel/DXSquirrel/DXSquirrel.vcproj create mode 100644 vscript/languages/squirrel/DXSquirrel/DXSquirrel71.vcproj create mode 100644 vscript/languages/squirrel/DXSquirrel/DXSquirrel_Binds.cpp create mode 100644 vscript/languages/squirrel/DXSquirrel/DXSquirrel_Binds.h create mode 100644 vscript/languages/squirrel/DXSquirrel/DXSquirrel_DX.cpp create mode 100644 vscript/languages/squirrel/DXSquirrel/DXSquirrel_Device.cpp create mode 100644 vscript/languages/squirrel/DXSquirrel/DXSquirrel_Math.cpp create mode 100644 vscript/languages/squirrel/DXSquirrel/DXSquirrel_Mesh.cpp create mode 100644 vscript/languages/squirrel/DXSquirrel/ReadMe.txt create mode 100644 vscript/languages/squirrel/DXSquirrel/Resource.h create mode 100644 vscript/languages/squirrel/DXSquirrel/dxsquirrel.nut create mode 100644 vscript/languages/squirrel/DXSquirrel/small.ico create mode 100644 vscript/languages/squirrel/DXSquirrel/stdafx.cpp create mode 100644 vscript/languages/squirrel/DXSquirrel/stdafx.h create mode 100644 vscript/languages/squirrel/HISTORY create mode 100644 vscript/languages/squirrel/Makefile create mode 100644 vscript/languages/squirrel/README create mode 100644 vscript/languages/squirrel/README_SQPLUS.txt create mode 100644 vscript/languages/squirrel/Solution Items create mode 100644 vscript/languages/squirrel/doc/sqdbg.chm create mode 100644 vscript/languages/squirrel/doc/sqdbg.pdf create mode 100644 vscript/languages/squirrel/doc/sqstdlib2.chm create mode 100644 vscript/languages/squirrel/doc/sqstdlib2.pdf create mode 100644 vscript/languages/squirrel/doc/squirrel2.chm create mode 100644 vscript/languages/squirrel/doc/squirrel2.pdf create mode 100644 vscript/languages/squirrel/etc/minimal.c create mode 100644 vscript/languages/squirrel/etc/test.nut create mode 100644 vscript/languages/squirrel/include/sqdbgserver.h create mode 100644 vscript/languages/squirrel/include/sqrdbg.h create mode 100644 vscript/languages/squirrel/include/sqstdaux.h create mode 100644 vscript/languages/squirrel/include/sqstdblob.h create mode 100644 vscript/languages/squirrel/include/sqstdio.h create mode 100644 vscript/languages/squirrel/include/sqstdmath.h create mode 100644 vscript/languages/squirrel/include/sqstdstring.h create mode 100644 vscript/languages/squirrel/include/sqstdsystem.h create mode 100644 vscript/languages/squirrel/include/squirrel.h create mode 100644 vscript/languages/squirrel/minimalSqPlus/Makefile create mode 100644 vscript/languages/squirrel/minimalSqPlus/minimalSqPlus.cbp create mode 100644 vscript/languages/squirrel/minimalSqPlus/minimalSqPlus.cpp create mode 100644 vscript/languages/squirrel/minimalSqPlus/minimalSqPlus.vcproj create mode 100644 vscript/languages/squirrel/minimalSqPlus/minimalSqPlus71.vcproj create mode 100644 vscript/languages/squirrel/readme_valve.txt create mode 100644 vscript/languages/squirrel/samples/ackermann.nut create mode 100644 vscript/languages/squirrel/samples/array.nut create mode 100644 vscript/languages/squirrel/samples/class.nut create mode 100644 vscript/languages/squirrel/samples/classattributes.nut create mode 100644 vscript/languages/squirrel/samples/coroutines.nut create mode 100644 vscript/languages/squirrel/samples/delegation.nut create mode 100644 vscript/languages/squirrel/samples/fibonacci.nut create mode 100644 vscript/languages/squirrel/samples/flow.nut create mode 100644 vscript/languages/squirrel/samples/generators.nut create mode 100644 vscript/languages/squirrel/samples/hello.nut create mode 100644 vscript/languages/squirrel/samples/list.nut create mode 100644 vscript/languages/squirrel/samples/loops.nut create mode 100644 vscript/languages/squirrel/samples/matrix.nut create mode 100644 vscript/languages/squirrel/samples/metamethods.nut create mode 100644 vscript/languages/squirrel/samples/methcall.nut create mode 100644 vscript/languages/squirrel/samples/tailstate.nut create mode 100644 vscript/languages/squirrel/sq/Makefile create mode 100644 vscript/languages/squirrel/sq/sq.c create mode 100644 vscript/languages/squirrel/sq/sq.cbp create mode 100644 vscript/languages/squirrel/sq/sq.vcproj create mode 100644 vscript/languages/squirrel/sq/sq71.vcproj create mode 100644 vscript/languages/squirrel/sqdbg/doc/sqdbg.chm create mode 100644 vscript/languages/squirrel/sqdbg/doc/sqdbg.pdf create mode 100644 vscript/languages/squirrel/sqdbg/main.cpp create mode 100644 vscript/languages/squirrel/sqdbg/makebin.pl create mode 100644 vscript/languages/squirrel/sqdbg/ps3socket.h create mode 100644 vscript/languages/squirrel/sqdbg/serialize_state.inl create mode 100644 vscript/languages/squirrel/sqdbg/serialize_state.nut create mode 100644 vscript/languages/squirrel/sqdbg/sqdbg.cbp create mode 100644 vscript/languages/squirrel/sqdbg/sqdbg.chm create mode 100644 vscript/languages/squirrel/sqdbg/sqdbg.pdf create mode 100644 vscript/languages/squirrel/sqdbg/sqdbg.vcproj create mode 100644 vscript/languages/squirrel/sqdbg/sqdbg71.vcproj create mode 100644 vscript/languages/squirrel/sqdbg/sqdbgWithUnicode.vcproj create mode 100644 vscript/languages/squirrel/sqdbg/sqdbgWithUnicode71.vcproj create mode 100644 vscript/languages/squirrel/sqdbg/sqdbgserver.cpp create mode 100644 vscript/languages/squirrel/sqdbg/sqrdbg.cpp create mode 100644 vscript/languages/squirrel/sqdbg/test.nut create mode 100644 vscript/languages/squirrel/sqdbg/testscripts/test.nut create mode 100644 vscript/languages/squirrel/sqdbg/testscripts/utils/commons.nut create mode 100644 vscript/languages/squirrel/sqdbglib/ReadMe.txt create mode 100644 vscript/languages/squirrel/sqdbglib/sqdbglib.cbp create mode 100644 vscript/languages/squirrel/sqdbglib/sqdbglib.vcproj create mode 100644 vscript/languages/squirrel/sqdbglib/sqdbglib71.vcproj create mode 100644 vscript/languages/squirrel/sqplus/Makefile create mode 100644 vscript/languages/squirrel/sqplus/SqPlus.cpp create mode 100644 vscript/languages/squirrel/sqplus/SqPlusConst.h create mode 100644 vscript/languages/squirrel/sqplus/SquirrelBindingsUtils.cpp create mode 100644 vscript/languages/squirrel/sqplus/SquirrelBindingsUtils.h create mode 100644 vscript/languages/squirrel/sqplus/SquirrelBindingsUtilsWin32.cpp create mode 100644 vscript/languages/squirrel/sqplus/SquirrelBindingsUtilsWin32.h create mode 100644 vscript/languages/squirrel/sqplus/SquirrelObject.cpp create mode 100644 vscript/languages/squirrel/sqplus/SquirrelObject.h create mode 100644 vscript/languages/squirrel/sqplus/SquirrelObjectImpl.h create mode 100644 vscript/languages/squirrel/sqplus/SquirrelVM.cpp create mode 100644 vscript/languages/squirrel/sqplus/SquirrelVM.h create mode 100644 vscript/languages/squirrel/sqplus/sqplus.cbp create mode 100644 vscript/languages/squirrel/sqplus/sqplus.h create mode 100644 vscript/languages/squirrel/sqplus/sqplus.vcproj create mode 100644 vscript/languages/squirrel/sqplus/sqplus71.vcproj create mode 100644 vscript/languages/squirrel/sqplus/sqplusWin32.h create mode 100644 vscript/languages/squirrel/sqstdlib/Makefile create mode 100644 vscript/languages/squirrel/sqstdlib/sqstdaux.cpp create mode 100644 vscript/languages/squirrel/sqstdlib/sqstdblob.cpp create mode 100644 vscript/languages/squirrel/sqstdlib/sqstdblobimpl.h create mode 100644 vscript/languages/squirrel/sqstdlib/sqstdio.cpp create mode 100644 vscript/languages/squirrel/sqstdlib/sqstdlib.cbp create mode 100644 vscript/languages/squirrel/sqstdlib/sqstdlib.vcproj create mode 100644 vscript/languages/squirrel/sqstdlib/sqstdlib71.vcproj create mode 100644 vscript/languages/squirrel/sqstdlib/sqstdmath.cpp create mode 100644 vscript/languages/squirrel/sqstdlib/sqstdrex.cpp create mode 100644 vscript/languages/squirrel/sqstdlib/sqstdstream.cpp create mode 100644 vscript/languages/squirrel/sqstdlib/sqstdstream.h create mode 100644 vscript/languages/squirrel/sqstdlib/sqstdstring.cpp create mode 100644 vscript/languages/squirrel/sqstdlib/sqstdsystem.cpp create mode 100644 vscript/languages/squirrel/squirrel.workspace create mode 100644 vscript/languages/squirrel/squirrel/Makefile create mode 100644 vscript/languages/squirrel/squirrel/sqapi.cpp create mode 100644 vscript/languages/squirrel/squirrel/sqarray.h create mode 100644 vscript/languages/squirrel/squirrel/sqbaselib.cpp create mode 100644 vscript/languages/squirrel/squirrel/sqclass.cpp create mode 100644 vscript/languages/squirrel/squirrel/sqclass.h create mode 100644 vscript/languages/squirrel/squirrel/sqclosure.h create mode 100644 vscript/languages/squirrel/squirrel/sqcompiler.cpp create mode 100644 vscript/languages/squirrel/squirrel/sqcompiler.h create mode 100644 vscript/languages/squirrel/squirrel/sqdebug.cpp create mode 100644 vscript/languages/squirrel/squirrel/sqfuncproto.h create mode 100644 vscript/languages/squirrel/squirrel/sqfuncstate.cpp create mode 100644 vscript/languages/squirrel/squirrel/sqfuncstate.h create mode 100644 vscript/languages/squirrel/squirrel/sqlexer.cpp create mode 100644 vscript/languages/squirrel/squirrel/sqlexer.h create mode 100644 vscript/languages/squirrel/squirrel/sqmem.cpp create mode 100644 vscript/languages/squirrel/squirrel/sqobject.cpp create mode 100644 vscript/languages/squirrel/squirrel/sqobject.h create mode 100644 vscript/languages/squirrel/squirrel/sqopcodes.h create mode 100644 vscript/languages/squirrel/squirrel/sqpcheader.h create mode 100644 vscript/languages/squirrel/squirrel/sqstate.cpp create mode 100644 vscript/languages/squirrel/squirrel/sqstate.h create mode 100644 vscript/languages/squirrel/squirrel/sqstring.h create mode 100644 vscript/languages/squirrel/squirrel/sqtable.cpp create mode 100644 vscript/languages/squirrel/squirrel/sqtable.h create mode 100644 vscript/languages/squirrel/squirrel/squirrel.cbp create mode 100644 vscript/languages/squirrel/squirrel/squirrel.vcproj create mode 100644 vscript/languages/squirrel/squirrel/squirrel71.vcproj create mode 100644 vscript/languages/squirrel/squirrel/squirrellib.cbp create mode 100644 vscript/languages/squirrel/squirrel/squserdata.h create mode 100644 vscript/languages/squirrel/squirrel/squtils.h create mode 100644 vscript/languages/squirrel/squirrel/sqvm.cpp create mode 100644 vscript/languages/squirrel/squirrel/sqvm.h create mode 100644 vscript/languages/squirrel/testSqPlus/Makefile create mode 100644 vscript/languages/squirrel/testSqPlus/testSqPlus.cbp create mode 100644 vscript/languages/squirrel/testSqPlus/testSqPlus.cpp create mode 100644 vscript/languages/squirrel/testSqPlus/testSqPlus.vcproj create mode 100644 vscript/languages/squirrel/testSqPlus/testSqPlus71.vcproj create mode 100644 vscript/languages/squirrel/testSqPlus2/Makefile create mode 100644 vscript/languages/squirrel/testSqPlus2/testSqPlus2.cbp create mode 100644 vscript/languages/squirrel/testSqPlus2/testSqPlus2.cpp create mode 100644 vscript/languages/squirrel/testSqPlus2/testSqPlus2.vcproj create mode 100644 vscript/languages/squirrel/testSqPlus2/testSqPlus271.vcproj create mode 100644 vscript/languages/squirrel/vsquirrel/init.nut create mode 100644 vscript/languages/squirrel/vsquirrel/init_nut.h create mode 100644 vscript/languages/squirrel/vsquirrel/test.nut create mode 100644 vscript/languages/squirrel/vsquirrel/vsquirrel.cpp create mode 100644 vscript/languages/squirrel/vsquirrel/vsquirrel.h create mode 100644 vscript/languages/squirrel/vsquirrel/vsquirrel.vpc create mode 100644 vscript/vscript.cpp create mode 100644 vscript/vscript.vpc create mode 100644 vscript/vscript_sob.vpc create mode 100644 vscript/vsi.nul create mode 100644 vscript/xbox/xbox.def diff --git a/engine/GameEventManager.cpp b/engine/GameEventManager.cpp index 1d6d50fc..766a2273 100644 --- a/engine/GameEventManager.cpp +++ b/engine/GameEventManager.cpp @@ -41,11 +41,11 @@ static ConVar net_showevents( "net_showevents", "0", FCVAR_CHEAT, "Dump game eve EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CGameEventManager, IGameEventManager2, INTERFACEVERSION_GAMEEVENTSMANAGER2, s_GameEventManager ); -CGameEvent::CGameEvent( CGameEventDescriptor *descriptor ) +CGameEvent::CGameEvent( CGameEventDescriptor *descriptor, const char *name ) { Assert( descriptor ); m_pDescriptor = descriptor; - m_pDataKeys = new KeyValues( descriptor->name ); + m_pDataKeys = new KeyValues( name ); } CGameEvent::~CGameEvent() @@ -63,6 +63,11 @@ int CGameEvent::GetInt( const char *keyName, int defaultValue) return m_pDataKeys->GetInt( keyName, defaultValue ); } +uint64 CGameEvent::GetUint64( const char *keyName, uint64 defaultValue) +{ + return m_pDataKeys->GetUint64( keyName, defaultValue ); +} + float CGameEvent::GetFloat( const char *keyName, float defaultValue ) { return m_pDataKeys->GetFloat( keyName, defaultValue ); @@ -83,6 +88,11 @@ void CGameEvent::SetInt( const char *keyName, int value ) m_pDataKeys->SetInt( keyName, value ); } +void CGameEvent::SetUint64( const char *keyName, uint64 value ) +{ + m_pDataKeys->SetUint64( keyName, value ); +} + void CGameEvent::SetFloat( const char *keyName, float value ) { m_pDataKeys->SetFloat( keyName, value ); @@ -158,8 +168,8 @@ void CGameEventManager::Reset() m_Listeners.PurgeAndDeleteElements(); m_EventFiles.RemoveAll(); m_EventFileNames.RemoveAll(); + m_EventMap.Purge(); m_bClientListenersChanged = true; - Assert( m_GameEvents.Count() == 0 ); } @@ -189,10 +199,12 @@ void CGameEventManager::WriteEventList(SVC_GameEventList *msg) Assert( descriptor.eventid >= 0 && descriptor.eventid < MAX_EVENT_NUMBER ); + const char *pName = m_EventMap.GetElementName( descriptor.elementIndex ); + msg->m_DataOut.WriteUBitLong( descriptor.eventid, MAX_EVENT_BITS ); - msg->m_DataOut.WriteString( descriptor.name ); - - KeyValues *key = descriptor.keys->GetFirstSubKey(); + msg->m_DataOut.WriteString( pName ); + + KeyValues *key = descriptor.keys->GetFirstSubKey(); while ( key ) { @@ -208,7 +220,6 @@ void CGameEventManager::WriteEventList(SVC_GameEventList *msg) } msg->m_DataOut.WriteUBitLong( TYPE_LOCAL, 3 ); // end marker - msg->m_nNumEvents++; } } @@ -296,7 +307,8 @@ void CGameEventManager::WriteListenEventList(CLC_ListenEvents *msg) if ( descriptor.eventid == -1 ) { - DevMsg("Warning! Client listens to event '%s' unknown by server.\n", descriptor.name ); + const char *pName = m_EventMap.GetElementName(descriptor.elementIndex); + DevMsg("Warning! Client listens to event '%s' unknown by server.\n", pName ); continue; } @@ -304,17 +316,17 @@ void CGameEventManager::WriteListenEventList(CLC_ListenEvents *msg) } } -IGameEvent *CGameEventManager::CreateEvent( CGameEventDescriptor *descriptor ) +IGameEvent *CGameEventManager::CreateEvent( CGameEventDescriptor *descriptor, const char *name ) { - return new CGameEvent ( descriptor ); + return new CGameEvent ( descriptor, name ); } -IGameEvent *CGameEventManager::CreateEvent( const char *name, bool bForce ) +IGameEvent *CGameEventManager::CreateEvent( const char *name, bool bForce, int *pCookie ) { if ( !name || !name[0] ) return NULL; - CGameEventDescriptor *descriptor = GetEventDescriptor( name ); + CGameEventDescriptor *descriptor = GetEventDescriptor( name, pCookie ); // check if this event name is known if ( !descriptor ) @@ -330,7 +342,7 @@ IGameEvent *CGameEventManager::CreateEvent( const char *name, bool bForce ) } // create & return the new event - return new CGameEvent ( descriptor ); + return new CGameEvent ( descriptor, name ); } bool CGameEventManager::FireEvent( IGameEvent *event, bool bServerOnly ) @@ -351,7 +363,8 @@ IGameEvent *CGameEventManager::DuplicateEvent( IGameEvent *event ) return NULL; // create new instance - CGameEvent *newEvent = new CGameEvent ( gameEvent->m_pDescriptor ); + const char *pName = m_EventMap.GetElementName(gameEvent->m_pDescriptor->elementIndex ); + CGameEvent *newEvent = new CGameEvent ( gameEvent->m_pDescriptor, pName ); // free keys newEvent->m_pDataKeys->deleteThis(); @@ -414,12 +427,16 @@ bool CGameEventManager::FireEventIntern( IGameEvent *event, bool bServerOnly, bo { if ( bClientOnly ) { - ConMsg( "Game event \"%s\", Tick %i:\n", descriptor->name, cl.GetClientTickCount() ); +#ifndef DEDICATED + const char *pName = m_EventMap.GetElementName(descriptor->elementIndex); + ConMsg( "Game event \"%s\", Tick %i:\n", pName, cl.GetClientTickCount() ); ConPrintEvent( event ); +#endif } else if ( net_showevents.GetInt() > 1 ) { - ConMsg( "Server event \"%s\", Tick %i:\n", descriptor->name, sv.GetTick() ); + const char *pName = m_EventMap.GetElementName(descriptor->elementIndex); + ConMsg( "Server event \"%s\", Tick %i:\n", pName, sv.GetTick() ); ConPrintEvent( event ); } } @@ -491,7 +508,8 @@ bool CGameEventManager::SerializeEvent( IGameEvent *event, bf_write* buf ) if ( net_showevents.GetInt() > 2 ) { - DevMsg("Serializing event '%s' (%i):\n", descriptor->name, descriptor->eventid ); + const char *pName = m_EventMap.GetElementName(descriptor->elementIndex); + DevMsg("Serializing event '%s' (%i):\n", pName, descriptor->eventid ); } while ( key ) @@ -545,11 +563,12 @@ IGameEvent *CGameEventManager::UnserializeEvent( bf_read *buf) } // create new event - IGameEvent *event = CreateEvent( descriptor ); + const char *pName = m_EventMap.GetElementName(descriptor->elementIndex); + IGameEvent *event = CreateEvent( descriptor, pName ); if ( !event ) { - DevMsg( "CGameEventManager::UnserializeEvent:: failed to create event %s.\n", descriptor->name ); + DevMsg( "CGameEventManager::UnserializeEvent:: failed to create event %i.\n", descriptor->eventid ); return NULL; } @@ -766,9 +785,7 @@ bool CGameEventManager::RegisterEvent( KeyValues * event) int index = m_GameEvents.AddToTail(); descriptor = &m_GameEvents.Element(index); - AssertMsg2( V_strlen( event->GetName() ) <= MAX_EVENT_NAME_LENGTH, "Event named '%s' exceeds maximum name length %d", event->GetName(), MAX_EVENT_NAME_LENGTH ); - - Q_strncpy( descriptor->name, event->GetName(), MAX_EVENT_NAME_LENGTH ); + descriptor->elementIndex = m_EventMap.Insert( event->GetName(), index ); } else { @@ -859,20 +876,34 @@ void CGameEventManager::FreeEvent( IGameEvent *event ) delete event; } -CGameEventDescriptor *CGameEventManager::GetEventDescriptor(const char * name) +CGameEventDescriptor *CGameEventManager::GetEventDescriptor(const char * name, int *pCookie) { + const uint32 cookieBit = 0x80000000; + const uint32 cookieMask = ~cookieBit; + if ( !name || !name[0] ) return NULL; - for (int i=0; i < m_GameEvents.Count(); i++ ) + if ( pCookie && *pCookie ) { - CGameEventDescriptor *descriptor = &m_GameEvents[i]; + int gameEventIndex = uint32(*pCookie) & cookieMask; + CGameEventDescriptor *pDescriptor = &m_GameEvents[gameEventIndex]; + if ( !V_stricmp( m_EventMap.GetElementName(pDescriptor->elementIndex), name ) ) + { + return pDescriptor; + } + } + int eventMapIndex = m_EventMap.Find( name ); + if ( eventMapIndex == m_EventMap.InvalidIndex() ) + return NULL; - if ( Q_strcmp( descriptor->name, name ) == 0 ) - return descriptor; + int gameEventIndex = m_EventMap[eventMapIndex]; + if ( pCookie ) + { + *pCookie = cookieBit | gameEventIndex; } - return NULL; + return &m_GameEvents[gameEventIndex]; } bool CGameEventManager::AddListenerAll( void *listener, int nListenerType ) diff --git a/engine/GameEventManager.h b/engine/GameEventManager.h index 02d247dc..74ddafda 100644 --- a/engine/GameEventManager.h +++ b/engine/GameEventManager.h @@ -13,6 +13,7 @@ #pragma once #endif +#include "utldict.h" #include #include #include @@ -34,16 +35,16 @@ class CGameEventDescriptor public: CGameEventDescriptor() { - name[0] = 0; eventid = -1; keys = NULL; local = false; reliable = true; + elementIndex = -1; } public: - char name[MAX_EVENT_NAME_LENGTH]; // name of this event - int eventid; // network index number, -1 = not networked + int eventid; // network index number, -1 = not networked + int elementIndex; KeyValues *keys; // KeyValue describing data types, if NULL only name bool local; // local event, never tell clients about that bool reliable; // send this event as reliable message @@ -54,7 +55,7 @@ class CGameEvent : public IGameEvent { public: - CGameEvent( CGameEventDescriptor *descriptor ); + CGameEvent( CGameEventDescriptor *descriptor, const char *name ); virtual ~CGameEvent(); const char *GetName() const; @@ -64,11 +65,13 @@ public: bool GetBool( const char *keyName = NULL, bool defaultValue = false ); int GetInt( const char *keyName = NULL, int defaultValue = 0 ); + uint64 GetUint64( const char *keyName = NULL, uint64 defaultValue = 0 ); float GetFloat( const char *keyName = NULL, float defaultValue = 0.0f ); const char *GetString( const char *keyName = NULL, const char *defaultValue = "" ); void SetBool( const char *keyName, bool value ); void SetInt( const char *keyName, int value ); + void SetUint64( const char *keyName, uint64 value ); void SetFloat( const char *keyName, float value ); void SetString( const char *keyName, const char *value ); @@ -111,8 +114,9 @@ public: // IGameEventManager functions bool AddListener( IGameEventListener2 *listener, const char *name, bool bServerSide ); bool FindListener( IGameEventListener2 *listener, const char *name ); void RemoveListener( IGameEventListener2 *listener); - - IGameEvent *CreateEvent( const char *name, bool bForce = false ); + + IGameEvent *CreateEvent( const char *name, bool bForce = false, int *pCookie = NULL ); + IGameEvent *DuplicateEvent( IGameEvent *event); bool FireEvent( IGameEvent *event, bool bDontBroadcast = false ); bool FireEventClientSide( IGameEvent *event ); @@ -127,7 +131,7 @@ public: void ReloadEventDefinitions(); // called by server on new map bool AddListener( void *listener, CGameEventDescriptor *descriptor, int nListenerType ); - CGameEventDescriptor *GetEventDescriptor( const char *name ); + CGameEventDescriptor *GetEventDescriptor( const char *name, int *pCookie = NULL ); CGameEventDescriptor *GetEventDescriptor( IGameEvent *event ); CGameEventDescriptor *GetEventDescriptor( int eventid ); @@ -145,13 +149,14 @@ public: protected: - IGameEvent *CreateEvent( CGameEventDescriptor *descriptor ); + IGameEvent *CreateEvent( CGameEventDescriptor *descriptor, const char *name ); bool RegisterEvent( KeyValues * keys ); void UnregisterEvent(int index); bool FireEventIntern( IGameEvent *event, bool bServerSide, bool bClientOnly ); CGameEventCallback* FindEventListener( void* listener ); CUtlVector m_GameEvents; // list of all known events + CUtlDict m_EventMap; CUtlVector m_Listeners; // list of all registered listeners CUtlSymbolTable m_EventFiles; // list of all loaded event files CUtlVector m_EventFileNames; diff --git a/engine/baseclient.cpp b/engine/baseclient.cpp index 4ec46652..cd87b8fa 100644 --- a/engine/baseclient.cpp +++ b/engine/baseclient.cpp @@ -66,10 +66,13 @@ CBaseClient::CBaseClient() m_bReportFakeClient = true; m_iTracing = 0; m_bPlayerNameLocked = false; + + m_nDebugID = EVENT_DEBUG_ID_INIT; } CBaseClient::~CBaseClient() { + m_nDebugID = EVENT_DEBUG_ID_SHUTDOWN; } @@ -670,6 +673,11 @@ void CBaseClient::FireGameEvent( IGameEvent *event ) } } +int CBaseClient::GetEventDebugID( void ) +{ + return m_nDebugID; +} + bool CBaseClient::SendServerInfo( void ) { COM_TimestampedLog( " CBaseClient::SendServerInfo" ); diff --git a/engine/baseclient.h b/engine/baseclient.h index b399f9e6..21ea47ee 100644 --- a/engine/baseclient.h +++ b/engine/baseclient.h @@ -144,6 +144,8 @@ public: // IClientMessageHandlers public: // IGameEventListener virtual void FireGameEvent( IGameEvent *event ); + int m_nDebugID; + virtual int GetEventDebugID( void ); public: diff --git a/engine/cdll_engine_int.cpp b/engine/cdll_engine_int.cpp index f986a207..0b2c7154 100644 --- a/engine/cdll_engine_int.cpp +++ b/engine/cdll_engine_int.cpp @@ -539,6 +539,8 @@ public: virtual bool REMOVED_SteamRefreshLogin( const char *password, bool isSecure ) { return false; } virtual bool REMOVED_SteamProcessCall( bool & finished ) { return false; } + virtual ISPSharedMemory *GetSinglePlayerSharedMemorySpace( const char *handle, int ent_num = MAX_EDICTS ); + virtual void SetGamestatsData( CGamestatsData *pGamestatsData ); virtual CGamestatsData *GetGamestatsData(); @@ -1568,6 +1570,13 @@ void CEngineClient::OnStorageDeviceDetached( void ) g_pXboxSystem->CloseContainers(); } + +ISPSharedMemory *CEngineClient::GetSinglePlayerSharedMemorySpace( const char *szName, int ent_num ) +{ + // TODO(nillerusr): it this necessary? Implement later if so + return NULL; //g_pSinglePlayerSharedMemoryManager->GetSharedMemory( szName, ent_num ); +} + void CEngineClient::ResetDemoInterpolation( void ) { if( demorecorder->IsRecording() ) diff --git a/engine/cmodel.cpp b/engine/cmodel.cpp index 373eea3a..22eaab69 100644 --- a/engine/cmodel.cpp +++ b/engine/cmodel.cpp @@ -50,47 +50,28 @@ csurface_t *CCollisionBSPData::GetSurfaceAtIndex( unsigned short surfaceIndex ) return &map_surfaces[surfaceIndex]; } -#if TEST_TRACE_POOL -CTSPool g_TraceInfoPool; -#else -class CTraceInfoPool : public CTSList -{ -public: - CTraceInfoPool() = default; -}; - -CTraceInfoPool g_TraceInfoPool; -#endif +static TraceInfo_t g_TraceInfo; TraceInfo_t *BeginTrace() { -#if TEST_TRACE_POOL - TraceInfo_t *pTraceInfo = g_TraceInfoPool.GetObject(); -#else - TraceInfo_t *pTraceInfo; - if ( !g_TraceInfoPool.PopItem( &pTraceInfo ) ) + if ( g_TraceInfo.m_BrushCounters[0].Count() != GetCollisionBSPData()->numbrushes + 1 ) { - pTraceInfo = new TraceInfo_t; - } -#endif - if ( pTraceInfo->m_BrushCounters[0].Count() != GetCollisionBSPData()->numbrushes + 1 ) - { - memset( pTraceInfo->m_Count, 0, sizeof( pTraceInfo->m_Count ) ); - pTraceInfo->m_nCheckDepth = -1; + memset( g_TraceInfo.m_Count, 0, sizeof( g_TraceInfo.m_Count ) ); + g_TraceInfo.m_nCheckDepth = -1; for ( int i = 0; i < MAX_CHECK_COUNT_DEPTH; i++ ) { - pTraceInfo->m_BrushCounters[i].SetCount( GetCollisionBSPData()->numbrushes + 1 ); - pTraceInfo->m_DispCounters[i].SetCount( g_DispCollTreeCount ); + g_TraceInfo.m_BrushCounters[i].SetCount( GetCollisionBSPData()->numbrushes + 1 ); + g_TraceInfo.m_DispCounters[i].SetCount( g_DispCollTreeCount ); - memset( pTraceInfo->m_BrushCounters[i].Base(), 0, pTraceInfo->m_BrushCounters[i].Count() * sizeof(TraceCounter_t) ); - memset( pTraceInfo->m_DispCounters[i].Base(), 0, pTraceInfo->m_DispCounters[i].Count() * sizeof(TraceCounter_t) ); + memset( g_TraceInfo.m_BrushCounters[i].Base(), 0, g_TraceInfo.m_BrushCounters[i].Count() * sizeof(TraceCounter_t) ); + memset( g_TraceInfo.m_DispCounters[i].Base(), 0, g_TraceInfo.m_DispCounters[i].Count() * sizeof(TraceCounter_t) ); } } - PushTraceVisits( pTraceInfo ); + PushTraceVisits( &g_TraceInfo ); - return pTraceInfo; + return &g_TraceInfo; } void PushTraceVisits( TraceInfo_t *pTraceInfo ) @@ -114,16 +95,9 @@ void PopTraceVisits( TraceInfo_t *pTraceInfo ) Assert( pTraceInfo->m_nCheckDepth >= -1 ); } -void EndTrace( TraceInfo_t *&pTraceInfo ) +void EndTrace( TraceInfo_t *pTraceInfo ) { PopTraceVisits( pTraceInfo ); - Assert( pTraceInfo->m_nCheckDepth == -1 ); -#if TEST_TRACE_POOL - g_TraceInfoPool.PutObject( pTraceInfo ); -#else - g_TraceInfoPool.PushItem( pTraceInfo ); -#endif - pTraceInfo = NULL; } static ConVar map_noareas( "map_noareas", "0", 0, "Disable area to area connection testing." ); diff --git a/engine/cmodel_private.h b/engine/cmodel_private.h index 5bf52eee..0f397534 100644 --- a/engine/cmodel_private.h +++ b/engine/cmodel_private.h @@ -158,7 +158,7 @@ struct cnode_t TraceInfo_t *BeginTrace(); void PushTraceVisits( TraceInfo_t *pTraceInfo ); void PopTraceVisits( TraceInfo_t *pTraceInfo ); -void EndTrace( TraceInfo_t *&pTraceInfo ); +void EndTrace( TraceInfo_t *pTraceInfo ); //----------------------------------------------------------------------------- diff --git a/engine/hltvserver.cpp b/engine/hltvserver.cpp index 0b4d8691..069ab3f0 100644 --- a/engine/hltvserver.cpp +++ b/engine/hltvserver.cpp @@ -475,6 +475,8 @@ CHLTVServer::CHLTVServer() m_nGlobalSlots = 0; m_nGlobalClients = 0; m_nGlobalProxies = 0; + + m_nDebugID = EVENT_DEBUG_ID_INIT; } CHLTVServer::~CHLTVServer() @@ -488,6 +490,8 @@ CHLTVServer::~CHLTVServer() // make sure everything was destroyed Assert( m_CurrentFrame == NULL ); Assert( CountClientFrames() == 0 ); + + m_nDebugID = EVENT_DEBUG_ID_SHUTDOWN; } void CHLTVServer::SetMaxClients( int number ) @@ -1015,9 +1019,13 @@ void CHLTVServer::FireGameEvent(IGameEvent *event) } } +int CHLTVServer::GetEventDebugID( void ) +{ + return m_nDebugID; +} + bool CHLTVServer::ShouldUpdateMasterServer() { - // If the main game server is active, then we let it update Steam with the server info. return !sv.IsActive(); } diff --git a/engine/hltvserver.h b/engine/hltvserver.h index fa5a657a..91fc058d 100644 --- a/engine/hltvserver.h +++ b/engine/hltvserver.h @@ -115,6 +115,8 @@ public: // CBaseServer interface: public: void FireGameEvent(IGameEvent *event); + int m_nDebugID; + int GetEventDebugID( void ); public: // IHLTVServer interface: IServer *GetBaseServer( void ); diff --git a/engine/sv_log.cpp b/engine/sv_log.cpp index f04d17da..c50c396d 100644 --- a/engine/sv_log.cpp +++ b/engine/sv_log.cpp @@ -262,11 +262,13 @@ CON_COMMAND( logaddress_list, "List all addresses currently being used by logadd CLog::CLog() { Reset(); + m_nDebugID = EVENT_DEBUG_ID_INIT; + } CLog::~CLog() { - + m_nDebugID = EVENT_DEBUG_ID_SHUTDOWN; } void CLog::Reset( void ) // reset all logging streams @@ -644,6 +646,11 @@ void CLog::FireGameEvent( IGameEvent *event ) } } +int CLog::GetEventDebugID( void ) +{ + return m_nDebugID; +} + struct TempFilename_t { bool IsGzip; diff --git a/engine/sv_log.h b/engine/sv_log.h index 42f05113..86771e1e 100644 --- a/engine/sv_log.h +++ b/engine/sv_log.h @@ -24,7 +24,8 @@ public: public: // IGameEventListener Interface void FireGameEvent( IGameEvent *event ); - + int m_nDebugID; + int GetEventDebugID( void ); public: bool IsActive( void ); // true if logging is "on" diff --git a/engine/vengineserver_impl.cpp b/engine/vengineserver_impl.cpp index 37dc07c6..39cbf298 100644 --- a/engine/vengineserver_impl.cpp +++ b/engine/vengineserver_impl.cpp @@ -1595,6 +1595,12 @@ public: return sv.GetPlayerInfo( (ent_num-1), pinfo ); } + virtual ISPSharedMemory *GetSinglePlayerSharedMemorySpace( const char *szName, int ent_num = MAX_EDICTS ) + { + // TODO(nillerusr): it this necessary? Implement later if so + return NULL; //return g_pSinglePlayerSharedMemoryManager->GetSharedMemory( szName, ent_num ); + } + bool IsClientFullyAuthenticated( edict_t *pEdict ) { int entnum = NUM_FOR_EDICT( pEdict ); diff --git a/game/shared/choreoevent.cpp b/game/shared/choreoevent.cpp index 439bf20f..133eca2f 100644 --- a/game/shared/choreoevent.cpp +++ b/game/shared/choreoevent.cpp @@ -787,9 +787,9 @@ float CFlexAnimationTrack::GetFracIntensity( float time, int type ) prev = MAX( -1, prev ); next = MIN( next, rampCount ); - bool clamp[ 2 ]; - CExpressionSample *esPre = GetBoundedSample( prev, clamp[ 0 ], type ); - CExpressionSample *esNext = GetBoundedSample( next, clamp[ 1 ], type ); + bool bClamp[ 2 ]; + CExpressionSample *esPre = GetBoundedSample( prev, bClamp[ 0 ], type ); + CExpressionSample *esNext = GetBoundedSample( next, bClamp[ 1 ], type ); float dt = esEnd->time - esStart->time; @@ -1654,9 +1654,9 @@ float CCurveData::GetIntensity( ICurveDataAccessor *data, float time ) prev = MAX( -1, prev ); next = MIN( next, rampCount ); - bool clamp[ 2 ]; - CExpressionSample *esPre = GetBoundedSample( data, prev, clamp[ 0 ] ); - CExpressionSample *esNext = GetBoundedSample( data, next, clamp[ 1 ] ); + bool bClamp[ 2 ]; + CExpressionSample *esPre = GetBoundedSample( data, prev, bClamp[ 0 ] ); + CExpressionSample *esNext = GetBoundedSample( data, next, bClamp[ 1 ] ); float dt = esEnd->time - esStart->time; @@ -1665,12 +1665,12 @@ float CCurveData::GetIntensity( ICurveDataAccessor *data, float time ) Vector vEnd( esEnd->time, esEnd->value, 0 ); Vector vNext( esNext->time, esNext->value, 0 ); - if ( clamp[ 0 ] ) + if ( bClamp[ 0 ] ) { vPre.x = vStart.x; } - if ( clamp[ 1 ] ) + if ( bClamp[ 1 ] ) { vNext.x = vEnd.x; } @@ -1836,9 +1836,9 @@ float CCurveData::GetIntensityArea( ICurveDataAccessor *data, float time ) prev = MAX( -1, prev ); next = MIN( next, rampCount ); - bool clamp[ 2 ]; - CExpressionSample *esPre = GetBoundedSample( data, prev, clamp[ 0 ] ); - CExpressionSample *esNext = GetBoundedSample( data, next, clamp[ 1 ] ); + bool bClamp[ 2 ]; + CExpressionSample *esPre = GetBoundedSample( data, prev, bClamp[ 0 ] ); + CExpressionSample *esNext = GetBoundedSample( data, next, bClamp[ 1 ] ); float dt = esEnd->time - esStart->time; @@ -1847,12 +1847,12 @@ float CCurveData::GetIntensityArea( ICurveDataAccessor *data, float time ) Vector vEnd( esEnd->time, esEnd->value, 0 ); Vector vNext( esNext->time, esNext->value, 0 ); - if ( clamp[ 0 ] ) + if ( bClamp[ 0 ] ) { vPre.x = vStart.x; } - if ( clamp[ 1 ] ) + if ( bClamp[ 1 ] ) { vNext.x = vEnd.x; } diff --git a/header-list.txt b/header-list.txt new file mode 100644 index 00000000..6f2882aa --- /dev/null +++ b/header-list.txt @@ -0,0 +1,9 @@ +// modified case headers + +public/appframework/iappsystem.h +public/color.h + +// replaced headers that breaking/can break sdk 2013 + +public/igameevents.h +public/engine/ICollideable.h diff --git a/public/appframework/iappsystem.h b/public/appframework/iappsystem.h new file mode 100644 index 00000000..fef4db00 --- /dev/null +++ b/public/appframework/iappsystem.h @@ -0,0 +1 @@ +#include "IAppSystem.h" diff --git a/public/bittools.h b/public/bittools.h new file mode 100644 index 00000000..b812fe1f --- /dev/null +++ b/public/bittools.h @@ -0,0 +1,46 @@ +//===== Copyright © 1996-2009, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#ifndef BITTOOLS_H +#define BITTOOLS_H +#ifdef _WIN32 +#pragma once +#endif + +namespace bittools +{ + template + struct RecurseBit + { + enum {result = RecurseBit::result}; + }; + + template + struct RecurseBit<0, C> + { + enum {result = C}; + }; + + template + struct RecursePow2 + { + enum {result = RecursePow2::result}; + }; + + template + struct RecursePow2<0, C> + { + enum {result = C}; + }; + +} + +#define ROUND_TO_POWER_OF_2( n ) ( bittools::RecursePow2< (n) - 1 >::result ) +#define MINIMUM_BITS_NEEDED( n ) ( bittools::RecurseBit< (n) - 1 >::result ) + +#endif //BITTOOLS_H + diff --git a/public/branchingsingleton.h b/public/branchingsingleton.h new file mode 100644 index 00000000..18fa3400 --- /dev/null +++ b/public/branchingsingleton.h @@ -0,0 +1,48 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: Macros for defining branching singletons. +// +// A branching singleton defines a singleton class within another class, and subclasses +// of the outer class can automatically expand on that singleton at their node in the +// class branching tree with the confidence that changes will be reflected in all +// subclasses. +// +// The primary reason to have a branching singleton is to centralize management code +// without being tied explicitly to one interface. The interface can possibly change +// vastly as it gets passed down the tree to the point where all the original functions +// are stubs and the interface uses an entirely different set of functions. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef BRANCHINGSINGLETON_H +#define BRANCHINGSINGLETON_H +#ifdef _WIN32 +#pragma once +#endif + + +#define START_BRANCHING_SINGLETON_DEFINITION_NOBASE( classname ) class classname + +#define START_BRANCHING_SINGLETON_DEFINITION( classname ) class classname : public Base##classname + +#define _END_BRANCHING_SINGLETON_DEFINITION( classname );\ + static classname *Get_##classname##_Static( void )\ + {\ + static classname s_Singleton;\ + return &s_Singleton;\ + }\ + \ + virtual Root##classname *Get_##classname##( void )\ + {\ + return Get_##classname##_Static();\ + }\ + typedef classname Base##classname; + +#define END_BRANCHING_SINGLETON_DEFINITION( classname ) _END_BRANCHING_SINGLETON_DEFINITION( classname ) + +#define END_BRANCHING_SINGLETON_DEFINITION_NOBASE( classname );\ + typedef classname Root##classname;\ + _END_BRANCHING_SINGLETON_DEFINITION( classname ); + +#endif //#ifndef BRANCHINGSINGLETON_H diff --git a/public/cdll_int.h b/public/cdll_int.h index d3e6dc44..650e8fe5 100644 --- a/public/cdll_int.h +++ b/public/cdll_int.h @@ -59,6 +59,7 @@ class IFileList; class CRenamedRecvTableInfo; class CMouthInfo; class IConVar; +class ISPSharedMemory; //----------------------------------------------------------------------------- // Purpose: This data structure is filled in by the engine when the client .dll requests information about @@ -519,6 +520,9 @@ public: virtual uint OnStorageDeviceAttached( void ) = 0; virtual void OnStorageDeviceDetached( void ) = 0; + //Finds or Creates a shared memory space, the returned pointer will automatically be AddRef()ed + virtual ISPSharedMemory *GetSinglePlayerSharedMemorySpace( const char *szName, int ent_num = MAX_EDICTS ) = 0; + virtual void ResetDemoInterpolation( void ) = 0; // Methods to set/get a gamestats data container so client & server running in same process can send combined data diff --git a/public/closedcaptions.cpp b/public/closedcaptions.cpp new file mode 100644 index 00000000..01e0e2f3 --- /dev/null +++ b/public/closedcaptions.cpp @@ -0,0 +1,62 @@ +//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= +#include "closedcaptions.h" +#include "filesystem.h" +#include "tier1/utlbuffer.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// Assumed to be set up by calling code +bool AsyncCaption_t::LoadFromFile( char const *pchFullPath ) +{ + FileHandle_t fh = g_pFullFileSystem->Open( pchFullPath, "rb" ); + if ( FILESYSTEM_INVALID_HANDLE == fh ) + return false; + + MEM_ALLOC_CREDIT(); + + CUtlBuffer dirbuffer; + + // Read the header + g_pFullFileSystem->Read( &m_Header, sizeof( m_Header ), fh ); + if ( m_Header.magic != COMPILED_CAPTION_FILEID ) + { + if( IsPS3() ) + return false; + else + Error( "Invalid file id for %s\n", pchFullPath ); + } + if ( m_Header.version != COMPILED_CAPTION_VERSION ) + { + if( IsPS3() ) + return false; + else + Error( "Invalid file version for %s\n", pchFullPath ); + } + if ( m_Header.directorysize < 0 || m_Header.directorysize > 64 * 1024 ) + { + if( IsPS3() ) + return false; + else + Error( "Invalid directory size %d for %s\n", m_Header.directorysize, pchFullPath ); + } + //if ( m_Header.blocksize != MAX_BLOCK_SIZE ) + // Error( "Invalid block size %d, expecting %d for %s\n", m_Header.blocksize, MAX_BLOCK_SIZE, pchFullPath ); + + int directoryBytes = m_Header.directorysize * sizeof( CaptionLookup_t ); + m_CaptionDirectory.EnsureCapacity( m_Header.directorysize ); + dirbuffer.EnsureCapacity( directoryBytes ); + + g_pFullFileSystem->Read( dirbuffer.Base(), directoryBytes, fh ); + g_pFullFileSystem->Close( fh ); + + m_CaptionDirectory.CopyArray( (const CaptionLookup_t *)dirbuffer.PeekGet(), m_Header.directorysize ); + m_CaptionDirectory.RedoSort( true ); + + m_DataBaseFile = pchFullPath; + return true; +} diff --git a/public/closedcaptions.h b/public/closedcaptions.h new file mode 100644 index 00000000..a40da946 --- /dev/null +++ b/public/closedcaptions.h @@ -0,0 +1,70 @@ +//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +#ifndef CLOSEDCAPTIONS_H +#define CLOSEDCAPTIONS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "captioncompiler.h" +#include "tier1/utlsymbol.h" +#include "tier1/utlsortvector.h" + +FORWARD_DECLARE_HANDLE( memhandle_t ); + +typedef CUtlSortVector< CaptionLookup_t, CCaptionLookupLess > CaptionDictionary_t; +struct AsyncCaption_t +{ + AsyncCaption_t() : + m_DataBaseFile( UTL_INVAL_SYMBOL ), + m_RequestedBlocks( 0, 0, BlockInfo_t::Less ) + { + Q_memset( &m_Header, 0, sizeof( m_Header ) ); + } + + struct BlockInfo_t + { + int fileindex; + int blocknum; + memhandle_t handle; + + static bool Less( const BlockInfo_t& lhs, const BlockInfo_t& rhs ) + { + if ( lhs.fileindex != rhs.fileindex ) + return lhs.fileindex < rhs.fileindex; + + return lhs.blocknum < rhs.blocknum; + } + }; + + AsyncCaption_t& operator =( const AsyncCaption_t& rhs ) + { + if ( this == &rhs ) + return *this; + + m_CaptionDirectory = rhs.m_CaptionDirectory; + m_Header = rhs.m_Header; + m_DataBaseFile = rhs.m_DataBaseFile; + + for ( int i = rhs.m_RequestedBlocks.FirstInorder(); i != rhs.m_RequestedBlocks.InvalidIndex(); i = rhs.m_RequestedBlocks.NextInorder( i ) ) + { + m_RequestedBlocks.Insert( rhs.m_RequestedBlocks[ i ] ); + } + + return *this; + } + + bool LoadFromFile( char const *pchFullPath ); + + CUtlRBTree< BlockInfo_t, unsigned short > m_RequestedBlocks; + + CaptionDictionary_t m_CaptionDirectory; + CompiledCaptionHeader_t m_Header; + CUtlSymbol m_DataBaseFile; +}; + +#endif // CLOSEDCAPTIONS_H diff --git a/public/color.h b/public/color.h new file mode 100644 index 00000000..57bd5253 --- /dev/null +++ b/public/color.h @@ -0,0 +1,8 @@ +//========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "Color.h" diff --git a/public/datacache/iprecachesystem.h b/public/datacache/iprecachesystem.h new file mode 100644 index 00000000..fa21075f --- /dev/null +++ b/public/datacache/iprecachesystem.h @@ -0,0 +1,51 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// $NoKeywords: $ +//===========================================================================// + +#ifndef IPRECACHESYSTEM_H +#define IPRECACHESYSTEM_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier0/dbg.h" +#include "tier2/tier2.h" +#include "tier2/resourceprecacher.h" +#include "appframework/iappsystem.h" + +//----------------------------------------------------------------------------- +// Resource access control API +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// IResourceAccessControl +// Purpose: Maintains lists of resources to use them as filters to prevent access +// to ensure proper precache behavior in game code +//----------------------------------------------------------------------------- +abstract_class IPrecacheSystem : public IAppSystem +{ +public: + // Precaches/uncaches all resources used by a particular system + virtual void Cache( IPrecacheHandler *pPrecacheHandler, PrecacheSystem_t nSystem, + const char *pName, bool bPrecache, ResourceList_t hResourceList, bool bBuildResourceList ) = 0; + + virtual void UncacheAll( IPrecacheHandler *pPrecacheHandler ) = 0 ; + + virtual void Register( IResourcePrecacher *pResourcePrecacherFirst, PrecacheSystem_t nSystem ) = 0; + + // Limits resource access to only resources used by this particular system + // Use GLOBAL system, and NULL name to disable limited resource access + virtual void LimitResourceAccess( PrecacheSystem_t nSystem, const char *pName ) = 0; + virtual void EndLimitedResourceAccess() = 0; +}; + +DECLARE_TIER2_INTERFACE( IPrecacheSystem, g_pPrecacheSystem ); + + +#endif // IPRECACHESYSTEM_H diff --git a/public/datamap.h b/public/datamap.h index 2f4edbf5..79a0a352 100644 --- a/public/datamap.h +++ b/public/datamap.h @@ -249,6 +249,17 @@ typedef void (CBaseEntity::*inputfunc_t)(inputdata_t &data); struct datamap_t; struct typedescription_t; +#if 0 +enum +{ + PC_NON_NETWORKED_ONLY = 0, + PC_NETWORKED_ONLY, + + PC_COPYTYPE_COUNT, + PC_EVERYTHING = PC_COPYTYPE_COUNT, +}; +#endif + enum { TD_OFFSET_NORMAL = 0, diff --git a/public/edict.h b/public/edict.h index 37c701b4..6adc20b0 100644 --- a/public/edict.h +++ b/public/edict.h @@ -61,6 +61,7 @@ public: int maxEntities; int serverCount; + edict_t *pEdicts; }; inline CGlobalVars::CGlobalVars( bool bIsClient ) : diff --git a/public/eiface.h b/public/eiface.h index 0656427a..f86195f2 100644 --- a/public/eiface.h +++ b/public/eiface.h @@ -60,6 +60,7 @@ class CSteamID; class IReplayFactory; class IReplaySystem; class IServer; +class ISPSharedMemory; typedef struct player_info_s player_info_t; @@ -402,6 +403,10 @@ public: // Returns the SteamID of the specified player. It'll be NULL if the player hasn't authenticated yet. virtual const CSteamID *GetClientSteamIDByPlayerIndex( int entnum ) = 0; + + //Finds or Creates a shared memory space, the returned pointer will automatically be AddRef()ed + virtual ISPSharedMemory *GetSinglePlayerSharedMemorySpace( const char *szName, int ent_num = MAX_EDICTS ) = 0; + // Gets a list of all clusters' bounds. Returns total number of clusters. virtual int GetClusterCount() = 0; virtual int GetAllClusterBounds( bbox_t *pBBoxList, int maxBBox ) = 0; diff --git a/public/engine/ICollideable.h b/public/engine/ICollideable.h index 8906e5a4..a19800c0 100644 --- a/public/engine/ICollideable.h +++ b/public/engine/ICollideable.h @@ -32,8 +32,10 @@ public: // These methods return the bounds of an OBB measured in "collision" space // which can be retreived through the CollisionToWorldTransform or // GetCollisionOrigin/GetCollisionAngles methods +#if !SOURCE_ASW virtual const Vector& OBBMinsPreScaled() const = 0; virtual const Vector& OBBMaxsPreScaled() const = 0; +#endif virtual const Vector& OBBMins() const = 0; virtual const Vector& OBBMaxs() const = 0; diff --git a/public/igameevents.h b/public/igameevents.h index 7d5465ec..1d7ffd10 100644 --- a/public/igameevents.h +++ b/public/igameevents.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // @@ -75,24 +75,32 @@ public: // Data access virtual bool GetBool( const char *keyName = NULL, bool defaultValue = false ) = 0; virtual int GetInt( const char *keyName = NULL, int defaultValue = 0 ) = 0; + virtual uint64 GetUint64( const char *keyName = NULL, uint64 defaultValue = 0 ) = 0; virtual float GetFloat( const char *keyName = NULL, float defaultValue = 0.0f ) = 0; virtual const char *GetString( const char *keyName = NULL, const char *defaultValue = "" ) = 0; virtual void SetBool( const char *keyName, bool value ) = 0; virtual void SetInt( const char *keyName, int value ) = 0; + virtual void SetUint64( const char *keyName, uint64 value ) = 0; virtual void SetFloat( const char *keyName, float value ) = 0; virtual void SetString( const char *keyName, const char *value ) = 0; }; +#define EVENT_DEBUG_ID_INIT 42 +#define EVENT_DEBUG_ID_SHUTDOWN 13 abstract_class IGameEventListener2 { public: virtual ~IGameEventListener2( void ) {}; - // FireEvent is called by EventManager if event just occurred + // FireEvent is called by EventManager if event just occured // KeyValue memory will be freed by manager if not needed anymore virtual void FireGameEvent( IGameEvent *event ) = 0; + +#if SOURCE_ASW + virtual int GetEventDebugID( void ) = 0; +#endif }; abstract_class IGameEventManager2 : public IBaseInterface @@ -117,7 +125,7 @@ public: // create an event by name, but doesn't fire it. returns NULL is event is not // known or no listener is registered for it. bForce forces the creation even if no listener is active - virtual IGameEvent *CreateEvent( const char *name, bool bForce = false ) = 0; + virtual IGameEvent *CreateEvent( const char *name, bool bForce = false, int *pCookie = NULL ) = 0; // fires a server event created earlier, if bDontBroadcast is set, event is not send to clients virtual bool FireEvent( IGameEvent *event, bool bDontBroadcast = false ) = 0; @@ -143,7 +151,7 @@ abstract_class IGameEventListener public: virtual ~IGameEventListener( void ) {}; - // FireEvent is called by EventManager if event just occurred + // FireEvent is called by EventManager if event just occured // KeyValue memory will be freed by manager if not needed anymore virtual void FireGameEvent( KeyValues * event) = 0; }; diff --git a/public/ispsharedmemory.h b/public/ispsharedmemory.h new file mode 100644 index 00000000..ce074eff --- /dev/null +++ b/public/ispsharedmemory.h @@ -0,0 +1,27 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +//===========================================================================// + +#ifndef ISPSHAREDMEMORY_H +#define ISPSHAREDMEMORY_H +#ifdef _WIN32 +#pragma once +#endif + +#include "basetypes.h" +#include "platform.h" + +abstract_class ISPSharedMemory +{ +public: + virtual bool Init( size_t iSize ) = 0; //Initial implementation assumes the size is fixed/hardcoded, returns true if this call actually created the memory, false if it already existed + virtual uint8 * Base( void ) = 0; + virtual size_t Size( void ) = 0; + + virtual void AddRef( void ) = 0; + virtual void Release( void ) = 0; +}; + +#endif diff --git a/public/networkvar.cpp b/public/networkvar.cpp index 65cb1d6a..e96947c3 100644 --- a/public/networkvar.cpp +++ b/public/networkvar.cpp @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // diff --git a/public/networkvar.h b/public/networkvar.h index 046cb5f3..5cd16450 100644 --- a/public/networkvar.h +++ b/public/networkvar.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // @@ -21,9 +21,10 @@ #pragma warning( disable : 4284 ) // warning C4284: return type for 'CNetworkVarT::operator ->' is 'int *' (ie; not a UDT or reference to a UDT. Will produce errors if applied using infix notation) -#define MyOffsetOf( type, var ) ( (intp)&((type*)0)->var ) +#define MyOffsetOf( type, var ) ( (int)&((type*)0)->var ) #ifdef _DEBUG + #undef new extern bool g_bUseNetworkVars; #define CHECK_USENETWORKVARS if(g_bUseNetworkVars) #else @@ -32,6 +33,44 @@ +// network vars use memcmp when fields are set. To ensure proper behavior your +// object's memory should be initialized to zero. This happens for entities automatically +// use this for other classes. +class CMemZeroOnNew +{ +public: + void *operator new( size_t nSize ) + { + void *pMem = MemAlloc_Alloc( nSize ); + V_memset( pMem, 0, nSize ); + return pMem; + } + + void* operator new( size_t nSize, int nBlockUse, const char *pFileName, int nLine ) + { + void *pMem = MemAlloc_Alloc( nSize, pFileName, nLine ); + V_memset( pMem, 0, nSize ); + return pMem; + } + + void operator delete(void *pData) + { + if ( pData ) + { + g_pMemAlloc->Free(pData); + } + } + + void operator delete( void* pData, int nBlockUse, const char *pFileName, int nLine ) + { + if ( pData ) + { + g_pMemAlloc->Free(pData, pFileName, nLine ); + } + } +}; + + inline int InternalCheckDeclareClass( const char *pClassName, const char *pClassNameMatch, void *pTestPtr, void *pBasePtr ) { // This makes sure that casting from ThisClass to BaseClass works right. You'll get a compiler error if it doesn't @@ -166,6 +205,7 @@ static inline void DispatchNetworkStateChanged( T *pObj, void *pVar ) template< class T > NetworkVar_##name& operator=( const T &val ) { *((type*)this) = val; return *this; } \ public: \ void CopyFrom( const type &src ) { *((type *)this) = src; NetworkStateChanged(); } \ + type & GetForModify( void ) { NetworkStateChanged(); return *((type *)this); } \ virtual void NetworkStateChanged() \ { \ DispatchNetworkStateChanged( (ThisClass_##name*)( ((char*)this) - GetOffset_##name() ) ); \ @@ -177,34 +217,32 @@ static inline void DispatchNetworkStateChanged( T *pObj, void *pVar ) }; \ NetworkVar_##name name; -template -FORCEINLINE void NetworkVarConstruct( T &x ) { x = T(0); } -FORCEINLINE void NetworkVarConstruct( color32_s &x ) { x.r = x.g = x.b = x.a = 0; } + template< class Type, class Changer > class CNetworkVarBase { public: - inline CNetworkVarBase() + CNetworkVarBase() { - NetworkVarConstruct( m_Value ); } - template< class C > - const Type& operator=( const C &val ) - { - return Set( ( const Type )val ); - } - - template< class C > - const Type& operator=( const CNetworkVarBase< C, Changer > &val ) - { - return Set( ( const Type )val.m_Value ); - } - - const Type& Set( const Type &val ) + FORCEINLINE explicit CNetworkVarBase( Type val ) + : m_Value( val ) { - if ( memcmp( &m_Value, &val, sizeof(Type) ) ) + NetworkStateChanged(); + } + + FORCEINLINE const Type& SetDirect( const Type &val ) + { + NetworkStateChanged(); + m_Value = val; + return m_Value; + } + + FORCEINLINE const Type& Set( const Type &val ) + { + if ( m_Value != val ) { NetworkStateChanged(); m_Value = val; @@ -212,66 +250,78 @@ public: return m_Value; } - Type& GetForModify() + template< class C > + FORCEINLINE const Type& operator=( const C &val ) + { + return Set( ( const Type )val ); + } + + template< class C > + FORCEINLINE const Type& operator=( const CNetworkVarBase< C, Changer > &val ) + { + return Set( ( const Type )val.m_Value ); + } + + FORCEINLINE Type& GetForModify() { NetworkStateChanged(); return m_Value; } template< class C > - const Type& operator+=( const C &val ) + FORCEINLINE const Type& operator+=( const C &val ) { return Set( m_Value + ( const Type )val ); } template< class C > - const Type& operator-=( const C &val ) + FORCEINLINE const Type& operator-=( const C &val ) { return Set( m_Value - ( const Type )val ); } template< class C > - const Type& operator/=( const C &val ) + FORCEINLINE const Type& operator/=( const C &val ) { return Set( m_Value / ( const Type )val ); } template< class C > - const Type& operator*=( const C &val ) + FORCEINLINE const Type& operator*=( const C &val ) { return Set( m_Value * ( const Type )val ); } template< class C > - const Type& operator^=( const C &val ) + FORCEINLINE const Type& operator^=( const C &val ) { return Set( m_Value ^ ( const Type )val ); } template< class C > - const Type& operator|=( const C &val ) + FORCEINLINE const Type& operator|=( const C &val ) { return Set( m_Value | ( const Type )val ); } - const Type& operator++() + FORCEINLINE const Type& operator++() { return (*this += 1); } - Type operator--() + FORCEINLINE Type operator--() { return (*this -= 1); } - Type operator++( int ) // postfix version.. + FORCEINLINE Type operator++( int ) // postfix version.. { Type val = m_Value; (*this += 1); return val; } - Type operator--( int ) // postfix version.. + FORCEINLINE Type operator--( int ) // postfix version.. { Type val = m_Value; (*this -= 1); @@ -282,22 +332,22 @@ public: // CNetworkVarBase = 0x1 // (it warns about converting from an int to an unsigned char). template< class C > - const Type& operator&=( const C &val ) + FORCEINLINE const Type& operator&=( const C &val ) { return Set( m_Value & ( const Type )val ); } - operator const Type&() const + FORCEINLINE operator const Type&() const { return m_Value; } - const Type& Get() const + FORCEINLINE const Type& Get() const { return m_Value; } - const Type* operator->() const + FORCEINLINE const Type* operator->() const { return &m_Value; } @@ -305,16 +355,16 @@ public: Type m_Value; protected: - inline void NetworkStateChanged() + FORCEINLINE void NetworkStateChanged() { Changer::NetworkStateChanged( this ); } }; - template< class Type, class Changer > class CNetworkColor32Base : public CNetworkVarBase< Type, Changer > { + typedef CNetworkVarBase< Type, Changer > base; public: inline void Init( byte rVal, byte gVal, byte bVal ) { @@ -332,29 +382,29 @@ public: const Type& operator=( const Type &val ) { - return this->Set( val ); + return Set( val ); } const Type& operator=( const CNetworkColor32Base &val ) { - return CNetworkVarBase::Set( val.m_Value ); + return base::Set( val.m_Value ); } - inline byte GetR() const { return CNetworkColor32Base::m_Value.r; } - inline byte GetG() const { return CNetworkColor32Base::m_Value.g; } - inline byte GetB() const { return CNetworkColor32Base::m_Value.b; } - inline byte GetA() const { return CNetworkColor32Base::m_Value.a; } - inline void SetR( byte val ) { SetVal( CNetworkColor32Base::m_Value.r, val ); } - inline void SetG( byte val ) { SetVal( CNetworkColor32Base::m_Value.g, val ); } - inline void SetB( byte val ) { SetVal( CNetworkColor32Base::m_Value.b, val ); } - inline void SetA( byte val ) { SetVal( CNetworkColor32Base::m_Value.a, val ); } + inline byte GetR() const { return this->m_Value.r; } + inline byte GetG() const { return this->m_Value.g; } + inline byte GetB() const { return this->m_Value.b; } + inline byte GetA() const { return this->m_Value.a; } + inline void SetR( byte val ) { SetVal( this->m_Value.r, val ); } + inline void SetG( byte val ) { SetVal( this->m_Value.g, val ); } + inline void SetB( byte val ) { SetVal( this->m_Value.b, val ); } + inline void SetA( byte val ) { SetVal( this->m_Value.a, val ); } protected: inline void SetVal( byte &out, const byte &in ) { if ( out != in ) { - CNetworkVarBase< Type, Changer >::NetworkStateChanged(); + this->NetworkStateChanged(); out = in; } } @@ -365,80 +415,79 @@ protected: template< class Type, class Changer > class CNetworkVectorBase : public CNetworkVarBase< Type, Changer > { + typedef CNetworkVarBase< Type, Changer > base; public: - inline void Init( float ix=0, float iy=0, float iz=0 ) + FORCEINLINE void Init( float ix=0, float iy=0, float iz=0 ) { - SetX( ix ); - SetY( iy ); - SetZ( iz ); + base::Set( Type( ix, iy, iz ) ); } - const Type& operator=( const Type &val ) + FORCEINLINE const Type& operator=( const Type &val ) { - return CNetworkVarBase< Type, Changer >::Set( val ); + return base::Set( val ); } - const Type& operator=( const CNetworkVectorBase &val ) + FORCEINLINE const Type& operator=( const CNetworkVectorBase &val ) { - return CNetworkVarBase::Set( val.m_Value ); + return base::Set( val.m_Value ); } - inline float GetX() const { return CNetworkVectorBase::m_Value.x; } - inline float GetY() const { return CNetworkVectorBase::m_Value.y; } - inline float GetZ() const { return CNetworkVectorBase::m_Value.z; } - inline float operator[]( int i ) const { return CNetworkVectorBase::m_Value[i]; } + FORCEINLINE float GetX() const { return this->m_Value.x; } + FORCEINLINE float GetY() const { return this->m_Value.y; } + FORCEINLINE float GetZ() const { return this->m_Value.z; } + FORCEINLINE float operator[]( int i ) const { return this->m_Value[i]; } - inline void SetX( float val ) { DetectChange( CNetworkVectorBase::m_Value.x, val ); } - inline void SetY( float val ) { DetectChange( CNetworkVectorBase::m_Value.y, val ); } - inline void SetZ( float val ) { DetectChange( CNetworkVectorBase::m_Value.z, val ); } - inline void Set( int i, float val ) { DetectChange( CNetworkVectorBase::m_Value[i], val ); } + FORCEINLINE void SetX( float val ) { DetectChange( this->m_Value.x, val ); } + FORCEINLINE void SetY( float val ) { DetectChange( this->m_Value.y, val ); } + FORCEINLINE void SetZ( float val ) { DetectChange( this->m_Value.z, val ); } + FORCEINLINE void Set( int i, float val ) { DetectChange( this->m_Value[i], val ); } - bool operator==( const Type &val ) const + FORCEINLINE bool operator==( const Type &val ) const { - return CNetworkVectorBase::m_Value == (Type)val; + return this->m_Value == (Type)val; } - bool operator!=( const Type &val ) const + FORCEINLINE bool operator!=( const Type &val ) const { - return CNetworkVectorBase::m_Value != (Type)val; + return this->m_Value != (Type)val; } - const Type operator+( const Type &val ) const + FORCEINLINE const Type operator+( const Type &val ) const { - return CNetworkVectorBase::m_Value + val; + return this->m_Value + val; } - const Type operator-( const Type &val ) const + FORCEINLINE const Type operator-( const Type &val ) const { - return CNetworkVectorBase::m_Value - val; + return this->m_Value - val; } - const Type operator*( const Type &val ) const + FORCEINLINE const Type operator*( const Type &val ) const { - return CNetworkVectorBase::m_Value * val; + return this->m_Value * val; } - const Type& operator*=( float val ) + FORCEINLINE const Type& operator*=( float val ) { - return CNetworkVarBase< Type, Changer >::Set( CNetworkVectorBase::m_Value * val ); + return base::Set( this->m_Value * val ); } - const Type operator*( float val ) const + FORCEINLINE const Type operator*( float val ) const { - return CNetworkVectorBase::m_Value * val; + return this->m_Value * val; } - const Type operator/( const Type &val ) const + FORCEINLINE const Type operator/( const Type &val ) const { - return CNetworkVectorBase::m_Value / val; + return this->m_Value / val; } private: - inline void DetectChange( float &out, float in ) + FORCEINLINE void DetectChange( float &out, float in ) { if ( out != in ) { - CNetworkVectorBase::NetworkStateChanged(); + this->NetworkStateChanged(); out = in; } } @@ -449,75 +498,73 @@ private: template< class Type, class Changer > class CNetworkQuaternionBase : public CNetworkVarBase< Type, Changer > { + typedef CNetworkVarBase< Type, Changer > base; public: inline void Init( float ix=0, float iy=0, float iz=0, float iw = 0 ) { - SetX( ix ); - SetY( iy ); - SetZ( iz ); - SetW( iw ); + base::Set( Quaternion( ix, iy, iz, iw ) ); } const Type& operator=( const Type &val ) { - return CNetworkVarBase< Type, Changer >::Set( val ); + return Set( val ); } const Type& operator=( const CNetworkQuaternionBase &val ) { - return CNetworkVarBase::Set( val.m_Value ); + return Set( val.m_Value ); } - inline float GetX() const { return CNetworkQuaternionBase::m_Value.x; } - inline float GetY() const { return CNetworkQuaternionBase::m_Value.y; } - inline float GetZ() const { return CNetworkQuaternionBase::m_Value.z; } - inline float GetW() const { return CNetworkQuaternionBase::m_Value.w; } - inline float operator[]( int i ) const { return CNetworkQuaternionBase::m_Value[i]; } + inline float GetX() const { return this->m_Value.x; } + inline float GetY() const { return this->m_Value.y; } + inline float GetZ() const { return this->m_Value.z; } + inline float GetW() const { return this->m_Value.w; } + inline float operator[]( int i ) const { return this->m_Value[i]; } - inline void SetX( float val ) { DetectChange( CNetworkQuaternionBase::m_Value.x, val ); } - inline void SetY( float val ) { DetectChange( CNetworkQuaternionBase::m_Value.y, val ); } - inline void SetZ( float val ) { DetectChange( CNetworkQuaternionBase::m_Value.z, val ); } - inline void SetW( float val ) { DetectChange( CNetworkQuaternionBase::m_Value.w, val ); } - inline void Set( int i, float val ) { DetectChange( CNetworkQuaternionBase::m_Value[i], val ); } + inline void SetX( float val ) { DetectChange( this->m_Value.x, val ); } + inline void SetY( float val ) { DetectChange( this->m_Value.y, val ); } + inline void SetZ( float val ) { DetectChange( this->m_Value.z, val ); } + inline void SetW( float val ) { DetectChange( this->m_Value.w, val ); } + inline void Set( int i, float val ) { DetectChange( this->m_Value[i], val ); } bool operator==( const Type &val ) const { - return CNetworkQuaternionBase::m_Value == (Type)val; + return this->m_Value == (Type)val; } bool operator!=( const Type &val ) const { - return CNetworkQuaternionBase::m_Value != (Type)val; + return this->m_Value != (Type)val; } const Type operator+( const Type &val ) const { - return CNetworkQuaternionBase::m_Value + val; + return this->m_Value + val; } const Type operator-( const Type &val ) const { - return CNetworkQuaternionBase::m_Value - val; + return this->m_Value - val; } const Type operator*( const Type &val ) const { - return CNetworkQuaternionBase::m_Value * val; + return this->m_Value * val; } const Type& operator*=( float val ) { - return CNetworkQuaternionBase< Type, Changer >::Set( CNetworkQuaternionBase::m_Value * val ); + return Set( this->m_Value * val ); } const Type operator*( float val ) const { - return CNetworkQuaternionBase::m_Value * val; + return this->m_Value * val; } const Type operator/( const Type &val ) const { - return CNetworkQuaternionBase::m_Value / val; + return this->m_Value / val; } private: @@ -525,7 +572,7 @@ private: { if ( out != in ) { - CNetworkQuaternionBase::NetworkStateChanged(); + this->NetworkStateChanged(); out = in; } } @@ -534,11 +581,10 @@ private: // Network ehandle wrapper. #if defined( CLIENT_DLL ) || defined( GAME_DLL ) - inline void NetworkVarConstruct( CBaseHandle &x ) {} - template< class Type, class Changer > class CNetworkHandleBase : public CNetworkVarBase< CBaseHandle, Changer > { + typedef CNetworkVarBase< CBaseHandle, Changer > base; public: const Type* operator=( const Type *val ) { @@ -553,12 +599,12 @@ private: bool operator !() const { - return !CNetworkHandleBase::m_Value.Get(); + return !this->m_Value.Get(); } operator Type*() const { - return static_cast< Type* >( CNetworkHandleBase::m_Value.Get() ); + return static_cast< Type* >( this->m_Value.Get() ); } const Type* Set( const Type *val ) @@ -678,7 +724,6 @@ private: class NetworkVar_##name \ { \ public: \ - NetworkVar_##name() { m_Value[0] = '\0'; } \ operator const char*() const { return m_Value; } \ const char* Get() const { return m_Value; } \ char* GetForModify() \ @@ -708,11 +753,6 @@ private: class NetworkVar_##name \ { \ public: \ - inline NetworkVar_##name() \ - { \ - for ( int i = 0 ; i < count ; ++i ) \ - NetworkVarConstruct( m_Value[i] ); \ - } \ template friend int ServerClassInit(T *); \ const type& operator[]( int i ) const \ { \ @@ -743,12 +783,12 @@ private: } \ const type* Base() const { return m_Value; } \ int Count() const { return count; } \ - protected: \ - inline void NetworkStateChanged( int net_change_index ) \ - { \ - CHECK_USENETWORKVARS ((ThisClass*)(((char*)this) - MyOffsetOf(ThisClass,name)))->stateChangedFn( &m_Value[net_change_index] ); \ - } \ type m_Value[count]; \ + protected: \ + inline void NetworkStateChanged( int index ) \ + { \ + CHECK_USENETWORKVARS ((ThisClass*)(((char*)this) - MyOffsetOf(ThisClass,name)))->stateChangedFn( &m_Value[index] ); \ + } \ }; \ NetworkVar_##name name; diff --git a/public/networkvar_vector.h b/public/networkvar_vector.h new file mode 100644 index 00000000..745ce186 --- /dev/null +++ b/public/networkvar_vector.h @@ -0,0 +1,341 @@ +//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== +// +// Included by networkvar.h +// +//================================================================================================== + +#ifndef NETWORKVAR_VECTOR_H +#define NETWORKVAR_VECTOR_H +#ifdef _WIN32 +#pragma once +#endif + + +// This is the normal case.. you've got a SendPropVector to match your CNetworkVector +#define CNetworkVector( name ) CNetworkVectorInternal( Vector, name, NetworkStateChanged, CNetworkVectorBase ) + +// This variant of a CNetworkVector should be used if you want to use SendPropFloat +// on each individual component of the vector. +#define CNetworkVectorXYZ( name ) CNetworkVectorInternal( Vector, name, NetworkStateChanged, CNetworkVectorXYZBase ) + +// This variant of a CNetworkVector should be used if you want to use SendPropVectorXY +// for the XY components and SendPropFloat for the Z component. +#define CNetworkVectorXY_SeparateZ( name ) CNetworkVectorInternal( Vector, name, NetworkStateChanged, CNetworkVectorXY_SeparateZBase ) + + + +// This is the normal case.. you've got a SendPropQAngle to match your CNetworkQAngle +#define CNetworkQAngle( name ) CNetworkVectorInternal( QAngle, name, NetworkStateChanged, CNetworkVectorBase ) + +// This variant of a CNetworkQAngle should be used if you want to use SendPropFloat +// on each individual component of the vector. +#define CNetworkQAngleXYZ( name ) CNetworkVectorInternal( QAngle, name, NetworkStateChanged, CNetworkVectorXYZBase ) + + + +// +// Use these variants if you want the networkvar to not trigger a change in the baseclass +// version but you might want it to trigger changes in derived classes that do network that variable. +// +#define CNetworkVectorForDerived( name ) \ + virtual void NetworkStateChanged_##name() {} \ + virtual void NetworkStateChanged_##name( void *pVar ) {} \ + CNetworkVectorInternal( Vector, name, NetworkStateChanged_##name, CNetworkVectorBase ) + +#define CNetworkVectorXYZForDerived( name ) \ + virtual void NetworkStateChanged_##name() {} \ + virtual void NetworkStateChanged_##name( void *pVar ) {} \ + CNetworkVectorInternal( Vector, name, NetworkStateChanged_##name, CNetworkVectorXYZBase ) + + + + +#define CNetworkVectorInternal( type, name, stateChangedFn, baseClass ) \ + NETWORK_VAR_START( type, name ) \ + NETWORK_VAR_END( type, name, baseClass, stateChangedFn ) + + + +// Network vector wrapper. +// +// The common base is shared between all CNetworkVectors. +// It includes everything but the Set() and operator=() functions, +// because the behavior of each of those is different for each vector type. +template< class Type, class Changer > +class CNetworkVectorCommonBase : public CNetworkVarBase< Type, Changer > +{ + typedef CNetworkVarBase< Type, Changer > base; +public: + + FORCEINLINE void Init( float ix=0, float iy=0, float iz=0 ) + { + base::Set( Type( ix, iy, iz ) ); + } + + FORCEINLINE float GetX() const { return this->m_Value.x; } + FORCEINLINE float GetY() const { return this->m_Value.y; } + FORCEINLINE float GetZ() const { return this->m_Value.z; } + FORCEINLINE float operator[]( int i ) const { return this->m_Value[i]; } + + FORCEINLINE bool operator==( const Type &val ) const + { + return this->m_Value == (Type)val; + } + + FORCEINLINE bool operator!=( const Type &val ) const + { + return this->m_Value != (Type)val; + } + + FORCEINLINE const Type operator+( const Type &val ) const + { + return this->m_Value + val; + } + + FORCEINLINE const Type operator-( const Type &val ) const + { + return this->m_Value - val; + } + + FORCEINLINE const Type operator*( const Type &val ) const + { + return this->m_Value * val; + } + + FORCEINLINE const Type& operator*=( float val ) + { + return base::Set( this->m_Value * val ); + } + + FORCEINLINE const Type operator*( float val ) const + { + return this->m_Value * val; + } + + FORCEINLINE const Type operator/( const Type &val ) const + { + return this->m_Value / val; + } + +protected: + FORCEINLINE void DetectChange( float &out, float in ) + { + if ( out != in ) + { + this->NetworkStateChanged(); + out = in; + } + } +}; + + + +// +// This is for a CNetworkVector that only generates one change offset. +// It should only ever be used with SendPropVector/QAngle. +// +// Single-component things like SendPropFloat should never refer to it because +// they require the network var to report an offset for each component. +// +template< class Type, class Changer > +class CNetworkVectorBase : public CNetworkVectorCommonBase< Type, Changer > +{ + typedef CNetworkVarBase< Type, Changer > base; +public: + static FORCEINLINE int GetNetworkVarFlags() { return NETWORKVAR_IS_A_VECTOR; } + + FORCEINLINE const Type& operator=( const Type &val ) + { + return base::Set( val ); + } + + FORCEINLINE const Type& operator=( const CNetworkVectorBase &val ) + { + return base::Set( val.m_Value ); + } + FORCEINLINE void SetX( float val ) { this->DetectChange( this->m_Value.x, val ); } + FORCEINLINE void SetY( float val ) { this->DetectChange( this->m_Value.y, val ); } + FORCEINLINE void SetZ( float val ) { this->DetectChange( this->m_Value.z, val ); } + FORCEINLINE void Set( int i, float val ) { this->DetectChange( this->m_Value[i], val ); } + + FORCEINLINE const Type& operator*=( float val ) + { + return base::Set( this->m_Value * val ); + } +}; + + +// +// This variant of a CNetworkVector should be used if you want to use SendPropFloat +// on each individual component of the vector. +// +template< class Type, class Changer > +class CNetworkVectorXYZBase : public CNetworkVectorCommonBase< Type, Changer > +{ + typedef CNetworkVectorCommonBase< Type, Changer > base; +public: + + static FORCEINLINE int GetNetworkVarFlags() { return NETWORKVAR_IS_A_VECTOR | NETWORKVAR_VECTOR_XYZ_FLAG; } + + FORCEINLINE const Type& operator=( const Type &val ) + { + return Set( val ); + } + + FORCEINLINE const Type& operator=( const CNetworkVectorBase &val ) + { + return Set( val.m_Value ); + } + + FORCEINLINE const Type& Set( const Type &val ) + { + SetX( val.x ); + SetY( val.y ); + SetZ( val.z ); + + return this->m_Value; + } + + FORCEINLINE Type& GetForModify() + { + this->NetworkStateChanged( &((float*)this)[0] ); + this->NetworkStateChanged( &((float*)this)[1] ); + this->NetworkStateChanged( &((float*)this)[2] ); + return this->m_Value; + } + + FORCEINLINE const Type& SetDirect( const Type &val ) + { + GetForModify() = val; + return this->m_Value; + } + + FORCEINLINE void SetX( float val ) { DetectChange( 0, val ); } + FORCEINLINE void SetY( float val ) { DetectChange( 1, val ); } + FORCEINLINE void SetZ( float val ) { DetectChange( 2, val ); } + FORCEINLINE void Set( int i, float val ) { DetectChange( i, val ); } + + FORCEINLINE const Type& operator+=( const Type &val ) + { + return Set( this->m_Value + val ); + } + + FORCEINLINE const Type& operator-=( const Type &val ) + { + return Set( this->m_Value - val ); + } + + FORCEINLINE const Type& operator*=( float val ) + { + return Set( this->m_Value * val ); + } + + FORCEINLINE const Type& operator/=( float val ) + { + return Set( this->m_Value / val ); + } + +private: + FORCEINLINE void DetectChange( int nComponent, float in ) + { + float *pVar = &((float*)this)[nComponent]; + if ( *pVar != in ) + { + if ( pVar != &((float*)this)[0] ) + { + this->NetworkStateChanged( &((float*)this)[0] ); // Always mark the start of the vector as changed + } + this->NetworkStateChanged( pVar ); + *pVar = in; + } + } +}; + + + +// +// This variant of a CNetworkVector should be used if you want to use SendPropVectorXY +// for the XY components and SendPropFloat for the Z component. +// +template< class Type, class Changer > +class CNetworkVectorXY_SeparateZBase : public CNetworkVectorCommonBase< Type, Changer > +{ + typedef CNetworkVectorCommonBase< Type, Changer > base; +public: + + static FORCEINLINE int GetNetworkVarFlags() { return NETWORKVAR_IS_A_VECTOR | NETWORKVAR_VECTOR_XY_SEPARATEZ_FLAG; } + + FORCEINLINE const Type& operator=( const Type &val ) + { + return Set( val ); + } + + FORCEINLINE const Type& operator=( const CNetworkVectorBase &val ) + { + return Set( val.m_Value ); + } + + FORCEINLINE const Type& Set( const Type &val ) + { + SetX( val.x ); + SetY( val.y ); + SetZ( val.z ); + + return this->m_Value; + } + + FORCEINLINE Type& GetForModify() + { + this->NetworkStateChanged( &((float*)this)[0] ); // Mark the offset of our XY SendProp as changed. + this->NetworkStateChanged( &((float*)this)[2] ); // Mark the offset of our Z SendProp as changed. + return this->m_Value; + } + + FORCEINLINE const Type& SetDirect( const Type &val ) + { + GetForModify() = val; + return this->m_Value; + } + + FORCEINLINE void SetX( float val ) { DetectChange( 0, val ); } + FORCEINLINE void SetY( float val ) { DetectChange( 1, val ); } + FORCEINLINE void SetZ( float val ) { DetectChange( 2, val ); } + FORCEINLINE void Set( int i, float val ) { DetectChange( i, val ); } + + FORCEINLINE const Type& operator+=( const Type &val ) + { + return Set( this->m_Value + val ); + } + + FORCEINLINE const Type& operator-=( const Type &val ) + { + return Set( this->m_Value - val ); + } + + FORCEINLINE const Type& operator*=( float val ) + { + return Set( this->m_Value * val ); + } + + FORCEINLINE const Type& operator/=( float val ) + { + return Set( this->m_Value / val ); + } + +private: + FORCEINLINE void DetectChange( int nComponent, float in ) + { + float *pVar = &((float*)this)[nComponent]; + if ( *pVar != in ) + { + this->NetworkStateChanged( &((float*)this)[0] ); // Mark the offset of our XY SendProp as changed. + this->NetworkStateChanged( &((float*)this)[2] ); // Mark the offset of our Z SendProp as changed. + + *pVar = in; + } + } +}; + + +#endif // NETWORKVAR_VECTOR_H + diff --git a/public/tier0/logging.h b/public/tier0/logging.h new file mode 100644 index 00000000..47bf4e0b --- /dev/null +++ b/public/tier0/logging.h @@ -0,0 +1,768 @@ +//============ Copyright (c) Valve Corporation, All rights reserved. ============ +// +// Logging system declarations. +// +// The logging system is a channel-based output mechanism which allows +// subsystems to route their text/diagnostic output to various listeners +// +//=============================================================================== + +#ifndef LOGGING_H +#define LOGGING_H + +#if !defined(__SPU__) + +#if defined( COMPILER_MSVC ) +#pragma once +#endif + +#include "color.h" +#include "icommandline.h" +#include + +// For XBX_** functions +#if defined( _X360 ) +#include "xbox/xbox_console.h" +#endif + +// Used by CColorizedLoggingListener +#if defined( _WIN32 ) || (defined(POSIX) && !defined(_GAMECONSOLE)) +#include "tier0/win32consoleio.h" +#endif + +/* + ---- Logging System ---- + + The logging system is a channel-based mechanism for all code (engine, + mod, tool) across all platforms to output information, warnings, + errors, etc. + + This system supersedes the existing Msg(), Warning(), Error(), DevMsg(), ConMsg() etc. functions. + There are channels defined in the new system through which all old messages are routed; + see LOG_GENERAL, LOG_CONSOLE, LOG_DEVELOPER, etc. + + To use the system, simply call one of the predefined macros: + + Log_Msg( ChannelID, [Color], Message, ... ) + Log_Warning( ChannelID, [Color], Message, ... ) + Log_Error( ChannelID, [Color], Message, ... ) + + A ChannelID is typically created by defining a logging channel with the + log channel macros: + + DEFINE_LOGGING_CHANNEL_NO_TAGS( LOG_ChannelName, "ChannelName", [Flags], [MinimumSeverity], [Color] ); + + or + + BEGIN_DEFINE_LOGGING_CHANNEL( LOG_ChannelName, "ChannelName", [Flags], [MinimumSeverity], [Color] ); + ADD_LOGGING_CHANNEL_TAG( "Tag1" ); + ADD_LOGGING_CHANNEL_TAG( "Tag2" ); + END_DEFINE_LOGGING_CHANNEL(); + + These macros create a global channel ID variable with the name specified + by the first parameter (in this example, LOG_ChannelName). This channel ID + can be used by various LoggingSystem_** functions to manipulate the channel settings. + + The optional [Flags] parameter is an OR'd together set of LoggingChannelFlags_t + values (default: 0). + + The optional [MinimumSeverity] parameter is the lowest threshold + above which messages will be processed (inclusive). The default is LS_MESSAGE, + which results in all messages, warnings, and errors being logged. + Variadic parameters to the Log_** functions will be ignored if a channel + is not enabled for a given severity (for performance reasons). + + Logging channels can have their minimum severity modified by name, ID, or tag. + + Logging channels are not hierarchical since there are situations in which + a channel needs to belong to multiple hierarchies. Use tags to create + categories or shallow hierarchies. + + @TODO (Feature wishlist): + 1) Callstack logging support + 2) Registering dynamic channels and unregistering channels at runtime + 3) Sentient robot to clean up the thousands of places using the old/legacy logging system. +*/ + +////////////////////////////////////////////////////////////////////////// +// Constants, Types, Forward Declares +////////////////////////////////////////////////////////////////////////// + +class CLoggingSystem; +class CThreadFastMutex; + +//----------------------------------------------------------------------------- +// Maximum length of a sprintf'ed logging message. +//----------------------------------------------------------------------------- +const int MAX_LOGGING_MESSAGE_LENGTH = 2048; + +//----------------------------------------------------------------------------- +// Maximum length of a channel or tag name. +//----------------------------------------------------------------------------- +const int MAX_LOGGING_IDENTIFIER_LENGTH = 32; + +//----------------------------------------------------------------------------- +// Maximum number of logging channels. Increase if needed. +//----------------------------------------------------------------------------- +const int MAX_LOGGING_CHANNEL_COUNT = 256; + +//----------------------------------------------------------------------------- +// Maximum number of logging tags across all channels. Increase if needed. +//----------------------------------------------------------------------------- +const int MAX_LOGGING_TAG_COUNT = 1024; + +//----------------------------------------------------------------------------- +// Maximum number of characters across all logging tags. Increase if needed. +//----------------------------------------------------------------------------- +const int MAX_LOGGING_TAG_CHARACTER_COUNT = 8192; + +//----------------------------------------------------------------------------- +// Maximum number of concurrent logging listeners in a given logging state. +//----------------------------------------------------------------------------- +const int MAX_LOGGING_LISTENER_COUNT = 16; + +//----------------------------------------------------------------------------- +// An invalid color set on a channel to imply that it should use +// a device-dependent default color where applicable. +//----------------------------------------------------------------------------- +const Color UNSPECIFIED_LOGGING_COLOR( 0, 0, 0, 0 ); + +//----------------------------------------------------------------------------- +// An ID returned by the logging system to refer to a logging channel. +//----------------------------------------------------------------------------- +typedef int LoggingChannelID_t; + +//----------------------------------------------------------------------------- +// A sentinel value indicating an invalid logging channel ID. +//----------------------------------------------------------------------------- +const LoggingChannelID_t INVALID_LOGGING_CHANNEL_ID = -1; + +//----------------------------------------------------------------------------- +// The severity of a logging operation. +//----------------------------------------------------------------------------- +enum LoggingSeverity_t +{ + //----------------------------------------------------------------------------- + // An informative logging message. + //----------------------------------------------------------------------------- + LS_MESSAGE = 0, + + //----------------------------------------------------------------------------- + // A warning, typically non-fatal + //----------------------------------------------------------------------------- + LS_WARNING = 1, + + //----------------------------------------------------------------------------- + // A message caused by an Assert**() operation. + //----------------------------------------------------------------------------- + LS_ASSERT = 2, + + //----------------------------------------------------------------------------- + // An error, typically fatal/unrecoverable. + //----------------------------------------------------------------------------- + LS_ERROR = 3, + + //----------------------------------------------------------------------------- + // A placeholder level, higher than any legal value. + // Not a real severity value! + //----------------------------------------------------------------------------- + LS_HIGHEST_SEVERITY = 4, +}; + +//----------------------------------------------------------------------------- +// Action which should be taken by logging system as a result of +// a given logged message. +// +// The logging system invokes ILoggingResponsePolicy::OnLog() on +// the specified policy object, which returns a LoggingResponse_t. +//----------------------------------------------------------------------------- +enum LoggingResponse_t +{ + LR_CONTINUE, + LR_DEBUGGER, + LR_ABORT, +}; + +//----------------------------------------------------------------------------- +// Logging channel behavior flags, set on channel creation. +//----------------------------------------------------------------------------- +enum LoggingChannelFlags_t +{ + //----------------------------------------------------------------------------- + // Indicates that the spew is only relevant to interactive consoles. + //----------------------------------------------------------------------------- + LCF_CONSOLE_ONLY = 0x00000001, + + //----------------------------------------------------------------------------- + // Indicates that spew should not be echoed to any output devices. + // A suitable logging listener must be registered which respects this flag + // (e.g. a file logger). + //----------------------------------------------------------------------------- + LCF_DO_NOT_ECHO = 0x00000002, +}; + +//----------------------------------------------------------------------------- +// A callback function used to register tags on a logging channel +// during initialization. +//----------------------------------------------------------------------------- +typedef void ( *RegisterTagsFunc )(); + +//----------------------------------------------------------------------------- +// A context structure passed to logging listeners and response policy classes. +//----------------------------------------------------------------------------- +struct LoggingContext_t +{ + // ID of the channel being logged to. + LoggingChannelID_t m_ChannelID; + // Flags associated with the channel. + LoggingChannelFlags_t m_Flags; + // Severity of the logging event. + LoggingSeverity_t m_Severity; + // Color of logging message if one was specified to Log_****() macro. + // If not specified, falls back to channel color. + // If channel color is not specified, this value is UNSPECIFIED_LOGGING_COLOR + // and indicates that a suitable default should be chosen. + Color m_Color; +}; + +//----------------------------------------------------------------------------- +// Interface for classes to handle logging output. +// +// The Log() function of this class is called synchronously and serially +// by the logging system on all registered instances of ILoggingListener +// in the current "logging state". +// +// Derived classes may do whatever they want with the message (write to disk, +// write to console, send over the network, drop on the floor, etc.). +// +// In general, derived classes should do one, simple thing with the output +// to allow callers to register multiple, orthogonal logging listener classes. +//----------------------------------------------------------------------------- +class ILoggingListener +{ +public: + virtual void Log( const LoggingContext_t *pContext, const tchar *pMessage ) = 0; +}; + +//----------------------------------------------------------------------------- +// Interface for policy classes which determine how to behave when a +// message is logged. +// +// Can return: +// LR_CONTINUE (continue execution) +// LR_DEBUGGER (break into debugger if one is present, otherwise continue) +// LR_ABORT (terminate process immediately with a failure code of 1) +//----------------------------------------------------------------------------- +class ILoggingResponsePolicy +{ +public: + virtual LoggingResponse_t OnLog( const LoggingContext_t *pContext ) = 0; +}; + +////////////////////////////////////////////////////////////////////////// +// Common Logging Listeners & Logging Response Policies +////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// A basic logging listener which prints to stdout and the debug channel. +//----------------------------------------------------------------------------- +class CSimpleLoggingListener : public ILoggingListener +{ +public: + CSimpleLoggingListener( bool bQuietPrintf = false, bool bQuietDebugger = false ) : + m_bQuietPrintf( bQuietPrintf ), + m_bQuietDebugger( bQuietDebugger ) + { + } + + virtual void Log( const LoggingContext_t *pContext, const tchar *pMessage ) + { +#ifdef _X360 + if ( !m_bQuietDebugger && XBX_IsConsoleConnected() ) + { + // send to console + XBX_DebugString( XMAKECOLOR( 0,0,0 ), pMessage ); + } + else +#endif + { +#if !defined( _CERT ) && !defined( DBGFLAG_STRINGS_STRIP ) + if ( !m_bQuietPrintf ) + { + _tprintf( _T("%s"), pMessage ); + } +#endif + +#ifdef _WIN32 + if ( !m_bQuietDebugger && Plat_IsInDebugSession() ) + { + Plat_DebugString( pMessage ); + } +#endif + } + } + + // If set to true, does not print anything to stdout. + bool m_bQuietPrintf; + // If set to true, does not print anything to debugger. + bool m_bQuietDebugger; +}; + +//----------------------------------------------------------------------------- +// A basic logging listener for GUI applications +//----------------------------------------------------------------------------- +class CSimpleWindowsLoggingListener : public ILoggingListener +{ +public: + virtual void Log( const LoggingContext_t *pContext, const tchar *pMessage ) + { + if ( Plat_IsInDebugSession() ) + { + Plat_DebugString( pMessage ); + } + if ( pContext->m_Severity == LS_ERROR ) + { + if ( Plat_IsInDebugSession() ) + DebuggerBreak(); + + Plat_MessageBox( "Error", pMessage ); + } + } +}; + + +//----------------------------------------------------------------------------- +// ** NOTE FOR INTEGRATION ** +// This was copied over from source 2 rather than integrated because +// source 2 has more significantly refactored tier0 logging. +// +// A logging listener with Win32 console API color support which which prints +// to stdout and the debug channel. +//----------------------------------------------------------------------------- +#if !defined(_GAMECONSOLE) +class CColorizedLoggingListener : public CSimpleLoggingListener +{ +public: + CColorizedLoggingListener( bool bQuietPrintf = false, bool bQuietDebugger = false ) : CSimpleLoggingListener( bQuietPrintf, bQuietDebugger ) + { + InitWin32ConsoleColorContext( &m_ColorContext ); + } + + virtual void Log( const LoggingContext_t *pContext, const tchar *pMessage ) + { + if ( !m_bQuietPrintf ) + { + int nPrevColor = -1; + + if ( pContext->m_Color != UNSPECIFIED_LOGGING_COLOR ) + { + nPrevColor = SetWin32ConsoleColor( &m_ColorContext, + pContext->m_Color.r(), pContext->m_Color.g(), pContext->m_Color.b(), + MAX( MAX( pContext->m_Color.r(), pContext->m_Color.g() ), pContext->m_Color.b() ) > 128 ); + } + + _tprintf( _T("%s"), pMessage ); + + if ( nPrevColor >= 0 ) + { + RestoreWin32ConsoleColor( &m_ColorContext, nPrevColor ); + } + } + +#ifdef _WIN32 + if ( !m_bQuietDebugger && Plat_IsInDebugSession() ) + { + Plat_DebugString( pMessage ); + } +#endif + } + + Win32ConsoleColorContext_t m_ColorContext; +}; +#endif // !_GAMECONSOLE + + +//----------------------------------------------------------------------------- +// Default logging response policy used when one is not specified. +//----------------------------------------------------------------------------- +class CDefaultLoggingResponsePolicy : public ILoggingResponsePolicy +{ +public: + virtual LoggingResponse_t OnLog( const LoggingContext_t *pContext ) + { + if ( pContext->m_Severity == LS_ASSERT && !CommandLine()->FindParm( "-noassert" ) ) + { + return LR_DEBUGGER; + } + else if ( pContext->m_Severity == LS_ERROR ) + { + return LR_ABORT; + } + else + { + return LR_CONTINUE; + } + } +}; + +//----------------------------------------------------------------------------- +// A logging response policy which never terminates the process, even on error. +//----------------------------------------------------------------------------- +class CNonFatalLoggingResponsePolicy : public ILoggingResponsePolicy +{ +public: + virtual LoggingResponse_t OnLog( const LoggingContext_t *pContext ) + { + if ( ( pContext->m_Severity == LS_ASSERT && !CommandLine()->FindParm( "-noassert" ) ) || pContext->m_Severity == LS_ERROR ) + { + return LR_DEBUGGER; + } + else + { + return LR_CONTINUE; + } + } +}; + +////////////////////////////////////////////////////////////////////////// +// Central Logging System +////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// The central logging system. +// +// Multiple instances can exist, though all exported tier0 functionality +// specifically works with a single global instance +// (via GetGlobalLoggingSystem()). +//----------------------------------------------------------------------------- +class CLoggingSystem +{ +public: + struct LoggingChannel_t; + + CLoggingSystem(); + ~CLoggingSystem(); + + //----------------------------------------------------------------------------- + // Register a logging channel with the logging system. + // The same channel can be registered multiple times, but the parameters + // in each call to RegisterLoggingChannel must either match across all calls + // or be set to defaults on any given call + // + // This function is not thread-safe and should generally only be called + // by a single thread. Using the logging channel definition macros ensures + // that this is called on the static initialization thread. + //----------------------------------------------------------------------------- + LoggingChannelID_t RegisterLoggingChannel( const char *pChannelName, RegisterTagsFunc registerTagsFunc, int flags = 0, LoggingSeverity_t minimumSeverity = LS_MESSAGE, Color spewColor = UNSPECIFIED_LOGGING_COLOR ); + + //----------------------------------------------------------------------------- + // Gets a channel ID from a string name. + // Performs a simple linear search; cache the value whenever possible + // or re-register the logging channel to get a global ID. + //----------------------------------------------------------------------------- + LoggingChannelID_t FindChannel( const char *pChannelName ) const; + + int GetChannelCount() const { return m_nChannelCount; } + + //----------------------------------------------------------------------------- + // Gets a pointer to the logging channel description. + //----------------------------------------------------------------------------- + LoggingChannel_t *GetChannel( LoggingChannelID_t channelID ); + const LoggingChannel_t *GetChannel( LoggingChannelID_t channelID ) const; + + //----------------------------------------------------------------------------- + // Returns true if the given channel has the specified tag. + //----------------------------------------------------------------------------- + bool HasTag( LoggingChannelID_t channelID, const char *pTag ) const { return GetChannel( channelID )->HasTag( pTag ); } + + //----------------------------------------------------------------------------- + // Returns true if the given channel has been initialized. + // The main purpose is catching m_nChannelCount being zero because no channels have been registered. + //----------------------------------------------------------------------------- + bool IsValidChannelID( LoggingChannelID_t channelID ) const { return ( channelID >= 0 ) && ( channelID < m_nChannelCount ); } + + //----------------------------------------------------------------------------- + // Returns true if the given channel will spew at the given severity level. + //----------------------------------------------------------------------------- + bool IsChannelEnabled( LoggingChannelID_t channelID, LoggingSeverity_t severity ) const { return IsValidChannelID( channelID ) && GetChannel( channelID )->IsEnabled( severity ); } + + //----------------------------------------------------------------------------- + // Functions to set the spew level of a channel either directly by ID or + // string name, or for all channels with a given tag. + // + // These functions are not technically thread-safe but calling them across + // multiple threads should cause no significant problems + // (the underlying data types being changed are 32-bit/atomic). + //----------------------------------------------------------------------------- + void SetChannelSpewLevel( LoggingChannelID_t channelID, LoggingSeverity_t minimumSeverity ); + void SetChannelSpewLevelByName( const char *pName, LoggingSeverity_t minimumSeverity ); + void SetChannelSpewLevelByTag( const char *pTag, LoggingSeverity_t minimumSeverity ); + void SetGlobalSpewLevel( LoggingSeverity_t minimumSeverity ); + + //----------------------------------------------------------------------------- + // Gets or sets the color of a logging channel. + // (The functions are not thread-safe, but the consequences are not + // significant.) + //----------------------------------------------------------------------------- + Color GetChannelColor( LoggingChannelID_t channelID ) const { return GetChannel( channelID )->m_SpewColor; } + void SetChannelColor( LoggingChannelID_t channelID, Color color ) { GetChannel( channelID )->m_SpewColor = color; } + + //----------------------------------------------------------------------------- + // Gets or sets the flags on a logging channel. + // (The functions are not thread-safe, but the consequences are not + // significant.) + //----------------------------------------------------------------------------- + LoggingChannelFlags_t GetChannelFlags( LoggingChannelID_t channelID ) const { return GetChannel( channelID )->m_Flags; } + void SetChannelFlags( LoggingChannelID_t channelID, LoggingChannelFlags_t flags ) { GetChannel( channelID )->m_Flags = flags; } + + //----------------------------------------------------------------------------- + // Adds a string tag to a channel. + // This is not thread-safe and should only be called by a RegisterTagsFunc + // callback passed in to RegisterLoggingChannel (via the + // channel definition macros). + //----------------------------------------------------------------------------- + void AddTagToCurrentChannel( const char *pTagName ); + + //----------------------------------------------------------------------------- + // Functions to save/restore the current logging state. + // Set bThreadLocal to true on a matching Push/Pop call if the intent + // is to override the logging listeners on the current thread only. + // + // Pushing the current logging state onto the state stack results + // in the current state being cleared by default (no listeners, default logging response policy). + // Set bClearState to false to copy the existing listener pointers to the new state. + // + // These functions which mutate logging state ARE thread-safe and are + // guarded by m_StateMutex. + //----------------------------------------------------------------------------- + void PushLoggingState( bool bThreadLocal = false, bool bClearState = true ); + void PopLoggingState( bool bThreadLocal = false ); + + //----------------------------------------------------------------------------- + // Registers a logging listener (a class which handles logged messages). + //----------------------------------------------------------------------------- + void RegisterLoggingListener( ILoggingListener *pListener ); + + //----------------------------------------------------------------------------- + // Returns whether the specified logging listener is registered. + //----------------------------------------------------------------------------- + bool IsListenerRegistered( ILoggingListener *pListener ); + + //----------------------------------------------------------------------------- + // Clears out all of the current logging state (removes all listeners, + // sets the response policy to the default). + //----------------------------------------------------------------------------- + void ResetCurrentLoggingState(); + + //----------------------------------------------------------------------------- + // Sets a policy class to decide what should happen when messages of a + // particular severity are logged + // (e.g. exit on error, break into debugger). + // If pLoggingResponse is NULL, uses the default response policy class. + //----------------------------------------------------------------------------- + void SetLoggingResponsePolicy( ILoggingResponsePolicy *pLoggingResponse ); + + //----------------------------------------------------------------------------- + // Logs a message to the specified channel using a given severity and + // spew color. Passing in UNSPECIFIED_LOGGING_COLOR for 'color' allows + // the logging listeners to provide a default. + // NOTE: test 'IsChannelEnabled(channelID,severity)' before calling this! + //----------------------------------------------------------------------------- + LoggingResponse_t LogDirect( LoggingChannelID_t channelID, LoggingSeverity_t severity, Color color, const tchar *pMessage ); + + // Internal data to represent a logging tag + struct LoggingTag_t + { + const char *m_pTagName; + LoggingTag_t *m_pNextTag; + }; + + // Internal data to represent a logging channel. + struct LoggingChannel_t + { + bool HasTag( const char *pTag ) const + { + LoggingTag_t *pCurrentTag = m_pFirstTag; + while( pCurrentTag != NULL ) + { + if ( stricmp( pCurrentTag->m_pTagName, pTag ) == 0 ) + { + return true; + } + pCurrentTag = pCurrentTag->m_pNextTag; + } + return false; + } + bool IsEnabled( LoggingSeverity_t severity ) const { return severity >= m_MinimumSeverity; } + void SetSpewLevel( LoggingSeverity_t severity ) { m_MinimumSeverity = severity; } + + LoggingChannelID_t m_ID; + LoggingChannelFlags_t m_Flags; // an OR'd combination of LoggingChannelFlags_t + LoggingSeverity_t m_MinimumSeverity; // The minimum severity level required to activate this channel. + Color m_SpewColor; + char m_Name[MAX_LOGGING_IDENTIFIER_LENGTH]; + LoggingTag_t *m_pFirstTag; + }; + +private: + // Represents the current state of the logger (registered listeners, response policy class, etc.) and can + // vary from thread-to-thread. It can also be pushed/popped to save/restore listener/response state. + struct LoggingState_t + { + // Index of the previous entry on the listener set stack. + int m_nPreviousStackEntry; + + // Number of active listeners in this set. Cannot exceed MAX_LOGGING_LISTENER_COUNT. + // If set to -1, implies that this state structure is not in use. + int m_nListenerCount; + // Array of registered logging listener objects. + ILoggingListener *m_RegisteredListeners[MAX_LOGGING_LISTENER_COUNT]; + + // Specific policy class to determine behavior of logging system under specific message types. + ILoggingResponsePolicy *m_pLoggingResponse; + }; + + // These state functions to assume the caller has already grabbed the mutex. + LoggingState_t *GetCurrentState(); + const LoggingState_t *GetCurrentState() const; + + int FindUnusedStateIndex(); + LoggingTag_t *AllocTag( const char *pTagName ); + + int m_nChannelCount; + LoggingChannel_t m_RegisteredChannels[MAX_LOGGING_CHANNEL_COUNT]; + + int m_nChannelTagCount; + LoggingTag_t m_ChannelTags[MAX_LOGGING_TAG_COUNT]; + + // Index to first free character in name pool. + int m_nTagNamePoolIndex; + // Pool of character data used for tag names. + char m_TagNamePool[MAX_LOGGING_TAG_CHARACTER_COUNT]; + + // Protects all data in this class except the registered channels + // (which are supposed to be registered using the macros at static/global init time). + // It is assumed that this mutex is reentrant safe on all platforms. + CThreadFastMutex *m_pStateMutex; + + // The index of the current "global" state of the logging system. By default, all threads use this state + // for logging unless a given thread has pushed the logging state with bThreadLocal == true. + // If a thread-local state has been pushed, g_nThreadLocalStateIndex (a global thread-local integer) will be non-zero. + // By default, g_nThreadLocalStateIndex is 0 for all threads. + int m_nGlobalStateIndex; + + // A pool of logging states used to store a stack (potentially per-thread). + static const int MAX_LOGGING_STATE_COUNT = 16; + LoggingState_t m_LoggingStates[MAX_LOGGING_STATE_COUNT]; + + // Default policy class which determines behavior. + CDefaultLoggingResponsePolicy m_DefaultLoggingResponse; + + // Default spew function. + CSimpleLoggingListener m_DefaultLoggingListener; + +}; + +////////////////////////////////////////////////////////////////////////// +// Logging Macros +////////////////////////////////////////////////////////////////////////// + +// This macro will resolve to the most appropriate overload of LoggingSystem_Log() depending on the number of parameters passed in. +#ifdef DBGFLAG_STRINGS_STRIP +#define InternalMsg( Channel, Severity, /* [Color], Message, */ ... ) do { if ( Severity == LS_ERROR && LoggingSystem_IsChannelEnabled( Channel, Severity ) ) LoggingSystem_Log( Channel, Severity, /* [Color], Message, */ ##__VA_ARGS__ ); } while( 0 ) +#else +#define InternalMsg( Channel, Severity, /* [Color], Message, */ ... ) do { if ( LoggingSystem_IsChannelEnabled( Channel, Severity ) ) LoggingSystem_Log( Channel, Severity, /* [Color], Message, */ ##__VA_ARGS__ ); } while( 0 ) +#endif + +//----------------------------------------------------------------------------- +// New macros, use these! +// +// The macros take an optional Color parameter followed by the message +// and the message formatting. +// We rely on the variadic macro (__VA_ARGS__) operator to paste in the +// extra parameters and resolve to the appropriate overload. +//----------------------------------------------------------------------------- +#define Log_Msg( Channel, /* [Color], Message, */ ... ) InternalMsg( Channel, LS_MESSAGE, /* [Color], Message, */ ##__VA_ARGS__ ) +#define Log_Warning( Channel, /* [Color], Message, */ ... ) InternalMsg( Channel, LS_WARNING, /* [Color], Message, */ ##__VA_ARGS__ ) +#define Log_Error( Channel, /* [Color], Message, */ ... ) InternalMsg( Channel, LS_ERROR, /* [Color], Message, */ ##__VA_ARGS__ ) +#ifdef DBGFLAG_STRINGS_STRIP +#define Log_Assert( ... ) LR_CONTINUE +#else +#define Log_Assert( Message, ... ) LoggingSystem_LogAssert( Message, ##__VA_ARGS__ ) +#endif + + +#define DECLARE_LOGGING_CHANNEL( Channel ) extern LoggingChannelID_t Channel + +#define DEFINE_LOGGING_CHANNEL_NO_TAGS( Channel, ChannelName, /* [Flags], [Severity], [Color] */ ... ) \ + LoggingChannelID_t Channel = LoggingSystem_RegisterLoggingChannel( ChannelName, NULL, ##__VA_ARGS__ ) + +#define BEGIN_DEFINE_LOGGING_CHANNEL( Channel, ChannelName, /* [Flags], [Severity], [Color] */ ... ) \ + static void Register_##Channel##_Tags(); \ + LoggingChannelID_t Channel = LoggingSystem_RegisterLoggingChannel( ChannelName, Register_##Channel##_Tags, ##__VA_ARGS__ ); \ + void Register_##Channel##_Tags() \ + { + +#define ADD_LOGGING_CHANNEL_TAG( Tag ) LoggingSystem_AddTagToCurrentChannel( Tag ) + +#define END_DEFINE_LOGGING_CHANNEL() \ + } + +////////////////////////////////////////////////////////////////////////// +// DLL Exports +////////////////////////////////////////////////////////////////////////// + +// For documentation on these functions, please look at the corresponding function +// in CLoggingSystem (unless otherwise specified). +PLATFORM_INTERFACE LoggingChannelID_t LoggingSystem_RegisterLoggingChannel( const char *pName, RegisterTagsFunc registerTagsFunc, int flags = 0, LoggingSeverity_t severity = LS_MESSAGE, Color color = UNSPECIFIED_LOGGING_COLOR ); + +PLATFORM_INTERFACE void LoggingSystem_RegisterLoggingListener( ILoggingListener *pListener ); +PLATFORM_INTERFACE void LoggingSystem_UnregisterLoggingListener(ILoggingListener *pListener); +PLATFORM_INTERFACE void LoggingSystem_ResetCurrentLoggingState(); +PLATFORM_INTERFACE void LoggingSystem_SetLoggingResponsePolicy( ILoggingResponsePolicy *pResponsePolicy ); +// NOTE: PushLoggingState() saves the current logging state on a stack and results in a new clear state +// (no listeners, default logging response policy). +PLATFORM_INTERFACE void LoggingSystem_PushLoggingState( bool bThreadLocal = false, bool bClearState = true ); +PLATFORM_INTERFACE void LoggingSystem_PopLoggingState( bool bThreadLocal = false ); + +PLATFORM_INTERFACE void LoggingSystem_AddTagToCurrentChannel( const char *pTagName ); + +// Returns INVALID_LOGGING_CHANNEL_ID if not found +PLATFORM_INTERFACE LoggingChannelID_t LoggingSystem_FindChannel( const char *pChannelName ); +PLATFORM_INTERFACE int LoggingSystem_GetChannelCount(); +PLATFORM_INTERFACE LoggingChannelID_t LoggingSystem_GetFirstChannelID(); +// Returns INVALID_LOGGING_CHANNEL_ID when there are no channels remaining. +PLATFORM_INTERFACE LoggingChannelID_t LoggingSystem_GetNextChannelID( LoggingChannelID_t channelID ); +PLATFORM_INTERFACE const CLoggingSystem::LoggingChannel_t *LoggingSystem_GetChannel( LoggingChannelID_t channelID ); + +PLATFORM_INTERFACE bool LoggingSystem_HasTag( LoggingChannelID_t channelID, const char *pTag ); + +PLATFORM_INTERFACE bool LoggingSystem_IsChannelEnabled( LoggingChannelID_t channelID, LoggingSeverity_t severity ); +PLATFORM_INTERFACE void LoggingSystem_SetChannelSpewLevel( LoggingChannelID_t channelID, LoggingSeverity_t minimumSeverity ); +PLATFORM_INTERFACE void LoggingSystem_SetChannelSpewLevelByName( const char *pName, LoggingSeverity_t minimumSeverity ); +PLATFORM_INTERFACE void LoggingSystem_SetChannelSpewLevelByTag( const char *pTag, LoggingSeverity_t minimumSeverity ); +PLATFORM_INTERFACE void LoggingSystem_SetGlobalSpewLevel( LoggingSeverity_t minimumSeverity ); + +// Color is represented as an int32 due to C-linkage restrictions +PLATFORM_INTERFACE int32 LoggingSystem_GetChannelColor( LoggingChannelID_t channelID ); +PLATFORM_INTERFACE void LoggingSystem_SetChannelColor( LoggingChannelID_t channelID, int color ); + +PLATFORM_INTERFACE LoggingChannelFlags_t LoggingSystem_GetChannelFlags( LoggingChannelID_t channelID ); +PLATFORM_INTERFACE void LoggingSystem_SetChannelFlags( LoggingChannelID_t channelID, LoggingChannelFlags_t flags ); + +//----------------------------------------------------------------------------- +// Logs a variable-argument to a given channel with the specified severity. +// NOTE: if adding overloads to this function, remember that the Log_*** +// macros simply pass their variadic parameters through to LoggingSystem_Log(). +// Therefore, you need to ensure that the parameters are in the same general +// order and that there are no ambiguities with the overload. +//----------------------------------------------------------------------------- +PLATFORM_INTERFACE LoggingResponse_t LoggingSystem_Log( LoggingChannelID_t channelID, LoggingSeverity_t severity, PRINTF_FORMAT_STRING const char *pMessageFormat, ... ) FMTFUNCTION( 3, 4 ); +PLATFORM_OVERLOAD LoggingResponse_t LoggingSystem_Log( LoggingChannelID_t channelID, LoggingSeverity_t severity, Color spewColor, PRINTF_FORMAT_STRING const char *pMessageFormat, ... ) FMTFUNCTION( 4, 5 ); + +PLATFORM_INTERFACE LoggingResponse_t LoggingSystem_LogDirect( LoggingChannelID_t channelID, LoggingSeverity_t severity, Color spewColor, const char *pMessage ); +PLATFORM_INTERFACE LoggingResponse_t LoggingSystem_LogAssert( PRINTF_FORMAT_STRING const char *pMessageFormat, ... ) FMTFUNCTION( 1, 2 ); + +#endif //#if !defined(__SPU__) + +#endif // LOGGING_H \ No newline at end of file diff --git a/public/tier0/platform.h b/public/tier0/platform.h index a8ad1b02..a91b1bd9 100644 --- a/public/tier0/platform.h +++ b/public/tier0/platform.h @@ -472,6 +472,18 @@ typedef void * HINSTANCE; #endif #define DebuggerBreakIfDebugging() if ( !Plat_IsInDebugSession() ) ; else DebuggerBreak() + +//----------------------------------------------------------------------------- +// Message Box +//----------------------------------------------------------------------------- +//#if defined( PLATFORM_WINDOWS_PC ) +//PLATFORM_INTERFACE void Plat_MessageBox( const char *pTitle, const tchar *pMessage ); +//#else +// TODO(nillerusr): add message box later +#define Plat_MessageBox( t, m ) ((void)0) +//#endif + + #ifdef STAGING_ONLY #define DebuggerBreakIfDebugging_StagingOnly() if ( !Plat_IsInDebugSession() ) ; else DebuggerBreak() #else @@ -626,6 +638,12 @@ typedef void * HINSTANCE; #define NO_ASAN #endif +#if defined( COMPILER_MSVC ) + #define TEMPLATE_STATIC static +#else + #define TEMPLATE_STATIC +#endif + #if defined( _WIN32 ) // Used for dll exporting and importing diff --git a/public/tier0/win32consoleio.h b/public/tier0/win32consoleio.h new file mode 100644 index 00000000..92b3914d --- /dev/null +++ b/public/tier0/win32consoleio.h @@ -0,0 +1,32 @@ +//======= Copyright © 1996-2006, Valve Corporation, All rights reserved. ====== +// +// Purpose: Win32 Console API helpers +// +//============================================================================= +#ifndef WIN32_CONSOLE_IO_H +#define WIN32_CONSOLE_IO_H + +#if defined( COMPILER_MSVC ) +#pragma once +#endif + +// Function to attach a console for I/O to a Win32 GUI application in a reasonably smart fashion. +PLATFORM_INTERFACE bool SetupWin32ConsoleIO(); + +// Win32 Console Color API Helpers, originally from cmdlib. + +struct Win32ConsoleColorContext_t +{ + int m_InitialColor; + uint16 m_LastColor; + uint16 m_BadColor; + uint16 m_BackgroundFlags; +}; + +PLATFORM_INTERFACE void InitWin32ConsoleColorContext( Win32ConsoleColorContext_t *pContext ); + +PLATFORM_INTERFACE uint16 SetWin32ConsoleColor( Win32ConsoleColorContext_t *pContext, int nRed, int nGreen, int nBlue, int nIntensity ); + +PLATFORM_INTERFACE void RestoreWin32ConsoleColor( Win32ConsoleColorContext_t *pContext, uint16 prevColor ); + +#endif diff --git a/public/tier2/resourceprecacher.h b/public/tier2/resourceprecacher.h new file mode 100644 index 00000000..2d562c73 --- /dev/null +++ b/public/tier2/resourceprecacher.h @@ -0,0 +1,195 @@ + //===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: Utilities for setting vproject settings +// +//===========================================================================// + +#ifndef _RESOURCEPRECACHER_H +#define _RESOURCEPRECACHER_H + +#ifdef _WIN32 +#pragma once +#endif + +//----------------------------------------------------------------------------- +// Resource list +//----------------------------------------------------------------------------- +FORWARD_DECLARE_HANDLE( ResourceList_t ); +#define RESOURCE_LIST_INVALID ( (ResourceList_t)-1 ) + +//----------------------------------------------------------------------------- +// Resource 'systems', which use other resources +// NOTE: If you add types here, be sure to fix s_pResourceSystemName +//----------------------------------------------------------------------------- +enum PrecacheSystem_t +{ + CLIENTGLOBAL = 0, // Always precache these + SERVERGLOBAL, + VGUI_PANEL, // What to precache when using a vgui panel + DISPATCH_EFFECT, // What to precache when using a dispatch effect + SHARED_SYSTEM, // Precache lists which are reused and can be referenced as a resource type + + PRECACHE_SYSTEM_COUNT, + +#if defined( GAME_DLL ) + GLOBAL = SERVERGLOBAL, +#elif defined( CLIENT_DLL ) || defined( GAMEUI_EXPORTS ) + GLOBAL = CLIENTGLOBAL, +#endif +}; + +//----------------------------------------------------------------------------- +// Resource types +// NOTE: If you add a type here, modify s_pResourceTypeName in resourceaccesscontrol.cpp +//----------------------------------------------------------------------------- +enum ResourceTypeOld_t // called 'Old' to disambiguate with ResourceSystem +{ + RESOURCE_VGUI_PANEL = 0, // .res file + RESOURCE_MATERIAL, // .vmt file + RESOURCE_MODEL, // .mdl file + RESOURCE_PARTICLE_SYSTEM, // particle system + RESOURCE_GAMESOUND, // game sound + + RESOURCE_TYPE_OLD_COUNT, +}; + + +//----------------------------------------------------------------------------- +// Resource types +// NOTE: If you add types here, be sure to fix s_pPrecacheResourceTypeName +// A compile-time assert will trigger if you don't. +//----------------------------------------------------------------------------- +enum PrecacheResourceType_t +{ + VGUI_RESOURCE = 0, // .res file + MATERIAL, // .vmt file + MODEL, // .mdl file + GAMESOUND, // sound + PARTICLE_SYSTEM, // particle system + ENTITY, // Other entity + DECAL, // A decal + PARTICLE_MATERIAL, // A particle system material (old-style, obsolete) + KV_DEP_FILE, // keyvalues file containing a resource dependency list + GAME_MATERIAL_DECALS, // All decals related to game materials ( resource name is ignored ) + PHYSICS_GAMESOUNDS, // Resource names are either "BulletSounds", "StepSounds", or "PhysicsImpactSounds" + SHARED, // a shared precache group (see PrecacheSystem_t SHARED) + + PRECACHE_RESOURCE_TYPE_COUNT, +}; + +//----------------------------------------------------------------------------- +// Callback interface for handler who knows how to precache particular kinds of resources +//----------------------------------------------------------------------------- +abstract_class IPrecacheHandler +{ +public: + virtual void CacheResource( PrecacheResourceType_t nType, const char *pName, + bool bPrecache, ResourceList_t hResourceList, int *pIndex = NULL ) = 0; +}; + +//----------------------------------------------------------------------------- +// Interface to automated system for precaching resources +//----------------------------------------------------------------------------- +abstract_class IResourcePrecacher +{ +public: + virtual void Cache( IPrecacheHandler *pPrecacheHandler, bool bPrecache, ResourceList_t hResourceList, bool bIgnoreConditionals ) = 0; + virtual PrecacheSystem_t GetSystem() = 0; + virtual const char *GetName() = 0; + virtual IResourcePrecacher *GetNext() = 0; + virtual void SetNext( IResourcePrecacher * pNext ) = 0; +}; + +//----------------------------------------------------------------------------- +// Actually does the precaching +//----------------------------------------------------------------------------- +class CBaseResourcePrecacher : public IResourcePrecacher +{ + // Other public methods +public: + CBaseResourcePrecacher( PrecacheSystem_t nSystem, const char *pName ) + { + m_nSystem = nSystem; + m_pName = pName; + m_pNext = sm_pFirst[nSystem]; + sm_pFirst[nSystem] = this; + } + + static void RegisterAll(); + + PrecacheSystem_t GetSystem() { return m_nSystem; } + const char *GetName() { return m_pName; } + IResourcePrecacher *GetNext() { return m_pNext; } + void SetNext( IResourcePrecacher * pNext ) { m_pNext = pNext; } + + static CBaseResourcePrecacher *sm_pFirst[PRECACHE_SYSTEM_COUNT]; + + PrecacheSystem_t m_nSystem; + const char *m_pName; + IResourcePrecacher *m_pNext; + + friend class CPrecacheRegister; +}; + + +//----------------------------------------------------------------------------- +// Automatic precache macros +//----------------------------------------------------------------------------- + +// Beginning +#define PRECACHE_REGISTER_BEGIN_CONDITIONAL( _system, _className, _condition ) \ + namespace _className ## Precache \ +{ \ +class CResourcePrecacher : public CBaseResourcePrecacher\ +{ \ +public: \ + CResourcePrecacher() : CBaseResourcePrecacher( _system, #_className ) {} \ +public: \ + virtual void Cache( IPrecacheHandler *pPrecacheHandler, bool bPrecache, ResourceList_t hResourceList, bool bIgnoreConditionals ); \ +}; \ + void CResourcePrecacher::Cache( IPrecacheHandler *pPrecacheHandler, bool bPrecache, ResourceList_t hResourceList, bool bIgnoreConditionals ) \ +{ \ + if ( !bIgnoreConditionals && !( _condition ) ) \ + return; + +#define PRECACHE_REGISTER_BEGIN( _system, _className ) \ + PRECACHE_REGISTER_BEGIN_CONDITIONAL( _system, _className, true ) + +// Resource precache definitions +#define PRECACHE( _type, _name ) pPrecacheHandler->CacheResource( _type, _name, bPrecache, hResourceList, NULL ); + +// NOTE: PRECACHE_INDEX_CONDITIONAL doesn't initialize the index to 0 +// on the assumption that some other conditional will + +//MCCLEANUP //NOTE: PRECACHE_INDEX and PRECACHE_INDEX_CONDITIONAL won't work in 64 bit because the old-school particle mgr is sending ptr data types into here. Hopefully the old-school particle mgr will die before this is an issue. + +#define PRECACHE_INDEX( _type, _name, _index ) pPrecacheHandler->CacheResource( _type, _name, bPrecache, hResourceList, (int*)( &(_index) ) ); +#define PRECACHE_CONDITIONAL( _type, _name, _condition ) \ + if ( !bIgnoreConditionals && ( _condition ) ) \ + pPrecacheHandler->CacheResource( _type, _name, bPrecache, hResourceList, NULL ); +#define PRECACHE_INDEX_CONDITIONAL( _type, _name, _index, _func ) \ + if ( bIgnoreConditionals || ( _condition ) ) \ +{ \ + pPrecacheHandler->CacheResource( _type, _name, bPrecache, hResourceList, (int*)( &(_index) ) ); \ +} + +//End +#define PRECACHE_REGISTER_END( ) \ +} \ + CResourcePrecacher s_ResourcePrecacher; \ +} + +// FIXME: Remove! Backward compat +#define PRECACHE_WEAPON_REGISTER( _className ) \ + PRECACHE_REGISTER_BEGIN( GLOBAL, _className ) \ + PRECACHE( ENTITY, #_className ) \ + PRECACHE_REGISTER_END() + +#define PRECACHE_REGISTER( _className ) \ + PRECACHE_REGISTER_BEGIN( GLOBAL, _className ) \ + PRECACHE( ENTITY, #_className ) \ + PRECACHE_REGISTER_END() + +#endif // _RESOURCEPRECACHER_H + + diff --git a/public/tier2/tier2_logging.h b/public/tier2/tier2_logging.h new file mode 100644 index 00000000..f5cee5d1 --- /dev/null +++ b/public/tier2/tier2_logging.h @@ -0,0 +1,72 @@ +//============ Copyright (c) Valve Corporation, All rights reserved. ============ +// +// Tier2 logging helpers. Adds support for file I/O +// +//=============================================================================== + +#ifndef TIER2_LOGGING_H +#define TIER2_LOGGING_H + +#if defined( COMPILER_MSVC ) +#pragma once +#endif + +#include "logging.h" + + +const int MAX_SIMULTANEOUS_LOGGING_FILE_COUNT = 16; +const int INVALID_LOGGING_FILE_HANDLE = -1; + +typedef int LoggingFileHandle_t; +typedef void * FileHandle_t; + +#define FILELOGGINGLISTENER_INTERFACE_VERSION "FileLoggingListener001" + +abstract_class IFileLoggingListener : public ILoggingListener +{ +public: + virtual void Log( const LoggingContext_t *pContext, const char *pMessage ) = 0; + + virtual LoggingFileHandle_t BeginLoggingToFile( const char *pFilename, const char *pOptions, const char *pPathID = NULL ) = 0; + virtual void EndLoggingToFile( LoggingFileHandle_t fileHandle ) = 0; + + virtual void AssignLogChannel( LoggingChannelID_t channelID, LoggingFileHandle_t loggingFileHandle ) = 0; + virtual void UnassignLogChannel( LoggingChannelID_t channelID ) = 0; + virtual void AssignAllLogChannels( LoggingFileHandle_t loggingFileHandle ) = 0; + virtual void UnassignAllLogChannels() = 0; +}; + +class CFileLoggingListener : public IFileLoggingListener +{ +public: + CFileLoggingListener(); + ~CFileLoggingListener(); + + virtual void Log( const LoggingContext_t *pContext, const char *pMessage ); + + virtual LoggingFileHandle_t BeginLoggingToFile( const char *pFilename, const char *pOptions, const char *pPathID = NULL ); + virtual void EndLoggingToFile( LoggingFileHandle_t fileHandle ); + + virtual void AssignLogChannel( LoggingChannelID_t channelID, LoggingFileHandle_t loggingFileHandle ); + virtual void UnassignLogChannel( LoggingChannelID_t channelID ); + virtual void AssignAllLogChannels( LoggingFileHandle_t loggingFileHandle ); + virtual void UnassignAllLogChannels(); + +private: + int GetUnusedFileInfo() const; + + struct FileInfo_t + { + FileHandle_t m_FileHandle; + + bool IsOpen() const { return m_FileHandle != 0; } + void Reset() { m_FileHandle = 0; } + }; + + FileInfo_t m_OpenFiles[MAX_SIMULTANEOUS_LOGGING_FILE_COUNT]; + + // Table which maps logging channel IDs to open files + int m_FileIndices[MAX_LOGGING_CHANNEL_COUNT]; +}; + +#endif // TIER2_LOGGING_H \ No newline at end of file diff --git a/public/vscript/ivscript.h b/public/vscript/ivscript.h new file mode 100644 index 00000000..d385225e --- /dev/null +++ b/public/vscript/ivscript.h @@ -0,0 +1,1467 @@ +//========== Copyright � 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: VScript +// +// Overview +// -------- +// VScript is an abstract binding layer that allows code to expose itself to +// multiple scripting languages in a uniform format. Code can expose +// functions, classes, and data to the scripting languages, and can also +// call functions that reside in scripts. +// +// Initializing +// ------------ +// +// To create a script virtual machine (VM), grab the global instance of +// IScriptManager, call CreateVM, then call Init on the returned VM. Right +// now you can have multiple VMs, but only VMs for a specific language. +// +// Exposing functions and classes +// ------------------------------ +// +// To expose a C++ function to the scripting system, you just need to fill out a +// description block. Using templates, the system will automatically deduce +// all of the binding requirements (parameters and return values). Functions +// are limited as to what the types of the parameters can be. See ScriptVariant_t. +// +// extern IScriptVM *pScriptVM; +// bool Foo( int ); +// void Bar(); +// float FooBar( int, const char * ); +// float OverlyTechnicalName( bool ); +// +// void RegisterFuncs() +// { +// ScriptRegisterFunction( pScriptVM, Foo ); +// ScriptRegisterFunction( pScriptVM, Bar ); +// ScriptRegisterFunction( pScriptVM, FooBar ); +// ScriptRegisterFunctionNamed( pScriptVM, OverlyTechnicalName, "SimpleName" ); +// } +// +// class CMyClass +// { +// public: +// bool Foo( int ); +// void Bar(); +// float FooBar( int, const char * ); +// float OverlyTechnicalName( bool ); +// }; +// +// BEGIN_SCRIPTDESC_ROOT( CMyClass ) +// DEFINE_SCRIPTFUNC( Foo ) +// DEFINE_SCRIPTFUNC( Bar ) +// DEFINE_SCRIPTFUNC( FooBar ) +// DEFINE_SCRIPTFUNC_NAMED( OverlyTechnicalName, "SimpleMemberName" ) +// END_SCRIPTDESC(); +// +// class CMyDerivedClass : public CMyClass +// { +// public: +// float DerivedFunc() const; +// }; +// +// BEGIN_SCRIPTDESC( CMyDerivedClass, CMyClass ) +// DEFINE_SCRIPTFUNC( DerivedFunc ) +// END_SCRIPTDESC(); +// +// CMyDerivedClass derivedInstance; +// +// void AnotherFunction() +// { +// // Manual class exposure +// pScriptVM->RegisterClass( GetScriptDescForClass( CMyClass ) ); +// +// // Auto registration by instance +// pScriptVM->RegisterInstance( &derivedInstance, "theInstance" ); +// } +// +// Classes with "DEFINE_SCRIPT_CONSTRUCTOR()" in their description can be instanced within scripts +// +// Scopes +// ------ +// Scripts can either be run at the global scope, or in a user defined scope. In the latter case, +// all "globals" within the script are actually in the scope. This can be used to bind private +// data spaces with C++ objects. +// +// Calling a function on a script +// ------------------------------ +// Generally, use the "Call" functions. This example is the equivalent of DoIt("Har", 6.0, 99). +// +// hFunction = pScriptVM->LookupFunction( "DoIt", hScope ); +// pScriptVM->Call( hFunction, hScope, true, NULL, "Har", 6.0, 99 ); +// +//============================================================================= + +#ifndef IVSCRIPT_H +#define IVSCRIPT_H + +#include "platform.h" +#include "datamap.h" +#include "appframework/iappsystem.h" +#include "tier1/functors.h" +#include "tier0/memdbgon.h" + +#if defined( _WIN32 ) +#pragma once +#endif + +#ifdef VSCRIPT_DLL_EXPORT +#define VSCRIPT_INTERFACE DLL_EXPORT +#define VSCRIPT_OVERLOAD DLL_GLOBAL_EXPORT +#define VSCRIPT_CLASS DLL_CLASS_EXPORT +#else +#define VSCRIPT_INTERFACE DLL_IMPORT +#define VSCRIPT_OVERLOAD DLL_GLOBAL_IMPORT +#define VSCRIPT_CLASS DLL_CLASS_IMPORT +#endif + +class CUtlBuffer; + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#define VSCRIPT_INTERFACE_VERSION "VScriptManager009" + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +class IScriptVM; + +enum ScriptLanguage_t +{ + SL_NONE, + SL_GAMEMONKEY, + SL_SQUIRREL, + SL_LUA, + SL_PYTHON, + + SL_DEFAULT = SL_SQUIRREL +}; + +class IScriptManager : public IAppSystem +{ +public: + virtual IScriptVM *CreateVM( ScriptLanguage_t language = SL_DEFAULT ) = 0; + virtual void DestroyVM( IScriptVM * ) = 0; +}; + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +DECLARE_POINTER_HANDLE( HSCRIPT ); +#define INVALID_HSCRIPT ((HSCRIPT)-1) + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +enum ExtendedFieldType +{ + FIELD_TYPEUNKNOWN = FIELD_TYPECOUNT, + FIELD_CSTRING, + FIELD_HSCRIPT, + FIELD_VARIANT, +}; + +typedef int ScriptDataType_t; +struct ScriptVariant_t; + +template struct ScriptDeducer { /*enum { FIELD_TYPE = FIELD_TYPEUNKNOWN };*/ }; +#define DECLARE_DEDUCE_FIELDTYPE( fieldType, type ) template<> struct ScriptDeducer { enum { FIELD_TYPE = fieldType }; }; + +DECLARE_DEDUCE_FIELDTYPE( FIELD_VOID, void ); +DECLARE_DEDUCE_FIELDTYPE( FIELD_FLOAT, float ); +DECLARE_DEDUCE_FIELDTYPE( FIELD_CSTRING, const char * ); +DECLARE_DEDUCE_FIELDTYPE( FIELD_CSTRING, char * ); +DECLARE_DEDUCE_FIELDTYPE( FIELD_VECTOR, Vector ); +DECLARE_DEDUCE_FIELDTYPE( FIELD_VECTOR, const Vector &); +DECLARE_DEDUCE_FIELDTYPE( FIELD_INTEGER, int ); +DECLARE_DEDUCE_FIELDTYPE( FIELD_BOOLEAN, bool ); +DECLARE_DEDUCE_FIELDTYPE( FIELD_CHARACTER, char ); +DECLARE_DEDUCE_FIELDTYPE( FIELD_HSCRIPT, HSCRIPT ); +DECLARE_DEDUCE_FIELDTYPE( FIELD_VARIANT, ScriptVariant_t ); + +#define ScriptDeduceType( T ) ScriptDeducer::FIELD_TYPE + +template +inline const char * ScriptFieldTypeName() +{ + T::using_unknown_script_type(); + return NULL; +} + +#define DECLARE_NAMED_FIELDTYPE( fieldType, strName ) template <> inline const char * ScriptFieldTypeName() { return strName; } +DECLARE_NAMED_FIELDTYPE( void, "void" ); +DECLARE_NAMED_FIELDTYPE( float, "float" ); +DECLARE_NAMED_FIELDTYPE( const char *, "cstring" ); +DECLARE_NAMED_FIELDTYPE( char *, "cstring" ); +DECLARE_NAMED_FIELDTYPE( Vector, "vector" ); +DECLARE_NAMED_FIELDTYPE( const Vector&, "vector" ); +DECLARE_NAMED_FIELDTYPE( int, "integer" ); +DECLARE_NAMED_FIELDTYPE( bool, "boolean" ); +DECLARE_NAMED_FIELDTYPE( char, "character" ); +DECLARE_NAMED_FIELDTYPE( HSCRIPT, "hscript" ); +DECLARE_NAMED_FIELDTYPE( ScriptVariant_t, "variant" ); + +inline const char * ScriptFieldTypeName( int16 eType) +{ + switch( eType ) + { + case FIELD_VOID: return "void"; + case FIELD_FLOAT: return "float"; + case FIELD_CSTRING: return "cstring"; + case FIELD_VECTOR: return "vector"; + case FIELD_INTEGER: return "integer"; + case FIELD_BOOLEAN: return "boolean"; + case FIELD_CHARACTER: return "character"; + case FIELD_HSCRIPT: return "hscript"; + case FIELD_VARIANT: return "variant"; + default: return "unknown_script_type"; + } +} + +//--------------------------------------------------------- + +struct ScriptFuncDescriptor_t +{ + ScriptFuncDescriptor_t() + { + m_pszFunction = NULL; + m_ReturnType = FIELD_TYPEUNKNOWN; + m_pszDescription = NULL; + } + + const char *m_pszScriptName; + const char *m_pszFunction; + const char *m_pszDescription; + ScriptDataType_t m_ReturnType; + CUtlVector m_Parameters; +}; + + +//--------------------------------------------------------- + +// Prefix a script description with this in order to not show the function or class in help +#define SCRIPT_HIDE "@" + +// Prefix a script description of a class to indicate it is a singleton and the single instance should be in the help +#define SCRIPT_SINGLETON "!" + +// Prefix a script description with this to indicate it should be represented using an alternate name +#define SCRIPT_ALIAS( alias, description ) "#" alias ":" description + +//--------------------------------------------------------- + +enum ScriptFuncBindingFlags_t +{ + SF_MEMBER_FUNC = 0x01, +}; + +#ifdef _PS3 +typedef void* ScriptFunctionBindingStorageType_t; // Function descriptor is actually 64-bit +#else +typedef void* ScriptFunctionBindingStorageType_t; +#endif + +typedef bool (*ScriptBindingFunc_t)( ScriptFunctionBindingStorageType_t pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ); + +struct ScriptFunctionBinding_t +{ + ScriptFuncDescriptor_t m_desc; + ScriptBindingFunc_t m_pfnBinding; + ScriptFunctionBindingStorageType_t m_pFunction; + unsigned m_flags; +}; + +//--------------------------------------------------------- +class IScriptInstanceHelper +{ +public: + virtual void *GetProxied( void *p ) { return p; } + virtual bool ToString( void *p, char *pBuf, int bufSize ) { return false; } + virtual void *BindOnRead( HSCRIPT hInstance, void *pOld, const char *pszId ) { return NULL; } +}; + +//--------------------------------------------------------- + +struct ScriptClassDesc_t +{ + ScriptClassDesc_t( void (*pfnInitializer)() ) : m_pszScriptName( 0 ), m_pszClassname( 0 ), m_pszDescription( 0 ), m_pBaseDesc( 0 ), m_pfnConstruct( 0 ), m_pfnDestruct( 0 ), pHelper(NULL) + { + (*pfnInitializer)(); + ScriptClassDesc_t **ppHead = GetDescList(); + m_pNextDesc = *ppHead; + *ppHead = this; + } + + const char * m_pszScriptName; + const char * m_pszClassname; + const char * m_pszDescription; + ScriptClassDesc_t * m_pBaseDesc; + CUtlVector m_FunctionBindings; + + void *(*m_pfnConstruct)(); + void (*m_pfnDestruct)( void *); + IScriptInstanceHelper * pHelper; // optional helper + + ScriptClassDesc_t * m_pNextDesc; + + static ScriptClassDesc_t **GetDescList() + { + static ScriptClassDesc_t *pHead; + return &pHead; + } +}; + +//--------------------------------------------------------- +// A simple variant type. Intentionally not full featured (no implicit conversion, no memory management) +//--------------------------------------------------------- + +enum SVFlags_t +{ + SV_FREE = 0x01, +}; + +#pragma warning(push) +#pragma warning(disable:4800) +struct ScriptVariant_t +{ + ScriptVariant_t() : m_flags( 0 ), m_type( FIELD_VOID ) { m_pVector = 0; } + ScriptVariant_t( int val ) : m_flags( 0 ), m_type( FIELD_INTEGER ) { m_int = val;} + ScriptVariant_t( float val ) : m_flags( 0 ), m_type( FIELD_FLOAT ) { m_float = val; } + ScriptVariant_t( double val ) : m_flags( 0 ), m_type( FIELD_FLOAT ) { m_float = (float)val; } + ScriptVariant_t( char val ) : m_flags( 0 ), m_type( FIELD_CHARACTER ) { m_char = val; } + ScriptVariant_t( bool val ) : m_flags( 0 ), m_type( FIELD_BOOLEAN ) { m_bool = val; } + ScriptVariant_t( HSCRIPT val ) : m_flags( 0 ), m_type( FIELD_HSCRIPT ) { m_hScript = val; } + + ScriptVariant_t( const Vector &val, bool bCopy = false ) : m_flags( 0 ), m_type( FIELD_VECTOR ) { if ( !bCopy ) { m_pVector = &val; } else { m_pVector = new Vector( val ); m_flags |= SV_FREE; } } + ScriptVariant_t( const Vector *val, bool bCopy = false ) : m_flags( 0 ), m_type( FIELD_VECTOR ) { if ( !bCopy ) { m_pVector = val; } else { m_pVector = new Vector( *val ); m_flags |= SV_FREE; } } + ScriptVariant_t( const char *val , bool bCopy = false ) : m_flags( 0 ), m_type( FIELD_CSTRING ) { if ( !bCopy ) { m_pszString = val; } else { m_pszString = strdup( val ); m_flags |= SV_FREE; } } + + bool IsNull() const { return (m_type == FIELD_VOID ); } + + operator int() const { Assert( m_type == FIELD_INTEGER ); return m_int; } + operator int64() const { Assert( m_type == FIELD_INTEGER ); return static_cast(m_int); } + operator float() const { Assert( m_type == FIELD_FLOAT ); return m_float; } + operator const char *() const { Assert( m_type == FIELD_CSTRING ); return ( m_pszString ) ? m_pszString : ""; } + operator const Vector &() const { Assert( m_type == FIELD_VECTOR ); static Vector vecNull(0, 0, 0); return (m_pVector) ? *m_pVector : vecNull; } + operator char() const { Assert( m_type == FIELD_CHARACTER ); return m_char; } + operator bool() const { Assert( m_type == FIELD_BOOLEAN ); return m_bool; } + operator HSCRIPT() const { Assert( m_type == FIELD_HSCRIPT ); return m_hScript; } + + void operator=( int i ) { m_type = FIELD_INTEGER; m_int = i; } + void operator=( int64 i ) { m_type = FIELD_INTEGER; m_int = i; } + void operator=( float f ) { m_type = FIELD_FLOAT; m_float = f; } + void operator=( double f ) { m_type = FIELD_FLOAT; m_float = (float)f; } + void operator=( const Vector &vec ) { m_type = FIELD_VECTOR; m_pVector = &vec; } + void operator=( const Vector *vec ) { m_type = FIELD_VECTOR; m_pVector = vec; } + void operator=( const char *psz ) { m_type = FIELD_CSTRING; m_pszString = psz; } + void operator=( char c ) { m_type = FIELD_CHARACTER; m_char = c; } + void operator=( bool b ) { m_type = FIELD_BOOLEAN; m_bool = b; } + void operator=( HSCRIPT h ) { m_type = FIELD_HSCRIPT; m_hScript = h; } + + void Free() { if ( ( m_flags & SV_FREE ) && ( m_type == FIELD_HSCRIPT || m_type == FIELD_VECTOR || m_type == FIELD_CSTRING ) ) delete m_pszString; } // Generally only needed for return results + + template + T Get() + { + T value; + AssignTo( &value ); + return value; + } + + template + bool AssignTo( T *pDest ) + { + ScriptDataType_t destType = ScriptDeduceType( T ); + if ( destType == FIELD_TYPEUNKNOWN ) + { + DevWarning( "Unable to convert script variant to unknown type\n" ); + } + if ( destType == m_type ) + { + *pDest = *this; + return true; + } + + if ( m_type != FIELD_VECTOR && m_type != FIELD_CSTRING && destType != FIELD_VECTOR && destType != FIELD_CSTRING ) + { + switch ( m_type ) + { + case FIELD_VOID: *pDest = 0; break; + case FIELD_INTEGER: *pDest = m_int; return true; + case FIELD_FLOAT: *pDest = m_float; return true; + case FIELD_CHARACTER: *pDest = m_char; return true; + case FIELD_BOOLEAN: *pDest = m_bool; return true; + case FIELD_HSCRIPT: *pDest = m_hScript; return true; + } + } + else + { + DevWarning( "No free conversion of %s script variant to %s right now\n", + ScriptFieldTypeName( m_type ), ScriptFieldTypeName() ); + if ( destType != FIELD_VECTOR ) + { + *pDest = 0; + } + } + return false; + } + + bool AssignTo( float *pDest ) + { + switch( m_type ) + { + case FIELD_VOID: *pDest = 0; return false; + case FIELD_INTEGER: *pDest = m_int; return true; + case FIELD_FLOAT: *pDest = m_float; return true; + case FIELD_BOOLEAN: *pDest = m_bool; return true; + default: + DevWarning( "No conversion from %s to float now\n", ScriptFieldTypeName( m_type ) ); + return false; + } + } + + bool AssignTo( int *pDest ) + { + switch( m_type ) + { + case FIELD_VOID: *pDest = 0; return false; + case FIELD_INTEGER: *pDest = m_int; return true; + case FIELD_FLOAT: *pDest = ( int )m_float; return true; + case FIELD_BOOLEAN: *pDest = m_bool; return true; + default: + DevWarning( "No conversion from %s to int now\n", ScriptFieldTypeName( m_type ) ); + return false; + } + } + + bool AssignTo( bool *pDest ) + { + switch( m_type ) + { + case FIELD_VOID: *pDest = 0; return false; + case FIELD_INTEGER: *pDest = m_int; return true; + case FIELD_FLOAT: *pDest = m_float; return true; + case FIELD_BOOLEAN: *pDest = m_bool; return true; + default: + DevWarning( "No conversion from %s to bool now\n", ScriptFieldTypeName( m_type ) ); + return false; + } + } + + bool AssignTo( const char **pDest ) + { + DevWarning( "No free conversion of string or vector script variant right now\n" ); + // If want to support this, probably need to malloc string and require free on other side [3/24/2008 tom] + *pDest = ""; + return false; + } + + bool AssignTo( ScriptVariant_t *pDest ) + { + pDest->m_type = m_type; + if ( m_type == FIELD_VECTOR ) + { + pDest->m_pVector = new Vector; + ((Vector *)(pDest->m_pVector))->Init( m_pVector->x, m_pVector->y, m_pVector->z ); + pDest->m_flags |= SV_FREE; + } + else if ( m_type == FIELD_CSTRING ) + { + pDest->m_pszString = strdup( m_pszString ); + pDest->m_flags |= SV_FREE; + } + else + { + pDest->m_int = m_int; + } + return false; + } + + union + { + int m_int; + float m_float; + const char * m_pszString; + const Vector * m_pVector; + char m_char; + bool m_bool; + HSCRIPT m_hScript; + }; + + int16 m_type; + int16 m_flags; + +private: +}; + +#define SCRIPT_VARIANT_NULL ScriptVariant_t() + +#pragma warning(pop) + + + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#include "vscript_templates.h" + +// Lower level macro primitives +#define ScriptInitFunctionBinding( pScriptFunction, func ) ScriptInitFunctionBindingNamed( pScriptFunction, func, #func ) +#define ScriptInitFunctionBindingNamed( pScriptFunction, func, scriptName ) do { ScriptInitFuncDescriptorNamed( (&(pScriptFunction)->m_desc), func, scriptName ); (pScriptFunction)->m_pfnBinding = ScriptCreateBinding( &func ); (pScriptFunction)->m_pFunction = ScriptConvertFreeFuncPtrToVoid( &func ); } while (0) + +#define ScriptInitMemberFunctionBinding( pScriptFunction, class, func ) ScriptInitMemberFunctionBinding_( pScriptFunction, class, func, #func ) +#define ScriptInitMemberFunctionBindingNamed( pScriptFunction, class, func, scriptName ) ScriptInitMemberFunctionBinding_( pScriptFunction, class, func, scriptName ) +#define ScriptInitMemberFunctionBinding_( pScriptFunction, class, func, scriptName ) do { ScriptInitMemberFuncDescriptor_( (&(pScriptFunction)->m_desc), class, func, scriptName ); (pScriptFunction)->m_pfnBinding = ScriptCreateBinding( ((class *)0), &class::func ); (pScriptFunction)->m_pFunction = ScriptConvertFuncPtrToVoid( &class::func ); (pScriptFunction)->m_flags = SF_MEMBER_FUNC; } while (0) + +#define ScriptInitClassDesc( pClassDesc, class, pBaseClassDesc ) ScriptInitClassDescNamed( pClassDesc, class, pBaseClassDesc, #class ) +#define ScriptInitClassDescNamed( pClassDesc, class, pBaseClassDesc, scriptName ) ScriptInitClassDescNamed_( pClassDesc, class, pBaseClassDesc, scriptName ) +#define ScriptInitClassDescNoBase( pClassDesc, class ) ScriptInitClassDescNoBaseNamed( pClassDesc, class, #class ) +#define ScriptInitClassDescNoBaseNamed( pClassDesc, class, scriptName ) ScriptInitClassDescNamed_( pClassDesc, class, NULL, scriptName ) +#define ScriptInitClassDescNamed_( pClassDesc, class, pBaseClassDesc, scriptName ) do { (pClassDesc)->m_pszScriptName = scriptName; (pClassDesc)->m_pszClassname = #class; (pClassDesc)->m_pBaseDesc = pBaseClassDesc; } while ( 0 ) + +#define ScriptAddFunctionToClassDesc( pClassDesc, class, func, description ) ScriptAddFunctionToClassDescNamed( pClassDesc, class, func, #func, description ) +#define ScriptAddFunctionToClassDescNamed( pClassDesc, class, func, scriptName, description ) do { ScriptFunctionBinding_t *pBinding = &((pClassDesc)->m_FunctionBindings[(pClassDesc)->m_FunctionBindings.AddToTail()]); pBinding->m_desc.m_pszDescription = description; ScriptInitMemberFunctionBindingNamed( pBinding, class, func, scriptName ); } while (0) + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#define ScriptRegisterFunction( pVM, func, description ) ScriptRegisterFunctionNamed( pVM, func, #func, description ) +#define ScriptRegisterFunctionNamed( pVM, func, scriptName, description ) do { static ScriptFunctionBinding_t binding; binding.m_desc.m_pszDescription = description; binding.m_desc.m_Parameters.RemoveAll(); ScriptInitFunctionBindingNamed( &binding, func, scriptName ); pVM->RegisterFunction( &binding ); } while (0) + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#define ALLOW_SCRIPT_ACCESS() template friend ScriptClassDesc_t *GetScriptDesc(T *); + +#define BEGIN_SCRIPTDESC( className, baseClass, description ) BEGIN_SCRIPTDESC_NAMED( className, baseClass, #className, description ) +#define BEGIN_SCRIPTDESC_ROOT( className, description ) BEGIN_SCRIPTDESC_ROOT_NAMED( className, #className, description ) + +#if defined(_MSC_VER) && (_MSC_VER < 1800) + #define DEFINE_SCRIPTDESC_FUNCTION( className, baseClass ) \ + ScriptClassDesc_t * GetScriptDesc( className * ) +#else + #define DEFINE_SCRIPTDESC_FUNCTION( className, baseClass ) \ + template <> ScriptClassDesc_t * GetScriptDesc( baseClass *); \ + template <> ScriptClassDesc_t * GetScriptDesc( className *) +#endif + +struct ScriptNoBase_t; + +// We use template specialization to allow classes to optionally override this function. +// For a given class, if this function is NOT overridden, the class' descriptor will use the base class' +// IScriptInstanceHelper object. +// If this function IS overridden, it will use the return value of the overridden function +template < typename TScriptClass > +IScriptInstanceHelper *GetScriptInstanceHelperOverride( IScriptInstanceHelper *pBaseClassHelper ) +{ + return pBaseClassHelper; +} + +inline IScriptInstanceHelper *GetScriptInstanceHelper_ScriptNoBase_t() +{ + return NULL; +} + +#define BEGIN_SCRIPTDESC_NAMED( className, baseClass, scriptName, description ) \ + IScriptInstanceHelper *GetScriptInstanceHelper_##baseClass(); \ + IScriptInstanceHelper *GetScriptInstanceHelper_##className() \ + { \ + return GetScriptInstanceHelperOverride< className >( GetScriptInstanceHelper_##baseClass() ); \ + }; \ + extern void Init##className##ScriptDesc(); \ + ScriptClassDesc_t g_##className##_ScriptDesc( &Init##className##ScriptDesc ); \ + DEFINE_SCRIPTDESC_FUNCTION( className, baseClass ) \ + { \ + return &g_##className##_ScriptDesc; \ + } \ + \ + void Init##className##ScriptDesc() \ + { \ + static bool bInitialized; \ + if ( bInitialized ) \ + { \ + return; \ + } \ + \ + bInitialized = true; \ + \ + typedef className _className; \ + ScriptClassDesc_t *pDesc = &g_##className##_ScriptDesc; \ + pDesc->m_pszDescription = description; \ + ScriptInitClassDescNamed( pDesc, className, GetScriptDescForClass( baseClass ), scriptName ); \ + pDesc->pHelper = GetScriptInstanceHelper_##className(); + + +#define BEGIN_SCRIPTDESC_ROOT_NAMED( className, scriptName, description ) \ + BEGIN_SCRIPTDESC_NAMED( className, ScriptNoBase_t, scriptName, description ) + +#define END_SCRIPTDESC() \ + return; \ + } + +#define DEFINE_SCRIPTFUNC( func, description ) DEFINE_SCRIPTFUNC_NAMED( func, #func, description ) +#define DEFINE_SCRIPTFUNC_NAMED( func, scriptName, description ) ScriptAddFunctionToClassDescNamed( pDesc, _className, func, scriptName, description ); +#define DEFINE_SCRIPT_CONSTRUCTOR() ScriptAddConstructorToClassDesc( pDesc, _className ); +#define DEFINE_SCRIPT_INSTANCE_HELPER( className, p ) template <> IScriptInstanceHelper *GetScriptInstanceHelperOverride< className >( IScriptInstanceHelper * ) { return p; } + +template ScriptClassDesc_t *GetScriptDesc(T *); + +template <> +#ifdef _PS3 +static +#endif +inline ScriptClassDesc_t *GetScriptDesc( ScriptNoBase_t *) { return NULL; } + +#define GetScriptDescForClass( className ) GetScriptDesc( ( className *)NULL ) + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +template +class CScriptConstructor +{ +public: + static void *Construct() { return new T; } + static void Destruct( void *p ) { delete (T *)p; } +}; + +#define ScriptAddConstructorToClassDesc( pClassDesc, class ) do { (pClassDesc)->m_pfnConstruct = &CScriptConstructor::Construct; (pClassDesc)->m_pfnDestruct = &CScriptConstructor::Destruct; } while (0) + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +enum ScriptErrorLevel_t +{ + SCRIPT_LEVEL_WARNING = 0, + SCRIPT_LEVEL_ERROR, +}; + +typedef void ( *ScriptOutputFunc_t )( const char *pszText ); +typedef bool ( *ScriptErrorFunc_t )( ScriptErrorLevel_t eLevel, const char *pszText ); + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#ifdef RegisterClass +#undef RegisterClass +#endif + +enum ScriptStatus_t +{ + SCRIPT_ERROR = -1, + SCRIPT_DONE, + SCRIPT_RUNNING, +}; + +class IScriptVM +{ +public: + virtual bool Init() = 0; + virtual void Shutdown() = 0; + + virtual bool ConnectDebugger() = 0; + virtual void DisconnectDebugger() = 0; + + virtual ScriptLanguage_t GetLanguage() = 0; + virtual const char *GetLanguageName() = 0; + + virtual void AddSearchPath( const char *pszSearchPath ) = 0; + + //-------------------------------------------------------- + + virtual bool Frame( float simTime ) = 0; + + //-------------------------------------------------------- + // Simple script usage + //-------------------------------------------------------- + virtual ScriptStatus_t Run( const char *pszScript, bool bWait = true ) = 0; + inline ScriptStatus_t Run( const unsigned char *pszScript, bool bWait = true ) { return Run( (char *)pszScript, bWait ); } + + //-------------------------------------------------------- + // Compilation + //-------------------------------------------------------- + virtual HSCRIPT CompileScript( const char *pszScript, const char *pszId = NULL ) = 0; + inline HSCRIPT CompileScript( const unsigned char *pszScript, const char *pszId = NULL ) { return CompileScript( (char *)pszScript, pszId ); } + virtual void ReleaseScript( HSCRIPT ) = 0; + + //-------------------------------------------------------- + // Execution of compiled + //-------------------------------------------------------- + virtual ScriptStatus_t Run( HSCRIPT hScript, HSCRIPT hScope = NULL, bool bWait = true ) = 0; + virtual ScriptStatus_t Run( HSCRIPT hScript, bool bWait ) = 0; + + //-------------------------------------------------------- + // Scope + //-------------------------------------------------------- + virtual HSCRIPT CreateScope( const char *pszScope, HSCRIPT hParent = NULL ) = 0; + virtual void ReleaseScope( HSCRIPT hScript ) = 0; + + //-------------------------------------------------------- + // Script functions + //-------------------------------------------------------- + virtual HSCRIPT LookupFunction( const char *pszFunction, HSCRIPT hScope = NULL ) = 0; + virtual void ReleaseFunction( HSCRIPT hScript ) = 0; + + //-------------------------------------------------------- + // Script functions (raw, use Call()) + //-------------------------------------------------------- + virtual ScriptStatus_t ExecuteFunction( HSCRIPT hFunction, ScriptVariant_t *pArgs, int nArgs, ScriptVariant_t *pReturn, HSCRIPT hScope, bool bWait ) = 0; + + //-------------------------------------------------------- + // External functions + //-------------------------------------------------------- + virtual void RegisterFunction( ScriptFunctionBinding_t *pScriptFunction ) = 0; + + //-------------------------------------------------------- + // External classes + //-------------------------------------------------------- + virtual bool RegisterClass( ScriptClassDesc_t *pClassDesc ) = 0; + + void RegisterAllClasses() + { + ScriptClassDesc_t *pCurrent = *ScriptClassDesc_t::GetDescList(); + while ( pCurrent ) + { + RegisterClass( pCurrent ); + pCurrent = pCurrent->m_pNextDesc; + } + } + + //-------------------------------------------------------- + // External instances. Note class will be auto-registered. + //-------------------------------------------------------- + + virtual HSCRIPT RegisterInstance( ScriptClassDesc_t *pDesc, void *pInstance ) = 0; + virtual void SetInstanceUniqeId( HSCRIPT hInstance, const char *pszId ) = 0; + template HSCRIPT RegisterInstance( T *pInstance ) { return RegisterInstance( GetScriptDesc( pInstance ), pInstance ); } + template HSCRIPT RegisterInstance( T *pInstance, const char *pszInstance, HSCRIPT hScope = NULL) { HSCRIPT hInstance = RegisterInstance( GetScriptDesc( pInstance ), pInstance ); SetValue( hScope, pszInstance, hInstance ); return hInstance; } + virtual void RemoveInstance( HSCRIPT ) = 0; + void RemoveInstance( HSCRIPT hInstance, const char *pszInstance, HSCRIPT hScope = NULL ) { ClearValue( hScope, pszInstance ); RemoveInstance( hInstance ); } + void RemoveInstance( const char *pszInstance, HSCRIPT hScope = NULL ) { ScriptVariant_t val; if ( GetValue( hScope, pszInstance, &val ) ) { if ( val.m_type == FIELD_HSCRIPT ) { RemoveInstance( val, pszInstance, hScope ); } ReleaseValue( val ); } } + + virtual void *GetInstanceValue( HSCRIPT hInstance, ScriptClassDesc_t *pExpectedType = NULL ) = 0; + + //---------------------------------------------------------------------------- + + virtual bool GenerateUniqueKey( const char *pszRoot, char *pBuf, int nBufSize ) = 0; + + //---------------------------------------------------------------------------- + + virtual bool ValueExists( HSCRIPT hScope, const char *pszKey ) = 0; + bool ValueExists( const char *pszKey ) { return ValueExists( NULL, pszKey ); } + + virtual bool SetValue( HSCRIPT hScope, const char *pszKey, const char *pszValue ) = 0; + virtual bool SetValue( HSCRIPT hScope, const char *pszKey, const ScriptVariant_t &value ) = 0; + bool SetValue( const char *pszKey, const ScriptVariant_t &value ) { return SetValue(NULL, pszKey, value ); } + + virtual void CreateTable( ScriptVariant_t &Table ) = 0; + virtual int GetNumTableEntries( HSCRIPT hScope ) = 0; + virtual int GetKeyValue( HSCRIPT hScope, int nIterator, ScriptVariant_t *pKey, ScriptVariant_t *pValue ) = 0; + + virtual bool GetValue( HSCRIPT hScope, const char *pszKey, ScriptVariant_t *pValue ) = 0; + bool GetValue( const char *pszKey, ScriptVariant_t *pValue ) { return GetValue(NULL, pszKey, pValue ); } + virtual void ReleaseValue( ScriptVariant_t &value ) = 0; + + virtual bool ClearValue( HSCRIPT hScope, const char *pszKey ) = 0; + bool ClearValue( const char *pszKey) { return ClearValue( NULL, pszKey ); } + + //---------------------------------------------------------------------------- + + virtual void WriteState( CUtlBuffer *pBuffer ) = 0; + virtual void ReadState( CUtlBuffer *pBuffer ) = 0; + virtual void RemoveOrphanInstances() = 0; + + virtual void DumpState() = 0; + + virtual void SetOutputCallback( ScriptOutputFunc_t pFunc ) = 0; + virtual void SetErrorCallback( ScriptErrorFunc_t pFunc ) = 0; + + //---------------------------------------------------------------------------- + + virtual bool RaiseException( const char *pszExceptionText ) = 0; + + //---------------------------------------------------------------------------- + // Call API + // + // Note for string and vector return types, the caller must delete the pointed to memory + //---------------------------------------------------------------------------- + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope = NULL, bool bWait = true, ScriptVariant_t *pReturn = NULL ) + { + return ExecuteFunction( hFunction, NULL, 0, pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1 ) + { + ScriptVariant_t args[1]; args[0] = arg1; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2 ) + { + ScriptVariant_t args[2]; args[0] = arg1; args[1] = arg2; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3 ) + { + ScriptVariant_t args[3]; args[0] = arg1; args[1] = arg2; args[2] = arg3; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4 ) + { + ScriptVariant_t args[4]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5 ) + { + ScriptVariant_t args[5]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6 ) + { + ScriptVariant_t args[6]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7 ) + { + ScriptVariant_t args[7]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8 ) + { + ScriptVariant_t args[8]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9 ) + { + ScriptVariant_t args[9]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10 ) + { + ScriptVariant_t args[10]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11 ) + { + ScriptVariant_t args[11]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11, ARG_TYPE_12 arg12 ) + { + ScriptVariant_t args[12]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; args[11] = arg12; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11, ARG_TYPE_12 arg12, ARG_TYPE_13 arg13 ) + { + ScriptVariant_t args[13]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; args[11] = arg12; args[12] = arg13; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11, ARG_TYPE_12 arg12, ARG_TYPE_13 arg13, ARG_TYPE_14 arg14 ) + { + ScriptVariant_t args[14]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; args[11] = arg12; args[12] = arg13; args[13] = arg14; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + +}; + + +//----------------------------------------------------------------------------- +// Script scope helper class +//----------------------------------------------------------------------------- + +class CDefScriptScopeBase +{ +public: + static IScriptVM *GetVM() + { + extern IScriptVM *g_pScriptVM; + return g_pScriptVM; + } +}; + +template +class CScriptScopeT : public CDefScriptScopeBase +{ +public: + CScriptScopeT() : + m_hScope( INVALID_HSCRIPT ), + m_flags( 0 ) + { + } + + ~CScriptScopeT() + { + Term(); + } + + bool IsInitialized() + { + return m_hScope != INVALID_HSCRIPT; + } + + bool Init( const char *pszName ) + { + m_hScope = GetVM()->CreateScope( pszName ); + return ( m_hScope != NULL ); + } + + bool Init( HSCRIPT hScope, bool bExternal = true ) + { + if ( bExternal ) + { + m_flags |= EXTERNAL; + } + m_hScope = hScope; + return ( m_hScope != NULL ); + } + + bool InitGlobal() + { + Assert( 0 ); // todo [3/24/2008 tom] + m_hScope = GetVM()->CreateScope( "" ); + return ( m_hScope != NULL ); + } + + void Term() + { + if ( m_hScope != INVALID_HSCRIPT ) + { + IScriptVM *pVM = GetVM(); + if ( pVM ) + { + for ( int i = 0; i < m_FuncHandles.Count(); i++ ) + { + pVM->ReleaseFunction( *m_FuncHandles[i] ); + } + } + m_FuncHandles.Purge(); + if ( m_hScope && pVM && !(m_flags & EXTERNAL) ) + { + pVM->ReleaseScope( m_hScope ); + } + m_hScope = INVALID_HSCRIPT; + } + m_flags = 0; + } + + void InvalidateCachedValues() + { + IScriptVM *pVM = GetVM(); + for ( int i = 0; i < m_FuncHandles.Count(); i++ ) + { + if ( *m_FuncHandles[i] ) + pVM->ReleaseFunction( *m_FuncHandles[i] ); + *m_FuncHandles[i] = INVALID_HSCRIPT; + } + m_FuncHandles.RemoveAll(); + } + + operator HSCRIPT() + { + return ( m_hScope != INVALID_HSCRIPT ) ? m_hScope : NULL; + } + + bool ValueExists( const char *pszKey ) { return GetVM()->ValueExists( m_hScope, pszKey ); } + bool SetValue( const char *pszKey, const ScriptVariant_t &value ) { return GetVM()->SetValue(m_hScope, pszKey, value ); } + bool GetValue( const char *pszKey, ScriptVariant_t *pValue ) { return GetVM()->GetValue(m_hScope, pszKey, pValue ); } + void ReleaseValue( ScriptVariant_t &value ) { GetVM()->ReleaseValue( value ); } + bool ClearValue( const char *pszKey) { return GetVM()->ClearValue( m_hScope, pszKey ); } + + ScriptStatus_t Run( HSCRIPT hScript ) + { + InvalidateCachedValues(); + return GetVM()->Run( hScript, m_hScope ); + } + + ScriptStatus_t Run( const char *pszScriptText, const char *pszScriptName = NULL ) + { + InvalidateCachedValues(); + HSCRIPT hScript = GetVM()->CompileScript( pszScriptText, pszScriptName ); + if ( hScript ) + { + ScriptStatus_t result = GetVM()->Run( hScript, m_hScope ); + GetVM()->ReleaseScript( hScript ); + return result; + } + return SCRIPT_ERROR; + } + + ScriptStatus_t Run( const unsigned char *pszScriptText, const char *pszScriptName = NULL ) + { + return Run( (const char *)pszScriptText, pszScriptName); + } + + HSCRIPT LookupFunction( const char *pszFunction ) + { + return GetVM()->LookupFunction( pszFunction, m_hScope ); + } + + void ReleaseFunction( HSCRIPT hScript ) + { + GetVM()->ReleaseFunction( hScript ); + } + + bool FunctionExists( const char *pszFunction ) + { + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + GetVM()->ReleaseFunction( hFunction ); + return ( hFunction != NULL ) ; + } + + //----------------------------------------------------- + + enum Flags_t + { + EXTERNAL = 0x01, + }; + + //----------------------------------------------------- + + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn = NULL ) + { + return GetVM()->ExecuteFunction( hFunction, NULL, 0, pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1 ) + { + ScriptVariant_t args[1]; args[0] = arg1; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2 ) + { + ScriptVariant_t args[2]; args[0] = arg1; args[1] = arg2; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3 ) + { + ScriptVariant_t args[3]; args[0] = arg1; args[1] = arg2; args[2] = arg3; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4 ) + { + ScriptVariant_t args[4]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5 ) + { + ScriptVariant_t args[5]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6 ) + { + ScriptVariant_t args[6]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7 ) + { + ScriptVariant_t args[7]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8 ) + { + ScriptVariant_t args[8]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9 ) + { + ScriptVariant_t args[9]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10 ) + { + ScriptVariant_t args[10]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11 ) + { + ScriptVariant_t args[11]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11, ARG_TYPE_12 arg12 ) + { + ScriptVariant_t args[12]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; args[11] = arg12; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11, ARG_TYPE_12 arg12, ARG_TYPE_13 arg13 ) + { + ScriptVariant_t args[13]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; args[11] = arg12; args[12] = arg13; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11, ARG_TYPE_12 arg12, ARG_TYPE_13 arg13, ARG_TYPE_14 arg14 ) + { + ScriptVariant_t args[14]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; args[11] = arg12; args[12] = arg13; args[13] = arg14; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn = NULL ) + { + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, NULL, 0, pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1 ) + { + ScriptVariant_t args[1]; args[0] = arg1; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2 ) + { + ScriptVariant_t args[2]; args[0] = arg1; args[1] = arg2; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3 ) + { + ScriptVariant_t args[3]; args[0] = arg1; args[1] = arg2; args[2] = arg3; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4 ) + { + ScriptVariant_t args[4]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5 ) + { + ScriptVariant_t args[5]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6 ) + { + ScriptVariant_t args[6]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7 ) + { + ScriptVariant_t args[7]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8 ) + { + ScriptVariant_t args[8]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9 ) + { + ScriptVariant_t args[9]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10 ) + { + ScriptVariant_t args[10]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11 ) + { + ScriptVariant_t args[11]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11, ARG_TYPE_12 arg12 ) + { + ScriptVariant_t args[12]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; args[11] = arg12; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11, ARG_TYPE_12 arg12, ARG_TYPE_13 arg13 ) + { + ScriptVariant_t args[13]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; args[11] = arg12; args[12] = arg13; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11, ARG_TYPE_12 arg12, ARG_TYPE_13 arg13, ARG_TYPE_14 arg14 ) + { + ScriptVariant_t args[14]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; args[11] = arg12; args[12] = arg13; args[13] = arg14; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + +protected: + HSCRIPT m_hScope; + int m_flags; + CUtlVectorConservative m_FuncHandles; +}; + +typedef CScriptScopeT<> CScriptScope; + +#define VScriptAddEnumToScope_( scope, enumVal, scriptName ) (scope).SetValue( scriptName, (int)enumVal ) +#define VScriptAddEnumToScope( scope, enumVal ) VScriptAddEnumToScope_( scope, enumVal, #enumVal ) + +#define VScriptAddEnumToRoot( enumVal ) g_pScriptVM->SetValue( #enumVal, (int)enumVal ) + +//----------------------------------------------------------------------------- +// Script function proxy support +//----------------------------------------------------------------------------- + +class CScriptFuncHolder +{ +public: + CScriptFuncHolder() : hFunction( INVALID_HSCRIPT ) {} + bool IsValid() { return ( hFunction != INVALID_HSCRIPT ); } + bool IsNull() { return ( !hFunction ); } + HSCRIPT hFunction; +}; + +#define DEFINE_SCRIPT_PROXY_GUTS( FuncName, N ) \ + CScriptFuncHolder m_hScriptFunc_##FuncName; \ + template < typename RET_TYPE FUNC_TEMPLATE_ARG_PARAMS_##N> \ + bool FuncName( RET_TYPE *pRetVal FUNC_ARG_FORMAL_PARAMS_##N ) \ + { \ + if ( !m_hScriptFunc_##FuncName.IsValid() ) \ + { \ + m_hScriptFunc_##FuncName.hFunction = LookupFunction( #FuncName ); \ + m_FuncHandles.AddToTail( &m_hScriptFunc_##FuncName.hFunction ); \ + } \ + \ + if ( !m_hScriptFunc_##FuncName.IsNull() ) \ + { \ + ScriptVariant_t returnVal; \ + ScriptStatus_t result = Call( m_hScriptFunc_##FuncName.hFunction, &returnVal, FUNC_CALL_ARGS_##N ); \ + if ( result != SCRIPT_ERROR ) \ + { \ + returnVal.AssignTo( pRetVal ); \ + returnVal.Free(); \ + return true; \ + } \ + } \ + return false; \ + } + +#define DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, N ) \ + CScriptFuncHolder m_hScriptFunc_##FuncName; \ + template < FUNC_SOLO_TEMPLATE_ARG_PARAMS_##N> \ + bool FuncName( FUNC_PROXY_ARG_FORMAL_PARAMS_##N ) \ + { \ + if ( !m_hScriptFunc_##FuncName.IsValid() ) \ + { \ + m_hScriptFunc_##FuncName.hFunction = LookupFunction( #FuncName ); \ + m_FuncHandles.AddToTail( &m_hScriptFunc_##FuncName.hFunction ); \ + } \ + \ + if ( !m_hScriptFunc_##FuncName.IsNull() ) \ + { \ + ScriptStatus_t result = Call( m_hScriptFunc_##FuncName.hFunction, NULL, FUNC_CALL_ARGS_##N ); \ + if ( result != SCRIPT_ERROR ) \ + { \ + return true; \ + } \ + } \ + return false; \ + } + +#define DEFINE_SCRIPT_PROXY_0V( FuncName ) \ + CScriptFuncHolder m_hScriptFunc_##FuncName; \ + bool FuncName() \ + { \ + if ( !m_hScriptFunc_##FuncName.IsValid() ) \ + { \ + m_hScriptFunc_##FuncName.hFunction = LookupFunction( #FuncName ); \ + m_FuncHandles.AddToTail( &m_hScriptFunc_##FuncName.hFunction ); \ + } \ + \ + if ( !m_hScriptFunc_##FuncName.IsNull() ) \ + { \ + ScriptStatus_t result = Call( m_hScriptFunc_##FuncName.hFunction, NULL ); \ + if ( result != SCRIPT_ERROR ) \ + { \ + return true; \ + } \ + } \ + return false; \ + } + +#define DEFINE_SCRIPT_PROXY_0( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 0 ) +#define DEFINE_SCRIPT_PROXY_1( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 1 ) +#define DEFINE_SCRIPT_PROXY_2( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 2 ) +#define DEFINE_SCRIPT_PROXY_3( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 3 ) +#define DEFINE_SCRIPT_PROXY_4( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 4 ) +#define DEFINE_SCRIPT_PROXY_5( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 5 ) +#define DEFINE_SCRIPT_PROXY_6( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 6 ) +#define DEFINE_SCRIPT_PROXY_7( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 7 ) +#define DEFINE_SCRIPT_PROXY_8( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 8 ) +#define DEFINE_SCRIPT_PROXY_9( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 9 ) +#define DEFINE_SCRIPT_PROXY_10( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 10 ) +#define DEFINE_SCRIPT_PROXY_11( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 11 ) +#define DEFINE_SCRIPT_PROXY_12( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 12 ) +#define DEFINE_SCRIPT_PROXY_13( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 13 ) +#define DEFINE_SCRIPT_PROXY_14( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 14 ) + +#define DEFINE_SCRIPT_PROXY_1V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 1 ) +#define DEFINE_SCRIPT_PROXY_2V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 2 ) +#define DEFINE_SCRIPT_PROXY_3V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 3 ) +#define DEFINE_SCRIPT_PROXY_4V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 4 ) +#define DEFINE_SCRIPT_PROXY_5V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 5 ) +#define DEFINE_SCRIPT_PROXY_6V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 6 ) +#define DEFINE_SCRIPT_PROXY_7V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 7 ) +#define DEFINE_SCRIPT_PROXY_8V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 8 ) +#define DEFINE_SCRIPT_PROXY_9V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 9 ) +#define DEFINE_SCRIPT_PROXY_10V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 10 ) +#define DEFINE_SCRIPT_PROXY_11V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 11 ) +#define DEFINE_SCRIPT_PROXY_12V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 12 ) +#define DEFINE_SCRIPT_PROXY_13V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 13 ) +#define DEFINE_SCRIPT_PROXY_14V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 14 ) + +//----------------------------------------------------------------------------- + +#include "tier0/memdbgoff.h" + +#endif // IVSCRIPT_H diff --git a/public/vscript/vscript_templates.h b/public/vscript/vscript_templates.h new file mode 100644 index 00000000..6e8e9005 --- /dev/null +++ b/public/vscript/vscript_templates.h @@ -0,0 +1,521 @@ +//========== Copyright (c) 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: +// +//============================================================================= + +#ifndef VSCRIPT_TEMPLATES_H +#define VSCRIPT_TEMPLATES_H + +#include "tier0/basetypes.h" + +#if defined( _WIN32 ) +#pragma once +#endif + +#define FUNC_APPEND_PARAMS_0 +#define FUNC_APPEND_PARAMS_1 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 1 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); +#define FUNC_APPEND_PARAMS_2 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 2 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); +#define FUNC_APPEND_PARAMS_3 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 3 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); +#define FUNC_APPEND_PARAMS_4 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 4 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); +#define FUNC_APPEND_PARAMS_5 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 5 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); +#define FUNC_APPEND_PARAMS_6 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 6 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); +#define FUNC_APPEND_PARAMS_7 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 7 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); +#define FUNC_APPEND_PARAMS_8 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 8 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); +#define FUNC_APPEND_PARAMS_9 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 9 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); +#define FUNC_APPEND_PARAMS_10 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 10 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_10 ) ); +#define FUNC_APPEND_PARAMS_11 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 11 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_10 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_11 ) ); +#define FUNC_APPEND_PARAMS_12 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 12 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_10 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_11 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_12 ) ); +#define FUNC_APPEND_PARAMS_13 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 13 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_10 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_11 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_12 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_13 ) ); +#define FUNC_APPEND_PARAMS_14 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 14 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_10 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_11 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_12 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_13 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_14 ) ); + +#define DEFINE_NONMEMBER_FUNC_TYPE_DEDUCER(N) \ + template \ + inline void ScriptDeduceFunctionSignature(ScriptFuncDescriptor_t *pDesc, FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \ + { \ + pDesc->m_ReturnType = ScriptDeduceType(FUNCTION_RETTYPE); \ + FUNC_APPEND_PARAMS_##N \ + } + +FUNC_GENERATE_ALL( DEFINE_NONMEMBER_FUNC_TYPE_DEDUCER ); + +#define DEFINE_MEMBER_FUNC_TYPE_DEDUCER(N) \ + template \ + inline void ScriptDeduceFunctionSignature(ScriptFuncDescriptor_t *pDesc, OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \ + { \ + pDesc->m_ReturnType = ScriptDeduceType(FUNCTION_RETTYPE); \ + FUNC_APPEND_PARAMS_##N \ + } + +FUNC_GENERATE_ALL( DEFINE_MEMBER_FUNC_TYPE_DEDUCER ); + +//------------------------------------- + +#define DEFINE_CONST_MEMBER_FUNC_TYPE_DEDUCER(N) \ + template \ + inline void ScriptDeduceFunctionSignature(ScriptFuncDescriptor_t *pDesc, OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const ) \ + { \ + pDesc->m_ReturnType = ScriptDeduceType(FUNCTION_RETTYPE); \ + FUNC_APPEND_PARAMS_##N \ + } + +FUNC_GENERATE_ALL( DEFINE_CONST_MEMBER_FUNC_TYPE_DEDUCER ); + +#define ScriptInitMemberFuncDescriptor_( pDesc, class, func, scriptName ) if ( 0 ) {} else { (pDesc)->m_pszScriptName = scriptName; (pDesc)->m_pszFunction = #func; ScriptDeduceFunctionSignature( pDesc, (class *)(0), &class::func ); } + +#define ScriptInitFuncDescriptorNamed( pDesc, func, scriptName ) if ( 0 ) {} else { (pDesc)->m_pszScriptName = scriptName; (pDesc)->m_pszFunction = #func; ScriptDeduceFunctionSignature( pDesc, &func ); } +#define ScriptInitFuncDescriptor( pDesc, func ) ScriptInitFuncDescriptorNamed( pDesc, func, #func ) +#define ScriptInitMemberFuncDescriptorNamed( pDesc, class, func, scriptName ) ScriptInitMemberFuncDescriptor_( pDesc, class, func, scriptName ) +#define ScriptInitMemberFuncDescriptor( pDesc, class, func ) ScriptInitMemberFuncDescriptorNamed( pDesc, class, func, #func ) + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +template +inline ScriptFunctionBindingStorageType_t ScriptConvertFreeFuncPtrToVoid( FUNCPTR_TYPE pFunc ) +{ +#if defined(_PS3) || defined(POSIX) + COMPILE_TIME_ASSERT( sizeof( FUNCPTR_TYPE ) == sizeof( void* ) * 2 || sizeof( FUNCPTR_TYPE ) == sizeof( void* ) ); + + if ( sizeof( FUNCPTR_TYPE ) == 4 ) + { + union FuncPtrConvertMI + { + FUNCPTR_TYPE pFunc; + ScriptFunctionBindingStorageType_t stype; + }; + + FuncPtrConvertMI convert; + convert.pFunc = pFunc; + return convert.stype; + } + else + { + union FuncPtrConvertMI + { + FUNCPTR_TYPE pFunc; + struct + { + ScriptFunctionBindingStorageType_t stype; + intptr_t iToc; + } fn8; + }; + + FuncPtrConvertMI convert; + convert.fn8.iToc = 0; + convert.pFunc = pFunc; + if ( !convert.fn8.iToc ) + return convert.fn8.stype; + + Assert( 0 ); + DebuggerBreak(); + return 0; + } +#else + return ( ScriptFunctionBindingStorageType_t ) pFunc; +#endif +} + +template +inline FUNCPTR_TYPE ScriptConvertFreeFuncPtrFromVoid( ScriptFunctionBindingStorageType_t p ) +{ +#if defined(_PS3) || defined(POSIX) + COMPILE_TIME_ASSERT( sizeof( FUNCPTR_TYPE ) == sizeof(void*)*2 || sizeof( FUNCPTR_TYPE ) == sizeof(void*) ); + + if ( sizeof( FUNCPTR_TYPE ) == 4 ) + { + union FuncPtrConvertMI + { + FUNCPTR_TYPE pFunc; + ScriptFunctionBindingStorageType_t stype; + }; + + FuncPtrConvertMI convert; + convert.pFunc = 0; + convert.stype = p; + return convert.pFunc; + } + else + { + union FuncPtrConvertMI + { + FUNCPTR_TYPE pFunc; + struct + { + ScriptFunctionBindingStorageType_t stype; + intptr_t iToc; + } fn8; + }; + + FuncPtrConvertMI convert; + convert.pFunc = 0; + convert.fn8.stype = p; + convert.fn8.iToc = 0; + return convert.pFunc; + } + + +#else + return (FUNCPTR_TYPE) p; +#endif +} + +template +inline ScriptFunctionBindingStorageType_t ScriptConvertFuncPtrToVoid( FUNCPTR_TYPE pFunc ) +{ + typedef FUNCPTR_TYPE FuncPtr_t; + size_t funcPtrSize = sizeof( FuncPtr_t ); funcPtrSize; + +#if defined(_PS3) || defined(POSIX) + return ScriptConvertFreeFuncPtrToVoid( pFunc ); +#else + + if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) ) ) + { + // simple inheritance + union FuncPtrConvert + { + void *p; + FUNCPTR_TYPE pFunc; + }; + + FuncPtrConvert convert; + convert.pFunc = pFunc; + return convert.p; + } +#if MSVC + else if ( ( IsPlatformWindowsPC32() && ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + sizeof( int ) ) ) || + ( IsPlatformWindowsPC64() && ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + sizeof( int ) * 2 ) ) ) + { + // multiple and virtual inheritance + struct MicrosoftUnknownMFP + { + void *p; + int m_delta; + }; + + union FuncPtrConvertMI + { + MicrosoftUnknownMFP mfp; + FUNCPTR_TYPE pFunc; + }; + + FuncPtrConvertMI convert; + convert.pFunc = pFunc; + if ( convert.mfp.m_delta == 0 ) + { + return convert.mfp.p; + } + AssertMsg( 0, "Function pointer must be from primary vtable" ); + } + else if ( ( IsPlatformWindowsPC32() && ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + ( sizeof( int ) * 3 ) ) ) || + ( IsPlatformWindowsPC64() && ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + ( sizeof( int ) * 4 ) ) ) ) + { + // unknown_inheritance case + struct MicrosoftUnknownMFP + { + void *p; + int m_delta; + int m_vtordisp; + int m_vtable_index; + }; + + union FuncPtrConvertMI + { + MicrosoftUnknownMFP mfp; + FUNCPTR_TYPE pFunc; + }; + + FuncPtrConvertMI convert; + convert.pFunc = pFunc; + if ( convert.mfp.m_delta == 0 ) + { + return convert.mfp.p; + } + AssertMsg( 0, "Function pointer must be from primary vtable" ); + } +#elif defined( GNUC ) + else if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + sizeof( int ) ) ) + { + AssertMsg( 0, "Note: This path has not been verified yet. See comments below in #else case." ); + + struct GnuMFP + { + union + { + void *funcadr; // If vtable_index_2 is even, then this is the function pointer. + int vtable_index_2; // If vtable_index_2 is odd, then this = vindex*2+1. + }; + int delta; + }; + + GnuMFP *p = (GnuMFP*)&pFunc; + if ( p->vtable_index_2 & 1 ) + { + char **delta = (char**)p->delta; + char *pCur = *delta + (p->vtable_index_2+1)/2; + return (void*)( pCur + 4 ); + } + else + { + return p->funcadr; + } + } +#else +#error "Need to implement code to crack non-offset member function pointer case" + // For gcc, see: http://www.codeproject.com/KB/cpp/FastDelegate.aspx + // + // Current versions of the GNU compiler use a strange and tricky + // optimization. It observes that, for virtual inheritance, you have to look + // up the vtable in order to get the voffset required to calculate the this + // pointer. While you're doing that, you might as well store the function + // pointer in the vtable. By doing this, they combine the m_func_address and + // m_vtable_index fields into one, and they distinguish between them by + // ensuring that function pointers always point to even addresses but vtable + // indices are always odd: + // + // // GNU g++ uses a tricky space optimisation, also adopted by IBM's VisualAge and XLC. + // struct GnuMFP { + // union { + // CODEPTR funcadr; // always even + // int vtable_index_2; // = vindex*2+1, always odd + // }; + // int delta; + // }; + // adjustedthis = this + delta + // if (funcadr & 1) CALL (* ( *delta + (vindex+1)/2) + 4) + // else CALL funcadr + // + // The G++ method is well documented, so it has been adopted by many other + // vendors, including IBM's VisualAge and XLC compilers, recent versions of + // Open64, Pathscale EKO, and Metrowerks' 64-bit compilers. A simpler scheme + // used by earlier versions of GCC is also very common. SGI's now + // discontinued MIPSPro and Pro64 compilers, and Apple's ancient MrCpp + // compiler used this method. (Note that the Pro64 compiler has become the + // open source Open64 compiler). + +#endif + else + AssertMsg( 0, "Member function pointer not supported. Why on earth are you using virtual inheritance!?" ); + return NULL; +#endif +} + +template +inline FUNCPTR_TYPE ScriptConvertFuncPtrFromVoid( ScriptFunctionBindingStorageType_t p ) +{ +#if defined(_PS3) || defined(POSIX) + return ScriptConvertFreeFuncPtrFromVoid( p ); +#else + + if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) ) ) + { + union FuncPtrConvert + { + void *p; + FUNCPTR_TYPE pFunc; + }; + + FuncPtrConvert convert; + convert.p = p; + return convert.pFunc; + } + +#if MSVC + if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + sizeof( int ) ) ) + { + struct MicrosoftUnknownMFP + { + void *p; + int m_delta; + }; + + union FuncPtrConvertMI + { + MicrosoftUnknownMFP mfp; + FUNCPTR_TYPE pFunc; + }; + + FuncPtrConvertMI convert; + convert.mfp.p = p; + convert.mfp.m_delta = 0; + return convert.pFunc; + } + if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + ( sizeof( int ) * 3 ) ) ) + { + struct MicrosoftUnknownMFP + { + void *p; + int m_delta; + int m_vtordisp; + int m_vtable_index; + }; + + union FuncPtrConvertMI + { + MicrosoftUnknownMFP mfp; + FUNCPTR_TYPE pFunc; + }; + + FuncPtrConvertMI convert; + convert.mfp.p = p; + convert.mfp.m_delta = 0; + return convert.pFunc; + } +#elif defined( POSIX ) + AssertMsg( 0, "Note: This path has not been implemented yet." ); +#else +#error "Need to implement code to crack non-offset member function pointer case" +#endif + Assert( 0 ); + return NULL; +#endif +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_0 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_1 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_1 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_2 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_2 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_3 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_3 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_4 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_4 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_5 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_5 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_6 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_6 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_7 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_7 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_8 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_8 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_9 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_9 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_10 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_10 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_11 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_11 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_12 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_12 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_13 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_13 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_14 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_14 + +#define SCRIPT_BINDING_ARGS_0 +#define SCRIPT_BINDING_ARGS_1 pArguments[0] +#define SCRIPT_BINDING_ARGS_2 pArguments[0], pArguments[1] +#define SCRIPT_BINDING_ARGS_3 pArguments[0], pArguments[1], pArguments[2] +#define SCRIPT_BINDING_ARGS_4 pArguments[0], pArguments[1], pArguments[2], pArguments[3] +#define SCRIPT_BINDING_ARGS_5 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4] +#define SCRIPT_BINDING_ARGS_6 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5] +#define SCRIPT_BINDING_ARGS_7 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6] +#define SCRIPT_BINDING_ARGS_8 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7] +#define SCRIPT_BINDING_ARGS_9 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8] +#define SCRIPT_BINDING_ARGS_10 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9] +#define SCRIPT_BINDING_ARGS_11 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9], pArguments[10] +#define SCRIPT_BINDING_ARGS_12 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9], pArguments[10], pArguments[11] +#define SCRIPT_BINDING_ARGS_13 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9], pArguments[10], pArguments[11], pArguments[12] +#define SCRIPT_BINDING_ARGS_14 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9], pArguments[10], pArguments[11], pArguments[12], pArguments[13] + + +#define DEFINE_SCRIPT_BINDINGS(N) \ + template \ + class CNonMemberScriptBinding##N \ + { \ + public: \ + static bool Call( ScriptFunctionBindingStorageType_t pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \ + { \ + Assert( nArguments == N ); \ + Assert( pReturn ); \ + Assert( !pContext ); \ + \ + if ( nArguments != N || !pReturn || pContext ) \ + { \ + return false; \ + } \ + *pReturn = (ScriptConvertFreeFuncPtrFromVoid(pFunction))( SCRIPT_BINDING_ARGS_##N ); \ + if ( pReturn->m_type == FIELD_VECTOR ) \ + pReturn->m_pVector = new Vector(*pReturn->m_pVector); \ + return true; \ + } \ + }; \ + \ + template \ + class CNonMemberScriptBinding##N \ + { \ + public: \ + static bool Call( ScriptFunctionBindingStorageType_t pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \ + { \ + Assert( nArguments == N ); \ + Assert( !pReturn ); \ + Assert( !pContext ); \ + \ + if ( nArguments != N || pReturn || pContext ) \ + { \ + return false; \ + } \ + (ScriptConvertFreeFuncPtrFromVoid(pFunction))( SCRIPT_BINDING_ARGS_##N ); \ + return true; \ + } \ + }; \ + \ + template \ + class CMemberScriptBinding##N \ + { \ + public: \ + static bool Call( ScriptFunctionBindingStorageType_t pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \ + { \ + Assert( nArguments == N ); \ + Assert( pReturn ); \ + Assert( pContext ); \ + \ + if ( nArguments != N || !pReturn || !pContext ) \ + { \ + return false; \ + } \ + *pReturn = (((OBJECT_TYPE_PTR)(pContext))->*ScriptConvertFuncPtrFromVoid(pFunction))( SCRIPT_BINDING_ARGS_##N ); \ + if ( pReturn->m_type == FIELD_VECTOR ) \ + pReturn->m_pVector = new Vector(*pReturn->m_pVector); \ + return true; \ + } \ + }; \ + \ + template \ + class CMemberScriptBinding##N \ + { \ + public: \ + static bool Call( ScriptFunctionBindingStorageType_t pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \ + { \ + Assert( nArguments == N ); \ + Assert( !pReturn ); \ + Assert( pContext ); \ + \ + if ( nArguments != N || pReturn || !pContext ) \ + { \ + return false; \ + } \ + (((OBJECT_TYPE_PTR)(pContext))->*ScriptConvertFuncPtrFromVoid(pFunction))( SCRIPT_BINDING_ARGS_##N ); \ + return true; \ + } \ + }; \ + \ + template \ + inline ScriptBindingFunc_t ScriptCreateBinding(FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \ + { \ + typedef FUNCTION_RETTYPE (*Func_t)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N); \ + return &CNonMemberScriptBinding##N::Call; \ + } \ + \ + template \ + inline ScriptBindingFunc_t ScriptCreateBinding(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE (FUNCTION_CLASS::*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \ + { \ + typedef FUNCTION_RETTYPE (FUNCTION_CLASS::*Func_t)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N); \ + return &CMemberScriptBinding##N::Call; \ + } \ + \ + template \ + inline ScriptBindingFunc_t ScriptCreateBinding(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE (FUNCTION_CLASS::*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const ) \ + { \ + typedef FUNCTION_RETTYPE (FUNCTION_CLASS::*Func_t)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N); \ + return &CMemberScriptBinding##N::Call; \ + } + +FUNC_GENERATE_ALL( DEFINE_SCRIPT_BINDINGS ); + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#endif // VSCRIPT_TEMPLATES_H diff --git a/tier2/tier2_logging.cpp b/tier2/tier2_logging.cpp new file mode 100644 index 00000000..0c2dcdba --- /dev/null +++ b/tier2/tier2_logging.cpp @@ -0,0 +1,123 @@ +//============ Copyright (c) Valve Corporation, All rights reserved. ============ +// +// Tier2 logging helpers. +// +//=============================================================================== + +#include "tier2_logging.h" +#include "filesystem.h" +#include "interfaces/interfaces.h" + +CFileLoggingListener::CFileLoggingListener() +{ + for ( int i = 0; i < MAX_SIMULTANEOUS_LOGGING_FILE_COUNT; ++ i ) + { + m_OpenFiles[i].Reset(); + } + for ( int i = 0; i < MAX_LOGGING_CHANNEL_COUNT; ++ i ) + { + m_FileIndices[i] = INVALID_LOGGING_FILE_HANDLE; + } +} + +CFileLoggingListener::~CFileLoggingListener() +{ + for ( int i = 0; i < MAX_SIMULTANEOUS_LOGGING_FILE_COUNT; ++ i ) + { + if ( m_OpenFiles[i].IsOpen() ) + { + g_pFullFileSystem->Close( m_OpenFiles[i].m_FileHandle ); + m_OpenFiles[i].Reset(); + } + } +} + +LoggingFileHandle_t CFileLoggingListener::BeginLoggingToFile( const char *pFilename, const char *pOptions, const char *pPathID /* = NULL */ ) +{ + int fileHandle = GetUnusedFileInfo(); + if ( fileHandle != INVALID_LOGGING_FILE_HANDLE ) + { + m_OpenFiles[fileHandle].m_FileHandle = g_pFullFileSystem->Open( pFilename, pOptions, pPathID ); + } + return fileHandle; +} + +void CFileLoggingListener::EndLoggingToFile( LoggingFileHandle_t fileHandle ) +{ + Assert( fileHandle >= 0 && fileHandle < MAX_SIMULTANEOUS_LOGGING_FILE_COUNT ); + /* if the file had any channels associated with it, disassociate them. */ + if ( fileHandle != INVALID_LOGGING_FILE_HANDLE ) + { + for ( int i = 0 ; i < MAX_LOGGING_CHANNEL_COUNT ; ++i ) + { + if ( m_FileIndices[i] == fileHandle ) + UnassignLogChannel( i ); + } + } + + g_pFullFileSystem->Close( m_OpenFiles[fileHandle].m_FileHandle ); + m_OpenFiles[fileHandle].Reset(); +} + +void CFileLoggingListener::AssignLogChannel( LoggingChannelID_t channelID, LoggingFileHandle_t loggingFileHandle ) +{ + Assert( loggingFileHandle >= 0 && loggingFileHandle < MAX_SIMULTANEOUS_LOGGING_FILE_COUNT ); + Assert( m_OpenFiles[loggingFileHandle].IsOpen() ); + Assert( channelID >= 0 && channelID < MAX_LOGGING_CHANNEL_COUNT ); + m_FileIndices[channelID] = loggingFileHandle; +} + +void CFileLoggingListener::UnassignLogChannel( LoggingChannelID_t channelID ) +{ + Assert( channelID >= 0 && channelID < MAX_LOGGING_CHANNEL_COUNT ); + m_FileIndices[channelID] = INVALID_LOGGING_FILE_HANDLE; +} + +void CFileLoggingListener::AssignAllLogChannels( LoggingFileHandle_t loggingFileHandle ) +{ + Assert( loggingFileHandle >= 0 && loggingFileHandle < MAX_SIMULTANEOUS_LOGGING_FILE_COUNT ); + Assert( m_OpenFiles[loggingFileHandle].IsOpen() ); + for ( int i = 0; i < MAX_LOGGING_CHANNEL_COUNT; ++ i ) + { + m_FileIndices[i] = loggingFileHandle; + } +} + +void CFileLoggingListener::UnassignAllLogChannels() +{ + for ( int i = 0; i < MAX_LOGGING_CHANNEL_COUNT; ++ i ) + { + m_FileIndices[i] = INVALID_LOGGING_FILE_HANDLE; + } +} + +void CFileLoggingListener::Log( const LoggingContext_t *pContext, const char *pMessage ) +{ + if ( ( pContext->m_Flags & LCF_CONSOLE_ONLY ) != 0 ) + { + return; + } + + Assert( pContext->m_ChannelID >= 0 && pContext->m_ChannelID < MAX_LOGGING_CHANNEL_COUNT ); + int nFileIndex = m_FileIndices[pContext->m_ChannelID]; + if ( nFileIndex >= 0 && nFileIndex < MAX_SIMULTANEOUS_LOGGING_FILE_COUNT ) + { + // Shouldn't be trying to log to a closed file. + Assert( m_OpenFiles[nFileIndex].IsOpen() ); + + g_pFullFileSystem->Write( pMessage, Q_strlen( pMessage ), m_OpenFiles[nFileIndex].m_FileHandle ); + g_pFullFileSystem->Flush( m_OpenFiles[nFileIndex].m_FileHandle ); + } +} + +int CFileLoggingListener::GetUnusedFileInfo() const +{ + for ( int i = 0; i < MAX_SIMULTANEOUS_LOGGING_FILE_COUNT; ++ i ) + { + if ( !m_OpenFiles[i].IsOpen() ) + { + return i; + } + } + return INVALID_LOGGING_FILE_HANDLE; +} diff --git a/vscript/CMakeLists.txt b/vscript/CMakeLists.txt new file mode 100644 index 00000000..81cdbbee --- /dev/null +++ b/vscript/CMakeLists.txt @@ -0,0 +1,125 @@ +#//----------------------------------------------------------------------------- +#// VSCRIPT.VPC +#// +#// Project Script +#//----------------------------------------------------------------------------- +cmake_minimum_required(VERSION 3.16) +project(vscript_client) +set(SRCDIR "${CMAKE_SOURCE_DIR}") +set(CMAKE_MODULE_PATH ${SRCDIR}/cmake) +set(OUTBINNAME "vscript_client") +set(OUTBINDIR ${SRCDIR}/../game/bin) + +include(${CMAKE_MODULE_PATH}/detect_platform.cmake) +include(${CMAKE_MODULE_PATH}/source_dll_base.cmake) + +add_definitions(-DVSCRIPT_DLL_EXPORT) +add_definitions(-DLUA_MOD_CASE_INSENSITIVE) + +if( POSIX ) + include_directories(./languages/squirrel/include) + include_directories(./languages/squirrel/sqplus) + #include_directories(./languages/lua/lua-5.1.4/src) +endif() + + +target_sources(${OUTBINNAME} PRIVATE vscript.cpp) +#target_sources(${OUTBINNAME} PRIVATE ./languages/gm/vgm/vgm.cpp) +#if( NOT LINUX ) +# target_sources(${OUTBINNAME} PRIVATE ./languages/lua/vlua/vlua.cpp) +#endif() +target_sources(${OUTBINNAME} PRIVATE ./languages/squirrel/vsquirrel/vsquirrel.cpp) + +#TODO: nut builder for nut_init.h? Or hardcode like the others +# $File ".\languages\squirrel\vsquirrel\init.nut" +# $CustomBuildStep +# { +# $CommandLine "$SRCDIR\devtools\srcsrv\perl\bin\perl.exe $SRCDIR\devtools\bin\texttoarray.pl $(InputPath) g_Script_$(InputName)> $(InputDir)$(InputName)_nut.h" [$WINDOWS] +# $CommandLine "perl $SRCDIR\devtools\bin\texttoarray.pl $(InputPath) g_Script_$(InputName)> $(InputDir)$(InputName)_nut.h" [$POSIX] +# $Description "$(InputFileName) produces $(InputName)_nut.h" +# $Outputs "$(InputDir)$(InputName)_nut.h" +# } + +#GameMonkey +#EXCLUDED FROM BUILD! +#$ExcludedFromBuild "Yes" +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmArraySimple.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmByteCode.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmByteCodeGen.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmCodeGen.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmCodeGenHooks.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmCodeTree.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmCrc.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmDebug.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmFunctionObject.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmHash.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmIncGC.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmLibHooks.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmListDouble.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmLog.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmMachine.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmMachineLib.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmMem.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmMemChain.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmMemFixed.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmMemFixedSet.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmOperators.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmParser.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmScanner.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmStream.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmStreamBuffer.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmStringObject.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmTableObject.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmThread.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmUserObject.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmUtil.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/gm/gmVariable.cpp") + +#BINDS +#EXCLUDED FROM BUILD! +#$ExcludedFromBuild "Yes" +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/binds/gmArrayLib.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/binds/gmCall.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/binds/gmGCRoot.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/binds/gmGCRootUtil.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/binds/gmHelpers.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/binds/gmMathLib.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/binds/gmStringLib.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/binds/gmSystemLib.cpp" ) +#target_sources(${OUTBINNAME} PRIVATE "./languages/gm/src/binds/gmVector3Lib.cpp") + +#Squirrel +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/squirrel/sqapi.cpp" ) +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/squirrel/sqbaselib.cpp" ) +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/squirrel/sqclass.cpp" ) +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/squirrel/sqcompiler.cpp" ) +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/squirrel/sqdebug.cpp" ) +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/squirrel/sqfuncstate.cpp" ) +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/squirrel/sqlexer.cpp" ) +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/squirrel/sqmem.cpp" ) +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/squirrel/sqobject.cpp" ) +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/squirrel/sqstate.cpp" ) +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/squirrel/sqtable.cpp" ) +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/squirrel/sqvm.cpp" ) +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/sqdbg/sqrdbg.cpp" ) +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/sqdbg/sqdbgserver.cpp" ) + +#sqstdlib +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/sqstdlib/sqstdaux.cpp") +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/sqstdlib/sqstdblob.cpp" ) +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/sqstdlib/sqstdmath.cpp" ) +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/sqstdlib/sqstdrex.cpp" ) +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/sqstdlib/sqstdstream.cpp" ) +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/sqstdlib/sqstdstring.cpp" ) + +#sqplus +# $File ".\languages\squirrel\sqplus\SquirrelBindingsUtilsWin32.cpp" [!$PS3&&!$POSIX] +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/sqplus/SqPlus.cpp" ) +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/sqplus/SquirrelBindingsUtils.cpp" ) +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/sqplus/SquirrelObject.cpp" ) +target_sources(${OUTBINNAME} PRIVATE "./languages/squirrel/sqplus/SquirrelVM.cpp" ) + + +# $Folder "Lua" [ !$X360 && !$PS3 && !$LINUX] + +target_link_libraries(${OUTBINNAME} libvstdlib_client mathlib_client) \ No newline at end of file diff --git a/vscript/_vpc_/manifest_vscript/linux64/manifest.txt b/vscript/_vpc_/manifest_vscript/linux64/manifest.txt new file mode 100644 index 00000000..0dd0ccbf --- /dev/null +++ b/vscript/_vpc_/manifest_vscript/linux64/manifest.txt @@ -0,0 +1,412 @@ +// ----------------------------------------- // +// File generated by VPC // +// ----------------------------------------- // + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmArrayLib.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmArrayLib.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmArrayLib.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmCall.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmCall.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmCall.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmGCRoot.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmGCRoot.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmGCRoot.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmGCRootUtil.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmGCRootUtil.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmGCRootUtil.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmHelpers.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmHelpers.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmHelpers.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmMathLib.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmMathLib.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmMathLib.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmStringLib.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmStringLib.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmStringLib.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmSystemLib.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmSystemLib.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmSystemLib.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmVector3Lib.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmVector3Lib.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/binds/gmVector3Lib.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmArraySimple.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmArraySimple.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmArraySimple.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmByteCode.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmByteCode.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmByteCode.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmByteCodeGen.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmByteCodeGen.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmByteCodeGen.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmCodeGen.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmCodeGen.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmCodeGen.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmCodeGenHooks.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmCodeGenHooks.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmCodeGenHooks.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmCodeTree.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmCodeTree.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmCodeTree.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmCrc.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmCrc.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmCrc.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmDebug.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmDebug.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmDebug.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmFunctionObject.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmFunctionObject.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmFunctionObject.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmHash.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmHash.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmHash.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmIncGC.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmIncGC.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmIncGC.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmLibHooks.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmLibHooks.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmLibHooks.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmListDouble.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmListDouble.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmListDouble.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmLog.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmLog.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmLog.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmMachine.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmMachine.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmMachine.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmMachineLib.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmMachineLib.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmMachineLib.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmMem.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmMem.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmMem.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmMemChain.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmMemChain.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmMemChain.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmMemFixed.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmMemFixed.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmMemFixed.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmMemFixedSet.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmMemFixedSet.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmMemFixedSet.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmOperators.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmOperators.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmOperators.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmParser.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmParser.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmParser.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmScanner.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmScanner.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmScanner.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmStream.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmStream.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmStream.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmStreamBuffer.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmStreamBuffer.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmStreamBuffer.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmStringObject.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmStringObject.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmStringObject.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmTableObject.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmTableObject.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmTableObject.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmThread.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmThread.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmThread.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmUserObject.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmUserObject.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmUserObject.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmUtil.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmUtil.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmUtil.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmVariable.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmVariable.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/src/gm/gmVariable.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/public/tier0/memoverride.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/public/tier0/memoverride.cpp +Release output file: /home/lwss/Documents/cstrike15_src/public/tier0/memoverride.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/vgm/vgm.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/vgm/vgm.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/gm/vgm/vgm.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/vscript.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/vscript.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/vscript.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/vsquirrel/vsquirrel.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/vsquirrel/vsquirrel.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/vsquirrel/vsquirrel.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqplus/SqPlus.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqplus/SqPlus.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqplus/SqPlus.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqplus/SquirrelBindingsUtils.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqplus/SquirrelBindingsUtils.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqplus/SquirrelBindingsUtils.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqplus/SquirrelObject.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqplus/SquirrelObject.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqplus/SquirrelObject.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqplus/SquirrelVM.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqplus/SquirrelVM.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqplus/SquirrelVM.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqstdlib/sqstdaux.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqstdlib/sqstdaux.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqstdlib/sqstdaux.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqstdlib/sqstdblob.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqstdlib/sqstdblob.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqstdlib/sqstdblob.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqstdlib/sqstdmath.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqstdlib/sqstdmath.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqstdlib/sqstdmath.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqstdlib/sqstdrex.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqstdlib/sqstdrex.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqstdlib/sqstdrex.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqstdlib/sqstdstream.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqstdlib/sqstdstream.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqstdlib/sqstdstream.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqstdlib/sqstdstring.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqstdlib/sqstdstring.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqstdlib/sqstdstring.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqapi.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqapi.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqapi.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqbaselib.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqbaselib.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqbaselib.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqclass.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqclass.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqclass.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqcompiler.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqcompiler.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqcompiler.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqdbg/sqdbgserver.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqdbg/sqdbgserver.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqdbg/sqdbgserver.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqdebug.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqdebug.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqdebug.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqfuncstate.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqfuncstate.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqfuncstate.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqlexer.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqlexer.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqlexer.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqmem.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqmem.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqmem.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqobject.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqobject.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqobject.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqdbg/sqrdbg.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqdbg/sqrdbg.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/sqdbg/sqrdbg.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqstate.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqstate.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqstate.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqtable.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqtable.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqtable.cpp +Containing unity file: +PCH file: + +Source file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqvm.cpp +Debug output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqvm.cpp +Release output file: /home/lwss/Documents/cstrike15_src/vscript/languages/squirrel/squirrel/sqvm.cpp +Containing unity file: +PCH file: + diff --git a/vscript/languages/gm/EditorHighlighters/ConTEXT/Highlighters/GameMonkey.chl b/vscript/languages/gm/EditorHighlighters/ConTEXT/Highlighters/GameMonkey.chl new file mode 100644 index 00000000..d2e233ee --- /dev/null +++ b/vscript/languages/gm/EditorHighlighters/ConTEXT/Highlighters/GameMonkey.chl @@ -0,0 +1,219 @@ +////////////////////////////////////////////////////////////////////////////// +// +// GameMonkey highlighter written by Matthew Riek and Greg Douglas +// +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +// language name + +Language: GameMonkey Script + + +////////////////////////////////////////////////////////////////////////////// +// default file filter +// note: if more than one extension is associated, eg: +// C/C++ files (*.c,*.cpp,*.h,*.hpp)|*.c;*.cpp;*.h;*.hpp + +Filter: GameMonkey Script files (*.gm)|*.gm + + +////////////////////////////////////////////////////////////////////////////// +// help file which will be invokend when F1 is pressed + +HelpFile: + + +////////////////////////////////////////////////////////////////////////////// +// language case sensitivity +// 0 - no +// 1 - yes + +CaseSensitive: 1 + + +////////////////////////////////////////////////////////////////////////////// +// comment type: LineComment - comment to the end of line +// BlockCommentBeg - block comment begin, it could be +// multiline +// BlockCommentEnd - block comment end + +LineComment: // +BlockCommentBeg: /* +BlockCommentEnd: */ + + +////////////////////////////////////////////////////////////////////////////// +// identifier characters +// note: characters shouldn't be delimited, except arrays +// array of chars could be defined as from_char..to_char + +IdentifierBegChars: a..z A..Z _ +IdentifierChars: a..z A..Z _ 0..9 + +////////////////////////////////////////////////////////////////////////////// +// numeric constants begin characters +// note: characters shouldn't be delimited, except arrays +// array of chars could be defined as from_char..to_char +// number always starts with 0..9 except when NumConstBeg +// defines other + +NumConstBegChars: 0..9 + + +////////////////////////////////////////////////////////////////////////////// +// numeric constants characters +// note: characters shouldn't be delimited, except arrays +// array of chars could be defined as from_char..to_char +// number always starts with 0..9 except when NumConstBeg +// defines other + +NumConstChars: 0..9 abcdefxABCDEFX . + + +////////////////////////////////////////////////////////////////////////////// +// escape character + +EscapeChar: + + +////////////////////////////////////////////////////////////////////////////// +// keyword table +// note: delimited with spaces, lines could be wrapped +// you may divide keywords into two groups which can be +// highlighted differently + +// op codes + +KeyWords1: if + else + for + foreach + in + and + or + while + dowhile + function + return + continue + break + null + global + local + member + table + true + false + this + +KeyWords2: + +KeyWords3: + debug + typeId + typeName + typeRegisterOperator + typeRegisterVariable + sysCollectGarbage + sysGetMemoryUsage + sysGetDesiredMemoryUsageHard + sysGetDesiredMemoryUsageSoft + sysSetDesiredMemoryUsageHard + sysSetDesiredMemoryUsageSoft + sysSetDesiredMemoryUsageAuto + sysTime + doString + globals + threadTime + threadId + threadAllIds + threadKill + threadKillAll + thread + yield + exit + assert + sleep + signal + block + stateSet + stateSetOnThread + stateGet + stateGetLast + stateSetExitFunction + tableCount + tableDuplicate + print + format + +////////////////////////////////////////////////////////////////////////////// +// string delimiter: StringBegChar - string begin char +// StringEndChar - string end char +// MultilineStrings - enables multiline strings, as perl +// has it + +StringBegChar: "`' +StringEndChar: "`' +MultilineStrings: 0 + + +////////////////////////////////////////////////////////////////////////////// +// use preprocessor: 0 - no +// 1 - yes +// note: if yes, '#' and statements after it will be +// highlighted with Preprocessor defined colors + +UsePreprocessor: 0 + + +////////////////////////////////////////////////////////////////////////////// +// highlight line: 0 - no +// 1 - yes +// note: if yes, current line will be highlighted + +CurrLineHighlighted: 0 + + +////////////////////////////////////////////////////////////////////////////// +// colors +// note: first value is foreground, second is background color +// and third (optional) represents font attribute: +// B - bold +// I - italic +// U - underline +// S - strike out +// attributes can be combined: eg. B or BI +// as value, it could be used any standard windows color: +// clBlack, clMaroon, clGreen, clOlive, clNavy, +// clPurple, clTeal, clGray, clSilver, clRed, clLime, +// clYellow, clBlue, clFuchsia, clAqua, clLtGray, +// clDkGray, clWhite, clScrollBar, clBackground, +// clActiveCaption, clInactiveCaption, clMenu, clWindow, +// clWindowFrame, clMenuText, clWindowText, clCaptionText, +// clActiveBorder, clInactiveBorder, clAppWorkSpace, +// clHighlight, clHighlightText, clBtnFace, clBtnShadow, +// clGrayText, clBtnText, clInactiveCaptionText, +// clBtnHighlight, cl3DDkShadow, cl3DLight, clInfoText, +// clInfoBk +// as value, it could be used hex numeric constant too: +// $BBGGRR - BB: blue, GG: green, RR: red, eg: $FF6A00 + +SpaceCol: $00D0D0D0 clNavy +Keyword1Col: clYellow clNavy +Keyword2Col: clYellow clNavy +Keyword3Col: $00FFC0C0 clNavy +IdentifierCol: $00D0D0D0 clNavy +CommentCol: $00C0C000 clNavy +NumberCol: clLime clNavy +StringCol: clLime clNavy +SymbolCol: clWhite clNavy +PreprocessorCol: $00FFFF40 clNavy +SelectionCol: clNavy $00D0D0D0 +CurrentLineCol: clBlack clYellow + +OverrideTxtFgColor: 0 +BlockAutoindent: 0 +BlockBegStr: +BlockEndStr: +MatchedBracesCol: $008080FF clNavy diff --git a/vscript/languages/gm/EditorHighlighters/Crimson Editor/Link/extension.gm b/vscript/languages/gm/EditorHighlighters/Crimson Editor/Link/extension.gm new file mode 100644 index 00000000..a4da0b9e --- /dev/null +++ b/vscript/languages/gm/EditorHighlighters/Crimson Editor/Link/extension.gm @@ -0,0 +1,2 @@ +LANGSPEC:GM.SPC +KEYWORDS:GM.KEY diff --git a/vscript/languages/gm/EditorHighlighters/Crimson Editor/Spec/gm.key b/vscript/languages/gm/EditorHighlighters/Crimson Editor/Spec/gm.key new file mode 100644 index 00000000..c39548b7 --- /dev/null +++ b/vscript/languages/gm/EditorHighlighters/Crimson Editor/Spec/gm.key @@ -0,0 +1,80 @@ +[-COMMENT-:GLOBAL] +# GM GameMonkey LANGUAGE KEYWORDS FILE FOR CRIMSON EDITOR +# FIRST EDITED BY Greg + +[KEYWORDS0:GLOBAL] +if +else +for +foreach +in +and +or +while +dowhile +function +return +continue +break +null +global +local +member +table +true +false +this + +[KEYWORDS1:GLOBAL] +debug +typeId +typeName +typeRegisterOperator +typeRegisterVariable +sysCollectGarbage +sysGetMemoryUsage +sysSetDesiredMemoryUsageHard +sysSetDesiredMemoryUsageSoft +sysSetDesiredMemoryUsageAuto +sysGetDesiredMemoryUsageHard +sysGetDesiredMemoryUsageSoft +sysTime +doString +globals +threadTime +threadId +threadAllIds +threadKill +threadKillAll +thread +yield +exit +assert +sleep +signal +block +stateSet +stateSetOnThread +stateGet +stateGetLast +stateSetExitFunction +tableCount +tableDuplicate +print +format + +[KEYWORDS2:GLOBAL] + +[KEYWORDS3:GLOBAL] + +[KEYWORDS4:GLOBAL] + +[KEYWORDS5:GLOBAL] + +[KEYWORDS6:GLOBAL] + +[KEYWORDS7:GLOBAL] + +[KEYWORDS8:GLOBAL] + +[KEYWORDS9:GLOBAL] diff --git a/vscript/languages/gm/EditorHighlighters/Crimson Editor/Spec/gm.spc b/vscript/languages/gm/EditorHighlighters/Crimson Editor/Spec/gm.spc new file mode 100644 index 00000000..6f82316c --- /dev/null +++ b/vscript/languages/gm/EditorHighlighters/Crimson Editor/Spec/gm.spc @@ -0,0 +1,34 @@ +# GM GameMonkey LANGUAGE SPECIFICATION FILE FOR CRIMSON EDITOR +# FIRST EDITED BY Greg + +$CASESENSITIVE=YES +$DELIMITERS=~`!@#$%^&*()-+=|\{}[]:;"',.<>/? + +# There are currently no preprocessor commands in GM, but there maybe sometime +# $KEYWORDPREFIX=# + +# Bit of a hack to highlight binary constants +# Will need to set Variable color to match constants +#$BINARYMARK=0x Be nice if this was available +# The below lines don't behave as expected +#$VARIABLEPREFIX=0b +#$SPECIALVARIABLECHARS=0b + +$HEXADECIMALMARK=0x + +$ESCAPECHAR=\ +$QUOTATIONMARK1=" +$QUOTATIONMARK2=' + +# In the current version of CrimsonEditor (3.51), the $QUOTATIONMARK3 +# tag isn't supported, but maybe it will be in the future... +#$QUOTATIONMARK3=` + +$LINECOMMENT=// +$BLOCKCOMMENTON=/* +$BLOCKCOMMENTOFF=*/ +$INDENTATIONON={ +$INDENTATIONOFF=} +$PAIRS1=() +$PAIRS2=[] +$PAIRS3={} diff --git a/vscript/languages/gm/EditorHighlighters/PSPad editor/Syntax/GameMonkey Script.INI b/vscript/languages/gm/EditorHighlighters/PSPad editor/Syntax/GameMonkey Script.INI new file mode 100644 index 00000000..f7e39b7d --- /dev/null +++ b/vscript/languages/gm/EditorHighlighters/PSPad editor/Syntax/GameMonkey Script.INI @@ -0,0 +1,76 @@ +;PSPad user HighLighter definition file +[Settings] +Name=GameMonkey Script +HTMLGroup=0 +Label=0 +FileType=*.gm +CommentString= +SlashComment=1 +CComment=1 +SlashComment=1 +IndentChar= +UnIndentChar= +TabWidth=2 +CaseSensitive=1 +SingleQuote=1 +DoubleQuote=1 +KeyWordChars=_ +CodeExplorer=ftUnknown +[KeyWords] +[ReservedWords] +and= +break= +continue= +dowhile= +else= +false= +for= +foreach= +function= +global= +if= +in= +local= +member= +null= +or= +return= +table= +this= +true= +while= +[KeyWords2] +assert= +block= +debug= +doString= +exit= +format= +globals= +print= +signal= +sleep= +stateGet= +stateGetLast= +stateSet= +stateSetExitFunction= +stateSetOnThread= +sysCollectGarbage= +sysGetDesiredMemoryUsage= +sysGetMemoryUsage= +sysSetDesiredMemoryUsage= +sysTime= +tableCount= +tableDuplicate= +thread= +threadId= +threadIds= +threadKill= +threadKillAll= +threadTime= +typeId= +typeName= +typeRegisterOperator= +typeRegisterVariable= +yield= +[KeyWords3] diff --git a/vscript/languages/gm/bin/StripCR.exe b/vscript/languages/gm/bin/StripCR.exe new file mode 100644 index 0000000000000000000000000000000000000000..b8a1a91057ba1a58c1b71fda0cb76a430c51b2b7 GIT binary patch literal 5632 zcmeHLeQZzYzrwm`@*3y+32p(X(b1Bo&AGtZ9wp7s15 z5RI@>HyiF-v`X!?i55+aPE*x=bQ5%GnKZYiO*_$vtsfx4q^OI!hmuvMA2jPS?tb?^ zCv{O*P5Y~zdZlykIp?19yXTzy5x=x=eUQu`gj9eiC1eOAYd+q8a%W+>df_wGj%f4xja85o2Q$CeFxgf-x^*YzU zC1YmxMcPy7+}ve0AB07Ko-x1lJunGpf&@&9z5-2xYz~+c^p)&MVSx5Ck1?k?9O~ZI zQ`l^dn_^9;+3gN=d8s_a)-qhVrd%WSv;n4RI2g={ZoSoSJwPcni%stb_un3{o^m1; z!);C^9Dy$CxfiC{lk>6@4r3nhFawCC)N?=dPddh~hQbztU6ujYW%*#JXInR0KHFbI z0{h#t{Vt-f%l5m8?vsCKhhc|c76&c`gZftj2?sS8H1!C4xf(1NFy@qivCOOzyDZGYlpoS)=iVWo9O?=-6@#I`GWS~s2Ux6dXW_%0P155G%R0e9Y8Z$-AI8+fPV0pMfHZcG>!q~@2gaGF^=qhY zUao<$-#P?^jc2QERKGQg!!7`9b;(z@u-#){rpH+*^f-&8l*eDd+Id`G$|KKC1`i|{ zv`$P?>OI$zZJ(rrgFNPkpfTIu4fRBGRal>x?M1V&&Dsd|r2?)05fY&F`*>f+`z5^p zD*A*=p129y9Cf0|(j-Zcgu~hhAs8I1^yYm9Q?l4fi5b*05B8^;s@O3w9EA(dBH&Zy zEkXU!BW!)Yxwg(7&DAqLm#lLSg8YTV64|u~OZ@};>7}?nHNcA6YjxEkUeLwK3cfak;uXuU_>{xZSPp{tn29w$E zg}Fb-=fu%m|0J%ACkgOiwyG7u(ri^58>mNy(ya19$hoK|%B59YI9rm)*>`m5FcFf_n^ZM;f8aiRTB!^M1Pg4hVzd zh<{K#3wqU0J(~c52Pr3>Y8vi$C0teuoPx58!4U?>szW^w!^~_SL6pV_HO^AwRV#%} z#$#g^bH|$`K5*%`=VD+5S<&%~x^r zM)Yh;%@?f4Va8vh@fv=+2l9Gl^M*HlCyWh&L2&}{&WEvSOnQw8>LK90Me3<2jV?Y8 zibdGDnVtBqS1fvqx#j$b%pRV}Mh4gOQsES>UkV#}2P*a9DXGEnsKN25xn-m?&}E7f zImz;y;^eT1Z1KK`6M&B%MVO?3Q(ZdW>=k`!BTn`mK&16P-uuyKoB2i?SJ8T%Eyi|V z<|@6;Z9M}N+^YiB>nf~20sj57*XQ3q8*D8k-17WID1Hx=!{X?9@CW+&khzK73R4_4 z35qj^p8m+K$cm#CW3O2|;l?nQFpTSLj8Pkd4gVF!4Ge?UZ((5*{A@<&AQrpM*hg=k z)i2HS+>746_ZJ?SpmeB+6)xO{ai8f7(mfW(U(<`m7+_AS39qB(#JzEe*X7ZRi|wrBI)l{h#bg1z}aN?HW))R__vSr;5@@nx<-k8i^Ph*2u6_(=0|76$@x8 z239A0|E1!Y3{OE5q*PjGRhq{8Fiu{?xbo2`r|s4&5mnQq2x@Mmc1l=1hONO@rBo_H zY0b?_ucGczgov6-v0Y2DYN>qt?R;+KXJYDX;0%^z++_Of7k%V;5Nk|UJU((CXi7eV zXYd?oO1>U{U>1T{Yvuj_*0C4&G+qRDemgqXcBU3Sv2eEI&bC9BpF8})@wQ%8ugJ>n z87;EiK35&nV~2zTl98t5hIABXpuFwCm#=h9xyI&Mep?Z{F!P~n9Z*?V|H>xg&P_E9 zcTfklvTZd@nS}TUB^)Lyl01JBPScMc341EKSI-h=|nuni`QZ z8M4Q5r=+*5Q6pI@;TnSMHX4%F=a;mYis+Px)S?;+tH5i_dQ&{o%N6+B!{inNZ;7IB zlG#?Sj}p>UrY)@lb)IQE`!c$e+7wSoYclNRXB@d(?ARc-d6)4`BbOZ^_6SB&i1q)W Y{jBuneOxZ=mtncyQ7(MWf95OjZ%gc={r~^~ literal 0 HcmV?d00001 diff --git a/vscript/languages/gm/bin/bison.exe b/vscript/languages/gm/bin/bison.exe new file mode 100644 index 0000000000000000000000000000000000000000..4881bf604916b1331205bdd5f32624831e2a2331 GIT binary patch literal 196096 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

Y%&V;-)+npYsq0 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 YcfY#-V)nRSdX^UC{nvVu+I#bV0CDn^H~;_u literal 0 HcmV?d00001 diff --git a/vscript/languages/gm/bin/flex.exe b/vscript/languages/gm/bin/flex.exe new file mode 100644 index 0000000000000000000000000000000000000000..58f10ce3561e8b693e3e4d3ef247bc6507c38608 GIT binary patch literal 181248 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 z zoM*P8kIgPf!jSYd-mni;P?Uv{j0Lg2;2uI8tveC`$$+^V&<6k}Ks+E05CsSWgaT}+ zlZj{-blsP(0n-!5-2XKv{s86xpg9=X)m26}5t?^WfMPC#ul!JxQ)6G}q#{mE(<8qg zY4YQPmoS8*6!?TgH0V+CQ0AjFBk=MRw0se_9N{$`=n)?Ap+`winU~TQ0B?_i9!wtB zfN&GwCLjW9=|TWKgiHMBQPQOR)^7L(OL-{|7(&UHoHX_^=Z3FWA zNQg?>9L7}np)%PQDRzCMohznW7P%4=4q6)D_`(RVJb_7iq+k9;Hm{ktRQs zcUw2KWgPMgL90QLkIH%mVF94VxK9t^bk$xd-#Vnpk5U%Bl$X*dZy3TdJsF?;oyZ^G z0e3#a*-{*(%a4-2G7qJb97>)P*Mzw33fiReN`xB$t$>a?C;YB-PBd;J&6kMcQOco# z&6FR?8;o#Qv}GLf0}mKEV~2bugtGx1Wg^_J_$u=g%}Kypub@df--hrGDUQk6@7fG-?K&WJx7J&B4pxy{Mrkt{du%e<0hWc6TF(6Rjj9VLf7L&dzr zN~THg^bk*i9iT<>QGeKjcZzH1K%e61*{L%!-}s71cb!6}K*V+RP+qE66Vmel*%ECU z$LNve3dMWVFe62A`YzH6kw&;x3Z509*VRKj3AaswyX#kQ^-qcP?}jhyqv;p&5Dw0m zxQM?PyApxvkz_D|9zAp6lU!NwN!R)CNiWOcQ-4|wpZe`a`2O%;hfnj`UGQaI+kS;t z6L9Gf;1jP)@QK$g_{2+FB=Wi)KJf~LPrUAfPrRbxlgx$ii6_x${S}^@6}Z8hjmXjY zk?W&TfgAk`xWs!p$gKYb9FmhOHZo=!_{3w76qfyQ2$OCjq#moK|2#-X(AjQjmuM*6$5kC+C|-!8^&VgTX(0sb4(JK-zoEXpx*F9GP0 z>7G!~q4?HcNFRx_{^`wnrXpck*mduAubW904X>A8>9b04ecK330ttp7>(vC@(! zW`s`^ZxtlO&WH#b9~~c$S=Y2_6WrHOjK$V$qjApk7~|Z>umVF`SckMkDeY-4BV$Hs zDckdp!}&{|xhNd-Tt6J5WEC#M%*!VuC;#cpyqxTeLY!sb6v|wbkzbILzo>wFf}^ZB zDJobR4w|%hf>2P7>$r;sc%McK06j##HIQbOK(pjmafj=#)~QgKZz!ua&g=k zRmMUb`sK^v?ZCqkS=JI@CM2iMNP-6Fip3@0jFNmh&f@-nG9jiQpH98FBBGX6kZsN= zgxGWz^MX$X!wdDzkZ>%jjBK+P&a=qH%9LRdwK6Fq3x_Va)HYO=k%^z6L^6nTuY%WN zvvmp1O)`rX7ju(T8ChaV8BqXA4wo@EtI!&olSjNKK%d1+7UF0sGaLIVY7y5DG_#gu z=jC%c(szy(s7ts3p7#th7Y)h<`HONEi;7@pU1qKY{EKlghNC^4uUYW>jhNkoT6S(p zu{C2+cFxnd{Rf=F3{n1UGj0}&;YCZJ6wGx+3K^M&g&B01ijyR68u3SotY)Ke-t@U> zME7yiSSqAjRFIL4lUKX}3x|jqbTnCzZKTXB*=R)TqD)*eWG=Eox481O7!Ai#Q1B$j z-NxD!Zcb$^&9oNNJ;9l*Y}TTJyhVi>#W+LrO=eA@or^6po8xm97G)MK{`O$^BI1%O&ed5iT zPn%~H9rI!~u8;**04;hJ+Vl)XtRx|#Kcv{?WjMNDLTB02iy@$y-nd6%l4i%m z%NFfD71c2ch?CFhT%=DjEI|U!L2+b{8nzOZw48jL4JT1ux;WBCUJm4D;dMUAmV%|p zS!hUk4`mi{HKoaC4!S>_@Y?CUhc!p!2FEM}YX7aODJOf#U`i!!W5XoJPZXwf96PBTdNV+)E9 zH_<3YlQs6($8;aq^8eHHsQ)ed-y)gmp=g+Gvb843))vDC!{{x{f(`zeG&6mMNvfTA zI)gWh4VXJc^(8h9F`jFt7#xuoqtB84d!8N*^k|?*13en((Lj#|dNk0ZfgTO?XrM;} zJsRlI!2bs|P;TUG8;nfw@zbWKid%?S>Wa&Jue7{^#n>*uh8=bS*mf;)Df8x;^Rd1TWh3apDYXQC>&-GjKIO zJ2l6=RHVgqDDRA!OS17LM`wE2Ug<7g+#V3=dC4$+VL^#CI&X1D8KSWlS3t4e<(!!i zk6kwG-r(zi#l@ZJQECack(3w;esiRI{YVz`QrYNH{hQ-_0KNbPeyZoLd}m%W*nYZL z8Ol8F?*pZ}<5qjupJEG@n~mS${Kt?FqL~nqgX32A(D|zhaRmiNWpdAZj|O@)(4&DK z4fJTBM*}??=+Qur26{Bmqk$d`{NJnrHTbD;Lp}n(ZDzr;(Fb80{?i@cjqoYG622e& zM)>q?fdIcZd=q}FtUr7Ud>won{9yPS;a`N0pRu>WV-L|GPA|Z%?;_rY_@++rKFERJ z2tqu`rNi%_!DEk1&xTNF7xCGMH+G8eiyLP6ZUgZu4es`mj{;P{9|V6h{6P4X@Pptt z!XFG@fd3SHd~jh~2|pPAMfhRxe}o?={Vp3YIHg<*x`{9CBA&{*uABJnUBugfU)4o? zZ+u{Mk}6MnWO;hyMd&8Jy__|k6TE4qo_ z*iHQQZsIGuiLdV_{$w}tLO1d4-Nb9C(@BqrqM|>K#07T~Pk${e`V)K`laB8&B$~^^ zRorI0%i)j+6}4w~SRJY2Leco-^s!MY4i{wH;pGTlSAtkji0WMymd%@wwJkAw07CxgrR%&tAgK9KYq!6uA-^%-{aeAuQ#h-?SE%T_PC4T zhwlAqRMe1O{b%?E`jzziWMFvE@jm~&^wRky-^~9uqxI9v`))1nbNaU8+s6$Y-7E9j zJ3o%Pw7UJYPr-mVL*TgMV}=cD_g&xm@6RrORCO%)v!A~-oLhaqr1_iH^KHw1%DT4Y z=7}5Euf$yb=cS7`Zv=cZ?A5!U9yx#D;$APSPjX>5ANlE?){no7yLkEHiPrS*U%vFL zOEciPkYjf~Fk<)6{y|ZinyVYX`SA4oru^3HuD5ls4AYN_82!em=MC>0vPM_jea{$S z{Gmx3CMQi86L#0cZzkm4`{0Nt`qa1<`Yh>vHqaFGZlA%vIk&d-t~ZE8oh|^t(@2b=TGjXQwu`X zhSuT5!(X_ow?Tbp;2o0&KCX54zSsXDADxT8>F;{M-`B6=`t^%XwCrygdFjICJ1@?@ zX#MG@pHBSv^7m8E7oVN-`RLDQoc*hi{*&d#;p?kzZ2I|L^{jyM;BSZDJv@2vto{ML z%6wn*UF=iudWy5C-{|!~pQ*jyQ7`qe`3z9s-K*ADxc1v0Yra2v;obIvYgaE$zhJs} z`{gZHZ(R;+ZTj~BVb}SFZ;pLYbKyyQwUp+bYGoKTWeCGR=>btlfS6zG8RqOMv&)-y=TzjweZQI{=>c-?= zpAQTka8Y&7)ylTbm%sA)xAx6}9}SAt4I7X;czN);+x!QAJ}5b`^tMeyKDa$$c+BXC z@pn%8Fnr>;Ki%Ey?op$!+?6t7=7`tsS~ALKOxA?#$*TL)CT5L(%@BN#>+Uo|+mQM` z^Zd7H|E4P%xN+d^0}2QIZpe$b#}CdJ@IhZ)@5J8kYfQa9REMfwa$Rz@aCV2w*@t6(|-Q`@~fAAxN_u{TKy;ge`+5dd?UCfa7e%Fs^_^kH7B*# zw5feAsK52OPp$Er?{}9^){VTY)2=jJ3BLB%E6Xm_{@}R$T6@Til}@^La=vx@_u3yUEtTI6_`0B}h2$M3RM-EU2=wKtDlO}*A|W3uZ>^)r1x?r-hy7x1EP`=H!l`;eaof8VF* zrysvA`S_uRxkn0*Rvb?{b@=?Nmyi4U2i!k+;=t=ZF;{zCnAXzV@?Xu*p8Nf`*IFOB z@}g?8I_;L($D&&~^j~)`xXae(->x;jH+xSQ^vC}9-F&%ie@l8>!L7Z$9?{12`G;z& zYk>ORK9>i46YLt+cvs5kFAVu1?+xBFs62S!$QgGJ9T{``UQNBvLd`w>hXoD^4DRoz zJ2fPD#QxB?N4E{zdB>HZeMVjgdwojSv=h^Q7nyf|dibdcUrh9$n0W7;F#)48M?Z4! zJr7))`Jw5LDX-7@F8Q0pwU54%Fev`otdyB0G4rGSrWZsWxbNn~)swO!)23w_)elaO zczepchqzg9CA<=MWJ>DT$@)JJaR&R|aYMguboKbjlg{72eu{C*Ba_~}=lq?Y4XFv* z8T8!XvBA&Yk)wZd_%p$i12+0D^x4pNL{P8cBko*!$8Q1)v~Or;_Acl%O8XbzGi`If z3~qS*z{vdxwVxiFeQMX)$S=M4Jxi+h)}L$` z@{zsajSpY0-%|Tw&A|^g?4I}5rtQCZ{lULpePhDgQ+5w}uXJBt%?}4}98gtV-;?w1 zqyK8#Icvw<9l`&o{Kx%oe)9J^OhpHutpf&99tWBR5a{{6bJ=im2zTl!V`nZKXD z@a2|ot1e{zSpNOeZzrGX{pqEXZ=HGItKWXL_lw9c0-C=3`oF#%axU!4b0;HC)HbgF z=-ZEW9jiMYd_1f%;7G-h&Bs=M{P4%FV}Ct5@bG;#nFn4z=yUk>bm@_}y3oCEzW3<|lj;sOjy#cg?C(d$9V)N==fQ~T!5_@t_hnVT>eDs74mzuE z)ubKLeK@*qO6|Lg?E!3!&D%6FR8U>2GySoRAXS2H}XXf5>=KOPJ z?mu^SW|NsrGGCJKd*yka_kFLXugVE6`CPH1Qqb_VXV2IY)it$&^x9;t(hGTqZzY!C zrehtkufSKBIB)|VM>;@Z5F25-{LP4F5F-he^`hl?HX(xej!a`-6y6j0bKcOaD95SK znR6MNi65}0*akv1V=9}@=%oB48sHh&bI5)rBsG+IC}+Y=C=OkU{DTdE&G<^}dT2s+ zdE8IRfj8i%(U!8`^11|SVXknlz*Trj-@=4o6Xi75J;f(w#+tdGgSr<>1J^FFoYyk% zT%gV3;^2QF`@-S>->=_c!^=yTbT77Bd|~leaPeY6pvm09>Fu7N%X0e~>q)C5n^YS! z>zig|15~hI@K*Rrzgd5t=)I7xcT>+tZ-rolwU^#OJxH-9_Yq!U$AJ=LDSTNQ1&yhr z)nd&LO$c-Y+6ftIUMiy%KNMS(393Rhq=|sLfpOp*9H5#pv1Z_XE3NK)WoMa9*^FYF zye~N|dAK5nvN;uj6%mz(sx9hvG)^?7Hl;NXYR4)Mmjk8Oi#Fz8$R=lvXMwrX3XT`1 z7p%yenDP?Zv)_VKo_|GBHvD+_`|V#&Mp^pC^zy&uX`BCe|C*oLnxgvh=^L1q zn0=*qeYsV6a%oS|zv3AcqWVQ0Y5h@>gvrH9GYt=lRbP{%dH?fc}6m&ul5r z0=TYR&w|)Y?9#zRO%{Qmse(~yU_+u&bD4Z)9io}A7MWcLYe469APSs2(YbDrY< z&1a9F(;U=aKDEJhs>4aUbEX!i&K!M$ow`IdoxDkq=jdYHspnuh;5Ojy;Sg`jc6D}I z=2hW(+4G#+Ue^Uq>um?DhRnB_%oaOZ`dFcM(;dBxzB}J@I_Diukh_g9u!MAgAKHw7Ip?0%yf9f@BO1Lj>=K7fnd{<4I=QlK+IHPBpsrMD9V$WXd z9TtuH7c3(5-vOuj31$K8a?|TZD=9@brDkvJ?pvO;FLU>HTk7d)*Xe;;XV^5`0CrlN zRO_o2-WC|6D_ksV2?HfX;N}vzxWiB?vK_R?im?;gSBj~lWnEC?qw?t`twohNuk+Uy z9juJ2f7AG6pr!jp`_In#otf>q4Oy+$?b^<~?$7PsEn6E(s}h=-?Gbgk)lTJE)dj`B zt0Ec`>kf1nx4KkRHh*ulD_c{&vf_C8%d%^QR|+0x>;I8`Z}@c~9Z1vrZT{2qC;PYH z&%>|AKTN-Ry?_7yXJXCE{SOIov2l)m`^$C7KJSv>i#{d1pGe&O+UvXG1L;fU zm$)A*es2F^oj&n9EvF@Ocdn=sDcjV1vdN)8Yv`k#V641u@{$@SFV`5$Tzb&1^d9x7zhY!O zM*9Ss1!WWCa1;hgqjQIOclmhUHF1sLl;JMnZEgm23h6KSiPBE}#l6N@MGByc*(&Tp z##_<|DHHbs@RLCOm3@x~Z9A!Lr`uk1eI6Q=FjR+RixErg4*Cb$3oc7IYPdw~Z_6+} zZ}-*ov)MOevEfToeJgjvS4JM<7iP1qa2BSQ|)v)@oR33K!&^v`fV z;ma9JT0Iqqv&Xn=#XoBajbc^`8p0?r4hVa#b$k(f*R=-)f zDO?sN*-yWW`FKYkbfzaI-_nqBWx6k&Vbf3>YaNDQ7x7R)2`gra5 zI`y*k%X5~UTD(8JVAZNcOJ{xYjrH*NIO^VQr?FdV&$n!{158d?GK@BhFPV5-Eik%m zvB2iM%~E@U-7(ipt0c#*4zBh}yQ6NQKAmoM{-xG$a?y_x4lB2?5zQsL5NU(xK6I+`5)T2i>^*s@K58yuD=q{C$A~^Q`uUtFS4btX|NO+cHPuK6p_!I4)86%2%r{YL-A&>SL3Z za+RVKTT4|$a^X~S-=6j8%x$dQnf1YL9|Ff$$ESf0!l^ap=yx6v~r*u)t^Rk38 z$4X(v=F*^w_VPA#B7YX0TtNDA(i6qFd1@GDkU2i4*# zPF4S^ZmZ3y*i(O~46L42G+b6(lvRo=s4ckuZ(sJbzi(2oX(oT(q$=Jvz7{2}O{6^F zK7I9AoqXq6SW>}*viLi%E$%;kG<4&Cug5xiQFKtWQ8ah~d(r*;y7QLTs;|{t)7*G) z{reqC?AyD{2ehy94}{<6e>}+AnzOT{wm7Tue3N72pT3Sr?SKH zJY_Vx5;=?sAV-s^NV#GflUe?XiB~`oUw|>zT(gFP>+M<5KhQ_KUo_+{Iq6 z{cg>|1`PR)&RsIaY^uF`r{g^bE336OskZa%B(|_qhh3TDLdVb6D#r!pt;S3FKMYW^ zJ(1q;|?x zLKpTT=8?7-4#poOyHJ_*sdPSTHs?3{3jYenjB6(NLpyA6OOR;vPp`>!*3{Y4qGq1= zD_t1t?+}rCVRAct>yLF8 zcMU|H-hkP%bi2uxduvZ^i&(#5U2Ui=C}ysM|H$+^UhY#)O`SKLJk`xRaO%P70n<%g zPPhd*U@bm~53+rD2XQsTw2l{&Yb{I4!8-3eaZyZpWW(Ybc4bU`a22EGXmwC!Mu}&^ z!g5t5(mtj8=FlI1F=d`V_djc6@&eUX&*TR;_E5zjMC7Y~}Owb0mYHhUq>KyNO%p+&s17Yt_&4!ZK#n)`~L~K~-m}R#XQxoA+Fo6wB4>ROA=B5Wfigg15)Ke5wKxZA&AB8;!tU}*`VPq}iByX$1H|y=zLAGOFd#5^1*)n~*U&g$s`JAA( zrIDeO@C_lf^`^_$u8djwAu?w5rj3?c9d`umU$i%UU(Al*dq%f!-BP||U^8RawymqS z-rh2~?ZCEUQTkEX9WI;n*O!Iw56fKDyzFAw%B5j5eP^x;SRUZ&HqR@`9p@6`>g#pR zv&r+MSBZPg)FhuvzJ8uhtSNR`*2$Jjj0i>q!?Sw+T$rU#Kfs*J>fvh9DYD(k2MOJ?QG$Q=4h{O*t(^d#qT z#{>5pv*IGIy|~IfKXDFo=FWMivx_g;#mcX?-q;Y|baU{Q+1)SqyzXHi&V8ZxCjI@l zujJGnzh~v<7qk}TRyEhUbpGjDG_q7R4CR4LawPQ?q zaf!etBvJBja?04sNsRR1^h{(Am+{6CC z-YB3`#?a~5d*DkNi*kn835toX=wo1=rb}6&PL&NP?oW(N{FAW9)#HJ3dpH=n1Eztt zR43Xo{&T~-76JC@mTlHPR^O~$%zl|#o7}XzZ~Dvhoq4XsNsDP#O~#unhV-Th)^N*6ec5{_M72Noz4uRhqC^$?sJ49tQcouVk`4V@WuPo&SD3g zT68zKU}rnqxh{NjxUSFo z$d&hY0l;u>7Gja zCB}igZVDHRg{zd|a(C5S^$WGFwjRC;eNj%xuSv~EZw|K)*bjf}d)t3^By%`Wl0NF8 zc7@$=A8{mIcKwWANte=F1PIqexSiv~j}$L8P?^?R#yi@$xOupHWO~WmlRam6es#}q z7rG?6dAp~%`?y9p?Q=|YCOUs}V|oO5)VLEo{XO{}^IcClZL#mRrCP_CUlFen4+`wX zX(m5e@$~a_0eddroYu}D^Xdc{%mVIHE{1Qzf6epNzr!sQFEoiTs~3Maj@DamwAiTD zP|wuWWKwTP#A1r*Zj?0aN757gZSq`V2L2BAAD)E|0p5WY=nBk1piKQ-eOmfn<~PZo zV2%;SMh7%KEq(q2cLopkhIa1PrCZ0km$%2Z?`%C=yuCcW2rT}Ux%lsnZ`AkkZvtMw zdTsNZ_@pOs>!Xw>?;p>2a{iV2CFjMtXZeY{UkyFknH-*M{Bid8eJRABW&f7_H7R~y z*;E_QfNjn0-8jr0x05fBqsTODGkzY`jz$;J42h-~lNHtn%|!My?ZO-z-7k6?`{1YS zpV~W(z?UaYCp@#*7ldvMaOs-cXzc1$9=Phx$Ohn{f1=y3xW~u16Br?#tLK_ zGnX@SsGSsq8cI&17vSoEsmgS@fh=Umy05I`cym%?VvTkAs_NY_^8m+r#4++LTjR~Zu!OI#9nha>M04a_*pT3Yf zjdp~2ioTU<$T6n55^oVUX^J6%>aN6gY%KHo>Rao48%i1}E!>tRE#(by4R>m3bu(*kRBo;~RZgv3Q}Mg( zzv^{Wu@&8wigI0qS$?5(deM&ZSEVgQwWViDUKL+0887~sKQ(_Wi;$6&IhlItw}0x~ zU+mQOj{~2*J{rBT`LHi3Iw|tWo)@zos^V;K&$yOw{(r}t|MzE{b6(NMt{#e`U4M1+ z!>#SHpW~Wie%!lq^XP4d+qJi{;?^b1zx(pm^V_@b?!3>w%e{FzVg9XEPj@`}_B8hS zgBORN*gs2pz3#j0w`2OdoI4datHCB^M^ayuWaX%d!WB7!TSQKwS&8C!0~Q>cR;L+m zo2SD5j`OSLtO?pM$6%piVf6g?Ma=n&=H|`w4p8`J%s60%tY( zU7A_%eP>FuE5%LELEseSj59xIJKtiz-8qYUW~W6fte&%Ylw0Ue$>o8YEu%w!8)#K$ zt6EE4%WoEG3lHVRRDLg8UTRstuKY)hL2X0z^6qcl5d(8av=ZXDliFb1N82=shikQ# zig0ZK{0^>>UZ4D-V+_M42PJ1G9#5*}jKMR~y#sHC{RXyl2|G=?>zYWdzU|k$hMSFg zE)VMWTMknu6cCqGi5lv@# zZU?6x_gX&V+MHhRf!S;Q9{KtQMEdRZ8}Y|XpD}aFbpM&x7PQRSKR0#ugumC^&wfHb z%h{iN;Au2(j{8aX7mgb|wayfW0?RKJQ!KI#pPO71XK;^+Pq7N<^QcX5CQc)rRIDBA z8D2cp++y6nuf4tFam!#E+TdKrs7@LW4LaTJ(Wy{Suo9)TPZxmdSGlVnlPWR$+bJ;WjEE! zy>*6sUWV_&h1ceM3gQGm4?e!kVEO9M(2&o|ESBd5A76o4G_q)J*z`raR>(rPEO`@d zyX@Ptg<+H>AD5q7mJ_ygY2?al!C#m7Ep%FNcVXZ>$~?~83x3`K&u8ZAqQQN3Q(ele z)ebDw+SarjvB>SEw>Ta2yGA8O*(cvY;kMy{Nj7V@3(J>-!$K?{=5AD%^~@xE+Q?! z1s(}*3VIm4E$qkA(Ur}iM?=;Gg)Zoy;~n5LeVdQH*D6O_n~V0a__obMG_C;_-TARC!8k}{%0I(iLp(!?Qu!6akG=Vo%2ZbP|eWu z=lQN&eqwoGgfh}@P4fmx)TJ#xyRx=a@9NmLZujl&q;0~@T~T+pYB!cem2TX&Va|ry zO%5Ab8ywfoiY!{Ueyu8k7AcOXS+XJHS$b^+bry2=Ny^+$~vjNc#gP~nsV@C%#>-A2#AMKdL=8IXw;JyV_IQZ9BSK%SZbAC?h56W6B^c z8F;U8M_}|R@E+I+7!l9msf-PbJRXi2ZX^`x8`SA}b9amSnFW;3qCS?pNF!Xxf_SA2 zFRm3khDQ^$FbY{!yb;O)rUm60X$|!`j!t_@Y{MNSv+>!a_jr3uuQm|~*0N;PlZnF{ z2U}X9PGOUIo3{5syHE4B>hijMZGReTJH|Ro``1Z+4Udi4@oKf zhmBSlIGc_c#OP<}T{V3s_R{Y(T+FvNIA}aav|5yEUZsE9w8iwT`9-rJiyrIcmbXmC zESDM+EhBBGTYR;V1B`oVsX-;(EOO4i`g7o6LTXgTT3UCpVr-m75YTM zJ@zO+fZR@%;heEJOon=cx?RSRwDgblB(?{(J?NZl3}{R5o>Oz8qo+~RdaP+fGoz)d zEwin5IBIbHWRg64++G={?N+~o%iw+LSoxC)+T@M#tX|dNf!=4m_`ZscjUBUFYg>|9 zR<-fXWY~`rEbmq8+S_D|)h0Mc@Aa13g*`P(3p|{p}vwno(5LSpo>LI`mF8 z3waM7(y0md5anc3{ADVhQUzWoJOLAsf5a2GVeNY@6_=o~0$tF(m<>3P2vU~g`)Skh z<76{>BJ~ihn;O72;wB2p=t{vu&Q#tUZW?mF47pD!7&#UgVKmRhCq4Tl%tQZQZjvRujf7|jPQNv{P9M3vT|W*#nKt}DHgr`?TMDaK8 z*_^p$c>TXkJ!|dP)vdi0adP?ZknAO=f~a$RXN6B&F=f~*&aJ@-uv=*U!x$E%FpuIz z;4;{;2jvI!YQ*{d_)e|3LG(kIh){{4`5Hvd8)vAV0( zx5uEnzdvc<$e)=#MjN4Ms>y}W-l#u6o<9QnQXJgG2UL{{Ks~qV~``w z>Y-h)#d(V&6TUgm?1uS6^DKjV<`?v@7#$Q93RiMIFc};QWrT)ccjHHp<$xKyMYR&m zRT(NQCktiO!|`KFCv7Ho$ht>MhAak3I$ky0s7xt+pC0x1S0?&r_|N*k5r0nqs7@RG z8T_~XcVe2`pEdthX3Wb%{$&-P%z2c5H}gR8iqf`{?z*IkXEi-lkE>Q!dskkn5tnJp zvx@JQ#%G&UBo}Qgy<4IzIZ{+z0ag~*U8E}IcVN!USZyD`@kGyV{NzAW}DS@>k`v1#st%Mmb=Uzo504MRy$2St@l~I zwkGOW>LL5P4uKBEwm&QmSZ%fWW{xw#SYS+tO`e$CwsJPluzGB_*m$bhW6Km%wJ1eg z!n-1_;5Zpt^SwpuSu6OZ3>s}K4yA0z-2?jZm%(u$RCPx6Os5y>m)ObjMhYj^55N+K z!IA+|Z&hb#OKbb-hK44O7OU3j4XZojJFoPcb}RcU`$NX}$?Mg(p=;0$AOW<)&d~L@ zeuOwf1UOhKm0M2SlBvd888?tqNbw>TxHhg!(P@RN3Idyc!_}|f3Wfrs? z@<(imU#LBla#pqApnjy;HzOmHrxuOIsb*^|H(2hl0j=Ly_?jD9KeWDObKmNf*$dO_ zCT?ac%#Rzl8t_bGjfRC(eG?HNn8$bFOXx||SON``m$l?)=>l(2!iyS>|5qmOHaRniG>_oAo8r zGyO&eDNB-B`*$oeF6UkD{X*Z|(Bg{HPgPGUo;KX9OKmJ@^=|py!|aJ9`z33U zKbY)PhC&B0yMPg}7c0fHaK_XGViaXIQ;)4;TxWW*aqMtbjWCpCZe~%CHP`&Iq^1S zG4nR#8g(}N3rml)n>$Y5!;NPg;uLd6nOOD+qn}wv(`Tc!7u03sARX#pi5UiFLFV#5 zW9Y#1uBjcjJE%<&&4IO-8Y60nHO=MMD%O;>SHCast9o0zqPnH}YSTair}Jf(_b78D zOKzkfLqDJ#Y%M01#9~OfPq?+BAhDt06T?4dGNa4pCoGL@$W{%u{#O3B-z;=eNNd3E zhHavAs{1;Z5Z7(4(;WXf#W=+~HrT}2W?G-OBAYxmk23mf_{{W_F=#Subirt~>0eW= z`G00xjTai>jaj0Vf}i|b{8q+RrhvAaasXe3OT&1p^HlmW6S-#0Vf??*u|X4^`mC$X zugOezI=)uUD>p9e&5g>b$p}bWnz84{m2XAg7(cIn%}GU5a=x~G7k}^h&ii%tPx|+& zKiB@r|N5t|&fi&-Rq~_!b9r=4QSF=NZ>_#G`A1| zyhpuI%h9Y<{gkGRhYXz?PLa?@e@~u~aplg6*-)nD0VF{(uo|K%J{g;VJxW}TccOfu zf{b4@BI60ym&-R0@wOUSi_MK!iPstJ)BD5E6L1X?zFhA;pKbJ3f84;+pw(blSfI-< zvyBRjml&Tlu`n7ny=?T%RAa2$<7PF+y@qi{`o{gHbM)(k_eHDqXrf5HLxM>CRiZ+1 zg*YV9aNpBre9RL~J4B$te?G$08&mNz9PX;D^D?o_`}ycX#ibZvFm`eb4&C zhHpxSM?a1PPx_8em;W5|9zQ>Ff3$0Si{}*xWBW%zdNtDt>;wNo30%l(%!6w z{NCFguLcr&a{CYUjSi&u_YNK%OB!A=zG>W7>N=sXSgZBY>_tt{|A11!6pbeABotsj z;BVq$aPzQTU^tmgY^VHS^-yo}zH+DWSBiG>-|8(Dg&Oth1q*XoHf&pR1f>-J8+Qe> z5#50(px1~P^2J1>m(T^sPt5`(TDeEVQpO<{;QiWZih0l}6i}a&kIOb{lWu&J&r}z9B$+(_zAX`=NwCs4Lys@OItm#b8={|?i zGRdZ~4mk>KhTFAM(Qnv1+HwZS5VIKk3U<4GwUN8YZPUBPj+Sx@wbe_jMEi}-6|SjH zR~;K&T-}4+)UIq-nUmDR)7jT~w!63UUuVc^$YzV(Ydd$VRDKvzp@z4|CyhWck>@L$1JBhyX@bTq76Awg~xLJ zOZ>8(D_TpAmkd_>RSncNHe=f-x(f!^4V4Z37)cv(orsgzOwJ$sBsn-SO%bmSh6>Sr z=m-2T{wi6)Br+n{3prjwB{xv7j&Gs|>CMo)BJvkq(a+a=q_X&Ls)n^4hiECUp7WA7F3R90h`9VSqP@Hv4vxQ*?Z!OIHe|=qC#h?h$gS=rQy*dN|vMnZhVzSkWP>4Sj^_Nnwy~5IzxKlG90v zG!f}I^&oWyc^SQxc7k3&&tMKRq8Ull6Z9?g0}MwxMA7AlxGVTQI0<|YdZ&0WVLozj z;8d%qwW}JanqKN(no?MvBhOy;&oJv)woBfDg7rlobEoA!$V2knip>fq%g>g-FN?3< zT2WiQsrGP_QPC)(w`Fohn!%kO@!d zT^GBEv&FZJ?8UK$SqAzBhGr2aVWtzN@kSb>JRO3w-)OPvUgN2TErwJhHGhq0i_lrH zM>tilkyjv;FzC#e^gE0ko`TWAoXgxx|42Je+f7_Z+)l{W*@hP6Ic%soqY74TQv}K* zWc%b_rF+MnhqesH_Ob?ox@NX)YTi}XQsr4OtCUn=RZPrs%U+&&=(jQrOtZ{j{2j@R z%s!oUCH-;U$(-Zat$DMG8p<-Os%v*PiQ0hfhyC5d$>S-?akY>31pErf#&+Yd^Wek!P>vZZz z`x}S7x_$d*w3oE4Z`@LsSN^#KQ~0}Jel|O|AcLEomM+Z<{u}%EV|rW~OJ~Zt{rqqtsOzHNHTRA^)U` zlkHWTDH5T>8X>IGUPp$ZqX-@j(xTey8grx)n2wo)wa1bPad=-MKoroX(`jrh*O^l>OII~ryh?KQh-R%B{s=4yG<+|FX7L6W-2qK ziHBK^LAIf}zK=<{IKptFagBbYI9s?@Bgoq(+$6v=pVTX}u%y)PYG15Fj z$eIbLQF&8wTz*-aElnJIH{m^m>jf7%c7hUCRV6%1(cowKY>X2oadEh}{A6SFzz^n!CV<6x!IukU*bfd2^g-9GY4IM=jbaC4) z-Tn^N$f09OobryWQd%ghpG=rkO9j&KiA$3P<4KZ=!QaCj{Zj@8`)7Ad?V8_O*Yc)W zSTn0~UDclQ3q|o|8}jevU&|NdZ_07c!xfy)UsY6B(pVB({;1?w`O?~&x@Qd^8XH;# zofTbC1D6I#ghh-i9rpTq1f>0Y)e*K zA;WO0!7<}T!#}1j#!tU&kW~_ zL&f&GYN=PEB;jn%Nq#Tq7%N0~I$GHW8SCg*sh+eH`UVn(36fq>H26_nVR9TPnjA@b zLYzk&CZ56n!?+Od5R-}1uxAM&m`B8UfGLoVe!}cSIRBG8f-9jm)nTQzG*VV3iy5<% zR!J--jE1rX9S0T+=JfjywhqP(xc8LzWv^HyT;y)ZAkrTSwyJk%r^j>pHb4{VufQkwAMrEHOK#?PV zE-RRz%Ht+NC#Owxj?EhNmgtYg58LT*6vC)-BvtZp*k1Bt_~&5GNXu}QL_4CdL*2Ti z*OVzL5!4DTfS;m7j2heq9>PDze;_O)uOjy8yuo9l4Q(aaj1*0kQL^aIXy$ZV)&rU~ zolW0KEo1mmZ|QjFZbljzp&8KpC>nA&RjgZg9{w^xN*uv85Y*Tdybm~uoeut|D|)|$ zd;)!t7W4sNjXu(DMmE8ZkWJ78oB}i8T+J5kb?reYL;*mr)N*yS>V*87JV16pra%5* zY|H5G(XbKGKy3fH-r^p=juV}$T1(oL4Z9nI8#XjTcAF z8_SvlTX(b{>(TGOJsdn#F*ZetDrPD6s;_HtuoASx*kO(FZiEV)oRE*dKnf>%lAUyW zV?Xf(^&8C$^JAhybaP1e0q>9uyXp zL7&R_$p9FEjJJ%njJ539>_zN{TpZ7go5+35spD>AYk504`?--kIcJ%`f=AHX$1M}C z;5mq{@ccNxINMksIQQ6_InP<|Xc3$YS~>kMC6}?A8pJ4|pQJfbL5eSpK-ovFBN>uO zBnx~a*#jR&x`p3Cu+sVMar_+6415X7Koa;2D8tn0<{eDI+(&PsO=vCf10^79kZd>$ z^+lqzqtJKl7if{L-fvXpqzqG8D(1_xl~WZPRhIG)l~@`k`zM_`9zOPREM|0aWZB^L zAx_`Sp(Q;ldaJuJy>q&Yy1sU%boq1=y3Y2r_k?v7^ttxg4BQ)fK4LJEJsLXkTArfN zSsGnYvj{E2G=ogtZ)-?iPHCrGGQ*fG_8LwmkHh=J^W&i9ieQK6kp$b>oK;`NXRj`%_-$skk`8utTHU1l6A?X0wkaCrNnO4vE%v{Ob z!V)q5vi`DOaz1gE@W*+b!aQM(C_;a_-d_<@bXfFA6ezG1uH%2@AL1ACZTUBOS=@Pi z2mUeMKYl)!%6H`{@2y8Xli}{3p z#Oy%Tz!~iTf@lXJBWDs0ZB>&sJoPb+o9425j_SBduJKWYsJ^N-IveDvanYoyL!r~^9nc%i zY)y-*Qf05+p>9`(s^_S8YDSem)sgCx&{@rZY7{C`&)4pSKU>vYDk4san+kOb{dT;Nr_iI)reJ7)yL%t z$}DA}B1~?fNK!h>&&g{PN942RL@7z$Dl3*Am>iKY6@xm3)DLN{!az=vAC?}Pw3k}x zaPzMdt0ta|{Te+nx_IR7Fm*&%D?OCdAJy;HlidHXJEZ$-XL%Rey18>jE8JGt0%{zS1NB~m|8-cSQ+RkRRhB4ZoFgT9Md z!3bmcup()z8A5s=M|A@B&{qy+>Jw+dT_YXAd4I+g+$0={SkEQQOpMp{J24XQL@ zx_CSb^3cXZdmt_(hWm&#|! zz2ud$b&3s>sPvxnlr&T}BE2kEO5e%+WdX8kX_%BCyD2M{Es*8ta;t5sh00>}W%VCT zr`l8-1KS|W(KB!;>Vy78-ve!!nV8w&4U8>j9d^Gi<~G3o#U9YD`Zv}bXN*^2PZR9$ zrGzJV0`W19OgKR}NBB&zC1QwE@I-+ZX-pL8=? zXM=Uf8z2vLL>pkDb~h@5PM|fKMy*;ahwo{xz>75F$QSh%I8ifzCP1^aH=)fME;LU& z12Weff~621O4NYR3tf%|s~fd(YFnre;%gSFvmhHyvUZW?5^Myo*4}~E!0}K5^jiB8 ziiI+?FO{3LJeebus&r8a6t#-iI)2hxu}J!#JWFaLQ_Ci$zRCpoRmCz{qzWq^lqaf= zE1jTn)osX6bpVP{OLS-Xo!Sa=QjS7ewL9zpcfh^KBg7ZpiM#}^!g!tL-v~LSY0z#| zIcZyT*mk;Rj+&^%%bk_2%D#zt^1g|MvhWG|nB!!ibb~Bq^qG_=-6ivpIm=@e`;`gG zb5N#MqhSJXwZ>RW^eOHMPL5NN@(C+w%@iBv3u+3Zm2rYDWxi)#XZ5oaIi4H_{{Z`h zV1ToPbDMvH#}K^H@uKnkEqqtLhSMv6+085mZWI4Ja|th*8_LDAFSD+)?KrRLL9C;? zimnDm6zd)%fND>(rGB7wQB5gHG#n$B(xB^zpi@0kGV$B-6U58p*@Q#*PSPa)3W_cNW$f#QJ@b{2$X?d=oZid?+Vmnl7JuJADk95tiwch12@qD zG!O{`e<4PgbMRv{7d?zV0u;bi%n{TUN?I_3h)#O1owkWvAS2mSGtoPiO&K_SQeogyBzxkQw=`FE+8PlXK*Lx z2!;wi$7pm>UIKP1rWo7@ECkMDM96H+M>HHb1UG{B0X24~ZfbEdhJgvh7Go{|JAkLy z8DKT`0Ol@y0b8h3<>-d40gw)}YQxM2&Y;ei?O+M^5?%q8V{U?%G3W7vm}1;&+#$?H zj0(hHgF!Rwe()joI&KGc8-|H1177P`y%U%G2V)3LL$n{h7KUHHSe$M{m*DZ(}ahvZE9 zMqEYwMcz+1PA;S@B|f1%AwJfjGhU=0WDX&f_zD+Em_vxcmtqqLMc60U6s!o?g*}bw z!z2UW!71oD&=J`TtOL&I_JK1JiMSzBZ6$IBZH5I12_8V~-~-4<V+EUVvuyqZB(hVvut3qZl2w3U^AMI zrlKmO6+NZ%5zfdCxIlXzRzVc49sE&iqrC^EK!>#M&=YNv+6fY98lX;1jK*2BTH~a6 zq_t3cYNkLh)F$c-b(^|fRi?7h+)`~+@6@qtCF)8jUE=_`s;#uGs(b3c>L6``nhr_T z%QS`BYVB^g1&Po;Mf|i_bXdznW^3Kh|Iqi^H|TEN^yyKw9^I<@4u0SuCKxjVyo9yE z+Tt#Q_i$!lGar)n@Cw zdbze6NkSF_FrtHcfk5ymHU`vS&*M^XZbS`^OCS<<6Y7bl@t+BQ@oxwe!c#m;7mL3m zJR{lSnZ$nt1JW*h1_2~A;Gf`IaMidogq^sHgzbdqgx5HId<4D~>kUTWUW41PZQvTv zOXqpLu=-#$W&zNPdIHu!CURcq=M!~%`vJ{^oskXjF64uD2(r{VpyfJ$6$95o>2MF!qP-3Y;b?dd z)TG@7he1iYTr~+IY8y0dntz%z8bEUs0yW7HL+h=xCV@~H6t7vK(>WwS)jBMxSodBh z#1MIgyn|n&xyWHS4mHw-AQp%h;DUVD+2{4Txog{iMZhG=!bD+aW6Cglz!|{*Xzonl zqbSk^Uez<%1cDqQpn@{OiXa$6Ktbe`$O=RVha4j7hAsDtYf5ecHJfC^qb zL;eX`gV>uc?o<^sFZTy5@gGt3J1x(2$-W2c+H#zN+EqJTG|*T$ZUJsR5+ zdpnjEn;m=Coo5D^iMFwg!hsje>{yx2w%yb_rk-tX`kPVaRi0|TVwC;SebbC}H=8%j zVAI;(YFC+JJKKI}|781^rTku}V*FmZlqdWXvC@lJEv4(ux}B4+&(}`{7CA$m6@h=~ ziMqG*mfo!joImM)YO|{61XTy!(XnMvB0{=HtTZ&nF< zylSG(=M7jB)gRR#^Gnyz+c}^rom&D`&N^qacAa}1!;Zx@fdx7>cp#7% zxGmx7;9=*H;57j!u-cgs{A=I`J;C|LX&%__JgBeHX9vE~L!Cv=2hM(HeQ>68p3@y` zDaRXs>ZCfKtA2q*=R$Vtbf8F`=H#d)wvoOItQ+aJPCeCKttRez+kR(f+PBm+)zcZN zf8?7G&)O8zUNyB{)x+v3b(!r=v^&=>wwr7bk@x^L)n@WPLut+`H8POql<6@#S&gs- zaA1jA&rad3#Og1YWOJuo@aC%@n-?44Vd$t}3 zRs_Z-ToTwHED59pF9|#wIIMpiI7@%#jB@(w*L5nhcs@9M%bUM?>pA8DwUOB2J#~xy zLG8g3?^ey!HF}nsu5Qx3(4$>yKkLCk>RH{Lw;Y|JmgzM6lODj%K_jP!zSZgPv~!v` zozVM%&gj6tz!ky0+Huw})6PbU|8UmoJ9SvUsy5ic{66Yz^kkeJskAOvy!A+x+DA+; zeBIS{ncZf;GNUYbn4#u-)55ej33ig%2q!DeM{YOXgtFc)G#3(6e_|HXCfB5!X=c5< zA$Fy^%&l;TxpU3$-M#K;)7>;6wwz?9nqt$?+-mPKLE`zd>`kUKPnG)E74}q~_bQyUZYSp1GOvTDs%hmtya@8{8}0rm=s-vfRShm(i@4iZzW5iRHL;VvA$FVz)h}I*Le<^mU+b&k(R~)PKh($`PRwcnjYBXyoG(e7w8^r9|#3r3*_pnoZ*49 zoSkUYEIm$dLsq|Xj6PT2sD6tsOm})a4V_%oOHWnB>Si@jKTgEgMyKjF_Mjc1u283{ z4yvPFXtV4*v)V1?e?k|U|1f_y@8f^ZGN+r0*yrx6u_E_VceOhw*3s=28ybs6?~A6z zN}(_z+9tX*`eJlJY-@B*^r`5+XwPVe*v_h1(Wj$dR81yT(fL*LqJ5(St7276s;;d3 zT~%T9?^PE>Lsjdm=2eZX+FBW_`n>9`%2TV_L~pNZUDYvq9`$EOyG8S>zOKBTK95&k zUzJ}qu4+isRNY$DJUTntCAutnb97{MUG%!x*l1Do_2?JTS;(z8+CDZvHYqkZcDnnK zTkLjo!|s`8wrON8Hv{Z#W*>S{ZswvJ1$L#~Zb#U9YO}qLyY1-TVbehkLIXdxcM_FU z*!S%dcDLPWx3booq7sqNaH7zQ)l|NXcc*%d_i8?){z5EpwYm`Gv6W6mc?`-Np=dI?D zyTPQ{uT2-$)%V*@He|;z!`yHGVmsr>_L_$oJI53dg{GSM*k6S^)6_TfOrqK8UJ8bX z+~ICrxYo%%5F5t6KoRN3(T`)}*-5)Lc5kc$pSjFqPsgryTe~;8PsW~czjJrFpMlwS zH)y+>RBOx^Sl%J5zSwlLg~WHa!?{`TZM9mV3Yce_@}Z`VabDeyzDey`;WV zhj|n1BD~o=t@UBGiZxOfbptiCRSG)Zlg|QmA@7uJsUA}E)K+_*ecm=yE9|-USE`-5 zfX_$lhy7&Vvg7PWW-YPaJt~=a?`me5$tq0+^wqi#zu7%N@1yOx`1m9>*gj=vp%E|H zN;GOTeN%ZJGSfb59%d$wny?*$KU!fOJHfPLWi}b^SDN~kFW0FbY5jto2X}_p9=4Yq zU|+W{+RtoAHBw`EyY1(!2*0!e=A=pF4yhshf^{ZOs!DlY^((zXjnb}4)C+W${*E@| z)oH4!ddQZ5O#?knWve0jOYFKp?Y0x~${#U{KZUp7kERY*vusnOcCGpx?LMD% z%|u2ovU#?Z8f71~>FRq%f7?6_e?GPyd1qvnt)s40w=*{+tNYZK_I!1}y$x(8G2eC4 zGkLOhyN>Ei=SKZCa(&EcPRx6Uvy#0g9cUN0(wP*f!~ca33;f`G8|WDL&UwS>z|PLq zfinVk2JQ>=XT9{U^QhA#aB84Qpo!DixdwmtiT*(E(QmRNbcb`L{vGS9KkFxW!n{Ha z)pO7Y#kHIMoeJqm`ZV21zo??Bxqd-?qsmo^Zl*tFKKmR01d_~5_>j6#|Dbj;`^8kT z-l#V6!!&jDLn@8^om+H)PSanj5+Z?1^>qD?K2x8gZ`E7XCVdK#Mp*ww_tfv9TL)Rk zZPnlD7j=bR6L_9@V?1+W2WG)NtPeZ0A}rNoor#q5pYYBw;-M#*@9R1RI@{Umi~{HV zs)tiYr=z>wkzSb^tt{i5&MLl{YNjJs0X>0}_AD@~Ycm+(Zu5p2Xrk^=cGkM%$saN6 zZIaCd!xz2pk33;k;Uh0G516Nki~m5c-`g}`uEx4bv9v6FdlzD!*4TYp_$K~&wH>H( z)ou0>`;9HPe@5@;(ee!TPsXSR@aZoQ1-2mCTxq`|&i=|?h5ZHKs#3d%_;%Ypa5TrB zZ@WWZmOUGO23Xm&vhSD$tbP9oPfOwCwPuOA1;2b2kz+qR{^O>z$zkuLiFwKVm0YRm zWbPxzxtX{n-#*P^0}}c7}8C(;u1#&Dplfyl0I0(tK)u0{(+$yLlCu zU%BtNolJr;?ieK3()2bH;m|(wj_GZiAm3${_cPeutR!x;>2N-qk*2H8*2S`~Qq$l~ zLzQix#4p$39l4L-Yx?1TTB?C+f|`pqJpj#H)P8%PN?~ns2OR9H=E2Wq>H@n4ANm3F z-YLouVV-Flqjh(vHnuZbt z+cgcZxBxBajqm)_c^c?G^qG(W*NC~c3EEo+8^~a{-s6Nq>u1pQ%=o8$*k4kZuaN zg@IoQ1sCIGhA{g^A$Xj4RK3qF^j{r56k{06^NhhDef z;~!vzwn)7WqYvbb>37p+02(t;jiXmv<=Ss;BCCyW(Wi@P^F49UyWoEaExW{r*|v@C#(cVfni3+gtEgSan&V+CU=5!oNMSJ=zm&RmwgK`U ziA|)Sky-HlL)sP6ay0o2q?LmNBFK3fC0AnUSJ7rU)-;E9Ygu(Z51cvRvVi<7do8dE zsNKjoucJe60;>@Ienb4Yj?Z@68p%BYO>ctTN+7I2vdJn0&)#P5w;>#xgPq>QoZk|y z`88TH8o9bqoeW3Q;NcDM{1H}hOX2z*NMJJUG_7W$8RJwI+AtrzYKx?bu-!Yn&ss~-OL>$(jyHUk-Ye8H zJ}by=BG&pq{hiM?ATDLp`9ONyYqb(Ais;=Fow}538q|o!@j7hIM5Nmqt?7a`wgCG? z>YAfrouTkzG_o(c*o!{rGnb`Oaw#Q)!0b9;7J*F|$b-YfoYqj^*5eMl&iIT4Fd0L%J2uw4dL&Ye>|v0}cEM`rd|?4cOTZa9j$NC0N4}>?0rj-GH5~1J5;B z(JC-rN1IoGwA|xFIrK;2#UbXs-QcnV4HXUr7{_IlD6PIC-OJ}2%0J<{hx^^6mcGO@ z&=95n_muAE&Sl03K*4F88k!T3!%xt&hu#T9GP`NN6Ta`F_e+o?U{8|roufer7 z+%E(7QgB}it{cI99aL;a7Eh30P7jgMa<6nda6X}Sn-e!`VoPOFOlZ4MAl`fnj~g67aER7C*h zpFWM;OSS}}56|5qX{Dsa#cI)f%71o5l3#xLIV$)Ake7P5NyT#|TSDpK^77)6l9Ia* zmv5!XqD715OVcF9UrnlB<{(eMEl1##OTOHL13t0x@-2ebBjsDS6xRXHB1Wn+e-VF4 z#dRNhhQFlZYBSRML^#+BcDt*w>cY z4S&(S_@@wOZ_c=XVzc7}M+9d?75>OexN__HCh<`x^G}$?KRFJoB)>(3MJ>h+IIlq9 zvdZP^6%h_|cGN-M9ZCQYh_=eMX( z^LAJFFNyeYiUpU73Xr6renqi|t7N?b59h-k2^17p({#ApudncF!sAFmM8>9tWGR^E zCkv|eMNmQpPrtP zk2OkL3YMjN0Lm%^>xc?cMSVtkHBCY3EQd#ewYPhjBLy{CuSM-F z1@SC+|Gyrh=Mpo7IOBRA;r{qX#GI_>y>X()Yd~Cq*ZwtX$2|rt{{&Zr0;IPd)&*?)1_BBNACs)gOaBAmW1K{ z<)b0L`qPh9P!6%ZFrv?%%PE;oNg?_9++RUWj`!O>5!HK78-68coXTeCf9^2RsQLM*m@~De~B1mAf!2k;$w+uP^PUs2SeK z6WNCqnq+sT9cdapQ~7SHe`po(#$Brtsi}`%2|j~aMahxbCs54`zx9c(nSK14R?u4r zu2UGNKbRJRM+iB{`YfBAkAL0cwrWeej(pm&*H!~%Fl#uWy>_2?nb0JCQt8v~s6M_F z^Wpl*N0-&G&zl0cBvLBmnN1vz_Ha!2EqLeAG7PjZIuwQ$=@*yA1X@j{uF!)aQkT1_ zw97(^>Z+k0{XVuAfoWS0SCLRirPFF0^%MEXC=;tGJyESdIT}}i*p+XN%_(i!7kpurRPfoqp2QUKc^%F*L_P3GeRM_HHS`C#DNj?gJyv34)tPR?MzOZY6l_n*-jZ`sD9@#sENyisq23YixRpkMS* ze7Up}pK&~{N!_uBcs${sua|M0;v5$b@AJ)vJdK=aia&cyf$K7s$g~E^u_H*n7v6L- z?R-fIu0nzMMX}c0YN)=q&ZQ*o!DZLQpJi%hSn>C=cPO%}(R|UeqvzGSwc>`(>~?7RvwJ_V$LmzUS z>%vR1uVXnL=W|{5MB^>QhNS&P$3T=Fg`&f-R@fexM=vK(HR~hSMhr}b7 z^Zb4|u~c6;pGi6hZNHM(Y#1d&RR$%4iI;|w4yA41~&Y z*o^QkAFUN?B?1{vPUdNUj+LC$Ugp(y_yzF98;RD5Erm`1RU)5w8z1s<38*g2?9&tq zC(%P@klMJ5{A;X9^m-=sXa1tr5;I7TxP7#!_6IOfV7a_5E>6B#;M> zgnuW)&+j_{&iHXe9AAkie~Bg^Yb!_VU7M3a`MJ)X9NH!DFvsIiZGNB3mkCe&*;%~N zi7h_P*JH;oIDrbBwr9EjPE0orx0p^TgMADfmK$=LJ;N=U|ue^MrO7!wY zD%0!7lSZ%KG?na?PghB#$$Ya$#z~ZK*pMdU1qA**d<#d$lNGU}LZOD<%2<9emZyac z{ha(>tixJnyVIF=BhZFxxn2(Uh7noFGoWip2N7=!7C`Ei-~l83<&p;J} zx_~6j8&RxRR(oQN@zrO4ax&+z&*HU7<%w1*F|?$YaaAhBso|rq8=@^Uz(!^)-y3GK zR+L|r^;fg9VkkgnGLFn0{wf3zj47+u5Z+LpAxjK-ytzm5>`a~w#^H?sUd`H4;B@q! zL!{Qac9ddP9zpsEJrc!CB^6z&!PFmL@eHmp?J{UH(Q6@;9X)F*kJ_WlWM%X76{_rc z)P^;jaV0_zL#ud|>*0kQUC}#@{Ddq1N=k5x(Ed6Wfr-de!baIkzWuN%N&pY z5nHICsD`H};$=6Fmq+(MmZK-)r)+d+G*Re?V_KsviszBCV`ty$A_nc^TvnsvS)btS|x>js>i9WpejCc ze>xOSE}Ri6oG~Tbqt&#@d7aW)h4Qj;$y^!7AZ0|~uBj<~hYoKQx-mX(*Ob(hi&DF! zbxG-RF+HYC&Cd=O6y#6sGc|kCdC`U}R6 z9plzPzj5nlo%f%%amX;%zrH{80Q}Frd0^;KVShSwxrqP%(5bK&*k2raNQ8ejbWGTM z=trYRpqKE7eE1P|+!Fa7S&**y$kmmhY!V?S|5=ohrZ`U?B|;l7N*~o0 zX^IUff8O5(!Rs4?h^%=Jm=j)9R~H3hz=z}FP` zngU-_;A;weO@Xf|@HGX#rojIf6ksK8Gn?bKr1pEd{cKp9AXgrr3{WoKxZ|%GRQRtuE$J+|HN*wvqZW- zAa_2c_#3%$$hDVT*)o17x!uy;LvE*ZKSgf4bpMXr7U_P7+^Tf{2e}ov2Q_jXO@(Vc zxrX5a9;?W`pF)?A>s@lyk!v5hYRI*lTvw56fLz7o>Lu4D^()|p%3#I!} za_36-FUakd?jMrd1@~ZtTuyR@$>o4+XlJIJ+Hp$bo&DJzd^Dp-uJ0V3HLgNE^OTzJdKU3 zK*aqNAp!7Ti)j0h4dHi+4EKrz?=%>g7E<6ESTG1?tu9Z zn1^6~2lEt656p`&ufhBe%mJ7qFebpyf|&?&Cd^cri(syRxe6u#b1lrxFl%7KFn7Z| z0P|~@Kf-KJ`omaNnTZW(C2qC*9osnydRx{&URTFrcY60b=Bxqhlf|i71KRj4s>pZp z^wuX!+!-Rd%$dmGX9xNHc9W9VrFq?&H(T?%Xo}FhInngR7-y`nR);K+ikc{N@LpsQ z0mv^C^4k$~7+FohOg}&L8MU)II`{VNR9@qxla(jSsbTxkfqpjJ>{arf*Jd5BLI#%3 zeC9xG7h7j;i)pit2G3XDLDRzF+I|c^jfhyk-j^sv}49I64887RpV#NZ2`8{?O=lq7qFdq zdwCE|-gY<`YB-1OlvG2CO~AGk!uQyWqdm4ZUpYFFFg z5UZX(ap`gw|w>y^P=YE45>&FCjPp}u^ix2=LGyWe8}t)b~X z&@csI7Z_my3X7A0U1dY5yz5LNm$h|KjEE@E`spz$mC%x<{!~wL8Ip)n3HUB{RW{?S z)LEmI$+G)EkVM(>azJGaQwFajGZ3OEC%5awGj)G1F&kI82cej&3_4bgEh zRCe%BPZyZ~y&(mJu*HjxcW(jDGP=G|k;~fJPQ8?dT@`hQ$0V%Pf(pmNN7XfzphD~E zph7w-_BgtRPK6A3f06K-;k_r}RpD(*c+=or9rv>JmbMs(;?J(E9{^DT{7=`9AWCGm zG7&|(Ve(*Rz*N8(HInT|oyEpVZKC}S@*_Ag#DtO0=E=J3;D3`L=dx0Bm`@H~6y~Pj zSw{B=pzNcfdt5%U?1r(xb=%Q+JuUD)6ZZ-fPTD?eL}}L62Z)|Ds72dctB1Bx=uGsi zL*b)oYpw-N-#r5~wSwfeao`O$c;_X&#|%81+^9-1YV$ zOk-!W9c(vG2LLt~4MDRj-#tYPpNs`Ey_l#Z4}3Jxa5_d&252Wj#Waazn@k2LeA4po zkN`)Oe{G`t4TqD!u@3Gv+{qEASl*Hr+H$9iv<&XJsue>8kr@0B?FBK9|| zNR0;oUZ(Y)u6Us*;5QmxcivXbtd*%+8GbE2%!D~V!^aCgG$~gD3aASFB5J>Z-{+*y zG}04(nGv-pqP9>L)~zX8QG!Ns#B>s}3YAzc&8KQ+xV03mI8hm-VV_gpj}A)w!o_MV z8Rlqw!4I?aKwiuf4QBcHb;uR&Rkh2tCRJ;~derlI@C$VKUkvY*6X8+)(Px;#GCkdE zQrHRYZ%amZdqb@LcOR4}i+_fJq4+BNa%bG@qixCJUr-=Bs09JfTiw%$i1or2*%2;4xS*(qvJXhC-dr>q4zuSslA1QNbnc8d>tzVX{ zmE~wSRX26H!6h1TvRDB7~!g7SKDg*Xz;eZtG#T61=BCKj%M~^rpXMoMk$Lw0EMhd%GhS;l$%_pLQ=d&KM&t)%Q$BWJG%W}sK z@7uPlmuS0-J^L1bbP@!)-E|2NtW<65TK7oZ0?}LJ40-LstG8I<+=`Uv%m)`9m;8LP ze}v?xf*9lgJ62F?wuS}&Fb`8}m4EfPyj@2Qvf*%_$@=KQq1o830Si02wcQ7~fvtl2 zGE|uqz76azmR})x$lAjCA!tBFAcs(;F9p8gm)_4B#uN=`5j#m?l}cX7(cgEo42);A zmy^v?Q@7H;3W$sTj&aE*SMpT{2w9u9#$2nNxuEW9F@=xlFC*~(2>`Qy7ymK;F8-@i zcct#C(*FibKSckJ zhW;)3ek=XXf$vE0dHlbPtg?RW zpr^^a+6+kr&q8;{>WTUYfi$hJUe)6@ugq#tFvxxUw@ARsRW>Q2&JK5*v~q9{x7QkT z-U;w-8wC$@3A@B|BzR`kP%8FP>@9XNIO@NE!>!^?81fkIo+BZ?KwGbBS6~4jF`C7E zH42~Cb$rsn#7KOSGo66X??&NsLjA5JnFQ+hCE=ZhQ!UVtFVXoBevLrP76n@>O%ffHXln03916D(YM;peASUT+m3>R z&n!4KlvZ$y8vLd|vb{n}bd(Av5M$$f^-AM*C**Q%kCs8@10 zwNB>E_VffTKAwj;n)t=qZ17oHZLU_E!@ooA@6DG9CKw6wwb~-Bwy<^ta5S2b$2yd? zH&)S34Dz)p5D=a>NFWM5-l9lT{z?Pio%{pp38gBtMx5QE5)CSQQ7ct>-`_!;ROWX8 zGiDjku2Px5ka-=D&D1Rnzh_#Y*}J7ASPu0`XecwA0Ws1eV#rUb5nEU};*G8(Yy-a~ z$@tyDPmbTb&%^KBWc=o!3!R8yb+>wQ4EqI!!RnJ^DA2NClpf35TTo|PJ(I1md=-AK z8uC@*=jv=LyC8V+l-eU}EOFBB;D=}n3zlwD#8O1O3Y;ZwM_X6K(h<6p1)SRWaH$ic zQCnhOh%E{e;#ipkX~9Ka9s?6t>eSLHT@p7)8KNe^Ivd%N8-QwtiQ7|}8(EW`gpZrH z^gv=<#6qHO!Y7b}mevA}Itea{oe%z!Co=#>D2=vw7yozt*pHk${3Z4y(RA8H5ECc3 z^Z%wv)|(GT3|o^=|3{1(wmKWqOl(FD=>8KnBfuBulEvosV#wqzTCuIY*d8sGqp&zf zD=x%-h4xcEGeq2MwzHD?aw_>C2A~iG5FIOoz=s5|y7-y|EI`XaRNxP0O34Yf3dH-> zK$yb7z>};3LTm^M3<)*_)GI~Wpf`M*T?txsnate(!N3DE&Z?YJrp&LB$Pgy8Lo}z3a&|Zjv5-*)fVm$Z_1W*x`s$k4(gfx6QB_ys~ z3asa4vr-4Mch`_yn@2xFB=Pj~94wISV

EQTU@2zLU4ZLcusPIFaE!sXS;6?odEJ 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 U|wp7byhVdO$EmbKrx>>)@N?Lo4Itk3WZ2K?4+m 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

HdArEU$R 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

}~_z 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 z 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 literal 0 HcmV?d00001 diff --git a/vscript/languages/gm/doc/ChangeLog.txt b/vscript/languages/gm/doc/ChangeLog.txt new file mode 100644 index 00000000..98d4f7a1 --- /dev/null +++ b/vscript/languages/gm/doc/ChangeLog.txt @@ -0,0 +1,324 @@ +----------------------------------------------------------- +GameMonkey Script Change Log + +Newer entries are at the bottom. +Dates are dd/mm/yy + +Note that very minor changes like a renamed variable or +modified comment may not appear in this list. +----------------------------------------------------------- + + +22/12/03 +o Package 1.0 ready for public release. + +02/01/04 +o Updated script reference doc with system functions, compiler string concat and other. + +08/01/04 +o Fixed filename case mismatch between filenames and #includes for Unix and other platform. +o Renamed and modifed gmNetwork to NetClient and NetServer as they are not gm files. +o Modified GMD project to show gmDebugger in gm file set and use Win32 #defs for windows specific parts. +o Removed memory display from snake.gm +o Added sample script descriptions file. +o Removed GM_MAX() and GM_MIN() macros and replaced with template versions in gmUtil +o Added gmLog2ge function as faster version of gmHighestBit, and changed gmArraySimple and gmArrayComplex to suit. +o Fixed buffer overrun bug with gmVariable::AsString function. +o Removed all warning level 4 warnings bar the warnings generated from flex and bison files. +o Added GM_VERSION #define to gmMachine.h. first version @ "1.1". added gmVersion script binding. +o Changed some #ifdef DEBUG to #ifdef GM_DEBUG_BUILD + +09/01/04 +o Added constant folding for ints and floats +o Added +=, -=, *=, /= etc. Some more optimisation is required on this to avoid reavaluation of complex l-value. + +10/01/04 +o Added threadKillAll() binding to allow termination of all threads. +o Added threadIds() binding to allow access to all threads. +o Modified BomberRun.gm to allow exit from main menu. + +16/01/04 +o Added Minimal code to use GM example. + +18/01/04 +o Fixed bug in string operator not. Incorrectly returned true instead of false. + +23/01/04 +o Modified copyright message to be 'GameMonkey Script' as that is the full name. + +25/01/04 +o Added GameObject example code. + +07/02/04 +o Remove GM_ASSERT from macro GM_CHECK_FLOAT_PARAM. Was probably left in from some previous debugging. + +20/02/04 +o gmMachine::Get/SetDesiredByteMemoryUsage() removed and replaced with Get/SetDesiredByteMemoryUsageHard() and Get/SetDesiredByteMemoryUsageSoft(). +o Changed behaviour of gmMachine::SetDesiredByteMemoryUsage***(). No longer sets auto-memory to false, also does not have auto-memory parameter. +o New incremental garbage collection logic to govern the inc GC system. +o New GC stats functions: TODO +o Set gmConfig.h to use incremental GC by default. Was using atomic GC. +o Renamed machine bound function threadIds() to threadAllIds() to make it more different from threadId() and more consistent with other naming. + +21/02/04 +o Added paranoid check code to Incremental GC. +o Fixed serious bug in gmTable with IncGC that caused deleted 'values' to go through write barrier. +o Added Sleep(0) to WIN32 build of GME to improve windows performance which otherwise suffers from unyielding threads. + +26/02/04 +o Changed strtol to strtoul in gmParser.y to convert hex and binary numbers to unsigned ints causing them to not be truncated. They will appear as full signed ints rather than be clipped to 0-2b range. + +03/03/04 +o Fixed bug in gmCodeGen.cpp The array container could resize causing pointers to become invalid. List is now used to hold function pointers. + +06/03/04 +o Generate code target to big/little endian regardless of source platform. + +09/03/04 +o Modified gmMachine::CollectGarbage() AND binding sysCollectGarbage() to take a optional parameter to perform force full collection. +o Improved VM GC logic so garbage collector will always free memory when it has the chance after a collect cycle. +o Added sysSetDesiredMemoryUsageAuto() binding to enable auto adjust of memory limits (used to be flag in old set memory limit functions). + +11/03/04 +o Fixed excess memory bug in gmCodeGen.cpp as result of previous bug fix. +o Improved VM GC logic so garbage collector auto sizes soft and hard limits better, but realize logic is still poor as long as only soft limit is exceeded. + +01/04/04 +o Fixed gmRandomFloat to use RAND_MAX instead of 65535. Effects some platforms as these were not equivalent. + +21/04/04 +o Improved gmThread::Param(), returns reference to gmVariable instead of instance. + +18/06/04 +o Removed reseting of error log from gmMachine and gmThread. Allowed memory limit on log. Updated examples. + +23/08/04 +o Fixed gmMachine::Init(). Global table not initialized after ResetAndFreeMemory(). + +10/10/04 +o Fixed bugs in gmCodeGen.cpp. Removed remaining array resize bugs. + +24/10/04 +o Remove gmArrayComplex and replaced with gmArraySimple to reduce code as it was not necessary. +o Removed 'no effect' variables that had been there to remove warning 'unreferenced parameter'. +o Wrapped new with GM_NEW and GM_PLACEMENT_NEW for simpler replacement eg. debug new. +o Changed multi char constatns 'abcd' to macro version for better compiler compatability. +o Aligned memory for allocator in gmLibHooks.cpp for PS2. Added alignment size #define. +o Moved #include "assert.h" from gm into gm_Configp.h for better compatability. +o Other minor changes for compiler compatability or reduction of compiler warnings. + +25/10/04 +o Changed behaviour of Block() to yeild if blocked on 'null'. +o Made functions in gmThread const. +o Added memory presizing functions to allocators and gmMachine. + +27/10/04 +o Changed malloc,free,realloc to new,delete equivalents in bison.simple and flex.skl files. +o Aligned memory addresses in gmCodeTree, gmLog. +o Added ToDoList.txt to the \docs folder. Removed readme.txt from src\gm folder. + +02/11/04 +o Added new line to end of files to remove warnings on some compilers. +o Fixed some non-commented comments on preprocessor commands to remove warnings on some compilers. +o Changed some includes to later standard: cassert, new, to remove warnings on some compilers. +o Moved non gm header includes into gmConfig.h with comments. External includes now only in gmConfig.h and gmConfig_p.h. +o Renamed platform\win32 to win32msvc. Added platform\win32gcc. Adjusted paths in projects to reflect this change. + +11/11/04 +o Fixed commented #define in gmParser.y. +o Fixed bug in gmCallScript.h. If C called C bound function via script, thread was not exited correctly. +o Added gmCallScript::BeginFunction() Generic function call, and AddParamTable(). + +07/12/04 +o Removed platform specific #defines and checks from gmConfig.h + +10/12/04 +o Added #include to flex.skl for Linux compile. +o Fixed bug in GML. Code used obsolete non 32bit byte code. + +11/12/04 +o Added gmCall. gmCallScript is now deprecated. + +27/12/04 +o Replaced GC related 'workLeftToDo' variable names with 'workLeftToGo' so a simple 'todo' search won't find these. +o Implemented file.Seek() as it was not implemented. + +01/01/05 +o gmfrontend.bat strips CR chars from flex and bison script files before generating compiler files. This should help Linux & Unix builds. + +24/01/05 +o Fixed more compiler warnings. + +30/01/05 +o Added newline to end of gmDebugger.cpp. Will have to watch for this in future to keep gcc happy. + +03/02/05 +o Added (experimental) new table creation syntax. eg. t = {1,2,3,}; same as t = table(1,2,3); for simplified config files. + +04/02/05 +o Added explicit gmVariable() constructors for gmTableObject and gmFunctionObject completing the default set. + +10/02/05 +o Modified gmCall to improve access to return variables. + +21/03/05 +o Added ability for gmMachine to handle cpp owned gmObjects and handle GC for them. +o Changed gmMachine::Presize() (and related functions) to take named params instead of int array for clarity and future expansion. +o Modified gmMemFixedSet to have more smaller memory sizes. + +09/04/05 +o Removed Windows specific hack from gmDebugger.cpp and moved it to the example Windows debugger files. +o Added gmCall::AddParam() for generic gmVariable params. + +14/04/05 +o Added syntax highlighting to debugger. (Actually added back old files I found, that were meant for an IDE never finished.) +o Added line numbering to debugger. A quick hack, but maybe useful. + +16/04/05 +o Changed gmObject derived class constructors to be non-public. This forces creation by gmMachine. +o Minor change to gmListDouble to make some compiler happy. + +21/04/05 +o Minor changes for compatability with MSVS 2005. gmMathLib, gmStringLib, platform header. + +04/05/05 +o Added GM_FLOAT_OR_INT_PARAM and GM_CHECK_FLOAT_OR_INT_PARAM to gmThread.h to help with numerical parameters. + +09/05/05 +o Changed some #defines in gmThread.h gmIncGC.cpp/.h prefixed with GM_ to reduce potential conflict with other code. + +10/05/05 +o Fixed/Changed friend declaration used by gmTableObject and gmFunctionObject non-public constructors, to work with MSVC 6, 2003, 2005. Handling of friend template functions was different and broken. +o Added optional UserBreak callback to allow external code to break thread execution. Eg. to exit endless loop when user pressed CTRL-BREAK. + +05/08/05 +o Fixed bug in GameObject example, String operator= not always used. + +29/09/05 +o Fixed bug in gmTableObject. GC WriteBarrier was not being called with setting values to null. Old values, reassigned elsewhere could be lost. + +30/10/05 +o Changed location of thread create event so 'this' should be available for query. + +14/11/05 +o Removed gmShutdownVector3Lib() from Vector3 binds example. + +11/01/06 +o Fixed bug in gmMachine::RemoveCPPOwnedGMObject(). Was not calling WriteBarrier. +o Added gmMachine::IsCPPOwnedGMObject(). +o Added gmMachine::GetTypeTable() (as per DrEvil's mod). +o Modified gmMachine::RegisterLib(), Allow append/modify existing table (as per Oli's mod). +o Removed gmCallScript. (Had been depricated for a long time.) +o Added experimental gmGCRoot to \binds. Current implementation uses STL, but allows custom containers. + +21/01/06 +o Changed gmMachine, all non-public members are now protected instead of private to allow derived access. +o Changed project and workspaces from MSVC 6 to MSVC 8 (2005) + To compile the Windows based examples & utils, you will need at least 'MS Visual C++ 2005 Express' and the 'Platform SDK', both freely downloadable from Microsoft. + To run the Windows examples you will need VC8 compatible runtimes installed, The '.Net Framework 2.0' redistributables or 'Windows Update' will provide these. + (Left VC6 projects and workspaces in for now. Debugger still relies on MFC which is not supported by 2005 Express edition.) + +08/03/06 +o Changed doString and (system.)DoFile bindings to take optional 'this' as parameter +o Added gmThread Param() with default gmVariable param. + +10/03/06 +o Removed CrimsonEdit syntax highlighting for binary numbers as it did not behave as expected. + +15/03/06 +o Changed GC to start in 'off' state. + +02/04/06 +o Fixed gmMachine anomaly where, when a new thread is created just before yielding, and the yield occured in the last running thread, the new thread was skipped until the next execution cycle. + +05/04/06 +o Fixed bug where local (shared) strings waiting for finalization were reused. Made them revive properly. +o Removed old write barrier from gmTable, leaving new correct code only. + +16/04/06 +o Changed AsString() default for reference types to display pointer in hex instead of decimal. + +17/04/06 +o Added more info on binding functions to GameMonkeyScriptReference.pdf + +22/04/06 +o Changed gmThread so that final stack frame including 'this' is still valid when MC_THREAD_DESTROY occurs. + +20/05/06 +o Added config #define GMMACHINE_REMOVECOMPILER to allow compiler to be removed from gmMachine. Saves some KBs as well as disables compilation. + +03/06/06 +o Added optional divide by zero check in operators to create GM exception rather than OS exception, as per DrEvil's suggestion. + +19/06/06 +o Changed gmMachine::AddCPPOwnedGMObject() and RemoveCPPOwnedGMObject() to ignore NULL ptrs rather than ASSERT on them, for caller convenience. + +24/07/06 +o Added two gmMachine function registration wrappers to provide alternate interface. +o Added %u to bound function 'format' to support unsigned ints. + +01/08/06 +o Added gmVariable::IsNull(). + +13/09/06 +o Added a bunch of accessor functions to gmVariable and gmTable for convenience. + +15/09/06 +o Added #define-able nullify in gmVariable ctor. Disabled by default. + +26/09/06 +o Added #define _USE_32BIT_TIME_T so system binding 32 bit time functions work with MSVC 8 runtimes. + +18/10/06 +o Changed new gmVariable helpers to be const. + +26/10/06 +o Added user data to function registering. This can be useful when binding C/C++ functions, particularly when registering MANY script functions to ONE C function that redirects to MANY C/C++ member functions. + +05/12/06 +o Fixed setdot misspelled as getdot in gmOperators.cpp and gmMachineLib.cpp. + +04/01/07 +o Modified gmKillThread() to behave as its comment describes. + +17/01/07 +o Fixed bug where GC was not correctly handling persistent strings. Thanks Kaz. + +20/01/07 +o Improved GC stats to reduce false warnings about bad GC config. + +21/01/07 +o Added operators implemented from script. Thanks Seth 'Nightmare'. +o Added another GC stats related function. +o Rearranged pragmas and includes in config headers so order could influence subsequent files. +o Added 'typename' to some template declarations in gmGCRootUtil. + +21/02/07 +o Fixed atan2 binding. Thanks 'blackstormy'. + +20/03/07 +o Modified GC auto calibrate to allow no shrink. +o Moved GC related settings to gmConfig.h. +o Added gmMachine::GetAutoMemoryUsage(). +o Changed GME initial memory setting. +o Added example Vector3 non operator Add for efficiency comparison. + +03/05/07 +o Added Experimental user type op_bool test for conditions. Thanks Kaz. +o Modified killed threads. Callback from killed state before recycle/delete. +o Added const to more functions in gmThread. + +16/06/07 +o Fix bug relating to thread stack resize gmThread::Touch(). Thanks DrEvil. +o Build .EXEs with VC2005 SP1, static linked VC runtimes except for Debugger which uses MFC. + Get vcredist_x86.exe from http://www.microsoft.com/downloads/details.aspx?familyid=200B2FD9-AE1A-4A14-984D-389C36F85647&displaylang=en or search for "Microsoft Visual C++ 2005 SP1 Redistributable Package" if needed. + +22/10/07 +o Added gmMachine::BindLibToFunction() Just a call through to existing gmLibHooks. +o Changed gmGCRoot<>::Set() to handle null. +o Removed a_filename from gmMachine::ExecuteFunction() since it wasn't used and could confuse users. + +11/11/07 +o Modified all GM_*_PARAM() and added overloads for all gmThread:Param*(), to check if invalid type was present. +o Modified threadKill() to ignore threads with invalid Id instead of killing current thread. + diff --git a/vscript/languages/gm/doc/GameMonkeyFAQ.pdf b/vscript/languages/gm/doc/GameMonkeyFAQ.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7f8aef1332f7015d0405b977e5e2acfb028cc65f GIT binary patch literal 155118 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 z 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 hu0f>loRQsmz7tSiG26G+3yG-vCDkE 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
+

gm

+

+
+

array

+
Brief: array will create a fixed size array object
Param: int size optional (0)
Return: array


+

array

+

+
+

Size

+
Brief: Size will return the current size of the fixed array
Return: int array size

+

Resize

+
Brief: Resize will resize the array to a new size
Param: int size optional (0)
Return: null

+

Shift

+
Brief: Shift will shift slide the array elements by a delta, nulls are shifted in
Param: int delta
Return: null

+

Move

+
Brief: Move will perform a non destructive move on the array
Param: int dst
Param: int src
Param: int size
Return: null


+

math

+

+
+

abs

+
Brief: abs will return the absolute value of the passed int \ float
Param: int\float
Return: int\float abs(param)

+

sqrt

+
Brief: sqrt will return the square root of the passed int \ float
Param: int\float
Return: int\float sqrt(param)

+

sqrt

+
Brief: sqrt will return the square root of the passed int \ float
Param: int\float A
Param: int\float B
Return: int\float A to the power of B

+

floor

+
Brief: floor
Param: float A
Return: float floor(A)

+

ceil

+
Brief: ceil
Param: float A
Return: float ceil(A)

+

round

+
Brief: round
Param: float A
Return: float round(A)

+

degtorad

+
Brief: degtorad will convert degrees to radians
Param: float\int deg
Return: float

+

radtodeg

+
Brief: radtodeg will convert radians to degrees
Param: float\int rad
Return: float

+

cos

+
Brief: cos will return the radian cosine
Param: float
Return: float

+

sin

+
Brief: sin will return the radian sine
Param: float
Return: float

+

tan

+
Brief: tan will return the radian tan (sin/cos)
Param: float
Return: float

+

acos

+
Brief: acos will return the radian arc cosine
Param: float
Return: float

+

asin

+
Brief: asin will return the radian arc sine
Param: float
Return: float

+

atan

+
Brief: atan will return the radian arc tangent
Param: float
Return: float

+

atan

+
Brief: atan will return the radian arc tangent of x / y
Param: float x
Param: float y
Return: float

+

log

+
Brief: log will return the natural logarithm of 1 parameter, or (base, value) the logarithm to base
Param: float natural \ base
Param: float value (optional)
Return: float

+

min

+
Brief: min will return the min of the 2 passed values
Param: float\int A
Param: float\int B
Return: float \ int min(A, B)

+

max

+
Brief: max will return the max of the 2 passed values
Param: float\int A
Param: float\int B
Return: float \ int max(A, B)

+

clamp

+
Brief: clamp will return the clamed value. clamp(min, val, max)
Param: float\int MIN
Param: float\int VALUE
Param: float\int MAX
Return: float\int value clamped to min, max

+

randint

+
Brief: randint will return a random int from lower inclusive to upper.
Param: int lower inclusive
Param: int upper
Return: int

+

randfloat

+
Brief: randfloat will return a random float from lower inclusive to upper.
Param: float lower inclusive
Param: float upper
Return: float

+

randseed

+
Brief: randseed will seed the random number generator
Param: int seed


+

string

+

+Brief: string operations often store a copy of the string on the stack, so keep string sizes reasonable

+

IsEmpty

+
Brief: IsEmpty will test to see if the string is 0 length
Return: non-zero if the string is empty

+

Length

+
Brief: Length will return the length of the string not including the null terminating character
Return: int length

+

Left

+
Brief: Left will return the left count charaters of the string
Param: int count
Return: string

+

Right

+
Brief: Right will return the right count charaters of the string
Param: int count
Return: string

+

RightAt

+
Brief: RightAt will return the charaters right of and including the given index
Param: int index
Return: string

+

Mid

+
Brief: Mid will return count characters from the start index
Param: int startIndex
Param: int count
Return: string

+

Compare

+
Brief: Compare will perform a string compare
Param: string to compare
Return: -1 if the this < compare string, 0 if the strings are equal, 1 otherwise

+

CompareNoCase

+
Brief: CompareNoCase will perform a string compare (case insensitive)
Param: string to compare
Return: -1 if the this < compare string, 0 if the strings are equal, 1 otherwise

+

Int

+
Brief: Int will return the int value of the string
Return: int value

+

Float

+
Brief: Float will return the float value of the string
Return: float value

+

String

+
Return: string

+

Upper

+
Brief: Upper will return the string as uppercase
Return: string

+

Lower

+
Brief: Lower will return the string as lowercase
Return: string

+

SpanIncluding

+
Brief: SpanIncluding will return this string while characters are within the passed string
Param: string charset
Return: string

+

SpanExcluding

+
Brief: SpanExcluding will return this string while characters are not within the passed string
Param: string charset
Return: string

+

AppendPath

+
Brief: AppendPath will append a path make sure one '\' is maintained
Param: string path to append
Return: string

+

ReplaceCharsInSet

+
Brief: ReplaceCharsInSet will replace all chars in this that are within the charset with the given int char
Param: int char to replace with
Param: string charset of chars to replace
Return: string

+

Find

+
Brief: Find will find the first occurance of the passed string within this string
Param: string search string
Param: int start index optional (0)
Return: int index of first occurance, or -1 if the string was not found

+

Reverse

+
Brief: Reverse characters of a string
Return: string

+

ReverseFind

+
Brief: ReverseFind will find the first occurance of the passed string within this string starting from the right
Param: string search string
Return: int index of first occurance, or -1 if the string was not found

+

GetAt

+
Brief: GetAt will return the char at the given index
Param: int index
Return: int char, or null if index was out of range

+

SetAt

+
Brief: SetAt will return the string with the character set at the given position
Param: int index
Param: int char
Return: string

+

TrimLeft

+
Brief: TrimLeft will return the string with the chars from the passed char set trimmed from the left
Param: string charset optional (" \r\n\v\t")
Return: string

+

TrimRight

+
Brief: TrimRight will return the string with the chars from the passed char set trimmed from the right
Param: string charset optional (" \r\n\v\t")
Return: string

+

GetFilenameNoExt

+
Brief: GetFilenameNoExt will return the filename part of a path string
Return: string

+

GetFilename

+
Brief: GetFilename will return the filename part of a path string incl. extension
Return: string

+

GetExtension

+
Brief: GetExtension will return the file extension
Param: int inclDot optional (0) 1 will include '.', 0 won't
Return: string

+

SetExtension

+
Brief: SetExtension returns a string with the extension change to the given one.
Param: string ext optional (null) the new extension, with or without the dot. null to remove extension.
Return: string

+

GetPath

+
Brief: GetPath will return the file path from a path string
Param: int inclSlash optional (0) will include a '\' on the end of the path
Return: string


+

system

+

+Brief: system functions are bound in a "system" table.

+

Exec

+
Brief: Exec will execute a system command
Param: string params will be concatinated together with a single space to form the final system command string
Return: integer value returned from system exec call, -1 on error

+

DoFile

+
Brief: DoFile will execute the gm script in the named file
Param: string filename
Param: int optional (1) as 1 will execute string before returning, 0 will execute later.
Param: ref optional (null) set 'this'
Return: thread id of new thread created to execute file

+

File

+
Brief: File will create a file object
Return: file object

+

FileExists

+
Brief: FileExists will test to see if a file exists
Param: string filename
Return: 1 if the file exists, otherwise 0

+

FileFindFirst

+
Brief: FileFindFirst will start a file search will test to see if a file exists
Param: string filesearch (may contain wildcards, eg, `c:\temp\*.txt`)
Return: fileFind object. fileFind object has .filename and .size member
See Also: fileFind

+

FileFindNext

+
Brief: FileFindNext will get the next file matching the file find
Param: fileFind object returned by FileFindFirst call or FileFindNext call
Return: fileFind object
See Also: fileFind

+

FileInfo

+
Brief: FileInfo will return a file info object that has readonly members for .creationDate
Param: string path
Return: fileInfo object, fileInfo object has a .creationTime, .accessedTime, .modifiedTime and a .size

+

CreateFolder

+
Brief: CreateFolder will create a file path if it does not already exist
Param: string path
Return: int 0 on failure, 1 on successful create, 2 if folder already exists

+

DeleteFolder

+
Brief: DeleteFolder will remove a file path
Param: string path
Param: int remove subfiles and folders optional (0)
Return: int 1 on success, 0 con failure

+

Time

+
Brief: Time will return a unix style time_t as an int
Return: the current time

+

FormatTime

+
Brief: FormatTime will take a int (time_t) value and format according to the passed format string.
Param: int time (-1) is a (time_t) to be converted to a string, passing -1 gets current time
Param: string format ("%A %d %B %Y, %I:%M:%S %p") is the format string to use.
%a : Abbreviated weekday name
%A : Full weekday name
%b : Abbreviated month name
%B : Full month name
%c : Date and time representation appropriate for locale
%d : Day of month as decimal number (01 – 31)
%H : Hour in 24-hour format (00 – 23)
%I : Hour in 12-hour format (01 – 12)
%j : Day of year as decimal number (001 – 366)
%m : Month as decimal number (01 – 12)
%M : Minute as decimal number (00 – 59)
%p : Current locale’s A.M./P.M. indicator for 12-hour clock
%S : Second as decimal number (00 – 59)
%U : Week of year as decimal number, with Sunday as first day of week (00 – 53)
%w : Weekday as decimal number (0 – 6; Sunday is 0)
%W : Week of year as decimal number, with Monday as first day of week (00 – 53)
%x : Date representation for current locale
%X : Time representation for current locale
%y : Year without century, as decimal number (00 – 99)
%Y : Year with century, as decimal number
%z, %Z : Time-zone name or abbreviation; no characters if time zone is unknown
%% : Percent sign

Return: the time as a string.


+

fileFind

+

+Brief: fileFind object has a "filename" and "size" member

+

GetAttribute

+
Brief: GetAttribute will test a file attribute.
Param: int char attribute 'r' readonly, 'a' archive, 's' system, 'h' hidden, 'c' compressed, 'd' directory
Return: 1 if the attribute is set, 0 otherwise


+

file

+

+
+

Open

+
Brief: Open will open a file in binary mode
Param: string filename
Param: int readonly optional (1)
Return: 1 if the open was successful, 0 otherwise

+

OpenText

+
Brief: OpenText will open a file in text mode
Param: string filename
Param: int readonly optional (1)
Return: 1 if the open was successful, 0 otherwise

+

Close

+
Brief: Close will close a file

+

IsOpen

+
Brief: IsOpen will test to see if a file is open
Return: 1 if the file is open, 0 otherwise

+

Seek

+
Brief: Move to position within file
Param: int offset positional offset relative to origin
Param: int origin eg. myFile.SEEK_CUR, myFile.SEEK_END, myFile.SEEK_SET for current, end, start origins.
Return: int 1 if operation succeeded, 0 if failed.

+

Tell

+
Brief: Tell will return the current cursor position of the file
Return: int the current cursor position, -1 on error

+

ReadLine

+
Brief: ReadLine will read a line of text from the file.
Param: int keep optional (0) as 1 will keep the "\n" char on the line, otherwise it is removed
Return: string, or null on eof

+

ReadChar

+
Brief: ReadChar will read a char from the file
Return: int char or null on eof

+

WriteString

+
Brief: WriteString will write a string to the file
Param: string to write to file
Return: 1 on success, null on error

+

WriteChar

+
Brief: WriteChar will write a char to the file
Param: int char to write to file
Return: 1 on success, null on error


+

Vector3

+

+
+

Vector3

+
Brief: Create a Vector3 object
Param: float x or [0] optional (0)
Param: float y or [1] optional (0)
Param: float z or [2] optional (0)


+

Vector3

+

+Brief: Vector3 math class

+

DominantAxis

+
Brief: Find the index of the largest vector component.
This: Vector to evaluate.
Return: int Index of largest component.

+

Dot

+
Brief: Calculate the Dot (or Inner) Product of two vectors.
This: Vector3 First vector.
Param: Vector3 Second vector.
Return: float result.

+

Length

+
Brief: Length will return the length of the vector.
Return: float Dot product result that is cosine of the angle between the two vectors.

+

Cross

+
Brief: Calculate the Cross (or Outer) Product of two vectors.
This: Vector3 First vector.
Param: Vector3 Second vector.
Return: Vector3 Cross product resultant vector that is perpendicular to the two input vectors and length sine of the angle between them.

+

Normalize

+
Brief: Return a unit length copy of this vector.
This: Vector to be copied.
Return: Vector3 Unit length copy of this vector.

+

LengthSquared

+
Brief: Return the squared length of the vector.
Return: float Squared length of the vector.

+

ProjectFrom

+
Brief: Project a direction from a point.
This: Vector3 Direction.
Param: Vector3 Start point;
Param: float Distance or time.
Return: Vector3 Projected result.

+

Clone

+
Brief: Return a copy of this vector.
Return: A copy of this vector.

+

Set

+
Brief: Set vector from other vector or 3 components.

+

LerpToPoint

+
Brief: Linear interpolate between two 'point' vectors.
This: Vector3 From vector.
Param: Vector3 To vector.
Param: float Fraction or time between 0 and 1.
Return: Vector3 Resulting inbetween vector.

+

SlerpToVector

+
Brief: Spherical linear interpolate between two vectors.
This: Vector3 From vector.
Param: Vector3 To vector.
Param: float Fraction or time between 0 and 1.
Return: Vector3 Resulting inbetween vector.

+

RotateAxisAngle

+
Brief: Rotate around Axis by Angle.
This: Vector3 Vector to rotate.
Param: Vector3 Unit length axis of rotation.
Param: float Angle amount to rotate.
Return: Vector3 Resulting rotated vector.

+

RotateX

+
Brief: Rotate around X Axis by Angle.
This: Vector3 Vector to rotate.
Param: float Angle amount to rotate.
Return: Vector3 Resulting rotated vector.

+

RotateX

+
Brief: Rotate around Y Axis by Angle.
This: Vector3 Vector to rotate.
Param: float Angle amount to rotate.
Return: Vector3 Resulting rotated vector.

+

RotateZ

+
Brief: Rotate around Z Axis by Angle.
This: Vector3 Vector to rotate.
Param: float Angle amount to rotate.
Return: Vector3 Resulting rotated vector.

+

SetAdd

+
Brief: Add two vectors, store result in this. Demonstrate relative efficiency compared to operator version.
This: Vector3 Result vector.
Param: Vector3 First vector.
Param: Vector3 Second vector.

+

Add

+
Brief: Add vector to this. Demonstrate relative efficiency compared to operator version.
This: Vector3 Result vector.
Param: Vector3 vector to add.


+

gm

+

+Brief: functions in the gm lib are all global scope

+

debug

+
Brief: debug will cause a the debugger to break at this point while running.


+

gm

+

+Brief: functions in the gm lib are all global scope

+

gmVersion

+
Brief: gmVersion will return the gmMachine version string. version string is major type . minor type as a string and was added at version 1.1
Return: string

+

typeId

+
Brief: typeId will return the type id of the passed var
Param: var
Return: integer type

+

typeName

+
Brief: typeName will return the type name of the passed var
Param: var
Return: string

+

typeRegisterOperator

+
Brief: typeRegisterOperator will register an operator for a type
Param: int typeid
Param: string operator name is one of "getdot", "setdot", "getind", "setind", "add", "sub", "mul", "div", "mod", "inc", "dec", "bitor", "bitxor", "bitand", "shiftleft", "shiftright", "bitinv", "lt", "gt", "lte", "gte", "eq", "neq", "neg", "pos", "not"
Param: function
Return: 1 on success, otherwise 0

+

typeRegisterVariable

+
Brief: typeRegisterVariable will register a variable with a type such that (type).varname will return the variable
Param: int typeid
Param: string var name
Param: var
Return: 1 on success, otherwise 0

+

sysCollectGarbage

+
Brief: sysCollectGarbage will run the garbage collector iff the current mem used is over the desired mem used
Param: forceFullCollect (false) Optionally perform full garbage collection immediately if garbage collection is not disabled.
Return: 1 if the gc was run, 0 otherwise

+

sysGetMemoryUsage

+
Brief: sysGetMemoryUsage will return the current memory used in bytes
Return: int memory usage

+

sysSetDesiredMemoryUsageHard

+
Brief: sysSetDesiredMemoryUsageHard will set the desired memory useage in bytes. when this is exceeded the garbage collector will be run.
Param: int desired mem usage in bytes

+

sysSetDesiredMemoryUsageSoft

+
Brief: sysSetDesiredMemoryUsageSoft will set the desired memory useage in bytes. when this is exceeded the garbage collector will be run.
Param: int desired mem usage in bytes

+

sysGetDesiredMemoryUsageHard

+
Brief: sysGetDesiredMemoryUsageHard will get the desired memory useage in bytes. Note that this value is used to start garbage collection, it is not a strict limit.
Return: int Desired memory usage in bytes.

+

sysGetDesiredMemoryUsageSoft

+
Brief: sysGetDesiredMemoryUsageSoft will get the desired memory useage in bytes. Note that this value is used to start garbage collection, it is not a strict limit.
Return: int Desired memory usage in bytes.

+

sysSetDesiredMemoryUsageAuto

+
Brief: sysSetDesiredMemoryUsageAuto will enable auto adjustment of the memory limit(s) for subsequent garbage collections.
Param: int enable or disable flag

+

sysGetStatsGCNumFullCollects

+
Brief: sysGetStatsGCNumFullCollects Return the number of times full garbage collection has occured.
Return: int Number of times full collect has occured.

+

sysGetStatsGCNumIncCollects

+
Brief: sysGetStatsGCNumIncCollects Return the number of times incremental garbage collection has occured. This number may increase in twos as the GC has multiple phases which appear as restarts.
Return: int Number of times incremental collect has occured.

+

sysGetStatsGCNumWarnings

+
Brief: sysGetStatsGCNumWarnings Return the number of warnings because the GC or VM thought the GC was poorly configured. If this number is large and growing rapidly, the GC soft and hard limits need to be configured better. Do not be concerned if this number grows slowly.
Return: int Number of warnings garbage collect has generated.

+

sysIsGCRunning

+
Brief: Returns true if GC is running a cycle.

+

sysTime

+
Brief: sysTime will return the machine time in milli seconds
Return: int

+

doString

+
Brief: doString will execute the passed gm script
Param: string script
Param: int optional (1) set as true and the string will execute before returning to this thread
Param: ref optional (null) set 'this'
Return: int thread id of thread created for string execution

+

globals

+
Brief: globals will return the globals table
Return: table containing all global variables

+

threadTime

+
Brief: threadTime will return the thread execution time in milliseconds
Return: int

+

threadId

+
Brief: threadId will return the thread id of the current executing script
Return: int

+

threadAllIds

+
Brief: threadIds returns a table of thread Ids
Return: table of thread Ids

+

threadKill

+
Brief: threadKill will kill the thread with the given id
Param: int threadId optional (0) will kill this thread

+

threadKillAll

+
Brief: threadKillAll will kill all the threads except the current one
Param: bool optional (false) will kill this thread if true

+

thread

+
Brief: thread will start a new thread
Param: function entry point of the thread
Param: ... parameters to pass to the entry function
Return: int threadid

+

yield

+
Brief: yield will hand execution control to the next thread

+

exit

+
Brief: exit will kill this thread

+

assert

+
Brief: assert
Param: int expression if true, will do nothing, if false, will cause an exception

+

sleep

+
Brief: sleep will sleep this thread for the given number of seconds
Param: int\float seconds

+

signal

+
Brief: signal will signal the given variable, this will unblock dest threads that are blocked on the same variable.
Param: var
Param: int destThreadId optional (0) 0 will signal all threads

+

block

+
Brief: block will block on all passed vars, execution will halt until another thread signals one of the block variables. Will yield on null and return null.
Param: ... vars
Return: the unblocking var

+

stateSet

+
Brief: stateSet will collapse the stack to nothing, and push the passed functions.
Param: function new state function to execute
Param: ... params for new state function

+

stateSetOnThread

+
Brief: stateSetOnThread will collapse the stack of the given thread id to nothing, and push the passed functions.
Param: int thread id
Param: function new state function to execute
Param: ... params for new state function

+

stateGet

+
Brief: stateGet will return the function on the bottom of this threads execution stack iff it was pushed using stateSet
Param: a_threadId Optional Id of thread to get state on. \reutrn function \ null

+

stateGetLast

+
Brief: stateGetLast will return the last state function of this thread
Param: a_threadId Optional Id of thread to get last state on. \reutrn function \ null

+

stateSetExitFunction

+
Brief: stateSetExitFunction will set an exit function for this state, that will be called with no parameters if this thread switches state
Param: function

+

tableCount

+
Brief: tableCount will return the number of elements in a table object
Param: table
Return: int

+

tableDuplicate

+
Brief: tableDuplicate will duplicate the passed table object
Param: table
Return: table

+

print

+
Brief: print will print the given vars to the print handler. passed strings are concatinated together with a seperating space.
Param: ... strings

+

format

+
Brief: format (like sprintf, but returns a string) %d, %s, %f, %c, %b, %x, %e
Param: string
\ No newline at end of file diff --git a/vscript/languages/gm/scripts/Bomber.gm b/vscript/languages/gm/scripts/Bomber.gm new file mode 100644 index 00000000..27125090 --- /dev/null +++ b/vscript/languages/gm/scripts/Bomber.gm @@ -0,0 +1,1689 @@ +// +// Bomber By Kazys Stepanas +// + + +//-------------------------------------------------------------------------------------------------- +// Globals. +//-------------------------------------------------------------------------------------------------- +global bgCol = CA.B_BLACK; +global quit = false; +global lastTouchedBlock = -1; +global player; + +global gameLevel = 1; + +global blocks = table(count = 0); +global powerups = table(count = 0); +global enemies = table(count = 0); +global blockDeadZone = table(x1 = 31, y1 = 8, x2 = 39, y2 = 14); +global enemyDeadZone = table(x1 = 22, y1 = 7, x2 = 45, y2 = 16); + +// Thing types. +global T_Space = 0; +global T_Player = 1; +global T_Bomb = 2; +global T_Explosion = 3; +global T_Block = 4; +global T_Grid = 5; +global T_Powerup = 6; +global T_Enemy = 7; + +// Powerup types. +global PT_Bomb = 1; +global PT_Size = 2; +global PT_Life = 3; + +// Dead zone types. +global DT_None = 0; +global DT_Block = 1; +global DT_Enemy = 2; + +//-------------------------------------------------------------------------------------------------- +// Grid control. +//-------------------------------------------------------------------------------------------------- +global grid = table(startX = 0, startY = 0, spaceX = 1, spaceY = 1, rows = 0, cols = 0); + +//-------------------------------------------------------------------------------------------------- +// Constants +//-------------------------------------------------------------------------------------------------- +global screen = table(w = 80, h = 23); +global statusY = 24; + +global bombFuse = 1.25; +global explodeTime = 0.75; +global explodeCycle = 0.05; +global maxPlayerBombs = 10; +global maxPlayerSize = 5; +global maxPowerups = 20; +global maxLives = 5; +global startLives = 3; + +global scoreBlock = 10; +global scoreNME = 50; + +global nmeMoveTime = 1.0; +global powerupChance = 40; +global maxLevel = 10; +global maxBlockHits = 3; + +//-------------------------------------------------------------------------------------------------- +// Graphics +//-------------------------------------------------------------------------------------------------- +global playerPix = "\2"; +global playerDeadPix = "\5"; +global bombPix = "\15"; +global expPix = "+"; +global gridPix = "\178"; +global block1Pix = "\176"; +global block2Pix = "\177"; +global block3Pix = "\219"; +global nmePix = "\232"; +global lifePix = "\3"; +global bombSizePix = "#"; +global bombExtraPix = "*"; +global spacePix = " "; + +//-------------------------------------------------------------------------------------------------- +// Colours +//-------------------------------------------------------------------------------------------------- +global bgColour = 0; +global fgColour = CA.F_RED | CA.F_GREEN; + +global playerColour = CA.F_GREEN | CA.F_BLUE;// | CA.F_INTENSITY; +global gridColour = CA.F_RED; +global blockColour = CA.F_RED | CA.F_GREEN | CA.F_INTENSITY; +global nmeColour = CA.F_RED | CA.F_BLUE; +global powerupColour = CA.F_GREEN | CA.F_INTENSITY; +global puLifeColour = CA.F_RED; + +global statusColour = CA.F_RED | CA.F_GREEN; + +global bombColour = CA.F_BLUE | CA.F_INTENSITY; +global expColourCount = 5; +global expColours = array(expColourCount); + +global readyColour = CA.F_RED; + +expColours[0] = CA.F_RED | CA.F_INTENSITY; +expColours[1] = CA.F_BLUE|CA.F_RED; +expColours[2] = CA.F_RED|CA.F_GREEN | CA.F_INTENSITY; +expColours[3] = CA.F_RED; +expColours[4] = CA.F_RED|CA.F_GREEN; + + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +global IsPointWithin = function(a_ptx, a_pty, a_rx1, a_ry1, a_rx2, a_ry2) +{ + return (a_ptx >= a_rx1 and a_ptx <= a_rx2 and a_pty >= a_ry1 and a_pty <= a_ry2); +}; + +global OverlapRect = function(a_r1x1, a_r1y1, a_r1x2, a_r1y2, a_r2x1, a_r2y1, a_r2x2, a_r2y2) +{ + // Test one rect against the other. + if (IsPointWithin(a_r2x1, a_r2y1, a_r1x1, a_r1y1, a_r1x2, a_r1y2) or + IsPointWithin(a_r2x1, a_r2y2, a_r1x1, a_r1y1, a_r1x2, a_r1y2) or + IsPointWithin(a_r2x2, a_r2y2, a_r1x1, a_r1y1, a_r1x2, a_r1y2) or + IsPointWithin(a_r2x2, a_r2y1, a_r1x1, a_r1y1, a_r1x2, a_r1y2)) + { + return true; + } + + // Test the other rect. + if (IsPointWithin(a_r1x1, a_r1y1, a_r2x1, a_r2y1, a_r2x2, a_r2y2) or + IsPointWithin(a_r1x1, a_r1y2, a_r2x1, a_r2y1, a_r2x2, a_r2y2) or + IsPointWithin(a_r1x2, a_r1y2, a_r2x1, a_r2y1, a_r2x2, a_r2y2) or + IsPointWithin(a_r1x2, a_r1y1, a_r2x1, a_r2y1, a_r2x2, a_r2y2)) + { + return true; + } + + return false; +}; + +global ScreenClampX = function(a_x) +{ + if (a_x < 0) + { + return 0; + } + else if (a_x >= screen.w) + { + return screen.w-1; + } + + return a_x; +}; + +global ScreenClampY = function(a_y) +{ + if (a_y < 0) + { + return 0; + } + else if (a_y >= screen.h) + { + return screen.h-1; + } + + return a_y; +}; + +global ScreenClamp = function() +{ + .x = ScreenClampX(.x); + .y = ScreenClampY(.y); +}; + +global BombAt = function(a_x, a_y) +{ + for (i = 0; i < player.nextBomb; i=i+1) + { + bomb = player.bombs[i]; + if (bomb.x == a_x and bomb.y == a_y) + { + return true; + } + } + return false; +}; + +global PointOverlap = function(a_x1, a_y1, a_x2, a_y2) +{ + return IsPointWithin(.x, .y, a_x1, a_y1, a_x2, a_y2); +}; + +//-------------------------------------------------------------------------------------------------- +// Player object. +//-------------------------------------------------------------------------------------------------- +global Player = function() +{ + newPlayer = table(x = -1, y = -1); + newPlayer.bombSize = 1; + newPlayer.bombFuse = bombFuse; + newPlayer.bombs = array(maxPlayerBombs); + newPlayer.maxBombs = 1; + newPlayer.nextBomb = 0; + newPlayer.threadId = -1; + newPlayer.lastCanMoveThing = null; + newPlayer.dead = false; + newPlayer.lives = startLives; + newPlayer.score = 0; + newPlayer.threadId = -1; + + //------------------------------------ + //------------------------------------ + newPlayer.Draw = function() + { + CATTRIB(bgColour | playerColour); + if (!.dead) + { + XYTEXT(.x, .y, playerPix); + } + else + { + XYTEXT(.x, .y, playerDeadPix); + } + }; + + //------------------------------------ + //------------------------------------ + newPlayer.DrawStatus = function() + { + CATTRIB(bgColour | puLifeColour | CA.F_INTENSITY); + XYTEXT(0, statusY, format("%s : %d ", lifePix, .lives)); + CATTRIB(bgColour | powerupColour); + XYTEXT(10, statusY, format("%s : %d ", bombExtraPix, .maxBombs)); + XYTEXT(20, statusY, format("%s : %d ", bombSizePix, .bombSize)); + CATTRIB(bgColour | statusColour); + XYTEXT(50, statusY, format("Score : %d ", .score)); + }; + + newPlayer.AddScore = function(a_add) + { + .score = .score + a_add; + .DrawStatus(); + }; + + //------------------------------------ + //------------------------------------ + newPlayer.CanMove = function(a_x, a_y) + { + thing = GetThingAt(a_x, a_y, false); + .lastCanMoveThing = thing; + return thing.type == T_Space or thing.type == T_Explosion or + thing.type == T_Powerup or thing.type == T_Enemy; + }; + + //------------------------------------ + //------------------------------------ + newPlayer.Move = function(a_dx, a_dy) + { + if (!.dead) + { + oldX = .x; + oldY = .y; + newX = ScreenClampX(.x + a_dx); + newY = ScreenClampY(.y + a_dy); + + if (.CanMove(newX, newY)) + { + .x = newX; + .y = newY; + if (.lastCanMoveThing.type == T_Powerup) + { + .lastCanMoveThing.thing.Pickup(); + } + else if (.lastCanMoveThing.type == T_Explosion or .lastCanMoveThing.type == T_Enemy) + { + .Kill(); + } + + RefreshXY(oldX, oldY); + RefreshXY(.x, .y); + } + } + }; + + //------------------------------------ + //------------------------------------ + newPlayer.Kill = function() + { + .dead = true; + RefreshXY(.x, .y); + }; + + //------------------------------------ + //------------------------------------ + newPlayer.DropBomb = function() + { + if (!.dead and .nextBomb < .maxBombs and !BombAt(.x, .y)) + { + newBomb = Bomb(.x, .y, .bombSize, .bombFuse, this); + .bombs[.nextBomb] = newBomb; + .nextBomb = .nextBomb + 1; + newBomb.Draw(); + } + }; + + //------------------------------------ + //------------------------------------ + newPlayer.FreeBomb = function(a_bomb) + { + found = false; + limit = .nextBomb; + for (i = 0; i < limit; i=i+1) + { + if (.bombs[i] == a_bomb) + { + found = true; + .nextBomb = .nextBomb - 1; + } + if (found) + { + if (i+1 < limit) + { + .bombs[i] = .bombs[i+1]; + } + else + { + .bombs[i] = null; + } + } + } + }; + + //------------------------------------ + //------------------------------------ + newPlayer.StartThread = function() + { + this:stateSet(.IdleState); + }; + + //------------------------------------ + //------------------------------------ + newPlayer.IdleState = function() + { + while (!quit) + { + pressed = false; + if (ISPRESSED(38)) + { + .Move(0, -1); + pressed = true; + } + else if (ISPRESSED(40)) + { + .Move(0, 1); + pressed = true; + } + else if (ISPRESSED(39)) + { + .Move(1, 0); + pressed = true; + } + else if (ISPRESSED(37)) + { + .Move(-1, 0); + pressed = true; + } + else if (ISPRESSED(' ')) + { + .DropBomb(); + pressed = true; + } + + if (pressed) + { + sleep(0.075); + } + else if (.dead) + { + this:stateSet(.DeadState); + } + else + { + yield(); + } + } + }; + + //------------------------------------ + //------------------------------------ + newPlayer.DeadState = function() + { + sleep(explodeTime); + if (.lives > 0) + { + .lives = .lives - 1; + } + if (.maxBombs > 1) + { + .maxBombs = .maxBombs - 1; + } + if (.bombSize > 1) + { + .bombSize = .bombSize - 1; + } + .DrawStatus(); + + while (!quit) + { + if (.lives > 0 and ISPRESSED(' ')) + { + while (!quit) + { + pos = .GetStartPos(); + thing = GetThingAt(pos.x, pos.y, false); + if (thing.type == T_Enemy) + { + thing.thing.Kill(); + } + sleep(0.2); + + oldX = .x; + oldY = .y; + .x = pos.x; + .y = pos.y; + + .dead = false; + RefreshXY(oldX, oldY); + RefreshXY(.x, .y); + this:stateSet(.IdleState); + } + } + yield(); + } + }; + + //------------------------------------ + //------------------------------------ + newPlayer.Overlap = PointOverlap; + + //------------------------------------ + //------------------------------------ + newPlayer.Cheat = function() + { + .lives = 5; + .maxBombs = 10; + .bombSize = 5; + .DrawStatus(); + }; + + newPlayer.GetStartPos = function() + { + // Position near centre. + ptx = grid.startX + (grid.rows/2)*grid.spaceX; + pty = grid.startY + (grid.cols/2)*grid.spaceY; + return table(x = ptx, y = pty); + }; + + pos = newPlayer.GetStartPos(); + newPlayer.x = pos.x; + newPlayer.y = pos.y; + + newPlayer.Start = function() + { + .threadId = this:thread(.StartThread); + }; + + newPlayer.Stop = function() + { + threadKill(.threadId); + }; + + return newPlayer; +}; + +//-------------------------------------------------------------------------------------------------- +// Bomb object. +//-------------------------------------------------------------------------------------------------- +global Bomb = function(a_x, a_y, a_size, a_fuse, a_owner) +{ + newBomb = table(x = a_x, y = a_y, size = a_size, fuse = a_fuse, owner = a_owner); + newBomb.explode = false; + newBomb.expMinX = 0; + newBomb.expMaxX = 0; + newBomb.expMinY = 0; + newBomb.expMaxY = 0; + newBomb.visible = true; + newBomb.threadId = -1; + + newBomb.CountDown = function() + { + this:stateSet(.FuseState); + }; + + newBomb.Explode = function() + { + this:stateSetOnThread(.threadId, .ExplodeState); + }; + + newBomb.FuseState = function() + { + sleep(.fuse); + this:stateSet(.ExplodeState); + }; + + newBomb.ExplodeState = function() + { + .expMinX = ScreenClampX(.x - .size); + .expMaxX = ScreenClampX(.x + .size); + .expMinY = ScreenClampY(.y - .size); + .expMaxY = ScreenClampY(.y + .size); + + .explode = true; + .visible = false; + .KillStuff(); + .visible = true; + .Draw(); + count = 1+g_count; + + inc = explodeCycle/explodeTime; + for (i = 0; i < explodeTime; i = i + inc) + { + sleep(explodeCycle); + .Draw(); + } + + .visible = false; + RefreshRect(.expMinX, .expMinY, .expMaxX - .expMinX + 1, .expMaxY - .expMinY + 1); + if (.owner != null) + { + .owner.FreeBomb(this); + } + exit(); + }; + + newBomb.KillStuff = function() + { + // Kill stuff. + for (x = .x; x >= .expMinX; x=x-1) + { + if (!.TryKill(GetThingAt(x, .y, true))) + { + .expMinX = x; + break; + } + } + for (x = .x+1; x <= .expMaxX; x=x+1) + { + if (!.TryKill(GetThingAt(x, .y, true))) + { + .expMaxX = x; + break; + } + } + + for (y = .y; y >= .expMinY; y=y-1) + { + if (!.TryKill(GetThingAt(.x, y, true))) + { + .expMinY = y; + break; + } + } + for (y = .y+1; y <= .expMaxY; y=y+1) + { + if (!.TryKill(GetThingAt(.x, y, true))) + { + .expMaxY = y; + break; + } + } + }; + + newBomb.TryKill = function(a_thing) + { + if (a_thing.type == T_Block) + { + a_thing.thing.Kill(); + return false; + } + else if (a_thing.type == T_Bomb and a_thing.thing != this) + { + a_thing.thing.Explode(); + } + else if (a_thing.type == T_Player or a_thing.type == T_Enemy) + { + a_thing.thing.Kill(); + } + return true; + }; + + newBomb.Draw = function() + { + if (.visible) + { + if (.explode) + { + CATTRIB(bgColour | expColours[randint(0, expColourCount)]); + for (x = .expMinX; x <= .expMaxX; x=x+1) + { + if (IsSpaceOnGrid(x, .y)) + { + XYTEXT(x, .y, expPix); + } + } + + for (y = .expMinY; y <= .expMaxY; y=y+1) + { + if (IsSpaceOnGrid(.x, y)) + { + XYTEXT(.x, y, expPix); + } + } + } + else + { + CATTRIB(bgColour | bombColour); + XYTEXT(.x, .y, bombPix); + } + } + }; + + newBomb.Overlap = function(a_x1, a_y1, a_x2, a_y2) + { + if (.explode) + { + return OverlapRect(.expMinX, .y, .expMaxX, .y+1, a_x1, a_y1, a_x2, a_y2) and OverlapRect(.x, .expMinY, .x+1, .expMaxY, a_x1, a_y1, a_x2, a_y2); + } + return IsPointWithin(.x, .y, a_x1, a_y1, a_x2, a_y2); + }; + + newBomb.FuseThread = function() + { + sleep(.fuse); + .Explode(); + }; + + newBomb.threadId = newBomb:thread(newBomb.CountDown); + newBomb:thread(newBomb.FuseThread); + return newBomb; +}; + +//-------------------------------------------------------------------------------------------------- +// Block code. +//-------------------------------------------------------------------------------------------------- +global Block = function(a_x, a_y) +{ + newBlock = table(x = a_x, y = a_y, visible = true); + newBlock.hits = 1; + + newBlock.Draw = function() + { + if (.visible) + { + CATTRIB(bgColour | blockColour); + if (.hits == 3) + { + XYTEXT(.x, .y, block3Pix); + } + else if (.hits == 2) + { + XYTEXT(.x, .y, block2Pix); + } + else + { + XYTEXT(.x, .y, block1Pix); + } + } + }; + + newBlock.Overlap = PointOverlap; + + newBlock.KillThread = function() + { + yield(); + yield(); + if (.visible) + { + .visible = false; + player.AddScore(scoreBlock); + if (randint(0, 100) < powerupChance) + { + AddPowerup(.x, .y); + } + } + }; + + newBlock.Kill = function() + { + .hits = .hits - 1; + if (.hits == 0) + { + this:thread(.KillThread); + } + RefreshXY(.x, .y); + }; + + return newBlock; +}; + +global CreateBlocks = function(a_num) +{ + global maxBlockHits; + global blocks = table(count = 0, blocks = array(a_num)); + for (i = 0; i < a_num; i=i+1) + { + pos = GetRandomFreePos(DT_Block, true); + if (pos.x != -1 and pos.y != -1) + { + thing = GetThingAt(pos.x, pos.y, false); + if (thing.type == DT_Block) + { + if (thing.thing.hits < maxBlockHits) + { + thing.thing.hits = thing.thing.hits + 1; + } + } + else + { + blocks.blocks[i] = Block(pos.x, pos.y); + blocks.count = i; + } + } + } + blocks.count = a_num; +}; + +//-------------------------------------------------------------------------------------------------- +// Powerup. +//-------------------------------------------------------------------------------------------------- +global Powerup = function(a_x, a_y, a_type) +{ + newPu = table(x = a_x, y = a_y, type = a_type); + + if (a_type == PT_Bomb) + { + newPu.Draw = function() + { + CATTRIB(bgColour | powerupColour); + XYTEXT(.x, .y, bombExtraPix); + }; + + newPu.Pickup = function() + { + if (player.maxBombs < maxPlayerBombs) + { + player.maxBombs = player.maxBombs + 1; + } + player.DrawStatus(); + RemovePowerup(this); + }; + } + else if (a_type == PT_Size) + { + newPu.Draw = function() + { + CATTRIB(bgColour | powerupColour); + XYTEXT(.x, .y, bombSizePix); + }; + + newPu.Pickup = function() + { + if (player.bombSize < maxPlayerSize) + { + player.bombSize = player.bombSize + 1; + } + player.DrawStatus(); + RemovePowerup(this); + }; + } + else if (a_type == PT_Life) + { + newPu.Draw = function() + { + CATTRIB(bgColour | puLifeColour); + XYTEXT(.x, .y, lifePix); + }; + + newPu.Pickup = function() + { + if (player.lives < maxLives) + { + player.lives = player.lives + 1; + } + player.DrawStatus(); + RemovePowerup(this); + }; + } + else + { + newPu.Draw = function() + { + }; + + newPu.Pickup = function() + { + RemovePowerup(this); + }; + } + + newPu.Overlap = PointOverlap; + + return newPu; +}; + +//-------------------------------------------------------------------------------------------------- +// Powerup management. +//-------------------------------------------------------------------------------------------------- +global RandomPowerupType = function() +{ + int = randint(0, 100); + + if (int < 49) + { + return PT_Bomb; + } + if (int < 98) + { + return PT_Size; + } + + return PT_Life; +}; + +global AddPowerup = function(a_x, a_y) +{ + if (powerups.count < maxPowerups) + { + powerups.powerups[powerups.count] = Powerup(a_x, a_y, RandomPowerupType()); + powerups.count = powerups.count + 1; + RefreshXY(a_x, a_y); + } +}; + +global RemovePowerup = function(a_pu) +{ + found = false; + count = powerups.count; + for (i = 0; i < count; i = i + 1) + { + if (powerups.powerups[i] == a_pu) + { + found = true; + powerups.powerups[i] = null; + powerups.count = powerups.count - 1; + } + if (found) + { + if (i+1 < count) + { + powerups.powerups[i] = powerups.powerups[i+1]; + } + else + { + powerups.powerups[i] = null; + } + } + } +}; + +global InitPowerups = function() +{ + global powerups = table(count = 0, powerups = array(maxPowerups)); +}; + +//-------------------------------------------------------------------------------------------------- +// Enemies. +//-------------------------------------------------------------------------------------------------- +global CreateEnemies = function(a_num) +{ + global enemies = table(count = 0, enemies = array(a_num)); + + for (i = 0; i < a_num; i=i+1) + { + pos = GetRandomFreePos(DT_Enemy, false); + if (pos.x != -1 and pos.y != -1) + { + enemies.enemies[i] = Enemy(pos.x, pos.y); + enemies.count = i+1; + } + } +}; + +global Enemy = function(a_x, a_y) +{ + newEnemy = table(x = a_x, y = a_y, dead = false); + newEnemy.lastCanMoveThing = null; + newEnemy.lastPos = table(x = a_x, y = a_y); + newEnemy.threadId = -1; + + //------------------------------------ + //------------------------------------ + newEnemy.Draw = function() + { + if (!.dead) + { + CATTRIB(bgColour | nmeColour); + XYTEXT(.x, .y, nmePix); + } + }; + + //------------------------------------ + //------------------------------------ + newEnemy.Kill = function() + { + player.AddScore(scoreNME); + .dead = true; + if (randint(0, 100) < powerupChance) + { + AddPowerup(.x, .y); + } + RefreshXY(.x, .y); + }; + + //------------------------------------ + //------------------------------------ + newEnemy.Overlap = PointOverlap; + + //------------------------------------ + // Movement. + //------------------------------------ + newEnemy.CanMove = function(a_x, a_y) + { + if (a_x < 0 or a_x >= screen.w or a_y < 0 or a_y > screen.h) + { + return false; + } + + thing = GetThingAt(a_x, a_y, false); + .lastCanMoveThing = thing; + return thing.type == T_Space or thing.type == T_Exlposion or + thing.type == T_Powerup or thing.type == T_Player; + }; + + //------------------------------------ + //------------------------------------ + newEnemy.MoveX = function() + { + // Is the player on the same column? + if (.y == player.y) + { + // Are we within a grid spacing? + if (player.x - .x <= grid.spaceX + 1) + { + if (.x < player.x) + { + start = .x+1; + end = player.x+1; + moveX = start; + } + else + { + start = player.x+1; + end = .x; + moveX = end-1; + } + // Do we have a clear path. + moveOk = true; + for (x = start; moveOk and x < end; x=x+1) + { + if (!.CanMove(x, .y)) + { + moveOk = false; + } + } + if (moveOk and .CanMove(moveX, .y)) + { + .MoveTo(moveX, .y); + return true; + } + } + } + + mx = 1; + if (player.x < .x) + { + mx = -1; + } + if ((.x+mx != .lastPos.x or .y != .lastPos.y) and .CanMove(.x+mx, .y)) + { + .MoveTo(.x+mx, .y); + return true; + } + return false; + }; + + //------------------------------------ + //------------------------------------ + newEnemy.MoveY = function() + { + // Is the player on the same row? + if (.x == player.x) + { + // Are we within a grid spacing? + if (player.y - .y <= grid.spaceY + 1) + { + if (.y < player.y) + { + start = .y+1; + end = player.y+1; + moveY = start; + } + else + { + start = player.y+1; + end = .y; + moveY = end-1; + } + // Do we have a clear path. + moveOk = true; + for (y = start; moveOk and y < end; y=y+1) + { + if (!.CanMove(.x, y)) + { + moveOk = false; + } + } + if (moveOk and .CanMove(.x, moveY)) + { + .MoveTo(.x, moveY); + return true; + } + } + } + + my = 1; + if (player.y < .y) + { + my = -1; + } + if ((.x != .lastPos.x or .y+my != .lastPos.y) and .CanMove(.x, .y+my)) + { + .MoveTo(.x, .y+my); + return true; + } + return false; + }; + + //------------------------------------ + //------------------------------------ + newEnemy.MoveTo = function(a_x, a_y) + { + .lastPos.x = .x; + .lastPos.y = .y; + + thing = GetThingAt(a_x, a_y, false); + + .x = a_x; + .y = a_y; + + if (thing.type == T_Player) + { + player.Kill(); + } + else if (thing.type == T_Explosion) + { + .Kill(); + } + + RefreshXY(.lastPos.x, .lastPos.y); + RefreshXY(.x, .y); + }; + + //------------------------------------ + //------------------------------------ + newEnemy.Move = function() + { + moved = false; + if (!player.dead) + { + // Try move towards the player. + preferX = abs(player.x - .x) > abs(player.y - .y); + if (preferX) + { + moved = .MoveX(); + if (!moved) + { + moved = .MoveY(); + } + } + else + { + moved = .MoveY(); + if (!moved) + { + moved = .MoveX(); + } + } + + // Try move away from the last position. + if (!moved) + { + testX = 2*.x - .lastPos.x; + testY = 2*.y - .lastPos.y; + if (.CanMove(testX, testY)) + { + .MoveTo(testX, testY); + moved = true; + } + } + } + + if (!moved and (.lastPos.x != .x or .lastPos.y != .y) and .CanMove(.lastPos.x, .lastPos.y)) + { + .MoveTo(.lastPos.x, .lastPos.y); + } + }; + + //------------------------------------ + // Thread functions and states. + //------------------------------------ + newEnemy.Start = function() + { + .threadId = this:thread(.IdleState); + }; + + //------------------------------------ + //------------------------------------ + newEnemy.IdleState = function() + { + while (!quit and !.dead) + { + sleep(nmeMoveTime); + .Move(); + } + }; + + newEnemy.Start(); + + return newEnemy; +}; + +//-------------------------------------------------------------------------------------------------- +// Refresh functions. +//-------------------------------------------------------------------------------------------------- +global Refresh = function() +{ + CATTRIB(bgColour | fgColour); + CLS(); + + // Draw blocks. + for (b = 0; b < blocks.count; b=b+1) + { + blocks.blocks[b].Draw(); + } + + // Draw powerups. + for (p = 0; p < powerups.count; p=p+1) + { + powerups.powerups[p].Draw(); + } + + // Draw enemies. + for (e = 0; e < enemies.count; e=e+1) + { + enemies.enemies[e].Draw(); + } + + // Draw bombs. + for (b = 0; b < player.nextBomb; b=b+1) + { + player.bombs[b].Draw(); + } + + player.Draw(); + player.DrawStatus(); + + DrawGrid(); +}; + +global RefreshXY = function(a_x, a_y) +{ + RefreshRect(a_x, a_y, 1, 1); +}; + +global RefreshRect = function(a_x, a_y, a_w, a_h) +{ + // Clear the area. + xLimit = a_x + a_w; + yLimit = a_y + a_h; + CATTRIB(bgColour | fgColour); + for (x = a_x; x < xLimit; x=x+1) + { + for (y = a_y; y < yLimit; y=y+1) + { + XYTEXT(x, y, spacePix); + } + } + + // Draw blocks. + for (b = 0; b < blocks.count; b=b+1) + { + blk = blocks.blocks[b]; + if (blk.Overlap(a_x, a_y, xLimit, yLimit)) + { + blk.Draw(); + } + } + + // Draw powerups. + for (p = 0; p < powerups.count; p=p+1) + { + pu = powerups.powerups[p]; + if (pu.Overlap(a_x, a_y, xLimit, yLimit)) + { + pu.Draw(); + } + } + + // Draw enemies. + for (e = 0; e < enemies.count; e=e+1) + { + nme = enemies.enemies[e]; + if (nme.Overlap(a_x, a_y, xLimit, yLimit)) + { + nme.Draw(); + } + } + + // Draw bombs. + for (b = 0; b < player.nextBomb; b=b+1) + { + bomb = player.bombs[b]; + if (bomb.Overlap(a_x, a_y, xLimit, yLimit)) + { + bomb.Draw(); + } + } + + if (player.Overlap(a_x, a_y, xLimit, yLimit)) + { + player.Draw(); + } + + DrawGridRect(a_x, a_y, a_w, a_h); +}; + +//-------------------------------------------------------------------------------------------------- +// Grid control. +//-------------------------------------------------------------------------------------------------- +global Grid = function(a_startX, a_startY, a_spaceX, a_spaceY) +{ + grid.startX = a_startX; + grid.startY = a_startY; + grid.spaceX = a_spaceX; + grid.spaceY = a_spaceY; + + grid.rows = (screen.w-grid.startX) / (grid.spaceX + 1); + grid.cols = (screen.h-grid.startY) / (grid.spaceY + 1); + + if ((screen.w-grid.startX) % (grid.spaceX + 1) != 0) + { + grid.rows = grid.rows + 1; + } + + if ((screen.h-grid.startY) % (grid.spaceY + 1) != 0) + { + grid.cols = grid.cols + 1; + } +}; + +global DrawGrid = function() +{ + DrawGridRect(0, 0, screen.w, screen.h); +}; + +global DrawGridRect = function(a_startX, a_startY, a_w, a_h) +{ + xLimit = a_startX + a_w; + yLimit = a_startY + a_h; + CATTRIB(bgColour | gridColour); + for (x = a_startX; x < xLimit; x=x+1) + { + for (y = a_startY; y < yLimit; y=y+1) + { + if (!IsSpaceOnGrid(x, y)) + { + XYTEXT(x, y, gridPix); + } + } + } +}; + +global IsSpaceOnGrid = function(a_x, a_y) +{ + return (a_x - grid.startX) % (grid.spaceX+1) == 0 or (a_y - grid.startY) % (grid.spaceY+1) == 0; +}; + +global IsFreePos = function(a_x, a_y, a_allowBlocks) +{ + thing = GetThingAt(a_x, a_y, true); + return thing.type == T_Space or (a_allowBlocks and thing.type == T_Block); +}; + +global GetThingAt = function(a_x, a_y, a_ignoreExplosion) +{ + if (!IsSpaceOnGrid(a_x, a_y)) + { + return table(thing = grid, type = T_Grid); + } + + // Test blocks + for (b = 0; b < blocks.count; b=b+1) + { + blk = blocks.blocks[b]; + if (blk.visible and blk.x == a_x and blk.y == a_y) + { + return table(thing = blk, type = T_Block); + } + } + + // Test enemies. + for (e = 0; e < enemies.count; e=e+1) + { + nme = enemies.enemies[e]; + if (!nme.dead and nme.x == a_x and nme.y == a_y) + { + return table(thing = nme, type = T_Enemy); + } + } + + // Test player pos. + if (!player.dead and a_x == player.x and a_y == player.y) + { + return table(thing = player, type = T_Player); + } + + // Test bombs. + for (b = 0; b < player.nextBomb; b=b+1) + { + bomb = player.bombs[b]; + if (!bomb.explode) + { + if (bomb.x == a_x and bomb.y == a_y) + { + return table(thing = bomb, type = T_Bomb); + } + } + else if (!a_ignoreExplosion and bomb.Overlap(a_x, a_y, a_x+1, a_y+1)) + { + return table(thing = bomb, type = T_Explosion); + } + } + + // Test powerups. + for (p = 0; p < powerups.count; p=p+1) + { + pu = powerups.powerups[p]; + if (pu.x == a_x and pu.y == a_y) + { + return table(thing = pu, type = T_Powerup); + } + } + + return table(thing = null, type = T_Space); +}; + +global InDeadZone = function(a_dtType, a_x, a_y) +{ + if (a_dtType == DT_Block) + { + return IsPointWithin(a_x, a_y, blockDeadZone.x1, blockDeadZone.y1, blockDeadZone.x2, blockDeadZone.y2); + } + if (a_dtType == DT_Enemy) + { + return IsPointWithin(a_x, a_y, enemyDeadZone.x1, enemyDeadZone.y1, enemyDeadZone.x2, enemyDeadZone.y2); + } + return false; +}; + +global GetRandomFreePos1 = function(a_deadZoneType, a_allowBlocks, a_tries) +{ + row = randint(0, grid.rows); + col = randint(0, grid.cols); + + px = row*grid.spaceX + grid.startX; + py = col*grid.spaceY + grid.startY; + + if (a_deadZoneType != DT_None and InDeadZone(a_deadZoneType, px, py)) + { + return GetRandomFreePos1(a_deadZoneType, a_tries); + } + + if (IsFreePos(px, py)) + { + return table(x = px, y = py); + } + + while (py < screen.h) + { + py=py+1; + if ((a_deadZoneType == DT_None or !InDeadZone(a_deadZoneType, px, py)) and IsFreePos(px, py)) + { + return table(x = px, y = py); + } + } + + if (tries < 5) + { + return GetRandomFreePos1(a_tries+1); + } + return table(x = -1, y = -1); +}; + +global GetRandomFreePos = function(a_deadZoneType, a_allowBlocks) +{ + return GetRandomFreePos1(a_deadZoneType, a_allowBlocks, 0); +}; + +//-------------------------------------------------------------------------------------------------- +// Initialisation. +//-------------------------------------------------------------------------------------------------- +RenderRect = function(a_rect) +{ + CATTRIB(bgColour | gridColour); + for (i = a_rect.x1; i <= a_rect.x2; i=i+1) + { + for (j = a_rect.y1; j <= a_rect.y2; j=j+1) + { + XYTEXT(i, j, "o"); + } + } +}; + +MemThread = function() +{ + while (!quit) + { + CATTRIB(bgColour | statusColour); + XYTEXT(65, statusY, format("Mem: %d ", sysGetMemoryUsage())); + sleep(1.0); + } +}; + +//-------------------------------------------------------------------------------------------------- +// Level thread. +//-------------------------------------------------------------------------------------------------- +global GameOver = function() +{ + CATTRIB(bgColour | statusColour); + CLS(); + + local score = player.score; + KillAll(); + + sleep(0.3); + + global quit; + while (!quit) + { + CATTRIB(bgColour | expColours[randint(0, expColourCount)]); + x = 8; + y = 8; + XYTEXT(x, y, "__________________________________________________________"); y=y+1; + XYTEXT(x, y, " __ __ "); y=y+1; + XYTEXT(x, y, " / ) / ) "); y=y+1; + XYTEXT(x, y, " / __ _ _ __ / / __ )__ "); y=y+1; + XYTEXT(x, y, " / --, / ) / / ) /___) / / | / /___) / )"); y=y+1; + XYTEXT(x, y, "_(____/___(___(_/_/__/_(___ ____(____/____|/__(___ _/_____"); y=y+1; + + CATTRIB(bgColour | statusColour); + XYTEXT(0, statusY, format("Score : %d", score)); + + if (threadTime() < 1000 and ISPRESSED(' ')) + { + stateSet(TitleScreenState); + } + else if (ISPRESSED(27)) + { + quit = true; + } + + sleep(randfloat(0.03, 0.3)); + } + + global player = null; + global blocks = null; + global enemies = null; + + stateSet(TitleScreenState); +}; + +global GameState = function() +{ + global maxLevel; + global player; + global blocks; + global enemies; + global gameLevel; + Grid(3, 2, 5, 5); + if (player == null or player.lives <= 0) + { + player = Player(); + } + pos = player.GetStartPos(); + player.x = pos.x; + player.y = pos.y; + + global nmeMoveTime = 1.0 - gameLevel*0.1; + + InitPowerups(); + CreateBlocks(min(10 + 10*gameLevel, 99)); + CreateEnemies(5*gameLevel); + yield(); + Refresh(); + + yield(); + player.Start(); + + local done = false; + while (!quit and !done) + { + local count; + + done = true; + if (ISPRESSED(27)) + { + global quit = true; + break; + } +/* + // Check blocks. + count = blocks.count; + for (i = 0; done and i < count; i=i+1) + { + blk = blocks.blocks[i]; + if (blk.visible) + { + done = false; + } + } +*/ + // Check enemies. + count = enemies.count; + for (i = 0; done and i < count; i=i+1) + { + nme = enemies.enemies[i]; + if (!nme.dead) + { + done = false; + } + } + + // Check bombs. + done = done and player.nextBomb == 0; + + // Check for lives. + done = done or player.lives <= 0; + + sleep(0.3); + } + + player.Stop(); + + if (!quit) + { + if (player.lives <= 0) + { + stateSet(GameOver); + } + global gameLevel; + gameLevel=gameLevel+1; + stateSet(LevelState); + } + + KillAll(); +}; + +global LevelState = function() +{ + global maxLevel; + global gameLevel; + + if (gameLevel > maxLevel) + { + gameLevel = maxLevel; + } + + CATTRIB(bgColour | statusColour); + CLS(); + + sleep(0.3); + + global quit; + while (!quit) + { + CATTRIB(bgColour | expColours[randint(0, expColourCount)]); + x = 17; + y = 8; + XYTEXT(x, y, "___________________________________________"); y=y+1; + XYTEXT(x, y, " ____ ___ "); y=y+1; + XYTEXT(x, y, " / ) / ( ) "); y=y+1; + XYTEXT(x, y, " /___ / __ __ __ / / "); y=y+1; + XYTEXT(x, y, " / | /___) / ) / / / / / "); y=y+1; + XYTEXT(x, y, "_/_____|__(___ _(___(_(___/___(___/__o_____"); y=y+1; + XYTEXT(x, y, " / "); y=y+1; + XYTEXT(x, y, " (_ / "); y=y+1; + + if (threadTime() > 1000 and ISPRESSED(' ')) + { + CLS(); + sleep(0.5); + stateSet(GameState); + } + else if (ISPRESSED(27)) + { + quit = true; + } + + sleep(randfloat(0.03, 0.3)); + } + + KillAll(); +}; + +global KillAll = function() +{ + // Kill all threads. + global player; + global enemies; + global blocks; + + if (player) + { + local count = player.nextBomb; + for (i = 0; i < count; i=i+1) + { + threadKill(player.bombs[i].threadId); + } + threadKill(player.threadId); + } + + if (enemies) + { + count = enemies.count; + for (i = 0; i < count; i=i+1) + { + threadKill(enemies.enemies[i].threadId); + } + } +}; + +global TitleScreenState = function() +{ + CATTRIB(bgColour | statusColour); + CLS(); + sleep(0.3); + while (!quit) + { + CATTRIB(bgColour | expColours[randint(0, expColourCount)]); + x = 17; + y = 8; + XYTEXT(x, y, "_________________________________________"); y=y+1; + XYTEXT(x, y, " ____ "); y=y+1; + XYTEXT(x, y, " / ) / "); y=y+1; + XYTEXT(x, y, " /__ / __ _ _ /__ __ )__ "); y=y+1; + XYTEXT(x, y, " / ) / ) / / ) / ) /___) / )"); y=y+1; + XYTEXT(x, y, "_/____/___(___/_/_/__/_(___/_(___ _/_____"); y=y+1; + XYTEXT(x, y, "_________________________________________"); y=y+1; + + if (ISPRESSED(27)) + { + global quit = true; + break; + } + else if (ISPRESSED(' ')) + { + global gameLevel = 1; + stateSet(LevelState); + } + sleep(randfloat(0.03, 0.3)); + } + + KillAll(); + exit(); +}; + +CURSOR(0, 0); // bool visible, percentage visible +CATTRIB(fgColour | bgColour); + +thread(MemThread); + +quit = false; +CLS(); + +stateSet(TitleScreenState); diff --git a/vscript/languages/gm/scripts/BomberRun.gm b/vscript/languages/gm/scripts/BomberRun.gm new file mode 100644 index 00000000..7c952a0f --- /dev/null +++ b/vscript/languages/gm/scripts/BomberRun.gm @@ -0,0 +1,691 @@ + +//----------------------------------------------------------------------------- +// BomberRun by George Allan +//----------------------------------------------------------------------------- + +global score = 0; +global height = 23; +global gframe = 0; +global detec = table(); +global killStars = 0; +global playerx = 0; +global playery = 0; +global fireCnt = 0; +global fireMax = 3; +global clearExplo = 0; + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +global sync = function() { + time = TICK(); + wait = (1./30.) - time; + if(wait > 0) { + sleep(wait); + } + TICK(); + global gframe = gframe + 1; +}; + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +global star = function() { + + global detec; + global killStars; + + frame = 0; + while (1) { + + x = randint(1,79); + y = randint(2,height); + + // On top of a building ? + if (y < detec[x]-1) { + + // Print Star for a while + t = randint(50,100); + for (i=0;it-2) { + XYTEXT(x,y,","); + } + else { + XYTEXT(x,y,"."); + } + + // Sync to the master frame + while (frame == gframe) { + yield(); + if (killStars) { + exit(); + } + } + frame = gframe; + } + + // Clear Star + CATTRIB(CA.F_BLUE | CA.B_BLUE); + XYTEXT(x,y," "); + } + yield(); + if (killStars) { + exit(); + } + } +}; + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +global particle = function(x, y) { + + global detec; + global clearExplo; + + pcoltab = table(CA.F_RED|CA.F_INTENSITY, CA.F_RED|CA.F_GREEN|CA.F_INTENSITY, CA.F_RED|CA.F_GREEN|CA.F_BLUE|CA.F_INTENSITY); + pfrtab = table(".", "+", "*"); + + xmom = randfloat(-1.0,1.0); +// ymom = randfloat(-0.2,-2.0); + ymom = randfloat(-2.0,-0.2); + + xpos = x.Float(); + ypos = y.Float(); + + frame = -1; + + time = randint(10,40); + from = time; + + frint = randint(0,3); + + while (1) { + + if (y < detec[x]) { + CATTRIB(CA.F_BLUE | CA.B_BLUE); + XYTEXT(x,y," "); + } + xpos = xpos + xmom; + ypos = ypos + ymom; + ymom = ymom + 0.15f; + x = xpos.Int(); + y = ypos.Int(); + + // On Screen + if ( y >= height || y < 0 || x < 0 || x > 79) { + exit(); + } + + // Out of Time ? + time = time - 1; + if (time < 0 || clearExplo) { + exit(); + } + + if (y < detec[x]) { + fr = (time*3) / from; + CATTRIB(pcoltab[fr] | CA.B_BLUE); + XYTEXT(x,y,pfrtab[frint]); + } + + // Sync to the master frame + while (frame == gframe) { + yield(); + } + frame = gframe; + } +}; + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +global explode = function(x, y) { + + global particle; + + for (i=0;i<10;i=i+1) { + thread(particle, x, y); + } +}; + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +global bullet = function() { + + global detec; + global playerx; + global playery; + global score; + global gframe; + global fireCnt; + global score; + global explode; + + firex = playerx; + firey = playery+1; + fireHTG = 4; + frame = gframe; + + score = score - 10; + + while (1) { + + // Detection + if (firey > height-1 || fireHTG <= 0) { + fireCnt = fireCnt - 1; + exit(); + } + else { + // If okay - display + CATTRIB(CA.F_RED|CA.F_GREEN|CA.F_BLUE|CA.F_INTENSITY | CA.B_BLUE); + XYTEXT(firex,firey,"\31"); + } + + // Sync to the master frame + while (frame == gframe) { + yield(); + } + frame = gframe; + + // Clear Bullet + CATTRIB(CA.F_BLUE | CA.B_BLUE); + XYTEXT(firex,firey," "); + + firey = firey + 1; + first = 0; + + // Detection + if (detec[firex] < firey) { + score = score + 10; + detec[firex] = firey; + fireHTG = fireHTG - 1; + // Boom ! + explode(firex,firey); + } + } +}; + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +game = function() { + + global detec; + global killStars; + global star; + global bullet; + global playerx; + global playery; + global fireCnt; + global fireMax; + global score; + global explode; + + killStars = 0; + allgone = 0; + + for (i=0;i<30;i=i+1) { + thread(star); + } + + CATTRIB(CA.F_BLUE | CA.B_BLUE); + CLS(); + + coltab = table(CA.B_GREEN|CA.B_RED, CA.B_BLUE|CA.B_RED, CA.B_BLUE|CA.B_GREEN, CA.B_GREEN); + coltabfore = table(CA.F_GREEN|CA.F_RED, CA.F_BLUE|CA.F_RED, CA.F_BLUE|CA.F_GREEN, CA.F_GREEN); + btypes = table("\254", "\58", "\124"); + ttypes = table("\191", "\194", "\218"); + + // Clear Collision + for (i=0;i<=150;i=i+1) { + detec[i] = height; + } + + // Buildings + for (x=0;x<80;x=x+1) { + + // Calc Height + rand = 10; + if (x < 30) { + rand = x / 3; + } + if (x > 50) { + rand = (80-x) / 3; + } + if (x < 10) { + rand = 0; + } + if (x > 70) { + rand = 0; + } + rand = randint(0,rand); + if (rand > 1) { + + // Detection + detec[x] = height-rand; + + // Random Building Color + col = randint(0,4); + + // Random Top + if (randint(0,10) < 2) { + CATTRIB(coltabfore[col] | CA.B_BLUE); + ttype = randint(0,3); + XYTEXT(x,height-rand-1,ttypes[ttype]); + } + + // The Main Building + btype = randint(0,3); + CATTRIB(coltab[col] | CA.F_BLACK); + for (y=height-rand;y 10) { + landingtimer = 0; + playery = playery + 1; + } + } + + // Move and reposition if reach the side of the screen + playerx = playerx+1; + if (playerx > 79) { + playerx = 2; + playery = playery + 1; + } + + // Not too low + if (playery > height-1) { + playery = height-1; + } + + // Print at new position + CATTRIB(CA.F_RED|CA.F_GREEN|CA.F_BLUE|CA.F_INTENSITY | CA.B_BLUE); + XYTEXT(playerx-2,playery,"\200"); + XYTEXT(playerx-1,playery,"\205"); + XYTEXT(playerx,playery,"\254"); + + // Landed !!! + if (playerx == 60 && playery == height-1) { + for (i=0;i<60;i=i+1) { + sync(); + } + // Completion bonus - based on fireMax + if (score != 50) { + score = score + (6-fireMax) * 1000; + } + niceone(); + return; + } + + // Hit a building (ignores arieals) + if (detec[playerx+1] <= playery) { + sync(); + + y0 = playery; + y1 = playery; + y2 = playery; + x = playerx; + + // Dramatic Pause ! + for (i=0;i<20;i=i+1) { + XYTEXT(x-2,y0,"\200"); + XYTEXT(x-1,y1,"\205"); + XYTEXT(x-0,y2,"\254"); + sync(); + } + + done = 0; + while (!done) { + done = 1; + + // Clear + CATTRIB(CA.F_BLUE | CA.B_BLUE); + XYTEXT(x-2,y0," "); + XYTEXT(x-1,y1," "); + XYTEXT(x-0,y2," "); + + // Move + if (y0 < detec[x-2]-1) { + y0 = y0 + 1; + done = 0; + } + if (y1 < detec[x-1]-1) { + y1 = y1 + 1; + done = 0; + } + if (y2 < detec[x-0]-1) { + y2 = y2 + 1; + done = 0; + } + + // Print + CATTRIB(CA.F_RED|CA.F_GREEN|CA.F_BLUE|CA.F_INTENSITY | CA.B_BLUE); + XYTEXT(x-2,y0,"\200"); + XYTEXT(x-1,y1,"\205"); + XYTEXT(x-0,y2,"\254"); + sync(); + } + + for (i=0;i<60;i=i+1) { + XYTEXT(x-2,y0,"\200"); + XYTEXT(x-1,y1,"\205"); + XYTEXT(x-0,y2,"\254"); + sync(); + } + gameover(); + return; + } + else { + if (anim == 1) { + XYTEXT(playerx+1,playery,"\217"); + anim = 0; + } + else { + XYTEXT(playerx+1,playery,"\191"); + anim = 1; + } + } + + // Next Frame + sync(); + } +}; + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +titlescreen = function() { + + global killStars = 1; + global fireMax = 0; + global score = 0; + global detec; + global clearExplo = 0; + + for (i=0;i<81;i=i+1) { + detec[i] = height; + } + + CATTRIB(0); + CLS(); + + CATTRIB(CA.F_RED); + CURSOR(0,0); + + maxtab = 12; + tabindex = 0; + tctab = table( CA.F_RED|CA.F_BLUE|CA.F_GREEN | CA.F_INTENSITY, + CA.F_GREEN | CA.F_INTENSITY | CA.F_INTENSITY, + CA.F_BLUE, + CA.F_GREEN | CA.F_INTENSITY, + CA.F_RED|CA.F_GREEN | CA.F_INTENSITY, + CA.F_RED|CA.F_BLUE|CA.F_GREEN | CA.F_INTENSITY, + CA.F_BLUE | CA.F_INTENSITY, + CA.F_BLUE | CA.F_INTENSITY, + CA.F_RED|CA.F_BLUE|CA.F_GREEN, + CA.F_BLUE, + CA.F_BLUE | CA.F_INTENSITY, + CA.F_RED|CA.F_GREEN | CA.F_INTENSITY ); + + maxtab2 = 8; + tabindex2 = 0; + tctab2 = table( CA.F_RED|CA.F_BLUE|CA.F_GREEN | CA.F_INTENSITY, + CA.F_RED|CA.F_BLUE|CA.F_GREEN | CA.F_INTENSITY, + CA.F_RED|CA.F_BLUE|CA.F_GREEN | CA.F_INTENSITY, + CA.F_RED|CA.F_GREEN | CA.F_INTENSITY, + CA.F_RED | CA.F_INTENSITY, + CA.F_RED, + CA.F_RED | CA.F_INTENSITY, + CA.F_RED|CA.F_GREEN | CA.F_INTENSITY ); + + + // Flush Keyboard !? + ISPRESSED(' '); + ISPRESSED(' '); + ISPRESSED(' '); + + while(!fireMax) { + + // Start in which mode + if (ISPRESSED('1')) { fireMax = 1; } + if (ISPRESSED('2')) { fireMax = 2; } + if (ISPRESSED('3')) { fireMax = 3; } + if (ISPRESSED('4')) { fireMax = 4; } + if (ISPRESSED('5')) { fireMax = 5; } + if (ISPRESSED(' ')) { fireMax = 3; } + if (ISPRESSED('C')) { fireMax = 50; } + if (ISPRESSED(27)) { threadKillAll(true); } // Kill all threads when ESC is pressed + + // Title Color + tabindex = tabindex + 1; + if (tabindex >= maxtab) { + tabindex = 0; + } + CATTRIB(tctab[tabindex]); + + CLS(); + XYTEXT(4,2,` ________ ______ ________ `); + XYTEXT(4,3,` ___ __ )____________ ______ /________________ __ \___ ________ `); + XYTEXT(4,4,` __ __ | __ \_ __ ``__ \_ __ \ _ \_ ___/_ /_/ / / / /_ __ \ `); + XYTEXT(4,5,` _ /_/ // /_/ / / / / / / /_/ / __/ / _ _, _// /_/ /_ / / / `); + XYTEXT(4,6,` /_____/ \____//_/ /_/ /_//_.___/\___//_/ /_/ |_| \__,_/ /_/ /_/ `); + + // Text Color + tabindex2 = tabindex2 + 1; + if (tabindex2 >= maxtab2) { + tabindex2 = 0; + } + CATTRIB(tctab2[tabindex2]); + + XYTEXT(12,8, " Written in GameMonkey by Happy "); + + XYTEXT(12,11, " Flatten the city by dropping bombs (spacebar)"); + XYTEXT(12,12, " Destory all buildings to land saftley"); + XYTEXT(12,13, " Score 10 points for each builing piece destoryed"); + XYTEXT(12,14, " Loose 10 points for each bomb dropped"); + XYTEXT(12,15, " Landing bonus is based on difficulty setting"); + + XYTEXT(12,18, " Press 'Space' to play at standard level"); + XYTEXT(12,19, " Press 1-5 to choose difficulty (number of bombs)"); + XYTEXT(12,20, "Press 'C' to play the cheat version (hold the spacebar!)"); + XYTEXT(12,21, " Press 'Q' to to quit during play"); + XYTEXT(12,22, " Press ESC to exit game now"); + + x = randint(2,78); + y = randint(2,height-2); + explode(x,y); + + sync(); + } + + clearExplo = 1; + sync(); + sync(); + clearExplo = 0; +}; + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +global niceone = function() { + + global killStars = 0; + global detec; + global score; + global clearExplo = 0; + global fireMax; + + for (i=0;i<500;i=i+1) { + thread(star); + } + + for (i=0;i<200;i=i+1) { + + CATTRIB(CA.F_RED|CA.F_GREEN|CA.F_BLUE|CA.F_INTENSITY|CA.B_BLUE); + CLS(); + + XYTEXT(1,7,` .__ __. __ ______ _______ ______ .__ __. _______ __ __ __ `); + XYTEXT(1,8,` | \ | || | / | ____| / __ \ | \ | || ____| | || || | `); + XYTEXT(1,9,` | \| || || ,----' |__ | | | || \| || |__ | || || | `); + XYTEXT(1,10,` | . `` || || | | __| | | | || . `` || __| | || || | `); + XYTEXT(1,11,` | |\ || || ``----. |____ | ``--' || |\ || |____ |__||__||__| `); + XYTEXT(1,12,` |__| \__||__| \______|_______| \______/ |__| \__||_______| (__)(__)(__) `); + XY(1,15); + if (score < 0) { + print(" You score is to crap too mention !"); + } + else if (score < 1500) { + print(" Your score is a average", score); + } + else if (score < 3000) { + print(" Your score is a respectable", score); + } + else { + print(" Your score is an awesome", score); + } + if (fireMax == 50) { + XY(1,17); + print(" --- Now try again without cheating ;) ---"); + } + + x = randint(2,78); + y = randint(2,height-2); + explode(x,y); + + sync(); + } + + +}; + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +global gameover = function() { + + global killStars = 1; + global detec; + global score; + global clearExplo = 1; + + CATTRIB(CA.F_RED|CA.F_INTENSITY); + for (i=height+15;i>-15;i=i-1) { + CLS(); + y = i; + if (y >= 0 && y <= height) { XYTEXT(8,y,` _______ ___ .___ ___. _______ `); } + y = y + 1; + if (y >= 0 && y <= height) { XYTEXT(8,y,` / _____| / \ | \/ || ____| `); } + y = y + 1; + if (y >= 0 && y <= height) { XYTEXT(8,y,` | | __ / ^ \ | \ / || |__ `); } + y = y + 1; + if (y >= 0 && y <= height) { XYTEXT(8,y,` | | |_ | / /_\ \ | |\/| || __| `); } + y = y + 1; + if (y >= 0 && y <= height) { XYTEXT(8,y,` | |__| | / _____ \ | | | || |____ `); } + y = y + 1; + if (y >= 0 && y <= height) { XYTEXT(8,y,` \______|/__/ _\__\|__|__|__||_______| `); } + y = y + 1; + if (y >= 0 && y <= height) { XYTEXT(8,y,` / __ \ \ \ / /| ____| _ \ `); } + y = y + 1; + if (y >= 0 && y <= height) { XYTEXT(8,y,` | | | | \ \/ / | |__ | |_) | `); } + y = y + 1; + if (y >= 0 && y <= height) { XYTEXT(8,y,` | | | | \ / | __| | / `); } + y = y + 1; + if (y >= 0 && y <= height) { XYTEXT(8,y,` | ``--' | \ / | |____| |\ \----. `); } + y = y + 1; + if (y >= 0 && y <= height) { XYTEXT(8,y,` \______/ \__/ |_______| _| ``._____| `); } + y = y + 1; + sync(); + } +}; + +//----------------------------------------------------------------------------- +// and finaly - the main loop ! +//----------------------------------------------------------------------------- + + while (1) { + titlescreen(); + game(); + } + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + diff --git a/vscript/languages/gm/scripts/ScriptDescriptions.txt b/vscript/languages/gm/scripts/ScriptDescriptions.txt new file mode 100644 index 00000000..3bb8aa15 --- /dev/null +++ b/vscript/languages/gm/scripts/ScriptDescriptions.txt @@ -0,0 +1,33 @@ +Descriptions of some of the example scripts + +----------------------------------------------------------- + +Snake.gm +Bomber.gm +BomberRun.gm +MineSweeper.gm + +Were written in a few hours by programmers testing an early +version of GameMonkey. They were given the script +reference, a copy of gme.exe and a syntax highlighter file. + +----------------------------------------------------------- + +gmDoc.gm (and related files) + +Is a utility to scan through .cpp files, find comments +relating to GM script bindings and generate a .html file +documenting those functions. + +----------------------------------------------------------- + +benchmark.gm + +Is a set of benchmarks used by Doug Bagley at +http://www.bagley.org/~doug/shootout/ +to compare the performance of several languages. +( Note that simply executing these scripts with +different languages does not provide a true indication +of comparative performance. ) + +----------------------------------------------------------- \ No newline at end of file diff --git a/vscript/languages/gm/scripts/benchmarks.gm b/vscript/languages/gm/scripts/benchmarks.gm new file mode 100644 index 00000000..8c8e3c0d --- /dev/null +++ b/vscript/languages/gm/scripts/benchmarks.gm @@ -0,0 +1,230 @@ +// Set of benchmarks + +sysSetDesiredMemoryUsageHard(16 * 1024, 1); +sysSetDesiredMemoryUsageSoft(sysGetDesiredMemoryUsageHard()); + +// +// +// ACKERMAN +// +// + +print("*** ACKERMAN ***"); + +global Ack = function(M, N) +{ + if (M == 0) + { + N=N+1; + return(N); + } + + if (N == 0) + { + M=M-1; + return(Ack(M, 1)); + } + N=N-1; + return (Ack(M-1, Ack(M, N))); +}; + +NUM = 8; +TICK(); //GD Used to be clock() what was that matt? +print(Ack(3,NUM)); +print("time = ", TICK()); + +// +// +// FIB +// +// + +print("*** FIB ***"); + +global fib = function(n) +{ + if (n < 2) { return(1); } + return fib(n-2) + fib(n-1); +}; + +N = 32; +TICK(); +print(fib(N)); +print("time = ", TICK()); + +// +// +// MATRIX +// +// + +print("*** MATRIX ***"); + +local n = 300; +local size = 30; + +mkmatrix = function(rows, cols) +{ + count = 1; + mx = table(); + + for(i=0; i < rows; i=i+1) + { + row = table(); + for(j = 0; j < cols; j=j+1) + { + row[j] = count; + count=count+1; + } + mx[i] = row; + } + return mx; +}; + +mmult = function(rows, cols, m1, m2) +{ + m3 = table(); + + for(i = 0; i < rows; i=i+1) + { + m3[i] = table(); + m1_i = m1[i]; + for(j = 0; j < cols; j=j+1) + { + rowj = 0; + for(k = 0; k < cols; k=k+1) + { + rowj = rowj + m1_i[k] * m2[k][j]; + } + m3[i][j] = rowj; + } + } + + return m3; +}; + +TICK(); +m1 = mkmatrix(size, size); +m2 = mkmatrix(size, size); + +for(i = 0; i < n; i=i+1) +{ + mm = mmult(size, size, m1, m2); +} + +t = TICK(); + +print(mm[0][0], mm[2][3], mm[3][2], mm[4][4]); +print("time = ", t); + +// +// +// HASH +// +// + +print("*** HASH ***"); + +local n = 80000; +TICK(); + +X=table(); +for(i=1; i <= n; i=i+1) +{ + //print(format("%x", i), i); + X[format("%x", i)] = i; +} + +c = 0; + +for(i=n; i>=1; i=i-1) +{ + if(X[i+""]) + { + c=c+1; + } +} + +print(c); +print("time = ", TICK()); + +// +// +// HEAPSORT +// +// + +print("*** HEAPSORT ***"); + +global IM = 139968.; +global IA = 3877.; +global IC = 29573.; +global LAST = 42.; + +gen_random = function(max) +{ + global LAST = (LAST * IA + IC) % IM; + return ((max * LAST) / IM); +}; + +heapsort = function(n, ra) +{ + l = n/2 + 1; + ir = n; + + for(;;) + { + if(l > 1) + { + l=l-1; + rra = ra[l]; + } + else + { + rra = ra[ir]; + ra[ir] = ra[1]; + ir=ir-1; + if(ir == 1) + { + ra[1] = rra; + return; + } + } + + i = l; + j = l * 2; + while(j <= ir) + { + if(j < ir and ra[j] < ra[j+1]) + { + j=j+1; + } + if(rra < ra[j]) + { + ra[i] = ra[j]; + i = j; + j = j + i; + } + else + { + j = ir + 1; + } + } + + ra[i] = rra; + } +}; + +TICK(); + +local ary = table(); +local N = 80000; + +for(i = 0; i < N; i=i+1) +{ + ary[i] = gen_random(1.0); +} + +heapsort(N, ary); +print(ary[N-1]); +print("time = ", TICK()); diff --git a/vscript/languages/gm/scripts/gmDoc/gmdoc.cmd b/vscript/languages/gm/scripts/gmDoc/gmdoc.cmd new file mode 100644 index 00000000..c49dfba1 --- /dev/null +++ b/vscript/languages/gm/scripts/gmDoc/gmdoc.cmd @@ -0,0 +1,9 @@ +@echo off + +rem Update GM Script function documentation + +..\..\bin\gme.exe gmdoc.gm gmdoc.txt gmdoc.html + +copy gmdoc.html ..\..\doc + +rem Done. \ No newline at end of file diff --git a/vscript/languages/gm/scripts/gmDoc/gmdoc.gm b/vscript/languages/gm/scripts/gmDoc/gmdoc.gm new file mode 100644 index 00000000..a264ef1d --- /dev/null +++ b/vscript/languages/gm/scripts/gmDoc/gmdoc.gm @@ -0,0 +1,333 @@ +//debug(); + +// +// This program generates html documentation for script functions. +// It merely converts comments with a certain syntax into documentation. +// Example: +// +// /*gm +// \lib Library Name +// */ +// +// /*gm +// \function Function name +// \brief Brief description of function +// \param Parameter description, you should describe type information +// \return Return value description +// */ +// + + +// +// \function CreateGMDocumenter +// +global CreateGMDocumenter = function() +{ + documenter = table + ( + // \function ExtractGmCommentStrings + // \param fp is source file handle + // \param commentHandler is a function taking 2 params, comment string and context + // \param context is passed to comment handler + ExtractCommentStrings = function(fp, commentHandler, context) + { + openGmComment = "/*gm"; + openGmCommentLen = openGmComment.Length(); + closeGmComment = "*/"; + closeGmCommentLen = closeGmComment.Length(); + + line = fp.ReadLine(); + while(line) + { + pos = line.Find(openGmComment); + while(pos >= 0) + { + pos = pos + openGmCommentLen; + line = line.Right(line.Length() - pos); + comment = ""; + + // eat up lines untill end of comment + pos = line.Find(closeGmComment); + while(pos < 0) + { + comment = comment + line; + line = fp.ReadLine(); + + if(line == null) + { + pos = 0; + } + else + { + pos = line.Find(closeGmComment); + } + } + + if(line) + { + comment = comment + line.Left(pos); + line = line.Right(line.Length() - (pos + closeGmCommentLen)); + pos = line.Find(openGmComment); + } + else + { + pos = -1; + } + + if(comment.Length() > 0) + { + // process comment string + comment = comment.ReplaceCharsInSet(' ', "\r\n\v"); + commentHandler(comment, context); + } + } + line = fp.ReadLine(); + } + }, + + // \function CommentHandler + // \param comment is an incoming comment string + // \param context is a table with a m_sections table where each m_section + // is a function taking the section string and the context + // context also has a BeginComment() call + CommentHandler = function(comment, context) + { + if(comment and comment.Length()) + { + commentSet = table(); + + foreach(section and sectionHandler in context.m_sections) + { + search = comment; + sectionStart = search.Find(section); + sectionLength = section.Length(); + offset = 0; + + while(sectionStart >= 0) + { + commentSet[offset + sectionStart] = section; + offset = offset + sectionLength; + search = search.Right(search.Length() - sectionLength); + sectionStart = search.Find(section); + } + } + + // commentSet is now a table containing the start positions of each comment bit. + length = comment.Length(); + local j; + + for(i = 0; i < length; i = i + 1) + { + if(commentSet[i]) + { + // find the next comment... + for(j = i + 1; j < length; j = j + 1) + { + if(commentSet[j] or j == (length - 1)) + { + section = commentSet[i]; + sectionLength = section.Length(); + first = i + sectionLength; + count = (j - i) - sectionLength; + subComment = comment.Mid(first, count); + context.m_sections[section](subComment, context); + break; + } + } + } + } + } + }, + + m_files = table(), + + // \function AddFile will add a file to be documented + AddFile = function(filename) + { + .m_files[tableCount(.m_files)] = filename; + }, + + // \function CreateDocumentation will create documentation for all added files + // \param path is the output path for the resulting .html docco + CreateDocumentation = function(filename) + { + context = table(); + context.m_sections = table(); + context.m_htmlOut = system.File(); + context.m_xmlOut = system.File(); + context.m_lib = ""; + + context.m_sections[`\lib`] = function(comment, context) + { + comment = comment.TrimLeft().TrimRight(); + // trim parenthesis + + context.Write("

\n"); + context.Heading(1, comment); + context.Write("

\n"); + context.m_lib = comment; + }; + context.m_sections[`\function`] = function(comment, context) + { + comment = comment.TrimLeft().TrimRight(); + // trim parenthesis + + context.Write("
\n"); + context.Write(format(``,context.m_lib,comment)); + context.Heading(3, comment); + context.Write(``); + context.XMLWrite(format(``, context.m_lib, comment)); + }; + context.m_sections[`\brief`] = function(comment, context) + { + context.Write(format("Brief:%s
", comment)); + }; + context.m_sections[`\param`] = function(comment, context) + { + context.Write(format("Param:%s
", comment)); + }; + context.m_sections[`\return`] = function(comment, context) + { + context.Write(format("Return:%s
", comment)); + }; + context.m_sections[`\sa`] = function(comment, context) + { + context.Write(format("See Also:%s
", comment)); + }; + context.Heading = function(number, string) + { + .m_htmlOut.WriteString(format("%s\n", number, string, number)); + }; + context.m_sections[`\this`] = function(comment, context) + { + context.Write(format("This:%s
", comment)); + }; + context.Paragraph = function(string) + { + .m_htmlOut.WriteString(format("

%s

\n", string)); + }; + context.Write = function(string) + { + .m_htmlOut.WriteString(string); + }; + context.XMLWrite = function(string) + { + if(.m_xmlOut) + { + .m_xmlOut.WriteString(string); + } + }; + + + xmlFilename = filename.SetExtension("xml"); + if(!context.m_xmlOut.Open(xmlFilename, 0)) + { + print("** ERROR: Failed to open XML output file '",xmlFilename,"' ! **"); + context.m_xmlOut = null; + } + + context.XMLWrite(``); + context.XMLWrite(""); + + // + if(context.m_htmlOut.Open(filename, 0)) + { + // write html head + context.Write("GM Documentation"); + foreach(file in .m_files) + { + fp = system.File(); + if(fp.Open(file)) + { + print(`Documenting`, file, `...`); + + .ExtractCommentStrings(fp,.CommentHandler,context); + + fp.Close(); + } + } + + context.XMLWrite(""); + if(context.m_xmlOut) + +{ + context.m_xmlOut.Close(); +} + + context.Write(""); + context.m_htmlOut.Close(); + } + } + ); + + return documenter; +}; + +/* + * + * Entry Point + * +*/ + +print("Starting GMDoc..."); + +inFile = arg[0]; // directory/file listings of 'to be documented' files +outFile = arg[1]; // ouput help files + +documenter = CreateGMDocumenter(); + +dirsFile = system.File(); + +if(!dirsFile.Open(inFile, 1)) +{ + print("** Failed to open input file! **"); +} +else +{ + nextLine = dirsFile.ReadLine(); + + while(nextLine) + { + nextLine = nextLine.TrimRight(); // carriage return syndrome + + path = nextLine; + filename = nextLine.GetFilename(); + pos = filename.Find(".cpp",filename.Length() - 5); + + if(pos >= 0) // doc file + { + if(system.FileExists(path)) + { + documenter.AddFile(path); + } + } + else // doc directory + { + handle = system.FileFindFirst(path ^ `\*.*`); + while(handle) + { + extension = handle.filename.GetExtension().Lower(); + print(extension); + if(extension == `cpp` or extension == `gm`) + { + if(system.FileExists(path ^ handle.filename)) + { + documenter.AddFile(path ^ handle.filename); + } + } + handle = system.FileFindNext(handle); + } + } + + nextLine = dirsFile.ReadLine(); // read next line + } +} + +dirsFile.Close(); + +documenter.CreateDocumentation(outFile); + +print(`Done.`); + + + diff --git a/vscript/languages/gm/scripts/gmDoc/gmdoc.html b/vscript/languages/gm/scripts/gmDoc/gmdoc.html new file mode 100644 index 00000000..a23259de --- /dev/null +++ b/vscript/languages/gm/scripts/gmDoc/gmdoc.html @@ -0,0 +1,308 @@ +GM Documentation

+

gm

+

+
+

array

+
Brief: array will create a fixed size array object
Param: int size optional (0)
Return: array


+

array

+

+
+

Size

+
Brief: Size will return the current size of the fixed array
Return: int array size

+

Resize

+
Brief: Resize will resize the array to a new size
Param: int size optional (0)
Return: null

+

Shift

+
Brief: Shift will shift slide the array elements by a delta, nulls are shifted in
Param: int delta
Return: null

+

Move

+
Brief: Move will perform a non destructive move on the array
Param: int dst
Param: int src
Param: int size
Return: null


+

math

+

+
+

abs

+
Brief: abs will return the absolute value of the passed int \ float
Param: int\float
Return: int\float abs(param)

+

sqrt

+
Brief: sqrt will return the square root of the passed int \ float
Param: int\float
Return: int\float sqrt(param)

+

sqrt

+
Brief: sqrt will return the square root of the passed int \ float
Param: int\float A
Param: int\float B
Return: int\float A to the power of B

+

floor

+
Brief: floor
Param: float A
Return: float floor(A)

+

ceil

+
Brief: ceil
Param: float A
Return: float ceil(A)

+

round

+
Brief: round
Param: float A
Return: float round(A)

+

degtorad

+
Brief: degtorad will convert degrees to radians
Param: float\int deg
Return: float

+

radtodeg

+
Brief: radtodeg will convert radians to degrees
Param: float\int rad
Return: float

+

cos

+
Brief: cos will return the radian cosine
Param: float
Return: float

+

sin

+
Brief: sin will return the radian sine
Param: float
Return: float

+

tan

+
Brief: tan will return the radian tan (sin/cos)
Param: float
Return: float

+

acos

+
Brief: acos will return the radian arc cosine
Param: float
Return: float

+

asin

+
Brief: asin will return the radian arc sine
Param: float
Return: float

+

atan

+
Brief: atan will return the radian arc tangent
Param: float
Return: float

+

atan

+
Brief: atan will return the radian arc tangent of x / y
Param: float x
Param: float y
Return: float

+

log

+
Brief: log will return the natural logarithm of 1 parameter, or (base, value) the logarithm to base
Param: float natural \ base
Param: float value (optional)
Return: float

+

min

+
Brief: min will return the min of the 2 passed values
Param: float\int A
Param: float\int B
Return: float \ int min(A, B)

+

max

+
Brief: max will return the max of the 2 passed values
Param: float\int A
Param: float\int B
Return: float \ int max(A, B)

+

clamp

+
Brief: clamp will return the clamed value. clamp(min, val, max)
Param: float\int MIN
Param: float\int VALUE
Param: float\int MAX
Return: float\int value clamped to min, max

+

randint

+
Brief: randint will return a random int from lower inclusive to upper.
Param: int lower inclusive
Param: int upper
Return: int

+

randfloat

+
Brief: randfloat will return a random float from lower inclusive to upper.
Param: float lower inclusive
Param: float upper
Return: float

+

randseed

+
Brief: randseed will seed the random number generator
Param: int seed


+

string

+

+Brief: string operations often store a copy of the string on the stack, so keep string sizes reasonable

+

IsEmpty

+
Brief: IsEmpty will test to see if the string is 0 length
Return: non-zero if the string is empty

+

Length

+
Brief: Length will return the length of the string not including the null terminating character
Return: int length

+

Left

+
Brief: Left will return the left count charaters of the string
Param: int count
Return: string

+

Right

+
Brief: Right will return the right count charaters of the string
Param: int count
Return: string

+

RightAt

+
Brief: RightAt will return the charaters right of and including the given index
Param: int index
Return: string

+

Mid

+
Brief: Mid will return count characters from the start index
Param: int startIndex
Param: int count
Return: string

+

Compare

+
Brief: Compare will perform a string compare
Param: string to compare
Return: -1 if the this < compare string, 0 if the strings are equal, 1 otherwise

+

CompareNoCase

+
Brief: CompareNoCase will perform a string compare (case insensitive)
Param: string to compare
Return: -1 if the this < compare string, 0 if the strings are equal, 1 otherwise

+

Int

+
Brief: Int will return the int value of the string
Return: int value

+

Float

+
Brief: Float will return the float value of the string
Return: float value

+

String

+
Return: string

+

Upper

+
Brief: Upper will return the string as uppercase
Return: string

+

Lower

+
Brief: Lower will return the string as lowercase
Return: string

+

SpanIncluding

+
Brief: SpanIncluding will return this string while characters are within the passed string
Param: string charset
Return: string

+

SpanExcluding

+
Brief: SpanExcluding will return this string while characters are not within the passed string
Param: string charset
Return: string

+

AppendPath

+
Brief: AppendPath will append a path make sure one '\' is maintained
Param: string path to append
Return: string

+

ReplaceCharsInSet

+
Brief: ReplaceCharsInSet will replace all chars in this that are within the charset with the given int char
Param: int char to replace with
Param: string charset of chars to replace
Return: string

+

Find

+
Brief: Find will find the first occurance of the passed string within this string
Param: string search string
Param: int start index optional (0)
Return: int index of first occurance, or -1 if the string was not found

+

Reverse

+
Brief: Reverse characters of a string
Return: string

+

ReverseFind

+
Brief: ReverseFind will find the first occurance of the passed string within this string starting from the right
Param: string search string
Return: int index of first occurance, or -1 if the string was not found

+

GetAt

+
Brief: GetAt will return the char at the given index
Param: int index
Return: int char, or null if index was out of range

+

SetAt

+
Brief: SetAt will return the string with the character set at the given position
Param: int index
Param: int char
Return: string

+

TrimLeft

+
Brief: TrimLeft will return the string with the chars from the passed char set trimmed from the left
Param: string charset optional (" \r\n\v\t")
Return: string

+

TrimRight

+
Brief: TrimRight will return the string with the chars from the passed char set trimmed from the right
Param: string charset optional (" \r\n\v\t")
Return: string

+

GetFilenameNoExt

+
Brief: GetFilenameNoExt will return the filename part of a path string
Return: string

+

GetFilename

+
Brief: GetFilename will return the filename part of a path string incl. extension
Return: string

+

GetExtension

+
Brief: GetExtension will return the file extension
Param: int inclDot optional (0) 1 will include '.', 0 won't
Return: string

+

SetExtension

+
Brief: SetExtension returns a string with the extension change to the given one.
Param: string ext optional (null) the new extension, with or without the dot. null to remove extension.
Return: string

+

GetPath

+
Brief: GetPath will return the file path from a path string
Param: int inclSlash optional (0) will include a '\' on the end of the path
Return: string


+

system

+

+Brief: system functions are bound in a "system" table.

+

Exec

+
Brief: Exec will execute a system command
Param: string params will be concatinated together with a single space to form the final system command string
Return: integer value returned from system exec call, -1 on error

+

DoFile

+
Brief: DoFile will execute the gm script in the named file
Param: string filename
Param: int optional (1) as 1 will execute string before returning, 0 will execute later.
Param: ref optional (null) set 'this'
Return: thread id of new thread created to execute file

+

File

+
Brief: File will create a file object
Return: file object

+

FileExists

+
Brief: FileExists will test to see if a file exists
Param: string filename
Return: 1 if the file exists, otherwise 0

+

FileFindFirst

+
Brief: FileFindFirst will start a file search will test to see if a file exists
Param: string filesearch (may contain wildcards, eg, `c:\temp\*.txt`)
Return: fileFind object. fileFind object has .filename and .size member
See Also: fileFind

+

FileFindNext

+
Brief: FileFindNext will get the next file matching the file find
Param: fileFind object returned by FileFindFirst call or FileFindNext call
Return: fileFind object
See Also: fileFind

+

FileInfo

+
Brief: FileInfo will return a file info object that has readonly members for .creationDate
Param: string path
Return: fileInfo object, fileInfo object has a .creationTime, .accessedTime, .modifiedTime and a .size

+

CreateFolder

+
Brief: CreateFolder will create a file path if it does not already exist
Param: string path
Return: int 0 on failure, 1 on successful create, 2 if folder already exists

+

DeleteFolder

+
Brief: DeleteFolder will remove a file path
Param: string path
Param: int remove subfiles and folders optional (0)
Return: int 1 on success, 0 con failure

+

Time

+
Brief: Time will return a unix style time_t as an int
Return: the current time

+

FormatTime

+
Brief: FormatTime will take a int (time_t) value and format according to the passed format string.
Param: int time (-1) is a (time_t) to be converted to a string, passing -1 gets current time
Param: string format ("%A %d %B %Y, %I:%M:%S %p") is the format string to use.
%a : Abbreviated weekday name
%A : Full weekday name
%b : Abbreviated month name
%B : Full month name
%c : Date and time representation appropriate for locale
%d : Day of month as decimal number (01 – 31)
%H : Hour in 24-hour format (00 – 23)
%I : Hour in 12-hour format (01 – 12)
%j : Day of year as decimal number (001 – 366)
%m : Month as decimal number (01 – 12)
%M : Minute as decimal number (00 – 59)
%p : Current locale’s A.M./P.M. indicator for 12-hour clock
%S : Second as decimal number (00 – 59)
%U : Week of year as decimal number, with Sunday as first day of week (00 – 53)
%w : Weekday as decimal number (0 – 6; Sunday is 0)
%W : Week of year as decimal number, with Monday as first day of week (00 – 53)
%x : Date representation for current locale
%X : Time representation for current locale
%y : Year without century, as decimal number (00 – 99)
%Y : Year with century, as decimal number
%z, %Z : Time-zone name or abbreviation; no characters if time zone is unknown
%% : Percent sign

Return: the time as a string.


+

fileFind

+

+Brief: fileFind object has a "filename" and "size" member

+

GetAttribute

+
Brief: GetAttribute will test a file attribute.
Param: int char attribute 'r' readonly, 'a' archive, 's' system, 'h' hidden, 'c' compressed, 'd' directory
Return: 1 if the attribute is set, 0 otherwise


+

file

+

+
+

Open

+
Brief: Open will open a file in binary mode
Param: string filename
Param: int readonly optional (1)
Return: 1 if the open was successful, 0 otherwise

+

OpenText

+
Brief: OpenText will open a file in text mode
Param: string filename
Param: int readonly optional (1)
Return: 1 if the open was successful, 0 otherwise

+

Close

+
Brief: Close will close a file

+

IsOpen

+
Brief: IsOpen will test to see if a file is open
Return: 1 if the file is open, 0 otherwise

+

Seek

+
Brief: Move to position within file
Param: int offset positional offset relative to origin
Param: int origin eg. myFile.SEEK_CUR, myFile.SEEK_END, myFile.SEEK_SET for current, end, start origins.
Return: int 1 if operation succeeded, 0 if failed.

+

Tell

+
Brief: Tell will return the current cursor position of the file
Return: int the current cursor position, -1 on error

+

ReadLine

+
Brief: ReadLine will read a line of text from the file.
Param: int keep optional (0) as 1 will keep the "\n" char on the line, otherwise it is removed
Return: string, or null on eof

+

ReadChar

+
Brief: ReadChar will read a char from the file
Return: int char or null on eof

+

WriteString

+
Brief: WriteString will write a string to the file
Param: string to write to file
Return: 1 on success, null on error

+

WriteChar

+
Brief: WriteChar will write a char to the file
Param: int char to write to file
Return: 1 on success, null on error


+

Vector3

+

+
+

Vector3

+
Brief: Create a Vector3 object
Param: float x or [0] optional (0)
Param: float y or [1] optional (0)
Param: float z or [2] optional (0)


+

Vector3

+

+Brief: Vector3 math class

+

DominantAxis

+
Brief: Find the index of the largest vector component.
This: Vector to evaluate.
Return: int Index of largest component.

+

Dot

+
Brief: Calculate the Dot (or Inner) Product of two vectors.
This: Vector3 First vector.
Param: Vector3 Second vector.
Return: float result.

+

Length

+
Brief: Length will return the length of the vector.
Return: float Dot product result that is cosine of the angle between the two vectors.

+

Cross

+
Brief: Calculate the Cross (or Outer) Product of two vectors.
This: Vector3 First vector.
Param: Vector3 Second vector.
Return: Vector3 Cross product resultant vector that is perpendicular to the two input vectors and length sine of the angle between them.

+

Normalize

+
Brief: Return a unit length copy of this vector.
This: Vector to be copied.
Return: Vector3 Unit length copy of this vector.

+

LengthSquared

+
Brief: Return the squared length of the vector.
Return: float Squared length of the vector.

+

ProjectFrom

+
Brief: Project a direction from a point.
This: Vector3 Direction.
Param: Vector3 Start point;
Param: float Distance or time.
Return: Vector3 Projected result.

+

Clone

+
Brief: Return a copy of this vector.
Return: A copy of this vector.

+

Set

+
Brief: Set vector from other vector or 3 components.

+

LerpToPoint

+
Brief: Linear interpolate between two 'point' vectors.
This: Vector3 From vector.
Param: Vector3 To vector.
Param: float Fraction or time between 0 and 1.
Return: Vector3 Resulting inbetween vector.

+

SlerpToVector

+
Brief: Spherical linear interpolate between two vectors.
This: Vector3 From vector.
Param: Vector3 To vector.
Param: float Fraction or time between 0 and 1.
Return: Vector3 Resulting inbetween vector.

+

RotateAxisAngle

+
Brief: Rotate around Axis by Angle.
This: Vector3 Vector to rotate.
Param: Vector3 Unit length axis of rotation.
Param: float Angle amount to rotate.
Return: Vector3 Resulting rotated vector.

+

RotateX

+
Brief: Rotate around X Axis by Angle.
This: Vector3 Vector to rotate.
Param: float Angle amount to rotate.
Return: Vector3 Resulting rotated vector.

+

RotateX

+
Brief: Rotate around Y Axis by Angle.
This: Vector3 Vector to rotate.
Param: float Angle amount to rotate.
Return: Vector3 Resulting rotated vector.

+

RotateZ

+
Brief: Rotate around Z Axis by Angle.
This: Vector3 Vector to rotate.
Param: float Angle amount to rotate.
Return: Vector3 Resulting rotated vector.

+

SetAdd

+
Brief: Add two vectors, store result in this. Demonstrate relative efficiency compared to operator version.
This: Vector3 Result vector.
Param: Vector3 First vector.
Param: Vector3 Second vector.

+

Add

+
Brief: Add vector to this. Demonstrate relative efficiency compared to operator version.
This: Vector3 Result vector.
Param: Vector3 vector to add.


+

gm

+

+Brief: functions in the gm lib are all global scope

+

debug

+
Brief: debug will cause a the debugger to break at this point while running.


+

gm

+

+Brief: functions in the gm lib are all global scope

+

gmVersion

+
Brief: gmVersion will return the gmMachine version string. version string is major type . minor type as a string and was added at version 1.1
Return: string

+

typeId

+
Brief: typeId will return the type id of the passed var
Param: var
Return: integer type

+

typeName

+
Brief: typeName will return the type name of the passed var
Param: var
Return: string

+

typeRegisterOperator

+
Brief: typeRegisterOperator will register an operator for a type
Param: int typeid
Param: string operator name is one of "getdot", "setdot", "getind", "setind", "add", "sub", "mul", "div", "mod", "inc", "dec", "bitor", "bitxor", "bitand", "shiftleft", "shiftright", "bitinv", "lt", "gt", "lte", "gte", "eq", "neq", "neg", "pos", "not"
Param: function
Return: 1 on success, otherwise 0

+

typeRegisterVariable

+
Brief: typeRegisterVariable will register a variable with a type such that (type).varname will return the variable
Param: int typeid
Param: string var name
Param: var
Return: 1 on success, otherwise 0

+

sysCollectGarbage

+
Brief: sysCollectGarbage will run the garbage collector iff the current mem used is over the desired mem used
Param: forceFullCollect (false) Optionally perform full garbage collection immediately if garbage collection is not disabled.
Return: 1 if the gc was run, 0 otherwise

+

sysGetMemoryUsage

+
Brief: sysGetMemoryUsage will return the current memory used in bytes
Return: int memory usage

+

sysSetDesiredMemoryUsageHard

+
Brief: sysSetDesiredMemoryUsageHard will set the desired memory useage in bytes. when this is exceeded the garbage collector will be run.
Param: int desired mem usage in bytes

+

sysSetDesiredMemoryUsageSoft

+
Brief: sysSetDesiredMemoryUsageSoft will set the desired memory useage in bytes. when this is exceeded the garbage collector will be run.
Param: int desired mem usage in bytes

+

sysGetDesiredMemoryUsageHard

+
Brief: sysGetDesiredMemoryUsageHard will get the desired memory useage in bytes. Note that this value is used to start garbage collection, it is not a strict limit.
Return: int Desired memory usage in bytes.

+

sysGetDesiredMemoryUsageSoft

+
Brief: sysGetDesiredMemoryUsageSoft will get the desired memory useage in bytes. Note that this value is used to start garbage collection, it is not a strict limit.
Return: int Desired memory usage in bytes.

+

sysSetDesiredMemoryUsageAuto

+
Brief: sysSetDesiredMemoryUsageAuto will enable auto adjustment of the memory limit(s) for subsequent garbage collections.
Param: int enable or disable flag

+

sysGetStatsGCNumFullCollects

+
Brief: sysGetStatsGCNumFullCollects Return the number of times full garbage collection has occured.
Return: int Number of times full collect has occured.

+

sysGetStatsGCNumIncCollects

+
Brief: sysGetStatsGCNumIncCollects Return the number of times incremental garbage collection has occured. This number may increase in twos as the GC has multiple phases which appear as restarts.
Return: int Number of times incremental collect has occured.

+

sysGetStatsGCNumWarnings

+
Brief: sysGetStatsGCNumWarnings Return the number of warnings because the GC or VM thought the GC was poorly configured. If this number is large and growing rapidly, the GC soft and hard limits need to be configured better. Do not be concerned if this number grows slowly.
Return: int Number of warnings garbage collect has generated.

+

sysIsGCRunning

+
Brief: Returns true if GC is running a cycle.

+

sysTime

+
Brief: sysTime will return the machine time in milli seconds
Return: int

+

doString

+
Brief: doString will execute the passed gm script
Param: string script
Param: int optional (1) set as true and the string will execute before returning to this thread
Param: ref optional (null) set 'this'
Return: int thread id of thread created for string execution

+

globals

+
Brief: globals will return the globals table
Return: table containing all global variables

+

threadTime

+
Brief: threadTime will return the thread execution time in milliseconds
Return: int

+

threadId

+
Brief: threadId will return the thread id of the current executing script
Return: int

+

threadAllIds

+
Brief: threadIds returns a table of thread Ids
Return: table of thread Ids

+

threadKill

+
Brief: threadKill will kill the thread with the given id
Param: int threadId optional (0) will kill this thread

+

threadKillAll

+
Brief: threadKillAll will kill all the threads except the current one
Param: bool optional (false) will kill this thread if true

+

thread

+
Brief: thread will start a new thread
Param: function entry point of the thread
Param: ... parameters to pass to the entry function
Return: int threadid

+

yield

+
Brief: yield will hand execution control to the next thread

+

exit

+
Brief: exit will kill this thread

+

assert

+
Brief: assert
Param: int expression if true, will do nothing, if false, will cause an exception

+

sleep

+
Brief: sleep will sleep this thread for the given number of seconds
Param: int\float seconds

+

signal

+
Brief: signal will signal the given variable, this will unblock dest threads that are blocked on the same variable.
Param: var
Param: int destThreadId optional (0) 0 will signal all threads

+

block

+
Brief: block will block on all passed vars, execution will halt until another thread signals one of the block variables. Will yield on null and return null.
Param: ... vars
Return: the unblocking var

+

stateSet

+
Brief: stateSet will collapse the stack to nothing, and push the passed functions.
Param: function new state function to execute
Param: ... params for new state function

+

stateSetOnThread

+
Brief: stateSetOnThread will collapse the stack of the given thread id to nothing, and push the passed functions.
Param: int thread id
Param: function new state function to execute
Param: ... params for new state function

+

stateGet

+
Brief: stateGet will return the function on the bottom of this threads execution stack iff it was pushed using stateSet
Param: a_threadId Optional Id of thread to get state on. \reutrn function \ null

+

stateGetLast

+
Brief: stateGetLast will return the last state function of this thread
Param: a_threadId Optional Id of thread to get last state on. \reutrn function \ null

+

stateSetExitFunction

+
Brief: stateSetExitFunction will set an exit function for this state, that will be called with no parameters if this thread switches state
Param: function

+

tableCount

+
Brief: tableCount will return the number of elements in a table object
Param: table
Return: int

+

tableDuplicate

+
Brief: tableDuplicate will duplicate the passed table object
Param: table
Return: table

+

print

+
Brief: print will print the given vars to the print handler. passed strings are concatinated together with a seperating space.
Param: ... strings

+

format

+
Brief: format (like sprintf, but returns a string) %d, %s, %f, %c, %b, %x, %e
Param: string
\ No newline at end of file diff --git a/vscript/languages/gm/scripts/gmDoc/gmdoc.txt b/vscript/languages/gm/scripts/gmDoc/gmdoc.txt new file mode 100644 index 00000000..0b4ffac9 --- /dev/null +++ b/vscript/languages/gm/scripts/gmDoc/gmdoc.txt @@ -0,0 +1,2 @@ +..\..\src\binds +..\..\src\gm \ No newline at end of file diff --git a/vscript/languages/gm/scripts/gmDoc/gmdoc.xml b/vscript/languages/gm/scripts/gmDoc/gmdoc.xml new file mode 100644 index 00000000..b241485a --- /dev/null +++ b/vscript/languages/gm/scripts/gmDoc/gmdoc.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/vscript/languages/gm/scripts/minesweeper.gm b/vscript/languages/gm/scripts/minesweeper.gm new file mode 100644 index 00000000..b792d1ae --- /dev/null +++ b/vscript/languages/gm/scripts/minesweeper.gm @@ -0,0 +1,608 @@ +// +// MineSweeper By Andriy Doroshchuk +// + +global cursorOverClosed = CA.F_RED | CA.F_INTENSITY | CA.B_BLACK | CA.TRAILING_BYTE; +global cursorOverOpened = CA.F_RED | CA.F_INTENSITY | CA.B_BLUE | CA.TRAILING_BYTE; +global frameColor = CA.F_RED | CA.F_GREEN | CA.F_BLUE | CA.B_BLACK | CA.TRAILING_BYTE; +global closedColor = CA.F_BLUE | CA.B_BLACK | CA.TRAILING_BYTE; +global openedColor = CA.F_BLUE | CA.B_BLUE | CA.TRAILING_BYTE; +global numberColor = CA.F_BLUE | CA.F_GREEN| CA.F_INTENSITY | CA.B_BLUE | CA.TRAILING_BYTE; +global markColor = CA.F_BLUE | CA.F_RED | CA.F_INTENSITY | CA.B_BLUE | CA.TRAILING_BYTE; +global mineColor = CA.F_GREEN| CA.F_RED | CA.B_BLUE | CA.TRAILING_BYTE; +global helpColor = CA.F_GREEN| CA.F_RED | CA.F_BLUE |CA.B_BLUE | CA.TRAILING_BYTE; +global winColor = CA.F_GREEN| CA.F_INTENSITY | CA.B_BLACK | CA.TRAILING_BYTE; +global looseColor = CA.F_RED | CA.F_INTENSITY | CA.B_BLACK | CA.TRAILING_BYTE; + +// wait till key will be released +global WaitForKey = function(key) +{ + for (;ISPRESSED(key);){} +}; + +// print debug message +global DebugText = function(text) +{ + CATTRIB(frameColor); + XYTEXT(0, 0, text); +}; + + +game = table( + x = 15, + y = 0, + lx = 30, + ly = 15, + mineCurr = 0, + mineMax = 10, + currLevel = 2, + cX = 0, + cY = 0, + + field = table(), + + // index in the field + Index = function(x, y) + { + return (y*.lx+x); + }, + + // draw field frame + DrawFrame = function() + { + i; + + // set color + CATTRIB(frameColor); + + // borders + for (i=.x+1; i<.x+.lx+1; i=i+1) + { + XYTEXT(i, .y, "-"); + XYTEXT(i, .y+.ly+1, "-"); + } + for (i=.y+1; i<.y+.ly+1; i=i+1) + { + XYTEXT(.x, i, "|"); + XYTEXT(.x+.lx+1, i, "|"); + } + + // corners + XYTEXT(.x, .y, "\1"); + XYTEXT(.x+.lx+1, .y, "\1"); + XYTEXT(.x, .y+.ly+1, "\1"); + XYTEXT(.x+.lx+1, .y+.ly+1, "\1"); + + // count + XYTEXT(.x+3, .y, "[" + .mineCurr.String() + ":" + .mineMax.String() + "]"); + }, + + // field cell drawing + DrawCell = function(x, y, cursor) + { + index = .Index(x, y); + // debug cell = .field[index].String(); + cell = " "; + + // closed cell + if (.field[index] < 10) + { + if (cursor) + { + CATTRIB(cursorOverClosed); + cell = "W"; + } + else + { + CATTRIB(closedColor); + } + } + // opened cell + else if (.field[index] < 20) + { + if (.field[index] == 10) + { + if (cursor) + { + CATTRIB(cursorOverOpened); + cell = "W"; + } + else + { + CATTRIB(openedColor); + } + } + else if (.field[index] < 19) + { + if (cursor) + { + CATTRIB(cursorOverOpened); + } + else + { + CATTRIB(numberColor); + } + val = .field[index] % 10; + cell = val.String(); + } + else + { + CATTRIB(mineColor); + cell = "@"; + } + } + // intended mine + else + { + if (cursor) + { + CATTRIB(cursorOverOpened); + } + else + { + CATTRIB(markColor); + } + cell = "?"; + } + + XYTEXT(.x+x+1, .y+y+1, cell); + }, + + // field cell drawing + DrawCurrCell = function(cursor) + { + .DrawCell(.cX, .cY, cursor); + }, + + // field drawing + DrawField = function() + { + i; j; + + .DrawFrame(); + for (i=0; i<.lx; i=i+1) + { + for (j=0; j<.ly; j=j+1) + { + .DrawCell(i, j, 0); + } + } + }, + + // help string + HelpString = function(msg, line, mode) + { + if (mode == 1) + { + CATTRIB(CA.F_BLUE | CA.F_GREEN | CA.F_INTENSITY | CA.B_BLACK | CA.TRAILING_BYTE); + } + else if (mode == 2) + { + CATTRIB(CA.F_RED | CA.B_BLACK | CA.TRAILING_BYTE); + } + else + { + CATTRIB(CA.F_GREEN | CA.B_BLACK | CA.TRAILING_BYTE); + } + + + XYTEXT(0, 25-line, " "); + XYTEXT((80-msg.Length())/2, 25-line, msg); + }, + + // Initialise field + InitField = function(level) + { + i; j; + t1;t2; + count; position; index; + + // clear screen + CATTRIB(frameColor); + CLS(); + + // set current level + .currLevel = level; + + // field extents + if (level == 1) + { + .lx = 10; + .ly = 10; + .mineMax = 8; + } + else if (level == 2) + { + .lx = 18; + .ly = 15; + .mineMax = 35; + } + else + { + .lx = 30; + .ly = 15; + .mineMax = 90; + } + .x = (80-.lx)/2; + .mineCurr = 0; + + // init field contents + max = .lx*.ly; + for (i=0; i=0) && (t1<.lx) + && (t2>=0) && (t2<.ly)) + { + index = .Index(t1, t2); + if (.field[index] < 9) + { + .field[index] = .field[index] + 1; + } + } + } + } + } + } + } + + // draw field frame + .DrawFrame(); + + // set current cell + .cX=.lx/2; + .cY=.ly/2; + .DrawField(); + .DrawCell(.cX, .cY, 1); + + .HelpString("", 4, 0); + .HelpString("F2 - beginner. F3 - intermediate. F4 - expert", 2, 0); + .HelpString("Enter - open. Space - mark as a mine. Backspace - open around.", 1, 0); + }, + + // restart current game + RestartField = function() + { + .InitField(.currLevel); + }, + + // restart game after finishing + Restart = function(win) + { + .HelpString("", 2, 0); + .HelpString("", 1, 0); + + if (win) + { + .HelpString("Congratulations, you won! Press F1 to continue.", 4, 1); + for (; !ISPRESSED(112);){} + } + else + { + .HelpString("Sorry, you are dead! Press F1 to continue.", 4, 2); + .DrawField(); + } + for (; !ISPRESSED(112);){} + + .RestartField(); + }, + + // field opening when open an empty cell + CheckCell = function(x, y) + { + i; j; + index = .Index(x, y); + + if (.field[index] == 0) + { + .field[index] = 10; + + // check surrounding + for (i=x-1; i=0) && (i<.lx) + && (j>=0) && (j<.ly)) + { + .CheckCell(i, j); + } + } + } + } + else + { + if (.field[index] < 9) + { + .field[index] = .field[index] + 10; + } + } + + .DrawCell(x, y, 0); + }, + + // check win condition + CheckWin = function() + { + i; j; index; + count = 0; + for (i=0; i<.lx; i=i+1) + { + for (j=0; j<.ly; j=j+1) + { + index = .Index(i, j); + if (.field[index] < 10) + { + count = 0; + i = .lx; + j = .ly; + } + else if (.field[index] >= 20) + { + count = count + 1; + } + } + } + + if (count == .mineMax) + { + .DrawCell(.cX, .cY, 0); + .Restart(1); + } + else + { + .DrawCell(.cX, .cY, 1); + } + }, + + // open field cell + OpenCell = function(x, y, check) + { + i; j; + index = .Index(x, y); + if (!check) + { + if (.field[index] >= 20) + { + return; + } + } + + // check the field + if (check && (.field[index] % 10) == 9) + { + for (i=0; i<.lx; i=i+1) + { + for (j=0; j<.ly; j=j+1) + { + index = .Index(i, j); + .field[index] = (.field[index] % 10) + 10; + } + } + + .Restart(0); + } + else + { + .CheckCell(x, y); + .CheckWin(); + } + }, + + // open cells around open mine + HelperCell = function() + { + i; j; + index = .Index(.cX, .cY); + + // perform the action only if the cell is already open + if (.field[index]>=10 && .field[index]<20) + { + // calculate mines around this cell + mines = 0; + for (i=.cX-1; i<.cX+2; i=i+1) + { + for (j=.cY-1; j<.cY+2; j=j+1) + { + if ((i!=.cX || j!=.cY) + && (i>=0) && (i<.lx) + && (j>=0) && (j<.ly)) + { + index = .Index(i, j); + if (.field[index] >= 20) + { + mines = mines + 1; + } + } + } + } + + // check that we can open + index = .Index(.cX, .cY); + if (mines == (.field[index] % 10)) + { + for (i=.cX-1; i<.cX+2; i=i+1) + { + for (j=.cY-1; j<.cY+2; j=j+1) + { + if ((i!=.cX || j!=.cY) + && (i>=0) && (i<.lx) + && (j>=0) && (j<.ly)) + { + .OpenCell(i, j, 0); + } + } + } + } + } + }, + + // move cursor + Move = function(dir) + { + .DrawCurrCell(0); + if (dir == 1) + { + if (.cY > 0) + { + .cY = .cY - 1; + } + } + else if (dir == 3) + { + if (.cY<.ly-1) + { + .cY = .cY + 1; + } + } + else if (dir == 0) + { + if (.cX > 0) + { + .cX = .cX - 1; + } + } + else if (dir == 2) + { + if (.cX<.lx-1) + { + .cX = .cX + 1; + } + } + WaitForKey(37+dir); + .DrawCurrCell(1); + }, + + // open current cell + Open = function() + { + WaitForKey(13); + .OpenCell(.cX, .cY, 1); + }, + + // mark current cell + Mark = function() + { + WaitForKey(32); + index = .Index(.cX, .cY); + if (.field[index] < 10) + { + .field[index] = (.field[index] % 10) + 20; + .mineCurr = .mineCurr + 1; + .DrawFrame(); + .CheckWin(); + } + else if (.field[index] >= 20) + { + .field[index] = .field[index] % 10; + .mineCurr = .mineCurr -1; + .DrawFrame(); + .DrawCurrCell(1); + } + }, + + // init the game + Run = function() + { + CURSOR(0, 0); + .RestartField(); + + for (;!ISPRESSED(27);) + { + if (ISPRESSED(37)) + { + .Move(0); + } + else if (ISPRESSED(38)) + { + .Move(1); + } + else if (ISPRESSED(39)) + { + .Move(2); + } + else if (ISPRESSED(40)) + { + .Move(3); + } + else if (ISPRESSED(32)) + { + .Mark(); + } + else if (ISPRESSED(13)) + { + .Open(); + } + else if (ISPRESSED(8)) + { + .HelperCell(); + WaitForKey(8); + } + else if (ISPRESSED(113)) + { + WaitForKey(113); + .InitField(1); + } + else if (ISPRESSED(114)) + { + WaitForKey(114); + .InitField(2); + } + else if (ISPRESSED(115)) + { + WaitForKey(115); + .InitField(3); + } + else + { + DebugText(" "); + } + } + } + +); + +game.Run(); + + diff --git a/vscript/languages/gm/scripts/snake.gm b/vscript/languages/gm/scripts/snake.gm new file mode 100644 index 00000000..e9392ccc --- /dev/null +++ b/vscript/languages/gm/scripts/snake.gm @@ -0,0 +1,696 @@ + +/* + + SNAKE + + by matty riek. + +*/ + +global showMemoryUsage = false; + +CURSOR(0,0); + +global g_sx = 80; +global g_sy = 24; +global g_border = + +"\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205" +"\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205" +"\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205\205"; + +global LocFromXY = function(a_x, a_y) { return a_y * g_sx + a_x; }; +global XFromLoc = function(a_loc) { return a_loc % g_sx; }; +global YFromLoc = function(a_loc) { return a_loc / g_sx; }; +global background = CA.B_BLUE; + +global fade0 = table( CA.F_RED|CA.F_BLUE|CA.F_GREEN | CA.F_INTENSITY | background, + CA.F_GREEN | CA.F_INTENSITY | CA.F_INTENSITY | background, + CA.F_BLUE | background, + CA.F_GREEN | CA.F_INTENSITY | background, + CA.F_RED|CA.F_GREEN | CA.F_INTENSITY | background, + CA.F_RED|CA.F_BLUE|CA.F_GREEN | CA.F_INTENSITY | background, + CA.F_BLUE | CA.F_INTENSITY | background, + CA.F_BLUE | CA.F_INTENSITY | background, + CA.F_RED|CA.F_BLUE|CA.F_GREEN | background, + CA.F_BLUE | background, + CA.F_BLUE | CA.F_INTENSITY | background, + CA.F_RED|CA.F_GREEN | CA.F_INTENSITY | background ); + +global fade1 = table( CA.F_RED|CA.F_BLUE|CA.F_GREEN | CA.F_INTENSITY | background, + CA.F_RED|CA.F_BLUE|CA.F_GREEN | CA.F_INTENSITY | background, + CA.F_RED|CA.F_BLUE|CA.F_GREEN | CA.F_INTENSITY | background, + CA.F_RED|CA.F_GREEN | CA.F_INTENSITY | background, + CA.F_RED | CA.F_INTENSITY | background, + CA.F_RED | background, + CA.F_RED | CA.F_INTENSITY | background, + CA.F_RED|CA.F_GREEN | CA.F_INTENSITY | background ); + +global fadeRed = table( CA.F_RED|CA.F_INTENSITY | background , CA.F_RED | background); + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// CreateGemType +// + +global CreateGemType = function(a_char, a_time, a_score, a_chance, a_length, a_cycle, a_pickup, a_mover) +{ + gem = table(m_char = a_char, m_time = a_time * 1000, m_score = a_score, m_chance = a_chance, m_length = a_length, m_cycle = a_cycle, m_mover = a_mover); + + gem.Pickup = function() + { + }; + + if(a_pickup) + { + gem.Pickup = a_pickup; + } + + gem.i = 0; + gem.Draw = function(x, y) + { + .i = .i + 1; + if(.i >= tableCount(.m_cycle)) + { + .i = 0; + } + CATTRIB(.m_cycle[.i]); + XYTEXT(x, y, .m_char); + CATTRIB(background | CA.F_GREEN | CA.F_INTENSITY); + }; + return gem; +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// DrawScreen +// +global DrawScreen = function() +{ + // + CATTRIB(background | CA.F_GREEN | CA.F_INTENSITY); + + // clear screen + CLS(); + + // draw border + XYTEXT(1, 0, g_border); + XYTEXT(1, g_sy - 1, g_border); + + ey = g_sy - 1; + for(i = 1; i < ey; i = i + 1) + { + XYTEXT(0, i, "\186"); + XYTEXT(g_sx - 1, i, "\186"); + } + XYTEXT(0, 0, "\201"); + XYTEXT(g_sx - 1, 0, "\187"); + XYTEXT(0, ey, "\200"); + XYTEXT(g_sx - 1, ey, "\188"); + +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// EmitGems +// +EmitGems = function(a_game) +{ + // add a gem + for(;;) + { + // choose a random sleep time + sleep( randfloat( + a_game.m_levels[a_game.m_level][1] / a_game.m_gameSpeed, + a_game.m_levels[a_game.m_level][2] / a_game.m_gameSpeed) + ); + + // pick a random location + x = randint(1, g_sx - 2); + y = randint(1, g_sy - 2); + loc = LocFromXY(x, y); + + // test if the location is on a existing gem or snake + if(a_game.m_gems[loc]) + { + continue; + } + onsnake = false; + foreach(snake in a_game.m_snakes) + { + if(snake.IsAt(loc)) + { + onsnake = true; + break; + } + } + if(onsnake) { continue; } + + // choose a gem + found = false; + while(!found) + { + foreach(gem in a_game.m_gemTypes) + { + if(randint(0, 100) < gem.m_chance) + { + found = true; + break; + } + } + } + + // add the gem + gemInstance = table(m_gem = gem, m_expire = sysTime() + (gem.m_time / a_game.m_gameSpeed)); + a_game.m_gems[loc] = gemInstance; + if(gem.m_mover) + { + gemInstance.m_dirX = randint(-1, 2); + gemInstance.m_dirY = randint(-1, 2); + } + + // draw the gem + gem.Draw(x, y); + } +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// ReclaimGems +// +ReclaimGems = function(a_game) +{ + // add a gem + for(;;) + { + time = sysTime(); + + foreach(key and gem in a_game.m_gems) + { + if(time > gem.m_expire) + { + // remove from screen + XYTEXT(XFromLoc(key), YFromLoc(key), " "); + a_game.m_gems[key] = null; + b = true; + break; + } + } + + yield(); + } +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// DrawGems +// +DrawGems = function(a_game) +{ + for(;;) + { + foreach(key and gem in a_game.m_gems) + { + x = XFromLoc(key); + y = YFromLoc(key); + gem.m_gem.Draw(x, y); + } + sleep(1 / 30.); + } +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Move mover gems +// +MoveMovers = function(a_game) +{ + for(;;) + { + movers = table(); + foreach(key and gem in a_game.m_gems) + { + if(gem.m_gem.m_mover) + { + x = XFromLoc(key); + y = YFromLoc(key); + + XYTEXT(x, y, " "); + + x = x + gem.m_dirX; + y = y + gem.m_dirY; + + if(x <= 1 or x >= g_sx - 2) { gem.m_dirX = -gem.m_dirX; } + if(y <= 1 or y >= g_sy - 2) { gem.m_dirY = -gem.m_dirY; } + gem.m_newLoc = LocFromXY(x, y); + movers[key] = gem; + } + } + + foreach(key and gem in movers) + { + a_game.m_gems[key] = null; + a_game.m_gems[gem.m_newLoc] = gem; + } + sleep(1 / 4.); + } +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Snake +// +Snake = function(a_id, a_name, a_score, a_scoreX, a_scoreY, a_headChar, a_tailChar, a_startX, a_startY, a_startDir, a_keys) +{ + snake = table( + m_id = a_id, + m_grow = 2, + m_credits = 3, + m_startX = a_startX, + m_startY = a_startY, + m_startDir = a_startDir, + m_name = a_name, + m_score = a_score, + m_scoreX = a_scoreX, + m_scoreY = a_scoreY, + m_body = array(50), + m_length = 0, + m_dir = a_startDir, // 0 right, 1 up, 2 left, 3 down + m_head = table( + m_headChar = a_headChar, + m_tailChar = a_tailChar, + m_x = a_startX, + m_y = a_startY + ), + m_keys = a_keys + ); + + /////////////////////////////////////////////////////////////////////////////////////////////////// + // + // Die + // + snake.Die = function() // return true if snake has no credits + { + // flash a death thinggy + + i = 10; + while(i) + { + if(i & 1) { + XYTEXT(.m_scoreX, .m_scoreY, format(" *** FATALITY *** ", .m_name)); + } + else { + XYTEXT(.m_scoreX, .m_scoreY, format(" ", .m_name)); + } + sleep(0.2f); + i = i - 1; + } + + .UpdateScore(); + + // clear the snake + for(i = 0; i < .m_length; i = i + 1) + { + loc = .m_body[i]; + x = XFromLoc(loc); + y = YFromLoc(loc); + XYTEXT(x, y, " "); + } + XYTEXT(.m_head.m_x, .m_head.m_y, " "); + + // update the credits + .m_credits = .m_credits - 1; + if(.m_credits) + { + .m_head.m_x = .m_startX; + .m_head.m_y = .m_startY; + .m_dir = .m_startDir; + .m_grow = 2; + .m_length = 0; + return false; + } + return true; + }; + + /////////////////////////////////////////////////////////////////////////////////////////////////// + // + // UpdateScore + // + snake.UpdateScore = function() + { + XYTEXT(.m_scoreX, .m_scoreY, format(" %d UP %s SCORE %d ", .m_credits, .m_name, .m_score)); + }; + + /////////////////////////////////////////////////////////////////////////////////////////////////// + // + // Draw + // + snake.Draw = function(a_oldX, a_oldY) + { + // clear the tail. + if(.m_length > 0 and .grow == null) + { + loc = .m_body[.m_length - 1]; + y = YFromLoc(loc); + x = XFromLoc(loc); + XYTEXT(x, y, " "); + } + + // grow the snake + if(.grow) + { + .m_length = .m_length + 1; + if(.m_length >= .m_body.Size()) + { + .m_body.Resize(.m_body.Size() * 2); + } + .grow = false; + } + + // move the body along. + for(i = .m_length - 1; i > 0; i = i - 1) + { + .m_body[i] = .m_body[i - 1]; + } + + // put the new tail piece in + if(.m_length) + { + .m_body[0] = LocFromXY(a_oldX, a_oldY); + XYTEXT(a_oldX, a_oldY, .m_head.m_tailChar); + } + else + { + XYTEXT(a_oldX, a_oldY, " "); + } + + // draw the new head + XYTEXT(.m_head.m_x, .m_head.m_y, .m_head.m_headChar); + }; + + /////////////////////////////////////////////////////////////////////////////////////////////////// + // + // IsAt + // + snake.IsAt = function(a_loc) + { + for(i = 0; i < .m_length; i = i + 1) + { + if(a_loc == .m_body[i]) + { + return true; + } + } + if(a_loc == LocFromXY(.m_head.m_x, .m_head.m_y)) + { + return true; + } + return false; + }; + + /////////////////////////////////////////////////////////////////////////////////////////////////// + // + // Update + // + snake.Update = function(a_game) + { + member UpdateScore; + + UpdateScore(); + for(;;) + { + wait = 1.0f / (a_game.m_snakeMoveRate * a_game.m_gameSpeed); + sleep(wait); + + x = .m_head.m_x; + y = .m_head.m_y; + + if(.m_dir == 0) { x = x + 1; } + else if(.m_dir == 1) { y = y - 1; } + else if(.m_dir == 2) { x = x - 1; } + else if(.m_dir == 3) { y = y + 1; } + + // did we collect a gem? + loc = LocFromXY(x, y); + gem = a_game.m_gems[loc]; + if(gem) + { + // update score + .m_score = .m_score + gem.m_gem.m_score; + .m_grow = gem.m_gem.m_length; + pickup = gem.m_gem.Pickup; + this:pickup(); + UpdateScore(); + + // remove the gem + a_game.m_gems[loc] = null; + } + + // did we run into a wall?? + dead = false; + if(x <= 0 or x >= g_sx - 1 or y <= 0 or y >= g_sy - 1) + { + dead = true; + } + + // did we run into ourselves? + if(!dead and .IsAt(loc)) + { + dead = true; + } + + // update position + oldX = .m_head.m_x; + oldY = .m_head.m_y; + .m_head.m_x = x; + .m_head.m_y = y; + + // did we run into another snake + if(!dead) + { + foreach(snake in a_game.m_snakes) + { + if(snake != this and snake.IsAt(loc)) + { + dead = true; + break; + } + } + } + + // did we die? + if(dead) + { + .m_head.m_x = oldX; + .m_head.m_y = oldY; + die = .Die(); + .UpdateScore(); + if(die) + { + a_game.m_snakes[.m_id] = null; + threadKill(.kht); + exit(); + } + } + .Draw(oldX, oldY); + + if(.m_grow) + { + .grow = true; + .m_grow = .m_grow - 1; + } + } + }; + + /////////////////////////////////////////////////////////////////////////////////////////////////// + // + // KeyHandler + // + snake.KeyHandler = function(a_game) + { + wait = 1.0f / a_game.m_keyUpdateRate; + for(;;) + { + for(i = 0; i < 4; i = i + 1) + { + if(ISPRESSED(.m_keys[i])) + { + .m_dir = i; + break; + } + } + sleep(wait); + } + }; + + return snake; +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Game +// +g_game = table( + + // goodies + m_gems = table(), + + m_levels = table( + + // level is speed, lower spawn time, upper spawn time, next level score + table(1.0f, 10, 20, 500), + table(2.0f, 8, 18, 1500), + table(2.5f, 5, 16, 2700), + table(3.0f, 4, 13, 3800), + table(3.5f, 3, 10, 5000) + ), + + m_gemTypes = table( + + CreateGemType("\4", 22, 50, 40, 3, fade0), // standard 1 + CreateGemType("\5", 17, 100, 30, 4, fade0), // standard 2 + CreateGemType("\6", 15, 200, 20, 5, fade1), // standard 3 + CreateGemType("\3", 30, 20, 15, 0, fadeRed, function() { .m_credits = .m_credits + 1; }, true), // 1up + CreateGemType("\15", 45, 0, 15, 50, fade1) // bomb + ), + + // snakes + m_snakes = table( + Snake(0, "lefty", 0, 8, 23, "\1", "\176", 1, 12, 0, table('D', 'W', 'A', 'S')), + Snake(1, "righty", 0, 50, 23, "\2", "\177", 78, 12, 2, table('L', 'I', 'J', 'K')) + ), + + // game + m_level = 0, + m_over = false, + m_totalScore = 0, + + // timing + m_speedup = 2.0f, // overall speed multiplier + m_gameSpeed = 1.0f, // current game speed + m_keyUpdateRate = 30.0f, // times per second + m_snakeMoveRate = 4.0f // times per second +); + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Main +// +ScoreMonitor = function() +{ + .m_gameSpeed = .m_speedup * .m_levels[.m_level][0]; + + for(;;) + { + // update scores and levels. + .m_totalScore = 0; + foreach(snake in .m_snakes) + { + .m_totalScore = .m_totalScore + snake.m_score; + } + + // are they at the next level + if(.m_totalScore >= .m_levels[.m_level][3]) + { + // level up.... have we finished + .m_level = .m_level + 1; + if(.m_level >= tableCount(.m_levels)) + { + // you win.... + XYTEXT(0,0,"YOUWIN"); + sleep(5); + .gameover = true; + } + else + { + // next level + .m_gameSpeed = .m_speedup * .m_levels[.m_level][0]; + } + } + + XYTEXT(8, 0, format("LEVEL %d, SCORE %d, NEXT LEVEL TARGET %d", .m_level, .m_totalScore, .m_levels[.m_level][3])); + if(showMemoryUsage) + { + XYTEXT(8, 1, format("mem %d Desired H: %d S: %d F: %d I: %d W: %d", + sysGetMemoryUsage(), + sysGetDesiredMemoryUsageHard(), + sysGetDesiredMemoryUsageSoft(), + sysGetStatsGCNumFullCollects(), + sysGetStatsGCNumIncCollects(), + sysGetStatsGCNumWarnings() )); + } + sleep(0.1); + } +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Title Screen +// + +// todo + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Main +// + +DrawScreen(); + +// start the snakes +foreach(snake in g_game.m_snakes) +{ + snake.kht = snake:thread(snake.KeyHandler, g_game); + snake.ut = snake:thread(snake.Update, g_game); +} + +// start the gems +egt = thread(EmitGems, g_game); +rgt = thread(ReclaimGems, g_game); +dgt = thread(DrawGems, g_game); +mmt = thread(MoveMovers, g_game); +smt = g_game:thread(ScoreMonitor); + +for(;;) +{ + // test for escape key + if(g_game.gameover or ISPRESSED(27)) + { + // kill threads + threadKill(egt); + threadKill(rgt); + threadKill(dgt); + threadKill(smt); + threadKill(mmt); + + foreach(snake in g_game.m_snakes) + { + threadKill(snake.kht); + threadKill(snake.ut); + } + exit(); + } + yield(); +} + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/gm/src/binds/gmArrayLib.cpp b/vscript/languages/gm/src/binds/gmArrayLib.cpp new file mode 100644 index 00000000..3eedf1ec --- /dev/null +++ b/vscript/languages/gm/src/binds/gmArrayLib.cpp @@ -0,0 +1,413 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmArrayLib.h" +#include "gmThread.h" +#include "gmMachine.h" +#include "gmHelpers.h" + +// Must be last header +#include "memdbgon.h" + +// +// +// Implementation of array binding +// +// + +#if GM_ARRAY_LIB + +// Statics and globals +gmType GM_ARRAY = GM_NULL; +gmVariable gmUserArray::m_null; + + +bool gmUserArray::Construct(gmMachine * a_machine, int a_size) +{ + m_null.Nullify(); + m_array = NULL; + m_size = 0; + return Resize(a_machine, a_size); +} + + +void gmUserArray::Destruct(gmMachine * a_machine) +{ + if(m_array) + { + a_machine->Sys_Free(m_array); + m_array = NULL; + } + m_size = 0; +} + + +bool gmUserArray::Resize(gmMachine * a_machine, int a_size) +{ + if(a_size < 0) a_size = 0; + int copysize = (a_size > m_size) ? m_size : a_size; + gmVariable * array = (gmVariable *) a_machine->Sys_Alloc(sizeof(gmVariable) * a_size); + // copy contents. + if(m_array) + { + memcpy(array, m_array, sizeof(gmVariable) * copysize); + if(a_size > copysize) + { + memset(array + copysize, 0, sizeof(gmVariable) * (a_size - copysize)); + } + a_machine->Sys_Free(m_array); + } + else + { + memset(array, 0, sizeof(gmVariable) * a_size); + } + m_array = array; + m_size = a_size; + return true; +} + +#if GM_USE_INCGC +bool gmUserArray::Trace(gmMachine * a_machine, gmGarbageCollector* a_gc, const int a_workLeftToGo, int& a_workDone) +{ + int i; + for(i = 0; i < m_size; ++i) + { + if(m_array[i].IsReference()) + { + gmObject * object = GM_MOBJECT(a_machine, m_array[i].m_value.m_ref); + a_gc->GetNextObject(object); + ++a_workDone; + } + } + + ++a_workDone; + return true; +} +#else //GM_USE_INCGC +void gmUserArray::Mark(gmMachine * a_machine, gmuint32 a_mark) +{ + int i; + for(i = 0; i < m_size; ++i) + { + if(m_array[i].IsReference()) + { + gmObject * object = GM_MOBJECT(a_machine, m_array[i].m_value.m_ref); + if(object->NeedsMark(a_mark)) object->Mark(a_machine, a_mark); + } + } +} +#endif //GM_USE_INCGC + + +bool gmUserArray::Shift(int a_shift) +{ + if(a_shift < 0) // shift left + { + a_shift = -a_shift; + if(a_shift >= m_size) + { + memset(m_array, 0, m_size); + } + else + { + int size = m_size - a_shift; + memmove(m_array, m_array + a_shift, sizeof(gmVariable) * size); + memset(m_array + size, 0, sizeof(gmVariable) * a_shift); + } + } + else if(a_shift > 0) // shift right + { + if(a_shift >= m_size) + { + memset(m_array, 0, m_size); + } + else + { + int size = m_size - a_shift; + memmove(m_array + a_shift, m_array, sizeof(gmVariable) * size); + memset(m_array, 0, sizeof(gmVariable) * a_shift); + } + } + return true; +} + + +int gmUserArray::Move(int a_dest, int a_src, int a_size) +{ + int start = a_src; + int dest = a_dest; + int size = a_size; + + if(start < 0) + { + size += start; + dest -= start; + start = 0; + } + + if(dest < 0) + { + size += dest; + start -= dest; + dest = 0; + } + + if(size <= 0) return 0; + if(start >= m_size) return 0; + if(dest >= m_size) return 0; + if((dest + size) < 0) return 0; + + if(start + size > m_size) + { + size = m_size - start; + } + if(dest + size > m_size) + { + size = m_size - dest; + } + if(size <= 0) return 0; + + GM_ASSERT(dest >= 0); + GM_ASSERT(start >= 0); + GM_ASSERT(start + size <= m_size); + GM_ASSERT(dest + size <= m_size); + + memmove(m_array + dest, m_array + start, sizeof(gmVariable) * size); + + return size; +} + +gmUserArray* gmUserArray_Create(gmMachine* a_machine, int a_size) +{ + gmUserArray * newArray = (gmUserArray *) a_machine->Sys_Alloc(sizeof(gmUserArray)); + newArray->Construct(a_machine, a_size); + return newArray; +} + + +// functions + +static int GM_CDECL gmfArray(gmThread * a_thread) // size +{ + GM_INT_PARAM(size, 0, 0); + gmUserArray * array = (gmUserArray *) a_thread->GetMachine()->Sys_Alloc(sizeof(gmUserArray)); + array->Construct(a_thread->GetMachine(), size); + a_thread->PushNewUser(array, GM_ARRAY); + return GM_OK; +} + +static int GM_CDECL gmfArraySize(gmThread * a_thread) // return size +{ + gmUserObject * arrayObject = a_thread->ThisUserObject(); + GM_ASSERT(arrayObject->m_userType == GM_ARRAY); + if(arrayObject->m_user) + { + gmUserArray * array = (gmUserArray *) arrayObject->m_user; + a_thread->PushInt(array->Size()); + } + return GM_OK; +} + +static int GM_CDECL gmfArrayResize(gmThread * a_thread) // size +{ + GM_INT_PARAM(size, 0, 0); + gmUserObject * arrayObject = a_thread->ThisUserObject(); + GM_ASSERT(arrayObject->m_userType == GM_ARRAY); + if(arrayObject->m_user) + { + gmUserArray * array = (gmUserArray *) arrayObject->m_user; + array->Resize(a_thread->GetMachine(), size); + } + return GM_OK; +} + +static int GM_CDECL gmfArrayShift(gmThread * a_thread) // shift +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_INT_PARAM(shift, 0); + + gmUserObject * arrayObject = a_thread->ThisUserObject(); + GM_ASSERT(arrayObject->m_userType == GM_ARRAY); + if(arrayObject->m_user) + { + gmUserArray * array = (gmUserArray *) arrayObject->m_user; + array->Shift(shift); + } + return GM_OK; +} + +static int GM_CDECL gmfArrayMove(gmThread * a_thread) // dst, src, size +{ + GM_CHECK_NUM_PARAMS(3); + GM_CHECK_INT_PARAM(dst, 0); + GM_CHECK_INT_PARAM(src, 1); + GM_CHECK_INT_PARAM(size, 2); + + gmUserObject * arrayObject = a_thread->ThisUserObject(); + GM_ASSERT(arrayObject->m_userType == GM_ARRAY); + if(arrayObject->m_user) + { + gmUserArray * array = (gmUserArray *) arrayObject->m_user; + array->Move(dst, src, size); + } + return GM_OK; +} + +static void GM_CDECL gmArrayGetInd(gmThread * a_thread, gmVariable * a_operands) +{ + gmUserObject * arrayObject = (gmUserObject *) GM_OBJECT(a_operands->m_value.m_ref); + GM_ASSERT(arrayObject->m_userType == GM_ARRAY); + gmUserArray * array = (gmUserArray *) arrayObject->m_user; + if(a_operands[1].m_type == GM_INT) + { + int index = a_operands[1].m_value.m_int; + *a_operands = array->GetAt(index); + return; + } + a_operands->Nullify(); +} + +static void GM_CDECL gmArraySetInd(gmThread * a_thread, gmVariable * a_operands) +{ + gmUserObject * arrayObject = (gmUserObject *) GM_OBJECT(a_operands->m_value.m_ref); + GM_ASSERT(arrayObject->m_userType == GM_ARRAY); + gmUserArray * array = (gmUserArray *) arrayObject->m_user; + if(a_operands[1].m_type == GM_INT) + { + int index = a_operands[1].m_value.m_int; + +#if GM_USE_INCGC + //Apply write barrier + gmVariable oldVar = array->GetAt(index); + if(oldVar.IsReference()) + { + a_thread->GetMachine()->GetGC()->WriteBarrier((gmObject*)oldVar.m_value.m_ref); + } +#endif //GM_USE_INCGC + + array->SetAt(index, a_operands[2]); + } +} + +#if GM_USE_INCGC +static void GM_CDECL gmGCDestructArrayUserType(gmMachine * a_machine, gmUserObject* a_object) +{ + if(a_object->m_user) + { + gmUserArray * array = (gmUserArray *) a_object->m_user; + array->Destruct(a_machine); + a_machine->Sys_Free(array); + } + a_object->m_user = NULL; +} + +static bool GM_CDECL gmGCTraceArrayUserType(gmMachine * a_machine, gmUserObject* a_object, gmGarbageCollector* a_gc, const int a_workLeftToGo, int& a_workDone) +{ + if(a_object->m_user) + { + gmUserArray * array = (gmUserArray *) a_object->m_user; + return array->Trace(a_machine, a_gc, a_workLeftToGo, a_workDone); + } + return true; +} + +#else //GM_USE_INCGC +static void GM_CDECL gmMarkArrayUserType(gmMachine * a_machine, gmUserObject * a_object, gmuint32 a_mark) +{ + if(a_object->m_user) + { + gmUserArray * array = (gmUserArray *) a_object->m_user; + array->Mark(a_machine, a_mark); + } +} + +static void GM_CDECL gmGCArrayUserType(gmMachine * a_machine, gmUserObject * a_object, gmuint32 a_mark) +{ + if(a_object->m_user) + { + gmUserArray * array = (gmUserArray *) a_object->m_user; + array->Destruct(a_machine); + a_machine->Sys_Free(array); + } + a_object->m_user = NULL; +} +#endif //GM_USE_INCGC + +// libs + +static gmFunctionEntry s_arrayLib[] = +{ + /*gm + \lib gm + */ + /*gm + \function array + \brief array will create a fixed size array object + \param int size optional (0) + \return array + */ + {"array", gmfArray}, +}; + +static gmFunctionEntry s_arrayTypeLib[] = +{ + /*gm + \lib array + */ + /*gm + \function Size + \brief Size will return the current size of the fixed array + \return int array size + */ + {"Size", gmfArraySize}, + /*gm + \function Resize + \brief Resize will resize the array to a new size + \param int size optional (0) + \return null + */ + {"Resize", gmfArrayResize}, + /*gm + \function Shift + \brief Shift will shift slide the array elements by a delta, nulls are shifted in + \param int delta + \return null + */ + {"Shift", gmfArrayShift}, + /*gm + \function Move + \brief Move will perform a non destructive move on the array + \param int dst + \param int src + \param int size + \return null + */ + {"Move", gmfArrayMove}, +}; + +void gmBindArrayLib(gmMachine * a_machine) +{ + gmUserArray::m_null.Nullify(); //Init static null + + a_machine->RegisterLibrary(s_arrayLib, sizeof(s_arrayLib) / sizeof(s_arrayLib[0])); + GM_ARRAY = a_machine->CreateUserType("array"); + a_machine->RegisterTypeLibrary(GM_ARRAY, s_arrayTypeLib, sizeof(s_arrayTypeLib) / sizeof(s_arrayTypeLib[0])); +#if GM_USE_INCGC + a_machine->RegisterUserCallbacks(GM_ARRAY, gmGCTraceArrayUserType, gmGCDestructArrayUserType); +#else //GM_USE_INCGC + a_machine->RegisterUserCallbacks(GM_ARRAY, gmMarkArrayUserType, gmGCArrayUserType); +#endif //GM_USE_INCGC + a_machine->RegisterTypeOperator(GM_ARRAY, O_GETIND, NULL, gmArrayGetInd); + a_machine->RegisterTypeOperator(GM_ARRAY, O_SETIND, NULL, gmArraySetInd); +} + +#endif // GM_ARRAY_LIB diff --git a/vscript/languages/gm/src/binds/gmArrayLib.h b/vscript/languages/gm/src/binds/gmArrayLib.h new file mode 100644 index 00000000..56717ab5 --- /dev/null +++ b/vscript/languages/gm/src/binds/gmArrayLib.h @@ -0,0 +1,95 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMARRAYLIB_H_ +#define _GMARRAYLIB_H_ + +#include "gmConfig.h" +#include "gmVariable.h" + +// Fwd decls +class gmMachine; + +#define GM_ARRAY_LIB 1 +#define GM_ARRAY_LIB_GROW_BY 16 + +#if GM_ARRAY_LIB + +extern gmType GM_ARRAY; + +void gmBindArrayLib(gmMachine * a_machine); + +/*! + \class gmUserArray +*/ +class gmUserArray +{ +public: + + /// \brief Construct() + bool Construct(gmMachine * a_machine, int a_size); + + /// \brief Destruct() + void Destruct(gmMachine * a_machine); +#if GM_USE_INCGC + bool Trace(gmMachine * a_machine, gmGarbageCollector* a_gc, const int a_workLeftToGo, int& a_workDone); +#else //GM_USE_INCGC + /// \brief Mark() + void Mark(gmMachine * a_machine, gmuint32 a_mark); +#endif //GM_USE_INCGC + + /// \brief GetAt() + GM_FORCEINLINE const gmVariable &GetAt(int a_index) + { + if(a_index >= 0 && a_index < m_size) + { + return m_array[a_index]; + } + return m_null; + } + + /// \brief SetAt() + GM_FORCEINLINE bool SetAt(int a_index, const gmVariable &a_variable) + { + if(a_index >= 0 && a_index < m_size) + { + m_array[a_index] = a_variable; + return true; + } + return false; + } + + /// \brief Size() + GM_FORCEINLINE int Size() const { return m_size; } + + /// \brief Resize() + bool Resize(gmMachine * a_machine, int a_size); + + /// \brief Shift() + bool Shift(int a_shift); + + /// \brief Move() + int Move(int a_dest, int a_src, int a_size); + + // data + gmVariable * m_array; + int m_size; + + static gmVariable m_null; +}; + + +/// \brief Create a GM_ARRAY. This much be put into a user object. +gmUserArray* gmUserArray_Create(gmMachine* a_machine, int a_size = 0); + +#endif // GM_ARRAY_LIB + +#endif // _GMARRAYLIB_H_ diff --git a/vscript/languages/gm/src/binds/gmCall.cpp b/vscript/languages/gm/src/binds/gmCall.cpp new file mode 100644 index 00000000..f6c6f612 --- /dev/null +++ b/vscript/languages/gm/src/binds/gmCall.cpp @@ -0,0 +1,17 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmCall.h" + +// Must be last header +#include "memdbgon.h" + diff --git a/vscript/languages/gm/src/binds/gmCall.h b/vscript/languages/gm/src/binds/gmCall.h new file mode 100644 index 00000000..f2befd28 --- /dev/null +++ b/vscript/languages/gm/src/binds/gmCall.h @@ -0,0 +1,434 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMCALL_H_ +#define _GMCALL_H_ + +#include "gmConfig.h" +#include "gmThread.h" +#include "gmMachine.h" + +#undef GetObject //Fix for Win32 where GetObject is #defined + +/// \class gmCall +/// \brief A helper class to call script functions from C +/// Warning: Do not store any of the reference type return variables (eg. GM_SRING). +/// As the object may be garbage collected. Instead, copy immediately as necessary. +class gmCall +{ +public: + + /// \brief Constructor + gmCall() + { +#ifdef GM_DEBUG_BUILD + m_locked = false; +#endif //GM_DEBUG_BUILD + } + + /// \brief Begin the call of a global function + /// \param a_machine Virtual machine instance + /// \param a_funcName Name of function + /// \param a_this The 'this' used by the function. + /// \param a_delayExecuteFlag Set true if you want function thread to not execute now. + /// \return true on sucess, false if function was not found. + GM_FORCEINLINE bool BeginGlobalFunction(gmMachine * a_machine, const char * a_funcName, + const gmVariable& a_this = gmVariable::s_null, + bool a_delayExecuteFlag = false) + { + GM_ASSERT(a_machine); + + gmStringObject * funcNameStringObj = a_machine->AllocPermanantStringObject(a_funcName); // Slow + + return BeginGlobalFunction(a_machine, funcNameStringObj, a_this, a_delayExecuteFlag); + } + + /// \brief Begin the call of a global function + /// \param a_machine Virtual machine instance + /// \param a_funcNameStringObj A string object that was found or created earlier, much faster than creating from c string. + /// \param a_this The 'this' used by the function. + /// \param a_delayExecuteFlag Set true if you want function thread to not execute now. + /// \return true on sucess, false if function was not found. + GM_FORCEINLINE bool BeginGlobalFunction(gmMachine * a_machine, gmStringObject * a_funcNameStringObj, + const gmVariable& a_this = gmVariable::s_null, + bool a_delayExecuteFlag = false) + { + GM_ASSERT(a_machine); + GM_ASSERT(a_funcNameStringObj); + + gmVariable lookUpVar; + gmVariable foundFunc; + + lookUpVar.SetString(a_funcNameStringObj); + foundFunc = a_machine->GetGlobals()->Get(lookUpVar); + + if( GM_FUNCTION == foundFunc.m_type ) // Check found variable is a function + { + gmFunctionObject * functionObj = (gmFunctionObject *)foundFunc.m_value.m_ref; //Func Obj from variable + + return BeginFunction(a_machine, functionObj, a_this, a_delayExecuteFlag); + } + return false; + } + + /// \brief Begin the call of a object function + /// \param a_machine Virtual machine instance + /// \param a_funcName Name of function. + /// \param a_tableObj The table on the object to look up the function. + /// \param a_this The 'this' used by the function. + /// \param a_delayExecuteFlag Set true if you want function thread to not execute now. + /// \return true on sucess, false if function was not found. + GM_FORCEINLINE bool BeginTableFunction(gmMachine * a_machine, const char * a_funcName, + gmTableObject * a_tableObj, const gmVariable& a_this = gmVariable::s_null, + bool a_delayExecuteFlag = false) + { + GM_ASSERT(a_machine); + GM_ASSERT(a_funcName); + + gmStringObject * funcNameStringObj = a_machine->AllocPermanantStringObject(a_funcName); // Slow + + return BeginTableFunction(a_machine, funcNameStringObj, a_tableObj, a_this, a_delayExecuteFlag); + } + + /// \brief Begin the call of a object function + /// \param a_machine Virtual machine instance + /// \param a_funcNameStringObj A string object that was found or created earlier, much faster than creating from c string. + /// \param a_tableObj The table on the object to look up the function. + /// \param a_this The 'this' used by the function. + /// \param a_delayExecuteFlag Set true if you want function thread to not execute now. + /// \return true on sucess, false if function was not found. + GM_FORCEINLINE bool BeginTableFunction(gmMachine * a_machine, gmStringObject * a_funcNameStringObj, + gmTableObject * a_tableObj, const gmVariable& a_this = gmVariable::s_null, + bool a_delayExecuteFlag = false) + { + GM_ASSERT(a_machine); + //GM_ASSERT(a_tableObj); + GM_ASSERT(a_funcNameStringObj); + + gmVariable lookUpVar; + gmVariable foundFunc; + + if ( !a_tableObj ) + { + a_tableObj = a_machine->GetGlobals(); + } + + lookUpVar.SetString(a_funcNameStringObj); + foundFunc = a_tableObj->Get(lookUpVar); + + if( GM_FUNCTION == foundFunc.m_type ) // Check found variable is a function + { + gmFunctionObject * functionObj = (gmFunctionObject *)foundFunc.m_value.m_ref; //Func Obj from variable + return BeginFunction(a_machine, functionObj, a_this, a_delayExecuteFlag); + } + return false; + } + + /// \brief Begin the call of a object function + /// \param a_funcObj A function object that was found or created earlier. + /// \param a_tableObj The table on the object to look up the function. + /// \param a_this The 'this' used by the function. + /// \param a_delayExecuteFlag Set true if you want function thread to not execute now. + /// \return true on sucess, false if function was not found. + GM_FORCEINLINE bool BeginFunction(gmMachine * a_machine, gmFunctionObject * a_funcObj, + const gmVariable &a_thisVar = gmVariable::s_null, + bool a_delayExecuteFlag = false) + { + GM_ASSERT(a_machine); + GM_ASSERT(a_funcObj); + +#ifdef GM_DEBUG_BUILD + // YOU CANNOT NEST gmCall::Begin + GM_ASSERT(m_locked == false); + m_locked = true; +#endif //GM_DEBUG_BUILD + + Reset(a_machine); + + if( GM_FUNCTION == a_funcObj->GetType() ) // Check found variable is a function + { + m_thread = m_machine->CreateThread(); // Create thread for func to run on + m_thread->Push(a_thisVar); // this + m_thread->PushFunction(a_funcObj); // function + m_delayExecuteFlag = a_delayExecuteFlag; + return true; + } + +#ifdef GM_DEBUG_BUILD + GM_ASSERT(m_locked == true); + m_locked = false; +#endif //GM_DEBUG_BUILD + + return false; + } + + /// \brief Add a parameter variable + GM_FORCEINLINE void AddParam(const gmVariable& a_var) + { + GM_ASSERT(m_machine); + GM_ASSERT(m_thread); + + m_thread->Push(a_var); + ++m_paramCount; + } + + /// \brief Add a parameter that is null + GM_FORCEINLINE void AddParamNull() + { + GM_ASSERT(m_machine); + GM_ASSERT(m_thread); + + m_thread->PushNull(); + ++m_paramCount; + } + + /// \brief Add a parameter that is a integer + GM_FORCEINLINE void AddParamInt(const int a_value) + { + GM_ASSERT(m_machine); + GM_ASSERT(m_thread); + + m_thread->PushInt(a_value); + ++m_paramCount; + } + + /// \brief Add a parameter that is a float + GM_FORCEINLINE void AddParamFloat(const float a_value) + { + GM_ASSERT(m_machine); + GM_ASSERT(m_thread); + + m_thread->PushFloat(a_value); + ++m_paramCount; + } + + /// \brief Add a parameter that is a string + GM_FORCEINLINE void AddParamString(const char * a_value, int a_len = -1) + { + GM_ASSERT(m_machine); + GM_ASSERT(m_thread); + + m_thread->PushNewString(a_value, a_len); + ++m_paramCount; + } + + /// \brief Add a parameter that is a string (faster version since c string does not need lookup) + GM_FORCEINLINE void AddParamString(gmStringObject * a_value) + { + GM_ASSERT(m_machine); + GM_ASSERT(m_thread); + + m_thread->PushString(a_value); + ++m_paramCount; + } + + /// \brief Add a parameter that is a user object. Creates a new user object. + /// \param a_value Pointer to user object data + /// \param a_userType Type of user object beyond GM_USER + GM_FORCEINLINE void AddParamUser(void * a_value, int a_userType) + { + GM_ASSERT(m_machine); + GM_ASSERT(m_thread); + + m_thread->PushNewUser(a_value, a_userType); + ++m_paramCount; + } + + /// \brief Add a parameter that is a user object. + /// \param a_userObj Pushes an existing user object without creating a new one. + GM_FORCEINLINE void AddParamUser(gmUserObject * a_userObj) + { + GM_ASSERT(m_machine); + GM_ASSERT(m_thread); + + m_thread->PushUser(a_userObj); + ++m_paramCount; + } + + /// \brief Add a parameter that is a table object. + /// \param a_tableObj Pushes an existing table object without creating a new one. + GM_FORCEINLINE void AddParamTable(gmTableObject * a_tableObj) + { + GM_ASSERT(m_machine); + GM_ASSERT(m_thread); + + m_thread->PushTable(a_tableObj); + ++m_paramCount; + } + + /// \brief Make the call. If a return value was expected, it will be set in here. + /// \param a_threadId Optional + GM_FORCEINLINE void End(int * a_threadId = NULL) + { + GM_ASSERT(m_machine); + GM_ASSERT(m_thread); + +#ifdef GM_DEBUG_BUILD + // CAN ONLY CALL ::End() after a successful ::Begin + GM_ASSERT(m_locked == true); + m_locked = false; +#endif //GM_DEBUG_BUILD + + int state = m_thread->PushStackFrame(m_paramCount); + if(state != gmThread::KILLED) // Can be killed immedialy if it was a C function + { + if(m_delayExecuteFlag) + { + state = m_thread->GetState(); + } + else + { + state = m_thread->Sys_Execute(&m_returnVar); + } + } + else + { + // Was a C function call, grab return var off top of stack + m_returnVar = *(m_thread->GetTop() - 1); + m_machine->Sys_SwitchState(m_thread, gmThread::KILLED); + } + + // If we requested a thread Id + if(a_threadId) + { + if(state != gmThread::KILLED) + { + *a_threadId = m_thread->GetId(); + } + else + { + *a_threadId = GM_INVALID_THREAD; + } + } + + if(state == gmThread::KILLED) + { + m_returnFlag = true; // Function always returns something, null if not explicit. + m_thread = NULL; // Thread has exited, no need to remember it. + } + } + + /// \brief Accesss thread created for function call. + GM_FORCEINLINE gmThread * GetThread() { return m_thread; } + + /// \brief Returns reference to 'return' variable. Never fails, but variable may be a 'null' varaible if none was returned. + const gmVariable& GetReturnedVariable() { return m_returnVar; } + + /// \brief Returns true if function exited and returned a variable. + bool DidReturnVariable() { return m_returnFlag; } + + /// \brief Did function return a null? + /// \return true if function returned null. + bool GetReturnedNull() + { + if(m_returnFlag && (m_returnVar.m_type == GM_NULL)) + { + return true; + } + return false; + } + + /// \brief Get returned int + /// \return true if function returned an int. + bool GetReturnedInt(int& a_value) + { + if(m_returnFlag && (m_returnVar.m_type == GM_INT)) + { + a_value = m_returnVar.m_value.m_int; + return true; + } + return false; + } + + /// \brief Get returned float + /// \return true if function returned an float. + bool GetReturnedFloat(float& a_value) + { + if(m_returnFlag && (m_returnVar.m_type == GM_FLOAT)) + { + a_value = m_returnVar.m_value.m_float; + return true; + } + return false; + } + + /// \brief Get returned string + /// \return true if function returned an string. + bool GetReturnedString(const char *& a_value) + { + if(m_returnFlag && (m_returnVar.m_type == GM_STRING)) + { + a_value = ((gmStringObject *)m_machine->GetObject(m_returnVar.m_value.m_ref))->GetString(); + return true; + } + return false; + } + + /// \brief Get returned user + /// \return true if function returned an user. + bool GetReturnedUser(void *& a_value, int a_userType) + { + if(m_returnFlag && (m_returnVar.m_type == a_userType)) + { + a_value = (void *)m_returnVar.m_value.m_ref; + return true; + } + return false; + } + + /// \brief Get returned user or null + /// \return true if function returned an user or null. + bool GetReturnedUserOrNull(void *& a_value, int a_userType) + { + if(m_returnFlag) + { + if(m_returnVar.m_type == a_userType) + { + a_value = (void *)m_returnVar.m_value.m_ref; + return true; + } + else if(m_returnVar.m_type == GM_NULL) + { + a_value = (void *)NULL; + return true; + } + } + return false; + } + +protected: + + gmMachine * m_machine; + gmThread * m_thread; + gmVariable m_returnVar; + int m_paramCount; + bool m_returnFlag; + bool m_delayExecuteFlag; +#ifdef GM_DEBUG_BUILD + bool m_locked; +#endif //GM_DEBUG_BUILD + + /// \brief Used internally to clear call information. + GM_FORCEINLINE void Reset(gmMachine * a_machine) + { + GM_ASSERT(a_machine); + m_machine = a_machine; + m_thread = NULL; + m_returnVar.Nullify(); + m_returnFlag = false; + m_paramCount = 0; + m_delayExecuteFlag = false; + }; + +}; + + +#endif // _GMCALL_H_ diff --git a/vscript/languages/gm/src/binds/gmGCRoot.cpp b/vscript/languages/gm/src/binds/gmGCRoot.cpp new file mode 100644 index 00000000..85ea7eeb --- /dev/null +++ b/vscript/languages/gm/src/binds/gmGCRoot.cpp @@ -0,0 +1,215 @@ +// +// gmGCRoot.cpp +// + +#include "gmGCRoot.h" + +// Must be last header +#include "memdbgon.h" + + +// Init statics and constants +gmGCRootManager* gmGCRootManager::s_staticInstance; + + +gmGCRootManager::gmGCRootManager() +{ + m_machineHolderSet.Init(0, 4); +} + + +gmGCRootManager::~gmGCRootManager() +{ + DestroyAllMachines(); +} + + +void gmGCRootManager::Init() +{ + GM_ASSERT( !s_staticInstance ); + + if( !s_staticInstance ) + { + s_staticInstance = new gmGCRootManager; + } +} + + +void gmGCRootManager::Destroy() +{ + if( s_staticInstance ) + { + delete s_staticInstance; + s_staticInstance = NULL; + } +} + + +gmgcrHolder* gmGCRootManager::FindOrAdd(gmObject* a_object, gmMachine* a_machine) +{ + GM_ASSERT(a_object); + GM_ASSERT(a_machine); + + if( !a_object || !a_machine ) + { + return NULL; + } + + MachineHolders* machineSet = FindOrAddMachine(a_machine); + + gmgcrHolder* holder = NULL; + if( !machineSet->m_mapPtrToHolder.GetAt(a_object, holder) ) + { + // Add new + holder = m_memHolder.Alloc(); + holder->Init(a_object, a_machine); + machineSet->m_mapPtrToHolder.SetAt(a_object, holder); + + a_machine->AddCPPOwnedGMObject(a_object); // Add to GC roots + } + return holder; +} + + +void gmGCRootManager::RemoveObject(gmObject* a_object, gmMachine* a_machine) +{ + if( a_object && a_machine ) + { + a_machine->RemoveCPPOwnedGMObject(a_object); // Remove from GC roots + + gmGCRootManager::MachineHolders* machineSet = FindOrAddMachine(a_machine); + + machineSet->m_mapPtrToHolder.RemoveAt(a_object); + } +} + + +void gmGCRootManager::FreeHolder(const gmgcrHolder* a_holder) +{ + if( a_holder ) + { + m_memHolder.Free( const_cast(a_holder) ); + } +} + + +void gmGCRootManager::DestroyMachine(gmMachine* a_machine) +{ + int foundIndex = -1; + + // Find existing set + for(int mIndex=0; mIndex < m_machineHolderSet.GetSize(); ++mIndex) + { + if( m_machineHolderSet[mIndex].m_machine == a_machine ) + { + foundIndex = mIndex; + break; + } + } + + if( foundIndex >= 0 ) + { + MachineHolders* destroySet = &m_machineHolderSet[foundIndex]; + + // Cleanup all internal pointers + gmgcrMap::Iterator it; + + // Iterate carefully as we are deleting while iterating + destroySet->m_mapPtrToHolder.GetFirst(it); + while( !destroySet->m_mapPtrToHolder.IsNull(it) ) + { + gmgcrHolder* toDelete = NULL; + if( destroySet->m_mapPtrToHolder.GetValue(it, toDelete) ) + { + // NOTE: Delete this found value after incrementing iterator + } + destroySet->m_mapPtrToHolder.GetNext(it); + if( toDelete ) + { + toDelete->Destroy(); + } + } + + // Remove machine set + m_machineHolderSet.RemoveAt(foundIndex); + } +} + + +gmGCRootManager::MachineHolders* gmGCRootManager::FindOrAddMachine(gmMachine* a_machine) +{ + // NOTE: Expect very small number of machines. If this is not so, accelerate search. + + GM_ASSERT( a_machine ); + + // Find existing set + for(int mIndex=0; mIndex < m_machineHolderSet.GetSize(); ++mIndex) + { + if( m_machineHolderSet[mIndex].m_machine == a_machine ) + { + return &m_machineHolderSet[mIndex]; + } + } + + // Create new set + int newIndex = m_machineHolderSet.AddEmpty(); + MachineHolders* newSet = &m_machineHolderSet[newIndex]; + newSet->m_machine = a_machine; + return newSet; +} + + +void gmGCRootManager::DestroyAllMachines() +{ + while( m_machineHolderSet.GetSize() ) + { + DestroyMachine( m_machineHolderSet[m_machineHolderSet.GetLastIndex()].m_machine ); + } +} + + +#if 0 +// Test the gmGCRoot system +void TestGMGCRoot() +{ + gmGCRootManager::Init(); // Init system + { + gmMachine machine1; + + gmGCRoot ptr1; + + gmStringObject* stringObj1 = machine1.AllocStringObject("hello"); + + ptr1.Set(stringObj1, &machine1); // Initialize via func + + gmStringObject* nat1 = ptr1; // Assign pointer + + gmGCRoot ptr2; + ptr2 = ptr1; + + ptr1 = NULL; // Assign to null + ptr2 = NULL; + //ptr2 = nat1; // ERROR + + gmStringObject* stringObj2 = machine1.AllocStringObject("apple"); + gmGCRoot ptr3(stringObj2, &machine1); // Initialize via constructor + gmGCRoot ptr4(stringObj2, &machine1); // Duplicate without copy + + gmGCRoot ptr5; + { + gmMachine machine2; + + gmStringObject* stringObj3 = machine2.AllocStringObject("bannana"); + ptr5.Set(stringObj3, &machine2); + + gmGCRootManager::Get()->DestroyMachine(&machine2); // Null associated pointers + } + if( ptr5 ) + { + int i=1; // Won't get here + } + + } + gmGCRootManager::Destroy(); +} +#endif diff --git a/vscript/languages/gm/src/binds/gmGCRoot.h b/vscript/languages/gm/src/binds/gmGCRoot.h new file mode 100644 index 00000000..21fefc30 --- /dev/null +++ b/vscript/languages/gm/src/binds/gmGCRoot.h @@ -0,0 +1,399 @@ +#ifndef GMGCROOT_H +#define GMGCROOT_H + +// +// gmGCRoot.h +// + +#include "gmThread.h" +#include "gmGCRootUtil.h" + + +/////////////////////////////////////////////////////////////////////////////// +// +// gmGCRoot +// +// Templated smart pointer style wrapper for gmObject* +// Automatically adds and removed CPP owned gmObject* from gmMachine roots +// +// It works by storing the gmObject* inside a shared reference counted holder +// object. When a gmObject* is first wrapped, a holder object is created to +// store it. Subsequent initializations will share the same holder object. It +// is much more efficient to assign the pointer from one gmGCRoot to another +// than create a new one from the raw gmObject*. +// +// +// To use, you must initialize and destroy the system with: +// gmGCRootManager::Init(); +// gmGCRootManager::Destroy(); +// When you destruct a gmMachine that was used by the system, call this first: +// gmGCRootManager::Get()->DestroyMachine(myMachine); +// Initialize a pointer by either: +// gmGCRoot ptr1(myObject, myMachine); +// gmGCRoot ptr2; ptr2.Set(myObject, myMachine); +// Copy and test pointers as you would a C style pointer eg: +// if( ptr1 ) { int type = ptr1->GetType(); } +// ptr2 = ptr1; +// ptr1 = NULL; +// +// +// Example usage: +// gmGCRootManager::Init(); // Call once first eg. App initialization +// gmGCRoot ptr1; // A null pointer +// gmGCRoot ptr2(myString, myMachine); // A pointer +// gmStringObject* nat1 = ptr2; // Cast to native +// gmGCRoot ptr3 = ptr2; // Assign from other (Fast copy of shared pointer) +// ptr2 = NULL; // Assign to null +// ptr2 = nat1; // COMPILE ERROR! can't assign without gmMachine +// gmGCRootManager::Get()->DestroyMachine(myMachine); // Call before destructing a gmMachine +// gmGCRootManager::Destroy(); // Call once before App exit +// +/////////////////////////////////////////////////////////////////////////////// + +// Fwd decls +class gmGCRootManager; +class gmgcrHolder; + + +/// Bass class for objects reference counted types +class gmgcrRefCount +{ +public: + + /// Construct, starts reference count at 0 (Must be wrapped in smart ptr to increment and later release) + gmgcrRefCount() { m_referenceCount = 0; } + /// Destructor + virtual ~gmgcrRefCount() { } + + /// Get reference count + int GetReferenceCount() const { return m_referenceCount; } + + /// Increment reference count + void AddReference() const { ++m_referenceCount; } + + /// Decrement reference count + int ReleaseReference() const + { + GM_ASSERT( m_referenceCount > 0 ); + if( --m_referenceCount == 0 ) + { + DeleteThis(); + return true; + } + return false; + } + + /// Delete this object. May override if this is not desired behavior. + /// NOTE: This function is 'const' so override with const also! + virtual void DeleteThis() const { delete this; } + +private: + + mutable int m_referenceCount; ///< Reference counter + +}; + + +/// Manager for gm gc roots +class gmGCRootManager +{ +public: + + /// Access singleton + static gmGCRootManager* Get() { return s_staticInstance; } + + /// Initialize gm gcroot manager + static void Init(); + + /// Destroy gm gcroot manager + static void Destroy(); + + ~gmGCRootManager(); + + // Find or Add shard holder for gmObject + gmgcrHolder* FindOrAdd(gmObject* a_object, gmMachine* a_machine); + + // Free holder memory only + void FreeHolder(const gmgcrHolder* a_holder); + + // Dissassociate holder contents + void RemoveObject(gmObject* a_object, gmMachine* a_machine); + + /// Call before destroying a gmMachine so that any associated objects can be disassociated and have pointers nullified. + void DestroyMachine(gmMachine* a_machine); + +protected: + + // Store gmObjects per machine + class MachineHolders + { + public: + gmMachine* m_machine; + //gmgcrMap m_mapPtrToHolder; + gmgcrMap m_mapPtrToHolder; + }; + + static gmGCRootManager* s_staticInstance; // Singleton + + gmgcrArray< MachineHolders > m_machineHolderSet; // Holders per machine + gmgcrMemFixed m_memHolder; // Holder memory + + // Non public constructor to prevent multiple instances + gmGCRootManager(); + + // Find or add machine + MachineHolders* FindOrAddMachine(gmMachine* a_machine); + + // Destroy all machine associations + void DestroyAllMachines(); + +}; + + +/// Holder that is always valid and may contain the real pointer +class gmgcrHolder : public gmgcrRefCount +{ +public: + + /// Default contsructor for simple allocation, Init() should be called immediately. + gmgcrHolder() + { + m_object = NULL; + m_machine = NULL; + } + + /// Initialize with real object + void Init(gmObject* a_object, + gmMachine* a_machine) + { + m_object = a_object; + m_machine = a_machine; + } + + /// Destroy object pointer (May occur before this holder dies) + void Destroy() const + { + if( m_object ) + { + GM_ASSERT( gmGCRootManager::Get() ); + gmGCRootManager::Get()->RemoveObject(m_object, m_machine); + } + + m_object = NULL; + m_machine = NULL; + } + + /// Get the real pointer + void* GetPtr() { return m_object; } + +private: + + /// Called when reference count reaches zero + void DeleteThis() const + { + Destroy(); + + GM_ASSERT( gmGCRootManager::Get() ); + + gmGCRootManager::Get()->FreeHolder(this); + } + + mutable gmObject* m_object; ///< The object + mutable gmMachine* m_machine; ///< The owning machine + +}; + + +/// This is the smart pointer to a gmObject +/// It adds the gmObject to the gmMachine GC roots so that the object is not collected while held +/// Initialize via constructor or Set(). eg. gmGCRoot ptr(myString, myMachine); +/// Fast cast to native type and fast copy to compatible pointer. +/// Slower FIRST construct and FINAL destruct as shared holder object performs map insert/removal. +/// If gmMachine is destructed, contents will be nullified. (As long as manager was called correctly.) +template< typename TYPE > +class gmGCRoot +{ +public: + + /// Empty Constructor. Equals NULL. + gmGCRoot() { m_ptrToHolder = NULL; } + + // NOTE: Currently not very safe since holder and controller are not typed. + /// Construct from holder + explicit gmGCRoot(gmgcrHolder* a_holder) + { + m_ptrToHolder = a_holder; + if( m_ptrToHolder ) + { + m_ptrToHolder->AddReference(); + } + } + + /// Construct from pointers + gmGCRoot(TYPE* a_object, gmMachine* a_machine) + { + m_ptrToHolder = NULL; + Set(a_object, a_machine); + } + + /// Set pointer + void Set(TYPE* a_object, gmMachine* a_machine) + { + if( m_ptrToHolder ) + { + m_ptrToHolder->ReleaseReference(); + } + + if( !a_object ) // Handle null assignment + { + m_ptrToHolder = NULL; + return; + } + + GM_ASSERT( gmGCRootManager::Get() ); + + m_ptrToHolder = gmGCRootManager::Get()->FindOrAdd( (gmObject*)a_object, (gmMachine*) a_machine ); + m_ptrToHolder->AddReference(); + } + + /// Copy Constructor + gmGCRoot(const gmGCRoot& a_ref) + { + m_ptrToHolder = a_ref.m_ptrToHolder; + if (m_ptrToHolder != NULL) + { + m_ptrToHolder->AddReference(); + } + } + + /// Destructor + ~gmGCRoot() + { + if( m_ptrToHolder ) + { + m_ptrToHolder->ReleaseReference(); + } + } + + /// Access the referenced type + operator TYPE* () { return (TYPE*)m_ptrToHolder->GetPtr(); } + operator const TYPE* () const { return (TYPE*)m_ptrToHolder->GetPtr(); } + + /// Access the object as pointer + TYPE* operator -> () { return (TYPE*)m_ptrToHolder->GetPtr(); } + const TYPE* operator -> () const { return (TYPE*)m_ptrToHolder->GetPtr(); } + + /// Access the object as reference + TYPE& operator * () { return *((TYPE*)m_ptrToHolder->GetPtr()); } + const TYPE& operator * () const { return *((TYPE*)m_ptrToHolder->GetPtr()); } + + /// Access object with standard function instead of operator. Useful when compiler finds conversion ambigous. + TYPE* Resolve() { return (TYPE*)m_ptrToHolder->GetPtr(); } + const TYPE* Resolve() const { return (TYPE*)m_ptrToHolder->GetPtr(); } + + /// Assign from other reference + gmGCRoot& operator = (const gmGCRoot& a_ref) + { + if( m_ptrToHolder != a_ref.GetHolder() ) + { + if( m_ptrToHolder != NULL ) + { + m_ptrToHolder->ReleaseReference(); + } + m_ptrToHolder = a_ref.GetHolder(); + if(m_ptrToHolder) + { + m_ptrToHolder->AddReference(); + } + } + return *this; + } + + /// Assign to NULL. Make shorter code path for assignment with zero (null in C++) + gmGCRoot& operator = (int a_null) + { + GM_ASSERT(a_null == 0); + if( m_ptrToHolder != NULL ) + { + m_ptrToHolder->ReleaseReference(); + } + m_ptrToHolder = NULL; + return *this; + } + + /// Equality test + int operator == (const gmGCRoot& a_ref) const + { + if( m_ptrToHolder == a_ref.GetHolder() ) + { + return true; + } + // Both holders cannot be NULL at this point, but one maybe. + if( (a_ref.GetHolder() == NULL) && (m_ptrToHolder->GetPtr() == NULL) ) + { + return true; + } + if( m_ptrToHolder == NULL ) + { + if( a_ref.GetHolder()->GetPtr() == NULL ) + { + return true; + } + } + else + { + if( a_ref.GetHolder() != NULL ) + { + if( a_ref.GetHolder()->GetPtr() == m_ptrToHolder->GetPtr() ) + { + return true; + } + } + } + return false; + } + + /// Non equality test + int operator != (const gmGCRoot& a_ref) const { return !operator==(a_ref); } + + /// Less than comparison for use in Containers + int operator < (const gmGCRoot& a_ref) const + { + if( a_ref.GetHolder() == NULL ) + { + return false; + } + if( m_ptrToHolder == NULL ) + { + return true; + } + return ( m_ptrToHolder->GetPtr() < a_ref.GetHolder()->GetPtr() ); + } + + /// Greater than comparison for use in Containers + int operator > (const gmGCRoot& a_ref) const + { + if( m_ptrToHolder == NULL ) + { + return false; + } + if( a_ref.GetHolder() == NULL ) + { + return true; + } + return ( m_ptrToHolder->GetPtr() > a_ref.GetHolder()->GetPtr() ); + } + + /// Access the holder. Necessary since this is a templated class. + gmgcrHolder* GetHolder() const { return m_ptrToHolder; } + +private: + + mutable gmgcrHolder* m_ptrToHolder; ///< Pointer to holder of the real pointer + +}; + + + + +#endif //GMGCROOT_H diff --git a/vscript/languages/gm/src/binds/gmGCRootUtil.cpp b/vscript/languages/gm/src/binds/gmGCRootUtil.cpp new file mode 100644 index 00000000..ad3ed216 --- /dev/null +++ b/vscript/languages/gm/src/binds/gmGCRootUtil.cpp @@ -0,0 +1,33 @@ +// +// gmGCRootUtil.cpp +// + +#include "gmGCRoot.h" +#include "gmGCRootUtil.h" + +// Must be last header +#include "memdbgon.h" + + + +gmgcrMemFixed::gmgcrMemFixed() + : gmMemFixed( sizeof(gmgcrHolder) ) +{ + +} + +gmgcrHolder* gmgcrMemFixed::Alloc() +{ + gmgcrHolder* ptr = (gmgcrHolder*)gmMemFixed::Alloc(); + gmConstructElement(ptr); + return ptr; +} + +void gmgcrMemFixed::Free(gmgcrHolder* a_ptr) +{ + if( a_ptr ) + { + gmDestructElement(a_ptr); + gmMemFixed::Free(a_ptr); + } +} diff --git a/vscript/languages/gm/src/binds/gmGCRootUtil.h b/vscript/languages/gm/src/binds/gmGCRootUtil.h new file mode 100644 index 00000000..f58352fa --- /dev/null +++ b/vscript/languages/gm/src/binds/gmGCRootUtil.h @@ -0,0 +1,171 @@ +#ifndef GMGCROOTUTIL_H +#define GMGCROOTUTIL_H + +// +// gmGCRootUtil.h +// + +#include "gmThread.h" + +// +// This file has containers and utilities for implementing gmGCRoot +// You may replace these implementations with your own containers with relative ease. +// + +// Fwd decls +class gmGCRootManager; +class gmgcrHolder; + + +// STL version +#include +#include + +template +class gmgcrMap +{ + typename std::map m_map; + +public: + + // Iterator, derive or contain native container iterator + class Iterator + { + public: + typename std::map::iterator m_it; + }; + + // Get Value at unique Key, return true if found + int GetAt(KEY a_key, VALUE& a_value) + { + typename std::map::iterator it = m_map.find(a_key); + if( it != m_map.end() ) + { + a_value = (*it).second; + return true; + } + return false; + }; + + // Set Value and unique Key + void SetAt(KEY a_key, VALUE& a_value) + { + m_map[a_key] = a_value; + } + + // Remove pair at unique Key + void RemoveAt(KEY a_key) + { + m_map.erase(a_key); + } + + // Iteration Get first pair + void GetFirst(Iterator& a_it) + { + a_it.m_it = m_map.begin(); + } + + // Iteration Get next pair + void GetNext(Iterator& a_it) + { + if( a_it.m_it != m_map.end() ) + { + ++a_it.m_it; + } + } + + // Iteration Is iterator valid. Return false if not. + int IsNull(Iterator& a_it) + { + if( a_it.m_it == m_map.end() ) + { + return true; + } + return false; + } + + // Iteration Get Value from iterator, return false if failed + int GetValue(Iterator& a_it, VALUE& a_value) + { + if( a_it.m_it != m_map.end() ) + { + a_value = (*a_it.m_it).second; + return true; + } + return false; + } + +}; + + +// Array, derive or contain array style container +template +class gmgcrArray +{ + typename std::vector m_array; + +public: + + // Set initial array size and any grow / presize for efficiency + void Init(int a_initialSize, int a_growSize) + { + SetSize(a_initialSize); + } + + // Set array size, and grow size + void SetSize(int a_size) + { + m_array.resize(a_size); + } + + // Return number of elements in array + int GetSize() + { + return m_array.size(); + } + + // Return last index eg. GetSize()-1 + int GetLastIndex() + { + return GetSize() - 1; + } + + // Remove element at index + void RemoveAt(int a_index) + { + m_array.erase(m_array.begin() + a_index); + } + + // Access element at index (by reference) + TYPE& operator[](int a_index) + { + return m_array[a_index]; + } + + // Add (default) element to array, returning index of new element + int AddEmpty() + { + int oldCount = GetSize(); // old count becomes new index + SetSize(oldCount+1); + return oldCount; + } + +}; + + +// Allocator, derive or contain frame style allocator +class gmgcrMemFixed : public gmMemFixed +{ +public: + + gmgcrMemFixed(); + + // Allocate and construct + gmgcrHolder* Alloc(); + + // Destruct and free + void Free(gmgcrHolder* a_ptr); + +}; + +#endif //GMGCROOTUTIL_H \ No newline at end of file diff --git a/vscript/languages/gm/src/binds/gmHelpers.cpp b/vscript/languages/gm/src/binds/gmHelpers.cpp new file mode 100644 index 00000000..7422eada --- /dev/null +++ b/vscript/languages/gm/src/binds/gmHelpers.cpp @@ -0,0 +1,64 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmHelpers.h" + + +// Must be last header +#include "memdbgon.h" + + +/*! + \brief gmRandomInt() returns a random int b/n two values + \return number is >= min and < max (exclusive of max) +*/ +int gmRandomInt(int a_min, int a_max) +{ + if(a_min > a_max) + { + int temp = a_max; + a_max = a_min; + a_min = temp; + } + else if(a_min == a_max) + { + return a_min; // hmmm, not good. + } + + int randVal = rand(); + int val = (randVal % (a_max - a_min)) + a_min; + + return val; +} + + +/*! + \brief gmRandomInt() returns a random int b/n two values + \return number is >= min and < max (exclusive of max) +*/ +float gmRandomFloat(float a_min, float a_max) +{ + if(a_min > a_max) + { + float temp = a_max; + a_max = a_min; + a_min = temp; + } + else if(a_min == a_max) + { + return a_min; // hmmm, not good. + } + + int randVal = rand() % RAND_MAX; + float frandVal = (float)randVal / (float)RAND_MAX; + return a_min + (frandVal * (a_max - a_min)); +} diff --git a/vscript/languages/gm/src/binds/gmHelpers.h b/vscript/languages/gm/src/binds/gmHelpers.h new file mode 100644 index 00000000..e3d0d8e6 --- /dev/null +++ b/vscript/languages/gm/src/binds/gmHelpers.h @@ -0,0 +1,179 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMHELPERS_H_ +#define _GMHELPERS_H_ + +#include "gmConfig.h" +#include "gmThread.h" +#include + +// +// Helpers +// + +#define GM_PI_VALUE 3.1415927f + +// Clamp value between to range +template +GM_FORCEINLINE TYPE gmClamp(const TYPE a_min, const TYPE a_value, const TYPE a_max) +{ + if(a_value < a_min) + { + return a_min; + } + else if(a_value > a_max) + { + return a_max; + } + return a_value; +} + +template +GM_FORCEINLINE TYPE gmMin3(const TYPE a_x, const TYPE a_y, const TYPE a_z) +{ + if(a_y < a_x) + { + if(a_z < a_y) + { + return a_z; + } + else + { + return a_y; + } + } + else + { + if (a_z < a_x) + { + return a_z; + } + else + { + return a_x; + } + } +} + +template +GM_FORCEINLINE TYPE gmMax3(const TYPE a_x, const TYPE a_y, const TYPE a_z) +{ + if(a_y > a_x) + { + if(a_z > a_y) + { + return a_z; + } + else + { + return a_y; + } + } + else + { + if (a_z > a_x) + { + return a_z; + } + else + { + return a_x; + } + } +} + +GM_FORCEINLINE float gmGetFloatOrIntParamAsFloat(gmThread * a_thread, int a_paramIndex) +{ + if(a_thread->ParamType(a_paramIndex) == GM_INT) + { + return (float)a_thread->Param(a_paramIndex).m_value.m_int; + } + else + { + return a_thread->Param(a_paramIndex).m_value.m_float; + } +} + + +GM_FORCEINLINE bool gmGetFloatOrIntParamAsFloat(gmThread * a_thread, int a_paramIndex, float& a_retValue) +{ + if(a_thread->ParamType(a_paramIndex) == GM_INT) + { + a_retValue = (float)a_thread->Param(a_paramIndex).m_value.m_int; + return true; + } + else if(a_thread->ParamType(a_paramIndex) == GM_FLOAT) + { + a_retValue = a_thread->Param(a_paramIndex).m_value.m_float; + return true; + } + else + { + return false; + } +} + +GM_FORCEINLINE int gmGetFloatOrIntParamAsInt(gmThread * a_thread, int a_paramIndex) +{ + if(a_thread->ParamType(a_paramIndex) == GM_INT) + { + return a_thread->Param(a_paramIndex).m_value.m_int; + } + else + { + return (int)a_thread->Param(a_paramIndex).m_value.m_float; + } +} + +GM_FORCEINLINE bool gmGetFloatOrIntParamAsInt(gmThread * a_thread, int a_paramIndex, int& a_retValue) +{ + if(a_thread->ParamType(a_paramIndex) == GM_INT) + { + a_retValue = a_thread->Param(a_paramIndex).m_value.m_int; + return true; + } + else if(a_thread->ParamType(a_paramIndex) == GM_FLOAT) + { + a_retValue = (int)a_thread->Param(a_paramIndex).m_value.m_float; + return true; + } + else + { + return false; + } +} + +/*! + \brief gmRandomInt() returns a random int b/n two values + Beware of overflow since ints are only 32bit on Intel + \return number is >= min and < max (exclusive of max) +*/ +int gmRandomInt(int a_min, int a_max); + +/*! + \brief gmRandomInt() returns a random int b/n two values + Note this is a low precision random value since it is generated from an int. + \return number is >= min and < max (exclusive of max) +*/ +float gmRandomFloat(float a_min, float a_max); + +/*! + \brief Returns the sine and cosine of values + Note should make platform specific version +*/ +GM_FORCEINLINE void gmSinCos(const float a_angle, float& a_sin, float& a_cos) +{ + a_sin = (float)sinf(a_angle); + a_cos = (float)cosf(a_angle); +} + +#endif // _GMHELPERS_H_ diff --git a/vscript/languages/gm/src/binds/gmMathLib.cpp b/vscript/languages/gm/src/binds/gmMathLib.cpp new file mode 100644 index 00000000..cd4ae328 --- /dev/null +++ b/vscript/languages/gm/src/binds/gmMathLib.cpp @@ -0,0 +1,860 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmMathLib.h" +#include "gmThread.h" +#include "gmMachine.h" +#include "gmHelpers.h" +#include "gmUtil.h" +#include + +// Must be last header +#include "memdbgon.h" + + + +// +// Conversion +// + +int GM_CDECL gmfToString(gmThread * a_thread) +{ + const gmVariable * var = a_thread->GetThis(); + + if(GM_INT == var->m_type) + { + char numberAsStringBuffer[64]; + sprintf(numberAsStringBuffer, "%d", var->m_value.m_int); // this won't be > 64 chars + a_thread->PushNewString(numberAsStringBuffer); + } + else if (GM_FLOAT == var->m_type) + { + char numberAsStringBuffer[64]; + + sprintf(numberAsStringBuffer, "%f", var->m_value.m_float); // this won't be > 64 chars + + a_thread->PushNewString(numberAsStringBuffer); + } + else if (GM_STRING == var->m_type) + { + a_thread->PushString( (gmStringObject *) GM_OBJECT(var->m_value.m_ref) ); + } + else + { + return GM_EXCEPTION; + } + + + return GM_OK; +} + + + +int GM_CDECL gmfToFloat(gmThread * a_thread) +{ + const gmVariable * var = a_thread->GetThis(); + + if(GM_INT == var->m_type) + { + a_thread->PushFloat((float)var->m_value.m_int); + } + else if (GM_FLOAT == var->m_type) + { + a_thread->PushFloat(var->m_value.m_float); + } + else if (GM_STRING == var->m_type) + { + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char * cstr = * strObj; + + a_thread->PushFloat( (float)atof(cstr) ); + } + else + { + //a_thread->PushFloat( 0.0f ); + return GM_EXCEPTION; + } + + return GM_OK; +} + + + +int GM_CDECL gmfToInt(gmThread * a_thread) +{ + const gmVariable * var = a_thread->GetThis(); + + if(GM_INT == var->m_type) + { + a_thread->PushInt(var->m_value.m_int); + } + else if (GM_FLOAT == var->m_type) + { + a_thread->PushInt( (int)var->m_value.m_float); + } + else if (GM_STRING == var->m_type) + { + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char * cstr = * strObj; + + a_thread->PushInt( atoi(cstr) ); + } + else + { + //a_thread->PushInt( 0 ); + return GM_EXCEPTION; + } + + return GM_OK; +} + + + +// +// Math +// + + + +// int randint(int a_min, int a_max); +// returned number is >= a_min and < a_max (exclusive of max) +static int GM_CDECL gmfRandInt(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(2); + GM_CHECK_INT_PARAM(min, 0); + GM_CHECK_INT_PARAM(max, 1); + + a_thread->PushInt( gmRandomInt(min, max) ); + + return GM_OK; +} + + + +// float randfloat(float a_min, float a_max); +// returned number is >= a_min and < a_max (exclusive of max) +static int GM_CDECL gmfRandFloat(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(2); + GM_CHECK_FLOAT_PARAM(min, 0); + GM_CHECK_FLOAT_PARAM(max, 1); + + a_thread->PushFloat( gmRandomFloat(min, max) ); + + return GM_OK; +} + + + +// void randseed(int a_seed); +static int GM_CDECL gmfRandSeed(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_INT_PARAM(seed, 0); + + srand(seed); + + return GM_OK; +} + + + +static int GM_CDECL gmfAbs(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + + if(a_thread->ParamType(0) == GM_INT) + { + int intValue = a_thread->Param(0).m_value.m_int; + a_thread->PushInt(abs(intValue)); + + return GM_OK; + } + else if(a_thread->ParamType(0) == GM_FLOAT) + { + float floatValue = a_thread->Param(0).m_value.m_float; + a_thread->PushFloat((float)fabsf(floatValue)); + + return GM_OK; + } + + return GM_EXCEPTION; +} + + + +static int GM_CDECL gmfSqrt(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + + if(a_thread->ParamType(0) == GM_INT) + { + int intValue = a_thread->Param(0).m_value.m_int; + a_thread->PushInt((int)sqrtf((float)intValue)); + + return GM_OK; + } + else if(a_thread->ParamType(0) == GM_FLOAT) + { + float floatValue = a_thread->Param(0).m_value.m_float; + a_thread->PushFloat(sqrtf(floatValue)); + + return GM_OK; + } + + return GM_EXCEPTION; +} + + + +static int GM_CDECL gmfPower(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(2); + + int minType = gmMin(a_thread->ParamType(0), a_thread->ParamType(1)); + if(minType < GM_INT) + { + return GM_EXCEPTION; + } + int maxType = gmMax(a_thread->ParamType(0), a_thread->ParamType(1)); + + if(maxType == GM_INT) + { + int valX = a_thread->Param(0).m_value.m_int; + int valY = a_thread->Param(1).m_value.m_int; + a_thread->PushInt((int)pow((float)valX, (float)valY)); + + return GM_OK; + } + else if(maxType == GM_FLOAT) + { + float valX = gmGetFloatOrIntParamAsFloat(a_thread, 0); + float valY = gmGetFloatOrIntParamAsFloat(a_thread, 1); + a_thread->PushFloat((float)pow(valX, valY)); + + return GM_OK; + } + else + { + return GM_EXCEPTION; + } +} + + + +static int GM_CDECL gmfFloor(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + + if(a_thread->ParamType(0) == GM_INT) //Do nothing if Int + { + int intValue = a_thread->Param(0).m_value.m_int; + a_thread->PushInt(intValue); + + return GM_OK; + } + else if(a_thread->ParamType(0) == GM_FLOAT) + { + float floatValue = a_thread->Param(0).m_value.m_float; + a_thread->PushFloat(floorf(floatValue)); + + return GM_OK; + } + + return GM_EXCEPTION; +} + + + +static int GM_CDECL gmfCeil(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + + if(a_thread->ParamType(0) == GM_INT) //Do nothing if Int + { + int intValue = a_thread->Param(0).m_value.m_int; + a_thread->PushInt(intValue); + + return GM_OK; + } + else if(a_thread->ParamType(0) == GM_FLOAT) + { + float floatValue = a_thread->Param(0).m_value.m_float; + a_thread->PushFloat(ceilf(floatValue)); + + return GM_OK; + } + + return GM_EXCEPTION; +} + + + +static int GM_CDECL gmfRound(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + + if(a_thread->ParamType(0) == GM_INT) //Do nothing if Int + { + int intValue = a_thread->Param(0).m_value.m_int; + a_thread->PushInt(intValue); + + return GM_OK; + } + else if(a_thread->ParamType(0) == GM_FLOAT) + { + float floatValue = a_thread->Param(0).m_value.m_float; + a_thread->PushFloat(floorf(floatValue + 0.5f)); + + return GM_OK; + } + + return GM_EXCEPTION; +} + + + +static int GM_CDECL gmfDegToRad(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + + float floatValue; + + if(a_thread->ParamType(0) == GM_INT) { floatValue = (float) a_thread->Param(0).m_value.m_int; } + else if(a_thread->ParamType(0) == GM_FLOAT) { floatValue = a_thread->Param(0).m_value.m_float; } + else { return GM_EXCEPTION; } + + a_thread->PushFloat( floatValue * (GM_PI_VALUE / 180.0f) ); + + return GM_OK; +} + + + +static int GM_CDECL gmfRadToDeg(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + + float floatValue; + + if(a_thread->ParamType(0) == GM_INT) { floatValue = (float) a_thread->Param(0).m_value.m_int; } + else if(a_thread->ParamType(0) == GM_FLOAT) { floatValue = a_thread->Param(0).m_value.m_float; } + else { return GM_EXCEPTION; } + + a_thread->PushFloat( floatValue * (180.0f / GM_PI_VALUE) ); + + return GM_OK; +} + + + +static int GM_CDECL gmfSin(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + + float floatValue; + + if(a_thread->ParamType(0) == GM_INT) { floatValue = (float) a_thread->Param(0).m_value.m_int; } + else if(a_thread->ParamType(0) == GM_FLOAT) { floatValue = a_thread->Param(0).m_value.m_float; } + else { return GM_EXCEPTION; } + + a_thread->PushFloat(sinf(floatValue)); + + return GM_OK; +} + + + +static int GM_CDECL gmfASin(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + + float floatValue; + + if(a_thread->ParamType(0) == GM_INT) { floatValue = (float) a_thread->Param(0).m_value.m_int; } + else if(a_thread->ParamType(0) == GM_FLOAT) { floatValue = a_thread->Param(0).m_value.m_float; } + else { return GM_EXCEPTION; } + + a_thread->PushFloat(asinf(floatValue)); + + return GM_OK; +} + + + +static int GM_CDECL gmfCos(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + + float floatValue; + + if(a_thread->ParamType(0) == GM_INT) { floatValue = (float) a_thread->Param(0).m_value.m_int; } + else if(a_thread->ParamType(0) == GM_FLOAT) { floatValue = a_thread->Param(0).m_value.m_float; } + else { return GM_EXCEPTION; } + + a_thread->PushFloat(cosf(floatValue)); + + return GM_OK; +} + + + +static int GM_CDECL gmfACos(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + + float floatValue; + + if(a_thread->ParamType(0) == GM_INT) { floatValue = (float) a_thread->Param(0).m_value.m_int; } + else if(a_thread->ParamType(0) == GM_FLOAT) { floatValue = a_thread->Param(0).m_value.m_float; } + else { return GM_EXCEPTION; } + + a_thread->PushFloat(acosf(floatValue)); + + return GM_OK; +} + + + +static int GM_CDECL gmfTan(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + + float floatValue; + + if(a_thread->ParamType(0) == GM_INT) { floatValue = (float) a_thread->Param(0).m_value.m_int; } + else if(a_thread->ParamType(0) == GM_FLOAT) { floatValue = a_thread->Param(0).m_value.m_float; } + else { return GM_EXCEPTION; } + + a_thread->PushFloat(tanf(floatValue)); + + return GM_OK; +} + + + +static int GM_CDECL gmfATan(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + + float floatValue; + + if(a_thread->ParamType(0) == GM_INT) { floatValue = (float) a_thread->Param(0).m_value.m_int; } + else if(a_thread->ParamType(0) == GM_FLOAT) { floatValue = a_thread->Param(0).m_value.m_float; } + else { return GM_EXCEPTION; } + + a_thread->PushFloat(atanf(floatValue)); + + return GM_OK; +} + + + +//returns the arctangent of y/x +static int GM_CDECL gmfATan2(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(2); + + float floatValueY; + float floatValueX; + + if(a_thread->ParamType(0) == GM_INT) {floatValueY = (float) a_thread->Param(0).m_value.m_int;} + else if(a_thread->ParamType(0) == GM_FLOAT) {floatValueY = a_thread->Param(0).m_value.m_float;} + else {return GM_EXCEPTION;} + + if(a_thread->ParamType(1) == GM_INT) {floatValueX = (float) a_thread->Param(1).m_value.m_int;} + else if(a_thread->ParamType(1) == GM_FLOAT) {floatValueX = a_thread->Param(1).m_value.m_float;} + else {return GM_EXCEPTION;} + + a_thread->PushFloat(atan2f(floatValueY, floatValueX)); + + return GM_OK; +} + + + +static int GM_CDECL gmfLog(gmThread * a_thread) +{ + int numParams = GM_THREAD_ARG->GetNumParams(); + + if(numParams == 1) //Natural log + { + if(a_thread->ParamType(0) == GM_INT) + { + float floatValue = (float) a_thread->Param(0).m_value.m_int; + a_thread->PushInt( (int) log(floatValue) ); + return GM_OK; + } + else if(a_thread->ParamType(0) == GM_FLOAT) + { + float floatValue = (float) a_thread->Param(0).m_value.m_float; + + a_thread->PushFloat( logf(floatValue) ); + return GM_OK; + } + else {return GM_EXCEPTION;} + } + else if(numParams == 2) //Log to base params: base, value + { + int minType = gmMin(a_thread->ParamType(0), a_thread->ParamType(1)); + if(minType < GM_INT) + { + return GM_EXCEPTION; + } + int maxType = gmMax(a_thread->ParamType(0), a_thread->ParamType(1)); + + if(maxType == GM_INT) + { + int base = a_thread->Param(0).m_value.m_int; + int value = a_thread->Param(1).m_value.m_int; + + a_thread->PushInt( (int)( log10f((float)value) / log10f((float)base) ) ); + + return GM_OK; + } + else if(maxType == GM_FLOAT) + { + float base = gmGetFloatOrIntParamAsFloat(a_thread, 0); + float value = gmGetFloatOrIntParamAsFloat(a_thread, 1); + + a_thread->PushFloat( (float)( log10(value) / log10(base) ) ); + + return GM_OK; + } + else + { + return GM_EXCEPTION; + } + } + else + { + return GM_EXCEPTION; + } +} + + + +static int GM_CDECL gmfMin(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(2); + + int minType = gmMin(a_thread->ParamType(0), a_thread->ParamType(1)); + if(minType < GM_INT) + { + return GM_EXCEPTION; + } + + int maxType = gmMax(a_thread->ParamType(0), a_thread->ParamType(1)); + + if(maxType == GM_INT) + { + int valX = a_thread->Param(0).m_value.m_int; + int valY = a_thread->Param(1).m_value.m_int; + a_thread->PushInt( gmMin(valX, valY) ); + + return GM_OK; + } + else if(maxType == GM_FLOAT) + { + float valX = gmGetFloatOrIntParamAsFloat(a_thread, 0); + float valY = gmGetFloatOrIntParamAsFloat(a_thread, 1); + a_thread->PushFloat( gmMin(valX, valY) ); + + return GM_OK; + } + else + { + return GM_EXCEPTION; + } +} + + + +static int GM_CDECL gmfMax(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(2); + + int minType = gmMin(a_thread->ParamType(0), a_thread->ParamType(1)); + if(minType < GM_INT) + { + return GM_EXCEPTION; + } + + int maxType = gmMax(a_thread->ParamType(0), a_thread->ParamType(1)); + + if(maxType == GM_INT) + { + int valX = a_thread->Param(0).m_value.m_int; + int valY = a_thread->Param(1).m_value.m_int; + a_thread->PushInt( gmMax(valX, valY) ); + + return GM_OK; + } + else if(maxType == GM_FLOAT) + { + float valX = gmGetFloatOrIntParamAsFloat(a_thread, 0); + float valY = gmGetFloatOrIntParamAsFloat(a_thread, 1); + a_thread->PushFloat( gmMax(valX, valY) ); + + return GM_OK; + } + else + { + return GM_EXCEPTION; + } +} + + + +static int GM_CDECL gmfClamp(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(3); + + //params: min, value, max + + int minType = gmMin3(a_thread->ParamType(0), a_thread->ParamType(1), a_thread->ParamType(2)); + if(minType < GM_INT) + { + return GM_EXCEPTION; + } + + int maxType = gmMax3(a_thread->ParamType(0), a_thread->ParamType(1), a_thread->ParamType(2)); + + if(maxType == GM_INT) + { + int limitMin = a_thread->Param(0).m_value.m_int; + int value = a_thread->Param(1).m_value.m_int; + int limitMax = a_thread->Param(2).m_value.m_int; + + a_thread->PushInt( gmClamp(limitMin, value, limitMax) ); + + return GM_OK; + } + else if(maxType == GM_FLOAT) + { + float limitMin = gmGetFloatOrIntParamAsFloat(a_thread, 0); + float value = gmGetFloatOrIntParamAsFloat(a_thread, 1); + float limitMax = gmGetFloatOrIntParamAsFloat(a_thread, 2); + + a_thread->PushFloat( gmClamp(limitMin, value, limitMax) ); + + return GM_OK; + } + else + { + return GM_EXCEPTION; + } +} + + +// +// Libs and bindings +// + + +static gmFunctionEntry s_mathLib[] = +{ + /*gm + \lib math + */ + /*gm + \function abs + \brief abs will return the absolute value of the passed int \ float + \param int\float + \return int\float abs(param) + */ + {"abs", gmfAbs}, + /*gm + \function sqrt + \brief sqrt will return the square root of the passed int \ float + \param int\float + \return int\float sqrt(param) + */ + {"sqrt", gmfSqrt}, + /*gm + \function sqrt + \brief sqrt will return the square root of the passed int \ float + \param int\float A + \param int\float B + \return int\float A to the power of B + */ + {"power", gmfPower}, + /*gm + \function floor + \brief floor + \param float A + \return float floor(A) + */ + {"floor", gmfFloor}, + /*gm + \function ceil + \brief ceil + \param float A + \return float ceil(A) + */ + {"ceil", gmfCeil}, + /*gm + \function round + \brief round + \param float A + \return float round(A) + */ + {"round", gmfRound}, + /*gm + \function degtorad + \brief degtorad will convert degrees to radians + \param float\int deg + \return float + */ + {"degtorad", gmfDegToRad}, + /*gm + \function radtodeg + \brief radtodeg will convert radians to degrees + \param float\int rad + \return float + */ + {"radtodeg", gmfRadToDeg}, + /*gm + \function cos + \brief cos will return the radian cosine + \param float + \return float + */ + {"cos", gmfCos}, + /*gm + \function sin + \brief sin will return the radian sine + \param float + \return float + */ + {"sin", gmfSin}, + /*gm + \function tan + \brief tan will return the radian tan (sin/cos) + \param float + \return float + */ + {"tan", gmfTan}, + /*gm + \function acos + \brief acos will return the radian arc cosine + \param float + \return float + */ + {"acos", gmfACos}, + /*gm + \function asin + \brief asin will return the radian arc sine + \param float + \return float + */ + {"asin", gmfASin}, + /*gm + \function atan + \brief atan will return the radian arc tangent + \param float + \return float + */ + {"atan", gmfATan}, + /*gm + \function atan + \brief atan will return the radian arc tangent of x / y + \param float x + \param float y + \return float + */ + {"atan2", gmfATan2}, + /*gm + \function log + \brief log will return the natural logarithm of 1 parameter, or (base, value) the logarithm to base + \param float natural \ base + \param float value (optional) + \return float + */ + {"log", gmfLog}, + /*gm + \function min + \brief min will return the min of the 2 passed values + \param float\int A + \param float\int B + \return float \ int min(A, B) + */ + {"min", gmfMin}, + /*gm + \function max + \brief max will return the max of the 2 passed values + \param float\int A + \param float\int B + \return float \ int max(A, B) + */ + {"max", gmfMax}, + /*gm + \function clamp + \brief clamp will return the clamed value. clamp(min, val, max) + \param float\int MIN + \param float\int VALUE + \param float\int MAX + \return float\int value clamped to min, max + */ + {"clamp", gmfClamp}, + /*gm + \function randint + \brief randint will return a random int from lower inclusive to upper. + \param int lower inclusive + \param int upper + \return int + */ +#if 0 // Using Source versions [2/13/2008 tom] + {"randint", gmfRandInt}, + /*gm + \function randfloat + \brief randfloat will return a random float from lower inclusive to upper. + \param float lower inclusive + \param float upper + \return float + */ + {"randfloat", gmfRandFloat}, + /*gm + \function randseed + \brief randseed will seed the random number generator + \param int seed + */ + {"randseed", gmfRandSeed}, +#endif +}; + + + +static gmFunctionEntry s_intLib[] = +{ + {"String", gmfToString}, + {"Float", gmfToFloat}, + {"Int", gmfToInt}, +}; + + + +static gmFunctionEntry s_floatLib[] = +{ + {"String", gmfToString}, + {"Float", gmfToFloat}, + {"Int", gmfToInt}, +}; + + +void gmBindMathLib(gmMachine * a_machine) +{ + a_machine->RegisterLibrary(s_mathLib, sizeof(s_mathLib) / sizeof(s_mathLib[0])); + a_machine->RegisterTypeLibrary(GM_INT, s_intLib, sizeof(s_intLib) / sizeof(s_intLib[0])); + a_machine->RegisterTypeLibrary(GM_FLOAT, s_floatLib, sizeof(s_floatLib) / sizeof(s_floatLib[0])); +} + diff --git a/vscript/languages/gm/src/binds/gmMathLib.h b/vscript/languages/gm/src/binds/gmMathLib.h new file mode 100644 index 00000000..745c72a5 --- /dev/null +++ b/vscript/languages/gm/src/binds/gmMathLib.h @@ -0,0 +1,21 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMMATHLIB_H_ +#define _GMMATHLIB_H_ + +#include "gmConfig.h" + +class gmMachine; + +void gmBindMathLib(gmMachine * a_machine); + +#endif // _GMMATHLIB_H_ diff --git a/vscript/languages/gm/src/binds/gmStringLib.cpp b/vscript/languages/gm/src/binds/gmStringLib.cpp new file mode 100644 index 00000000..cfadc545 --- /dev/null +++ b/vscript/languages/gm/src/binds/gmStringLib.cpp @@ -0,0 +1,1174 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmStringLib.h" +#include "gmThread.h" +#include "gmMachine.h" +#include "gmHelpers.h" + + +// Must be last header +#include "memdbgon.h" + + +// +// String +// + + +#define GM_WHITE_SPACE " \t\v\r\n" + + +static int GM_CDECL gmfStringLeft(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_INT_PARAM(count, 0); + + const gmVariable * var = a_thread->GetThis(); + + GM_ASSERT(var->m_type == GM_STRING); + + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char * str = (const char *) *strObj; + + int length = strObj->GetLength(); + count = gmClamp(0, count, length); + + char * buffer = (char *) alloca(count + 1); + memcpy(buffer, str, count); + buffer[count] = 0; + + a_thread->PushNewString(buffer); + + return GM_OK; +} + + +static int GM_CDECL gmfStringRight(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_INT_PARAM(count, 0); + + const gmVariable * var = a_thread->GetThis(); + + GM_ASSERT(var->m_type == GM_STRING); + + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char * str = (const char *) *strObj; + + int length = strObj->GetLength(); + count = gmClamp(0, count, length); + + char * buffer = (char *) alloca(count + 1); + memcpy(buffer, str + length - count, count); + buffer[count] = 0; + + a_thread->PushNewString(buffer); + + return GM_OK; +} + + +static int GM_CDECL gmfStringRightAt(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_INT_PARAM(index, 0); + + const gmVariable * var = a_thread->GetThis(); + + GM_ASSERT(var->m_type == GM_STRING); + + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char * str = (const char *) *strObj; + + int length = strObj->GetLength(); + index = gmClamp(0, index, length); + int count = (length - index); + char * buffer = (char *) alloca(count + 1); + memcpy(buffer, str + index, count); + buffer[count] = 0; + + a_thread->PushNewString(buffer, count); + + return GM_OK; +} + + +static int GM_CDECL gmfStringMid(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(2); + + int first = 0, count = 0; + + if(!gmGetFloatOrIntParamAsInt(a_thread, 0, first)) {return GM_EXCEPTION;} + if(!gmGetFloatOrIntParamAsInt(a_thread, 1, count)) {return GM_EXCEPTION;} + + const gmVariable * var = a_thread->GetThis(); + + GM_ASSERT(var->m_type == GM_STRING); + + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char * str = (const char *) *strObj; + + int length = strObj->GetLength(); + + //Check bounds + if (first < 0) + { + first = 0; + } + if (count < 0) + { + count = 0; + } + if (first + count > length) + { + count = length - first; + } + if (first > length) + { + count = 0; + } + + char * buffer = (char *) alloca(count + 1); + memcpy(buffer, str + first, count); + buffer[count] = 0; + + a_thread->PushNewString(buffer); + + return GM_OK; +} + + +static int GM_CDECL gmfStringLength(gmThread * a_thread) +{ + const gmVariable * var = a_thread->GetThis(); + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + + a_thread->PushInt(strObj->GetLength()); + + return GM_OK; +} + + +static int GM_CDECL gmfStringIsEmpty(gmThread * a_thread) +{ + const gmVariable * var = a_thread->GetThis(); + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + + a_thread->PushInt( (strObj->GetLength() == 0) ); + + return GM_OK; +} + + +static int GM_CDECL gmfStringCompare(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + + if(a_thread->ParamType(0) == GM_STRING) + { + const gmVariable * var = a_thread->GetThis(); + + GM_ASSERT(var->m_type == GM_STRING); + + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char* thisStr = (const char *) *strObj; + const char* otherStr = a_thread->ParamString(0); + + a_thread->PushInt(strcmp(thisStr, otherStr)); + + return GM_OK; + } + + return GM_EXCEPTION; +} + + +static int GM_CDECL gmfStringCompareNoCase(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + + if(a_thread->ParamType(0) == GM_STRING) + { + const gmVariable * var = a_thread->GetThis(); + + GM_ASSERT(var->m_type == GM_STRING); + + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char* thisStr = (const char *) *strObj; + const char* otherStr = a_thread->ParamString(0); + + a_thread->PushInt(_gmstricmp(thisStr, otherStr)); + + return GM_OK; + } + + return GM_EXCEPTION; +} + + +static int GM_CDECL gmfStringLower(gmThread * a_thread) +{ + const gmVariable * var = a_thread->GetThis(); + + GM_ASSERT(var->m_type == GM_STRING); + + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char * str = (const char *) *strObj; + + int length = strObj->GetLength(); + char * buffer = (char *) alloca(length + 1); + memcpy(buffer, str, length + 1); + + strlwr(buffer); + + a_thread->PushNewString(buffer, length); + + return GM_OK; +} + + +static int GM_CDECL gmfStringUpper(gmThread * a_thread) +{ + const gmVariable * var = a_thread->GetThis(); + + GM_ASSERT(var->m_type == GM_STRING); + + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char * str = (const char *) *strObj; + + int length = strObj->GetLength(); + char * buffer = (char *) alloca(length + 1); + memcpy(buffer, str, length + 1); + + strupr(buffer); + + a_thread->PushNewString(buffer, length); + + return GM_OK; +} + + +static int GM_CDECL gmfStringSpanIncluding(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + + if(a_thread->ParamType(0) == GM_STRING) + { + const gmVariable * var = a_thread->GetThis(); + + GM_ASSERT(var->m_type == GM_STRING); + + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char * thisStr = (const char *) *strObj; + const char * otherStr = a_thread->ParamString(0); + + int offset = strspn(thisStr, otherStr); + char * buffer = (char *) alloca(offset + 1); + memcpy(buffer, thisStr, offset); + buffer[offset] = 0; + + a_thread->PushNewString(buffer, offset); + + return GM_OK; + } + + return GM_EXCEPTION; +} + + +static int GM_CDECL gmfStringSpanExcluding(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + + if(a_thread->ParamType(0) == GM_STRING) + { + const gmVariable * var = a_thread->GetThis(); + + GM_ASSERT(var->m_type == GM_STRING); + + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char * thisStr = (const char *) *strObj; + const char * otherStr = a_thread->ParamString(0); + + int offset = strcspn(thisStr, otherStr); + char * buffer = (char *) alloca(offset + 1); + memcpy(buffer, thisStr, offset); + buffer[offset] = 0; + + a_thread->PushNewString(buffer, offset); + + return GM_OK; + } + + return GM_EXCEPTION; +} + + +// string.AppendPath(a_appendString, a_endWithSlash); +// Append this string with another string, fixing for slashes +// a_endWithSlash is optional, default is false, removing trailing slashes. +static int GM_CDECL gmfStringAppendPath(gmThread * a_thread) +{ + //Need at least 1 parameter + if(a_thread->GetNumParams() < 1) + { + return GM_EXCEPTION; + } + + //Optional trailing slash flag + int PutTrailingSlash = a_thread->ParamInt(1, false); + + if(a_thread->ParamType(0) == GM_STRING) + { + const gmVariable * varA = a_thread->GetThis(); + + GM_ASSERT(varA->m_type == GM_STRING); + + gmStringObject * strObjA = (gmStringObject *) GM_OBJECT(varA->m_value.m_ref); + gmStringObject * strObjB = a_thread->ParamStringObject(0); + const char* cStrA = strObjA->GetString(); + const char* cStrB = strObjB->GetString(); + int lenA = strObjA->GetLength(); + int lenB = strObjB->GetLength(); + + int curLength = lenA; + int appLength = lenB; + + //Alloc buffer on stack is fine, path strings cannot be long + char * buffer = (char *) alloca(curLength + appLength + 2); + + if(lenA > 0) + { + memcpy(buffer, cStrA, lenA); + + + //Make sure first part has a slash + if(buffer[curLength-1] != '\\' && buffer[curLength-1] != '/') + { + buffer[curLength] = '\\'; + curLength += 1; + } + } + + if(lenB > 0) + { + //Remove slash from start of append string + const char* startOfAppend = cStrB; + if((startOfAppend[0] == '\\') || (startOfAppend[0] == '/')) + { + startOfAppend += 1; + appLength -= 1; + } + + //Append the string + memcpy(&buffer[curLength], startOfAppend, appLength); + } + + int newLength = curLength + appLength; + + if(PutTrailingSlash && (newLength > 0)) //Only add slash if string is not empty + { + //Make sure path ends with slash + if(buffer[newLength-1] != '\\' && buffer[newLength-1] != '/') + { + buffer[newLength] = '\\'; + newLength += 1; + } + } + else + { + //Make sure path does not end with slash + if(buffer[newLength-1] == '\\' || buffer[newLength-1] == '/') + { + newLength -= 1; + } + } + + //Make sure it is terminated + buffer[newLength] = 0; + + a_thread->PushNewString(buffer, newLength); + + return GM_OK; + } + + return GM_EXCEPTION; +} + + +// string.RemoveInvalidChars(a_replaceChar, a_invalidSet) +// eg. "File Name#1.tga".RemoveInvalidChars("_","# ") returns "File_Name_1.tga" +// Note: Parameters are optional. +static int GM_CDECL gmfStringReplaceCharsInSet(gmThread * a_thread) +{ + GM_INT_PARAM(repCharInt, 0, '_'); + GM_STRING_PARAM(invalidCharSet, 1, " \\/:-+"); + + char repChar = (char)repCharInt; //Convert full int to char + const gmVariable * varA = a_thread->GetThis(); + + GM_ASSERT(varA->m_type == GM_STRING); + + gmStringObject * strObjA = (gmStringObject *) GM_OBJECT(varA->m_value.m_ref); + const char* cStrA = strObjA->GetString(); + int lenA = strObjA->GetLength(); + + //Alloc buffer on stack is fine, path strings cannot be long + char * buffer = (char *) alloca(lenA + 1); + memcpy(buffer, cStrA, lenA + 1); + + int validPos; + + //Check that replacement char is NOT in invalid set, otherwise endless loop... + if(strchr(invalidCharSet, repChar)) + { + return GM_EXCEPTION; + } + + for(;;) + { + validPos = strcspn(buffer, invalidCharSet); + if(validPos != lenA) + { + buffer[validPos] = repChar; + } + else + { + break; + } + } + + a_thread->PushNewString(buffer, lenA); + + return GM_OK; +} + + +// string.AppendPath(a_appendString, a_endWithSlash); +// Append this string with another string, fixing for slashes +// a_endWithSlash is optional, default is false, removing trailing slashes. +static void GM_CDECL gmStringOpAppendPath(gmThread * a_thread, gmVariable * a_operands) +{ + // Both types must be strings + if(a_operands[0].m_type != GM_STRING || + a_operands[1].m_type != GM_STRING) + { + a_operands[0].m_type = GM_NULL; + a_operands[0].m_value.m_ref = 0; + return; + } + + gmStringObject * strObjA = (gmStringObject *) GM_OBJECT(a_operands[0].m_value.m_ref); + gmStringObject * strObjB = (gmStringObject *) GM_OBJECT(a_operands[1].m_value.m_ref); + const char* cStrA = strObjA->GetString(); + const char* cStrB = strObjB->GetString(); + int lenA = strObjA->GetLength(); + int lenB = strObjB->GetLength(); + + int curLength = lenA; + int appLength = lenB; + + //Alloc buffer on stack is fine, path strings cannot be long + char * buffer = (char *) alloca(curLength + appLength + 2); + + if(lenA <= 0) + { + a_operands[0] = a_operands[1]; + } + + if(lenB <= 0) + { + return; + } + + memcpy(buffer, cStrA, lenA); + + //Make sure first part has a slash + if(buffer[curLength-1] != '\\' && buffer[curLength-1] != '/') + { + buffer[curLength] = '\\'; + curLength += 1; + } + + //Remove slash from start of append string + const char* startOfAppend = cStrB; + if((startOfAppend[0] == '\\') || (startOfAppend[0] == '/')) + { + startOfAppend += 1; + appLength -= 1; + } + + //Append the string + memcpy(&buffer[curLength], startOfAppend, appLength); + + int newLength = curLength + appLength; + + //Make sure it is terminated + buffer[newLength] = 0; + + a_operands[0].m_type = GM_STRING; + a_operands[0].m_value.m_ref = a_thread->GetMachine()->AllocStringObject(buffer, newLength)->GetRef(); +} + + +// int string.Find(char/string a_charOrStringToFind, int a_startOffset == 0); +// Find a character or character string in a string. +// Returns character offset or -1 if not found. +static int GM_CDECL gmStringFind(gmThread * a_thread) +{ + int numParams = GM_THREAD_ARG->GetNumParams(); + int startOffset = 0; + char* retCharPtr = NULL; + const gmVariable * var = a_thread->GetThis(); + GM_ASSERT(var->m_type == GM_STRING); + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char* thisStr = (const char *) *strObj; + + if(numParams == 2) + { + if(a_thread->ParamType(1) == GM_INT) + { + startOffset = a_thread->ParamInt(1); //Optional start offset param + } + else + { + return GM_EXCEPTION; + } + } + else if(numParams < 1 || numParams > 2) + { + return GM_EXCEPTION; + } + + //Check if this string is empty, or start offset out of range + if( (strObj->GetLength() == 0) || + (startOffset > strObj->GetLength()) || + (startOffset < 0) + ) + { + a_thread->PushInt( -1 ); //return Not Found + return GM_OK; + } + + if(a_thread->ParamType(0) == GM_INT) + { + const char otherChar = (char)a_thread->ParamInt(0); + + //Find character + retCharPtr = (char*)strchr(thisStr + startOffset, otherChar); + } + else if(a_thread->ParamType(0) == GM_STRING) + { + const char* otherStr = a_thread->ParamString(0); + + //Find string + retCharPtr = (char*)strstr(thisStr + startOffset, otherStr); + } + else + { + return GM_EXCEPTION; + } + + // return -1 for not found, distance from beginning otherwise + int retOffset = (retCharPtr == NULL) ? -1 : (int)(retCharPtr - thisStr); + a_thread->PushInt(retOffset); + + return GM_OK; +} + + +static int GM_CDECL gmStringReverse(gmThread * a_thread) +{ + const gmVariable * var = a_thread->GetThis(); + GM_ASSERT(var->m_type == GM_STRING); + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char * str = (const char *) *strObj; + + int len = strlen(str); + if(len > 0) + { + char * buffer = (char *) alloca(len + 1); + memcpy(buffer, str, len + 1); //Copy old string + + while(len--) + { + buffer[len] = *(str++); + } + + a_thread->PushNewString(buffer); + } + return GM_OK; +} + + +// int string.ReverseFind(char/string a_charOrStringToFind); +// Find the last instance of a specific character in a string. +// Returns character offset or -1 if not found. +static int GM_CDECL gmStringReverseFind(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + + const char* retCharPtr = NULL; + const gmVariable * var = a_thread->GetThis(); + GM_ASSERT(var->m_type == GM_STRING); + gmStringObject * thisStrObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char* thisStr = (const char *) *thisStrObj; + + if(a_thread->ParamType(0) == GM_INT) + { + const char otherChar = (char)a_thread->ParamInt(0); + + //Find character + retCharPtr = strrchr(thisStr, otherChar); + } + else if(a_thread->ParamType(0) == GM_STRING) + { + gmStringObject * otherStrObj = a_thread->ParamStringObject(0); + const char* otherStr = a_thread->ParamString(0); + + //Find string + const char* lastFoundPtr = NULL; + const char* newTestPtr = NULL; + const char* curTestPtr = thisStr; + const char* endThisStr = thisStr + thisStrObj->GetLength(); + int searchStrLength = otherStrObj->GetLength(); + + //Search through string for last occurence + //Not very efficient, but very rarely used. + for(;;) + { + newTestPtr = strstr(curTestPtr, otherStr); + if(!newTestPtr) + { + break; + } + lastFoundPtr = newTestPtr; + curTestPtr = newTestPtr + searchStrLength; + if(curTestPtr > endThisStr) + { + break; + } + }; + + retCharPtr = lastFoundPtr; + } + else + { + return GM_EXCEPTION; + } + + // return -1 for not found, distance from beginning otherwise + int retOffset = (retCharPtr == NULL) ? -1 : (int)(retCharPtr - thisStr); + a_thread->PushInt(retOffset); + + return GM_OK; +} + + +// int string[int index] +// Note: Because strings are constant and in a table, it is impossible to implement SetInd. +static void GM_CDECL gmStringOpGetInd(gmThread * a_thread, gmVariable * a_operands) +{ + if( a_operands[0].m_type != GM_STRING || + a_operands[1].m_type != GM_INT ) + { + a_operands->Nullify(); + return; + } + + gmStringObject * strObjA = (gmStringObject *) GM_OBJECT(a_operands[0].m_value.m_ref); + const char* cStrA = strObjA->GetString(); + int index = a_operands[1].m_value.m_int; + + if( index < 0 || index > strObjA->GetLength()-1 ) + { + a_operands->Nullify(); + } + else + { + a_operands->SetInt( (int)cStrA[index] ); + } +} + +// int string.GetAt(int a_index); +// Returns character at offset or null if index out of range. +static int GM_CDECL gmStringGetAt(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_INT_PARAM(index, 0); + + const gmVariable * var = a_thread->GetThis(); + + GM_ASSERT(var->m_type == GM_STRING); + + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char * str = (const char *) *strObj; + + if(index < 0 || index >= strObj->GetLength()) + { + a_thread->PushNull(); //Return null if index out of range + return GM_OK; + } + + a_thread->PushInt(str[index]); + return GM_OK; +} + + +// string string.SetAt(int a_index, int a_char); +// Returns string with modified character at offset, or original string if index out of range. +static int GM_CDECL gmStringSetAt(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_INT_PARAM(index, 0); + GM_CHECK_INT_PARAM(newChar, 1); + + const gmVariable * var = a_thread->GetThis(); + + GM_ASSERT(var->m_type == GM_STRING); + + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char * str = (const char *) *strObj; + int strLength = strObj->GetLength(); + + if(index < 0 || index >= strLength) + { + a_thread->PushString(strObj); //Return original string if index out of range + return GM_OK; + } + + char * buffer = (char *) alloca(strLength + 1); + memcpy(buffer, str, strLength + 1); //Copy old string + buffer[index] = (char)newChar; //Set character in string + + a_thread->PushNewString(buffer, strLength); + return GM_OK; +} + + +static int GM_CDECL gmStringTrimLeft(gmThread * a_thread) +{ + GM_STRING_PARAM(trim, 0, GM_WHITE_SPACE); + + const gmVariable * var = a_thread->GetThis(); + GM_ASSERT(var->m_type == GM_STRING); + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char * str = (const char *) *strObj; + if(strlen(str) > 0) + { + while(*str && strchr(trim, *str)) + ++str; + a_thread->PushNewString(str); + } + else + a_thread->PushString(strObj); + return GM_OK; +} + + +static int GM_CDECL gmStringTrimRight(gmThread * a_thread) +{ + GM_STRING_PARAM(trim, 0, GM_WHITE_SPACE); + + const gmVariable * var = a_thread->GetThis(); + GM_ASSERT(var->m_type == GM_STRING); + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char * str = (const char *) *strObj; + int strLength = strObj->GetLength(); + if(strLength > 0) + { + char * buffer = (char *) alloca(strLength + 1); + memcpy(buffer, str, strLength + 1); //Copy old string + + // Find beginning of trailing matches by starting at end + char *lpsz = buffer + strLength; + while (--lpsz >= buffer && strchr(trim, *lpsz) != NULL) {} + ++lpsz; + *lpsz = '\0'; + + a_thread->PushNewString(buffer); + } + else + { + a_thread->PushString(strObj); + } + return GM_OK; +} + + +static int GM_CDECL gmStringGetFilenameNoExt(gmThread * a_thread) +{ + const gmVariable * var = a_thread->GetThis(); + GM_ASSERT(var->m_type == GM_STRING); + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char * str = (const char *) *strObj; + int strLength = strObj->GetLength(); + + char * buffer = (char *) alloca(strLength + 1); + memcpy(buffer, str, strLength + 1); //Copy old string + + char *lpsz = buffer + strLength; + while (--lpsz >= buffer && *lpsz != '\\' && *lpsz != '/') {} + + buffer = ++lpsz; + strLength = strlen(buffer); + lpsz = buffer + strLength; + while (--lpsz >= buffer && *lpsz != '.') {} + if(*lpsz == '.') *lpsz = 0; + + a_thread->PushNewString(buffer); + return GM_OK; +} + + +static int GM_CDECL gmStringGetFilename(gmThread * a_thread) +{ + const gmVariable * var = a_thread->GetThis(); + GM_ASSERT(var->m_type == GM_STRING); + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char * str = (const char *) *strObj; + int strLength = strObj->GetLength(); + + const char *lpsz = str + strLength; + while (--lpsz >= str && *lpsz != '\\' && *lpsz != '/') {} + ++lpsz; + + a_thread->PushNewString(lpsz); + return GM_OK; +} + + +static int GM_CDECL gmStringGetExtension(gmThread * a_thread) +{ + GM_INT_PARAM(keepDot, 0, 0); + + const gmVariable * var = a_thread->GetThis(); + GM_ASSERT(var->m_type == GM_STRING); + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char * str = (const char *) *strObj; + int strLength = strObj->GetLength(); + + const char *lpsz = str + strLength; + while (--lpsz >= str && *lpsz != '.') {} + + if(*lpsz == '.') + { + if(!keepDot) + { + ++lpsz; + } + a_thread->PushNewString(lpsz); + } + else + { + a_thread->PushNewString(""); + } + return GM_OK; +} + + +static int GM_CDECL gmStringSetExtension(gmThread * a_thread) +{ + GM_STRING_PARAM(newExt, 0, ""); + + const gmVariable * var = a_thread->GetThis(); + GM_ASSERT(var->m_type == GM_STRING); + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + + const char * str = (const char *) *strObj; + int strLength = strObj->GetLength(); + int extLength = strlen(newExt); + + if (extLength && newExt[0] == '.') + { + ++newExt; + extLength = strlen(newExt); + } + + char *buffer = (char *) alloca(strLength + 1 + extLength); + memcpy(buffer, str, strLength + 1); + + char *lpsz = buffer + strLength; + while (--lpsz >= buffer && *lpsz != '.') {} + + if(*lpsz == '.') + { + *lpsz = '\0'; + if (extLength) + sprintf(buffer, "%s.%s", buffer, newExt); + + } + else if (extLength) + { + sprintf(buffer, "%s.%s", buffer, newExt); + } + + a_thread->PushNewString(buffer); + return GM_OK; +} + + +static int GM_CDECL gmStringGetPath(gmThread * a_thread) +{ + GM_INT_PARAM(keepSlash, 0, 0); + + const gmVariable * var = a_thread->GetThis(); + GM_ASSERT(var->m_type == GM_STRING); + gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); + const char * str = (const char *) *strObj; + int strLength = strObj->GetLength(); + + char * buffer = (char *) alloca(strLength + 1); + memcpy(buffer, str, strLength + 1); //Copy old string + + char *lpsz = buffer + strLength; + while (--lpsz >= buffer && *lpsz != '\\' && *lpsz != '/') {} + + if(*lpsz == '\\' || *lpsz == '/') + { + if(keepSlash) + lpsz[1] = 0; + else + lpsz[0] = 0; + a_thread->PushNewString(buffer); + } + else + { + a_thread->PushNewString(""); + } + return GM_OK; +} + +extern int GM_CDECL gmfToInt(gmThread * a_thread); +extern int GM_CDECL gmfToFloat(gmThread * a_thread); +extern int GM_CDECL gmfToString(gmThread * a_thread); + +static gmFunctionEntry s_stringLib[] = +{ + /*gm + \lib string + \brief string operations often store a copy of the string on the stack, so keep string sizes reasonable + */ + /*gm + \function IsEmpty + \brief IsEmpty will test to see if the string is 0 length + \return non-zero if the string is empty + */ + {"IsEmpty", gmfStringIsEmpty}, + /*gm + \function Length + \brief Length will return the length of the string not including the null terminating character + \return int length + */ + {"Length", gmfStringLength}, + /*gm + \function Left + \brief Left will return the left count charaters of the string + \param int count + \return string + */ + {"Left", gmfStringLeft}, + /*gm + \function Right + \brief Right will return the right count charaters of the string + \param int count + \return string + */ + {"Right", gmfStringRight}, + /*gm + \function RightAt + \brief RightAt will return the charaters right of and including the given index + \param int index + \return string + */ + {"RightAt", gmfStringRightAt}, + /*gm + \function Mid + \brief Mid will return count characters from the start index + \param int startIndex + \param int count + \return string + */ + {"Mid", gmfStringMid}, + /*gm + \function Compare + \brief Compare will perform a string compare + \param string to compare + \return -1 if the this < compare string, 0 if the strings are equal, 1 otherwise + */ + {"Compare", gmfStringCompare}, + /*gm + \function CompareNoCase + \brief CompareNoCase will perform a string compare (case insensitive) + \param string to compare + \return -1 if the this < compare string, 0 if the strings are equal, 1 otherwise + */ + {"CompareNoCase", gmfStringCompareNoCase}, + /*gm + \function Int + \brief Int will return the int value of the string + \return int value + */ + {"Int", gmfToInt}, + /*gm + \function Float + \brief Float will return the float value of the string + \return float value + */ + {"Float", gmfToFloat}, + /*gm + \function String + \return string + */ + {"String", gmfToString}, + /*gm + \function Upper + \brief Upper will return the string as uppercase + \return string + */ + {"Upper", gmfStringUpper}, + /*gm + \function Lower + \brief Lower will return the string as lowercase + \return string + */ + {"Lower", gmfStringLower}, + /*gm + \function SpanIncluding + \brief SpanIncluding will return this string while characters are within the passed string + \param string charset + \return string + */ + {"SpanIncluding", gmfStringSpanIncluding}, + /*gm + \function SpanExcluding + \brief SpanExcluding will return this string while characters are not within the passed string + \param string charset + \return string + */ + {"SpanExcluding", gmfStringSpanExcluding}, + /*gm + \function AppendPath + \brief AppendPath will append a path make sure one '\' is maintained + \param string path to append + \return string + */ + {"AppendPath", gmfStringAppendPath}, + /*gm + \function ReplaceCharsInSet + \brief ReplaceCharsInSet will replace all chars in this that are within the charset with the given int char + \param int char to replace with + \param string charset of chars to replace + \return string + */ + {"ReplaceCharsInSet", gmfStringReplaceCharsInSet}, + /*gm + \function Find + \brief Find will find the first occurance of the passed string within this string + \param string search string + \param int start index optional (0) + \return int index of first occurance, or -1 if the string was not found + */ + {"Find", gmStringFind}, + /*gm + \function Reverse + \brief Reverse characters of a string + \return string + */ + {"Reverse", gmStringReverse}, + /*gm + \function ReverseFind + \brief ReverseFind will find the first occurance of the passed string within this string starting from the right + \param string search string + \return int index of first occurance, or -1 if the string was not found + */ + {"ReverseFind", gmStringReverseFind}, + /*gm + \function GetAt + \brief GetAt will return the char at the given index + \param int index + \return int char, or null if index was out of range + */ + {"GetAt", gmStringGetAt}, + /*gm + \function SetAt + \brief SetAt will return the string with the character set at the given position + \param int index + \param int char + \return string + */ + {"SetAt", gmStringSetAt}, + /*gm + \function TrimLeft + \brief TrimLeft will return the string with the chars from the passed char set trimmed from the left + \param string charset optional (" \r\n\v\t") + \return string + */ + {"TrimLeft", gmStringTrimLeft}, + /*gm + \function TrimRight + \brief TrimRight will return the string with the chars from the passed char set trimmed from the right + \param string charset optional (" \r\n\v\t") + \return string + */ + {"TrimRight", gmStringTrimRight}, + + /*gm + \function GetFilenameNoExt + \brief GetFilenameNoExt will return the filename part of a path string + \return string + */ + {"GetFilenameNoExt", gmStringGetFilenameNoExt}, + /*gm + \function GetFilename + \brief GetFilename will return the filename part of a path string incl. extension + \return string + */ + {"GetFilename", gmStringGetFilename}, + /*gm + \function GetExtension + \brief GetExtension will return the file extension + \param int inclDot optional (0) 1 will include '.', 0 won't + \return string + */ + {"GetExtension", gmStringGetExtension}, + /*gm + \function SetExtension + \brief SetExtension returns a string with the extension change to the given one. + \param string ext optional (null) the new extension, with or without the dot. null to remove extension. + \return string + */ + {"SetExtension", gmStringSetExtension}, + /*gm + \function GetPath + \brief GetPath will return the file path from a path string + \param int inclSlash optional (0) will include a '\' on the end of the path + \return string + */ + {"GetPath", gmStringGetPath}, +/* + {"Insert", }, //int Insert(int index, char/string) + {"Delete", }, //int Delete(int index, int count=1) + {"Replace", }, //int Replace(char/string,char/string) + {"Scan", }, +*/ +}; + +void gmBindStringLib(gmMachine * a_machine) +{ + a_machine->RegisterTypeOperator(GM_STRING, O_BIT_XOR, NULL, gmStringOpAppendPath); + a_machine->RegisterTypeOperator(GM_STRING, O_GETIND, NULL, gmStringOpGetInd); + a_machine->RegisterTypeLibrary(GM_STRING, s_stringLib, sizeof(s_stringLib) / sizeof(s_stringLib[0])); +} + diff --git a/vscript/languages/gm/src/binds/gmStringLib.h b/vscript/languages/gm/src/binds/gmStringLib.h new file mode 100644 index 00000000..15796612 --- /dev/null +++ b/vscript/languages/gm/src/binds/gmStringLib.h @@ -0,0 +1,21 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMSTRINGLIB_H_ +#define _GMSTRINGLIB_H_ + +#include "gmConfig.h" + +class gmMachine; + +void gmBindStringLib(gmMachine * a_machine); + +#endif // _GMSTRINGLIB_H_ diff --git a/vscript/languages/gm/src/binds/gmSystemLib.cpp b/vscript/languages/gm/src/binds/gmSystemLib.cpp new file mode 100644 index 00000000..699a6c40 --- /dev/null +++ b/vscript/languages/gm/src/binds/gmSystemLib.cpp @@ -0,0 +1,986 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmSystemLib.h" +#include "gmThread.h" +#include "gmMachine.h" +#include "gmHelpers.h" + +#if GM_SYSTEM_LIB + +#include +#include +#include +#include +#include +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include + + +#undef GetObject + +// +// +// system functions +// +// + +extern void gmConcat(gmMachine * a_machine, char * &a_dst, int &a_len, int &a_size, const char * a_src, int a_growBy = 32); + + +static int GM_CDECL gmfSystem(gmThread * a_thread) +{ + const int bufferSize = 256; + int len = 0, size = 0, i, ret = -1; + char * str = NULL, buffer[bufferSize]; + + // build the string + for(i = 0; i < a_thread->GetNumParams(); ++i) + { + gmConcat(a_thread->GetMachine(), str, len, size, a_thread->Param(i).AsString(a_thread->GetMachine(), buffer, bufferSize), 64); + + if(str) + { + GM_ASSERT(len < size); + str[len++] = ' '; + str[len] = '\0'; + } + } + + // print the string + if(str) + { + ret = system(str); + a_thread->GetMachine()->Sys_Free(str); + } + + a_thread->PushInt(ret); + + return GM_OK; +} + +static int GM_CDECL gmfDoFile(gmThread * a_thread) // filename, now (1), return thread id, null on error, exception on compile error. +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_STRING_PARAM(filename, 0); + GM_INT_PARAM(now, 1, 1); + gmVariable paramThis = a_thread->Param(2, gmVariable::s_null); // 3rd param is 'this' + + int id = GM_INVALID_THREAD; + if(filename) + { + char * string = NULL; + + FILE * fp = fopen(filename, "rb"); + if(fp) + { + fseek(fp, 0, SEEK_END); + int size = ftell(fp); + rewind(fp); + string = new char[size + 1]; + fread(string, 1, size, fp); + string[size] = 0; + fclose(fp); + } + else + { + GM_EXCEPTION_MSG("failed to open file '%s'", filename); + return GM_EXCEPTION; + } + if(string == NULL) return GM_OK; + + int errors = a_thread->GetMachine()->ExecuteString(string, &id, (now) ? true : false, filename, ¶mThis); + delete[] string; + if(errors) + { + return GM_EXCEPTION; + } + else + { + a_thread->PushInt(id); + } + } + return GM_OK; +} + +// +// +// Implementation of ansi file binding +// +// + +static gmType s_gmFileType = GM_NULL; + +static int GM_CDECL gmfFile(gmThread * a_thread) +{ + a_thread->PushNewUser(NULL, s_gmFileType); + return GM_OK; +} + +static int GM_CDECL gmfFileExists(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_STRING_PARAM(filename, 0); + + FILE * fp = fopen(filename, "rb"); + if(fp) + { + a_thread->PushInt(1); + fclose(fp); + return GM_OK; + } + a_thread->PushInt(0); + return GM_OK; +} + +static int GM_CDECL gmfFileOpen(gmThread * a_thread) // path, readonly(true), return 1 on success. +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_STRING_PARAM(filename, 0); + GM_INT_PARAM(readonly, 1, 1); + + gmUserObject * fileObject = a_thread->ThisUserObject(); + GM_ASSERT(fileObject->m_userType == s_gmFileType); + if(fileObject->m_user) fclose((FILE *) fileObject->m_user); + fileObject->m_user = (void *) fopen(filename, (readonly) ? "rb" : "wb"); + if(fileObject->m_user) a_thread->PushInt(1); + else a_thread->PushInt(0); + return GM_OK; +} + +static int GM_CDECL gmfFileOpenText(gmThread * a_thread) // path, readonly(true), return 1 on success. +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_STRING_PARAM(filename, 0); + GM_INT_PARAM(readonly, 1, 1); + + gmUserObject * fileObject = a_thread->ThisUserObject(); + GM_ASSERT(fileObject->m_userType == s_gmFileType); + if(fileObject->m_user) fclose((FILE *) fileObject->m_user); + fileObject->m_user = (void *) fopen(filename, (readonly) ? "r" : "w"); + if(fileObject->m_user) a_thread->PushInt(1); + else a_thread->PushInt(0); + return GM_OK; +} + +static int GM_CDECL gmfFileClose(gmThread * a_thread) +{ + gmUserObject * fileObject = a_thread->ThisUserObject(); + GM_ASSERT(fileObject->m_userType == s_gmFileType); + if(fileObject->m_user) fclose((FILE *) fileObject->m_user); + fileObject->m_user = NULL; + return GM_OK; +} + +static int GM_CDECL gmfFileIsOpen(gmThread * a_thread) // return 1 if open, else 0 +{ + gmUserObject * fileObject = a_thread->ThisUserObject(); + GM_ASSERT(fileObject->m_userType == s_gmFileType); + a_thread->PushInt((fileObject->m_user) ? 1 : 0); + return GM_OK; +} + + +static void GM_CDECL gmFileOpGetDot(gmThread * a_thread, gmVariable * a_operands) +{ + gmUserObject * user = (gmUserObject *) GM_OBJECT(a_operands->m_value.m_ref); + if(user && user->m_user) + { + gmStringObject * member = (gmStringObject *) GM_OBJECT(a_operands[1].m_value.m_ref); + + GM_ASSERT(sizeof(gmptr) == sizeof(time_t)); + + if(strcmp(member->GetString(), "SEEK_CUR") == 0) + a_operands->SetInt(SEEK_CUR); + else if(strcmp(member->GetString(), "SEEK_END") == 0) + a_operands->SetInt(SEEK_END); + else if(strcmp(member->GetString(), "SEEK_SET") == 0) + a_operands->SetInt(SEEK_SET); + else + { + a_operands->Nullify(); + return; + } + return; + } + a_operands->Nullify(); +} + + +static int GM_CDECL gmfFileSeek(gmThread * a_thread) // return false on error +{ + gmUserObject * fileObject = a_thread->ThisUserObject(); + GM_ASSERT(fileObject->m_userType == s_gmFileType); + + GM_CHECK_NUM_PARAMS(2); + GM_CHECK_INT_PARAM(offset, 0); + GM_CHECK_INT_PARAM(origin, 1); + + if( origin != SEEK_CUR + && origin != SEEK_END + && origin != SEEK_SET ) + { + return GM_EXCEPTION; + } + + int result = fseek((FILE*)fileObject->m_user, offset, origin); + if(result != 0) + { + a_thread->PushInt(false); + } + a_thread->PushInt(true); + + return GM_OK; +} + +static int GM_CDECL gmfFileTell(gmThread * a_thread) // return -1 on error, else file pos. +{ + gmUserObject * fileObject = a_thread->ThisUserObject(); + GM_ASSERT(fileObject->m_userType == s_gmFileType); + long pos = -1; + if(fileObject->m_user) pos = ftell((FILE *) fileObject->m_user); + a_thread->PushInt(pos); + return GM_OK; +} + +static int GM_CDECL gmfFileReadLine(gmThread * a_thread) // flag keep \n (0), return string, or null on eof +{ + GM_INT_PARAM(keepLF, 0, 0); + const int len = GM_SYSTEM_LIB_MAX_LINE; + char buffer[len]; + gmUserObject * fileObject = a_thread->ThisUserObject(); + GM_ASSERT(fileObject->m_userType == s_gmFileType); + if(fileObject->m_user) + { + char * str = fgets(buffer, len, (FILE *) fileObject->m_user); + if(str) + { + int slen = strlen(str); + if(!keepLF) + { + if(!feof((FILE *) fileObject->m_user)) + str[--slen] = '\0'; + } + a_thread->PushNewString(str, slen); + } + } + return GM_OK; +} + +static int GM_CDECL gmfFileReadChar(gmThread * a_thread) // return int, return NULL on eof, or on error +{ + gmUserObject * fileObject = a_thread->ThisUserObject(); + GM_ASSERT(fileObject->m_userType == s_gmFileType); + if(fileObject->m_user) + { + int c = fgetc((FILE*) fileObject->m_user); + if(c != EOF) a_thread->PushInt(c); + } + return GM_OK; +} + +static int GM_CDECL gmfFileWriteChar(gmThread * a_thread) // int, return char written, or NULL on error +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_INT_PARAM(c, 0); + + gmUserObject * fileObject = a_thread->ThisUserObject(); + GM_ASSERT(fileObject->m_userType == s_gmFileType); + if(fileObject->m_user) + { + int r = fputc(c, (FILE *) fileObject->m_user); + if(r != EOF) a_thread->PushInt(r); + } + return GM_OK; +} + +static int GM_CDECL gmfFileWriteString(gmThread * a_thread) // string, return 1 on success, or NULL on error +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_STRING_PARAM(s, 0); + + gmUserObject * fileObject = a_thread->ThisUserObject(); + GM_ASSERT(fileObject->m_userType == s_gmFileType); + if(fileObject->m_user) + { + if(fputs(s, (FILE *) fileObject->m_user) != EOF) a_thread->PushInt(1); + } + return GM_OK; +} + +#if GM_USE_INCGC +static void GM_CDECL gmGCDestructFileUserType(gmMachine * a_machine, gmUserObject* a_object) +{ + if(a_object->m_user) fclose((FILE *) a_object->m_user); + a_object->m_user = NULL; +} +#else //GM_USE_INCGC +static void GM_CDECL gmGCFileUserType(gmMachine * a_machine, gmUserObject * a_object, gmuint32 a_mark) +{ + if(a_object->m_user) fclose((FILE *) a_object->m_user); + a_object->m_user = NULL; +} +#endif //GM_USE_INCGC + +// +// +// File Find user type +// +// + +static gmType s_gmFileFindType = GM_NULL; + +struct gmFileFindUser +{ + WIN32_FIND_DATA m_findData; + HANDLE m_iterator; +}; + +// +// +// File Info user type +// +// + +static gmType s_gmFileInfoType = GM_NULL; + +struct gmFileInfoUser +{ + time_t m_accessedTime; // last access time + time_t m_creationTime; // creation time + time_t m_modifiedTime; // last modify time + unsigned int m_size; // size +}; + +// +// +// System lib +// +// + +static int GM_CDECL gmfFindFirstFile(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_STRING_PARAM(filename, 0); + + gmFileFindUser * fileFind = (gmFileFindUser *) a_thread->GetMachine()->Sys_Alloc(sizeof(gmFileFindUser)); + fileFind->m_iterator = FindFirstFile(filename, &fileFind->m_findData); + + if(fileFind->m_iterator == INVALID_HANDLE_VALUE) + { + a_thread->GetMachine()->Sys_Free(fileFind); + return GM_OK; + } + + a_thread->PushNewUser(fileFind, s_gmFileFindType); + return GM_OK; +} + + +static int GM_CDECL gmfFindNextFile(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + + if(a_thread->ParamType(0) == s_gmFileFindType) + { + gmFileFindUser * fileFind = (gmFileFindUser *) a_thread->ParamUser(0); + if(fileFind && fileFind->m_iterator != INVALID_HANDLE_VALUE) + { + if(FindNextFile(fileFind->m_iterator, &fileFind->m_findData)) + { + a_thread->PushUser(a_thread->ParamUserObject(0)); + } + } + } + return GM_OK; +} + + +static int GM_CDECL gmfFileInfo(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_STRING_PARAM(filename, 0); + + struct _stat buf; + int fh, result; + + if((fh = _open(filename, _O_RDONLY)) == -1) return GM_OK; // return null + result = _fstat(fh, &buf); // Get data associated with "fh" + if(result == 0) //function obtained data correctly (0 == success, -1 == fail) + { + // create and push a gmFileInfoUser object + gmFileInfoUser * fileInfo = (gmFileInfoUser *) a_thread->GetMachine()->Sys_Alloc(sizeof(gmFileInfoUser)); + fileInfo->m_creationTime = buf.st_ctime; + fileInfo->m_accessedTime = buf.st_atime; + fileInfo->m_modifiedTime = buf.st_mtime; + fileInfo->m_size = buf.st_size; + a_thread->PushNewUser(fileInfo, s_gmFileInfoType); + } + _close( fh ); + return GM_OK; +} + + +static int GM_CDECL gmfCreateFolder(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_STRING_PARAM(path, 0); + BOOL result = CreateDirectory(path, NULL); + if(result) + { + a_thread->PushInt(1); + } + else + { + WIN32_FIND_DATA findData; + HANDLE handle = FindFirstFile(path, &findData); + if(handle == INVALID_HANDLE_VALUE) + { + a_thread->PushInt(0); + } + else + { + if(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + a_thread->PushInt(2); + } + else + { + a_thread->PushInt(0); + } + FindClose(handle); + } + } + return GM_OK; +} + + +bool RecurseDeletePath(const char * a_path) +{ + WIN32_FIND_DATA findData; + + char path[MAX_PATH] = ""; + strcpy(path,a_path); + + // remove trailing '\' char + int last = strlen(path) - 1; + if(path[last] == '\\') + { + path[last] = '\0'; + } + + // is path valid + HANDLE h = FindFirstFile(path,&findData); + + // path not could not be found OR path is a file, not a folder + if((h == INVALID_HANDLE_VALUE) || (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))) + { + return false; + } + + FindClose(h); + h = NULL; + + // push current working directory + char currDir[MAX_PATH + 1] = ""; + GetCurrentDirectory(MAX_PATH,currDir); + SetCurrentDirectory(path); + + // iterate over contents of folder + h = FindFirstFile("*",&findData); + + if(h != INVALID_HANDLE_VALUE) + { + for(;;) + { + if(strcmp(findData.cFileName,".") != 0 && strcmp(findData.cFileName,"..") != 0) + { + if(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + RecurseDeletePath(findData.cFileName); + } + else + { + DWORD attrs = GetFileAttributes(findData.cFileName); + if(attrs & FILE_ATTRIBUTE_READONLY) + { + SetFileAttributes(findData.cFileName,attrs ^ FILE_ATTRIBUTE_READONLY); + } + if(!DeleteFile(findData.cFileName)) + { + DWORD res = GetLastError(); + printf("\nDeleteFile() returned '%d'..\n",(int)res); + } + } + } + + if(!FindNextFile(h,&findData)) break; + } + } + + // pop current working directory + SetCurrentDirectory(currDir); + + FindClose(h); + h = NULL; + + // remove this directory + DWORD attrs = GetFileAttributes(path); + if(attrs & FILE_ATTRIBUTE_READONLY) + { + SetFileAttributes(path,attrs ^ FILE_ATTRIBUTE_READONLY); + } + return RemoveDirectory(path) != 0; +} + + +static int GM_CDECL gmfDeleteFolder(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_STRING_PARAM(path, 0); + GM_INT_PARAM(removeSubFolders, 1, 0); + + if(removeSubFolders) + { + a_thread->PushInt(RecurseDeletePath(path) ? 1 : 0); + } + else + { + a_thread->PushInt(RemoveDirectory(path) ? 1 : 0); + } + return GM_OK; +} + + +static int GM_CDECL gmfTime(gmThread * a_thread) +{ + time_t t; + time(&t); + GM_ASSERT(sizeof(time_t) == sizeof(gmptr)); + a_thread->PushInt((gmptr) t); + return GM_OK; +} + + +static int GM_CDECL gmfFormatTime(gmThread * a_thread) +{ + GM_INT_PARAM(t, 0, -1); + GM_STRING_PARAM(format, 1, "%A %d %B %Y, %I:%M:%S %p"); + char buffer[256]; + + if(t == -1) + { + time_t lt; + time(<); + t = (int) lt; + } + struct tm * ct = localtime((time_t *) &t); + strftime(buffer, 256, format, ct); + a_thread->PushNewString(buffer); + return GM_OK; +} + + +static int GM_CDECL gmfFileFindGetAttribute(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_INT_PARAM(attribute, 0); + + GM_ASSERT(a_thread->GetThis()->m_type == s_gmFileFindType); + gmFileFindUser * fileFind = (gmFileFindUser *) a_thread->ThisUser(); + + DWORD attr = 0; + if(attribute == 'r') + { + attr = FILE_ATTRIBUTE_READONLY; + } + else if(attribute == 'a') + { + attr = FILE_ATTRIBUTE_ARCHIVE; + } + else if(attribute == 's') + { + attr = FILE_ATTRIBUTE_SYSTEM; + } + else if(attribute == 'h') + { + attr = FILE_ATTRIBUTE_HIDDEN; + } + else if(attribute == 'd') + { + attr = FILE_ATTRIBUTE_DIRECTORY; + } + else if(attribute == 'c') + { + attr = FILE_ATTRIBUTE_COMPRESSED; + } + + a_thread->PushInt((fileFind->m_findData.dwFileAttributes & attr) ? 1 : 0); + return GM_OK; +} + + +static void GM_CDECL gmFileFindOpGetDot(gmThread * a_thread, gmVariable * a_operands) +{ + gmUserObject * user = (gmUserObject *) GM_OBJECT(a_operands->m_value.m_ref); + if(user && user->m_user) + { + gmFileFindUser * fileFind = (gmFileFindUser *) user->m_user; + gmStringObject * member = (gmStringObject *) GM_OBJECT(a_operands[1].m_value.m_ref); + + if(strcmp(member->GetString(), "filename") == 0) + { + a_operands->SetString(a_thread->GetMachine()->AllocStringObject(fileFind->m_findData.cFileName)); + return; + } + else if(strcmp(member->GetString(), "size") == 0) + { + a_operands->SetInt(fileFind->m_findData.nFileSizeLow); + return; + } + } + a_operands->Nullify(); +} + +#if GM_USE_INCGC +static void GM_CDECL gmGCDestructFileFindUserType(gmMachine * a_machine, gmUserObject* a_object) +{ + if(a_object->m_user) + { + gmFileFindUser * fileFind = (gmFileFindUser *) a_object->m_user; + if(fileFind->m_iterator != INVALID_HANDLE_VALUE) + { + FindClose(fileFind->m_iterator); + } + a_machine->Sys_Free(a_object->m_user); + } + a_object->m_user = NULL; +} +#else //GM_USE_INCGC +static void GM_CDECL gmGCFileFindUserType(gmMachine * a_machine, gmUserObject * a_object, gmuint32 a_mark) +{ + if(a_object->m_user) + { + gmFileFindUser * fileFind = (gmFileFindUser *) a_object->m_user; + if(fileFind->m_iterator != INVALID_HANDLE_VALUE) + { + FindClose(fileFind->m_iterator); + } + a_machine->Sys_Free(a_object->m_user); + } + a_object->m_user = NULL; +} +#endif //GM_USE_INCGC + + +static void GM_CDECL gmFileInfoOpGetDot(gmThread * a_thread, gmVariable * a_operands) +{ + gmUserObject * user = (gmUserObject *) GM_OBJECT(a_operands->m_value.m_ref); + if(user && user->m_user) + { + gmFileInfoUser * fileInfo = (gmFileInfoUser *) user->m_user; + gmStringObject * member = (gmStringObject *) GM_OBJECT(a_operands[1].m_value.m_ref); + + GM_ASSERT(sizeof(gmptr) == sizeof(time_t)); + + if(strcmp(member->GetString(), "creationTime") == 0) + a_operands->SetInt((gmptr) fileInfo->m_creationTime); + else if(strcmp(member->GetString(), "accessedTime") == 0) + a_operands->SetInt((gmptr) fileInfo->m_accessedTime); + else if(strcmp(member->GetString(), "modifiedTime") == 0) + a_operands->SetInt((gmptr) fileInfo->m_modifiedTime); + else if(strcmp(member->GetString(), "size") == 0) + a_operands->SetInt((gmptr) fileInfo->m_size); + else + { + a_operands->Nullify(); + return; + } + return; + } + a_operands->Nullify(); +} + + +#if GM_USE_INCGC +static void GM_CDECL gmGCDestructFileInfoUserType(gmMachine * a_machine, gmUserObject* a_object) +{ + if(a_object->m_user) + { + a_machine->Sys_Free(a_object->m_user); + } + a_object->m_user = NULL; +} +#else //GM_USE_INCGC +static void GM_CDECL gmGCFileInfoUserType(gmMachine * a_machine, gmUserObject * a_object, gmuint32 a_mark) +{ + if(a_object->m_user) + { + a_machine->Sys_Free(a_object->m_user); + } + a_object->m_user = NULL; +} +#endif //GM_USE_INCGC + +// +// +// binding +// +// + + +static gmFunctionEntry s_systemLib[] = +{ + /*gm + \lib system + \brief system functions are bound in a "system" table. + */ + /*gm + \function Exec + \brief Exec will execute a system command + \param string params will be concatinated together with a single space to form the final system command string + \return integer value returned from system exec call, -1 on error + */ + {"Exec", gmfSystem}, + /*gm + \function DoFile + \brief DoFile will execute the gm script in the named file + \param string filename + \param int optional (1) as 1 will execute string before returning, 0 will execute later. + \param ref optional (null) set 'this' + \return thread id of new thread created to execute file + */ + {"DoFile", gmfDoFile}, + /*gm + \function File + \brief File will create a file object + \return file object + */ + {"File", gmfFile}, + /*gm + \function FileExists + \brief FileExists will test to see if a file exists + \param string filename + \return 1 if the file exists, otherwise 0 + */ + {"FileExists", gmfFileExists}, + /*gm + \function FileFindFirst + \brief FileFindFirst will start a file search will test to see if a file exists + \param string filesearch (may contain wildcards, eg, `c:\temp\*.txt`) + \return fileFind object. fileFind object has .filename and .size member + \sa fileFind + */ + {"FileFindFirst", gmfFindFirstFile}, + /*gm + \function FileFindNext + \brief FileFindNext will get the next file matching the file find + \param fileFind object returned by FileFindFirst call or FileFindNext call + \return fileFind object + \sa fileFind + */ + {"FileFindNext", gmfFindNextFile}, + + /*gm + \function FileInfo + \brief FileInfo will return a file info object that has readonly members for .creationDate + \param string path + \return fileInfo object, fileInfo object has a .creationTime, .accessedTime, .modifiedTime and a .size + */ + {"FileInfo", gmfFileInfo}, + + /*gm + \function CreateFolder + \brief CreateFolder will create a file path if it does not already exist + \param string path + \return int 0 on failure, 1 on successful create, 2 if folder already exists + */ + {"CreateFolder", gmfCreateFolder}, + /*gm + \function DeleteFolder + \brief DeleteFolder will remove a file path + \param string path + \param int remove subfiles and folders optional (0) + \return int 1 on success, 0 con failure + */ + {"DeleteFolder", gmfDeleteFolder}, + + /*gm + \function Time + \brief Time will return a unix style time_t as an int + \return the current time + */ + {"Time", gmfTime}, + /*gm + \function FormatTime + \brief FormatTime will take a int (time_t) value and format according to the passed format string. + \param int time (-1) is a (time_t) to be converted to a string, passing -1 gets current time + \param string format ("%A %d %B %Y, %I:%M:%S %p") is the format string to use.
+ %a : Abbreviated weekday name
+ %A : Full weekday name
+ %b : Abbreviated month name
+ %B : Full month name
+ %c : Date and time representation appropriate for locale
+ %d : Day of month as decimal number (01 – 31)
+ %H : Hour in 24-hour format (00 – 23)
+ %I : Hour in 12-hour format (01 – 12)
+ %j : Day of year as decimal number (001 – 366)
+ %m : Month as decimal number (01 – 12)
+ %M : Minute as decimal number (00 – 59)
+ %p : Current locale’s A.M./P.M. indicator for 12-hour clock
+ %S : Second as decimal number (00 – 59)
+ %U : Week of year as decimal number, with Sunday as first day of week (00 – 53)
+ %w : Weekday as decimal number (0 – 6; Sunday is 0)
+ %W : Week of year as decimal number, with Monday as first day of week (00 – 53)
+ %x : Date representation for current locale
+ %X : Time representation for current locale
+ %y : Year without century, as decimal number (00 – 99)
+ %Y : Year with century, as decimal number
+ %z, %Z : Time-zone name or abbreviation; no characters if time zone is unknown
+ %% : Percent sign
+ \return the time as a string. + */ + {"FormatTime", gmfFormatTime}, +}; + +static gmFunctionEntry s_fileFindLib[] = +{ + /*gm + \lib fileFind + \brief fileFind object has a "filename" and "size" member + */ + /*gm + \function GetAttribute + \brief GetAttribute will test a file attribute. + \param int char attribute 'r' readonly, 'a' archive, 's' system, 'h' hidden, 'c' compressed, 'd' directory + \return 1 if the attribute is set, 0 otherwise + */ + {"GetAttribute", gmfFileFindGetAttribute}, +}; + + +static gmFunctionEntry s_fileLib[] = +{ + /*gm + \lib file + */ + /*gm + \function Open + \brief Open will open a file in binary mode + \param string filename + \param int readonly optional (1) + \return 1 if the open was successful, 0 otherwise + */ + {"Open", gmfFileOpen}, + /*gm + \function OpenText + \brief OpenText will open a file in text mode + \param string filename + \param int readonly optional (1) + \return 1 if the open was successful, 0 otherwise + */ + {"OpenText", gmfFileOpenText}, + /*gm + \function Close + \brief Close will close a file + */ + {"Close", gmfFileClose}, + /*gm + \function IsOpen + \brief IsOpen will test to see if a file is open + \return 1 if the file is open, 0 otherwise + */ + {"IsOpen", gmfFileIsOpen}, + /*gm + \function Seek + \brief Move to position within file + \param int offset positional offset relative to origin + \param int origin eg. myFile.SEEK_CUR, myFile.SEEK_END, myFile.SEEK_SET for current, end, start origins. + \return int 1 if operation succeeded, 0 if failed. + */ + {"Seek", gmfFileSeek}, + /*gm + \function Tell + \brief Tell will return the current cursor position of the file + \return int the current cursor position, -1 on error + */ + {"Tell", gmfFileTell}, + /*gm + \function ReadLine + \brief ReadLine will read a line of text from the file. + \param int keep optional (0) as 1 will keep the "\n" char on the line, otherwise it is removed + \return string, or null on eof + */ + {"ReadLine", gmfFileReadLine}, + /*gm + \function ReadChar + \brief ReadChar will read a char from the file + \return int char or null on eof + */ + {"ReadChar", gmfFileReadChar}, + /*gm + \function WriteString + \brief WriteString will write a string to the file + \param string to write to file + \return 1 on success, null on error + */ + {"WriteString", gmfFileWriteString}, + /*gm + \function WriteChar + \brief WriteChar will write a char to the file + \param int char to write to file + \return 1 on success, null on error + */ + {"WriteChar", gmfFileWriteChar}, +}; + + +void gmBindSystemLib(gmMachine * a_machine) +{ + // system + a_machine->RegisterLibrary(s_systemLib, sizeof(s_systemLib) / sizeof(s_systemLib[0]), "system"); + + // file + s_gmFileType = a_machine->CreateUserType("file"); +#if GM_USE_INCGC + a_machine->RegisterUserCallbacks(s_gmFileType, NULL, gmGCDestructFileUserType); +#else //GM_USE_INCGC + a_machine->RegisterUserCallbacks(s_gmFileType, NULL, gmGCFileUserType); +#endif //GM_USE_INCGC + a_machine->RegisterTypeLibrary(s_gmFileType, s_fileLib, sizeof(s_fileLib) / sizeof(s_fileLib[0])); + a_machine->RegisterTypeOperator(s_gmFileType, O_GETDOT, NULL, gmFileOpGetDot); + + // fileFind + s_gmFileFindType = a_machine->CreateUserType("fileFind"); + a_machine->RegisterTypeLibrary(s_gmFileFindType, s_fileFindLib, sizeof(s_fileFindLib) / sizeof(s_fileFindLib[0])); +#if GM_USE_INCGC + a_machine->RegisterUserCallbacks(s_gmFileFindType, NULL, gmGCDestructFileFindUserType); +#else //GM_USE_INCGC + a_machine->RegisterUserCallbacks(s_gmFileFindType, NULL, gmGCFileFindUserType); +#endif //GM_USE_INCGC + a_machine->RegisterTypeOperator(s_gmFileFindType, O_GETDOT, NULL, gmFileFindOpGetDot); + + // fileInfo + s_gmFileInfoType = a_machine->CreateUserType("fileInfo"); +#if GM_USE_INCGC + a_machine->RegisterUserCallbacks(s_gmFileInfoType, NULL, gmGCDestructFileInfoUserType); +#else //GM_USE_INCGC + a_machine->RegisterUserCallbacks(s_gmFileInfoType, NULL, gmGCFileInfoUserType); +#endif //GM_USE_INCGC + a_machine->RegisterTypeOperator(s_gmFileInfoType, O_GETDOT, NULL, gmFileInfoOpGetDot); +} + +#endif // GM_SYSTEM_LIB diff --git a/vscript/languages/gm/src/binds/gmSystemLib.h b/vscript/languages/gm/src/binds/gmSystemLib.h new file mode 100644 index 00000000..10bf5581 --- /dev/null +++ b/vscript/languages/gm/src/binds/gmSystemLib.h @@ -0,0 +1,28 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMSYSTEMLIB_H_ +#define _GMSYSTEMLIB_H_ + +#include "gmConfig.h" + +class gmMachine; + +#define GM_SYSTEM_LIB 1 +#define GM_SYSTEM_LIB_MAX_LINE 1024 // maximum file line length + +#if GM_SYSTEM_LIB + +void gmBindSystemLib(gmMachine * a_machine); + +#endif // GM_SYSTEM_LIB + +#endif // _GMSYSTEMLIB_H_ diff --git a/vscript/languages/gm/src/binds/gmVector3Lib.cpp b/vscript/languages/gm/src/binds/gmVector3Lib.cpp new file mode 100644 index 00000000..877336ec --- /dev/null +++ b/vscript/languages/gm/src/binds/gmVector3Lib.cpp @@ -0,0 +1,1059 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmVector3Lib.h" +#include "gmThread.h" +#include "gmMachine.h" +#include "gmHelpers.h" +#include + +// Must be last header +#include "memdbgon.h" + + +// +// Vector3 +// + +/// \brief Helper Vector3 class that resembles one used in a game. +/// Users will not use this class but cast to their own Vector3 implementation. +struct gmVector3 +{ + static int DominantAxis(const gmVector3& a_vec) + { + float absX, absY, absZ; + + absX = fabsf(a_vec.m_x); + absY = fabsf(a_vec.m_y); + absZ = fabsf(a_vec.m_z); + + if(absY > absX) + { + if(absZ > absY) + { return 2;} // Dominant Z + else + { return 1;} // Dominant Y + } + else if (absZ > absX) + {return 2;} // Dominant Z + else + {return 0;} // Dominant X + } + static float Dot(const gmVector3& a_vec1, const gmVector3& a_vec2) + { + return (a_vec1.m_x * a_vec2.m_x + a_vec1.m_y * a_vec2.m_y + a_vec1.m_z * a_vec2.m_z); + } + static void Cross(const gmVector3& a_vec1, const gmVector3& a_vec2, gmVector3& a_result) + { + GM_ASSERT( (&a_result != &a_vec1) && (&a_result != &a_vec2) ); + + a_result.m_x = (a_vec1.m_y * a_vec2.m_z) - (a_vec1.m_z * a_vec2.m_y); + a_result.m_y = (a_vec1.m_z * a_vec2.m_x) - (a_vec1.m_x * a_vec2.m_z); + a_result.m_z = (a_vec1.m_x * a_vec2.m_y) - (a_vec1.m_y * a_vec2.m_x); + } + static float Length(const gmVector3& a_vec) + { + return (float)sqrt(LengthSquared(a_vec)); + } + static float LengthSquared(const gmVector3& a_vec) + { + return Dot(a_vec, a_vec); + } + static void Normalize(const gmVector3& a_vec, gmVector3& a_result) + { + float len2 = LengthSquared(a_vec); + if(len2 != 0.0f) + { + float ooLen = 1.0f / (float)sqrt(len2); + MulScalar(a_vec, ooLen, a_result); + } + else + { + a_result.m_x = 0.0f; + a_result.m_y = 0.0f; + a_result.m_z = 0.0f; + } + } + static void Add(const gmVector3& a_vec1, const gmVector3& a_vec2, gmVector3& a_result) + { + a_result.m_x = a_vec1.m_x + a_vec2.m_x; + a_result.m_y = a_vec1.m_y + a_vec2.m_y; + a_result.m_z = a_vec1.m_z + a_vec2.m_z; + } + static void Sub(const gmVector3& a_vec1, const gmVector3& a_vec2, gmVector3& a_result) + { + a_result.m_x = a_vec1.m_x - a_vec2.m_x; + a_result.m_y = a_vec1.m_y - a_vec2.m_y; + a_result.m_z = a_vec1.m_z - a_vec2.m_z; + } + static void MulVector3(const gmVector3& a_vec1, const gmVector3& a_vec2, gmVector3& a_result) + { + a_result.m_x = a_vec1.m_x * a_vec2.m_x; + a_result.m_y = a_vec1.m_y * a_vec2.m_y; + a_result.m_z = a_vec1.m_z * a_vec2.m_z; + } + static void MulScalar(const gmVector3& a_vec, const float& a_scale, gmVector3& a_result) + { + a_result.m_x = a_vec.m_x * a_scale; + a_result.m_y = a_vec.m_y * a_scale; + a_result.m_z = a_vec.m_z * a_scale; + } + static void LerpPoints(const gmVector3& a_vecFrom, const gmVector3& a_vecTo, const float a_frac, gmVector3& a_result) + { + a_result.m_x = a_vecFrom.m_x + a_frac * (a_vecTo.m_x - a_vecFrom.m_x); + a_result.m_y = a_vecFrom.m_y + a_frac * (a_vecTo.m_y - a_vecFrom.m_y); + a_result.m_z = a_vecFrom.m_z + a_frac * (a_vecTo.m_z - a_vecFrom.m_z); + } + + // Set to Vector rotated by AxisAngle rotation + // Rotate a vector by a axis (unit vector) and angle (radians) + // Only useful if you want to do this once off, otherwise, create a matrix and rotate multiple vectors more efficiently + static void RotateAxisAngle(const gmVector3& a_point, const gmVector3& a_axis, const float a_angle, gmVector3& a_result) + { + //cos(t) V + (1 - cos(t)) (A dot V) A + sin(t) (A cross V). + + float sinAng, cosAng; + gmVector3 temp1, temp2; + gmSinCos(a_angle, sinAng, cosAng); + + MulScalar(a_point, cosAng, temp1); + MulScalar(a_axis, (1 - cosAng) * Dot(a_axis, a_point), temp2); + Cross(a_axis, a_point, a_result); + MulScalar(a_result, sinAng, a_result); + Add(temp1, a_result, a_result); + Add(temp2, a_result, a_result); + } + + static void RotateAboutX(const gmVector3& a_vec, float a_angle, gmVector3& a_result) + { + float sinAng, cosAng; + + gmSinCos(a_angle, sinAng, cosAng); + + a_result.m_y = a_vec.m_y * cosAng - a_vec.m_z * sinAng; + a_result.m_z = a_vec.m_y * sinAng + a_vec.m_z * cosAng; + a_result.m_x = a_vec.m_x; + } + + static void RotateAboutY(const gmVector3& a_vec, float a_angle, gmVector3& a_result) + { + float sinAng, cosAng; + + gmSinCos(a_angle, sinAng, cosAng); + + a_result.m_z = a_vec.m_z * cosAng - a_vec.m_x * sinAng; + a_result.m_x = a_vec.m_z * sinAng + a_vec.m_x * cosAng; + a_result.m_y = a_vec.m_y; + } + + static void RotateAboutZ(const gmVector3& a_vec, float a_angle, gmVector3& a_result) + { + float sinAng, cosAng; + + gmSinCos(a_angle, sinAng, cosAng); + + a_result.m_x = a_vec.m_x * cosAng - a_vec.m_y * sinAng; + a_result.m_y = a_vec.m_x * sinAng + a_vec.m_y * cosAng; + a_result.m_z = a_vec.m_z; + } + + // Spherical linear interpolation between two vectors + // Using quaternion style, find vector along smallest great circle between vectors + // [sin((1-t)*A)/sin(A)]*P + [sin(t*A)/sin(A)]*Q + static void SlerpVectors(const gmVector3& a_vecFrom, const gmVector3& a_vecTo, const float a_frac, gmVector3& a_result) + { + float sinA; + float ang; + float ooSinA; + gmVector3 partSrc, partDst; + float cosAng; + + cosAng = Dot(a_vecFrom, a_vecTo); + if(fabsf(cosAng) >= 0.999f) //if From is very similar to To + { + a_result = a_vecFrom; + return; + } + + ang = acosf(cosAng); + sinA = sinf(ang); + ooSinA = 1.0f / sinA; + + MulScalar(a_vecFrom, sinf((1 - a_frac) * ang) * ooSinA, partSrc); + MulScalar(a_vecTo, sinf(a_frac * ang) * ooSinA, partDst); + + Add(partSrc, partDst, a_result); + } + + static void Project(const gmVector3& a_dir, const gmVector3& a_point, const float a_time, gmVector3& a_result) + { + a_result.m_x = a_point.m_x + a_dir.m_x * a_time; + a_result.m_y = a_point.m_y + a_dir.m_y * a_time; + a_result.m_z = a_point.m_z + a_dir.m_z * a_time; + } + + union + { + float m_v[3]; + struct + { + float m_x; + float m_y; + float m_z; + }; + }; +}; + + +/// \brief The Vector3 bindings +/// Just a set of useful functions, operators, etc. for Vector3 +struct gmVector3Obj +{ + static int GM_CDECL DominantAxis(gmThread * a_thread) + { + GM_CHECK_NUM_PARAMS(0); + gmVector3* thisVec = (gmVector3*)a_thread->ThisUser_NoChecks(); + + a_thread->PushInt( gmVector3::DominantAxis(*thisVec) ); + return GM_OK; + } + + static int GM_CDECL Dot(gmThread * a_thread) + { + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_USER_PARAM(gmVector3*, GM_VECTOR3, otherVec, 0); + gmVector3* thisVec = (gmVector3*)a_thread->ThisUser_NoChecks(); + a_thread->PushFloat( gmVector3::Dot(*thisVec, *otherVec) ); + + return GM_OK; + } + + static int GM_CDECL Cross(gmThread * a_thread) + { + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_USER_PARAM(gmVector3*, GM_VECTOR3, otherVec, 0); + gmVector3* thisVec = (gmVector3*)a_thread->ThisUser_NoChecks(); + gmVector3* newVec = Alloc(a_thread->GetMachine(), false); + + gmVector3::Cross(*thisVec, *otherVec, *newVec); + + a_thread->PushNewUser(newVec, GM_VECTOR3); + + return GM_OK; + } + + static int GM_CDECL RotateAxisAngle(gmThread * a_thread) + { + GM_CHECK_NUM_PARAMS(2); + GM_CHECK_USER_PARAM(gmVector3*, GM_VECTOR3, otherVec, 0); + gmVector3* thisVec = (gmVector3*)a_thread->ThisUser_NoChecks(); + + float angle = 0; + if(!gmGetFloatOrIntParamAsFloat(a_thread, 1, angle)) + { + return GM_EXCEPTION; + } + + gmVector3* newVec = Alloc(a_thread->GetMachine(),false); + + gmVector3::RotateAxisAngle(*thisVec, *otherVec, angle, *newVec); + + a_thread->PushNewUser(newVec, GM_VECTOR3); + + return GM_OK; + } + + static int GM_CDECL RotateX(gmThread * a_thread) + { + GM_CHECK_NUM_PARAMS(1); + gmVector3* thisVec = (gmVector3*)a_thread->ThisUser_NoChecks(); + + float angle = 0; + if(!gmGetFloatOrIntParamAsFloat(a_thread, 0, angle)) + { + return GM_EXCEPTION; + } + + gmVector3* newVec = Alloc(a_thread->GetMachine(),false); + gmVector3::RotateAboutX(*thisVec, angle, *newVec); + a_thread->PushNewUser(newVec, GM_VECTOR3); + + return GM_OK; + } + + static int GM_CDECL RotateY(gmThread * a_thread) + { + GM_CHECK_NUM_PARAMS(1); + gmVector3* thisVec = (gmVector3*)a_thread->ThisUser_NoChecks(); + + float angle = 0; + if(!gmGetFloatOrIntParamAsFloat(a_thread, 0, angle)) + { + return GM_EXCEPTION; + } + + gmVector3* newVec = Alloc(a_thread->GetMachine(),false); + gmVector3::RotateAboutY(*thisVec, angle, *newVec); + a_thread->PushNewUser(newVec, GM_VECTOR3); + + return GM_OK; + } + + static int GM_CDECL RotateZ(gmThread * a_thread) + { + GM_CHECK_NUM_PARAMS(1); + gmVector3* thisVec = (gmVector3*)a_thread->ThisUser_NoChecks(); + + float angle = 0; + if(!gmGetFloatOrIntParamAsFloat(a_thread, 0, angle)) + { + return GM_EXCEPTION; + } + + gmVector3* newVec = Alloc(a_thread->GetMachine(),false); + gmVector3::RotateAboutZ(*thisVec, angle, *newVec); + a_thread->PushNewUser(newVec, GM_VECTOR3); + + return GM_OK; + } + + static int GM_CDECL Length(gmThread * a_thread) + { + GM_CHECK_NUM_PARAMS(0); + gmVector3* thisVec = (gmVector3*)a_thread->ThisUser_NoChecks(); + a_thread->PushFloat( gmVector3::Length(*thisVec) ); + + return GM_OK; + } + + static int GM_CDECL LengthSquared(gmThread * a_thread) + { + GM_CHECK_NUM_PARAMS(0); + gmVector3* thisVec = (gmVector3*)a_thread->ThisUser_NoChecks(); + a_thread->PushFloat( gmVector3::LengthSquared(*thisVec) ); + + return GM_OK; + } + + static int GM_CDECL Normalize(gmThread * a_thread) + { + GM_CHECK_NUM_PARAMS(0); + gmVector3* thisVec = (gmVector3*)a_thread->ThisUser_NoChecks(); + + gmVector3* newVec = Alloc(a_thread->GetMachine(),false); + gmVector3::Normalize(*thisVec, *newVec); + + a_thread->PushNewUser(newVec, GM_VECTOR3); + + return GM_OK; + } + + static int GM_CDECL Clone(gmThread * a_thread) + { + gmVector3* thisVec = (gmVector3*)a_thread->ThisUser_NoChecks(); + + gmVector3* newVec = Alloc(a_thread->GetMachine(),false); + *newVec = *thisVec; + a_thread->PushNewUser(newVec, GM_VECTOR3); + + return GM_OK; + } + + static int GM_CDECL Set(gmThread * a_thread) + { + gmVector3* thisVec = (gmVector3*)a_thread->ThisUser_NoChecks(); + + if(a_thread->Param(0).m_type == GM_VECTOR3) + { + GM_CHECK_USER_PARAM(gmVector3*, GM_VECTOR3, otherVec, 0); + *thisVec = *otherVec; + } + else + { + GM_CHECK_NUM_PARAMS(3); + if(!gmGetFloatOrIntParamAsFloat(a_thread, 0, thisVec->m_x)) + { + return GM_EXCEPTION; + } + if(!gmGetFloatOrIntParamAsFloat(a_thread, 1, thisVec->m_y)) + { + return GM_EXCEPTION; + } + if(!gmGetFloatOrIntParamAsFloat(a_thread, 2, thisVec->m_z)) + { + return GM_EXCEPTION; + } + } + + return GM_OK; + } + + static int GM_CDECL LerpToPoint(gmThread * a_thread) + { + GM_CHECK_NUM_PARAMS(2); + GM_CHECK_USER_PARAM(gmVector3*, GM_VECTOR3, otherVec, 0); + gmVector3* thisVec = (gmVector3*)a_thread->ThisUser_NoChecks(); + + float frac = 0; + if(!gmGetFloatOrIntParamAsFloat(a_thread, 1, frac)) + { + return GM_EXCEPTION; + } + + gmVector3* newVec = Alloc(a_thread->GetMachine(),false); + gmVector3::LerpPoints(*thisVec, *otherVec, frac, *newVec); + + a_thread->PushNewUser(newVec, GM_VECTOR3); + + return GM_OK; + } + + static int GM_CDECL SlerpToVector(gmThread * a_thread) + { + GM_CHECK_NUM_PARAMS(2); + GM_CHECK_USER_PARAM(gmVector3*, GM_VECTOR3, otherVec, 0); + gmVector3* thisVec = (gmVector3*)a_thread->ThisUser_NoChecks(); + + float frac = 0; + if(!gmGetFloatOrIntParamAsFloat(a_thread, 1, frac)) + { + return GM_EXCEPTION; + } + + gmVector3* newVec = Alloc(a_thread->GetMachine(),false); + gmVector3::SlerpVectors(*thisVec, *otherVec, frac, *newVec); + + a_thread->PushNewUser(newVec, GM_VECTOR3); + + return GM_OK; + } + + static int GM_CDECL ProjectFrom(gmThread * a_thread) + { + GM_CHECK_NUM_PARAMS(2); + GM_CHECK_USER_PARAM(gmVector3*, GM_VECTOR3, otherVec, 0); + gmVector3* thisVec = (gmVector3*)a_thread->ThisUser_NoChecks(); + + float time = 0; + if(!gmGetFloatOrIntParamAsFloat(a_thread, 1, time)) + { + return GM_EXCEPTION; + } + + gmVector3* newVec = Alloc(a_thread->GetMachine(),false); + gmVector3::Project(*thisVec, *otherVec, time, *newVec); + + a_thread->PushNewUser(newVec, GM_VECTOR3); + + return GM_OK; + } + + static void GM_CDECL OpAdd(gmThread * a_thread, gmVariable * a_operands) + { + // Check types + if(a_operands[0].m_type != GM_VECTOR3 || a_operands[1].m_type != GM_VECTOR3) + { + a_operands[0].Nullify(); + return; + } + + // Get operands + gmVector3* vecObjA = (gmVector3*) ((gmUserObject*)GM_OBJECT(a_operands[0].m_value.m_ref))->m_user; + gmVector3* vecObjB = (gmVector3*) ((gmUserObject*)GM_OBJECT(a_operands[1].m_value.m_ref))->m_user; + + // Create new + gmVector3* newVec = Alloc(a_thread->GetMachine(),false); + gmUserObject* newUserObj = a_thread->GetMachine()->AllocUserObject(newVec, GM_VECTOR3); + // Perform operation + gmVector3::Add(*vecObjA, *vecObjB, *newVec); + + // Return result + a_operands[0].SetUser(newUserObj); + } + + // a.SetAdd(b,c) Demonstrate relative efficiency compared to operator version + static int GM_CDECL SetAdd(gmThread * a_thread) + { + GM_CHECK_NUM_PARAMS(2); + GM_CHECK_USER_PARAM(gmVector3*, GM_VECTOR3, a_vec1, 0); + GM_CHECK_USER_PARAM(gmVector3*, GM_VECTOR3, a_vec2, 1); + + gmVector3* thisVec = (gmVector3*)a_thread->ThisUser_NoChecks(); + + // Perform operation + gmVector3::Add(*a_vec1, *a_vec2, *thisVec); + + return GM_OK; + } + + // a.Add(b) Demonstrate relative efficiency compared to operator version + static int GM_CDECL Add(gmThread * a_thread) + { + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_USER_PARAM(gmVector3*, GM_VECTOR3, a_vec1, 0); + + gmVector3* thisVec = (gmVector3*)a_thread->ThisUser_NoChecks(); + + // Perform operation + gmVector3::Add(*a_vec1, *thisVec, *thisVec); + + return GM_OK; + } + + static void GM_CDECL OpSub(gmThread * a_thread, gmVariable * a_operands) + { + // Check types + if(a_operands[0].m_type != GM_VECTOR3 || a_operands[1].m_type != GM_VECTOR3) + { + a_operands[0].Nullify(); + return; + } + + // Get operands + gmVector3* vecObjA = (gmVector3*) ((gmUserObject*)GM_OBJECT(a_operands[0].m_value.m_ref))->m_user; + gmVector3* vecObjB = (gmVector3*) ((gmUserObject*)GM_OBJECT(a_operands[1].m_value.m_ref))->m_user; + + // Create new + gmVector3* newVec = Alloc(a_thread->GetMachine(),false); + gmUserObject* newUserObj = a_thread->GetMachine()->AllocUserObject(newVec, GM_VECTOR3); + // Perform operation + gmVector3::Sub(*vecObjA, *vecObjB, *newVec); + + // Return result + a_operands[0].SetUser(newUserObj); + } + + static void GM_CDECL OpMul(gmThread * a_thread, gmVariable * a_operands) + { + // Check types + if(a_operands[0].m_type == GM_VECTOR3 && a_operands[1].m_type == GM_VECTOR3) + { + // Get operands + gmVector3* vecObjA = (gmVector3*) ((gmUserObject*)GM_OBJECT(a_operands[0].m_value.m_ref))->m_user; + gmVector3* vecObjB = (gmVector3*) ((gmUserObject*)GM_OBJECT(a_operands[1].m_value.m_ref))->m_user; + + // Create new + gmVector3* newVec = Alloc(a_thread->GetMachine(),false); + gmUserObject* newUserObj = a_thread->GetMachine()->AllocUserObject(newVec, GM_VECTOR3); + // Perform operation + gmVector3::MulVector3(*vecObjA, *vecObjB, *newVec); + + // Return result + a_operands[0].SetUser(newUserObj); + } + else if(a_operands[0].m_type == GM_VECTOR3 && (a_operands[1].m_type != GM_VECTOR3)) + { + // Get operands + gmVector3* vecObjA = (gmVector3*) ((gmUserObject*)GM_OBJECT(a_operands[0].m_value.m_ref))->m_user; + float scaleB = 0.0f; + + if(a_operands[1].m_type == GM_FLOAT) + { + scaleB = a_operands[1].m_value.m_float; + } + else if(a_operands[1].m_type == GM_INT) + { + scaleB = (float)a_operands[1].m_value.m_int; + } + + // Create new + gmVector3* newVec = Alloc(a_thread->GetMachine(),false); + gmUserObject* newUserObj = a_thread->GetMachine()->AllocUserObject(newVec, GM_VECTOR3); + // Perform operation + gmVector3::MulScalar(*vecObjA, scaleB, *newVec); + + // Return result + a_operands[0].SetUser(newUserObj); + } + else if((a_operands[0].m_type != GM_VECTOR3) && a_operands[1].m_type == GM_VECTOR3) + { + // Get operands + float scaleA = 0.0f; + gmVector3* vecObjB = (gmVector3*) ((gmUserObject*)GM_OBJECT(a_operands[1].m_value.m_ref))->m_user; + + if(a_operands[0].m_type == GM_FLOAT) + { + scaleA = a_operands[0].m_value.m_float; + } + else if(a_operands[0].m_type == GM_INT) + { + scaleA = (float)a_operands[0].m_value.m_int; + } + + // Create new + gmVector3* newVec = Alloc(a_thread->GetMachine(),false); + gmUserObject* newUserObj = a_thread->GetMachine()->AllocUserObject(newVec, GM_VECTOR3); + // Perform operation + gmVector3::MulScalar(*vecObjB, scaleA, *newVec); + + // Return result + a_operands[0].SetUser(newUserObj); + } + else + { + a_operands[0].Nullify(); + return; + } + } + + static void GM_CDECL OpNeg(gmThread * a_thread, gmVariable * a_operands) + { + // Check types + if(a_operands[0].m_type != GM_VECTOR3) + { + a_operands[0].Nullify(); + return; + } + + // Get operands + gmVector3* vecObjA = (gmVector3*) ((gmUserObject*)GM_OBJECT(a_operands[0].m_value.m_ref))->m_user; + + // Create new + gmVector3* newVec = Alloc(a_thread->GetMachine(),false); + gmUserObject* newUserObj = a_thread->GetMachine()->AllocUserObject(newVec, GM_VECTOR3); + + // Perform operation + newVec->m_x = -vecObjA->m_x; + newVec->m_y = -vecObjA->m_y; + newVec->m_z = -vecObjA->m_z; + + // Return result + a_operands[0].SetUser(newUserObj); + } + + static void GM_CDECL OpGetDot(gmThread * a_thread, gmVariable * a_operands) + { + GM_ASSERT(a_operands[0].m_type == GM_VECTOR3); + gmVector3* thisVec = (gmVector3*) ((gmUserObject*)GM_OBJECT(a_operands[0].m_value.m_ref))->m_user; + + GM_ASSERT(a_operands[1].m_type == GM_STRING); + gmStringObject* stringObj = (gmStringObject*)GM_OBJECT(a_operands[1].m_value.m_ref); + const char* cstr = stringObj->GetString(); + if(stringObj->GetLength() != 1) + { + a_operands[0].Nullify(); + return; + } + + if(cstr[0] == 'x') + { + a_operands[0].SetFloat(thisVec->m_x); + } + else if(cstr[0] == 'y') + { + a_operands[0].SetFloat(thisVec->m_y); + } + else if(cstr[0] == 'z') + { + a_operands[0].SetFloat(thisVec->m_z); + } + else + { + a_operands[0].Nullify(); + } + } + + static void GM_CDECL OpSetDot(gmThread * a_thread, gmVariable * a_operands) + { + GM_ASSERT(a_operands[0].m_type == GM_VECTOR3); + gmVector3* thisVec = (gmVector3*) ((gmUserObject*)GM_OBJECT(a_operands[0].m_value.m_ref))->m_user; + + GM_ASSERT(a_operands[2].m_type == GM_STRING); + gmStringObject* stringObj = (gmStringObject*)GM_OBJECT(a_operands[2].m_value.m_ref); + const char* cstr = stringObj->GetString(); + if(stringObj->GetLength() != 1) + { + return; + } + + float newFloat = 0.0f; + if(a_operands[1].m_type == GM_FLOAT) + { + newFloat = a_operands[1].m_value.m_float; + } + else if(a_operands[1].m_type == GM_INT) + { + newFloat = (float)a_operands[1].m_value.m_int; + } + + if(cstr[0] == 'x') + { + thisVec->m_x = newFloat; + } + else if(cstr[0] == 'y') + { + thisVec->m_y = newFloat; + } + else if(cstr[0] == 'z') + { + thisVec->m_z = newFloat; + } + } + + static void GM_CDECL OpGetInd(gmThread * a_thread, gmVariable * a_operands) + { + GM_ASSERT(a_operands[0].m_type == GM_VECTOR3); + gmVector3* thisVec = (gmVector3*) ((gmUserObject*)GM_OBJECT(a_operands[0].m_value.m_ref))->m_user; + if(a_operands[1].m_type == GM_INT) + { + int index = a_operands[1].m_value.m_int; + a_operands[0].SetFloat(thisVec->m_v[index]); + return; + } + a_operands[0].Nullify(); + } + + static void GM_CDECL OpSetInd(gmThread * a_thread, gmVariable * a_operands) + { + GM_ASSERT(a_operands[0].m_type == GM_VECTOR3); + gmVector3* thisVec = (gmVector3*) ((gmUserObject*)GM_OBJECT(a_operands[0].m_value.m_ref))->m_user; + if(a_operands[1].m_type == GM_INT) + { + int index = a_operands[1].m_value.m_int; + if(index < 0 || index >= 3) + { + return; + } + + if(a_operands[2].m_type == GM_FLOAT) + { + thisVec->m_v[index] = a_operands[2].m_value.m_float; + } + else if(a_operands[2].m_type == GM_INT) + { + thisVec->m_v[index] = (float)a_operands[2].m_value.m_int; + } + else + { + thisVec->m_v[index] = 0.0f; + } + } + } + +#if GM_BOOL_OP + static void GM_CDECL OpBool(gmThread * a_thread, gmVariable * a_operands) + { + GM_ASSERT(a_operands[0].m_type == GM_VECTOR3); + gmVector3* thisVec = (gmVector3*) ((gmUserObject*)GM_OBJECT(a_operands[0].m_value.m_ref))->m_user; + if (thisVec->m_x != 0 || thisVec->m_y != 0 && thisVec->m_z != 0) + { + a_operands[0] = gmVariable(1); + } + else + { + a_operands[0] = gmVariable(0); + } + } + + + static void GM_CDECL OpNot(gmThread * a_thread, gmVariable * a_operands) + { + GM_ASSERT(a_operands[0].m_type == GM_VECTOR3); + gmVector3* thisVec = (gmVector3*) ((gmUserObject*)GM_OBJECT(a_operands[0].m_value.m_ref))->m_user; + if (thisVec->m_x != 0 || thisVec->m_y != 0 && thisVec->m_z != 0) + { + a_operands[0] = gmVariable(0); + } + else + { + a_operands[0] = gmVariable(1); + } + } +#endif // GM_BOOL_OP + + static int GM_CDECL Vector3(gmThread * a_thread) + { + int numParams = a_thread->GetNumParams(); + gmVector3* newVec = Alloc(a_thread->GetMachine(),true); + if(numParams > 0) + { + gmGetFloatOrIntParamAsFloat(a_thread, 0, newVec->m_x); + } + if(numParams > 1) + { + gmGetFloatOrIntParamAsFloat(a_thread, 1, newVec->m_y); + } + if(numParams > 2) + { + gmGetFloatOrIntParamAsFloat(a_thread, 2, newVec->m_z); + } + a_thread->PushNewUser(newVec, GM_VECTOR3); + return GM_OK; + } + +#if GM_USE_INCGC + static void GM_CDECL GCDestruct(gmMachine * a_machine, gmUserObject* a_object) + { + GM_ASSERT(a_object->m_userType == GM_VECTOR3); + gmVector3* object = (gmVector3*)a_object->m_user; + Free(a_machine, object); + } + +#else //GM_USE_INCGC + + // Garbage collect 'Garbage Collect' function + static void GM_CDECL Collect(gmMachine * a_machine, gmUserObject * a_object, gmuint32 a_mark) + { + GM_ASSERT(a_object->m_userType == GM_VECTOR3); + gmVector3* object = (gmVector3*)a_object->m_user; + Free(a_machine, object); + } +#endif //GM_USE_INCGC + + static void GM_CDECL AsString(gmUserObject * a_object, char* a_buffer, int a_bufferLen) + { + gmVector3* vec = (gmVector3*)a_object->m_user; + //Note '#' always display decimal place, 'g' display exponent if > precision or 4 + _gmsnprintf(a_buffer, a_bufferLen, "(%#.8g, %#.8g, %#.8g)", vec->m_x, vec->m_y, vec->m_z); + } + + // Allocate memory for one object + static gmVector3* Alloc(gmMachine* a_machine, bool a_clearToZero) + { + a_machine->AdjustKnownMemoryUsed(sizeof(gmVector3)); + gmVector3* newObj = (gmVector3*)s_mem.Alloc(); //Allocate our type + if(a_clearToZero) //Optionally clear our members + { + newObj->m_x = 0.0f; + newObj->m_y = 0.0f; + newObj->m_z = 0.0f; + } + return newObj; + } + + // Free memory for one object + static void Free(gmMachine* a_machine, gmVector3* a_obj) + { + a_machine->AdjustKnownMemoryUsed(-(int)sizeof(gmVector3)); + s_mem.Free(a_obj); + } + + // Only call when gmMachine is shutdown + static void FreeAllMemory() + { + s_mem.ResetAndFreeMemory(); + } + + // Static members + static gmMemFixed s_mem; ///< Memory for vector3s +}; + +// Static and Global instances +gmMemFixed gmVector3Obj::s_mem(sizeof(gmVector3), 64); +gmType GM_VECTOR3 = GM_NULL; + +/// \brief Push a Vector3. (Eg. Use to return result). +void gmVector3_Push(gmThread* a_thread, const float* a_vec) +{ + gmVector3* newVec = gmVector3Obj::Alloc(a_thread->GetMachine(), false); + *newVec = *(gmVector3*)a_vec; + a_thread->PushNewUser(newVec, GM_VECTOR3); +} + +/// \brief Create a Vector3 user object and fill it (Eg. use, to set as table member). +gmUserObject* gmVector3_Create(gmMachine* a_machine, const float* a_vec) +{ + gmVector3* newVec = gmVector3Obj::Alloc(a_machine, false); + *newVec = *(gmVector3*)a_vec; + return a_machine->AllocUserObject(newVec, GM_VECTOR3); +} + +// libs + +static gmFunctionEntry s_vector3Lib[] = +{ + /*gm + \lib Vector3 + */ + /*gm + \function Vector3 + \brief Create a Vector3 object + \param float x or [0] optional (0) + \param float y or [1] optional (0) + \param float z or [2] optional (0) + */ + {"Vector3", gmVector3Obj::Vector3}, +}; + +static gmFunctionEntry s_vector3TypeLib[] = +{ + /*gm + \lib Vector3 + \brief Vector3 math class + */ + /*gm + \function DominantAxis + \brief Find the index of the largest vector component. + \this Vector to evaluate. + \return int Index of largest component. + */ + {"DominantAxis", gmVector3Obj::DominantAxis}, + /*gm + \function Dot + \brief Calculate the Dot (or Inner) Product of two vectors. + \this Vector3 First vector. + \param Vector3 Second vector. + \return float result. + */ + {"Dot", gmVector3Obj::Dot}, + /*gm + \function Length + \brief Length will return the length of the vector. + \return float Dot product result that is cosine of the angle between the two vectors. + */ + {"Length", gmVector3Obj::Length}, + /*gm + \function Cross + \brief Calculate the Cross (or Outer) Product of two vectors. + \this Vector3 First vector. + \param Vector3 Second vector. + \return Vector3 Cross product resultant vector that is perpendicular to the two input vectors and length sine of the angle between them. + */ + {"Cross", gmVector3Obj::Cross}, + /*gm + \function Normalize + \brief Return a unit length copy of this vector. + \this Vector to be copied. + \return Vector3 Unit length copy of this vector. + */ + {"Normalize", gmVector3Obj::Normalize}, + /*gm + \function LengthSquared + \brief Return the squared length of the vector. + \return float Squared length of the vector. + */ + {"LengthSquared", gmVector3Obj::LengthSquared}, + /*gm + \function ProjectFrom + \brief Project a direction from a point. + \this Vector3 Direction. + \param Vector3 Start point; + \param float Distance or time. + \return Vector3 Projected result. + */ + {"ProjectFrom", gmVector3Obj::ProjectFrom}, + /*gm + \function Clone + \brief Return a copy of this vector. + \return A copy of this vector. + */ + {"Clone", gmVector3Obj::Clone}, + /*gm + \function Set + \brief Set vector from other vector or 3 components. + */ + {"Set", gmVector3Obj::Set}, + /*gm + \function LerpToPoint + \brief Linear interpolate between two 'point' vectors. + \this Vector3 From vector. + \param Vector3 To vector. + \param float Fraction or time between 0 and 1. + \return Vector3 Resulting inbetween vector. + */ + {"LerpToPoint", gmVector3Obj::LerpToPoint}, + /*gm + \function SlerpToVector + \brief Spherical linear interpolate between two vectors. + \this Vector3 From vector. + \param Vector3 To vector. + \param float Fraction or time between 0 and 1. + \return Vector3 Resulting inbetween vector. + */ + {"SlerpToVector", gmVector3Obj::SlerpToVector}, + /*gm + \function RotateAxisAngle + \brief Rotate around Axis by Angle. + \this Vector3 Vector to rotate. + \param Vector3 Unit length axis of rotation. + \param float Angle amount to rotate. + \return Vector3 Resulting rotated vector. + */ + {"RotateAxisAngle", gmVector3Obj::RotateAxisAngle}, + /*gm + \function RotateX + \brief Rotate around X Axis by Angle. + \this Vector3 Vector to rotate. + \param float Angle amount to rotate. + \return Vector3 Resulting rotated vector. + */ + {"RotateX", gmVector3Obj::RotateX}, + /*gm + \function RotateX + \brief Rotate around Y Axis by Angle. + \this Vector3 Vector to rotate. + \param float Angle amount to rotate. + \return Vector3 Resulting rotated vector. + */ + {"RotateY", gmVector3Obj::RotateY}, + /*gm + \function RotateZ + \brief Rotate around Z Axis by Angle. + \this Vector3 Vector to rotate. + \param float Angle amount to rotate. + \return Vector3 Resulting rotated vector. + */ + {"RotateZ", gmVector3Obj::RotateZ}, + + /*gm + \function SetAdd + \brief Add two vectors, store result in this. Demonstrate relative efficiency compared to operator version. + \this Vector3 Result vector. + \param Vector3 First vector. + \param Vector3 Second vector. + */ + {"SetAdd", gmVector3Obj::SetAdd}, + + /*gm + \function Add + \brief Add vector to this. Demonstrate relative efficiency compared to operator version. + \this Vector3 Result vector. + \param Vector3 vector to add. + */ + {"Add", gmVector3Obj::Add}, +}; + + +/// \brief Bind Vector3 library +void gmBindVector3Lib(gmMachine * a_machine) +{ + // Lib + a_machine->RegisterLibrary(s_vector3Lib, sizeof(s_vector3Lib) / sizeof(s_vector3Lib[0])); + + // Register new user type + GM_VECTOR3 = a_machine->CreateUserType("Vector3"); + + // Operators + a_machine->RegisterTypeOperator(GM_VECTOR3, O_ADD, NULL, gmVector3Obj::OpAdd); + a_machine->RegisterTypeOperator(GM_VECTOR3, O_SUB, NULL, gmVector3Obj::OpSub); + a_machine->RegisterTypeOperator(GM_VECTOR3, O_MUL, NULL, gmVector3Obj::OpMul); + a_machine->RegisterTypeOperator(GM_VECTOR3, O_NEG, NULL, gmVector3Obj::OpNeg); + a_machine->RegisterTypeOperator(GM_VECTOR3, O_GETDOT, NULL, gmVector3Obj::OpGetDot); + a_machine->RegisterTypeOperator(GM_VECTOR3, O_SETDOT, NULL, gmVector3Obj::OpSetDot); + a_machine->RegisterTypeOperator(GM_VECTOR3, O_GETIND, NULL, gmVector3Obj::OpGetInd); + a_machine->RegisterTypeOperator(GM_VECTOR3, O_SETIND, NULL, gmVector3Obj::OpSetInd); +#if GM_BOOL_OP + a_machine->RegisterTypeOperator(GM_VECTOR3, O_BOOL, NULL, gmVector3Obj::OpBool); + a_machine->RegisterTypeOperator(GM_VECTOR3, O_NOT, NULL, gmVector3Obj::OpNot); +#endif // GM_BOOL_OP + + // Type Lib + a_machine->RegisterTypeLibrary(GM_VECTOR3, s_vector3TypeLib, sizeof(s_vector3TypeLib) / sizeof(s_vector3TypeLib[0])); + + // Register garbage collection for type +#if GM_USE_INCGC + a_machine->RegisterUserCallbacks(GM_VECTOR3, NULL, gmVector3Obj::GCDestruct, gmVector3Obj::AsString); +#else //GM_USE_INCGC + a_machine->RegisterUserCallbacks(GM_VECTOR3, NULL, gmVector3Obj::Collect, gmVector3Obj::AsString); +#endif //GM_USE_INCGC +} + diff --git a/vscript/languages/gm/src/binds/gmVector3Lib.h b/vscript/languages/gm/src/binds/gmVector3Lib.h new file mode 100644 index 00000000..704cca3b --- /dev/null +++ b/vscript/languages/gm/src/binds/gmVector3Lib.h @@ -0,0 +1,37 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMVECTOR3LIB_H_ +#define _GMVECTOR3LIB_H_ + +#include "gmConfig.h" +#include "gmVariable.h" + +class gmMachine; +class gmThread; +class gmUserObject; + +// Bind the Vector3 Library. +void gmBindVector3Lib(gmMachine * a_machine); + +// Push a Vector3 onto the stack +void gmVector3_Push(gmThread* a_thread, const float* a_vec); + +// Create a Vector3 user object and fill it +gmUserObject* gmVector3_Create(gmMachine* a_machine, const float* a_vec); + +// The Vector3 type Id. +extern gmType GM_VECTOR3; + +// Example of getting Vector3 from parameter +// GM_CHECK_USER_PARAM(float*, GM_VECTOR3, vec1, 0); + +#endif // _GMVECTOR3LIB_H_ diff --git a/vscript/languages/gm/src/examples/GameObject/App.cpp b/vscript/languages/gm/src/examples/GameObject/App.cpp new file mode 100644 index 00000000..d4f00980 --- /dev/null +++ b/vscript/languages/gm/src/examples/GameObject/App.cpp @@ -0,0 +1,473 @@ +#include +#include // multimedia timer (may need winmm.lib) +#include "App.h" +#include "ScriptSys.h" +#include "GameObj.h" +#include "ScriptObj.h" +#include "gmCall.h" +#include "InputKBWin32.h" + +App* App::s_instancePtr = NULL; + + +App::App() +{ + s_instancePtr = this; +} + + + +App::~App() +{ + s_instancePtr = NULL; +} + + +bool App::Init() +{ + InputKBWin32::Get().Init(); + + // Init console + InitConsole(); + + // Init script system for game objects + ScriptSys::Init(); + + // Register app bindings + RegisterScriptBindings(); + + // Init timer + m_deltaTime = 0; + m_lastTime = timeGetTime(); + + // Compile and run script + ScriptSys::Get()->ExecuteFile("TestGameObj.gm"); + +//TEST REMOVE +// ClearScreen(); +// SetColor(COLOR_YELLOW, COLOR_RED); +// SetCursor(10,10); +// Print("Hello"); +// PrintAt(10,10,"Hello"); + + + return true; +} + + +void App::Destroy() +{ + ScriptSys::Destroy(); +} + + +bool App::Update() +{ + int curTime = timeGetTime(); + m_deltaTime = curTime - m_lastTime; + m_lastTime = curTime; + + // Update input + InputKBWin32::Get().Update(); + + // Execute some script + ScriptSys::Get()->Execute(m_deltaTime); + + if(InputKBWin32::Get().IsKeyPressed('A')) + { + TestA(); + } + else if(InputKBWin32::Get().IsKeyPressed('B')) + { + TestB(); + } + else if(InputKBWin32::Get().IsKeyPressed('C')) + { + TestC(); + } + + if(InputKBWin32::Get().IsKeyPressed(VK_ESCAPE)) + { + return false; + } + + return true; +} + + +void App::InitConsole() +{ + CONSOLE_SCREEN_BUFFER_INFO csbi; + + m_console = GetStdHandle(STD_OUTPUT_HANDLE); + + GetConsoleScreenBufferInfo(m_console, &csbi); + + DWORD dwConSize = csbi.dwSize.X * csbi.dwSize.Y; + + m_screenSizeX = csbi.dwSize.X; + m_screenSizeY = csbi.dwSize.Y; +} + + +void App::TestA() +{ + // Test create a game object and set member in script + GameObj* newObj = new GameObj; + + printf("new GameObj = %x\n", newObj); + printf("GameObj.m_scriptObj = %x\n", newObj->GetScriptObj()); + + newObj->GetScriptObj()->SetMemberString("m_name", "MangoBoy"); + newObj->GetScriptObj()->ExecuteGlobalFunctionOnThis("WhatsMyName"); + + delete newObj; + + gmCall call; + if(call.BeginGlobalFunction(ScriptSys::Get()->GetMachine(), "RunGlobalObject")) + { + call.End(); + } +} + + +void App::TestB() +{ + // Test call script function that keeps running for a bit + gmCall call; + if(call.BeginGlobalFunction(ScriptSys::Get()->GetMachine(), "ThreadYieldTest")) + { + call.End(); + } +} + + +void App::TestC() +{ + // Quick test of collect garbage and cpp owned objects + + GameObj* newObj = new GameObj; + + printf("new GameObj = %x\n", newObj); + printf("GameObj.m_scriptObj = %x\n", newObj->GetScriptObj()); + + newObj->GetScriptObj()->SetMemberString("m_name", "PotatoHead"); + //newObj->GetScriptObj()->ExecuteGlobalFunctionOnThis("WhatsMyName"); + + ScriptSys::Get()->GetMachine()->CollectGarbage(true); + + delete newObj; +} + + +void App::SetCursor(int a_x, int a_y) +{ + ClipScreenCoordsi(a_x, a_y); + + COORD point; + + point.X = (short) a_x; + point.Y = (short) a_y; + + SetConsoleCursorPosition(m_console, point); +} + + +void App::ClearScreen() +{ + COORD coordScreen = { 0, 0 }; + DWORD cCharsWritten; + CONSOLE_SCREEN_BUFFER_INFO csbi; + DWORD dwConSize; + GetConsoleScreenBufferInfo(m_console, &csbi); + dwConSize = csbi.dwSize.X * csbi.dwSize.Y; + FillConsoleOutputCharacter(m_console, TEXT(' '), dwConSize, coordScreen, &cCharsWritten); + GetConsoleScreenBufferInfo(m_console, &csbi); + FillConsoleOutputAttribute(m_console, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten); + SetConsoleCursorPosition(m_console, coordScreen); +} + + +void App::Print(const char* a_string) +{ + printf("%s", a_string); +} + + +void App::PrintAt(int a_x, int a_y, const char* a_string) +{ + SetCursor(a_x, a_y); + Print(a_string); +} + + +int App::GetAttribFromColIndex(int a_colorIndex, bool a_isForeground) +{ + // WARNING These struct must match the color enums + static int foreColors[COLOR_MAX]= + { + 0, //COLOR_BLACK + FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, //COLOR_WHITE, + FOREGROUND_RED, //COLOR_RED + FOREGROUND_GREEN, //COLOR_GREEN, + FOREGROUND_BLUE, //COLOR_BLUE, + FOREGROUND_RED | FOREGROUND_BLUE, //COLOR_MAGENTA, + FOREGROUND_GREEN | FOREGROUND_BLUE, //COLOR_CYAN, + FOREGROUND_RED | FOREGROUND_GREEN, //COLOR_YELLOW, + }; + + static int backColors[COLOR_MAX]= + { + 0, //COLOR_BLACK + BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE, //COLOR_WHITE, + BACKGROUND_RED, //COLOR_RED + BACKGROUND_GREEN, //COLOR_GREEN, + BACKGROUND_BLUE, //COLOR_BLUE, + BACKGROUND_RED | BACKGROUND_BLUE, //COLOR_MAGENTA, + BACKGROUND_GREEN | BACKGROUND_BLUE, //COLOR_CYAN, + BACKGROUND_RED | BACKGROUND_GREEN, //COLOR_YELLOW, + }; + + + if( (a_colorIndex < COLOR_MIN) && (a_colorIndex >= COLOR_MAX) ) + { + if(a_isForeground) + { + return foreColors[COLOR_WHITE]; + } + else + { + return backColors[COLOR_WHITE]; + } + } + + if(a_isForeground) + { + return foreColors[a_colorIndex]; + } + else + { + return backColors[a_colorIndex]; + } +} + + +void App::SetColor(int a_foreColorIndex, int a_backColorIndex) +{ + int foreCol = GetAttribFromColIndex(a_foreColorIndex, true); + int backCol = GetAttribFromColIndex(a_backColorIndex, false); + + int param = foreCol | backCol; + + SetConsoleTextAttribute(m_console, (short) param); +} + + +bool App::ClipScreenCoordsf(float& a_posX, float& a_posY) +{ + bool wasClipped = false; + + if(a_posX < 0.0f) + { + a_posX = 0.0f; + wasClipped = true; + } + else if(a_posX >= (float)App::Get()->GetScreenSizeX()) + { + a_posX = (float)(App::Get()->GetScreenSizeX() - 1); + wasClipped = true; + } + + if(a_posY < 0.0f) + { + a_posY = 0.0f; + wasClipped = true; + } + else if(a_posY >= (float)App::Get()->GetScreenSizeY()) + { + a_posY = (float)(App::Get()->GetScreenSizeY() - 1); + wasClipped = true; + } + + return wasClipped; +} + + +bool App::ClipScreenCoordsi(int& a_posX, int& a_posY) +{ + bool wasClipped = false; + + if(a_posX < 0) + { + a_posX = 0; + wasClipped = true; + } + else if(a_posX >= App::Get()->GetScreenSizeX()) + { + a_posX = App::Get()->GetScreenSizeX() - 1; + wasClipped = true; + } + + if(a_posY < 0) + { + a_posY = 0; + wasClipped = true; + } + else if(a_posY >= App::Get()->GetScreenSizeY()) + { + a_posY = App::Get()->GetScreenSizeY() - 1; + wasClipped = true; + } + + return wasClipped; +} + + +////////////////////////////////////////////////// +// Script bindings +////////////////////////////////////////////////// + + +int GM_CDECL App::Console_Print(gmThread* a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_STRING_PARAM(a_string, 0); + + App::Get()->Print(a_string); + + return GM_OK; +} + + +int GM_CDECL App::Console_SetCursor(gmThread* a_thread) +{ + GM_CHECK_NUM_PARAMS(2); + GM_CHECK_INT_PARAM(a_curX, 0); + GM_CHECK_INT_PARAM(a_curY, 1); + + App::Get()->ClipScreenCoordsi(a_curX, a_curY); + App::Get()->SetCursor(a_curX, a_curY); + + return GM_OK; +} + + +int GM_CDECL App::Console_SetColor(gmThread* a_thread) +{ + GM_CHECK_NUM_PARAMS(2); + GM_CHECK_INT_PARAM(a_foreCol, 0); + GM_CHECK_INT_PARAM(a_backCol, 1); + + App::Get()->SetColor(a_foreCol, a_backCol); + + return GM_OK; +} + + +int GM_CDECL App::Input_KeyPressed(gmThread* a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_INT_PARAM(a_vKey, 0); + + if(InputKBWin32::Get().IsKeyPressed(a_vKey)) + { + a_thread->PushInt(1); + } + else + { + a_thread->PushInt(0); + } + + return GM_OK; +} + + +int GM_CDECL App::Input_KeyDown(gmThread* a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_INT_PARAM(a_vKey, 0); + + if(InputKBWin32::Get().IsKeyDown(a_vKey)) + { + a_thread->PushInt(1); + } + else + { + a_thread->PushInt(0); + } + + return GM_OK; +} + + +void App::RegisterScriptBindings() +{ + static gmFunctionEntry ConsoleLib[] = + { + /*gm + \lib Console + \brief Console Library + */ + /*gm + \function Print + \brief Print string at current cursor position + \param string a_string + */ + {"Print", Console_Print}, + /*gm + \function SetCursor + \brief Set cursor position + \param int a_curX Cursor x position + \param int a_curY Cursor y position + */ + {"SetCursor", Console_SetCursor}, + + /*gm + \function SetColor + \brief Set text color + \param int a_foreCol Foreground color + \param int a_backCol Background color + */ + {"SetColor", Console_SetColor}, + }; + + + static gmFunctionEntry InputLib[] = + { + /*gm + \lib Console + \brief Console Library + */ + /*gm + \function KeyPressed + \brief Was this key pressed + \param int a_vKey windows virtual key code (Most match ascii uppercase) + \return true if key was pressed this frame + */ + {"KeyPressed", Input_KeyPressed}, + + /*gm + \function KeyDown + \brief Is this key down + \param int a_vKey windows virtual key code (Most match ascii uppercase) + \return true if is down + */ + {"KeyDown", Input_KeyDown}, + + }; + + gmMachine* machine = ScriptSys::Get()->GetMachine(); + + machine->RegisterLibrary(ConsoleLib, sizeof(ConsoleLib) / sizeof(ConsoleLib[0]), "Console"); + machine->RegisterLibrary(InputLib, sizeof(InputLib) / sizeof(InputLib[0]), "Input"); + + // Make some global constants + machine->GetGlobals()->Set(machine, "COLOR_BLACK", gmVariable(GM_INT, COLOR_BLACK)); + machine->GetGlobals()->Set(machine, "COLOR_WHITE", gmVariable(GM_INT, COLOR_WHITE)); + machine->GetGlobals()->Set(machine, "COLOR_RED", gmVariable(GM_INT, COLOR_RED)); + machine->GetGlobals()->Set(machine, "COLOR_GREEN", gmVariable(GM_INT, COLOR_GREEN)); + machine->GetGlobals()->Set(machine, "COLOR_BLUE", gmVariable(GM_INT, COLOR_BLUE)); + machine->GetGlobals()->Set(machine, "COLOR_MAGENTA", gmVariable(GM_INT, COLOR_MAGENTA)); + machine->GetGlobals()->Set(machine, "COLOR_CYAN", gmVariable(GM_INT, COLOR_CYAN)); + machine->GetGlobals()->Set(machine, "COLOR_YELLOW", gmVariable(GM_INT, COLOR_YELLOW)); +} diff --git a/vscript/languages/gm/src/examples/GameObject/App.h b/vscript/languages/gm/src/examples/GameObject/App.h new file mode 100644 index 00000000..641285b8 --- /dev/null +++ b/vscript/languages/gm/src/examples/GameObject/App.h @@ -0,0 +1,72 @@ +// +// Example application +// +#include +#include "gmThread.h" + +class App +{ +public: + + enum + { + COLOR_MIN = 0, + + COLOR_BLACK = COLOR_MIN, + COLOR_WHITE, + COLOR_RED, + COLOR_GREEN, + COLOR_BLUE, + COLOR_MAGENTA, + COLOR_CYAN, + COLOR_YELLOW, + + + COLOR_MAX + }; + + static App* Get() { return s_instancePtr; } + + App(); + ~App(); + bool Init(); + void Destroy(); + bool Update(); + + void SetCursor(int a_x, int a_y); + void ClearScreen(); + void Print(const char* a_string); + void PrintAt(int a_x, int a_y, const char* a_string); + void SetColor(int a_foreColorIndex, int a_backColorIndex); + int GetScreenSizeX() { return m_screenSizeX; } + int GetScreenSizeY() { return m_screenSizeY; } + + bool ClipScreenCoordsf(float& a_posX, float& a_posY); + bool ClipScreenCoordsi(int& a_posX, int& a_posY); + +protected: + + int GetAttribFromColIndex(int a_colorIndex, bool a_isForeground); + void InitConsole(); + void RegisterScriptBindings(); + + static int GM_CDECL Console_Print(gmThread* a_thread); + static int GM_CDECL Console_SetCursor(gmThread* a_thread); + static int GM_CDECL Console_SetColor(gmThread* a_thread); + + static int GM_CDECL Input_KeyPressed(gmThread* a_thread); + static int GM_CDECL Input_KeyDown(gmThread* a_thread); + + void TestA(); + void TestB(); + void TestC(); + + int m_deltaTime; + int m_lastTime; + + int m_screenSizeX; + int m_screenSizeY; + HANDLE m_console; + + static App* s_instancePtr; ///< Ptr to instance of this class when created +}; diff --git a/vscript/languages/gm/src/examples/GameObject/GameObj.cpp b/vscript/languages/gm/src/examples/GameObject/GameObj.cpp new file mode 100644 index 00000000..e5f544e1 --- /dev/null +++ b/vscript/languages/gm/src/examples/GameObject/GameObj.cpp @@ -0,0 +1,317 @@ +// +// GameObj.cpp +// + +#include +#include "GameObj.h" +#include "App.h" +#include "ScriptObj.h" +#include "ScriptSys.h" + +GameObj::GameObj() +{ + m_scriptObj = NULL; + m_posX = -1; + m_posY = -1; + m_destX = m_posX; + m_destY = m_posY; + m_speed = 1.0f; + m_colorIndex = App::COLOR_WHITE; + + m_scriptObj = new ScriptObj(this); +} + + +GameObj::~GameObj() +{ + if(m_scriptObj) + { + delete m_scriptObj; + } +} + + +float GameObj::GetPosX() const +{ + return m_posX; +} + + +float GameObj::GetPosY() const +{ + return m_posY; +} + + +void GameObj::SetPos(const float a_x, const float a_y) +{ + m_posX = a_x; + m_posY = a_y; + + App::Get()->ClipScreenCoordsf(m_posX, m_posY); + + m_destX = m_posX; + m_destY = m_posY; +} + + +void GameObj::MoveTo(const float a_x, const float a_y) +{ + m_destX = a_x; + m_destY = a_y; + + App::Get()->ClipScreenCoordsf(m_destX, m_destY); +} + + +void GameObj::SetSpeed(const float a_speed) +{ + m_speed = a_speed; +} + + +float GameObj::GetSpeed() +{ + return m_speed; +} + + +void GameObj::SetColor(int a_colorIndex) +{ + if(a_colorIndex >= App::COLOR_MIN && a_colorIndex < App::COLOR_MAX) + { + m_colorIndex = a_colorIndex; + } +} + + +void GameObj::Update(float a_deltaTime) +{ + // NOTE: A real game would probably not update each object each frame + // but instead only update an object in a particular way when required. + // This example will do all updating in one place, and do so each frame. + + // Update movement + { + float dx = m_destX - m_posX; + float dy = m_destY - m_posY; + + float len2 = dx*dx + dy*dy; + + if(len2 > 0.0f) + { + float moveThisFrame = a_deltaTime * m_speed; + float distToGo = sqrtf(len2); + + // We can reach dest this frame + if(moveThisFrame > distToGo) + { + m_posX = m_destX; + m_posY = m_destY; + } + else + { + m_posX += dx * moveThisFrame; + m_posY += dy * moveThisFrame; + } + } + } +} + + +void GameObj::Render() +{ + +} + + +////////////////////////////////////////////////// +// Script +////////////////////////////////////////////////// + + +int GM_CDECL GameObj::GameObj_MoveTo(gmThread* a_thread) +{ + GM_CHECK_NUM_PARAMS(2); + GM_CHECK_FLOAT_PARAM(destX, 0); + GM_CHECK_FLOAT_PARAM(destY, 1); + GameObj* thisPtr = GetThisGameObj(a_thread); + if(!thisPtr) + { + return GM_EXCEPTION; + } + + thisPtr->MoveTo(destX, destY); + + return GM_OK; +} + + +int GM_CDECL GameObj::GameObj_SetPos(gmThread* a_thread) +{ + GM_CHECK_NUM_PARAMS(2); + GM_CHECK_FLOAT_PARAM(posX, 0); + GM_CHECK_FLOAT_PARAM(posY, 1); + GameObj* thisPtr = GetThisGameObj(a_thread); + if(!thisPtr) + { + return GM_EXCEPTION; + } + + thisPtr->SetPos(posX, posY); + + return GM_OK; +} + + +int GM_CDECL GameObj::GameObj_GetPosX(gmThread* a_thread) +{ + GM_CHECK_NUM_PARAMS(0); + GameObj* thisPtr = GetThisGameObj(a_thread); + if(!thisPtr) + { + return GM_EXCEPTION; + } + + a_thread->PushFloat(thisPtr->GetPosX()); + + return GM_OK; +} + + +int GM_CDECL GameObj::GameObj_GetPosY(gmThread* a_thread) +{ + GM_CHECK_NUM_PARAMS(0); + GameObj* thisPtr = GetThisGameObj(a_thread); + if(!thisPtr) + { + return GM_EXCEPTION; + } + + a_thread->PushFloat(thisPtr->GetPosY()); + + return GM_OK; +} + + +int GM_CDECL GameObj::GameObj_IsValid(gmThread* a_thread) +{ + GM_CHECK_NUM_PARAMS(0); + GameObj* thisPtr = GetThisGameObj(a_thread); + if(!thisPtr) + { + a_thread->PushInt(false); + } + else + { + a_thread->PushInt(true); + } + + return GM_OK; +} + + + +int GM_CDECL GameObj::GameObj_SetSpeed(gmThread* a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_FLOAT_PARAM(speed, 0); + GameObj* thisPtr = GetThisGameObj(a_thread); + if(!thisPtr) + { + return GM_EXCEPTION; + } + + thisPtr->SetSpeed(speed); + + return GM_OK; +} + + +int GM_CDECL GameObj::GameObj_GetSpeed(gmThread* a_thread) +{ + GM_CHECK_NUM_PARAMS(0); + GameObj* thisPtr = GetThisGameObj(a_thread); + if(!thisPtr) + { + return GM_EXCEPTION; + } + + a_thread->PushFloat(thisPtr->GetSpeed()); + + return GM_OK; +} + + +int GM_CDECL GameObj::GameObj_SetColor(gmThread* a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_INT_PARAM(colorIndex, 0); + GameObj* thisPtr = GetThisGameObj(a_thread); + if(!thisPtr) + { + return GM_EXCEPTION; + } + + thisPtr->SetColor(colorIndex); + + return GM_OK; +} + + +void GameObj::RegisterScriptBindings() +{ + static gmFunctionEntry gameObjTypeLib[] = + { + /*gm + \lib GameObj + \brief Game Object class + */ + /*gm + \function SetPos + \brief Set position + \param float a_posX New position X component + \param float a_posY New position Y component + */ + {"SetPos", GameObj_SetPos}, + /*gm + \function GetPosX + \brief Get position X + \return float Get position X component. + */ + {"GetPosX", GameObj_GetPosX}, + /*gm + \function GetPosY + \brief Get position Y + \return float Get position Y component. + */ + {"GetPosY", GameObj_GetPosY}, + /*gm + \function IsValid + \brief Is this a valid object, or has it been deleted or such + \return int true if valid + */ + {"IsValid", GameObj_IsValid}, + /*gm + \function SetSpeed + \brief Set speed + \param a_speed New speed + */ + {"SetSpeed", GameObj_SetSpeed}, + /*gm + \function GetSpeed + \brief Get speed + \return float Current speed + */ + {"GetSpeed", GameObj_GetSpeed}, + /*gm + \function SetColor + \brief Set color + \param a_color New color + */ + {"SetColor", GameObj_SetColor}, + + }; + + ScriptSys::Get()->GetMachine()->RegisterTypeLibrary(ScriptObj::GMTYPE_GAMEOBJ, gameObjTypeLib, sizeof(gameObjTypeLib) / sizeof(gameObjTypeLib[0])); +} diff --git a/vscript/languages/gm/src/examples/GameObject/GameObj.h b/vscript/languages/gm/src/examples/GameObject/GameObj.h new file mode 100644 index 00000000..c345d0af --- /dev/null +++ b/vscript/languages/gm/src/examples/GameObject/GameObj.h @@ -0,0 +1,61 @@ +#ifndef GAMEOBJ_H +#define GAMEOBJ_H + +#include "gmThread.h" + +// +// GameObj.h +// +// Example game object that uses the script interface component +// + +// Fwd decls +class ScriptObj; + + + +class GameObj +{ +public: + + GameObj(); + virtual ~GameObj(); + + ScriptObj* GetScriptObj() { return m_scriptObj; } + + float GetPosX() const; + float GetPosY() const; + void SetPos(const float a_x, const float a_y); + void MoveTo(const float a_x, const float a_y); + void SetSpeed(const float a_speed); + float GetSpeed(); + void SetColor(int a_colorIndex); + + void Update(float a_deltaTime); + void Render(); + + static void RegisterScriptBindings(); + +private: + + static int GM_CDECL GameObj_SetPos(gmThread* a_thread); + static int GM_CDECL GameObj_GetPosX(gmThread* a_thread); + static int GM_CDECL GameObj_GetPosY(gmThread* a_thread); + static int GM_CDECL GameObj_IsValid(gmThread* a_thread); + static int GM_CDECL GameObj_MoveTo(gmThread* a_thread); + static int GM_CDECL GameObj_SetSpeed(gmThread* a_thread); + static int GM_CDECL GameObj_GetSpeed(gmThread* a_thread); + static int GM_CDECL GameObj_SetColor(gmThread* a_thread); + + ScriptObj* m_scriptObj; + float m_posX; + float m_posY; + float m_destX; + float m_destY; + float m_speed; + int m_colorIndex; + +}; + + +#endif //GAMEOBJ_H \ No newline at end of file diff --git a/vscript/languages/gm/src/examples/GameObject/GameObject.dsp b/vscript/languages/gm/src/examples/GameObject/GameObject.dsp new file mode 100644 index 00000000..297801a9 --- /dev/null +++ b/vscript/languages/gm/src/examples/GameObject/GameObject.dsp @@ -0,0 +1,470 @@ +# Microsoft Developer Studio Project File - Name="GameObject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=GameObject - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "GameObject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "GameObject.mak" CFG="GameObject - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "GameObject - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "GameObject - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "Perforce Project" +# PROP Scc_LocalPath "..\.." +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "GameObject - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\gm" /I "..\..\platform\win32msvc" /I "..\..\binds" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0xc09 /d "NDEBUG" +# ADD RSC /l 0xc09 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "GameObject - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\gm" /I "..\..\platform\win32msvc" /I "..\..\binds" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0xc09 /d "_DEBUG" +# ADD RSC /l 0xc09 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "GameObject - Win32 Release" +# Name "GameObject - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\App.cpp +# End Source File +# Begin Source File + +SOURCE=.\App.h +# End Source File +# Begin Source File + +SOURCE=.\GameObj.cpp +# End Source File +# Begin Source File + +SOURCE=.\GameObj.h +# End Source File +# Begin Source File + +SOURCE=.\InputKBWin32.cpp +# End Source File +# Begin Source File + +SOURCE=.\InputKBWin32.h +# End Source File +# Begin Source File + +SOURCE=.\main.cpp +# End Source File +# Begin Source File + +SOURCE=.\NetClient.cpp +# End Source File +# Begin Source File + +SOURCE=.\NetClient.h +# End Source File +# Begin Source File + +SOURCE=.\ReadMe.txt +# End Source File +# Begin Source File + +SOURCE=.\ScriptObj.cpp +# End Source File +# Begin Source File + +SOURCE=.\ScriptObj.h +# End Source File +# Begin Source File + +SOURCE=.\ScriptSys.cpp +# End Source File +# Begin Source File + +SOURCE=.\ScriptSys.h +# End Source File +# Begin Source File + +SOURCE=.\StdStuff.cpp +# End Source File +# Begin Source File + +SOURCE=.\StdStuff.h +# End Source File +# Begin Source File + +SOURCE=.\TestGameObj.gm +# End Source File +# End Group +# Begin Group "gm" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\gm\gmArraySimple.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmArraySimple.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmByteCode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmByteCode.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmByteCodeGen.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmByteCodeGen.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmCodeGen.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmCodeGen.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmCodeGenHooks.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmCodeGenHooks.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmCodeTree.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmCodeTree.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmConfig.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmCrc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmDebug.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmDebug.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmFunctionObject.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmFunctionObject.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmHash.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmHash.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmIncGC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmIncGC.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmIterator.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmLibHooks.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmLibHooks.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmListDouble.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmListDouble.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmLog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmLog.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMachine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMachine.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMachineLib.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMachineLib.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMem.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMem.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMemChain.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMemChain.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMemFixed.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMemFixed.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMemFixedSet.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMemFixedSet.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmOperators.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmOperators.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmParser.cpp.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmScanner.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmScanner.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmStreamBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmStreamBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmStringObject.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmStringObject.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmTableObject.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmTableObject.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmThread.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmThread.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmUserObject.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmUserObject.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmUtil.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmUtil.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmVariable.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmVariable.h +# End Source File +# End Group +# Begin Group "gmBinds" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\binds\gmCall.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\binds\gmCall.h +# End Source File +# Begin Source File + +SOURCE=..\..\binds\gmHelpers.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\binds\gmHelpers.h +# End Source File +# Begin Source File + +SOURCE=..\..\binds\gmMathLib.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\binds\gmMathLib.h +# End Source File +# Begin Source File + +SOURCE=..\..\binds\gmStringLib.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\binds\gmStringLib.h +# End Source File +# Begin Source File + +SOURCE=..\..\binds\gmSystemLib.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\binds\gmSystemLib.h +# End Source File +# End Group +# Begin Group "gmConfig" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\platform\win32msvc\gmConfig_p.h +# End Source File +# End Group +# End Target +# End Project diff --git a/vscript/languages/gm/src/examples/GameObject/GameObject.dsw b/vscript/languages/gm/src/examples/GameObject/GameObject.dsw new file mode 100644 index 00000000..cb438466 --- /dev/null +++ b/vscript/languages/gm/src/examples/GameObject/GameObject.dsw @@ -0,0 +1,33 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "GameObject"=.\GameObject.dsp - Package Owner=<4> + +Package=<5> +{{{ + begin source code control + Perforce Project + ..\.. + end source code control +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/vscript/languages/gm/src/examples/GameObject/GameObject.vcproj b/vscript/languages/gm/src/examples/GameObject/GameObject.vcproj new file mode 100644 index 00000000..87cecc7f --- /dev/null +++ b/vscript/languages/gm/src/examples/GameObject/GameObject.vcproj @@ -0,0 +1,1383 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/gm/src/examples/GameObject/InputKBWin32.cpp b/vscript/languages/gm/src/examples/GameObject/InputKBWin32.cpp new file mode 100644 index 00000000..7583c737 --- /dev/null +++ b/vscript/languages/gm/src/examples/GameObject/InputKBWin32.cpp @@ -0,0 +1,102 @@ +// +// InputKBWin32.cpp +// + +#include +#include "InputKBWin32.h" + +// Init statics and constants +InputKBWin32 InputKBWin32::s_staticInstance; + + + +InputKBWin32::InputKBWin32() +{ + m_keyDownBufferIndex = 0; + + Init(); +} + + + +InputKBWin32::~InputKBWin32() +{ +} + + +void InputKBWin32::Init() +{ + for(int kIndex=0; kIndex=0) && (a_keyIndex < MAX_KEYS)); + return m_keyStatus[a_keyIndex]; + } + + /// Was key pressed this frame? (Non-zero if true) + inline int IsKeyPressed(int a_keyIndex) + { + GM_ASSERT((a_keyIndex >= 0) && (a_keyIndex < MAX_KEYS)); + return (m_keyStatus[a_keyIndex] & KEY_STATUS_PRESSED); + } + + /// Is key down this frame? (Non-zero if true) + inline int IsKeyDown(int a_keyIndex) + { + GM_ASSERT((a_keyIndex >= 0) && (a_keyIndex < MAX_KEYS)); + return (m_keyStatus[a_keyIndex] & KEY_STATUS_DOWN); + } + + /// Was key released this frame? (Non-zero if true) + inline int IsKeyRelesed(int a_keyIndex) + { + GM_ASSERT((a_keyIndex >= 0) && (a_keyIndex < MAX_KEYS)); + return (m_keyStatus[a_keyIndex] & KEY_STATUS_RELEASED); + } + + /// Is key up this frame? (Non-zero if true) + inline int IsKeyUp(int a_keyIndex) + { + GM_ASSERT((a_keyIndex >= 0) && (a_keyIndex < MAX_KEYS)); + return (m_keyStatus[a_keyIndex] & KEY_STATUS_UP); + } + + +private: + + /// Constructor, non-public to prevent multiple instances + InputKBWin32(); + + char m_keyDownBuffer[2][MAX_KEYS]; ///< Store current and last frame snapshot + int m_keyDownBufferIndex; ///< Index to swap buffers for current and last frame + int m_keyStatus[MAX_KEYS]; ///< Status of keys for this frame, persists until updated. + + static InputKBWin32 s_staticInstance; ///< Single instance of this class +}; + + +#endif //INPUTKBWIN32_H \ No newline at end of file diff --git a/vscript/languages/gm/src/examples/GameObject/NetClient.cpp b/vscript/languages/gm/src/examples/GameObject/NetClient.cpp new file mode 100644 index 00000000..631e4d15 --- /dev/null +++ b/vscript/languages/gm/src/examples/GameObject/NetClient.cpp @@ -0,0 +1,356 @@ +// See Copyright Notice in gmMachine.h + +#include "NetClient.h" +#include +#include // Requires Multi threaded library for _beginthread and _endthread +#include +#include +#include +#include // Requires Ws2_32.lib +#include + +#undef SendMessage // stupid windows + +// These two are for MSVS 2005 security consciousness until safe std lib funcs are available +#pragma warning(disable : 4996) // Deprecated functions +#define _CRT_SECURE_NO_DEPRECATE // Allow old unsecure standard library functions, Disable some 'warning C4996 - function was deprecated' + + +struct nPacket +{ + int id; // id == 0x4fe27d9a + int len; +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// QUEUE +// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +struct nQueueNode +{ + char * m_buffer; + int m_len; + nQueueNode * m_next; +}; + +class nQueue +{ +public: + nQueue() + { + m_queue = NULL; + m_lastDeQueue = NULL; + m_mutex = CreateMutex(NULL, FALSE, NULL); + } + + ~nQueue() + { + WaitForSingleObject(m_mutex, INFINITE); + + int a; + while(DeQueue(a)); + DeQueue(a); + + ReleaseMutex(m_mutex); + + // destroy mutex... todo + } + + bool EnQueue(const char * a_buffer, int a_len) + { + WaitForSingleObject(m_mutex, INFINITE); + + nQueueNode * node = new nQueueNode; + node->m_len = a_len; + node->m_buffer = new char[a_len]; + memcpy(node->m_buffer, a_buffer, a_len); + node->m_next = NULL; + + // add to end of list + nQueueNode ** n = &m_queue; + while(*n) n = &(*n)->m_next; + *n = node; + + ReleaseMutex(m_mutex); + + return true; + } + + const char * DeQueue(int &a_len) + { + const char * ret = NULL; + + WaitForSingleObject(m_mutex, INFINITE); + + if(m_lastDeQueue) + { + delete[] m_lastDeQueue->m_buffer; + delete m_lastDeQueue; + m_lastDeQueue = NULL; + } + + if(m_queue) + { + m_lastDeQueue = m_queue; + m_queue = m_queue->m_next; + a_len = m_lastDeQueue->m_len; + ret = m_lastDeQueue->m_buffer; + } + + ReleaseMutex(m_mutex); + + return ret; + } + + bool IsEmpty() { return (m_queue == NULL); } + +private: + + HANDLE m_mutex; + + nQueueNode * m_lastDeQueue; + nQueueNode * m_queue; +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// CLIENT +// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +struct nClientData +{ + SOCKET client; + nQueue messages; + CRITICAL_SECTION criticalSection; + bool threadAlive; +}; + + + +nClient::nClient() +{ + nClientData * cd = new nClientData; + cd->threadAlive = false; + cd->client = INVALID_SOCKET; + InitializeCriticalSection(&cd->criticalSection); + m_data = cd; +} + + + +nClient::~nClient() +{ + Close(); + nClientData * cd = (nClientData *) m_data; + DeleteCriticalSection(&cd->criticalSection); + delete cd; +} + + + +void nClient::Close() +{ + nClientData * cd = (nClientData *) m_data; + EnterCriticalSection(&cd->criticalSection); + + if(cd->client != INVALID_SOCKET) + { + closesocket(cd->client); + cd->client = INVALID_SOCKET; + } + + LeaveCriticalSection(&cd->criticalSection); + + // wait for the thread to die. + while(cd->threadAlive) + { + _sleep(0); + } + + WSACleanup(); +} + + + +bool nClient::IsConnected() +{ + bool result = false; + nClientData * cd = (nClientData *) m_data; + EnterCriticalSection(&cd->criticalSection); + if(cd->client != INVALID_SOCKET) + { + result = true; + } + LeaveCriticalSection(&cd->criticalSection); + return result; +} + + + +bool nClient::SendMessage(const char * a_buffer, int a_len) +{ + bool res = false; + nClientData * cd = (nClientData *) m_data; + nPacket packet; + packet.id = 0x4fe27d9a; + packet.len = a_len; + + EnterCriticalSection(&cd->criticalSection); + if(cd->client != INVALID_SOCKET) + { + send(cd->client, (const char *) &packet, sizeof(nPacket), 0); + send(cd->client, (const char *) a_buffer, a_len, 0); + res = true; + } + LeaveCriticalSection(&cd->criticalSection); + return res; +} + + + +const char * nClient::PumpMessage(int &a_len) +{ + nClientData * cd = (nClientData *) m_data; + const char * buffer = cd->messages.DeQueue(a_len); + return buffer; +} + + + +void nClientThread(void * param) +{ + nClientData * cd = (nClientData *) param; + EnterCriticalSection(&cd->criticalSection); + cd->threadAlive = true; + SOCKET client = cd->client; + LeaveCriticalSection(&cd->criticalSection); + + char * dbuffer = NULL; + char buffer[4096]; + char * sbp; + int state = 0; // 0 searching for packet, 1 getting message + int need = sizeof(nPacket); + + // packet header + nPacket packet; + char * dbp = (char *) &packet; + + // packet data + int dbufferSize = 0, n; + + // read loop + for(;;) + { + // read + n = recv(client, buffer, 4096, 0); + if(n == SOCKET_ERROR || n == 0) break; + sbp = buffer; + + // consume + while(n > 0) + { + int have = (n > need) ? need : n; + need -= have; + n -= have; + memcpy(dbp, sbp, have); + sbp += have; + dbp += have; + + // can we change state? + if(need == 0) + { + if(state == 0) + { + if(packet.id != 0x4fe27d9a) goto terror; + state = 1; + need = packet.len; + + // allocate the dbuffer + if(need > dbufferSize) + { + if(dbuffer) { delete[] dbuffer; } + dbufferSize = need + 512; + dbuffer = new char[dbufferSize]; + } + dbp = dbuffer; + } + else if(state == 1) + { + cd->messages.EnQueue(dbuffer, packet.len); + dbp = (char *) &packet; + need = sizeof(nPacket); + state = 0; + } + } + } + } + +terror: + + if(dbuffer) { delete[] dbuffer; } + + EnterCriticalSection(&cd->criticalSection); + cd->threadAlive = false; + LeaveCriticalSection(&cd->criticalSection); + + _endthread(); +} + + + +bool nClient::Connect(const char * a_server, short a_port) +{ + WSADATA wsaData; + struct hostent *hp; + unsigned int addr; + struct sockaddr_in server; + + int wsaret=WSAStartup(0x101,&wsaData); + if(wsaret) + return false; + + SOCKET conn; + + conn = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); + if(conn==INVALID_SOCKET) + return false; + + addr=inet_addr(a_server); + hp=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET); + + if(hp==NULL) + { + closesocket(conn); + return false; + } + + server.sin_addr.s_addr=*((unsigned long*)hp->h_addr); + server.sin_family=AF_INET; + server.sin_port=htons((u_short) a_port); + + if(connect(conn,(struct sockaddr*)&server,sizeof(server))) + { + closesocket(conn); + return false; + } + + nClientData * cd = (nClientData *) m_data; + EnterCriticalSection(&cd->criticalSection); + cd->client = conn; + LeaveCriticalSection(&cd->criticalSection); + + _beginthread(nClientThread, 0, cd); + _sleep(0); + + return true; +} + diff --git a/vscript/languages/gm/src/examples/GameObject/NetClient.h b/vscript/languages/gm/src/examples/GameObject/NetClient.h new file mode 100644 index 00000000..fa203141 --- /dev/null +++ b/vscript/languages/gm/src/examples/GameObject/NetClient.h @@ -0,0 +1,30 @@ +#ifndef _NETCLIENT_H_ +#define _NETCLIENT_H_ + +// See Copyright Notice in gmMachine.h + +#undef SendMessage // windows clash + +// +// nClient +// +class nClient +{ +public: + nClient(); + ~nClient(); + + bool Connect(const char * a_server, short a_port); + void Close(); + bool IsConnected(); + + bool SendMessage(const char * a_buffer, int a_len); + const char * PumpMessage(int &a_len); + +private: + + void * m_data; +}; + + +#endif //_NETCLIENT_H_ \ No newline at end of file diff --git a/vscript/languages/gm/src/examples/GameObject/ReadMe.txt b/vscript/languages/gm/src/examples/GameObject/ReadMe.txt new file mode 100644 index 00000000..838030c9 --- /dev/null +++ b/vscript/languages/gm/src/examples/GameObject/ReadMe.txt @@ -0,0 +1,10 @@ +This example is simply one way to implement 'Game Objects'. The example is a work in +progress, and is included because some of the code may provide useful to look at. + + +TODO +o make 'triggers' and 'units' +o make IsUnitInSquare function to clip movement +o use states for units to be 'player' 'following' 'mental' +o make triggers that change unit color and triggers that create mental state if not player +o highlight player by color and allow player to cycle through units to control \ No newline at end of file diff --git a/vscript/languages/gm/src/examples/GameObject/ScriptObj.cpp b/vscript/languages/gm/src/examples/GameObject/ScriptObj.cpp new file mode 100644 index 00000000..d552dca2 --- /dev/null +++ b/vscript/languages/gm/src/examples/GameObject/ScriptObj.cpp @@ -0,0 +1,326 @@ +// +// ScriptObj.cpp +// + +#include "gmCall.h" +#include "ScriptObj.h" +#include "ScriptSys.h" +#include "GameObj.h" + + +// Init statics and constants +gmType ScriptObj::GMTYPE_GAMEOBJ = -1; + + +ScriptObj::ScriptObj(GameObj* a_gameObj) +{ + GM_ASSERT(ScriptSys::Get()); + + m_userObject = NULL; // A user object will be created when it is first used, and shared by all script variables. + m_gameObj = a_gameObj; + m_tableObject = ScriptSys::Get()->GetMachine()->AllocTableObject(); + + ScriptSys::Get()->GetMachine()->AddCPPOwnedGMObject(m_tableObject); +} + + +ScriptObj::~ScriptObj() +{ + // Stop related threads + KillThreads(); + + if(m_userObject) + { + // Nullify script link to C object + m_userObject->m_user = NULL; + } + + // Destruct the gmObjects +#if GM_USE_INCGC + // Do nothing, it will be collected later, just nullify all reference to it +#else + if(m_userObject) + { + m_userObject->Destruct(ScriptSys::Get()->GetMachine()); + } + m_tableObject->Destruct(ScriptSys::Get()->GetMachine()); +#endif + + // Remove object from the list of all objects + ScriptSys::Get()->GetMachine()->RemoveCPPOwnedGMObject(m_tableObject); + if( m_userObject ) + { + ScriptSys::Get()->GetMachine()->RemoveCPPOwnedGMObject(m_userObject); + } +} + + +gmUserObject* ScriptObj::GetUserObject() +{ + if(!m_userObject) + { + m_userObject = ScriptSys::Get()->GetMachine()->AllocUserObject(this, GMTYPE_GAMEOBJ); + ScriptSys::Get()->GetMachine()->AddCPPOwnedGMObject(m_userObject); + } + + return m_userObject; +} + + +void ScriptObj::KillThreads() +{ + for(unsigned int tIndex=0; tIndexRemoveThreadIdButDontTouchGameObj(m_threads[tIndex]); + ScriptSys::Get()->GetMachine()->KillThread(m_threads[tIndex]); + } + m_threads.Reset(); +} + + +void ScriptObj::ExecuteStringOnThis(const char* a_string) +{ + gmMachine* machine = ScriptSys::Get()->GetMachine(); + gmVariable thisVar; + thisVar.SetUser(GetUserObject()); + int threadId = GM_INVALID_THREAD; + + int errors = machine->ExecuteString(a_string, &threadId, true, NULL, &thisVar); + if(errors) + { + bool first = true; + const char * message; + while((message = machine->GetLog().GetEntry(first))) + { + ScriptSys::Get()->LogError("%s\n", message); + } + machine->GetLog().Reset(); + } + else + { + ScriptSys::Get()->AssociateThreadIdWithGameObj(threadId, *GetGameObj()); + } +} + + +bool ScriptObj::ExecuteGlobalFunctionOnThis(const char* a_functionName) +{ + gmVariable thisVar; + thisVar.SetUser(GetUserObject()); + + gmCall call; + if(call.BeginGlobalFunction(ScriptSys::Get()->GetMachine(), a_functionName, thisVar, false)) + { + call.End(); + return true; + } + + return false; +} + + +void ScriptObj::SetMemberInt(const char* a_memberName, int a_int) +{ + ScriptSys::Get()->SetTableInt(a_memberName, a_int, m_tableObject); +} + + +void ScriptObj::SetMemberFloat(const char* a_memberName, float a_float) +{ + ScriptSys::Get()->SetTableFloat(a_memberName, a_float, m_tableObject); +} + + +void ScriptObj::SetMemberString(const char* a_memberName, const char* a_string, int a_strLength) +{ + ScriptSys::Get()->SetTableString(a_memberName, a_string, a_strLength, m_tableObject); +} + + +void ScriptObj::SetMemberGameObj(const char* a_memberName, GameObj* a_gameObj) +{ + ScriptSys::Get()->SetTableGameObj(a_memberName, a_gameObj, m_tableObject); +} + + +gmTableObject* ScriptObj::SetMemberTable(const char* a_memberName) +{ + return ScriptSys::Get()->SetTableTable(a_memberName, m_tableObject); +} + + +bool ScriptObj::GetMemberInt(const char* a_memberName, int& a_int) +{ + return ScriptSys::Get()->GetTableInt(a_memberName, a_int, m_tableObject); +} + + +bool ScriptObj::GetMemberFloat(const char* a_memberName, float& a_float) +{ + return ScriptSys::Get()->GetTableFloat(a_memberName, a_float, m_tableObject); +} + + +bool ScriptObj::GetMemberString(const char* a_memberName, String& a_string) +{ + return ScriptSys::Get()->GetTableString(a_memberName, a_string, m_tableObject); +} + + +bool ScriptObj::GetMemberGameObj(const char* a_memberName, GameObj*& a_gameObj) +{ + return ScriptSys::Get()->GetTableGameObj(a_memberName, a_gameObj, m_tableObject); +} + + +bool ScriptObj::GetMemberTable(const char* a_memberName, gmTableObject*& a_retTable) +{ + return ScriptSys::Get()->GetTableTable(a_memberName, a_retTable, m_tableObject); +} + + +void GM_CDECL ScriptObj::GameObjCallback_AsString(gmUserObject * a_object, char* a_buffer, int a_bufferLen) +{ + char mixBuffer[128]; + + ScriptObj* scriptObj = (ScriptObj*)a_object->m_user; + GameObj* gameObjPtr = NULL; + + if(scriptObj) + { + gameObjPtr = scriptObj->GetGameObj(); + } + + sprintf(mixBuffer,"CPtr: %x", gameObjPtr); + + int mixLength = strlen(mixBuffer); + int useLength = gmMin(mixLength, a_bufferLen-1); + GM_ASSERT(useLength > 0); + strncpy(a_buffer, mixBuffer, useLength); + a_buffer[useLength] = 0; +} + + +#if GM_USE_INCGC + +bool GM_CDECL ScriptObj::GameObjCallback_GCTrace(gmMachine * a_machine, gmUserObject* a_object, gmGarbageCollector* a_gc, const int a_workRemaining, int& a_workDone) +{ + GM_ASSERT(a_object->m_userType == GMTYPE_GAMEOBJ); + ScriptObj* scriptObj = (ScriptObj*)a_object->m_user; + + if(scriptObj) + { + a_gc->GetNextObject(scriptObj->GetTableObject()); + } + a_workDone +=2; + return true; +} + + +void GM_CDECL ScriptObj::GameObjCallback_GCDestruct(gmMachine * a_machine, gmUserObject * a_object) +{ + GM_ASSERT(a_object->m_userType == GMTYPE_GAMEOBJ); + ScriptObj* scriptObj = (ScriptObj*)a_object->m_user; + + if(scriptObj) + { + scriptObj->m_userObject = NULL; + } +} + +#else //GM_USE_INCGC + +void GM_CDECL ScriptObj::GameObjCallback_GCMark(gmMachine * a_machine, gmUserObject * a_object, gmuint32 a_mark) +{ + GM_ASSERT(a_object->m_userType == GMTYPE_GAMEOBJ); + ScriptObj* scriptObj = (ScriptObj*)a_object->m_user; + + if(scriptObj) + { + if(scriptObj->GetTableObject()->NeedsMark(a_mark)) + { + scriptObj->GetTableObject()->Mark(a_machine, a_mark); + } + } +} + + +void GM_CDECL ScriptObj::GameObjCallback_GCCollect(gmMachine * a_machine, gmUserObject * a_object, gmuint32 a_mark) +{ + GM_ASSERT(a_object->m_userType == GMTYPE_GAMEOBJ); + ScriptObj* scriptObj = (ScriptObj*)a_object->m_user; + + if(scriptObj) + { + scriptObj->m_userObject = NULL; + } +} + +#endif //GM_USE_INCGC + + +// NOTE: If you wanted to enable other dot operator behavior +// here is the place to do it, in the GetDot and SetDot operators. +// This example merely uses the gmTable embedded in the GameObj +// to allow script functions and data to be members of this object type. +// GameObj also registers 'type' functions that are accessed via the +// dot operator. + + +void GM_CDECL ScriptObj::GameObj_GetDot(gmThread * a_thread, gmVariable * a_operands) +{ + //O_GETDOT = 0, // object, "member" (tos is a_operands + 2) + GM_ASSERT(a_operands[0].m_type == GMTYPE_GAMEOBJ); + + gmUserObject* userObj = (gmUserObject*) GM_OBJECT(a_operands[0].m_value.m_ref); + ScriptObj* scriptObj = (ScriptObj*)userObj->m_user; + + if(!scriptObj) + { + a_operands[0].Nullify(); + + return; + } + + a_operands[0] = scriptObj->GetTableObject()->Get(a_operands[1]); +} + + +void GM_CDECL ScriptObj::GameObj_SetDot(gmThread * a_thread, gmVariable * a_operands) +{ + //O_SETDOT, // object, value, "member" (tos is a_operands + 3) + GM_ASSERT(a_operands[0].m_type == GMTYPE_GAMEOBJ); + + gmUserObject* userObj = (gmUserObject*) GM_OBJECT(a_operands[0].m_value.m_ref); + ScriptObj* scriptObj = (ScriptObj*)userObj->m_user; + + if(scriptObj) + { + scriptObj->GetTableObject()->Set(a_thread->GetMachine(), a_operands[2], a_operands[1]); + } +} + + +void ScriptObj::RegisterScriptBindings() +{ + gmMachine* machine = ScriptSys::Get()->GetMachine(); + + GM_ASSERT(machine); + + // Register new user type + GMTYPE_GAMEOBJ = machine->CreateUserType("GameObj"); + // Register garbage collection for our new type +#if GM_USE_INCGC + machine->RegisterUserCallbacks(GMTYPE_GAMEOBJ, GameObjCallback_GCTrace, GameObjCallback_GCDestruct, GameObjCallback_AsString); +#else //GM_USE_INCGC + machine->RegisterUserCallbacks(GMTYPE_GAMEOBJ, GameObjCallback_GCMark, GameObjCallback_GCCollect, GameObjCallback_AsString); +#endif //GM_USE_INCGC + // Bind Get dot operator for our type + machine->RegisterTypeOperator(GMTYPE_GAMEOBJ, O_GETDOT, NULL, GameObj_GetDot); + // Bind Set dot operator for our type + machine->RegisterTypeOperator(GMTYPE_GAMEOBJ, O_SETDOT, NULL, GameObj_SetDot); + // Bind functions +// machine->RegisterLibrary(regFuncList, sizeof(regFuncList) / sizeof(regFuncList[0])); + // Bind type functions +// machine->RegisterTypeLibrary(GM_GOB, regTypeFuncList, sizeof(regTypeFuncList) / sizeof(regTypeFuncList[0])); +} \ No newline at end of file diff --git a/vscript/languages/gm/src/examples/GameObject/ScriptObj.h b/vscript/languages/gm/src/examples/GameObject/ScriptObj.h new file mode 100644 index 00000000..50cbd78f --- /dev/null +++ b/vscript/languages/gm/src/examples/GameObject/ScriptObj.h @@ -0,0 +1,165 @@ +#ifndef SCRIPTOBJ_H +#define SCRIPTOBJ_H + +// +// ScriptObj.h +// +// Example script interface component for game object +// + +#include "gmThread.h" +#include "StdStuff.h" + +// Fwd decls +class GameObj; + + +// NOTE: In this implementation, the 'gmUserObject' only exists when the cpp object is used or needed by script. +// This implementation also shares that single user object amongst all referencing variables in script. +// Because of this, the cpp code does not need to handle the user object as if it were owned by cpp. +// The cpp object does however always contain a gmTableObject, and this is owned by cpp as it may not +// exist (be referenced) within the script. For this reason, the gmTableObject must be handled as a +// cpp owned object to allow correct GC handling. +// +// An alternate method, would be to always have a gmUserObject and let cpp code own this. This +// user object would be the root of its own child objects like the gmTableObject. This method may +// be simpler. +// + +// Script interface for game objects +class ScriptObj +{ +public: + + static gmType GMTYPE_GAMEOBJ; ///< The user type of a game object + + static void RegisterScriptBindings(); ///< Register game object script bindings + + ScriptObj(GameObj* a_gameObj); + virtual ~ScriptObj(); + + GameObj* GetGameObj() { return m_gameObj; } + + gmTableObject* GetTableObject() { return m_tableObject; } + gmUserObject* GetUserObject(); + + void AddThreadId(int a_threadId) + { + m_threads.InsertLast(a_threadId); + } + + void RemoveThreadId(int a_threadId) + { + for(unsigned int tIndex=0; tIndex < m_threads.GetSize(); ++tIndex) + { + if(m_threads[tIndex] == a_threadId) + { + m_threads.RemoveSwapLast(tIndex); + } + } + } + + /// Kill all threads running on this object + void KillThreads(); + + void ExecuteStringOnThis(const char* a_string); + + bool ExecuteGlobalFunctionOnThis(const char* a_functionName); + + void SetMemberInt(const char* a_memberName, int a_int); + void SetMemberFloat(const char* a_memberName, float a_float); + void SetMemberString(const char* a_memberName, const char* a_string, int a_strLength = -1); + void SetMemberGameObj(const char* a_memberName, GameObj* a_gameObj); + gmTableObject* SetMemberTable(const char* a_memberName); + + bool GetMemberInt(const char* a_memberName, int& a_int); + bool GetMemberFloat(const char* a_memberName, float& a_float); + bool GetMemberString(const char* a_memberName, String& a_string); + bool GetMemberGameObj(const char* a_memberName, GameObj*& a_gameObj); + bool GetMemberTable(const char* a_memberName, gmTableObject*& a_retTable); + +protected: + + static void GM_CDECL GameObjCallback_AsString(gmUserObject * a_object, char* a_buffer, int a_bufferLen); +#if GM_USE_INCGC + static bool GM_CDECL GameObjCallback_GCTrace(gmMachine * a_machine, gmUserObject* a_object, gmGarbageCollector* a_gc, const int a_workRemaining, int& a_workDone); + static void GM_CDECL GameObjCallback_GCDestruct(gmMachine * a_machine, gmUserObject * a_object); +#else //GM_USE_INCGC + static void GM_CDECL GameObjCallback_GCMark(gmMachine * a_machine, gmUserObject * a_object, gmuint32 a_mark); + static void GM_CDECL GameObjCallback_GCCollect(gmMachine * a_machine, gmUserObject * a_object, gmuint32 a_mark); +#endif //GM_USE_INCGC + static void GM_CDECL GameObj_GetDot(gmThread * a_thread, gmVariable * a_operands); + static void GM_CDECL GameObj_SetDot(gmThread * a_thread, gmVariable * a_operands); + + GameObj* m_gameObj; ///< The game object owner of this interface + gmUserObject* m_userObject; ///< The script object + gmTableObject* m_tableObject; ///< Table functionality for script object members + gmArraySimple m_threads; ///< Threads associated with this game object + +}; + +/* +/// \brief Get 'this' as GameObj of TYPE +/// Eg. Soldier* obj = GetThisGameObj(a_thread); +template +TYPE* GetThisGameObj(gmThread* a_thread) +{ + GM_ASSERT(a_thread->GetThis()->m_type == ScriptObj::GMTYPE_GAMEOBJ); //Paranoid check for type function + + ScriptObj* scriptObj = (ScriptObj*)a_thread->ThisUser(); + + CHECK(scriptObj); //Check for null GameObj ptr + + // You can check for valid derived type here + + return static_cast(scriptObj->GetGameObj()); +} + + +/// \brief Get param as GameObj of TYPE +/// Eg. Soldier* obj = GetGameObjParam(a_thread, 0); +template +TYPE* GetGameObjParam(gmThread* a_thread, int a_paramIndex) +{ + ScriptObj* scriptObj = (ScriptObj*)a_thread->ParamUserCheckType(a_paramIndex, ScriptObj::GMTYPE_GAMEOBJ); + + CHECK(scriptObj); //Check for null GameObj ptr + + // You can check for valid derived type here + + return static_cast(scriptObj->GetGameObj()); +} +*/ + + +/// \brief Get 'this' as GameObj of TYPE +inline GameObj* GetThisGameObj(gmThread* a_thread) +{ + GM_ASSERT(a_thread->GetThis()->m_type == ScriptObj::GMTYPE_GAMEOBJ); //Paranoid check for type function + + ScriptObj* scriptObj = (ScriptObj*)a_thread->ThisUser(); + + if(!scriptObj) + { + return NULL; + } + + return scriptObj->GetGameObj(); +} + + +/// \brief Get param as GameObj of TYPE +inline GameObj* GetGameObjParam(gmThread* a_thread, int a_paramIndex) +{ + ScriptObj* scriptObj = (ScriptObj*)a_thread->ParamUserCheckType(a_paramIndex, ScriptObj::GMTYPE_GAMEOBJ); + + if(!scriptObj) + { + return NULL; + } + + return scriptObj->GetGameObj(); +} + + +#endif //SCRIPTOBJ_H \ No newline at end of file diff --git a/vscript/languages/gm/src/examples/GameObject/ScriptSys.cpp b/vscript/languages/gm/src/examples/GameObject/ScriptSys.cpp new file mode 100644 index 00000000..ca49c8a3 --- /dev/null +++ b/vscript/languages/gm/src/examples/GameObject/ScriptSys.cpp @@ -0,0 +1,432 @@ +// +// ScriptSys.cpp +// + +#include "gmCall.h" +#include "ScriptSys.h" +#include "ScriptObj.h" +#include "GameObj.h" + + +// Init statics and constants +ScriptSys* ScriptSys::s_instance = NULL; +const int ScriptSys::DEBUGGER_DEFAULT_PORT = 49001; +const char* ScriptSys::DEBUGGER_DEFAULT_IP = "127.0.0.1"; // localhost + + +void ScriptSys::Init() +{ + GM_ASSERT( !s_instance ); // Just have one instance for this example + + s_instance = new ScriptSys; + + // Register Game Object type and bindings + ScriptObj::RegisterScriptBindings(); + GameObj::RegisterScriptBindings(); +} + + +void ScriptSys::Destroy() +{ + delete s_instance; + s_instance = NULL; +} + + +void ScriptSys::DebuggerSendMessage(gmDebugSession * a_session, const void * a_command, int a_len) +{ + nClient * client = (nClient *) a_session->m_user; + client->SendMessage((const char *) a_command, a_len); +} + + +const void* ScriptSys::DebuggerPumpMessage(gmDebugSession * a_session, int &a_len) +{ + nClient * client = (nClient *) a_session->m_user; + return client->PumpMessage(a_len); +} + + +ScriptSys::ScriptSys() +{ + m_machine = new gmMachine; + + //Set machine callbacks + gmMachine::s_machineCallback = ScriptSysCallback_Machine; + gmMachine::s_printCallback = ScriptSysCallback_Print; + + // Init debugger + gmBindDebugLib(m_machine); // Register debugging library + + m_debuggerIP = DEBUGGER_DEFAULT_IP; + m_debuggerPort = DEBUGGER_DEFAULT_PORT; + m_debugSession.m_sendMessage = DebuggerSendMessage; + m_debugSession.m_pumpMessage = DebuggerPumpMessage; + m_debugSession.m_user = &m_debugClient; + + if(m_debugClient.Connect(m_debuggerIP, ((short) m_debuggerPort))) + { + m_debugSession.Open(m_machine); + fprintf(stderr, "Debug session opened"GM_NL); + } + m_machine->SetDebugMode(true); +} + + +ScriptSys::~ScriptSys() +{ + // End debugger session if any + m_debugSession.Close(); + m_debugClient.Close(); + + // For debugging + _gmDumpLeaks(); + + delete m_machine; +} + + +void __cdecl ScriptSys::LogError(const char *a_str, ...) +{ + // WARNING This is not safe for longer strings, should use non-ansi vsprintnf, string type, or similar. + const int MAX_CHARS = 512; + char buffer[MAX_CHARS]; + + va_list args; + va_start(args, a_str); + + vsprintf(buffer, a_str, args); + + va_end(args); + + fprintf(stderr, "ERROR: %s", a_str); +} + + +GameObj* ScriptSys::GetGameObjFromThreadId(int a_threadId) +{ + ScriptObj* scriptObj; + + if(m_mapThreadGameObjs.GetAt(a_threadId, scriptObj)) + { + return scriptObj->GetGameObj(); + } + return NULL; +} + + +void ScriptSys::AssociateThreadIdWithGameObj(int a_threadId, GameObj& a_gameObj) +{ + ScriptObj* scriptObj = a_gameObj.GetScriptObj(); + + scriptObj->AddThreadId(a_threadId); + m_mapThreadGameObjs.SetAt(a_threadId, scriptObj); +} + + +void ScriptSys::DisassociateThreadIdWithGameObj(int a_threadId) +{ + ScriptObj* scriptObj; + + if(m_mapThreadGameObjs.RemoveAt(a_threadId, scriptObj)) + { + scriptObj->RemoveThreadId(a_threadId); + } +} + + +void ScriptSys::RemoveThreadIdButDontTouchGameObj(int a_threadId) +{ + m_mapThreadGameObjs.RemoveAt(a_threadId); +} + + +void ScriptSys::SetTableNull(const char* a_memberName, gmTableObject* a_table) +{ + GM_ASSERT(a_table); + gmTableObject* table = a_table; + gmVariable newVar; + newVar.Nullify(); + table->Set(m_machine, a_memberName, newVar); +} + + +void ScriptSys::SetTableInt(const char* a_memberName, int a_int, gmTableObject* a_table) +{ + GM_ASSERT(a_table); + gmTableObject* table = a_table; + gmVariable newVar; + newVar.SetInt(a_int); + table->Set(m_machine, a_memberName, newVar); +} + + +void ScriptSys::SetTableFloat(const char* a_memberName, float a_float, gmTableObject* a_table) +{ + GM_ASSERT(a_table); + gmTableObject* table = a_table; + gmVariable newVar; + newVar.SetFloat(a_float); + table->Set(m_machine, a_memberName, newVar); +} + + +void ScriptSys::SetTableString(const char* a_memberName, const char* a_string, int a_strLength, gmTableObject* a_table) +{ + GM_ASSERT(a_table); + gmTableObject* table = a_table; + gmVariable newVar; + newVar.SetString(m_machine->AllocStringObject(a_string, a_strLength)); + table->Set(m_machine, a_memberName, newVar); +} + +void ScriptSys::SetTableGameObj(const char* a_memberName, GameObj* a_gameObj, gmTableObject* a_table) +{ + GM_ASSERT(a_table); + GM_ASSERT(a_gameObj); + gmTableObject* table = a_table; + gmVariable newVar; + newVar.SetUser(a_gameObj->GetScriptObj()->GetUserObject()); + table->Set(m_machine, a_memberName, newVar); +} + + +gmTableObject* ScriptSys::SetTableTable(const char* a_memberName, gmTableObject* a_table) +{ + GM_ASSERT(a_table); + gmTableObject* table = a_table; + gmMachine* machine = m_machine; + gmVariable newVar; + gmTableObject* newTable = machine->AllocTableObject(); + newVar.SetTable(newTable); + table->Set(machine, a_memberName, newVar); + return newTable; //Return the table so we can potentially put things in it +} + + +bool ScriptSys::GetTableInt(const char* a_memberName, int& a_int, gmTableObject* a_table) +{ + GM_ASSERT(a_table); + gmTableObject* table = a_table; + gmVariable stringName; + gmVariable retVar; + + stringName.SetString(m_machine->AllocStringObject(a_memberName)); + retVar = table->Get(stringName); + if(retVar.m_type == GM_INT) + { + a_int = retVar.m_value.m_int; + return true; + } + return false; +} + + +bool ScriptSys::GetTableFloat(const char* a_memberName, float& a_float, gmTableObject* a_table) +{ + GM_ASSERT(a_table); + gmTableObject* table = a_table; + gmVariable stringName; + gmVariable retVar; + + stringName.SetString(m_machine->AllocStringObject(a_memberName)); + retVar = table->Get(stringName); + if(retVar.m_type == GM_FLOAT) + { + a_float = retVar.m_value.m_float; + return true; + } + return false; +} + + +bool ScriptSys::GetTableString(const char* a_memberName, String& a_string, gmTableObject* a_table) +{ + GM_ASSERT(a_table); + gmTableObject* table = a_table; + gmVariable stringName; + gmVariable retVar; + + stringName.SetString(m_machine->AllocStringObject(a_memberName)); + retVar = table->Get(stringName); + if(retVar.m_type == GM_STRING) + { + gmStringObject* stringObj = (gmStringObject*)GM_MOBJECT(m_machine, retVar.m_value.m_ref); + a_string = stringObj->GetString(); + return true; + } + return false; +} + + +bool ScriptSys::GetTableGameObj(const char* a_memberName, GameObj*& a_gameObj, gmTableObject* a_table) +{ + GM_ASSERT(a_table); + gmTableObject* table = a_table; + gmVariable stringName; + gmVariable retVar; + + stringName.SetString(m_machine->AllocStringObject(a_memberName)); + retVar = table->Get(stringName); + if(retVar.m_type == ScriptObj::GMTYPE_GAMEOBJ) + { + gmUserObject* userObj = (gmUserObject*)GM_MOBJECT(m_machine, retVar.m_value.m_ref); + a_gameObj = ((ScriptObj*)userObj->m_user)->GetGameObj(); + return true; + } + return false; +} + + +bool ScriptSys::GetTableTable(const char* a_memberName, gmTableObject*& a_retTable, gmTableObject* a_table) +{ + GM_ASSERT(a_table); + gmTableObject* table = a_table; + gmVariable stringName; + gmVariable retVar; + + stringName.SetString(m_machine->AllocStringObject(a_memberName)); + retVar = table->Get(stringName); + if(retVar.m_type == GM_TABLE) + { + a_retTable = (gmTableObject*)GM_MOBJECT(m_machine, retVar.m_value.m_ref); + return true; + } + return false; +} + + +void GM_CDECL ScriptSys::ScriptSysCallback_Print(gmMachine* a_machine, const char* a_string) +{ + printf("%s\n", a_string); +} + + +bool GM_CDECL ScriptSys::ScriptSysCallback_Machine(gmMachine* a_machine, gmMachineCommand a_command, const void* a_context) +{ + switch(a_command) + { + case MC_THREAD_EXCEPTION: + { + ScriptSys::Get()->LogAnyMachineErrorMessages(); + break; + } + case MC_COLLECT_GARBAGE: + { +/* // Old code +#if GM_USE_INCGC + gmGarbageCollector* gc = a_machine->GetGC(); + + for(unsigned int objIndex = 0; objIndexm_allScriptObjs.Count(); ++objIndex) + { + ScriptObj* scriptObj = ScriptSys::Get()->m_allScriptObjs[objIndex]; + gc->GetNextObject(scriptObj->GetTableObject()); + } +#else //GM_USE_INCGC + gmuint32 mark = *(gmuint32*)a_context; + + for(unsigned int objIndex = 0; objIndexm_allScriptObjs.Count(); ++objIndex) + { + ScriptObj* scriptObj = ScriptSys::Get()->m_allScriptObjs[objIndex]; + + if(scriptObj->GetTableObject()->NeedsMark(mark)) + { + scriptObj->GetTableObject()->Mark(a_machine, mark); + } + } +#endif //GM_USE_INCGC +*/ + break; + } + case MC_THREAD_CREATE: // Called when a thread is created. a_context is the thread. + { + break; + } + case MC_THREAD_DESTROY: // Called when a thread is destroyed. a_context is the thread that is about to die + { + gmThread* thread = (gmThread*)a_context; + ScriptSys::Get()->DisassociateThreadIdWithGameObj(thread->GetId()); + break; + } + } + return false; +} + + + +bool ScriptSys::ExecuteFile(const char* a_fileName) +{ + FILE* scriptFile = NULL; + char* fileString = NULL; + int fileSize = 0; + + GM_ASSERT(m_machine); + + if( !(scriptFile = fopen(a_fileName, "rb")) ) + { + return false; + } + + fseek(scriptFile, 0, SEEK_END); + fileSize = ftell(scriptFile); + fseek(scriptFile, 0, SEEK_SET); + fileString = new char [fileSize+1]; + fread(fileString, fileSize, 1, scriptFile); + fileString[fileSize] = 0; // Terminating null + fclose(scriptFile); + + int threadId = GM_INVALID_THREAD; + int errors = m_machine->ExecuteString(fileString, &threadId, true, a_fileName); + if(errors) + { + LogAnyMachineErrorMessages(); + } + + delete [] fileString; + + return true; +} + + +bool ScriptSys::ExecuteString(const char* a_string) +{ + GM_ASSERT(m_machine); + + int threadId = GM_INVALID_THREAD; + int errors = m_machine->ExecuteString(a_string, &threadId, true); + if (errors) + { + LogAnyMachineErrorMessages(); + } + + return true; +} + + +int ScriptSys::Execute(unsigned int a_deltaTimeMS) +{ + int numThreads = m_machine->Execute(a_deltaTimeMS); + + if(m_debugClient.IsConnected()) + { + m_debugSession.Update(); + } + else + { + m_debugSession.Close(); + } + + return numThreads; +} + + +void ScriptSys::LogAnyMachineErrorMessages() +{ + bool first = true; + const char * message; + while((message = m_machine->GetLog().GetEntry(first))) + { + LogError("%s"GM_NL, message); + } + m_machine->GetLog().Reset(); +} \ No newline at end of file diff --git a/vscript/languages/gm/src/examples/GameObject/ScriptSys.h b/vscript/languages/gm/src/examples/GameObject/ScriptSys.h new file mode 100644 index 00000000..9ae08eed --- /dev/null +++ b/vscript/languages/gm/src/examples/GameObject/ScriptSys.h @@ -0,0 +1,107 @@ +#ifndef SCRIPTSYS_H +#define SCRIPTSYS_H + +// +// ScriptSys.h +// +// Example script system to support scriptable game objects +// + +#include "gmThread.h" +#include "gmDebug.h" +#include "gmArraySimple.h" +#include "StdStuff.h" +#include "NetClient.h" + +// Fwd decls +class GameObj; +class ScriptObj; + +// Script system to support and control the virtual machine +class ScriptSys +{ +public: + + /// Access this system from anywhere once it has been initialized for convenience + static ScriptSys* Get() { return s_instance; } + + ScriptSys(); + virtual ~ScriptSys(); + + /// Get the GM machine + gmMachine* GetMachine() { return m_machine; } + + /// Set bindings and Init constant strings + static void Init(); + /// Clean out this structure + static void Destroy(); + + + /// Log an error message + void __cdecl LogError(const char *a_str, ...); + + /// Log any machine error messages that may be waiting + void LogAnyMachineErrorMessages(); + + /// Get GameObj that was associated with a thread Id. + GameObj* GetGameObjFromThreadId(int a_threadId); + + /// Associate a threadId with a GameObj, logically as a primary thread. + void AssociateThreadIdWithGameObj(int a_threadId, GameObj& a_gameObj); + /// Disassociate a threadId with a GameObj. + void DisassociateThreadIdWithGameObj(int a_threadId); + /// Remove the thread Id association, but don't modify the GameObj. + /// This can be used internally by GameObj to perform iteration and removal. + void RemoveThreadIdButDontTouchGameObj(int a_threadId); + + /// Run a script file + bool ExecuteFile(const char* a_fileName); + /// Executes a string. + bool ExecuteString(const char* a_str); + + /// Update the virtual machine. + int Execute(unsigned int a_deltaTimeMS); + + void SetTableNull(const char* a_memberName, gmTableObject* a_table); + void SetTableInt(const char* a_memberName, int a_int, gmTableObject* a_table); + void SetTableFloat(const char* a_memberName, float a_float, gmTableObject* a_table); + void SetTableString(const char* a_memberName, const char* a_string, int a_strLength, gmTableObject* a_table); + void SetTableGameObj(const char* a_memberName, GameObj* a_gameObj, gmTableObject* a_table); + gmTableObject* SetTableTable(const char* a_memberName, gmTableObject* a_table); + + bool GetTableInt(const char* a_memberName, int& a_int, gmTableObject* a_table); + bool GetTableFloat(const char* a_memberName, float& a_float, gmTableObject* a_table); + bool GetTableString(const char* a_memberName, String& a_string, gmTableObject* a_table); + bool GetTableGameObj(const char* a_memberName, GameObj*& a_gameObj, gmTableObject* a_table); + bool GetTableTable(const char* a_memberName, gmTableObject*& a_retTable, gmTableObject* a_table); + +protected: + + /// Machine 'print' binding callback + static void GM_CDECL ScriptSysCallback_Print(gmMachine* a_machine, const char* a_string); + /// Machine general and exception callback + static bool GM_CDECL ScriptSysCallback_Machine(gmMachine* a_machine, gmMachineCommand a_command, const void* a_context); + + /// Debugging support Send a message + static void DebuggerSendMessage(gmDebugSession * a_session, const void * a_command, int a_len); + /// Debugging support Pump a message + static const void* DebuggerPumpMessage(gmDebugSession * a_session, int &a_len); + + gmMachine* m_machine; ///< GM machine instance + Map m_mapThreadGameObjs; ///< Map script threadId to game object +/* // Old code + gmArraySimple m_allScriptObjs; ///< All the script objects, for garbage collection handling +*/ + + nClient m_debugClient; ///< Debugger network client + gmDebugSession m_debugSession; ///< Debugger session + const char* m_debuggerIP; ///< Debugger IP + int m_debuggerPort; ///< Debugger port + + static const int DEBUGGER_DEFAULT_PORT; ///< Debugger port number + static const char* DEBUGGER_DEFAULT_IP; ///< Debugger port number + static ScriptSys* s_instance; ///< Static instance for convenience +}; + + +#endif //SCRIPTSYS_H \ No newline at end of file diff --git a/vscript/languages/gm/src/examples/GameObject/StdStuff.cpp b/vscript/languages/gm/src/examples/GameObject/StdStuff.cpp new file mode 100644 index 00000000..86c3cbfd --- /dev/null +++ b/vscript/languages/gm/src/examples/GameObject/StdStuff.cpp @@ -0,0 +1,5 @@ +// +// StdStuff.cpp +// + +#include "StdStuff.h" \ No newline at end of file diff --git a/vscript/languages/gm/src/examples/GameObject/StdStuff.h b/vscript/languages/gm/src/examples/GameObject/StdStuff.h new file mode 100644 index 00000000..d34f289c --- /dev/null +++ b/vscript/languages/gm/src/examples/GameObject/StdStuff.h @@ -0,0 +1,194 @@ +#ifndef STDSTUFF_H +#define STDSTUFF_H + +// +// StdStuff.h +// +// Merely some containers and standard things you would +// find in MFC, STL, or your favourite library/engine. +// These were implemented as quickly and minimally as possible +// rather than introduce more code or external libraries. +// + +#include "gmHash.h" + +// Quick n dirty Map using the available hash table +template +class Map +{ +public: + + Map() + : m_hashTable(1024) // Just an arbitrary number at present + { + } + + virtual ~Map() + { + m_hashTable.RemoveAndDeleteAll(); + } + + /// \brief Insert a element associated with a key. + /// \param a_key Key to identify data. + /// \param a_value Data associated with Key. + void SetAt(const KEY& a_key, const VALUE& a_value) + { + HashNode* node = m_hashTable.Find(a_key); + if(node) + { + node->m_value = a_value; + } + else + { + node = new HashNode; + node->m_key = a_key; + node->m_value = a_value; + m_hashTable.Insert(node); + } + }; + + /// \brief Find a node in the map. + /// \param a_key Key to identiy element. + /// \param a_value Found element returned here. + /// \return TRUE if found, FALSE if not in map. + bool GetAt(const KEY& a_key, VALUE& a_value) + { + HashNode* node = m_hashTable.Find(a_key); + if(node) + { + a_value = node->m_value; + return true; + } + return false; + } + + /// \brief Remove a node from the map. + /// \param a_key Key to identiy element. + /// \param a_removedData Found element returned here. + /// \return TRUE if found, FALSE if not in map. + bool RemoveAt(const KEY& a_key, VALUE& a_removedData) + { + HashNode* node = m_hashTable.Find(a_key); + if(node) + { + a_removedData = node->m_value; + + m_hashTable.Remove(node); + delete node; + + return true; + } + return false; + } + + /// \brief Remove a node from the map. + /// \param a_key Key to identiy element. + /// \return TRUE if found, FALSE if not in map. + bool RemoveAt(const KEY& a_key) + { + HashNode* node = m_hashTable.Find(a_key); + if(node) + { + m_hashTable.Remove(node); + delete node; + + return true; + } + return false; + } + +protected: + + struct HashNode : public gmHashNode + { + VALUE m_value; + KEY m_key; + + virtual const KEY& GetKey() const { return m_key; } + + static inline gmuint Hash(const KEY& a_key) + { + return (unsigned int)a_key; + } + + static inline int Compare(const KEY& a_keyA, const KEY& a_keyB) + { + if(a_keyA < a_keyB) + { return -1; } + if(a_keyA > a_keyB) + { return 1; } + return 0; + } + }; + + // Blocking + gmHash m_hashTable; + +}; + + +// The most crap string implementation ever +class String +{ +public: + + String() + { + m_buffer = NULL; + SetBuffer(""); + } + + String(const char* a_newString) + { + m_buffer = NULL; + SetBuffer(a_newString); + } + + String(const char* a_newString, const int a_newStringLength) + { + m_buffer = NULL; + SetBuffer(a_newString, a_newStringLength); + } + + ~String() + { + delete [] m_buffer; + } + + operator const char* () const + { + return m_buffer; + } + + const char* operator = (const char* a_newString) + { + SetBuffer(a_newString); + return m_buffer; + } + + const char* operator = (const String& a_newString) + { + SetBuffer(a_newString); + return m_buffer; + } + +private: + + void SetBuffer(const char* a_newString, const int a_newStringLength) + { + delete [] m_buffer; + m_buffer = new char [a_newStringLength + 1]; + memcpy(m_buffer, a_newString, a_newStringLength); + m_buffer[a_newStringLength] = 0; + } + + void SetBuffer(const char* a_newString) + { + int newStringLength = strlen(a_newString); + SetBuffer(a_newString, newStringLength); + } + + char * m_buffer; +}; + +#endif //STDSTUFF_H \ No newline at end of file diff --git a/vscript/languages/gm/src/examples/GameObject/TestGameObj.gm b/vscript/languages/gm/src/examples/GameObject/TestGameObj.gm new file mode 100644 index 00000000..afb82a6d --- /dev/null +++ b/vscript/languages/gm/src/examples/GameObject/TestGameObj.gm @@ -0,0 +1,44 @@ +// Just a bunch of tests that don't mean anything at present. + +global WhatsMyName = function() +{ + print("m_name = ", .m_name); + print("this = ", this); + + if(.IsValid()) + { + .SetPos(23.0f, 56.0f); + print("position(", .GetPosX(), ",", .GetPosY(), ")"); + + global g_globalObj = this; + } +}; + + +global RunGlobalObject = function () +{ + g_globalObj:WhatsMyName(); +}; + + +global ThreadYieldTest = function() +{ + count = 0; + while(count < 30) + { + sleep(0.5f); + count += 1; + print("count=",count); + yield(); + } +}; + + +Console.SetColor(COLOR_RED, COLOR_BLACK); +Console.Print("Red"); +Console.SetColor(COLOR_GREEN, COLOR_BLACK); +Console.Print("Green"); +Console.Print("\n"); +Console.SetColor(COLOR_WHITE, COLOR_BLACK); + +print("Script compiled and executed. \n"); diff --git a/vscript/languages/gm/src/examples/GameObject/main.cpp b/vscript/languages/gm/src/examples/GameObject/main.cpp new file mode 100644 index 00000000..0805d77a --- /dev/null +++ b/vscript/languages/gm/src/examples/GameObject/main.cpp @@ -0,0 +1,30 @@ +#include +#include "StdStuff.h" +#include "App.h" + +// Entry point for Win32 app +int main(int argc, char* argv[]) +{ + String test1("hello"); + test1 = "world"; + const char* huh = test1; + + App app; + + if(!app.Init()) + { + fprintf(stderr,"Failed App::Init()"); + return 1; + } + + while(app.Update()) + { + } + + app.Destroy(); + + printf("App finished, press ENTER to exit."); + getchar(); // Wait for key press + + return 0; +} diff --git a/vscript/languages/gm/src/examples/Minimal/Minimal.dsp b/vscript/languages/gm/src/examples/Minimal/Minimal.dsp new file mode 100644 index 00000000..1ef49eaa --- /dev/null +++ b/vscript/languages/gm/src/examples/Minimal/Minimal.dsp @@ -0,0 +1,362 @@ +# Microsoft Developer Studio Project File - Name="Minimal" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=Minimal - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Minimal.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Minimal.mak" CFG="Minimal - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Minimal - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Minimal - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "Perforce Project" +# PROP Scc_LocalPath "..\.." +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Minimal - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "..\..\gm" /I "..\..\platform\win32msvc" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0xc09 /d "NDEBUG" +# ADD RSC /l 0xc09 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "Minimal - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\gm" /I "..\..\platform\win32msvc" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0xc09 /d "_DEBUG" +# ADD RSC /l 0xc09 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Minimal - Win32 Release" +# Name "Minimal - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\main.cpp +# End Source File +# End Group +# Begin Group "gm" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\gm\gmArraySimple.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmArraySimple.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmByteCode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmByteCode.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmByteCodeGen.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmByteCodeGen.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmCodeGen.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmCodeGen.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmCodeGenHooks.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmCodeGenHooks.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmCodeTree.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmCodeTree.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmConfig.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmCrc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmDebug.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmDebug.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmFunctionObject.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmFunctionObject.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmHash.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmHash.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmIncGC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmIncGC.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmIterator.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmLibHooks.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmLibHooks.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmListDouble.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmListDouble.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmLog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmLog.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMachine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMachine.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMachineLib.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMachineLib.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMem.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMem.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMemChain.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMemChain.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMemFixed.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMemFixed.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMemFixedSet.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmMemFixedSet.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmOperators.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmOperators.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmParser.cpp.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmScanner.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmScanner.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmStreamBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmStreamBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmStringObject.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmStringObject.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmTableObject.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmTableObject.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmThread.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmThread.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmUserObject.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmUserObject.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmUtil.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmUtil.h +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmVariable.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gm\gmVariable.h +# End Source File +# End Group +# Begin Group "win32" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\platform\win32msvc\gmConfig_p.h +# End Source File +# End Group +# End Target +# End Project diff --git a/vscript/languages/gm/src/examples/Minimal/Minimal.dsw b/vscript/languages/gm/src/examples/Minimal/Minimal.dsw new file mode 100644 index 00000000..8ef1f2c0 --- /dev/null +++ b/vscript/languages/gm/src/examples/Minimal/Minimal.dsw @@ -0,0 +1,33 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Minimal"=.\Minimal.dsp - Package Owner=<4> + +Package=<5> +{{{ + begin source code control + Perforce Project + ..\.. + end source code control +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/vscript/languages/gm/src/examples/Minimal/Minimal.vcproj b/vscript/languages/gm/src/examples/Minimal/Minimal.vcproj new file mode 100644 index 00000000..d2355894 --- /dev/null +++ b/vscript/languages/gm/src/examples/Minimal/Minimal.vcproj @@ -0,0 +1,1059 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/gm/src/examples/Minimal/main.cpp b/vscript/languages/gm/src/examples/Minimal/main.cpp new file mode 100644 index 00000000..1a67e2d8 --- /dev/null +++ b/vscript/languages/gm/src/examples/Minimal/main.cpp @@ -0,0 +1,78 @@ +#if 0 // This is trully the smallest app + +#include "gmThread.h" // game monkey script + +int main(int argc, char* argv[]) +{ + gmMachine machine; + machine.ExecuteString("print(`Hello world`);"); + getchar(); // Keypress before exit + return 0; +} + +#else // This is a tiny app + +#include +#include // multimedia timer (may need winmm.lib) +#include "gmThread.h" // game monkey script + +int main(int argc, char* argv[]) +{ + // Create virtual machine + gmMachine* machine = new gmMachine; + + // Get a script from stdin. Some examples: + // print("Hello world"); + // for( i = 0; i < 10; i=i+1 ) { print("i=",i); sleep(1.0); } + fprintf(stdout,"Please enter one line of script\n>"); + const int MAX_SCRIPT_SIZE = 4096; + char script[MAX_SCRIPT_SIZE]; + fgets(script, MAX_SCRIPT_SIZE-1, stdin); + + // Compile the script, but don't run it for now + int errors = machine->ExecuteString(script, NULL, false, NULL); + // Dump compile time errors to output + if(errors) + { + bool first = true; + const char * message; + + while((message = machine->GetLog().GetEntry(first))) + { + fprintf(stderr, "%s"GM_NL, message); + } + machine->GetLog().Reset(); + } + else + { + int deltaTime = 0; + int lastTime = timeGetTime(); + + // Keep executing script while threads persist + while(machine->Execute(deltaTime)) + { + // Update delta time + int curTime = timeGetTime(); + deltaTime = curTime - lastTime; + lastTime = curTime; + + // Dump run time errors to output + bool first = true; + const char * message; + while((message = machine->GetLog().GetEntry(first))) + { + fprintf(stderr, "%s"GM_NL, message); + } + machine->GetLog().Reset(); + } + } + + delete machine; // Finished with VM + + fprintf(stdout,"Script complete. Press a key to exit."); + getchar(); // Keypress before exit + + return 0; +} + +#endif // Minimal build type \ No newline at end of file diff --git a/vscript/languages/gm/src/gm/bison.hairy b/vscript/languages/gm/src/gm/bison.hairy new file mode 100644 index 00000000..999b5559 --- /dev/null +++ b/vscript/languages/gm/src/gm/bison.hairy @@ -0,0 +1,334 @@ + +extern int timeclock; + + +int yyerror; /* Yyerror and yycost are set by guards. */ +int yycost; /* If yyerror is set to a nonzero value by a */ + /* guard, the reduction with which the guard */ + /* is associated is not performed, and the */ + /* error recovery mechanism is invoked. */ + /* Yycost indicates the cost of performing */ + /* the reduction given the attributes of the */ + /* symbols. */ + + +/* YYMAXDEPTH indicates the size of the parser's state and value */ +/* stacks. */ + +#ifndef YYMAXDEPTH +#define YYMAXDEPTH 500 +#endif + +/* YYMAXRULES must be at least as large as the number of rules that */ +/* could be placed in the rule queue. That number could be determined */ +/* from the grammar and the size of the stack, but, as yet, it is not. */ + +#ifndef YYMAXRULES +#define YYMAXRULES 100 +#endif + +#ifndef YYMAXBACKUP +#define YYMAXBACKUP 100 +#endif + + +short yyss[YYMAXDEPTH]; /* the state stack */ +YYSTYPE yyvs[YYMAXDEPTH]; /* the semantic value stack */ +YYLTYPE yyls[YYMAXDEPTH]; /* the location stack */ +short yyrq[YYMAXRULES]; /* the rule queue */ +int yychar; /* the lookahead symbol */ + +YYSTYPE yylval; /* the semantic value of the */ + /* lookahead symbol */ + +YYSTYPE yytval; /* the semantic value for the state */ + /* at the top of the state stack. */ + +YYSTYPE yyval; /* the variable used to return */ + /* semantic values from the action */ + /* routines */ + +YYLTYPE yylloc; /* location data for the lookahead */ + /* symbol */ + +YYLTYPE yytloc; /* location data for the state at the */ + /* top of the state stack */ + + +int yynunlexed; +short yyunchar[YYMAXBACKUP]; +YYSTYPE yyunval[YYMAXBACKUP]; +YYLTYPE yyunloc[YYMAXBACKUP]; + +short *yygssp; /* a pointer to the top of the state */ + /* stack; only set during error */ + /* recovery. */ + +YYSTYPE *yygvsp; /* a pointer to the top of the value */ + /* stack; only set during error */ + /* recovery. */ + +YYLTYPE *yyglsp; /* a pointer to the top of the */ + /* location stack; only set during */ + /* error recovery. */ + + +/* Yyget is an interface between the parser and the lexical analyzer. */ +/* It is costly to provide such an interface, but it avoids requiring */ +/* the lexical analyzer to be able to back up the scan. */ + +yyget() +{ + if (yynunlexed > 0) + { + yynunlexed--; + yychar = yyunchar[yynunlexed]; + yylval = yyunval[yynunlexed]; + yylloc = yyunloc[yynunlexed]; + } + else if (yychar <= 0) + yychar = 0; + else + { + yychar = yylex(); + if (yychar < 0) + yychar = 0; + else yychar = YYTRANSLATE(yychar); + } +} + + + +yyunlex(chr, val, loc) +int chr; +YYSTYPE val; +YYLTYPE loc; +{ + yyunchar[yynunlexed] = chr; + yyunval[yynunlexed] = val; + yyunloc[yynunlexed] = loc; + yynunlexed++; +} + + + +yyrestore(first, last) +register short *first; +register short *last; +{ + register short *ssp; + register short *rp; + register int symbol; + register int state; + register int tvalsaved; + + ssp = yygssp; + yyunlex(yychar, yylval, yylloc); + + tvalsaved = 0; + while (first != last) + { + symbol = yystos[*ssp]; + if (symbol < YYNTBASE) + { + yyunlex(symbol, yytval, yytloc); + tvalsaved = 1; + ssp--; + } + + ssp--; + + if (first == yyrq) + first = yyrq + YYMAXRULES; + + first--; + + for (rp = yyrhs + yyprhs[*first]; symbol = *rp; rp++) + { + if (symbol < YYNTBASE) + state = yytable[yypact[*ssp] + symbol]; + else + { + state = yypgoto[symbol - YYNTBASE] + *ssp; + + if (state >= 0 && state <= YYLAST && yycheck[state] == *ssp) + state = yytable[state]; + else + state = yydefgoto[symbol - YYNTBASE]; + } + + *++ssp = state; + } + } + + if ( ! tvalsaved && ssp > yyss) + { + yyunlex(yystos[*ssp], yytval, yytloc); + ssp--; + } + + yygssp = ssp; +} + + + +int +yyparse() +{ + register int yystate; + register int yyn; + register short *yyssp; + register short *yyrq0; + register short *yyptr; + register YYSTYPE *yyvsp; + + int yylen; + YYLTYPE *yylsp; + short *yyrq1; + short *yyrq2; + + yystate = 0; + yyssp = yyss - 1; + yyvsp = yyvs - 1; + yylsp = yyls - 1; + yyrq0 = yyrq; + yyrq1 = yyrq0; + yyrq2 = yyrq0; + + yychar = yylex(); + if (yychar < 0) + yychar = 0; + else yychar = YYTRANSLATE(yychar); + +yynewstate: + + if (yyssp >= yyss + YYMAXDEPTH - 1) + { + yyabort("Parser Stack Overflow"); + YYABORT; + } + + *++yyssp = yystate; + +yyresume: + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yydefault; + + yyn += yychar; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar) + goto yydefault; + + yyn = yytable[yyn]; + if (yyn < 0) + { + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrlab; + + yystate = yyn; + + yyptr = yyrq2; + while (yyptr != yyrq1) + { + yyn = *yyptr++; + yylen = yyr2[yyn]; + yyvsp -= yylen; + yylsp -= yylen; + + yyguard(yyn, yyvsp, yylsp); + if (yyerror) + goto yysemerr; + + yyaction(yyn, yyvsp, yylsp); + *++yyvsp = yyval; + + yylsp++; + if (yylen == 0) + { + yylsp->timestamp = timeclock; + yylsp->first_line = yytloc.first_line; + yylsp->first_column = yytloc.first_column; + yylsp->last_line = (yylsp-1)->last_line; + yylsp->last_column = (yylsp-1)->last_column; + yylsp->text = 0; + } + else + { + yylsp->last_line = (yylsp+yylen-1)->last_line; + yylsp->last_column = (yylsp+yylen-1)->last_column; + } + + if (yyptr == yyrq + YYMAXRULES) + yyptr = yyrq; + } + + if (yystate == YYFINAL) + YYACCEPT; + + yyrq2 = yyptr; + yyrq1 = yyrq0; + + *++yyvsp = yytval; + *++yylsp = yytloc; + yytval = yylval; + yytloc = yylloc; + yyget(); + + goto yynewstate; + +yydefault: + + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + +yyreduce: + + *yyrq0++ = yyn; + + if (yyrq0 == yyrq + YYMAXRULES) + yyrq0 = yyrq; + + if (yyrq0 == yyrq2) + { + yyabort("Parser Rule Queue Overflow"); + YYABORT; + } + + yyssp -= yyr2[yyn]; + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTBASE] + *yyssp; + if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTBASE]; + + goto yynewstate; + +yysemerr: + *--yyptr = yyn; + yyrq2 = yyptr; + yyvsp += yyr2[yyn]; + +yyerrlab: + + yygssp = yyssp; + yygvsp = yyvsp; + yyglsp = yylsp; + yyrestore(yyrq0, yyrq2); + yyrecover(); + yystate = *yygssp; + yyssp = yygssp; + yyvsp = yygvsp; + yyrq0 = yyrq; + yyrq1 = yyrq0; + yyrq2 = yyrq0; + goto yyresume; +} + +$ diff --git a/vscript/languages/gm/src/gm/bison.simple b/vscript/languages/gm/src/gm/bison.simple new file mode 100644 index 00000000..a6a1cd41 --- /dev/null +++ b/vscript/languages/gm/src/gm/bison.simple @@ -0,0 +1,688 @@ +/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +#line 3 "bison.simple" + +/* Skeleton output parser for bison, + Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +#ifndef alloca +#ifdef __GNUC__ +#define alloca __builtin_alloca +#else /* not GNU C. */ +#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) +#include +#else /* not sparc */ +#if defined (MSDOS) && !defined (__TURBOC__) +#include +#else /* not MSDOS, or __TURBOC__ */ +#if defined(_AIX) +#include + #pragma alloca +#else /* not MSDOS, __TURBOC__, or _AIX */ +#ifdef __hpux +#ifdef __cplusplus +extern "C" { +void *alloca (unsigned int); +}; +#else /* not __cplusplus */ +void *alloca (); +#endif /* not __cplusplus */ +#endif /* __hpux */ +#endif /* not _AIX */ +#endif /* not MSDOS, or __TURBOC__ */ +#endif /* not sparc. */ +#endif /* not GNU C. */ +#endif /* alloca not defined. */ + +/* This is the parser code that is written into each bison parser + when the %semantic_parser declaration is not specified in the grammar. + It was written by Richard Stallman by simplifying the hairy parser + used when %semantic_parser is specified. */ + +/* Note: there must be only one dollar sign in this file. + It is replaced by the list of actions, each action + as one case of the switch. */ + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY -2 +#define YYEOF 0 +#define YYACCEPT return(0) +#define YYABORT return(1) +#define YYERROR goto yyerrlab1 +/* Like YYERROR except do call yyerror. + This remains here temporarily to ease the + transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ +#define YYFAIL goto yyerrlab +#define YYRECOVERING() (!!yyerrstatus) +#define YYBACKUP(token, value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { yychar = (token), yylval = (value); \ + yychar1 = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { yyerror ("syntax error: cannot back up"); YYERROR; } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +#ifndef YYPURE +#define YYLEX yylex() +#endif + +#ifdef YYPURE +#ifdef YYLSP_NEEDED +#ifdef YYLEX_PARAM +#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) +#else +#define YYLEX yylex(&yylval, &yylloc) +#endif +#else /* not YYLSP_NEEDED */ +#ifdef YYLEX_PARAM +#define YYLEX yylex(&yylval, YYLEX_PARAM) +#else +#define YYLEX yylex(&yylval) +#endif +#endif /* not YYLSP_NEEDED */ +#endif + +/* If nonreentrant, generate the variables here */ + +#ifndef YYPURE + +int yychar; /* the lookahead symbol */ +YYSTYPE yylval; /* the semantic value of the */ + /* lookahead symbol */ + +#ifdef YYLSP_NEEDED +YYLTYPE yylloc; /* location data for the lookahead */ + /* symbol */ +#endif + +int yynerrs; /* number of parse errors so far */ +#endif /* not YYPURE */ + +#if YYDEBUG != 0 +int yydebug; /* nonzero means print parse trace */ +/* Since this is uninitialized, it does not stop multiple parsers + from coexisting. */ +#endif + +/* YYINITDEPTH indicates the initial size of the parser's stacks */ + +#ifndef YYINITDEPTH +#define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH is the maximum size the stacks can grow to + (effective only if the built-in stack extension method is used). */ + +#if YYMAXDEPTH == 0 +#undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +#define YYMAXDEPTH 10000 +#endif + +/* Prevent warning if -Wstrict-prototypes. */ +#ifdef __GNUC__ +int yyparse (void); +#endif + +#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +#define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) +#else /* not GNU C or C++ */ +#ifndef __cplusplus + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__yy_memcpy (from, to, count) + char *from; + char *to; + int count; +{ + register char *f = from; + register char *t = to; + register int i = count; + + while (i-- > 0) + *t++ = *f++; +} + +#else /* __cplusplus */ + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__yy_memcpy (char *from, char *to, int count) +{ + register char *f = from; + register char *t = to; + register int i = count; + + while (i-- > 0) + *t++ = *f++; +} + +#endif +#endif + +#line 192 "bison.simple" + +/* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. + It should actually point to an object. + Grammar actions can access the variable by casting it + to the proper pointer type. */ + +#ifdef YYPARSE_PARAM +#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; +#else +#define YYPARSE_PARAM +#define YYPARSE_PARAM_DECL +#endif + +int +yyparse(YYPARSE_PARAM) + YYPARSE_PARAM_DECL +{ + register int yystate; + register int yyn; + register short *yyssp; + register YYSTYPE *yyvsp; + int yyerrstatus; /* number of tokens to shift before error messages enabled */ + int yychar1 = 0; /* lookahead token as an internal (translated) token number */ + + short yyssa[YYINITDEPTH]; /* the state stack */ + YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ + + short *yyss = yyssa; /* refer to the stacks thru separate pointers */ + YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ + +#ifdef YYLSP_NEEDED + YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ + YYLTYPE *yyls = yylsa; + YYLTYPE *yylsp; + +#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) +#else +#define YYPOPSTACK (yyvsp--, yyssp--) +#endif + + int yystacksize = YYINITDEPTH; + +#ifdef YYPURE + int yychar; + YYSTYPE yylval; + int yynerrs; +#ifdef YYLSP_NEEDED + YYLTYPE yylloc; +#endif +#endif + + YYSTYPE yyval; /* the variable used to return */ + /* semantic values from the action */ + /* routines */ + + int yylen; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Starting parse\n"); +#endif + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss - 1; + yyvsp = yyvs; +#ifdef YYLSP_NEEDED + yylsp = yyls; +#endif + +/* Push a new state, which is found in yystate . */ +/* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. */ +yynewstate: + + *++yyssp = (short) yystate; + + if (yyssp >= yyss + yystacksize - 1) + { + /* Give user a chance to reallocate the stack */ + /* Use copies of these so that the &'s don't force the real ones into memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; +#ifdef YYLSP_NEEDED + YYLTYPE *yyls1 = yyls; +#endif + + /* Get the current used size of the three stacks, in elements. */ + int size = yyssp - yyss + 1; + +#ifdef yyoverflow + /* Each stack pointer address is followed by the size of + the data in use in that stack, in bytes. */ +#ifdef YYLSP_NEEDED + /* This used to be a conditional around just the two extra args, + but that might be undefined if yyoverflow is a macro. */ + yyoverflow("parser stack overflow", + &yyss1, size * sizeof (*yyssp), + &yyvs1, size * sizeof (*yyvsp), + &yyls1, size * sizeof (*yylsp), + &yystacksize); +#else + yyoverflow("parser stack overflow", + &yyss1, size * sizeof (*yyssp), + &yyvs1, size * sizeof (*yyvsp), + &yystacksize); +#endif + + yyss = yyss1; yyvs = yyvs1; +#ifdef YYLSP_NEEDED + yyls = yyls1; +#endif +#else /* no yyoverflow */ + /* Extend the stack our own way. */ + if (yystacksize >= YYMAXDEPTH) + { + yyerror("parser stack overflow"); + return 2; + } + yystacksize *= 2; + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); + __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); + __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); +#ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); + __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); +#endif +#endif /* no yyoverflow */ + + yyssp = yyss + size - 1; + yyvsp = yyvs + size - 1; +#ifdef YYLSP_NEEDED + yylsp = yyls + size - 1; +#endif + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Stack size increased to %d\n", yystacksize); +#endif + + if (yyssp >= yyss + yystacksize - 1) + YYABORT; + } + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Entering state %d\n", yystate); +#endif + + goto yybackup; + yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* yychar is either YYEMPTY or YYEOF + or a valid token in external form. */ + + if (yychar == YYEMPTY) + { +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Reading a token: "); +#endif + yychar = YYLEX; + } + + /* Convert token to internal form (in yychar1) for indexing tables with */ + + if (yychar <= 0) /* This means end of input. */ + { + yychar1 = 0; + yychar = YYEOF; /* Don't call YYLEX any more */ + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Now at end of input.\n"); +#endif + } + else + { + yychar1 = YYTRANSLATE(yychar); + +#if YYDEBUG != 0 + if (yydebug) + { + fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); + /* Give the individual parser a way to print the precise meaning + of a token, for further debugging info. */ +#ifdef YYPRINT + YYPRINT (stderr, yychar, yylval); +#endif + fprintf (stderr, ")\n"); + } +#endif + } + + yyn += yychar1; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) + goto yydefault; + + yyn = yytable[yyn]; + + /* yyn is what to do for this token type in this state. + Negative => reduce, -yyn is rule number. + Positive => shift, yyn is new state. + New state is final state => don't bother to shift, + just return success. + 0, or most negative number => error. */ + + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrlab; + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); +#endif + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; +#ifdef YYLSP_NEEDED + *++yylsp = yylloc; +#endif + + /* count tokens shifted since error; after three, turn off error status. */ + if (yyerrstatus) yyerrstatus--; + + yystate = yyn; + goto yynewstate; + +/* Do the default action for the current state. */ +yydefault: + + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + +/* Do a reduction. yyn is the number of a rule to reduce with. */ +yyreduce: + yylen = yyr2[yyn]; + if (yylen > 0) + yyval = yyvsp[1-yylen]; /* implement default value of the action */ + +#if YYDEBUG != 0 + if (yydebug) + { + int i; + + fprintf (stderr, "Reducing via rule %d (line %d), ", + yyn, yyrline[yyn]); + + /* Print the symbols being reduced, and their result. */ + for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) + fprintf (stderr, "%s ", yytname[yyrhs[i]]); + fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); + } +#endif + +$ /* the action file gets copied in in place of this dollarsign */ +#line 487 "bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +#ifdef YYLSP_NEEDED + yylsp -= yylen; +#endif + +#if YYDEBUG != 0 + if (yydebug) + { + short *ssp1 = yyss - 1; + fprintf (stderr, "state stack now"); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif + + *++yyvsp = yyval; + +#ifdef YYLSP_NEEDED + yylsp++; + if (yylen == 0) + { + yylsp->first_line = yylloc.first_line; + yylsp->first_column = yylloc.first_column; + yylsp->last_line = (yylsp-1)->last_line; + yylsp->last_column = (yylsp-1)->last_column; + yylsp->text = 0; + } + else + { + yylsp->last_line = (yylsp+yylen-1)->last_line; + yylsp->last_column = (yylsp+yylen-1)->last_column; + } +#endif + + /* Now "shift" the result of the reduction. + Determine what state that goes to, + based on the state we popped back to + and the rule number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTBASE] + *yyssp; + if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTBASE]; + + goto yynewstate; + +yyerrlab: /* here on detecting error */ + + if (! yyerrstatus) + /* If not already recovering from an error, report this error. */ + { + ++yynerrs; + +#ifdef YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (yyn > YYFLAG && yyn < YYLAST) + { + int size = 0; + char *msg; + int x, count; + + count = 0; + /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ + for (x = (yyn < 0 ? -yyn : 0); + x < (int)(sizeof(yytname) / sizeof(char *)); x++) //_GD_ + if (yycheck[x + yyn] == x) + size += strlen(yytname[x]) + 15, count++; + //_GD_ msg = (char *) malloc(size + 15); + msg = GM_NEW( char [size + 15] ); + if (msg != 0) + { + strcpy(msg, "parse error"); + + if (count < 5) + { + count = 0; + for (x = (yyn < 0 ? -yyn : 0); + x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) + { + strcat(msg, count == 0 ? ", expecting `" : " or `"); + strcat(msg, yytname[x]); + strcat(msg, "'"); + count++; + } + } + yyerror(msg); + //_GD_ free(msg); + delete [] msg; + } + else + yyerror ("parse error; also virtual memory exceeded"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror("parse error"); + } + + goto yyerrlab1; +yyerrlab1: /* here on error raised explicitly by an action */ + + if (yyerrstatus == 3) + { + /* if just tried and failed to reuse lookahead token after an error, discard it. */ + + /* return failure if at end of input */ + if (yychar == YYEOF) + YYABORT; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); +#endif + + yychar = YYEMPTY; + } + + /* Else will try to reuse lookahead token + after shifting the error token. */ + + yyerrstatus = 3; /* Each real token shifted decrements this */ + + goto yyerrhandle; + +yyerrdefault: /* current state does not do anything special for the error token. */ + +#if 0 + /* This is wrong; only states that explicitly want error tokens + should shift them. */ + yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ + if (yyn) goto yydefault; +#endif + +yyerrpop: /* pop the current state because it cannot handle the error token */ + + if (yyssp == yyss) YYABORT; + yyvsp--; + yystate = *--yyssp; +#ifdef YYLSP_NEEDED + yylsp--; +#endif + +#if YYDEBUG != 0 + if (yydebug) + { + short *ssp1 = yyss - 1; + fprintf (stderr, "Error: state stack now"); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif + +yyerrhandle: + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yyerrdefault; + + yyn += YYTERROR; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) + goto yyerrdefault; + + yyn = yytable[yyn]; + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrpop; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrpop; + + if (yyn == YYFINAL) + YYACCEPT; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Shifting error token, "); +#endif + + *++yyvsp = yylval; +#ifdef YYLSP_NEEDED + *++yylsp = yylloc; +#endif + + yystate = yyn; + goto yynewstate; +} diff --git a/vscript/languages/gm/src/gm/flex.skl b/vscript/languages/gm/src/gm/flex.skl new file mode 100644 index 00000000..599066e2 --- /dev/null +++ b/vscript/languages/gm/src/gm/flex.skl @@ -0,0 +1,1512 @@ +/* A lexical scanner generated by flex */ + +/* Scanner skeleton version: + * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.85 95/04/24 10:48:47 vern Exp $ + */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_NEVER_INTERACTIVE 1 + +%- +#include +#include +%* + + +#ifdef __cplusplus + +#include +%+ +class istream; +%* + +/* Use prototypes in function declarations. */ +#define YY_USE_PROTOS + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_PROTOS +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef __TURBOC__ + #pragma warn -rch + #pragma warn -use +#include +#include +#define YY_USE_CONST +#define YY_USE_PROTOS +#endif + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + + +#ifdef YY_USE_PROTOS +#define YY_PROTO(proto) proto +#else +#define YY_PROTO(proto) () +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#define YY_BUF_SIZE 16384 + +typedef struct yy_buffer_state *YY_BUFFER_STATE; + +extern int yyleng; +%- +extern FILE *yyin, *yyout; +%* + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +/* The funky do-while in the following #define is used to turn the definition + * int a single C statement (which needs a semi-colon terminator). This + * avoids problems with code like: + * + * if ( condition_holds ) + * yyless( 5 ); + * else + * do_something_else(); + * + * Prior to using the do-while the compiler would get upset at the + * "else" because it interpreted the "if" statement as being all + * done when it reached the ';' after the yyless() call. + */ + +/* Return all but the first 'n' matched characters back to the input stream. */ + +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yytext_ptr ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ +typedef unsigned int yy_size_t; + + +struct yy_buffer_state + { +%- + FILE *yy_input_file; +%+ + istream* yy_input_file; +%* + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + }; + +%- Standard (non-C++) definition +static YY_BUFFER_STATE yy_current_buffer = 0; +%* + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + */ +#define YY_CURRENT_BUFFER yy_current_buffer + + +%- Standard (non-C++) definition +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; + +static int yy_n_chars; /* number of characters read into yy_ch_buf */ + + +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart YY_PROTO(( FILE *input_file )); + +void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); +void yy_load_buffer_state YY_PROTO(( void )); +YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); +void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); +void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); +void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); +#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) + +YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); +YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *str )); +YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); +%* + +static void *yy_flex_alloc YY_PROTO(( yy_size_t )); +static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); +static void yy_flex_free YY_PROTO(( void * )); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) + +%% yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here + +%- Standard (non-C++) definition +static yy_state_type yy_get_previous_state YY_PROTO(( void )); +static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); +static int yy_get_next_buffer YY_PROTO(( void )); +static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); +%* + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yytext_ptr = yy_bp; \ +%% code to fiddle yytext and yyleng for yymore() goes here + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ +%% code to copy yytext_ptr to yytext[] goes here, if %array + yy_c_buf_p = yy_cp; + +%% data tables for the DFA and the user's section 1 definitions go here + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap YY_PROTO(( void )); +#else +extern int yywrap YY_PROTO(( void )); +#endif +#endif + +%- +#ifndef YY_NO_UNPUT +static void yyunput YY_PROTO(( int c, char *buf_ptr )); +#endif +%* + +#ifndef yytext_ptr +static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); +#endif + +#ifndef YY_NO_INPUT +%- Standard (non-C++) definition +#ifdef __cplusplus +static int yyinput YY_PROTO(( void )); +#else +static int input YY_PROTO(( void )); +#endif +%* +#endif + +#if YY_STACK_USED +static int yy_start_stack_ptr = 0; +static int yy_start_stack_depth = 0; +static int *yy_start_stack = 0; +#ifndef YY_NO_PUSH_STATE +static void yy_push_state YY_PROTO(( int new_state )); +#endif +#ifndef YY_NO_POP_STATE +static void yy_pop_state YY_PROTO(( void )); +#endif +#ifndef YY_NO_TOP_STATE +static int yy_top_state YY_PROTO(( void )); +#endif + +#else +#define YY_NO_PUSH_STATE 1 +#define YY_NO_POP_STATE 1 +#define YY_NO_TOP_STATE 1 +#endif + +#ifdef YY_MALLOC_DECL +YY_MALLOC_DECL +#else +#if __STDC__ +#ifndef __cplusplus +#include +#endif +#else +/* Just try to get by without declaring the routines. This will fail + * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) + * or sizeof(void*) != sizeof(int). + */ +#endif +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ + +#ifndef ECHO +%- Standard (non-C++) definition +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +%+ C++ definition +#define ECHO LexerOutput( yytext, yyleng ) +%* +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ +%% fread()/read() definition of YY_INPUT goes here unless we're doing C++ +%+ C++ definition + if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); +%* +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +%- +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +%+ +#define YY_FATAL_ERROR(msg) LexerError( msg ) +%* +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +%- Standard (non-C++) definition +#define YY_DECL int yylex YY_PROTO(( void )) +%+ C++ definition +#define YY_DECL int yyFlexLexer::yylex() +%* +#endif + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +%% YY_RULE_SETUP definition goes here + +YY_DECL + { + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +%% user's declarations go here + + if ( yy_init ) + { + yy_init = 0; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yy_start ) + yy_start = 1; /* first start state */ + + if ( ! yyin ) +%- + yyin = stdin; +%+ + yyin = &cin; +%* + + if ( ! yyout ) +%- + yyout = stdout; +%+ + yyout = &cout; +%* + + if ( ! yy_current_buffer ) + yy_current_buffer = + yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_load_buffer_state(); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { +%% yymore()-related code goes here + yy_cp = yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + +%% code to set up and find next match goes here + +yy_find_action: +%% code to find the action number goes here + + YY_DO_BEFORE_ACTION; + +%% code for yylineno update goes here + +do_action: /* This label is used only to access EOF actions. */ + +%% debug code goes here + + switch ( yy_act ) + { /* beginning of action switch */ +%% actions go here + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { +%% code to do back-up for compressed tables and set up yy_cp goes here + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of yylex */ + +%+ +yyFlexLexer::yyFlexLexer( istream* arg_yyin, ostream* arg_yyout ) + { + yyin = arg_yyin; + yyout = arg_yyout; + yy_c_buf_p = 0; + yy_init = 1; + yy_start = 0; + yy_flex_debug = 0; + yylineno = 1; // this will only get updated if %option yylineno + + yy_did_buffer_switch_on_eof = 0; + + yy_looking_for_trail_begin = 0; + yy_more_flag = 0; + yy_more_len = 0; + + yy_start_stack_ptr = yy_start_stack_depth = 0; + yy_start_stack = 0; + + yy_current_buffer = 0; + +#ifdef YY_USES_REJECT + yy_state_buf = new yy_state_type[YY_BUF_SIZE + 2]; +#else + yy_state_buf = 0; +#endif + } + +yyFlexLexer::~yyFlexLexer() + { + delete yy_state_buf; + yy_delete_buffer( yy_current_buffer ); + } + +void yyFlexLexer::switch_streams( istream* new_in, ostream* new_out ) + { + if ( new_in ) + { + yy_delete_buffer( yy_current_buffer ); + yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); + } + + if ( new_out ) + yyout = new_out; + } + +#ifdef YY_INTERACTIVE +int yyFlexLexer::LexerInput( char* buf, int /* max_size */ ) +#else +int yyFlexLexer::LexerInput( char* buf, int max_size ) +#endif + { + if ( yyin->eof() || yyin->fail() ) + return 0; + +#ifdef YY_INTERACTIVE + yyin->get( buf[0] ); + + if ( yyin->eof() ) + return 0; + + if ( yyin->bad() ) + return -1; + + return 1; + +#else + (void) yyin->read( buf, max_size ); + + if ( yyin->bad() ) + return -1; + else + return yyin->gcount(); +#endif + } + +void yyFlexLexer::LexerOutput( const char* buf, int size ) + { + (void) yyout->write( buf, size ); + } +%* + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ + +%- +static int yy_get_next_buffer() +%+ +int yyFlexLexer::yy_get_next_buffer() +%* + { + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( yy_current_buffer->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a singled characater, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_n_chars = 0; + + else + { + int num_to_read = + yy_current_buffer->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ +#ifdef YY_USES_REJECT + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); +#else + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = yy_current_buffer; + + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + //_GD_ + int oldSize = b->yy_buf_size; + + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + /* Include room in for 2 EOB chars. */ + //_GD_ b->yy_ch_buf = (char *) + //_GD_ yy_flex_realloc( (void *) b->yy_ch_buf, + //_GD_ b->yy_buf_size + 2 ); + //_GD_ + void* newBytes = yy_flex_alloc( b->yy_buf_size + 2 ); + memcpy(newBytes, b->yy_ch_buf, oldSize)); + yy_flex_free(b->yy_ch_buf); + b->yy_ch_buf = newBytes; + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = yy_current_buffer->yy_buf_size - + number_to_move - 1; +#endif + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); + } + + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; + + return ret_val; + } + + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +%- +static yy_state_type yy_get_previous_state() +%+ +yy_state_type yyFlexLexer::yy_get_previous_state() +%* + { + register yy_state_type yy_current_state; + register char *yy_cp; + +%% code to get the start state into yy_current_state goes here + + for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { +%% code to find the next state goes here + } + + return yy_current_state; + } + + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + +%- +#ifdef YY_USE_PROTOS +static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) +#else +static yy_state_type yy_try_NUL_trans( yy_current_state ) +yy_state_type yy_current_state; +#endif +%+ +yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) +%* + { + register int yy_is_jam; +%% code to find the next state, and perhaps do backing up, goes here + + return yy_is_jam ? 0 : yy_current_state; + } + + +%- +#ifndef YY_NO_UNPUT +#ifdef YY_USE_PROTOS +static void yyunput( int c, register char *yy_bp ) +#else +static void yyunput( c, yy_bp ) +int c; +register char *yy_bp; +#endif +%+ +void yyFlexLexer::yyunput( int c, register char* yy_bp ) +%* + { + register char *yy_cp = yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; + + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + yy_n_chars = yy_current_buffer->yy_buf_size; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + +%% update yylineno here + + yytext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; + } +%- +#endif /* ifndef YY_NO_UNPUT */ +%* + + +%- +#ifdef __cplusplus +static int yyinput() +#else +static int input() +#endif +%+ +int yyFlexLexer::yyinput() +%* + { + int c; + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + yytext_ptr = yy_c_buf_p; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + { + yy_c_buf_p = + yytext_ptr + YY_MORE_ADJ; + return EOF; + } + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + break; + + case EOB_ACT_LAST_MATCH: +#ifdef __cplusplus + YY_FATAL_ERROR( + "unexpected last match in yyinput()" ); +#else + YY_FATAL_ERROR( + "unexpected last match in input()" ); +#endif + } + } + } + + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; + +%% update BOL and yylineno + + return c; + } + + +%- +#ifdef YY_USE_PROTOS +void yyrestart( FILE *input_file ) +#else +void yyrestart( input_file ) +FILE *input_file; +#endif +%+ +void yyFlexLexer::yyrestart( istream* input_file ) +%* + { + if ( ! yy_current_buffer ) + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_init_buffer( yy_current_buffer, input_file ); + yy_load_buffer_state(); + } + + +%- +#ifdef YY_USE_PROTOS +void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +#else +void yy_switch_to_buffer( new_buffer ) +YY_BUFFER_STATE new_buffer; +#endif +%+ +void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +%* + { + if ( yy_current_buffer == new_buffer ) + return; + + if ( yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + yy_current_buffer = new_buffer; + yy_load_buffer_state(); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } + + +%- +#ifdef YY_USE_PROTOS +void yy_load_buffer_state( void ) +#else +void yy_load_buffer_state() +#endif +%+ +void yyFlexLexer::yy_load_buffer_state() +%* + { + yy_n_chars = yy_current_buffer->yy_n_chars; + yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } + + +%- +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) +#else +YY_BUFFER_STATE yy_create_buffer( file, size ) +FILE *file; +int size; +#endif +%+ +YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( istream* file, int size ) +%* + { + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; + } + + +%- +#ifdef YY_USE_PROTOS +void yy_delete_buffer( YY_BUFFER_STATE b ) +#else +void yy_delete_buffer( b ) +YY_BUFFER_STATE b; +#endif +%+ +void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) +%* + { + if ( ! b ) + return; + + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yy_flex_free( (void *) b->yy_ch_buf ); + + yy_flex_free( (void *) b ); + } + + +%- +#ifndef YY_ALWAYS_INTERACTIVE +#ifndef YY_NEVER_INTERACTIVE +extern int isatty YY_PROTO(( int )); +#endif +#endif + +#ifdef YY_USE_PROTOS +void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) +#else +void yy_init_buffer( b, file ) +YY_BUFFER_STATE b; +FILE *file; +#endif + +%+ +extern "C" int isatty YY_PROTO(( int )); +void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, istream* file ) +%* + + { + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + +%- +#if YY_ALWAYS_INTERACTIVE + b->yy_is_interactive = 1; +#else +#if YY_NEVER_INTERACTIVE + b->yy_is_interactive = 0; +#else + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; +#endif +#endif +%+ + b->yy_is_interactive = 0; +%* + } + + +%- +#ifdef YY_USE_PROTOS +void yy_flush_buffer( YY_BUFFER_STATE b ) +#else +void yy_flush_buffer( b ) +YY_BUFFER_STATE b; +#endif + +%+ +void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) +%* + { + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == yy_current_buffer ) + yy_load_buffer_state(); + } +%* + + +#ifndef YY_NO_SCAN_BUFFER +%- +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) +#else +YY_BUFFER_STATE yy_scan_buffer( base, size ) +char *base; +yy_size_t size; +#endif + { + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; + } +%* +#endif + + +#ifndef YY_NO_SCAN_STRING +%- +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_string( yyconst char *str ) +#else +YY_BUFFER_STATE yy_scan_string( str ) +yyconst char *str; +#endif + { + int len; + for ( len = 0; str[len]; ++len ) + ; + + return yy_scan_bytes( str, len ); + } +%* +#endif + + +#ifndef YY_NO_SCAN_BYTES +%- +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) +#else +YY_BUFFER_STATE yy_scan_bytes( bytes, len ) +yyconst char *bytes; +int len; +#endif + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yy_flex_alloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; + } +%* +#endif + + +#ifndef YY_NO_PUSH_STATE +%- +#ifdef YY_USE_PROTOS +static void yy_push_state( int new_state ) +#else +static void yy_push_state( new_state ) +int new_state; +#endif +%+ +void yyFlexLexer::yy_push_state( int new_state ) +%* + { + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; + + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); + + if ( ! yy_start_stack ) + yy_start_stack = (int *) yy_flex_alloc( new_size ); + + else + yy_start_stack = (int *) yy_flex_realloc( + (void *) yy_start_stack, new_size ); + + if ( ! yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + yy_start_stack[yy_start_stack_ptr++] = YY_START; + + BEGIN(new_state); + } +#endif + + +#ifndef YY_NO_POP_STATE +%- +static void yy_pop_state() +%+ +void yyFlexLexer::yy_pop_state() +%* + { + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN(yy_start_stack[yy_start_stack_ptr]); + } +#endif + + +#ifndef YY_NO_TOP_STATE +%- +static int yy_top_state() +%+ +int yyFlexLexer::yy_top_state() +%* + { + return yy_start_stack[yy_start_stack_ptr - 1]; + } +#endif + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +%- +#ifdef YY_USE_PROTOS +static void yy_fatal_error( yyconst char msg[] ) +#else +static void yy_fatal_error( msg ) +char msg[]; +#endif + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); + } + +%+ + +void yyFlexLexer::LexerError( yyconst char msg[] ) + { + cerr << msg << '\n'; + exit( YY_EXIT_FAILURE ); + } +%* + + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n - YY_MORE_ADJ; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) + + +/* Internal utility routines. */ + +#ifndef yytext_ptr +#ifdef YY_USE_PROTOS +static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) +#else +static void yy_flex_strncpy( s1, s2, n ) +char *s1; +yyconst char *s2; +int n; +#endif + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } +#endif + + +#ifdef YY_USE_PROTOS +static void *yy_flex_alloc( yy_size_t size ) +#else +static void *yy_flex_alloc( size ) +yy_size_t size; +#endif + { + //_GD_ return (void *) malloc( size ); + return (void *) GM_NEW( char [size] ); + } + +#ifdef YY_USE_PROTOS +static void *yy_flex_realloc( void *ptr, yy_size_t size ) +#else +static void *yy_flex_realloc( ptr, size ) +void *ptr; +yy_size_t size; +#endif + { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + //_GD_ return (void *) realloc( (char *) ptr, size ); + } + +#ifdef YY_USE_PROTOS +static void yy_flex_free( void *ptr ) +#else +static void yy_flex_free( ptr ) +void *ptr; +#endif + { + //_GD_ free( ptr ); + delete [] (char*) ptr; + } + +#if YY_MAIN +int main() + { + yylex(); + return 0; + } +#endif diff --git a/vscript/languages/gm/src/gm/gmArraySimple.cpp b/vscript/languages/gm/src/gm/gmArraySimple.cpp new file mode 100644 index 00000000..5e0eb616 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmArraySimple.cpp @@ -0,0 +1,18 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmArraySimple.h" + + +// Must be last header +#include "memdbgon.h" + diff --git a/vscript/languages/gm/src/gm/gmArraySimple.h b/vscript/languages/gm/src/gm/gmArraySimple.h new file mode 100644 index 00000000..8ad6ea51 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmArraySimple.h @@ -0,0 +1,333 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMARRAYSIMPLE_H_ +#define _GMARRAYSIMPLE_H_ + +#include "gmConfig.h" +#include "gmUtil.h" + +#define TMPL template +#define QUAL gmArraySimple + +/// \class gmArraySimple +/// \brief templated array class for simple types with power of 2 auto size option. +/// Elements may be moved around in memory using memcpy() during resize operations. +TMPL class gmArraySimple +{ +public: + + enum + { + NULL_INDEX = ~0 + }; + + gmArraySimple(void); + gmArraySimple(const QUAL &a_array); + ~gmArraySimple(void); + + template + inline void InsertLast(const J &a_elem) + { + if(m_count >= m_size) + { + Resize(m_count + 1); + } + m_elem[m_count++] = a_elem; + } + + /// \brief SetBlockSize() will set the hysteresis memory grow by in elements. + /// \param a_blockSize as 0 will set automatic power of 2. + inline void SetBlockSize(gmuint a_blockSize) { m_blockSize = a_blockSize; } + + inline bool InsertLastIfUnique(const T &a_elem); + inline T& InsertLast(void); + inline void InsertBefore(gmuint a_index, const T &a_elem); + inline void Remove(gmuint a_index); + inline void RemoveSwapLast(gmuint a_index); + inline void RemoveLast(void); + + inline T &operator[](gmuint a_index); + inline const T &operator[](gmuint a_index) const; + + inline gmuint Count(void) const { return m_count; } + inline bool IsEmpty(void) const { return (m_count == 0); } + + inline void Reset(void) { SetCount(0); } + inline void ResetAndFreeMemory(void); + + inline void SetCount(gmuint a_count); + inline void SetCountAndFreeMemory(gmuint a_count); + inline void Touch(gmuint a_element); + + inline T* GetData(void) { return m_elem; } + inline const T* GetData(void) const { return m_elem; } + inline gmuint GetSize(void) { return m_size; } + bool IsValid(const T* a_elem) const; + + inline QUAL &operator=(const QUAL &a_array); + + inline bool FindRemove(const T &a_elem); + + template + inline gmuint FindIndex(const Q &a_elem) const + { + // iterate backwards, better chance of finding a_elem, given InsertLast() is + // used commonly which presents possible element coherence + if(m_count == 0) return NULL_INDEX; + gmuint i = m_count - 1; + do + { + if (m_elem[i] == a_elem) // used commonly which presents possible element coherence + return i; + } while(i-- > 0); + return NULL_INDEX; + } + +private: + + T *m_elem; + gmuint m_count, m_size; + gmuint m_blockSize; //!< 0 and will be power of 2 sizing. + + /// \brief Resize() will resize the array. + /// \param a_size is the required size. + void Resize(gmuint a_size, bool a_shrinkIfPossible = false); +}; + + +// +// implementation +// + + +TMPL +inline QUAL::gmArraySimple(void) +{ + m_elem = NULL; + m_count = 0; + m_size = 0; + m_blockSize = 0; // power of 2 auto +} + + +TMPL inline QUAL::gmArraySimple(const QUAL &a_array) +{ + m_elem = NULL; + m_count = 0; + m_size = 0; + m_blockSize = 0; // power of 2 auto + operator=(a_array); +} + + +TMPL +inline QUAL::~gmArraySimple(void) +{ + if(m_elem) + { + delete[] (char *) m_elem; + } +} + + +TMPL bool QUAL::InsertLastIfUnique(const T &a_elem) +{ + if(FindIndex(a_elem) == NULL_INDEX) + { + InsertLast(a_elem); + return true; + } + return false; +} + + +TMPL inline T& QUAL::InsertLast(void) +{ + if(m_count >= m_size) + { + Resize(m_count + 1); + } + return m_elem[m_count++]; +} + + +TMPL +inline void QUAL::InsertBefore(gmuint a_index, const T &a_elem) +{ + if(a_index >= m_count) + { + InsertLast(a_elem); + } + else + { + if(m_count >= m_size) + { + Resize(m_count + 1); + } + memmove(&m_elem[a_index+1], &m_elem[a_index], (m_count - a_index) * sizeof(T)); + m_elem[a_index] = a_elem; + ++m_count; + } +} + + +TMPL +inline void QUAL::Remove(gmuint a_index) +{ + if(a_index >= m_count) return; + memmove(&m_elem[a_index], &m_elem[a_index+1], (m_count - (a_index + 1)) * sizeof(T)); + --m_count; +} + + +TMPL +inline void QUAL::RemoveSwapLast(gmuint a_index) +{ + if (a_index >= m_count) return; + if(--m_count != a_index) + { + m_elem[a_index] = m_elem[m_count]; + } +} + + +TMPL +inline void QUAL::RemoveLast(void) +{ + GM_ASSERT(m_count > 0); + --m_count; +} + + +TMPL +inline T &QUAL::operator[](gmuint a_index) +{ + GM_ASSERT(a_index >= 0 && a_index < m_count); + return m_elem[a_index]; +} + + +TMPL +inline const T &QUAL::operator[](gmuint a_index) const +{ + GM_ASSERT(a_index >= 0 && a_index < m_count); + return m_elem[a_index]; +} + + +TMPL +inline void QUAL::ResetAndFreeMemory(void) +{ + if(m_elem) + { + delete[] (char *) m_elem; + m_elem = NULL; + } + m_count = m_size = 0; +} + + +TMPL +inline void QUAL::SetCount(gmuint a_count) +{ + if(a_count > m_size) + { + Resize(a_count); + } + m_count = a_count; +} + + +TMPL +inline void QUAL::SetCountAndFreeMemory(gmuint a_count) +{ + Resize(a_count, true); + m_count = a_count; +} + + +TMPL +inline void QUAL::Touch(gmuint a_element) +{ + if(a_element >= m_count) + { + SetCount(a_element + 1); + } +} + + +TMPL bool QUAL::IsValid(const T* a_elem) const +{ + gmuint index = (a_elem - m_elem); + return (index < m_count); +} + + +TMPL +inline QUAL &QUAL::operator=(const QUAL &a_array) +{ + SetCount(a_array.m_count); + memcpy((char*)m_elem, (const char*)a_array.m_elem, m_count * sizeof(T)); + return *this; +} + + +TMPL bool QUAL::FindRemove(const T &a_elem) +{ + gmuint index = FindIndex(a_elem); + if(index != NULL_INDEX) + { + Remove(index); + return true; + } + return false; +} + + +TMPL +void QUAL::Resize(gmuint a_size, bool a_shrinkIfPossible) +{ + if(m_size >= a_size) + { + // TODO: handle a_shrinkIfPossible. + return; + } + + // we need to grow, figure out a new size. + gmuint size = 0; + if(m_blockSize > 0) + { + size = ((a_size / m_blockSize) + 1) * m_blockSize; + } + else + { + size = gmLog2ge(gmMax(4, a_size + 1)); + } + + // alloc, copy, free + { + T * t = (T*) GM_NEW(char[sizeof(T) * size]); + if(m_elem) + { + memcpy(t, m_elem, m_count * sizeof(T)); + delete[] (char *) m_elem; + } + m_elem = t; + } + + m_size = size; +} + +#undef QUAL +#undef TMPL + +#endif diff --git a/vscript/languages/gm/src/gm/gmByteCode.cpp b/vscript/languages/gm/src/gm/gmByteCode.cpp new file mode 100644 index 00000000..3f5e2995 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmByteCode.cpp @@ -0,0 +1,134 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmByteCode.h" + +// Must be last header +#include "memdbgon.h" + + +#if GM_COMPILE_DEBUG + +void gmByteCodePrint(FILE * a_fp, const void * a_byteCode, int a_byteCodeLength) +{ + union + { + const gmuint32 * instruction32; + const gmuint8 * instruction; + }; + + instruction = (const gmuint8 *) a_byteCode; + const gmuint8 * end = instruction + a_byteCodeLength; + const gmuint8 * start = instruction; + const char * cp; + bool opiptr, opf32; + + while(instruction < end) + { + opiptr = false; + opf32 = false; + + int addr = instruction - start; + + switch(*instruction) + { + case BC_NOP : cp = "nop"; break; + case BC_LINE : cp = "line"; break; + + case BC_GETDOT : cp = "get dot"; opiptr = true; break; + case BC_SETDOT : cp = "set dot"; opiptr = true; break; + case BC_GETIND : cp = "get index"; break; + case BC_SETIND : cp = "set index"; break; + + case BC_BRA : cp = "bra"; opiptr = true; break; + case BC_BRZ : cp = "brz"; opiptr = true; break; + case BC_BRNZ : cp = "brnz"; opiptr = true; break; + case BC_BRZK : cp = "brzk"; opiptr = true; break; + case BC_BRNZK : cp = "brnzk"; opiptr = true; break; + case BC_CALL : cp = "call"; opiptr = true; break; + case BC_RET : cp = "ret"; break; + case BC_RETV : cp = "retv"; break; + case BC_FOREACH : cp = "foreach"; opiptr = true; break; + + case BC_POP : cp = "pop"; break; + case BC_POP2 : cp = "pop2"; break; + case BC_DUP : cp = "dup"; break; + case BC_DUP2 : cp = "dup2"; break; + case BC_SWAP : cp = "swap"; break; + case BC_PUSHNULL : cp = "push null"; break; + case BC_PUSHINT : cp = "push int"; opiptr = true; break; + case BC_PUSHINT0 : cp = "push int 0"; break; + case BC_PUSHINT1 : cp = "push int 1"; break; + case BC_PUSHFP : cp = "push fp"; opf32 = true; break; + case BC_PUSHSTR : cp = "push str"; opiptr = true; break; + case BC_PUSHTBL : cp = "push tbl"; break; + case BC_PUSHFN : cp = "push fn"; opiptr = true; break; + case BC_PUSHTHIS : cp = "push this"; break; + + case BC_GETLOCAL : cp = "get local"; opiptr = true; break; + case BC_SETLOCAL : cp = "set local"; opiptr = true; break; + case BC_GETGLOBAL : cp = "get global"; opiptr = true; break; + case BC_SETGLOBAL : cp = "set global"; opiptr = true; break; + case BC_GETTHIS : cp = "get this"; opiptr = true; break; + case BC_SETTHIS : cp = "set this"; opiptr = true; break; + + case BC_OP_ADD : cp = "add"; break; + case BC_OP_SUB : cp = "sub"; break; + case BC_OP_MUL : cp = "mul"; break; + case BC_OP_DIV : cp = "div"; break; + case BC_OP_REM : cp = "rem"; break; + + case BC_BIT_OR : cp = "bor"; break; + case BC_BIT_XOR : cp = "bxor"; break; + case BC_BIT_AND : cp = "band"; break; + case BC_BIT_INV : cp = "binv"; break; + case BC_BIT_SHL : cp = "bshl"; break; + case BC_BIT_SHR : cp = "bshr"; break; + + case BC_OP_NEG : cp = "neg"; break; + case BC_OP_POS : cp = "pos"; break; + case BC_OP_NOT : cp = "not"; break; + + case BC_OP_LT : cp = "lt"; break; + case BC_OP_GT : cp = "gt"; break; + case BC_OP_LTE : cp = "lte"; break; + case BC_OP_GTE : cp = "gte"; break; + case BC_OP_EQ : cp = "eq"; break; + case BC_OP_NEQ : cp = "neq"; break; + + default : cp = "ERROR"; break; + } + + ++instruction32; + + if(opf32) + { + float fval = *((float *) instruction); + instruction += sizeof(gmint32); + fprintf(a_fp, " %04d %s %f"GM_NL, addr, cp, fval); + } + else if (opiptr) + { + gmptr ival = *((gmptr *) instruction); + instruction += sizeof(gmptr); + fprintf(a_fp, " %04d %s %d"GM_NL, addr, cp, ival); + } + else + { + fprintf(a_fp, " %04d %s"GM_NL, addr, cp); + } + } +} + + +#endif // GM_COMPILE_DEBUG + diff --git a/vscript/languages/gm/src/gm/gmByteCode.h b/vscript/languages/gm/src/gm/gmByteCode.h new file mode 100644 index 00000000..8bd60e39 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmByteCode.h @@ -0,0 +1,102 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMBYTECODE_H_ +#define _GMBYTECODE_H_ + +#include "gmConfig.h" + +/// \enum gmByteCode +/// \brief gmByteCode are the op codes for the game monkey scripting. The first byte codes MUST match the gmOperator +/// enum. +enum gmByteCode +{ + // BC_GETDOT to BC_NOP MUST MATCH ENUM GMOPERATOR + + BC_GETDOT = 0, // tos '.' opptr, push result + BC_SETDOT, // tos-1 '.' opptr = tos, tos -= 2 + BC_GETIND, // tos-1 = tos-1 [tos], --tos + BC_SETIND, // tos-2 [tos-1] = tos, tos -= 3 + + // math + BC_OP_ADD, + BC_OP_SUB, + BC_OP_MUL, + BC_OP_DIV, + BC_OP_REM, + + // bit + BC_BIT_OR, + BC_BIT_XOR, + BC_BIT_AND, + BC_BIT_SHL, + BC_BIT_SHR, + BC_BIT_INV, + + // compare + BC_OP_LT, + BC_OP_GT, + BC_OP_LTE, + BC_OP_GTE, + BC_OP_EQ, + BC_OP_NEQ, + + // unary + BC_OP_NEG, + BC_OP_POS, + BC_OP_NOT, + + BC_NOP, + BC_LINE, // indicates instruction is on a new code line to the last executed instruction. used in debug mode + + // branch + BC_BRA, // branch always + BC_BRZ, // branch tos equal to zero, --tos + BC_BRNZ, // branch tos not equal to zero, --tos + BC_BRZK, // branch tos equal to zero keep value on stack + BC_BRNZK, // branch tos not equal to zero keep value on stack + BC_CALL, // call op16 num parameters + BC_RET, // return null, ++tos + BC_RETV, // return tos + BC_FOREACH, // op16 op16, table, iterator, leave loop complete bool on stack. + + // stack + BC_POP, // --tos + BC_POP2, // tos -=2 + BC_DUP, // tos + 1 = tos, ++tos + BC_DUP2, // tos + 1 = tos -1, tos + 2 = tos, tos += 2 + BC_SWAP, // + BC_PUSHNULL, // push null, + BC_PUSHINT, // push int opptr + BC_PUSHINT0, // push 0 + BC_PUSHINT1, // push 1 + BC_PUSHFP, // push floating point op32 + BC_PUSHSTR, // push string opptr + BC_PUSHTBL, // push table + BC_PUSHFN, // push function opptr + BC_PUSHTHIS, // push this + + // get set + BC_GETLOCAL, // get local op16 (stack offset) ++tos + BC_SETLOCAL, // set local op16 (stack offset) --tos + BC_GETGLOBAL, // get global opptr (symbol id) ++tos + BC_SETGLOBAL, // set global opptr (symbol id) --tos + BC_GETTHIS, // get this opptr (symbol id) ++tos + BC_SETTHIS, // set this opptr (symbol id) --tos +}; + +#if GM_COMPILE_DEBUG + +void gmByteCodePrint(FILE * a_fp, const void * a_byteCode, int a_byteCodeLength); + +#endif // GM_COMPILE_DEBUG + +#endif diff --git a/vscript/languages/gm/src/gm/gmByteCodeGen.cpp b/vscript/languages/gm/src/gm/gmByteCodeGen.cpp new file mode 100644 index 00000000..4f2c2b0d --- /dev/null +++ b/vscript/languages/gm/src/gm/gmByteCodeGen.cpp @@ -0,0 +1,158 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmByteCodeGen.h" + +// Must be last header +#include "memdbgon.h" + + + +gmByteCodeGen::gmByteCodeGen(void * a_context) +{ + m_tos = 0; + m_maxTos = 0; + m_emitCallback = NULL; + m_context = a_context; +} + + + +void gmByteCodeGen::Reset(void * a_context) +{ + gmStreamBufferDynamic::Reset(); + m_tos = 0; + m_maxTos = 0; + m_emitCallback = NULL; + m_context = a_context; +} + + + +bool gmByteCodeGen::Emit(gmByteCode a_instruction) +{ + if(m_emitCallback) m_emitCallback(Tell(), m_context); + AdjustStack(a_instruction); + *this << (gmuint32) a_instruction; + return true; +} + + + +bool gmByteCodeGen::Emit(gmByteCode a_instruction, gmuint32 a_operand32) +{ + if(m_emitCallback) m_emitCallback(Tell(), m_context); + AdjustStack(a_instruction); + *this << (gmuint32) a_instruction; + *this << a_operand32; + return true; +} + + + +bool gmByteCodeGen::EmitPtr(gmByteCode a_instruction, gmptr a_operand) +{ + if(m_emitCallback) m_emitCallback(Tell(), m_context); + AdjustStack(a_instruction); + *this << ((gmuint32) a_instruction); + *this << a_operand; + return true; +} + + +unsigned int gmByteCodeGen::Skip(unsigned int p_n, unsigned char p_value) +{ + unsigned int oldPos = Tell(); + if(p_n) + { + char * fill = (char *) alloca(p_n); + memset(fill, p_value, p_n); + Write(fill, p_n); + } + return oldPos; +} + + + +void gmByteCodeGen::AdjustStack(gmByteCode a_instruction) +{ + switch(a_instruction) + { + case BC_NOP : break; + case BC_LINE : break; + + case BC_GETDOT : m_tos += 0; break; + case BC_SETDOT : m_tos -= 2; break; + case BC_GETIND : --m_tos; break; + case BC_SETIND : m_tos -= 3; break; + + case BC_BRA : break; + case BC_BRZ : --m_tos; break; + case BC_BRNZ : --m_tos; break; + case BC_BRZK : break; + case BC_BRNZK : break; + case BC_CALL : break; + case BC_RET : break; + case BC_RETV : break; + case BC_FOREACH : ++m_tos; break; + + case BC_POP : --m_tos; break; + case BC_POP2 : m_tos -= 2; break; + case BC_DUP : ++m_tos; break; + case BC_DUP2 : m_tos += 2; break; + case BC_SWAP : break; + case BC_PUSHNULL : ++m_tos; break; + case BC_PUSHINT : ++m_tos; break; + case BC_PUSHINT0 : ++m_tos; break; + case BC_PUSHINT1 : ++m_tos; break; + case BC_PUSHFP : ++m_tos; break; + case BC_PUSHSTR : ++m_tos; break; + case BC_PUSHTBL : ++m_tos; break; + case BC_PUSHFN : ++m_tos; break; + case BC_PUSHTHIS : ++m_tos; break; + + case BC_GETLOCAL : ++m_tos; break; + case BC_SETLOCAL : --m_tos; break; + case BC_GETGLOBAL : ++m_tos; break; + case BC_SETGLOBAL : --m_tos; break; + case BC_GETTHIS : ++m_tos; break; + case BC_SETTHIS : --m_tos; break; + + case BC_OP_ADD : --m_tos; break; + case BC_OP_SUB : --m_tos; break; + case BC_OP_MUL : --m_tos; break; + case BC_OP_DIV : --m_tos; break; + case BC_OP_REM : --m_tos; break; + + case BC_BIT_OR : --m_tos; break; + case BC_BIT_XOR : --m_tos; break; + case BC_BIT_AND : --m_tos; break; + case BC_BIT_INV : --m_tos; break; + case BC_BIT_SHL : --m_tos; break; + case BC_BIT_SHR : --m_tos; break; + + case BC_OP_NEG : break; + case BC_OP_POS : break; + case BC_OP_NOT : break; + + case BC_OP_LT : --m_tos; break; + case BC_OP_GT : --m_tos; break; + case BC_OP_LTE : --m_tos; break; + case BC_OP_GTE : --m_tos; break; + case BC_OP_EQ : --m_tos; break; + case BC_OP_NEQ : --m_tos; break; + } + + if(m_tos > m_maxTos) m_maxTos = m_tos; +} + + diff --git a/vscript/languages/gm/src/gm/gmByteCodeGen.h b/vscript/languages/gm/src/gm/gmByteCodeGen.h new file mode 100644 index 00000000..0da95170 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmByteCodeGen.h @@ -0,0 +1,49 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h +*/ + +#ifndef _GMBYTECODEGEN_H_ +#define _GMBYTECODEGEN_H_ + +#include "gmConfig.h" +#include "gmStreamBuffer.h" +#include "gmByteCode.h" + +/// \class gmByteCodeBuffer +class gmByteCodeGen : public gmStreamBufferDynamic +{ +public: + gmByteCodeGen(void * a_context = NULL); + virtual ~gmByteCodeGen() {} + + void Reset(void * a_context = NULL); + + bool Emit(gmByteCode a_instruction); + bool Emit(gmByteCode a_instruction, gmuint32 a_operand32); + bool EmitPtr(gmByteCode a_instruction, gmptr a_operand); + + unsigned int Skip(unsigned int p_n, unsigned char p_value = 0); + + /// \brief m_emitCallback will be called whenever code is emitted + void (GM_CDECL *m_emitCallback)(int a_address, void * a_context); + + inline int GetMaxTos() const { return m_maxTos; } + inline int GetTos() const { return m_tos; } + inline void SetTos(int a_tos) { m_tos = a_tos; } + +protected: + + void AdjustStack(gmByteCode a_instruction); + + int m_tos; + int m_maxTos; + void * m_context; +}; + +#endif // _GMBYTECODEGEN_H_ diff --git a/vscript/languages/gm/src/gm/gmCodeGen.cpp b/vscript/languages/gm/src/gm/gmCodeGen.cpp new file mode 100644 index 00000000..2356842a --- /dev/null +++ b/vscript/languages/gm/src/gm/gmCodeGen.cpp @@ -0,0 +1,1549 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmCodeGen.h" +#include "gmCodeTree.h" +#include "gmByteCodeGen.h" +#include "gmArraySimple.h" +#include "gmListDouble.h" + +// Must be last header +#include "memdbgon.h" + + +//static const char * s_tempVarName0 = "__t0"; // Currently not used +static const char * s_tempVarName1 = "__t1"; + +#define SIZEOF_BC_BRA 8 + +/// \brief gmSortDebugLines will sort debug line information +static void gmSortDebugLines(gmArraySimple &a_lineInfo) +{ + int count = a_lineInfo.Count(); + + // sort by address + int i; + for(i = 0; i < count; ++i) + { + int min = i, j; + for(j = i + 1; j < count; ++j) + { + if(a_lineInfo[j].m_address < a_lineInfo[min].m_address) + { + min = j; + } + } + gmLineInfo t = a_lineInfo[min]; + a_lineInfo[min] = a_lineInfo[i]; + a_lineInfo[i] = t; + } + + // remove duplicate line numbers + int s, d; + for(s = 1, d = 0; s < count; ++s) + { + if(a_lineInfo[s].m_lineNumber != a_lineInfo[d].m_lineNumber) + { + a_lineInfo[++d] = a_lineInfo[s]; + } + } + + a_lineInfo.SetCount(++d); +} + + +/*! + \class gmCodeGenPrivate + \brief implementation of gmCodeGen +*/ +class gmCodeGenPrivate : public gmCodeGen +{ +public: + + gmCodeGenPrivate(); + virtual ~gmCodeGenPrivate(); + + // implementation + + virtual void FreeMemory(); + virtual int Lock(const gmCodeTreeNode * a_codeTree, gmCodeGenHooks * a_hooks, bool a_debug, gmLog * a_log); + virtual int Unlock(); + + // helpers + + bool Generate(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode, bool a_siblings = true); + bool GenDeclVariable(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenExprFunction(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenExprTable(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenStmtReturn(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenStmtBreak(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenStmtContinue(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenStmtFor(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenStmtForEach(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenStmtWhile(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenStmtDoWhile(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenStmtIf(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenStmtCompound(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenExprOpDot(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenExprOpUnary(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenExprOpArrayIndex(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenExprOpAr(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenExprOpShift(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenExprOpComparison(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenExprOpBitwise(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenExprOpAnd(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenExprOpOr(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenExprOpAssign(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenExprConstant(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenExprIdentifier(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenExprCall(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + bool GenExprThis(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode); + + bool m_locked; + int m_errors; + gmLog * m_log; + gmCodeGenHooks * m_hooks; + bool m_debug; + + // Variable + struct Variable + { + int m_offset; + gmCodeTreeVariableType m_type; + const char * m_symbol; + }; + + // FunctionState + class FunctionState : public gmListDoubleNode + { + public: + FunctionState(); + ~FunctionState() {} + + void Reset(); + int SetVariableType(const char * a_symbol, gmCodeTreeVariableType a_type); + // return -2 if the variable does not exist, -1 if it exists but is not a local + // set a type to var type if return >= -1 + int GetVariableOffset(const char * a_symbol, gmCodeTreeVariableType &a_type); + + const char * m_debugName; // name of the variable the function is assigned to. + gmArraySimple m_variables; + int m_numLocals; // number of local variables including parameters. + gmByteCodeGen m_byteCode; + + // line number debug. + int m_currentLine; + gmArraySimple m_lineInfo; + }; + + // Patch + struct Patch + { + gmuint32 m_address; + int m_next; + }; + + // LoopInfo + struct LoopInfo + { + int m_breaks; + int m_continues; + }; + + int m_currentLoop; //!< loop top of stack + FunctionState * m_currentFunction; //!< function top of stack + + gmListDouble m_functionStack; + gmArraySimple m_loopStack; + gmArraySimple m_patches; + + + // helper functions + FunctionState * PushFunction(); + FunctionState * PopFunction(); + void PushLoop(); + void PopLoop(); + void ApplyPatches(int a_patches, gmByteCodeGen * a_byteCode, gmuint32 a_value); +}; + + +// +// gmLineNumberCallback is used to record byte code instruction addresses against source code line numbers. +// The callback records entries into +// +void GM_CDECL gmLineNumberCallback(int a_address, void * a_context) +{ + gmCodeGenPrivate::FunctionState * state = (gmCodeGenPrivate::FunctionState *) a_context; + gmLineInfo info, * lastEntry = NULL; + info.m_address = a_address; + info.m_lineNumber = state->m_currentLine; + if(state->m_lineInfo.Count() > 0) + { + lastEntry = &state->m_lineInfo[state->m_lineInfo.Count() - 1]; + } + if(lastEntry == NULL || (lastEntry->m_address != a_address) || (lastEntry->m_lineNumber != state->m_currentLine)) + { + state->m_lineInfo.InsertLast(info); + } +} + + + +gmCodeGen& gmCodeGen::Get() +{ + static gmCodeGenPrivate codeGen; + return codeGen; +} + + + +// +// +// Implementation of gmCodeGenPrivate +// +// + +gmCodeGenPrivate::gmCodeGenPrivate() +{ + m_locked = false; + m_errors = 0; + m_log = NULL; + m_hooks = NULL; + m_debug = false; + + m_currentLoop = -1; + m_currentFunction = NULL; +} + + + +gmCodeGenPrivate::~gmCodeGenPrivate() +{ + FreeMemory(); +} + + + +void gmCodeGenPrivate::FreeMemory() +{ + if(m_locked == false) + { + m_currentLoop = -1; + m_currentFunction = NULL; + m_loopStack.ResetAndFreeMemory(); + m_functionStack.RemoveAndDeleteAll(); + m_patches.ResetAndFreeMemory(); + } +} + + + +int gmCodeGenPrivate::Lock(const gmCodeTreeNode * a_codeTree, gmCodeGenHooks * a_hooks, bool a_debug, gmLog * a_log) +{ + if(m_locked == true) return 1; + + // set up members + m_errors = 0; + m_locked = true; + m_log = a_log; + m_hooks = a_hooks; + m_debug = a_debug; + + GM_ASSERT(m_hooks != NULL); + + // set up memory and stacks. + m_currentLoop = -1; + m_currentFunction = NULL; + m_loopStack.Reset(); + m_patches.Reset(); + + // set up the stacks for the first procedure. + m_hooks->Begin(m_debug); + + PushFunction(); + GM_ASSERT(m_currentFunction); + + // generate the byte code for the root procedure + if(!Generate(a_codeTree, &m_currentFunction->m_byteCode)) + { + ++m_errors; + } + else + { + m_currentFunction->m_byteCode.Emit(BC_RET); + + // Create a locals table + const char ** locals = NULL; + if(m_debug) + { + locals = (const char **) alloca(sizeof(const char *) * m_currentFunction->m_numLocals); + memset(locals, 0, sizeof(const char *) * m_currentFunction->m_numLocals); + for(gmuint v = 0; v < m_currentFunction->m_variables.Count(); ++v) + { + Variable &variable = m_currentFunction->m_variables[v]; + if(variable.m_offset != -1) + { + locals[variable.m_offset] = variable.m_symbol; + } + } + } + + // Fill out a function info struct and add the function to the code gen hooks. + + gmSortDebugLines(m_currentFunction->m_lineInfo); + + gmFunctionInfo info; + info.m_id = m_hooks->GetFunctionId(); + info.m_root = true; + info.m_byteCode = m_currentFunction->m_byteCode.GetData(); + info.m_byteCodeLength = m_currentFunction->m_byteCode.Tell(); + info.m_numParams = 0; + info.m_numLocals = m_currentFunction->m_numLocals; + info.m_symbols = locals; + info.m_maxStackSize = m_currentFunction->m_byteCode.GetMaxTos(); + info.m_lineInfoCount = m_currentFunction->m_lineInfo.Count(); + info.m_lineInfo = m_currentFunction->m_lineInfo.GetData(); + info.m_debugName = "__main"; + m_hooks->AddFunction(info); + + //gmByteCodePrint(stdout, info.m_byteCode, info.m_byteCodeLength); + } + + PopFunction(); + + m_hooks->End(m_errors); + + return m_errors; +} + + + +int gmCodeGenPrivate::Unlock() +{ + m_errors = 0; + m_locked = false; + m_log = NULL; + m_hooks = NULL; + m_debug = false; + m_currentLoop = -1; + m_loopStack.Reset(); + m_patches.Reset(); + return 0; +} + + + +bool gmCodeGenPrivate::Generate(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode, bool a_siblings) +{ + bool res = true; + + while(a_node) + { + // record line number + static int s_line = 0; + if(m_currentFunction) m_currentFunction->m_currentLine = a_node->m_lineNumber; + + // if we are in debug, emit a BC_LINE instruction + if(m_debug && (s_line != a_node->m_lineNumber) && + !(a_node->m_type == CTNT_STATEMENT && a_node->m_subType == CTNST_COMPOUND)) + { + a_byteCode->Emit(BC_LINE); + s_line = a_node->m_lineNumber; + } + + switch(a_node->m_type) + { + case CTNT_DECLARATION : + { + switch(a_node->m_subType) + { + case CTNDT_VARIABLE : res = GenDeclVariable(a_node, a_byteCode); break; + default: + { + GM_ASSERT(false); + return false; + } + } + break; + } + case CTNT_STATEMENT : + { + switch(a_node->m_subType) + { + case CTNST_RETURN : res = GenStmtReturn(a_node, a_byteCode); break; + case CTNST_BREAK : res = GenStmtBreak(a_node, a_byteCode); break; + case CTNST_CONTINUE : res = GenStmtContinue(a_node, a_byteCode); break; + case CTNST_FOR : res = GenStmtFor(a_node, a_byteCode); break; + case CTNST_FOREACH : res = GenStmtForEach(a_node, a_byteCode); break; + case CTNST_WHILE : res = GenStmtWhile(a_node, a_byteCode); break; + case CTNST_DOWHILE : res = GenStmtDoWhile(a_node, a_byteCode); break; + case CTNST_IF : res = GenStmtIf(a_node, a_byteCode); break; + case CTNST_COMPOUND : res = GenStmtCompound(a_node, a_byteCode); break; + default: + { + GM_ASSERT(false); + return false; + } + } + break; + } + case CTNT_EXPRESSION : + { + switch(a_node->m_subType) + { + case CTNET_OPERATION : + { + switch(a_node->m_subTypeType) + { + case CTNOT_DOT : res = GenExprOpDot(a_node, a_byteCode); break; + case CTNOT_UNARY_PLUS : + case CTNOT_UNARY_MINUS : + case CTNOT_UNARY_COMPLEMENT : + case CTNOT_UNARY_NOT : res = GenExprOpUnary(a_node, a_byteCode); break; + case CTNOT_ARRAY_INDEX : res = GenExprOpArrayIndex(a_node, a_byteCode); break; + case CTNOT_TIMES : + case CTNOT_DIVIDE : + case CTNOT_REM : + case CTNOT_MINUS : + case CTNOT_ADD : res = GenExprOpAr(a_node, a_byteCode); break; + case CTNOT_SHIFT_LEFT : + case CTNOT_SHIFT_RIGHT : res = GenExprOpShift(a_node, a_byteCode); break; + case CTNOT_LT : + case CTNOT_GT : + case CTNOT_LTE : + case CTNOT_GTE : + case CTNOT_EQ : + case CTNOT_NEQ : res = GenExprOpComparison(a_node, a_byteCode); break; + case CTNOT_BIT_AND : + case CTNOT_BIT_XOR : + case CTNOT_BIT_OR : res = GenExprOpBitwise(a_node, a_byteCode); break; + case CTNOT_AND : res = GenExprOpAnd(a_node, a_byteCode); break; + case CTNOT_OR : res = GenExprOpOr(a_node, a_byteCode); break; + case CTNOT_ASSIGN : res = GenExprOpAssign(a_node, a_byteCode); break; + default: + { + GM_ASSERT(false); + return false; + } + } + break; + } + case CTNET_CONSTANT : res = GenExprConstant(a_node, a_byteCode); break; + case CTNET_IDENTIFIER : res = GenExprIdentifier(a_node, a_byteCode); break; + case CTNET_CALL : res = GenExprCall(a_node, a_byteCode); break; + case CTNET_THIS : res = GenExprThis(a_node, a_byteCode); break; + case CTNET_FUNCTION : res = GenExprFunction(a_node, a_byteCode); break; + case CTNET_TABLE : res = GenExprTable(a_node, a_byteCode); break; + default : + { + GM_ASSERT(false); + return false; + } + } + + break; + } + default: + { + GM_ASSERT(false); + return false; + } + } + + if(!res) + { + return false; + } + + if((a_node->m_flags & gmCodeTreeNode::CTN_POP) > 0) + { + a_byteCode->Emit(BC_POP); + } + + if(a_siblings) + { + a_node = a_node->m_sibling; + } + else a_node = NULL; + } + return true; +} + + + +bool gmCodeGenPrivate::GenDeclVariable(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_DECLARATION && a_node->m_subType == CTNDT_VARIABLE); + GM_ASSERT(m_currentFunction); + m_currentFunction->SetVariableType(a_node->m_children[0]->m_data.m_string, (gmCodeTreeVariableType) a_node->m_subTypeType); + return true; +} + + + +bool gmCodeGenPrivate::GenExprFunction(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_EXPRESSION && a_node->m_subType == CTNET_FUNCTION); + + gmptr id = m_hooks->GetFunctionId(); + a_byteCode->EmitPtr(BC_PUSHFN, id); + + // Create the function + PushFunction(); + + // Get a debug function name as the name of the variable the function is assigned to + if(m_debug && a_node->m_parent && a_node->m_parent->m_type == CTNT_EXPRESSION && a_node->m_parent->m_subType == CTNET_OPERATION && + (a_node->m_parent->m_subTypeType == CTNOT_ASSIGN || a_node->m_parent->m_subTypeType == CTNOT_ASSIGN_FIELD) && a_node->m_parent->m_children[1] == a_node) + { + const gmCodeTreeNode * debugName = a_node->m_parent->m_children[0]; + if(debugName && debugName->m_type == CTNT_EXPRESSION && debugName->m_subType == CTNET_IDENTIFIER) + { + } + else if(debugName->m_type == CTNT_EXPRESSION && debugName->m_subType == CTNET_OPERATION && + debugName->m_subTypeType == CTNOT_DOT) + { + debugName = debugName->m_children[1]; + } + else + { + debugName = NULL; + } + + if(debugName) + { + GM_ASSERT(debugName->m_type == CTNT_EXPRESSION && debugName->m_subType == CTNET_IDENTIFIER); + m_currentFunction->m_debugName = debugName->m_data.m_string; + } + } + + // Parameters + const gmCodeTreeNode * params = a_node->m_children[0]; + int numParams = 0; + while(params) + { + const gmCodeTreeNode * param = params->m_children[0]; + GM_ASSERT(param->m_type == CTNT_EXPRESSION && param->m_subType == CTNET_IDENTIFIER); + if(m_currentFunction->SetVariableType(param->m_data.m_string, CTVT_LOCAL) != numParams) + { + if(m_log) m_log->LogEntry("error (%d) parameter %s already declared", param->m_lineNumber, param->m_data.m_string); + PopFunction(); + return false; + } + ++numParams; + params = params->m_sibling; + } + + // Generate the code + bool res = Generate(a_node->m_children[1], &m_currentFunction->m_byteCode); + + // Generate a return incase the function didnt have one. + m_currentFunction->m_byteCode.Emit(BC_RET); + + if(res) + { + // Create a locals table + const char ** locals = NULL; + if(m_debug) + { + locals = (const char **) alloca(sizeof(const char *) * m_currentFunction->m_numLocals); + memset(locals, 0, sizeof(const char *) * m_currentFunction->m_numLocals); + + for(gmuint v = 0; v < m_currentFunction->m_variables.Count(); ++v) + { + Variable &variable = m_currentFunction->m_variables[v]; + if(variable.m_offset != -1) + { + locals[variable.m_offset] = variable.m_symbol; + } + } + } + + // Add the function to the hooks. + + gmSortDebugLines(m_currentFunction->m_lineInfo); + + gmFunctionInfo info; + info.m_id = id; + info.m_root = false; + info.m_byteCode = m_currentFunction->m_byteCode.GetData(); + info.m_byteCodeLength = m_currentFunction->m_byteCode.Tell(); + info.m_numParams = numParams; + info.m_numLocals = m_currentFunction->m_numLocals - numParams; + info.m_symbols = locals; + info.m_maxStackSize = m_currentFunction->m_byteCode.GetMaxTos(); + info.m_lineInfoCount = m_currentFunction->m_lineInfo.Count(); + info.m_lineInfo = m_currentFunction->m_lineInfo.GetData(); + info.m_debugName = m_currentFunction->m_debugName; + m_hooks->AddFunction(info); + + //gmByteCodePrint(stdout, info.m_byteCode, info.m_byteCodeLength); + } + + PopFunction(); + + return res; +} + + + +bool gmCodeGenPrivate::GenExprTable(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_EXPRESSION && a_node->m_subType == CTNET_TABLE); + + gmuint32 index = 0; + const gmCodeTreeNode * fields = a_node->m_children[0]; + + // Create table + a_byteCode->Emit(BC_PUSHTBL); + + // Create fields + while(fields) + { + a_byteCode->Emit(BC_DUP); + + if(fields->m_type == CTNT_EXPRESSION && fields->m_subType == CTNET_OPERATION && fields->m_subTypeType == CTNOT_ASSIGN_FIELD) + { + if(!Generate(fields->m_children[1], a_byteCode)) return false; + a_byteCode->EmitPtr(BC_SETDOT, m_hooks->GetSymbolId(fields->m_children[0]->m_data.m_string)); + } + else + { + a_byteCode->EmitPtr(BC_PUSHINT, index++); + if(!Generate(fields, a_byteCode, false)) return false; + a_byteCode->Emit(BC_SETIND); + } + + fields = fields->m_sibling; + } + + return true; +} + + + +bool gmCodeGenPrivate::GenStmtReturn(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_STATEMENT && a_node->m_subType == CTNST_RETURN); + + if(a_node->m_children[0]) + { + if(!Generate(a_node->m_children[0], a_byteCode)) return false; + return a_byteCode->Emit(BC_RETV); + } + return a_byteCode->Emit(BC_RET); +} + + + +bool gmCodeGenPrivate::GenStmtBreak(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_STATEMENT && a_node->m_subType == CTNST_BREAK); + + if(m_currentLoop >= 0) + { + a_byteCode->Emit(BC_BRA); + Patch * patch = &m_patches.InsertLast(); + patch->m_address = a_byteCode->Skip(sizeof(gmuint32)); + patch->m_next = m_loopStack[m_currentLoop].m_breaks; + m_loopStack[m_currentLoop].m_breaks = m_patches.Count()-1; + return true; + } + + if(m_log) m_log->LogEntry("error (%d) illegal break statement", a_node->m_lineNumber); + return false; +} + + + +bool gmCodeGenPrivate::GenStmtContinue(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_STATEMENT && a_node->m_subType == CTNST_CONTINUE); + + if(m_currentLoop >= 0) + { + a_byteCode->Emit(BC_BRA); + Patch * patch = &m_patches.InsertLast(); + patch->m_address = a_byteCode->Skip(sizeof(gmuint32)); + patch->m_next = m_loopStack[m_currentLoop].m_continues; + m_loopStack[m_currentLoop].m_continues = m_patches.Count()-1; + return true; + } + + if(m_log) m_log->LogEntry("error (%d) illegal continue statement", a_node->m_lineNumber); + return false; +} + + + +bool gmCodeGenPrivate::GenStmtFor(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_STATEMENT && a_node->m_subType == CTNST_FOR); + + unsigned int loc1, loc2 = 0, continueAddress; + + // Initialisers + if(!Generate(a_node->m_children[0], a_byteCode)) return false; + + PushLoop(); + + loc1 = a_byteCode->Tell(); + + // Condition expression + if(!Generate(a_node->m_children[1], a_byteCode)) + { + PopLoop(); + return false; + } + if(a_node->m_children[1] != NULL) // no branch for no test. + { + loc2 = a_byteCode->Skip(SIZEOF_BC_BRA); + } + + // Body + if(!Generate(a_node->m_children[3], a_byteCode)) + { + PopLoop(); + return false; + } + + // Continue patch + continueAddress = a_byteCode->Tell(); + + // Loop Expression + if(!Generate(a_node->m_children[2], a_byteCode)) + { + PopLoop(); + return false; + } + + a_byteCode->EmitPtr(BC_BRA, loc1); + loc1 = a_byteCode->Tell(); + if(a_node->m_children[1] != NULL) + { + a_byteCode->Seek(loc2); + a_byteCode->EmitPtr(BC_BRZ, loc1); + a_byteCode->Seek(loc1); + } + + ApplyPatches(m_loopStack[m_currentLoop].m_breaks, a_byteCode, loc1); + ApplyPatches(m_loopStack[m_currentLoop].m_continues, a_byteCode, continueAddress); + + PopLoop(); + return true; +} + + + +bool gmCodeGenPrivate::GenStmtForEach(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + unsigned int breakAddress, continueAddress, loc1, loc2; + + // Generate table + if(!Generate(a_node->m_children[0], a_byteCode)) + { + return false; + } + + PushLoop(); + + // Push the first iterator + a_byteCode->Emit(BC_PUSHINT, (gmuint32) -2); // first iterator value. + + continueAddress = a_byteCode->Tell(); + + // Generate call + const char * keyVar = s_tempVarName1; + if(a_node->m_children[2]) keyVar = a_node->m_children[2]->m_data.m_string; + const char * valueVar = a_node->m_children[1]->m_data.m_string; + + gmuint16 keyOffset = (gmuint16) m_currentFunction->SetVariableType(keyVar, CTVT_LOCAL); + gmuint16 valueOffset = (gmuint16) m_currentFunction->SetVariableType(valueVar, CTVT_LOCAL); + gmuint32 opcode = (keyOffset << 16) | (valueOffset & 0xffff); + + loc1 = a_byteCode->Tell(); + a_byteCode->Emit(BC_FOREACH, opcode); + + // Skip space for jump + loc2 = a_byteCode->Skip(SIZEOF_BC_BRA); + + // Generate body + if(!Generate(a_node->m_children[3], a_byteCode)) + { + PopLoop(); + return false; + } + + a_byteCode->Emit(BC_BRA, (gmuint32) loc1); + breakAddress = a_byteCode->Seek(loc2); + a_byteCode->EmitPtr(BC_BRZ, breakAddress); + a_byteCode->Seek(breakAddress); + + // pop table and iterator + a_byteCode->Emit(BC_POP2); + + ApplyPatches(m_loopStack[m_currentLoop].m_breaks, a_byteCode, breakAddress); + ApplyPatches(m_loopStack[m_currentLoop].m_continues, a_byteCode, continueAddress); + + PopLoop(); + return true; +} + + + +bool gmCodeGenPrivate::GenStmtWhile(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_STATEMENT && a_node->m_subType == CTNST_WHILE); + + unsigned int loc1, loc2, continueAddress; + + PushLoop(); + + // Continue address + loc1 = continueAddress = a_byteCode->Tell(); + + // Condition expression + if(!Generate(a_node->m_children[0], a_byteCode)) + { + PopLoop(); + return false; + } + + loc2 = a_byteCode->Skip(SIZEOF_BC_BRA); + + // Loop body + if(!Generate(a_node->m_children[1], a_byteCode)) + { + PopLoop(); + return false; + } + + a_byteCode->EmitPtr(BC_BRA, loc1); + loc1 = a_byteCode->Seek(loc2); + a_byteCode->EmitPtr(BC_BRZ, loc1); + a_byteCode->Seek(loc1); + + ApplyPatches(m_loopStack[m_currentLoop].m_breaks, a_byteCode, loc1); + ApplyPatches(m_loopStack[m_currentLoop].m_continues, a_byteCode, continueAddress); + + PopLoop(); + return true; +} + + + +bool gmCodeGenPrivate::GenStmtDoWhile(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_STATEMENT && a_node->m_subType == CTNST_DOWHILE); + + unsigned int loc1, continueAddress; + + PushLoop(); + + loc1 = a_byteCode->Tell(); + + // Loop body + if(!Generate(a_node->m_children[1], a_byteCode)) + { + PopLoop(); + return false; + } + + // Continue address + continueAddress = a_byteCode->Tell(); + + // Condition expression + if(!Generate(a_node->m_children[0], a_byteCode)) + { + PopLoop(); + return false; + } + + a_byteCode->EmitPtr(BC_BRNZ, loc1); + + loc1 = a_byteCode->Tell(); + + ApplyPatches(m_loopStack[m_currentLoop].m_breaks, a_byteCode, loc1); + ApplyPatches(m_loopStack[m_currentLoop].m_continues, a_byteCode, continueAddress); + + PopLoop(); + return true; +} + + + +bool gmCodeGenPrivate::GenStmtIf(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_STATEMENT && a_node->m_subType == CTNST_IF); + + unsigned int loc1, loc2, loc3; + + if(a_node->m_children[2]) // Is this an if-else, or just an if + { + if(!Generate(a_node->m_children[0], a_byteCode)) return false; + loc1 = a_byteCode->Skip(SIZEOF_BC_BRA); + if(!Generate(a_node->m_children[1], a_byteCode)) return false; + loc2 = a_byteCode->Skip(SIZEOF_BC_BRA); + if(!Generate(a_node->m_children[2], a_byteCode)) return false; + loc3 = a_byteCode->Seek(loc1); + a_byteCode->EmitPtr(BC_BRZ, loc2+SIZEOF_BC_BRA); + a_byteCode->Seek(loc2); + a_byteCode->EmitPtr(BC_BRA, loc3); + a_byteCode->Seek(loc3); + } + else + { + if(!Generate(a_node->m_children[0], a_byteCode)) return false; + loc1 = a_byteCode->Skip(SIZEOF_BC_BRA); + if(!Generate(a_node->m_children[1], a_byteCode)) return false; + loc2 = a_byteCode->Seek(loc1); + m_currentFunction->m_currentLine = a_node->m_lineNumber; + a_byteCode->EmitPtr(BC_BRZ, loc2); + a_byteCode->Seek(loc2); + } + + return true; +} + + + +bool gmCodeGenPrivate::GenStmtCompound(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + return Generate(a_node->m_children[0], a_byteCode); +} + + + +bool gmCodeGenPrivate::GenExprOpDot(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_EXPRESSION && a_node->m_subType == CTNET_OPERATION && a_node->m_subTypeType == CTNOT_DOT); + + if(!Generate(a_node->m_children[0], a_byteCode)) return false; + + // make sure child 1 is an identifier + const gmCodeTreeNode * id = a_node->m_children[1]; + if(id && id->m_type == CTNT_EXPRESSION && id->m_subType == CTNET_IDENTIFIER) + { + return a_byteCode->EmitPtr(BC_GETDOT, m_hooks->GetSymbolId(a_node->m_children[1]->m_data.m_string)); + } + + if(m_log) m_log->LogEntry("error (%d) illegal dot operator", a_node->m_lineNumber); + return false; +} + + + +bool gmCodeGenPrivate::GenExprOpUnary(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_EXPRESSION && a_node->m_subType == CTNET_OPERATION); + + if(!Generate(a_node->m_children[0], a_byteCode)) return false; + + switch(a_node->m_subTypeType) + { + case CTNOT_UNARY_PLUS : return a_byteCode->Emit(BC_OP_POS); + case CTNOT_UNARY_MINUS : return a_byteCode->Emit(BC_OP_NEG); + case CTNOT_UNARY_NOT : return a_byteCode->Emit(BC_OP_NOT); + case CTNOT_UNARY_COMPLEMENT : return a_byteCode->Emit(BC_BIT_INV); + default : + { + if(m_log) m_log->LogEntry("error (%d) unkown operator", a_node->m_lineNumber); + } + } + return false; +} + + + +bool gmCodeGenPrivate::GenExprOpArrayIndex(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_EXPRESSION && a_node->m_subType == CTNET_OPERATION && a_node->m_subTypeType == CTNOT_ARRAY_INDEX); + + if(!Generate(a_node->m_children[0], a_byteCode)) return false; + if(!Generate(a_node->m_children[1], a_byteCode)) return false; + + return a_byteCode->Emit(BC_GETIND); +} + + + +bool gmCodeGenPrivate::GenExprOpAr(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_EXPRESSION && a_node->m_subType == CTNET_OPERATION); + + if(!Generate(a_node->m_children[0], a_byteCode)) return false; + if(!Generate(a_node->m_children[1], a_byteCode)) return false; + + switch(a_node->m_subTypeType) + { + case CTNOT_TIMES : return a_byteCode->Emit(BC_OP_MUL); + case CTNOT_DIVIDE : return a_byteCode->Emit(BC_OP_DIV); + case CTNOT_REM : return a_byteCode->Emit(BC_OP_REM); + case CTNOT_ADD : return a_byteCode->Emit(BC_OP_ADD); + case CTNOT_MINUS : return a_byteCode->Emit(BC_OP_SUB); + default : + { + if(m_log) m_log->LogEntry("error (%d) unkown arithmatic operator", a_node->m_lineNumber); + } + } + return false; +} + + + +bool gmCodeGenPrivate::GenExprOpShift(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_EXPRESSION && a_node->m_subType == CTNET_OPERATION); + + if(!Generate(a_node->m_children[0], a_byteCode)) return false; + if(!Generate(a_node->m_children[1], a_byteCode)) return false; + + switch(a_node->m_subTypeType) + { + case CTNOT_SHIFT_LEFT : return a_byteCode->Emit(BC_BIT_SHL); + case CTNOT_SHIFT_RIGHT : return a_byteCode->Emit(BC_BIT_SHR); + default : + { + if(m_log) m_log->LogEntry("error (%d) unkown shift operator", a_node->m_lineNumber); + } + } + return false; +} + + + +bool gmCodeGenPrivate::GenExprOpComparison(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_EXPRESSION && a_node->m_subType == CTNET_OPERATION); + + if(!Generate(a_node->m_children[0], a_byteCode)) return false; + if(!Generate(a_node->m_children[1], a_byteCode)) return false; + + switch(a_node->m_subTypeType) + { + case CTNOT_LT : return a_byteCode->Emit(BC_OP_LT); + case CTNOT_GT : return a_byteCode->Emit(BC_OP_GT); + case CTNOT_LTE : return a_byteCode->Emit(BC_OP_LTE); + case CTNOT_GTE : return a_byteCode->Emit(BC_OP_GTE); + case CTNOT_EQ : return a_byteCode->Emit(BC_OP_EQ); + case CTNOT_NEQ : return a_byteCode->Emit(BC_OP_NEQ); + default : + { + if(m_log) m_log->LogEntry("error (%d) unkown comparison operator", a_node->m_lineNumber); + } + } + return false; +} + + + +bool gmCodeGenPrivate::GenExprOpBitwise(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_EXPRESSION && a_node->m_subType == CTNET_OPERATION); + + if(!Generate(a_node->m_children[0], a_byteCode)) return false; + if(!Generate(a_node->m_children[1], a_byteCode)) return false; + + switch(a_node->m_subTypeType) + { + case CTNOT_BIT_AND : return a_byteCode->Emit(BC_BIT_AND); + case CTNOT_BIT_XOR : return a_byteCode->Emit(BC_BIT_XOR); + case CTNOT_BIT_OR : return a_byteCode->Emit(BC_BIT_OR); + default : + { + if(m_log) m_log->LogEntry("error (%d) unkown bitwise operator", a_node->m_lineNumber); + } + } + return false; +} + + + +bool gmCodeGenPrivate::GenExprOpAnd(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_EXPRESSION && a_node->m_subType == CTNET_OPERATION && a_node->m_subTypeType == CTNOT_AND); + + unsigned int loc1, loc2; + + // Generate expression 1 + if(!Generate(a_node->m_children[0], a_byteCode)) return false; + loc1 = a_byteCode->Skip(SIZEOF_BC_BRA); + + // Generate expression 2 + a_byteCode->Emit(BC_POP); + if(!Generate(a_node->m_children[1], a_byteCode)) return false; + + // Seek back and finish expression 1 + loc2 = a_byteCode->Seek(loc1); + a_byteCode->EmitPtr(BC_BRZK, loc2); + a_byteCode->Seek(loc2); + + return true; +} + + + +bool gmCodeGenPrivate::GenExprOpOr(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_EXPRESSION && a_node->m_subType == CTNET_OPERATION && a_node->m_subTypeType == CTNOT_OR); + + unsigned int loc1, loc2; + + // Generate expression 1 + if(!Generate(a_node->m_children[0], a_byteCode)) return false; + loc1 = a_byteCode->Skip(SIZEOF_BC_BRA); + + // Generate expression 2 + a_byteCode->Emit(BC_POP); + if(!Generate(a_node->m_children[1], a_byteCode)) return false; + + // Seek back and finish expression 1 + loc2 = a_byteCode->Seek(loc1); + a_byteCode->EmitPtr(BC_BRNZK, loc2); + a_byteCode->Seek(loc2); + + return true; +} + + + +bool gmCodeGenPrivate::GenExprOpAssign(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_EXPRESSION && a_node->m_subType == CTNET_OPERATION); + + // value on left hand side must be an l-value... ie, a dot, array or identifier. + const gmCodeTreeNode * lValue = a_node->m_children[0]; + int type = 0; + + if(lValue->m_type == CTNT_EXPRESSION && lValue->m_subType == CTNET_OPERATION && lValue->m_subTypeType == CTNOT_DOT) + { + // Generate half l-value + if(!Generate(lValue->m_children[0], a_byteCode)) return false; + type = 0; + } + else if(lValue->m_type == CTNT_EXPRESSION && lValue->m_subType == CTNET_OPERATION && lValue->m_subTypeType == CTNOT_ARRAY_INDEX) + { + // Generate half l-value + if(!Generate(lValue->m_children[0], a_byteCode)) return false; + if(!Generate(lValue->m_children[1], a_byteCode)) return false; + type = 1; + } + else if(lValue->m_type == CTNT_EXPRESSION && lValue->m_subType == CTNET_IDENTIFIER) + { + type = 2; + } + else + { + if(m_log) m_log->LogEntry("error (%d) illegal l-value for '=' operator", a_node->m_lineNumber); + return false; + } + + // Generate r-value + if(!Generate(a_node->m_children[1], a_byteCode)) return false; + + // complete assignment + if(type == 0) + { + a_byteCode->EmitPtr(BC_SETDOT, m_hooks->GetSymbolId(lValue->m_children[1]->m_data.m_string)); + } + else if(type == 1) + { + a_byteCode->Emit(BC_SETIND); + } + else if(type == 2) + { + gmCodeTreeVariableType vtype; + int offset = m_currentFunction->GetVariableOffset(lValue->m_data.m_string, vtype); + + // if local, set local regardless + // if member set this + // if global, set global + // set and add local + + if((lValue->m_flags & gmCodeTreeNode::CTN_MEMBER) > 0) + { + return a_byteCode->EmitPtr(BC_SETTHIS, m_hooks->GetSymbolId(lValue->m_data.m_string)); + } + if(offset >= 0 && vtype == CTVT_LOCAL) + { + return a_byteCode->Emit(BC_SETLOCAL, (gmuint32) offset); + } + else if(offset == -1) + { + if(vtype == CTVT_MEMBER) + { + return a_byteCode->EmitPtr(BC_SETTHIS, m_hooks->GetSymbolId(lValue->m_data.m_string)); + } + else if(vtype == CTVT_GLOBAL) + { + return a_byteCode->EmitPtr(BC_SETGLOBAL, m_hooks->GetSymbolId(lValue->m_data.m_string)); + } + if(m_log) m_log->LogEntry("internal error"); + return false; + } + + offset = m_currentFunction->SetVariableType(lValue->m_data.m_string, CTVT_LOCAL); + return a_byteCode->Emit(BC_SETLOCAL, (gmuint32) offset); + } + else + { + // paranoia + if(m_log) m_log->LogEntry("internal error"); + return false; + } + + return true; +} + + + +bool gmCodeGenPrivate::GenExprConstant(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_EXPRESSION && a_node->m_subType == CTNET_CONSTANT); + + switch(a_node->m_subTypeType) + { + case CTNCT_INT : // INT + { + if(a_node->m_data.m_iValue == 0) + { + a_byteCode->Emit(BC_PUSHINT0); + } + else if(a_node->m_data.m_iValue == 1) + { + a_byteCode->Emit(BC_PUSHINT1); + } + else + { + a_byteCode->EmitPtr(BC_PUSHINT, *((gmptr *) &a_node->m_data.m_iValue)); + } + break; + } + case CTNCT_FLOAT : // FLOAT + { + a_byteCode->Emit(BC_PUSHFP, *((gmuint32 *) ((void *) &a_node->m_data.m_fValue))); + break; + } + case CTNCT_STRING : // STRING + { + a_byteCode->EmitPtr(BC_PUSHSTR, m_hooks->GetStringId(a_node->m_data.m_string)); + break; + } + case CTNCT_NULL : // NULL + { + a_byteCode->Emit(BC_PUSHNULL); + break; + } + default: + { + if(m_log) m_log->LogEntry("unkown constant type"); + return false; + } + } + + return true; +} + + + +bool gmCodeGenPrivate::GenExprIdentifier(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_EXPRESSION && a_node->m_subType == CTNET_IDENTIFIER); + + // if local, get local regardless + // if member, get this + // if global, get global + // get global + + if((a_node->m_flags & gmCodeTreeNode::CTN_MEMBER) > 0) + { + return a_byteCode->EmitPtr(BC_GETTHIS, m_hooks->GetSymbolId(a_node->m_data.m_string)); + } + + gmCodeTreeVariableType type; + int offset = m_currentFunction->GetVariableOffset(a_node->m_data.m_string, type); + + if(offset >= 0 && type == CTVT_LOCAL) + { + return a_byteCode->Emit(BC_GETLOCAL, (gmuint32) offset); + } + else if(offset != -2) + { + if(type == CTVT_MEMBER) + { + return a_byteCode->EmitPtr(BC_GETTHIS, m_hooks->GetSymbolId(a_node->m_data.m_string)); + } + else if(type == CTVT_GLOBAL) + { + return a_byteCode->EmitPtr(BC_GETGLOBAL, m_hooks->GetSymbolId(a_node->m_data.m_string)); + } + if(m_log) m_log->LogEntry("internal error"); + return false; + } + + return a_byteCode->EmitPtr(BC_GETGLOBAL, m_hooks->GetSymbolId(a_node->m_data.m_string)); +} + + + +bool gmCodeGenPrivate::GenExprCall(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_EXPRESSION && a_node->m_subType == CTNET_CALL); + + // mark the stack. + int stackLevel = a_byteCode->GetTos(); + + // if callee is a dot function, push left side of dot as 'this' + const gmCodeTreeNode * callee = a_node->m_children[0]; + + if(callee->m_type == CTNT_EXPRESSION && callee->m_subType == CTNET_OPERATION && callee->m_subTypeType == CTNOT_DOT) + { + if(!Generate(callee->m_children[0], a_byteCode)) return false; + a_byteCode->Emit(BC_DUP); + a_byteCode->EmitPtr(BC_GETDOT, m_hooks->GetSymbolId(callee->m_children[1]->m_data.m_string)); + } + else + { + if(a_node->m_children[2]) + { + if(!Generate(a_node->m_children[2], a_byteCode)) return false; + } + else + { +#if GM_COMPILE_PASS_THIS_ALWAYS + + a_byteCode->Emit(BC_PUSHTHIS); + +#else // !GM_COMPILE_PASS_THIS_ALWAYS + + // if the lvalue is a member, pass 'this', otherwise pass 'null' + bool pushed = false; + if(callee->m_type == CTNT_EXPRESSION && callee->m_subType == CTNET_IDENTIFIER) + { + gmCodeTreeVariableType vtype; + int offset = m_currentFunction->GetVariableOffset(callee->m_data.m_string, vtype); + if(((callee->m_flags & gmCodeTreeNode::CTN_MEMBER) > 0) || (offset == -1 && vtype == CTVT_MEMBER)) + { + a_byteCode->Emit(BC_PUSHTHIS); + pushed = true; + } + } + if(!pushed) + { + a_byteCode->Emit(BC_PUSHNULL); + } + +#endif // !GM_COMPILE_PASS_THIS_ALWAYS + } + if(!Generate(callee, a_byteCode)) return false; + } + + // push parameters, count the number of parameters + gmuint32 numParams = 0; + + const gmCodeTreeNode * params = a_node->m_children[1]; + + while(params) + { + ++numParams; + if(!Generate(params, a_byteCode, false)) return false; + params = params->m_sibling; + } + + // call + a_byteCode->Emit(BC_CALL, (gmuint32) numParams); + + // restore the stack level. + a_byteCode->SetTos(stackLevel + 1); + + return true; +} + + + +bool gmCodeGenPrivate::GenExprThis(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode) +{ + GM_ASSERT(a_node->m_type == CTNT_EXPRESSION && a_node->m_subType == CTNET_THIS); + return a_byteCode->Emit(BC_PUSHTHIS); +} + + + +gmCodeGenPrivate::FunctionState::FunctionState() +{ + m_debugName = NULL; + m_numLocals = 0; + m_currentLine = 1; + m_byteCode.Reset(this); +} + + + +void gmCodeGenPrivate::FunctionState::Reset() +{ + m_debugName = NULL; + m_variables.Reset(); + m_numLocals = 0; + m_currentLine = 1; + m_byteCode.Reset(this); + m_lineInfo.Reset(); +} + + + +int gmCodeGenPrivate::FunctionState::GetVariableOffset(const char * a_symbol, gmCodeTreeVariableType &a_type) +{ + for(gmuint v = 0; v < m_variables.Count(); ++v) + { + Variable &variable = m_variables[v]; + if(strcmp(variable.m_symbol, a_symbol) == 0) + { + a_type = variable.m_type; + if(variable.m_type == CTVT_LOCAL) + { + return variable.m_offset; + } + return -1; + } + } + + a_type = CTVT_GLOBAL; + return -2; +} + + + +int gmCodeGenPrivate::FunctionState::SetVariableType(const char * a_symbol, gmCodeTreeVariableType a_type) +{ + for(gmuint v = 0; v < m_variables.Count(); ++v) + { + Variable &variable = m_variables[v]; + if(strcmp(variable.m_symbol, a_symbol) == 0) + { + variable.m_type = a_type; + // if this variable was previously not a local, be is now being declared as local, get a stack offset. + if(a_type == CTVT_LOCAL && variable.m_offset == -1) + { + variable.m_offset = m_numLocals++; + } + return variable.m_offset; + } + } + + Variable &variable = m_variables.InsertLast(); + // if the new variable is a local, get a stack offset for it. + if(a_type == CTVT_LOCAL) + { + variable.m_offset = m_numLocals++; + } + else variable.m_offset = -1; + + variable.m_type = a_type; + variable.m_symbol = a_symbol; + return variable.m_offset; +} + + + +gmCodeGenPrivate::FunctionState * gmCodeGenPrivate::PushFunction() +{ + if(m_currentFunction) + { + if(m_currentFunction != m_functionStack.GetLast()) + { + m_currentFunction = m_functionStack.GetNext(m_currentFunction); + } + else + { + m_currentFunction = new FunctionState(); + m_functionStack.InsertLast(m_currentFunction); + } + } + else + { + if(m_functionStack.IsEmpty()) + { + m_currentFunction = new FunctionState(); + m_functionStack.InsertLast(m_currentFunction); + } + else + { + m_currentFunction = m_functionStack.GetFirst(); + } + } + + m_currentFunction->Reset(); + + m_currentFunction->m_byteCode.SetSwapEndianOnWrite(m_hooks->SwapEndian()); + + // if we are debugging, set up some line number debugging. + if(m_debug) + { + m_currentFunction->m_byteCode.m_emitCallback = gmLineNumberCallback; + } + + return m_currentFunction; +} + + + +gmCodeGenPrivate::FunctionState * gmCodeGenPrivate::PopFunction() +{ + if(m_currentFunction) + { + m_currentFunction->Reset(); + m_currentFunction = m_functionStack.GetPrev(m_currentFunction); + if(!m_functionStack.IsValid(m_currentFunction)) + { + m_currentFunction = NULL; + } + } + + return m_currentFunction; +} + + + +void gmCodeGenPrivate::PushLoop() +{ + LoopInfo * loop = &m_loopStack.InsertLast(); + m_currentLoop = m_loopStack.Count()-1; + loop->m_breaks = -1; + loop->m_continues = -1; +} + + +void gmCodeGenPrivate::PopLoop() +{ + m_loopStack.RemoveLast(); + if(m_loopStack.Count()) + { + m_currentLoop = m_loopStack.Count() - 1; + } + else + { + m_currentLoop = -1; + } +} + + +void gmCodeGenPrivate::ApplyPatches(int a_patches, gmByteCodeGen * a_byteCode, gmuint32 a_value) +{ + unsigned int pos = a_byteCode->Tell(); + while(a_patches >= 0) + { + Patch * curPatch = &m_patches[a_patches]; + + a_byteCode->Seek(curPatch->m_address); + *a_byteCode << a_value; + a_patches = curPatch->m_next; + } + a_byteCode->Seek(pos); +} diff --git a/vscript/languages/gm/src/gm/gmCodeGen.h b/vscript/languages/gm/src/gm/gmCodeGen.h new file mode 100644 index 00000000..6f3bc1bf --- /dev/null +++ b/vscript/languages/gm/src/gm/gmCodeGen.h @@ -0,0 +1,49 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMCODEGEN_H_ +#define _GMCODEGEN_H_ + +#include "gmConfig.h" +#include "gmLog.h" +#include "gmCodeGenHooks.h" + +// fwd decl +struct gmCodeTreeNode; + +/// \class gmCodeGen +/// \brief gmCodeGen will create byte code for a given code tree. after parsing script into a code tree using gmCodeTree, +/// turn it into byte code using this class. After the code gen has been run, the gmCodeTree may be unlocked. +/// Note that the code tree is parsed into a set of functions authored using a gmCodeGenHooks implementation. +class gmCodeGen +{ +public: + + /// \brief Get() will return the singleton code generator. + static gmCodeGen& Get(); + + /// \brief FreeMemory() will free all memory allocated by the code tree. must be unlocked + virtual void FreeMemory() = 0; + + /// \brief Lock() will create the byte code for the given gode tree. + /// \param a_codeTree is the code tree. + /// \param a_hooks is the byte code authoring object. + /// \param a_debug is true if debug info is required. + /// \param a_log is the compile log. + /// \return the number of errors encounted + virtual int Lock(const gmCodeTreeNode * a_codeTree, gmCodeGenHooks * a_hooks, bool a_debug, gmLog * a_log) = 0; + + /// \brief Unlock() will reset the code generator. + virtual int Unlock() = 0; +}; + + +#endif // _GMCODEGEN_H_ diff --git a/vscript/languages/gm/src/gm/gmCodeGenHooks.cpp b/vscript/languages/gm/src/gm/gmCodeGenHooks.cpp new file mode 100644 index 00000000..3ed698f4 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmCodeGenHooks.cpp @@ -0,0 +1,17 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmCodeGenHooks.h" + +// Must be last header +#include "memdbgon.h" + diff --git a/vscript/languages/gm/src/gm/gmCodeGenHooks.h b/vscript/languages/gm/src/gm/gmCodeGenHooks.h new file mode 100644 index 00000000..f472ae9d --- /dev/null +++ b/vscript/languages/gm/src/gm/gmCodeGenHooks.h @@ -0,0 +1,101 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMCODEGENHOOKS_H_ +#define _GMCODEGENHOOKS_H_ + +#include "gmConfig.h" + +/// \struct gmLineInfo +/// \brief gmLineInfo describes the debug info required for line number debugging +struct gmLineInfo +{ + int m_address; //!< byte code address + int m_lineNumber; //!< code line number +}; + +/// \struct gmFunctionInfo +/// \brief gmFunctionInfo +struct gmFunctionInfo +{ + gmptr m_id; //!< unique id of the function (as used in BC_PUSHFN) + bool m_root; //!< is this function the root function '__main' + + const void * m_byteCode; //!< byte code + int m_byteCodeLength; //!< byte code length in bytes + int m_numParams; //!< parameter count + int m_numLocals; //!< local variable count (includes registers) + int m_maxStackSize; //!< required temporary storage + + const char * m_debugName; //!< name of variable function was assigned to... may be NULL + const char ** m_symbols; //!< param and local variable names, sizeof m_numParams + m_numLocals; (indexed by stack offset) + int m_lineInfoCount; //!< number of entries in the line info array + const gmLineInfo * m_lineInfo; //!< line - instruction address mapping for debugging purposes. +}; + +/// \class gmCodeGenHooks +/// \brief gmCodeGenHooks is an interface that is fed to the compiler. basically the code gen hooks class allows you +/// to compile script directly into the runtime vm, or into a libary. +class gmCodeGenHooks +{ +public: + gmCodeGenHooks() {} + virtual ~gmCodeGenHooks() {} + + /// \brief Begin() will be called by gmCodeGen at the start of compilation. + /// \param a_debug is true if this is a debug build. + virtual bool Begin(bool a_debug) = 0; + + /// \brief AddFunction() is called each time the byte code for a function has been created. The memory passed in + /// the info structure is not valid after AddFunction returns. + /// \return true on success + virtual bool AddFunction(gmFunctionInfo &a_functionInfo) = 0; + + /// \brief End() is called by gmCodeGen at the end of a compilation. + /// \param a_errors is the number of compilation errors. + virtual bool End(int a_errors) = 0; + + /// \brief GetFunctionId() is called for the creation of unique function ids. + /// \return a unique id. + virtual gmptr GetFunctionId() = 0; + + /// \brief GetSymbolId() is called by the compiler to get a unique symbol id. this sybol id is a machine size int + /// id written into the byte code. + /// \return a unique id for each unique a_symbol. + virtual gmptr GetSymbolId(const char * a_symbol) = 0; + + /// \brief GetStringId() is called by the compiler to get a constant string id. the returned value is written into + /// the byte code for string lookups. + /// \return a unique id for each unique string. + virtual gmptr GetStringId(const char * a_string) = 0; + + /// \brief SwapEndian() returns true if the byte code is being compiled for a machine of differing endian + virtual bool SwapEndian() const { return false; } +}; + + +/// \class gmCodeGenHooksNull +/// \brief used for syntax checking etc. +class gmCodeGenHooksNull : public gmCodeGenHooks +{ +public: + gmCodeGenHooksNull() {} + virtual ~gmCodeGenHooksNull() {} + + virtual bool Begin(bool a_debug) { return true; } + virtual bool AddFunction(gmFunctionInfo &a_functionInfo) { return true; } + virtual bool End(int a_errors) { return true; } + virtual gmptr GetFunctionId() { return 0; } + virtual gmptr GetSymbolId(const char * a_symbol) { return 0; } + virtual gmptr GetStringId(const char * a_string) { return 0; } +}; + +#endif // _GMCODEGENHOOKS_H_ diff --git a/vscript/languages/gm/src/gm/gmCodeTree.cpp b/vscript/languages/gm/src/gm/gmCodeTree.cpp new file mode 100644 index 00000000..408c29f9 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmCodeTree.cpp @@ -0,0 +1,555 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmCodeTree.h" + +// Must be last header +#include "memdbgon.h" + + +gmCodeTreeNode * g_codeTree = NULL; + + + +gmCodeTree::gmCodeTree() : + m_mem(1, GMCODETREE_CHAINSIZE) +{ + g_codeTree = NULL; + m_locked = false; + m_errors = 0; + m_log = 0; +} + + + +gmCodeTree::~gmCodeTree() +{ + Unlock(); +} + + + +gmCodeTree &gmCodeTree::Get() +{ + static gmCodeTree codeTree; + return codeTree; +} + + + +void gmCodeTree::FreeMemory() +{ + if(m_locked == false) + { + m_mem.ResetAndFreeMemory(); + } +} + + + +int gmCodeTree::Lock(const char * a_script, gmLog * a_log) +{ + if(m_locked == true) return 1; + + m_errors = 0; + m_locked = true; + m_log = a_log; + g_codeTree = NULL; + //gmdebug = 1; + gmlineno = 1; + + // create a scan buffer + YY_BUFFER_STATE buffer = gm_scan_string(a_script); + if(buffer) + { + m_errors = gmparse(); + gm_delete_buffer(buffer); + } + return m_errors; +} + + + +int gmCodeTree::Unlock() +{ + m_mem.Reset(); + g_codeTree = NULL; + m_locked = false; + m_errors = 0; + m_log = NULL; + return 0; +} + + + +const gmCodeTreeNode * gmCodeTree::GetCodeTree() const +{ + return g_codeTree; +} + + + +void * gmCodeTree::Alloc(int a_size, int a_align) +{ + return m_mem.AllocBytes(a_size, a_align); +} + + + +#if GM_COMPILE_DEBUG + +const char * gmGetOperatorTypeName(gmCodeTreeNodeOperationType a_type) +{ + switch(a_type) + { + case CTNOT_INVALID : return "CTNOT_INVALID"; + case CTNOT_DOT : return "CTNOT_DOT"; + case CTNOT_UNARY_PLUS : return "CTNOT_UNARY_PLUS"; + case CTNOT_UNARY_MINUS : return "CTNOT_UNARY_MINUS"; + case CTNOT_UNARY_NOT : return "CTNOT_UNARY_NOT"; + case CTNOT_UNARY_COMPLEMENT : return "CTNOT_UNARY_COMPLEMENT"; + case CTNOT_ARRAY_INDEX : return "CTNOT_ARRAY_INDEX"; + case CTNOT_TIMES : return "CTNOT_TIMES"; + case CTNOT_DIVIDE : return "CTNOT_DIVIDE"; + case CTNOT_REM : return "CTNOT_REM"; + case CTNOT_ADD : return "CTNOT_ADD"; + case CTNOT_MINUS : return "CTNOT_MINUS"; + case CTNOT_LT : return "CTNOT_LT"; + case CTNOT_GT : return "CTNOT_GT"; + case CTNOT_LTE : return "CTNOT_LTE"; + case CTNOT_GTE : return "CTNOT_GTE"; + case CTNOT_EQ : return "CTNOT_EQ"; + case CTNOT_NEQ : return "CTNOT_NEQ"; + case CTNOT_AND : return "CTNOT_AND"; + case CTNOT_OR : return "CTNOT_OR"; + case CTNOT_BIT_OR : return "CTNOT_BIT_OR"; + case CTNOT_BIT_XOR : return "CTNOT_BIT_XOR"; + case CTNOT_BIT_AND : return "CTNOT_BIT_AND"; + case CTNOT_SHIFT_LEFT : return "CTNOT_SHIFT_LEFT"; + case CTNOT_SHIFT_RIGHT : return "CTNOT_SHIFT_RIGHT"; + case CTNOT_ASSIGN : return "CTNOT_ASSIGN"; + case CTNOT_ASSIGN_FIELD : return "CTNOT_ASSIGN_FIELD"; + default : break; + } + return "UNKNOWN OPERATOR TYPE"; +}; + + + +static void PrintRecursive(const gmCodeTreeNode * a_node, FILE * a_fp, bool a_firstCall) +{ + if(a_node) + { + static int indent; + int i; + + if(a_firstCall) + { + indent = 0; + } + + indent += 2; + + while(a_node != NULL) + { + for(i = 0; i < indent; ++i) + fprintf(a_fp, " "); + + if(a_node->m_type == CTNT_DECLARATION) + { + // + // DECLARATIONS + // + switch(a_node->m_subType) + { + case CTNDT_PARAMETER : fprintf(a_fp, "CTNDT_PARAMETER:%04d"GM_NL, a_node->m_lineNumber); break; + case CTNDT_VARIABLE : fprintf(a_fp, "CTNDT_VARIABLE:%04d, type %d"GM_NL, a_node->m_lineNumber, a_node->m_subTypeType); break; + default : fprintf(a_fp, "UNKNOWN DECLARATION:"GM_NL); break; + } + } + else if(a_node->m_type == CTNT_STATEMENT) + { + // + // STATEMENTS + // + switch(a_node->m_subType) + { + case CTNST_RETURN : fprintf(a_fp, "CTNST_RETURN:%04d"GM_NL, a_node->m_lineNumber); break; + case CTNST_BREAK : fprintf(a_fp, "CTNST_BREAK:%04d"GM_NL, a_node->m_lineNumber); break; + case CTNST_CONTINUE : fprintf(a_fp, "CTNST_CONTINUE:%04d"GM_NL, a_node->m_lineNumber); break; + case CTNST_FOR : fprintf(a_fp, "CTNST_FOR:%04d"GM_NL, a_node->m_lineNumber); break; + case CTNST_FOREACH : fprintf(a_fp, "CTNST_FOREACH:%04d"GM_NL, a_node->m_lineNumber); break; + case CTNST_WHILE : fprintf(a_fp, "CTNST_WHILE:%04d"GM_NL, a_node->m_lineNumber); break; + case CTNST_DOWHILE : fprintf(a_fp, "CTNST_DOWHILE:%04d"GM_NL, a_node->m_lineNumber); break; + case CTNST_IF : fprintf(a_fp, "CTNST_IF:%04d"GM_NL, a_node->m_lineNumber); break; + case CTNST_COMPOUND : fprintf(a_fp, "CTNST_COMPOUND:%04d"GM_NL, a_node->m_lineNumber); break; + default : fprintf(a_fp, "UNKNOWN STATEMENT:"GM_NL); break; + } + } + else if(a_node->m_type == CTNT_EXPRESSION) + { + // + // EXPRESSIONS + // + switch(a_node->m_subType) + { + case CTNET_OPERATION : + { + if(a_node->m_subTypeType < CTNOT_MAX) + { + fprintf(a_fp, "CTNET_OPERATION:%04d : %s"GM_NL, a_node->m_lineNumber, gmGetOperatorTypeName((gmCodeTreeNodeOperationType) a_node->m_subTypeType)); + } + else + { + fprintf(a_fp, "UNKNOWN CTNET_OPERATION"GM_NL); + } + break; + } + + case CTNET_CONSTANT : + { + switch(a_node->m_subTypeType) + { + case CTNCT_INT : fprintf(a_fp, "CTNCT_INT:%04d : %d"GM_NL, a_node->m_lineNumber, a_node->m_data.m_iValue); break; + case CTNCT_FLOAT : fprintf(a_fp, "CTNCT_FLOAT:%04d : %f"GM_NL, a_node->m_lineNumber, a_node->m_data.m_fValue); break; + case CTNCT_STRING : fprintf(a_fp, "CTNCT_STRING:%04d : %s"GM_NL, a_node->m_lineNumber, a_node->m_data.m_string); break; + case CTNCT_NULL : fprintf(a_fp, "CTNCT_NULL:%04d"GM_NL, a_node->m_lineNumber); break; + default: fprintf(a_fp, "UNKNOWN CTNET_CONSTANT"GM_NL); + } + break; + } + + case CTNET_IDENTIFIER : fprintf(a_fp, "CTNET_IDENTIFIER:%04d : %s"GM_NL, a_node->m_lineNumber, a_node->m_data.m_string); break; + case CTNET_THIS : fprintf(a_fp, "CTNET_THIS:%04d"GM_NL, a_node->m_lineNumber); break; + case CTNET_CALL : fprintf(a_fp, "CTNET_CALL:%04d"GM_NL, a_node->m_lineNumber); break; + case CTNET_FUNCTION : fprintf(a_fp, "CTNET_FUNCTION:%04d"GM_NL, a_node->m_lineNumber); break; + case CTNET_TABLE : fprintf(a_fp, "CTNET_TABLE:%04d"GM_NL, a_node->m_lineNumber); break; + default : fprintf(a_fp, "UNKNOWN EXPRESSION:"GM_NL); break; + } + } + else + { + fprintf(a_fp, "UNKNOWN NODE TYPE"GM_NL); + } + + // print the child nodes + for(i = 0; i < GMCODETREE_NUMCHILDREN; ++i) + { + if(a_node->m_children[i]) + { + PrintRecursive(a_node->m_children[i], a_fp, false); + } + } + a_node = a_node->m_sibling; + + } // while(a_node != NULL) + + indent -= 2; + } +} + + +void gmCodeTree::Print(FILE * a_fp) +{ + if(m_locked) + { + PrintRecursive(g_codeTree, a_fp, true); + } +} + + +#endif // GM_COMPILE_DEBUG + + + +gmCodeTreeNode * gmCodeTreeNode::Create(gmCodeTreeNodeType a_type, int a_subType, int a_lineNumber, int a_subTypeType) +{ + gmCodeTreeNode * node = (gmCodeTreeNode *) gmCodeTree::Get().Alloc(sizeof(gmCodeTreeNode), GM_DEFAULT_ALLOC_ALIGNMENT); + GM_ASSERT(node != NULL); + memset(node, 0, sizeof(gmCodeTreeNode)); + node->m_type = a_type; + node->m_subType = a_subType; + node->m_lineNumber = a_lineNumber; + node->m_subTypeType = a_subTypeType; + node->m_flags = 0; + return node; +} + + + +void gmCodeTreeNode::SetChild(int a_index, gmCodeTreeNode * a_node) +{ + GM_ASSERT(a_index >= 0 && a_index < GMCODETREE_NUMCHILDREN); + + m_children[a_index] = a_node; + if(a_node != NULL) + { + a_node->m_parent = this; + } +} + + +static bool gmFold(float &a_r, float a_a, int a_op) +{ + switch(a_op) + { + case CTNOT_UNARY_PLUS : a_r = a_a; break; + case CTNOT_UNARY_MINUS : a_r = -a_a; break; + default: return false; + } + return true; +} + + +static bool gmFold(int &a_r, int a_a, int a_op) +{ + switch(a_op) + { + case CTNOT_UNARY_PLUS : a_r = a_a; break; + case CTNOT_UNARY_MINUS : a_r = -a_a; break; + case CTNOT_UNARY_NOT : a_r = !a_a; break; + case CTNOT_UNARY_COMPLEMENT : a_r = ~a_a; break; + default: return false; + } + return true; +} + + +#include +static bool gmFold(float &a_r, float a_a, float a_b, int a_op) +{ + switch(a_op) + { + case CTNOT_TIMES : a_r = a_a * a_b; break; + case CTNOT_DIVIDE : if(a_b == 0) return false; a_r = a_a / a_b; break; + case CTNOT_REM : a_r = fmodf(a_a, a_b); break; + case CTNOT_ADD : a_r = a_a + a_b; break; + case CTNOT_MINUS : a_r = a_a - a_b; break; + default: return false; + } + return true; +} + + +static bool gmFold(int &a_r, int a_a, int a_b, int a_op) +{ + switch(a_op) + { + case CTNOT_TIMES : a_r = a_a * a_b; break; + case CTNOT_DIVIDE : if(a_b == 0) return false; a_r = a_a / a_b; break; + case CTNOT_REM : a_r = a_a % a_b; break; + case CTNOT_ADD : a_r = a_a + a_b; break; + case CTNOT_MINUS : a_r = a_a - a_b; break; + case CTNOT_BIT_OR : a_r = a_a | a_b; break; + case CTNOT_BIT_XOR : a_r = a_a ^ a_b; break; + case CTNOT_BIT_AND : a_r = a_a & a_b; break; + case CTNOT_SHIFT_LEFT : a_r = a_a << a_b; break; + case CTNOT_SHIFT_RIGHT : a_r = a_a >> a_b; break; + default: return false; + } + return true; +} + + +bool gmCodeTreeNode::ConstantFold() +{ + if(m_type == CTNT_EXPRESSION && m_subType == CTNET_OPERATION) + { + bool possibleUnaryFold = false; + bool possibleFold = false; + bool intOnly = false; + + switch(m_subTypeType) + { + case CTNOT_UNARY_PLUS : + case CTNOT_UNARY_MINUS : + possibleUnaryFold = true; + break; + case CTNOT_UNARY_NOT : + case CTNOT_UNARY_COMPLEMENT : + possibleUnaryFold = true; + intOnly = true; + break; + case CTNOT_TIMES : + case CTNOT_DIVIDE : + case CTNOT_REM : + case CTNOT_ADD : + case CTNOT_MINUS : + possibleFold = true; + break; + case CTNOT_BIT_OR : + case CTNOT_BIT_XOR : + case CTNOT_BIT_AND : + case CTNOT_SHIFT_LEFT : + case CTNOT_SHIFT_RIGHT : + possibleFold = true; + intOnly = true; + break; + default: + break; + } + + if(possibleUnaryFold) + { + gmCodeTreeNode * l = m_children[0]; + if(l && l->m_type == CTNT_EXPRESSION && l->m_subType == CTNET_CONSTANT) + { + if(l->m_subTypeType == CTNCT_INT || (l->m_subTypeType == CTNCT_FLOAT && !intOnly)) + { + // we can fold.... + m_children[0] = NULL; + m_subType = CTNET_CONSTANT; + + if(l->m_subTypeType == CTNCT_INT) + { + gmFold(m_data.m_iValue, l->m_data.m_iValue, m_subTypeType); + m_subTypeType = CTNCT_INT; + } + else if(l->m_subTypeType == CTNCT_FLOAT) + { + gmFold(m_data.m_fValue, l->m_data.m_fValue, m_subTypeType); + m_subTypeType = CTNCT_FLOAT; + } + return true; + } + } + } + else if(possibleFold) + { + gmCodeTreeNode * l = m_children[0], * r = m_children[1]; + if((l && l->m_type == CTNT_EXPRESSION && l->m_subType == CTNET_CONSTANT) && + (r && r->m_type == CTNT_EXPRESSION && r->m_subType == CTNET_CONSTANT)) + { + if((l->m_subTypeType == CTNCT_INT || (l->m_subTypeType == CTNCT_FLOAT && !intOnly)) && + (r->m_subTypeType == CTNCT_INT || (r->m_subTypeType == CTNCT_FLOAT && !intOnly))) + { + // we can fold.... + m_children[0] = NULL; m_children[1] = NULL; + m_subType = CTNET_CONSTANT; + if(l->m_subTypeType == CTNCT_INT && r->m_subTypeType == CTNCT_INT) + { + gmFold(m_data.m_iValue, l->m_data.m_iValue, r->m_data.m_iValue, m_subTypeType); + m_subTypeType = CTNCT_INT; + } + else if(l->m_subTypeType == CTNCT_FLOAT && r->m_subTypeType == CTNCT_FLOAT) + { + gmFold(m_data.m_fValue, l->m_data.m_fValue, r->m_data.m_fValue, m_subTypeType); + m_subTypeType = CTNCT_FLOAT; + } + else if(l->m_subTypeType == CTNCT_INT && r->m_subTypeType == CTNCT_FLOAT) + { + gmFold(m_data.m_fValue, (float) l->m_data.m_iValue, r->m_data.m_fValue, m_subTypeType); + m_subTypeType = CTNCT_FLOAT; + } + else if(l->m_subTypeType == CTNCT_FLOAT && r->m_subTypeType == CTNCT_INT) + { + gmFold(m_data.m_fValue, l->m_data.m_fValue, (float) r->m_data.m_iValue, m_subTypeType); + m_subTypeType = CTNCT_FLOAT; + } + return true; + } + } + } + } + return false; +} + + +void gmProcessSingleQuoteString(char * a_string) +{ + char * c = a_string; + char * r = a_string; + + while(*c) + { + if(c[0] == '`' && c[1] == '`' && c[2]) + { + *(r++) = *c; + c += 2; + continue; + } + else if(c[0] == '`') + { + ++c; + continue; + } + + *(r++) = *(c++); + } + *r = '\0'; +} + + + +void gmProcessDoubleQuoteString(char * a_string) +{ + char * c = a_string; + char * r = a_string; + + while(*c) + { + if(c[0] == '\"') + { + ++c; + continue; + } + else if(c[0] == '\\') + { + switch(c[1]) + { + case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : + case '6' : case '7' : case '8' : case '9' : + { + char buffer[4]; int i = 0; + while(i < 3 && isdigit(c[i+1])) + { + buffer[i] = c[i+1]; + ++i; + } + buffer[i] = '\0'; + *r = (char) (atoi(buffer) & 0xff); + c += (i - 1); + break; + } + case 'a' : *r = '\a'; break; + case 'b' : *r = '\b'; break; + case 'f' : *r = '\f'; break; + case 'n' : *r = '\n'; break; + case 'r' : *r = '\r'; break; + case 't' : *r = '\t'; break; + case 'v' : *r = '\v'; break; + case '\'' : *r = '\''; break; + case '\"' : *r = '\"'; break; + case '\\' : *r = '\\'; break; + default: *r = c[1]; + } + ++r; + c += 2; + continue; + } + *(r++) = *(c++); + } + *r = '\0'; +} + + + +int gmerror(char * a_message) +{ + gmCodeTree & ct = gmCodeTree::Get(); + if(ct.GetLog()) + { + ct.GetLog()->LogEntry("error (%d) %s", gmlineno, a_message); + } + return 0; +} + diff --git a/vscript/languages/gm/src/gm/gmCodeTree.h b/vscript/languages/gm/src/gm/gmCodeTree.h new file mode 100644 index 00000000..3c853543 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmCodeTree.h @@ -0,0 +1,254 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMCODETREE_H_ +#define _GMCODETREE_H_ + +#include "gmConfig.h" +#include "gmMem.h" +#include "gmMemChain.h" +#include "gmLog.h" +#include "gmScanner.h" + +#define GMCODETREE_NUMCHILDREN 4 + +// fwd decl +struct gmCodeTreeNode; + +/// \class gmCodeTree +/// \brief gmCodeTree is a singleton class for creating code trees. +class gmCodeTree +{ +protected: + gmCodeTree(); + +public: + ~gmCodeTree(); + + /// \brief Get() will return the singlton parser. + static gmCodeTree &Get(); + + /// \brief FreeMemory() will free all memory allocated by the code tree. must be unlocked + void FreeMemory(); + + /// \brief Lock() will create a code tree for the passed script. Note that the code tree is valid until + /// Unlock() is called. + /// \param a_script is a null terminated script string. + /// \return the number of errors encounted when parsing. + /// \sa Unlock() + int Lock(const char * a_script, gmLog * a_log = NULL); + + /// \brief Unlock() will unlock the singleton code tree such that it may be used again. + /// \return 0 on success + /// \sa Lock() + int Unlock(); + + /// \brief GetCodeTree() will return the code tree resulting from a Lock() operation. + /// \return NULL on failure + /// \sa Lock() + const gmCodeTreeNode * GetCodeTree() const; + + inline gmLog * GetLog() const { return m_log; } + + /// \brief Alloc() will return memory from the code tree memory pool. This method is used by the + /// parser when building the code tree. + /// \return NULL on failure + void * Alloc(int a_size, int a_align = GM_DEFAULT_ALLOC_ALIGNMENT); + +#if GM_COMPILE_DEBUG + + /// \brief Print() will write the tree to the given file. this is purely for debugging. + /// \param a_fp is an open file for writing. + void Print(FILE * a_fp); + +#endif // GM_COMPILE_DEBUG + +private: + + bool m_locked; + int m_errors; + gmLog * m_log; + gmMemChain m_mem; +}; + + + +/// \enum gmCodeTreeNodeType +/// \brief gmCodeTreeNodeType indicates the type of a gmCodeTreeNode. +enum gmCodeTreeNodeType +{ + CTNT_INVALID = 0, + CTNT_DECLARATION, + CTNT_STATEMENT, + CTNT_EXPRESSION, +}; + + + +/// \enum gmCodeTreeNodeDeclarationType +/// \brief if a tree node is of type CTNT_DECLARATION, gmCodeTreeNodeDeclarationType are the sub types +enum gmCodeTreeNodeDeclarationType +{ + CTNDT_PARAMETER = 0, + CTNDT_VARIABLE, +}; + + + +/// \enum gmCodeTreeVariableType +/// \brief if a treenode is CTNT_DECLARATION, CTNDT_VARIABLE, this is the type of variable decl. +enum gmCodeTreeVariableType +{ + CTVT_LOCAL = 0, + CTVT_GLOBAL, + CTVT_MEMBER, +}; + + + +/// \enum gmCodeTreeNodeStatementType +/// \brief if a tree node is of type CTNT_STATEMENT, gmCodeTreeNodeStatementType are the sub types +enum gmCodeTreeNodeStatementType +{ + CTNST_INVALID = 0, + CTNST_RETURN, + CTNST_BREAK, + CTNST_CONTINUE, + CTNST_FOR, + CTNST_FOREACH, + CTNST_WHILE, + CTNST_DOWHILE, + CTNST_IF, + CTNST_COMPOUND, +}; + + + +/// \enum gmCodeTreeNodeExpressionType +/// \brief +enum gmCodeTreeNodeExpressionType +{ + CTNET_INVALID = 0, + CTNET_OPERATION, + CTNET_CONSTANT, + CTNET_IDENTIFIER, + CTNET_THIS, + CTNET_CALL, + CTNET_FUNCTION, + CTNET_TABLE, +}; + + + +/// \enum gmCodeTreeNodeOperationType +/// \brief +enum gmCodeTreeNodeOperationType +{ + CTNOT_INVALID = 0, + CTNOT_DOT, + CTNOT_UNARY_PLUS, + CTNOT_UNARY_MINUS, + CTNOT_UNARY_COMPLEMENT, + CTNOT_UNARY_NOT, + CTNOT_ARRAY_INDEX, + CTNOT_TIMES, + CTNOT_DIVIDE, + CTNOT_REM, + CTNOT_ADD, + CTNOT_MINUS, + CTNOT_LT, + CTNOT_GT, + CTNOT_LTE, + CTNOT_GTE, + CTNOT_EQ, + CTNOT_NEQ, + CTNOT_AND, + CTNOT_OR, + CTNOT_BIT_OR, + CTNOT_BIT_XOR, + CTNOT_BIT_AND, + CTNOT_SHIFT_LEFT, + CTNOT_SHIFT_RIGHT, + CTNOT_ASSIGN, + CTNOT_ASSIGN_FIELD, + CTNOT_MAX, +}; + + + +/// \enum gmCodeTreeNodeConstantType +enum gmCodeTreeNodeConstantType +{ + CTNCT_INVALID = 0, + CTNCT_INT, + CTNCT_FLOAT, + CTNCT_STRING, + CTNCT_NULL, +}; + + + +/// \union gmCodeTreeNodeUnion +/// \brief +union gmCodeTreeNodeData +{ + char * m_string; + int m_iValue; + float m_fValue; +}; + + + +/// \struct gmCodeTreeNode +/// \brief gmCodeTreeNode is the tree node structure used to represent the game monkey script syntax tree. +struct gmCodeTreeNode +{ + // flags + enum + { + CTN_POP = (1 << 0), + CTN_MEMBER = (1 << 1), + }; + + /// \brief Create() will create a tree node. the singleton gmCodeTree must be locked. + /// \return a tree node + static gmCodeTreeNode * Create(gmCodeTreeNodeType a_type, int a_subType, int a_lineNumber, int a_subTypeType = 0); + + /// \brief SetChild() will set the child at the given index. + /// \param a_node is the child node, whose parent pointer will be assigned to this. + void SetChild(int a_index, gmCodeTreeNode * a_node); + + /// \brief ConstantFold() will pull child nodes into this node, and make this node a constant if possible + bool ConstantFold(); + + gmCodeTreeNodeType m_type; + int m_subType; + int m_subTypeType; + int m_flags; + + gmCodeTreeNode * m_children[GMCODETREE_NUMCHILDREN]; + gmCodeTreeNode * m_sibling; + gmCodeTreeNode * m_parent; + + int m_lineNumber; + gmCodeTreeNodeData m_data; +}; + +// +// misc lexing and parsing functions. +// + +void gmProcessSingleQuoteString(char * a_string); +void gmProcessDoubleQuoteString(char * a_string); +int gmerror(char * a_message); +int gmparse(void); + +#endif // _GMCODETREE_H_ diff --git a/vscript/languages/gm/src/gm/gmConfig.h b/vscript/languages/gm/src/gm/gmConfig.h new file mode 100644 index 00000000..18c351f4 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmConfig.h @@ -0,0 +1,106 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMCONFIG_H_ +#define _GMCONFIG_H_ + +// Include the platform config. +// All platform configuration exists in gmconfig_p.h +#include "gmConfig_p.h" + +#include // atoi, strtoul (binds: rand, srand) +#include // fprintf, sprintf, _snprintf, _vnsprintf +#include // stricmp, strcmp, strcpy, strlen, strcat, memset, memcpy (binds: strlwr, wtrupr, strspn, strcspn, strchr, strstr) +#include // va_start, va_end +#include // isdigit +#include // floorf, fmodf + + +/// \enum gmEndian Endian byte order +enum gmEndian +{ + GM_ENDIAN_BIG = 0, //!< MOTOROLA (MAC), NINTENDO GC + GM_ENDIAN_LITTLE = 1 //!< x86, XBOX, PS2 +}; + +// +// Game Monkey Configuration +// + +// COMPILE + +#define GM_COMPILE_DEBUG 1 // define for compile debugging code, ie, printing code trees, byte code etc. + +// COMPILE LOG + +#define GMLOG_CHAINSIZE 2048 // memory chunk resolution for the compile log + +// COMPILE PARSER + +#define GMCODETREE_CHAINSIZE 4096 // memory chunk resolution for compiler code tree nodes. + +// COMPILER CODE GENERATOR + +#define GM_COMPILE_PASS_THIS_ALWAYS 0 // set to 1 to pass current this to each function call + +// RUNTIME THREAD + +#define GMTHREAD_INITIALBYTESIZE 512 // initial stack byte size for a single thread +#define GMTHREAD_MAXBYTESIZE 128000 //1024 // max stack byte size for a single thread (Sample scripts like it big) + +// MACHINE + +#define GMMACHINE_REMOVECOMPILER 0 // Remove compiler code, will only be able to run precompiled libs +#define GMMACHINE_GMCHECKDIVBYZERO 0 // Let GM operator check for divide by zero and possibly cause GM run time exception (rather than OS exception) +#define GMMACHINE_NULL_VAR_CTOR 0 // Nullify gmVariable in constructor. Not recommended for real-time / time critical applications. +#define GMMACHINE_USERTYPEGROWBY 16 // allocate user types in chunks of this size +#define GMMACHINE_OBJECTCHUNKSIZE 32 // default object chunk allocation size +#define GMMACHINE_TBLCHUNKSIZE 32 // table object chunk allocation size +#define GMMACHINE_STRINGCHUNKSIZE 128 // default object chunk allocation size +#define GMMACHINE_STACKFCHUNKSIZE 128 // stack frame chunk size +#define GMMACHINE_AUTOMEM true // automatically decide garbage collection limit +#define GMMACHINE_AUTOMEMMULTIPY 2.5f // after gc cycle, set limit = current * GMMACHINE_AUTOMEMMULTIPY (This is for atomic GC) +#define GMMACHINE_AUTOMEMALLOWSHRINK 0 // Allow memory liimits to shrink, otherwise memory will grow when needed only +#define GMMACHINE_INITIALGCHARDLIMIT 128*1024 // default gc hard memory limit. +#define GMMACHINE_INITIALGCSOFTLIMIT (GMMACHINE_INITIALGCHARDLIMIT * 9 / 10) // default gc soft memory limit +#define GMMACHINE_STRINGHASHSIZE 8192 // this will be dynamic... todo +#define GMMACHINE_MAXKILLEDTHREADS 16 // max size of the free thread list (don't make too large, ie, < 32) +#define GMMACHINE_GCEVERYALLOC 0 // define this to check garbage collection every allocate. +#define GMMACHINE_SUPERPARANOIDGC 0 // validate references (only for debugging purposes) +#define GMMACHINE_THREEPASSGC 0 // 1 for safe gc of persisting objects that reference other objects, + // ie, persisting tables. if you only have persisting simple objects, ie + // strings, set to 0 for faster garbage collection. + +// Auto GC Calibration values +#define GMMACHINE_GC_HARD_MEM_INC_FRAC_OF_USED 1.5f // what to set hard limit to above used mem when growing hard limit +#define GMMACHINE_GC_HARD_MEM_DEC_FRAC_OF_USED 1.5f // what to set hard limit to above used mem when shinking hard limit +#define GMMACHINE_GC_SOFT_MEM_DEFAULT_FRAC_OF_HARD (9.0f/10.0f) // what to set soft limit as frac of hard limit by default +#define GMMACHINE_GC_HARD_MEM_SHRINK_THRESH 0.5f // threshold at which hard limit should shrink +#define GMMACHINE_GC_SOFT_MEM_MIN_FRAC 0.25f // minimum soft limit as frac of hard limit to shrink soft limit +#define GMMACHINE_GC_SOFT_MEM_DEC_FRAC 0.1f // amount to shrink soft limit as frac of soft/hard +#define GMMACHINE_GC_MIN_FRAMES_SINCE_RESTART 100 // if gc is restarting within this many frames/calls, it is probably configured bad +#define GM_GC_DEFAULT_WORK_INCREMENT 200 // Desired number of objects to trace per frame +#define GM_GC_DEFAULT_DESTRUCT_INCREMENT 200 // Desired number of old objects to free per frame + +#define GMMACHINE_CPPOWNEDGMOBJHASHSIZE 1024 // default hash table size for objects owned by cpp code, necessary for GC. + +// DEBUGGING + +#define GMDEBUG_SUPPORT 1 // allow use with the gm debugger + + +// GARBAGE COLLECTOR +#define GM_USE_INCGC 1 // use incremental garbage collector + + +#define GM_BOOL_OP 1 // Spport for a bool operator on user types for use in if statements. For full effect, users will want to implement operators [bool, ==, !=, !] + +#endif // _GMCONFIG_H_ diff --git a/vscript/languages/gm/src/gm/gmCrc.cpp b/vscript/languages/gm/src/gm/gmCrc.cpp new file mode 100644 index 00000000..ba9a2acc --- /dev/null +++ b/vscript/languages/gm/src/gm/gmCrc.cpp @@ -0,0 +1,84 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmCrc.h" + +// Must be last header +#include "memdbgon.h" + + +#define _gmUPDC32(A,C) (s_gmCrc32Table[((C) ^ ((gmuint8) A)) & 0xff] ^ ((C) >> 8)) + +// CRC polynomial 0xedb88320 +static gmuint32 s_gmCrc32Table[] = + { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d + }; + + + +gmuint32 gmCrc32String(const char *p_string) +{ + register gmuint32 crc32; + + crc32 = 0xffffffff; + + for (; *p_string; ++p_string) + { + crc32 = _gmUPDC32(*p_string, crc32); + } + + return ~crc32; +} + diff --git a/vscript/languages/gm/src/gm/gmCrc.h b/vscript/languages/gm/src/gm/gmCrc.h new file mode 100644 index 00000000..03066bad --- /dev/null +++ b/vscript/languages/gm/src/gm/gmCrc.h @@ -0,0 +1,19 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMCRC_H_ +#define _GMCRC_H_ + +#include "gmConfig.h" + +gmuint32 gmCrc32String(const char *p_string); + +#endif // _GMCRC_H_ diff --git a/vscript/languages/gm/src/gm/gmDebug.cpp b/vscript/languages/gm/src/gm/gmDebug.cpp new file mode 100644 index 00000000..c34416d3 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmDebug.cpp @@ -0,0 +1,741 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmDebug.h" +#include "gmConfig.h" +#include "gmMachine.h" +#include "gmThread.h" + +// Must be last header +#include "memdbgon.h" + + +#if GMDEBUG_SUPPORT + + +#define ID_mrun GM_MAKE_ID32('m','r','u','n') +#define ID_msin GM_MAKE_ID32('m','s','i','n') +#define ID_msou GM_MAKE_ID32('m','s','o','u') +#define ID_msov GM_MAKE_ID32('m','s','o','v') +#define ID_mgct GM_MAKE_ID32('m','g','c','t') +#define ID_mgsr GM_MAKE_ID32('m','g','s','r') +#define ID_mgsi GM_MAKE_ID32('m','g','s','i') +#define ID_mgti GM_MAKE_ID32('m','g','t','i') +#define ID_mgvi GM_MAKE_ID32('m','g','v','i') +#define ID_msbp GM_MAKE_ID32('m','s','b','p') +#define ID_mbrk GM_MAKE_ID32('m','b','r','k') +#define ID_mend GM_MAKE_ID32('m','e','n','d') + +#define ID_dbrk GM_MAKE_ID32('d','b','r','k') +#define ID_dexc GM_MAKE_ID32('d','e','x','c') +#define ID_drun GM_MAKE_ID32('d','r','u','n') +#define ID_dstp GM_MAKE_ID32('d','s','t','p') +#define ID_dsrc GM_MAKE_ID32('d','s','r','c') +#define ID_dctx GM_MAKE_ID32('d','c','t','x') +#define ID_call GM_MAKE_ID32('c','a','l','l') +#define ID_vari GM_MAKE_ID32('v','a','r','i') +#define ID_done GM_MAKE_ID32('d','o','n','e') +#define ID_dsri GM_MAKE_ID32('d','s','r','i') +#define ID_srci GM_MAKE_ID32('s','r','c','i') +#define ID_done GM_MAKE_ID32('d','o','n','e') +#define ID_dthi GM_MAKE_ID32('d','t','h','i') +#define ID_thri GM_MAKE_ID32('t','h','r','i') +#define ID_done GM_MAKE_ID32('d','o','n','e') +#define ID_derr GM_MAKE_ID32('d','e','r','r') +#define ID_dmsg GM_MAKE_ID32('d','m','s','g') +#define ID_dack GM_MAKE_ID32('d','a','c','k') +#define ID_dend GM_MAKE_ID32('d','e','n','d') + + +// +// functions to handle incomming commands from a debugger +// + +void gmMachineRun(gmDebugSession * a_session, int a_threadId); +void gmMachineStepInto(gmDebugSession * a_session, int a_threadId); +void gmMachineStepOver(gmDebugSession * a_session, int a_threadId); +void gmMachineStepOut(gmDebugSession * a_session, int a_threadId); +void gmMachineGetContext(gmDebugSession * a_session, int a_threadId, int a_callframe); +void gmMachineGetSource(gmDebugSession * a_session, int a_sourceId); +void gmMachineGetSourceInfo(gmDebugSession * a_session); +void gmMachineGetThreadInfo(gmDebugSession * a_session); +void gmMachineGetVariableInfo(gmDebugSession * a_session, int a_variableId); +void gmMachineSetBreakPoint(gmDebugSession * a_session, int a_responseId, int a_sourceId, int a_lineNumber, int a_threadId, int a_enabled); +void gmMachineBreak(gmDebugSession * a_session, int a_threadId); +void gmMachineQuit(gmDebugSession * a_session); + +// +// functions to package outgoing messages to a debugger +// + +void gmDebuggerBreak(gmDebugSession * a_session, int a_threadId, int a_sourceId, int a_lineNumber); +void gmDebuggerRun(gmDebugSession * a_session, int a_threadId); +void gmDebuggerStop(gmDebugSession * a_session, int a_threadId); +void gmDebuggerSource(gmDebugSession * a_session, int a_sourceId, const char * a_sourceName, const char * a_source); +void gmDebuggerException(gmDebugSession * a_session, int a_threadId); + +void gmDebuggerBeginContext(gmDebugSession * a_session, int a_threadId, int a_callFrame); +void gmDebuggerContextCallFrame(gmDebugSession * a_session, int a_callFrame, const char * a_functionName, int a_sourceId, int a_lineNumber, const char * a_thisSymbol, const char * a_thisValue, int a_thisId); +void gmDebuggerContextVariable(gmDebugSession * a_session, const char * a_varSymbol, const char * a_varValue, int a_varId); +void gmDebuggerEndContext(gmDebugSession * a_session); + +void gmDebuggerBeginSourceInfo(gmDebugSession * a_session); +void gmDebuggerSourceInfo(gmDebugSession * a_session, int a_sourceId, const char * a_sourceName); +void gmDebuggerEndSourceInfo(gmDebugSession * a_session); + +void gmDebuggerBeginThreadInfo(gmDebugSession * a_session); +void gmDebuggerThreadInfo(gmDebugSession * a_session, int a_threadId, int a_threadState); +void gmDebuggerEndThreadInfo(gmDebugSession * a_session); + +void gmDebuggerError(gmDebugSession * a_session, const char * a_error); +void gmDebuggerMessage(gmDebugSession * a_session, const char * a_message); +void gmDebuggerAck(gmDebugSession * a_session, int a_response, int a_posNeg); +void gmDebuggerQuit(gmDebugSession * a_session); + +// +// debug machine callback +// + +enum gmdThreadFlags +{ + TF_STEPOVER = (1 << 0), + TF_STEPINTO = (1 << 1), + TF_STEPOUT = (1 << 2), + TF_BREAK = (1 << 3), +}; + +// the following callbacks return true if the thread is to yield after completion of the callback. +static bool LineCallback(gmThread * a_thread) +{ + gmDebugSession * session = (gmDebugSession *) a_thread->GetMachine()->m_debugUser; + GM_ASSERT(session); + + if(!(a_thread->m_debugFlags & TF_STEPOVER) || + (a_thread->m_debugUser != ((a_thread->GetFrame()) ? a_thread->GetFrame()->m_returnBase : 0))) + { + int * bp = session->FindBreakPoint((void *) a_thread->GetInstruction()); + if(bp == NULL) + return false; + + if(*bp && *bp != a_thread->GetId()) + return false; + } + + a_thread->m_debugFlags = TF_BREAK; + const gmFunctionObject * fn = a_thread->GetFunctionObject(); + gmDebuggerBreak(session, a_thread->GetId(), fn->GetSourceId(), fn->GetLine(a_thread->GetInstruction())); + return true; +} + +static bool CallCallback(gmThread * a_thread) +{ + gmDebugSession * session = (gmDebugSession *) a_thread->GetMachine()->m_debugUser; + GM_ASSERT(session); + if(a_thread->m_debugFlags & TF_STEPINTO) + { + a_thread->m_debugFlags = TF_BREAK; + const gmFunctionObject * fn = a_thread->GetFunctionObject(); + gmDebuggerBreak(session, a_thread->GetId(), fn->GetSourceId(), fn->GetLine(a_thread->GetInstruction())); + return true; + } + return false; +} + +static bool RetCallback(gmThread * a_thread) +{ + gmDebugSession * session = (gmDebugSession *) a_thread->GetMachine()->m_debugUser; + GM_ASSERT(session); + if(((a_thread->m_debugFlags & TF_STEPOUT) && (a_thread->m_debugUser == a_thread->GetIntBase())) || + ((a_thread->m_debugFlags & TF_STEPOVER) && (a_thread->m_debugUser == a_thread->GetIntBase()))) + { + a_thread->m_debugFlags = TF_BREAK; + const gmFunctionObject * fn = a_thread->GetFunctionObject(); + gmDebuggerBreak(session, a_thread->GetId(), fn->GetSourceId(), fn->GetLine(a_thread->GetInstruction())); + return true; + } + return false; +} + +static bool IsBrokenCallback(gmThread * a_thread) +{ + return (a_thread->m_debugFlags & TF_BREAK) > 0; +} + +static gmMachineCallback s_prevMachineCallback = NULL; +bool GM_CDECL gmdMachineCallback(gmMachine * a_machine, gmMachineCommand a_command, const void * a_context) +{ + gmDebugSession * session = (gmDebugSession *) a_machine->m_debugUser; + const gmThread * thread = (const gmThread *) a_context; + + // chain callback + if(s_prevMachineCallback) s_prevMachineCallback(a_machine, a_command, a_context); + + // do we have a debug session? + if(session == NULL) return false; + + // command + switch(a_command) + { + case MC_THREAD_EXCEPTION : + { + // send thread exception message + gmDebuggerException(session, thread->GetId()); + a_machine->GetLog(); + bool first = true; + const char * entry; + while((entry = a_machine->GetLog().GetEntry(first))) + { + gmDebuggerError(session, entry); + } + return true; + } + case MC_THREAD_CREATE : + { + gmDebuggerRun(session, thread->GetId()); + break; + } + case MC_THREAD_DESTROY : + { + gmDebuggerStop(session, thread->GetId()); + break; + } + default : break; + }; + + return false; +} + +// +// debug session +// + +gmDebugSession::gmDebugSession() : + m_breaks(32) +{ + m_machine = NULL; +} + + +gmDebugSession::~gmDebugSession() +{ + m_breaks.RemoveAndDeleteAll(); +} + + +void gmDebugSession::Update() +{ + for(;;) + { + int len; + const void * msg = m_pumpMessage(this, len); + if(msg == NULL) + break; + + m_in.Open(msg, len); + + // parse the message + int id, pa, pb, pc, pd; + Unpack(id); + switch(id) + { + case ID_mrun : + Unpack(id); + gmMachineRun(this, id); + break; + case ID_msin : + Unpack(id); + gmMachineStepInto(this, id); + break; + case ID_msou : + Unpack(id); + gmMachineStepOut(this, id); + break; + case ID_msov : + Unpack(id); + gmMachineStepOver(this, id); + break; + case ID_mgct : + Unpack(id).Unpack(pa); + gmMachineGetContext(this, id, pa); + break; + case ID_mgsr : + Unpack(id); + gmMachineGetSource(this, id); + break; + case ID_mgsi : + gmMachineGetSourceInfo(this); + break; + case ID_mgti : + gmMachineGetThreadInfo(this); + break; + case ID_mgvi : + Unpack(id); + gmMachineGetVariableInfo(this, id); + break; + case ID_msbp : + Unpack(pa).Unpack(pb).Unpack(pc).Unpack(id).Unpack(pd); + gmMachineSetBreakPoint(this, pa, pb, pc, id, pd); + break; + case ID_mbrk : + Unpack(id); + gmMachineBreak(this, id); + break; + case ID_mend : + gmMachineQuit(this); + break; + default:; + } + } +} + + +bool gmDebugSession::Open(gmMachine * a_machine) +{ + Close(); + m_machine = a_machine; + m_machine->m_debugUser = this; + m_machine->m_line = LineCallback; + m_machine->m_call = CallCallback; + m_machine->m_isBroken = IsBrokenCallback; + m_machine->m_return = RetCallback; + s_prevMachineCallback = a_machine->s_machineCallback; + a_machine->s_machineCallback = gmdMachineCallback; + return true; +} + + +static bool threadIterClose(gmThread * a_thread, void * a_context) +{ + a_thread->m_debugFlags = 0; + a_thread->m_debugUser = 0; + return true; +} + + +bool gmDebugSession::Close() +{ + if(m_machine && m_machine->m_debugUser == this) + { + gmDebuggerQuit(this); + + m_machine->m_debugUser = NULL; + m_machine->s_machineCallback = s_prevMachineCallback; + + m_machine->m_line = NULL; + m_machine->m_call = NULL; + m_machine->m_return = NULL; + m_machine->m_isBroken = NULL; + + m_machine->KillExceptionThreads(); + m_machine->ForEachThread(threadIterClose, NULL); + m_machine = NULL; + + m_breaks.RemoveAndDeleteAll(); + m_out.ResetAndFreeMemory(); + + return true; + } + + m_breaks.RemoveAndDeleteAll(); + m_out.ResetAndFreeMemory(); + + return false; +} + + +gmDebugSession &gmDebugSession::Pack(int a_val) +{ + m_out << a_val; + return *this; +} + + +gmDebugSession &gmDebugSession::Pack(const char * a_val) +{ + if(a_val) + m_out.Write(a_val, strlen(a_val) + 1); + else + m_out.Write("", 1); + return *this; +} + + +void gmDebugSession::Send() +{ + m_sendMessage(this, m_out.GetData(), m_out.GetSize()); + m_out.Reset(); +} + + +gmDebugSession &gmDebugSession::Unpack(int &a_val) +{ + if(m_in.Read(&a_val, 4) != 4) a_val = 0; + return *this; +} + + +gmDebugSession &gmDebugSession::Unpack(const char * &a_val) +{ + // this is dangerous!!! + a_val = &m_in.GetData()[m_in.Tell()]; + int len = strlen(a_val); + m_in.Seek(m_in.Tell() + len + 1); + return *this; +} + + +bool gmDebugSession::AddBreakPoint(const void * a_bp, int a_threadId) +{ + BreakPoint * bp = m_breaks.Find((void *const&)a_bp); + if(bp) return false; + bp = GM_NEW( BreakPoint() ); + bp->m_bp = a_bp; + bp->m_threadId = a_threadId; + m_breaks.Insert(bp); + return true; +} + + +int * gmDebugSession::FindBreakPoint(const void * a_bp) +{ + BreakPoint * bp = m_breaks.Find((void *const&)a_bp); + if(bp) + { + return &bp->m_threadId; + } + return NULL; +} + + +bool gmDebugSession::RemoveBreakPoint(const void * a_bp) +{ + BreakPoint * bp = m_breaks.Find((void *const&)a_bp); + if(bp) + { + m_breaks.Remove(bp); + delete bp; + return true; + } + return false; +} + +// +// implementation +// + +void gmMachineRun(gmDebugSession * a_session, int a_threadId) +{ + gmThread * thread = a_session->GetMachine()->GetThread(a_threadId); + if(thread) + { + thread->m_debugFlags = 0; + } +} + +void gmMachineStepInto(gmDebugSession * a_session, int a_threadId) +{ + gmThread * thread = a_session->GetMachine()->GetThread(a_threadId); + if(thread) + { + thread->m_debugUser = (thread->GetFrame()) ? thread->GetFrame()->m_returnBase : 0; + thread->m_debugFlags = TF_STEPINTO | TF_STEPOVER; + } +} + +void gmMachineStepOver(gmDebugSession * a_session, int a_threadId) +{ + gmThread * thread = a_session->GetMachine()->GetThread(a_threadId); + if(thread) + { + thread->m_debugUser = (thread->GetFrame()) ? thread->GetFrame()->m_returnBase : 0; + thread->m_debugFlags = TF_STEPOVER; + } +} + +void gmMachineStepOut(gmDebugSession * a_session, int a_threadId) +{ + gmThread * thread = a_session->GetMachine()->GetThread(a_threadId); + if(thread) + { + thread->m_debugUser = (thread->GetFrame()) ? thread->GetFrame()->m_returnBase : 0; + thread->m_debugFlags = TF_STEPOUT; + } +} + +void gmMachineGetContext(gmDebugSession * a_session, int a_threadId, int a_callframe) +{ + const int buffSize = 256; + char buff[buffSize]; // buff is used for AsString + + gmThread * thread = a_session->GetMachine()->GetThread(a_threadId); + if(thread) + { + // count the number of frames on the thread + int numFrames = 0; + const gmStackFrame * frame = thread->GetFrame(); + while(frame) + { + ++numFrames; + frame = frame->m_prev; + } + + // if a valid frame was requested, fill out a context. + if(a_callframe >= 0 && a_callframe <= numFrames) + { + gmDebuggerBeginContext(a_session, a_threadId, a_callframe); + + // pack frames + frame = thread->GetFrame(); + numFrames = 0; + + gmVariable * base = thread->GetBase(); + const gmuint8 * ip = thread->GetInstruction(); + + while(frame) + { + // get the function object + gmVariable * fnVar = base - 1; + if(fnVar->m_type == GM_FUNCTION) + { + gmFunctionObject * fn = (gmFunctionObject *) GM_MOBJECT(thread->GetMachine(), fnVar->m_value.m_ref); + + // this + base[-2].AsStringWithType(thread->GetMachine(), buff, buffSize); + gmDebuggerContextCallFrame(a_session, numFrames, fn->GetDebugName(), fn->GetSourceId(), fn->GetLine(ip), "this", buff, (base[-2].IsReference()) ? base[-2].m_value.m_ref : 0); + + if(numFrames == a_callframe) + { + // this is the active frame, fill out the variables + int i; + for(i = 0; i < fn->GetNumParamsLocals(); ++i) + { + base[i].AsStringWithType(thread->GetMachine(), buff, buffSize); + gmDebuggerContextVariable(a_session, fn->GetSymbol(i), buff, (base[i].IsReference()) ? base[i].m_value.m_ref : 0); + } + } + } + else + { + base[-2].AsStringWithType(thread->GetMachine(), buff, buffSize); + gmDebuggerContextCallFrame(a_session, numFrames, "unknown", 0, 0, "this", buff, (base[-2].IsReference()) ? base[-2].m_value.m_ref : 0); + } + + // next call frame + ++numFrames; + base = thread->GetBottom() + frame->m_returnBase; + ip = frame->m_returnAddress; + frame = frame->m_prev; + } + + gmDebuggerEndContext(a_session); + } + } +} + +void gmMachineGetSource(gmDebugSession * a_session, int a_sourceId) +{ + const char * source; + const char * filename; + if(a_session->GetMachine()->GetSourceCode(a_sourceId, source, filename)) + { + gmDebuggerSource(a_session, a_sourceId, filename, source); + } +} + +void gmMachineGetSourceInfo(gmDebugSession * a_session) +{ + // todo +} + + +static bool threadIter(gmThread * a_thread, void * a_context) +{ + gmDebugSession * session = (gmDebugSession *) a_context; + int state = 0; // 0 - running, 1 - blocked, 2 - sleeping, 3 - exception, 4 - debug + if(a_thread->m_debugFlags) + state = 4; + else if(a_thread->GetState() == gmThread::EXCEPTION) + state = 3; + else if(a_thread->GetState() == gmThread::RUNNING) + state = 0; + else if(a_thread->GetState() == gmThread::BLOCKED) + state = 1; + else if(a_thread->GetState() == gmThread::SLEEPING) + state = 2; + else + state = 3; + gmDebuggerThreadInfo(session, a_thread->GetId(), state); + return true; +} + + +void gmMachineGetThreadInfo(gmDebugSession * a_session) +{ + gmDebuggerBeginThreadInfo(a_session); + a_session->GetMachine()->ForEachThread(threadIter, a_session); + gmDebuggerEndThreadInfo(a_session); +} + +void gmMachineGetVariableInfo(gmDebugSession * a_session, int a_variableId) +{ + // todo +} + +void gmMachineSetBreakPoint(gmDebugSession * a_session, int a_responseId, int a_sourceId, int a_lineNumber, int a_threadId, int a_enabled) +{ + bool sendAck = false; + + // get break point + const void * bp = (const void *) a_session->GetMachine()->GetInstructionAtBreakPoint(a_sourceId, a_lineNumber); + if(bp) + { + // get to next instruction + bp = (const void *) (((const char *) bp) + 4); + + int * id = a_session->FindBreakPoint(bp); + if(id) + { + if(!a_enabled) + { + a_session->RemoveBreakPoint(bp); + sendAck = true; + } + } + else + { + if(a_session->AddBreakPoint(bp, a_threadId)) + { + sendAck = true; + } + } + } + + if(sendAck) + gmDebuggerAck(a_session, a_responseId, 1); + else + gmDebuggerAck(a_session, a_responseId, 0); +} + +void gmMachineBreak(gmDebugSession * a_session, int a_threadId) +{ + gmThread * thread = a_session->GetMachine()->GetThread(a_threadId); + if(thread) + { + thread->m_debugUser = (thread->GetFrame()) ? thread->GetFrame()->m_returnBase : 0; + thread->m_debugFlags = TF_STEPINTO | TF_STEPOVER; + } +} + +void gmMachineQuit(gmDebugSession * a_session) +{ + a_session->Close(); +} + +void gmDebuggerBreak(gmDebugSession * a_session, int a_threadId, int a_sourceId, int a_lineNumber) { + a_session->Pack(ID_dbrk).Pack(a_threadId).Pack(a_sourceId).Pack(a_lineNumber).Send(); +} +void gmDebuggerException(gmDebugSession * a_session, int a_threadId) { + a_session->Pack(ID_dexc).Pack(a_threadId).Send(); +} +void gmDebuggerRun(gmDebugSession * a_session, int a_threadId) { + a_session->Pack(ID_drun).Pack(a_threadId).Send(); +} +void gmDebuggerStop(gmDebugSession * a_session, int a_threadId) { + a_session->Pack(ID_dstp).Pack(a_threadId).Send(); +} +void gmDebuggerSource(gmDebugSession * a_session, int a_sourceId, const char * a_sourceName, const char * a_source) { + a_session->Pack(ID_dsrc).Pack(a_sourceId).Pack(a_sourceName).Pack(a_source).Send(); +} +void gmDebuggerBeginContext(gmDebugSession * a_session, int a_threadId, int a_callFrame) { + a_session->Pack(ID_dctx).Pack(a_threadId).Pack(a_callFrame); +} +void gmDebuggerContextCallFrame(gmDebugSession * a_session, int a_callFrame, const char * a_functionName, int a_sourceId, int a_lineNumber, const char * a_thisSymbol, const char * a_thisValue, int a_thisId) { + a_session->Pack(ID_call).Pack(a_callFrame).Pack(a_functionName).Pack(a_sourceId).Pack(a_lineNumber).Pack(a_thisSymbol).Pack(a_thisValue).Pack(a_thisId); +} +void gmDebuggerContextVariable(gmDebugSession * a_session, const char * a_varSymbol, const char * a_varValue, int a_varId) { + a_session->Pack(ID_vari).Pack(a_varSymbol).Pack(a_varValue).Pack(a_varId); +} +void gmDebuggerEndContext(gmDebugSession * a_session) { + a_session->Pack(ID_done).Send(); +} +void gmDebuggerBeginSourceInfo(gmDebugSession * a_session) { + a_session->Pack(ID_dsri); +} +void gmDebuggerSourceInfo(gmDebugSession * a_session, int a_sourceId, const char * a_sourceName) { + a_session->Pack(ID_srci).Pack(a_sourceId).Pack(a_sourceName); +} +void gmDebuggerEndSourceInfo(gmDebugSession * a_session) { + a_session->Pack(ID_done).Send(); +} +void gmDebuggerBeginThreadInfo(gmDebugSession * a_session) { + a_session->Pack(ID_dthi); +} +void gmDebuggerThreadInfo(gmDebugSession * a_session, int a_threadId, int a_threadState) { + a_session->Pack(ID_thri).Pack(a_threadId).Pack(a_threadState); +} +void gmDebuggerEndThreadInfo(gmDebugSession * a_session) { + a_session->Pack(ID_done).Send(); +} +void gmDebuggerError(gmDebugSession * a_session, const char * a_error) { + a_session->Pack(ID_derr).Pack(a_error).Send(); +} +void gmDebuggerMessage(gmDebugSession * a_session, const char * a_message) { + a_session->Pack(ID_dmsg).Pack(a_message).Send(); +} +void gmDebuggerAck(gmDebugSession * a_session, int a_response, int a_posNeg) { + a_session->Pack(ID_dack).Pack(a_response).Pack(a_posNeg).Send(); +} +void gmDebuggerQuit(gmDebugSession * a_session) { + a_session->Pack(ID_dend).Send(); +} + + +// +// lib binding +// + + +int GM_CDECL gmdDebug(gmThread * a_thread) +{ + // if the machine has a debug session, attach a debug hook to the thread + if(a_thread->GetMachine()->m_debugUser && a_thread->GetMachine()->GetDebugMode()) + { + a_thread->m_debugUser = (a_thread->GetFrame()) ? a_thread->GetFrame()->m_returnBase : 0; + a_thread->m_debugFlags = TF_STEPINTO | TF_STEPOVER; + } + return GM_OK; +} + + + +static gmFunctionEntry s_debugLib[] = +{ + /*gm + \lib gm + \brief functions in the gm lib are all global scope + */ + + /*gm + \function debug + \brief debug will cause a the debugger to break at this point while running. + */ + + {"debug", gmdDebug}, +}; + + + +void gmBindDebugLib(gmMachine * a_machine) +{ + a_machine->RegisterLibrary(s_debugLib, sizeof(s_debugLib) / sizeof(s_debugLib[0])); +} + +#endif diff --git a/vscript/languages/gm/src/gm/gmDebug.h b/vscript/languages/gm/src/gm/gmDebug.h new file mode 100644 index 00000000..cbe476c3 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmDebug.h @@ -0,0 +1,88 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMDEBUG_H_ +#define _GMDEBUG_H_ + +#include "gmConfig.h" +#include "gmStreamBuffer.h" +#include "gmHash.h" + +class gmMachine; +class gmDebugSession; + +// bind debug lib +void gmBindDebugLib(gmMachine * a_machine); + +// callbacks used to hook up comms +typedef void (GM_CDECL *gmSendDebuggerMessage)(gmDebugSession * a_session, const void * a_command, int a_len); +typedef const void * (GM_CDECL *gmPumpDebuggerMessage)(gmDebugSession * a_session, int &a_len); + +#if GMDEBUG_SUPPORT + +/// \class gmDebugSession +class gmDebugSession +{ +public: + + gmDebugSession(); + ~gmDebugSession(); + + /// \brief Update() must be called to pump messages + void Update(); + + /// \brief Open() will start debugging on a_machine + bool Open(gmMachine * a_machine); + + /// \brief Close() will stop debugging + bool Close(); + + /// \brief GetMachine() + inline gmMachine * GetMachine() const { return m_machine; } + + gmSendDebuggerMessage m_sendMessage; + gmPumpDebuggerMessage m_pumpMessage; + void * m_user; + + // send message helpers + gmDebugSession &Pack(int a_val); + gmDebugSession &Pack(const char * a_val); + void Send(); + + // rcv message helpers + gmDebugSession &Unpack(int &a_val); + gmDebugSession &Unpack(const char * &a_val); + + // helpers + bool AddBreakPoint(const void * a_bp, int a_threadId); + int * FindBreakPoint(const void * a_bp); // return thread id + bool RemoveBreakPoint(const void * a_bp); + +private: + + class BreakPoint : public gmHashNode + { + public: + inline const void * GetKey() const { return m_bp; } + const void * m_bp; + int m_threadId; + }; + + gmMachine * m_machine; + + gmHash m_breaks; + gmStreamBufferDynamic m_out; + gmStreamBufferStatic m_in; +}; + +#endif + +#endif // _GMDEBUG_H_ diff --git a/vscript/languages/gm/src/gm/gmDebugger.cpp b/vscript/languages/gm/src/gm/gmDebugger.cpp new file mode 100644 index 00000000..c434223f --- /dev/null +++ b/vscript/languages/gm/src/gm/gmDebugger.cpp @@ -0,0 +1,321 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include +#include "gmDebugger.h" + +// +// Please note that gmDebugger.c/.h are for implementing +// a debugger application and should not be included +// in an normal GM application build. +// + +#ifndef GM_MAKE_ID32 + #define GM_MAKE_ID32( a, b, c, d ) ( ((d)<<24) | ((c)<<16) | ((b)<<8) | (a)) +#endif //GM_MAKE_ID32 + +#define ID_mrun GM_MAKE_ID32('m','r','u','n') +#define ID_msin GM_MAKE_ID32('m','s','i','n') +#define ID_msou GM_MAKE_ID32('m','s','o','u') +#define ID_msov GM_MAKE_ID32('m','s','o','v') +#define ID_mgct GM_MAKE_ID32('m','g','c','t') +#define ID_mgsr GM_MAKE_ID32('m','g','s','r') +#define ID_mgsi GM_MAKE_ID32('m','g','s','i') +#define ID_mgti GM_MAKE_ID32('m','g','t','i') +#define ID_mgvi GM_MAKE_ID32('m','g','v','i') +#define ID_msbp GM_MAKE_ID32('m','s','b','p') +#define ID_mbrk GM_MAKE_ID32('m','b','r','k') +#define ID_mend GM_MAKE_ID32('m','e','n','d') + +#define ID_dbrk GM_MAKE_ID32('d','b','r','k') +#define ID_dexc GM_MAKE_ID32('d','e','x','c') +#define ID_drun GM_MAKE_ID32('d','r','u','n') +#define ID_dstp GM_MAKE_ID32('d','s','t','p') +#define ID_dsrc GM_MAKE_ID32('d','s','r','c') +#define ID_dctx GM_MAKE_ID32('d','c','t','x') +#define ID_call GM_MAKE_ID32('c','a','l','l') +#define ID_vari GM_MAKE_ID32('v','a','r','i') +#define ID_done GM_MAKE_ID32('d','o','n','e') +#define ID_dsri GM_MAKE_ID32('d','s','r','i') +#define ID_srci GM_MAKE_ID32('s','r','c','i') +#define ID_done GM_MAKE_ID32('d','o','n','e') +#define ID_dthi GM_MAKE_ID32('d','t','h','i') +#define ID_thri GM_MAKE_ID32('t','h','r','i') +#define ID_done GM_MAKE_ID32('d','o','n','e') +#define ID_derr GM_MAKE_ID32('d','e','r','r') +#define ID_dmsg GM_MAKE_ID32('d','m','s','g') +#define ID_dack GM_MAKE_ID32('d','a','c','k') +#define ID_dend GM_MAKE_ID32('d','e','n','d') + +// +// Please note that gmDebugger.c/.h are for implementing +// a debugger application and should not be included +// in an normal GM application build. +// + + +gmDebuggerSession::gmDebuggerSession() +{ + m_outSize = 256; + m_out = (void*) new char[m_outSize]; + m_outCursor = 0; + m_in = NULL; + m_inCursor = m_inSize = NULL; +} + + +gmDebuggerSession::~gmDebuggerSession() +{ + if(m_out) + { + delete [] (char*)m_out; + } +} + + +void gmDebuggerSession::Update() +{ + for(;;) + { + m_in = m_pumpMessage(this, m_inSize); + if(m_in == NULL) break; + m_inCursor = 0; + + int id, pa, pb, pc; + const char * sa, * sb, * sc; + + Unpack(id); + switch(id) + { + case ID_dbrk : + Unpack(id).Unpack(pa).Unpack(pb); + gmDebuggerBreak(this, id, pa, pb); + break; + case ID_drun : + Unpack(id); + gmDebuggerRun(this, id); + break; + case ID_dstp : + Unpack(id); + gmDebuggerStop(this, id); + break; + case ID_dsrc : + Unpack(id).Unpack(sa).Unpack(sb); + gmDebuggerSource(this, id, sa, sb); + break; + case ID_dexc : + Unpack(id); + gmDebuggerException(this, id); + break; + case ID_dctx : + Unpack(id).Unpack(pa); // thread id, callframe + gmDebuggerBeginContext(this, id, pa); + for(;;) + { + Unpack(id); + if(id == ID_call) + { + Unpack(id).Unpack(sa).Unpack(pa).Unpack(pb).Unpack(sb).Unpack(sc).Unpack(pc); + gmDebuggerContextCallFrame(this, id, sa, pa, pb, sb, sc, pc); + } + else if(id == ID_vari) + { + Unpack(sa).Unpack(sb).Unpack(pa); + gmDebuggerContextVariable(this, sa, sb, pa); + } + else if(id == ID_done) break; + else break; + } + gmDebuggerEndContext(this); + break; + case ID_dsri : + // todo + break; + case ID_dthi : + gmDebuggerBeginThreadInfo(this); + for(;;) + { + Unpack(id); + if(id == ID_thri) + { + Unpack(pa).Unpack(pb); + gmDebuggerThreadInfo(this, pa, pb); + } + else if(id == ID_done) break; + else break; + } + gmDebuggerEndThreadInfo(this); + break; + case ID_derr : + Unpack(sa); + gmDebuggerError(this, sa); + break; + case ID_dmsg : + Unpack(sa); + gmDebuggerMessage(this, sa); + break; + case ID_dack : + Unpack(pa).Unpack(pb); + gmDebuggerAck(this, pa, pb); + break; + case ID_dend : + gmDebuggerQuit(this); + break; + default:; + } + } +} + + +bool gmDebuggerSession::Open() +{ + m_outCursor = 0; + return true; +} + + +bool gmDebuggerSession::Close() +{ + return true; +} + + +gmDebuggerSession &gmDebuggerSession::Pack(int a_val) +{ + Need(4); + memcpy((char *) m_out + m_outCursor, &a_val, 4); + m_outCursor += 4; + return *this; +} + + +gmDebuggerSession &gmDebuggerSession::Pack(const char * a_val) +{ + if(a_val) + { + int len = strlen(a_val) + 1; + Need(len); + memcpy((char *) m_out + m_outCursor, a_val, len); + m_outCursor += len; + } + else + { + Need(1); + memcpy((char *) m_out + m_outCursor, "", 1); + m_outCursor += 1; + } + return *this; +} + + +void gmDebuggerSession::Send() +{ + m_sendMessage(this, m_out, m_outCursor); + m_outCursor = 0; +} + + +gmDebuggerSession &gmDebuggerSession::Unpack(int &a_val) +{ + if(m_inCursor + 4 <= m_inSize) + { + memcpy(&a_val, (const char *) m_in + m_inCursor, 4); + m_inCursor += 4; + } + else + { + a_val = 0; + } + return *this; +} + + +gmDebuggerSession &gmDebuggerSession::Unpack(const char * &a_val) +{ + a_val = (const char *) m_in + m_inCursor; + m_inCursor += strlen(a_val) + 1; + return *this; +} + + +void gmDebuggerSession::Need(int a_bytes) +{ + if((m_outCursor + a_bytes) >= m_outSize) + { + int newSize = m_outSize + a_bytes + 256; + void * buffer = (void*)new char[newSize]; + memcpy(buffer, m_out, m_outCursor); + delete [] (char*)m_out; + m_out = buffer; + m_outSize = newSize; + } +} + + +void gmMachineRun(gmDebuggerSession * a_session, int a_threadId) +{ + a_session->Pack(ID_mrun).Pack(a_threadId).Send(); +} + +void gmMachineStepInto(gmDebuggerSession * a_session, int a_threadId) +{ + a_session->Pack(ID_msin).Pack(a_threadId).Send(); +} + +void gmMachineStepOver(gmDebuggerSession * a_session, int a_threadId) +{ + a_session->Pack(ID_msov).Pack(a_threadId).Send(); +} + +void gmMachineStepOut(gmDebuggerSession * a_session, int a_threadId) +{ + a_session->Pack(ID_msou).Pack(a_threadId).Send(); +} + +void gmMachineGetContext(gmDebuggerSession * a_session, int a_threadId, int a_callframe) +{ + a_session->Pack(ID_mgct).Pack(a_threadId).Pack(a_callframe).Send(); +} + +void gmMachineGetSource(gmDebuggerSession * a_session, int a_sourceId) +{ + a_session->Pack(ID_mgsr).Pack(a_sourceId).Send(); +} + +void gmMachineGetSourceInfo(gmDebuggerSession * a_session) +{ + a_session->Pack(ID_mgsi).Send(); +} + +void gmMachineGetThreadInfo(gmDebuggerSession * a_session) +{ + a_session->Pack(ID_mgti).Send(); +} + +void gmMachineGetVariableInfo(gmDebuggerSession * a_session, int a_variableId) +{ + a_session->Pack(ID_mgvi).Pack(a_variableId).Send(); +} + +void gmMachineSetBreakPoint(gmDebuggerSession * a_session, int a_responseId, int a_sourceId, int a_lineNumber, int a_threadId, int a_enabled) +{ + a_session->Pack(ID_msbp).Pack(a_responseId).Pack(a_sourceId).Pack(a_lineNumber).Pack(a_threadId).Pack(a_enabled).Send(); +} + +void gmMachineBreak(gmDebuggerSession * a_session, int a_threadId) +{ + a_session->Pack(ID_mbrk).Pack(a_threadId).Send(); +} + +void gmMachineQuit(gmDebuggerSession * a_session) +{ + a_session->Pack(ID_mend).Send(); +} diff --git a/vscript/languages/gm/src/gm/gmDebugger.h b/vscript/languages/gm/src/gm/gmDebugger.h new file mode 100644 index 00000000..b6a70ee6 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmDebugger.h @@ -0,0 +1,114 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMDEBUGGER_H_ +#define _GMDEBUGGER_H_ + +// +// Please note that gmDebugger.c/.h are for implementing +// a debugger application and should not be included +// in an normal GM application build. +// + + +class gmDebuggerSession; + +// callbacks used to hook up comms +typedef void (*gmSendMachineMessage)(gmDebuggerSession * a_session, const void * a_command, int a_len); +typedef const void * (*gmPumpMachineMessage)(gmDebuggerSession * a_session, int &a_len); + +/// \class gmDebuggerSession +class gmDebuggerSession +{ +public: + + gmDebuggerSession(); + ~gmDebuggerSession(); + + /// \brief Update() must be called to pump messages + void Update(); + + /// \brief Open() will start debugging + bool Open(); + + /// \brief Close() will stop debugging + bool Close(); + + gmSendMachineMessage m_sendMessage; + gmPumpMachineMessage m_pumpMessage; + void * m_user; // hook to your debugger + + // send message helpers + gmDebuggerSession &Pack(int a_val); + gmDebuggerSession &Pack(const char * a_val); + void Send(); + + // rcv message helpers + gmDebuggerSession &Unpack(int &a_val); + gmDebuggerSession &Unpack(const char * &a_val); + +private: + + void * m_out; + int m_outCursor, m_outSize; + void Need(int a_bytes); + + const void * m_in; + int m_inCursor, m_inSize; +}; + +// +// the debugger must implement the following functions +// + +extern void gmDebuggerBreak(gmDebuggerSession * a_session, int a_threadId, int a_sourceId, int a_lineNumber); +extern void gmDebuggerRun(gmDebuggerSession * a_session, int a_threadId); +extern void gmDebuggerStop(gmDebuggerSession * a_session, int a_threadId); +extern void gmDebuggerSource(gmDebuggerSession * a_session, int a_sourceId, const char * a_sourceName, const char * a_source); +extern void gmDebuggerException(gmDebuggerSession * a_session, int a_threadId); + +extern void gmDebuggerBeginContext(gmDebuggerSession * a_session, int a_threadId, int a_callFrame); +extern void gmDebuggerContextCallFrame(gmDebuggerSession * a_session, int a_callFrame, const char * a_functionName, int a_sourceId, int a_lineNumber, const char * a_thisSymbol, const char * a_thisValue, int a_thisId); +extern void gmDebuggerContextVariable(gmDebuggerSession * a_session, const char * a_varSymbol, const char * a_varValue, int a_varId); +extern void gmDebuggerEndContext(gmDebuggerSession * a_session); + +extern void gmDebuggerBeginSourceInfo(gmDebuggerSession * a_session); +extern void gmDebuggerSourceInfo(gmDebuggerSession * a_session, int a_sourceId, const char * a_sourceName); +extern void gmDebuggerEndSourceInfo(gmDebuggerSession * a_session); + +extern void gmDebuggerBeginThreadInfo(gmDebuggerSession * a_session); +extern void gmDebuggerThreadInfo(gmDebuggerSession * a_session, int a_threadId, int a_threadState); +extern void gmDebuggerEndThreadInfo(gmDebuggerSession * a_session); + +extern void gmDebuggerError(gmDebuggerSession * a_session, const char * a_error); +extern void gmDebuggerMessage(gmDebuggerSession * a_session, const char * a_message); +extern void gmDebuggerAck(gmDebuggerSession * a_session, int a_response, int a_posNeg); +extern void gmDebuggerQuit(gmDebuggerSession * a_session); + +// +// the debugger can use the following functions to send messages to the machine +// + +void gmMachineRun(gmDebuggerSession * a_session, int a_threadId); +void gmMachineStepInto(gmDebuggerSession * a_session, int a_threadId); +void gmMachineStepOver(gmDebuggerSession * a_session, int a_threadId); +void gmMachineStepOut(gmDebuggerSession * a_session, int a_threadId); +void gmMachineGetContext(gmDebuggerSession * a_session, int a_threadId, int a_callframe); +void gmMachineGetSource(gmDebuggerSession * a_session, int a_sourceId); +void gmMachineGetSourceInfo(gmDebuggerSession * a_session); +void gmMachineGetThreadInfo(gmDebuggerSession * a_session); +void gmMachineGetVariableInfo(gmDebuggerSession * a_session, int a_variableId); +void gmMachineSetBreakPoint(gmDebuggerSession * a_session, int a_responseId, int a_sourceId, int a_lineNumber, int a_threadId, int a_enabled); +void gmMachineBreak(gmDebuggerSession * a_session, int a_threadId); +void gmMachineQuit(gmDebuggerSession * a_session); + +#endif + diff --git a/vscript/languages/gm/src/gm/gmFunctionObject.cpp b/vscript/languages/gm/src/gm/gmFunctionObject.cpp new file mode 100644 index 00000000..53888f07 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmFunctionObject.cpp @@ -0,0 +1,286 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmFunctionObject.h" +#include "gmMachine.h" + +// Must be last header +#include "memdbgon.h" + + +gmFunctionObject::gmFunctionObject() +{ + m_cFunction = NULL; + m_cUserData = NULL; + m_debugInfo = NULL; + m_byteCode = NULL; + m_byteCodeLength = 0; + m_maxStackSize = 1; // return value + m_numLocals = 0; + m_numParams = 0; + m_numParamsLocals = 0; + m_numReferences = 0; + m_references = NULL; +} + +void gmFunctionObject::Destruct(gmMachine * a_machine) +{ + if(m_references) + { + a_machine->Sys_Free(m_references); + m_references = NULL; + } + if(m_byteCode) + { + a_machine->Sys_Free(m_byteCode); + m_byteCode = NULL; + } + if(m_debugInfo) + { + if(m_debugInfo->m_debugName) { a_machine->Sys_Free(m_debugInfo->m_debugName); } + if(m_debugInfo->m_lineInfo) { a_machine->Sys_Free(m_debugInfo->m_lineInfo); } + if(m_debugInfo->m_symbols) + { + int i; + for(i = 0; i < m_numParamsLocals; ++i) + { + a_machine->Sys_Free(m_debugInfo->m_symbols[i]); + } + a_machine->Sys_Free(m_debugInfo->m_symbols); + } + a_machine->Sys_Free(m_debugInfo); + m_debugInfo = NULL; + } + +#if GM_USE_INCGC + a_machine->DestructDeleteObject(this); +#endif //GM_USE_INCGC +} + +#if GM_USE_INCGC + + +bool gmFunctionObject::Trace(gmMachine * a_machine, gmGarbageCollector* a_gc, const int a_workLeftToGo, int& a_workDone) +{ + int i; + for(i = 0; i < m_numReferences; ++i) + { + gmObject * object = a_machine->GetObject(m_references[i]); + a_gc->GetNextObject(object); + ++a_workDone; + } + + ++a_workDone; + return true; +} + +#else //GM_USE_INCGC + +void gmFunctionObject::Mark(gmMachine * a_machine, gmuint32 a_mark) +{ + if(m_mark != GM_MARK_PERSIST) m_mark = a_mark; + int i; + for(i = 0; i < m_numReferences; ++i) + { + gmObject * object = a_machine->GetObject(m_references[i]); + if(object->NeedsMark(a_mark)) object->Mark(a_machine, a_mark); + } +} +#endif //GM_USE_INCGC + + +bool gmFunctionObject::Init(gmMachine * a_machine, bool a_debug, gmFunctionInfo &a_info, gmuint32 a_sourceId) +{ + // byte code + if(a_info.m_byteCodeLength) + { + m_byteCode = (gmuint8 *) a_machine->Sys_Alloc(a_info.m_byteCodeLength); + memcpy(m_byteCode, a_info.m_byteCode, a_info.m_byteCodeLength); + m_byteCodeLength = a_info.m_byteCodeLength; + } + else + { + m_byteCode = NULL; + m_byteCodeLength = 0; + } + + // stack info + m_maxStackSize = a_info.m_maxStackSize; + m_numLocals = a_info.m_numLocals; + m_numParams = a_info.m_numParams; + m_numParamsLocals = a_info.m_numParams + a_info.m_numLocals; + + // references + m_numReferences = 0; + m_references = NULL; + + if(m_byteCode) + { + // find the objects this function references by iterating over the byte code and collecting them. + // we could perform this step in the compilation phase if we don't want to iterate over the byte code. + + gmptr * references = (gmptr *) GM_NEW( char[a_info.m_byteCodeLength] ); + + union + { + const gmuint8 * instruction; + const gmuint32 * instruction32; + }; + + instruction = (const gmuint8 *) m_byteCode; + const gmuint8 * end = instruction + m_byteCodeLength; + for(;instruction < end;) + { + switch(*(instruction32++)) + { + case BC_GETDOT : + case BC_SETDOT : + case BC_BRA : + case BC_BRZ : + case BC_BRNZ : + case BC_BRZK : + case BC_BRNZK : + case BC_FOREACH : + case BC_PUSHINT : + case BC_GETGLOBAL : + case BC_SETGLOBAL : + case BC_GETTHIS : + case BC_SETTHIS : instruction += sizeof(gmptr); break; + case BC_PUSHFP : instruction += sizeof(gmfloat); break; + + case BC_CALL : + case BC_GETLOCAL : + case BC_SETLOCAL : instruction += sizeof(gmuint32); break; + + case BC_PUSHSTR : + case BC_PUSHFN : + { + // if the reference does not already exist, add it. + gmptr reference = *((gmptr *) instruction); + instruction += sizeof(gmptr); + int i; + for(i = 0; i < m_numReferences; ++i) + { + if(references[i] == reference) break; + } + if(i == m_numReferences) references[m_numReferences++] = reference; + break; + } + + default : break; + } + } + + if(m_numReferences > 0) + { + m_references = (gmptr *) a_machine->Sys_Alloc(sizeof(gmptr) * m_numReferences); + memcpy(m_references, references, sizeof(gmptr) * m_numReferences); + } + + delete [] (char*) references; + } + + // debug info + m_debugInfo = NULL; + if(a_debug) + { + m_debugInfo = (gmFunctionObjectDebugInfo *) a_machine->Sys_Alloc(sizeof(gmFunctionObjectDebugInfo)); + memset(m_debugInfo, 0, sizeof(gmFunctionObjectDebugInfo)); + + // source code id + m_debugInfo->m_sourceId = a_sourceId; + + // debug name + if(a_info.m_debugName) + { + int len = strlen(a_info.m_debugName) + 1; + m_debugInfo->m_debugName = (char *) a_machine->Sys_Alloc(len); + memcpy(m_debugInfo->m_debugName, a_info.m_debugName, len); + } + + // symbols + if(a_info.m_symbols) + { + m_debugInfo->m_symbols = (char **) a_machine->Sys_Alloc(sizeof(char *) * m_numParamsLocals); + int i; + for(i = 0; i < m_numParamsLocals; ++i) + { + int len = strlen(a_info.m_symbols[i]) + 1; + m_debugInfo->m_symbols[i] = (char *) a_machine->Sys_Alloc(len); + memcpy(m_debugInfo->m_symbols[i], a_info.m_symbols[i], len); + } + } + + // line number debugging. + if(a_info.m_lineInfo) + { + // alloc and copy + m_debugInfo->m_lineInfo = (gmLineInfo *) a_machine->Sys_Alloc(sizeof(gmLineInfo) * a_info.m_lineInfoCount); + memcpy(m_debugInfo->m_lineInfo, a_info.m_lineInfo, sizeof(gmLineInfo) * a_info.m_lineInfoCount); + m_debugInfo->m_lineInfoCount = a_info.m_lineInfoCount; + } + } + + return true; +} + + + +int gmFunctionObject::GetLine(int a_address) const +{ + if(m_debugInfo && m_debugInfo->m_lineInfo) + { + int i; + for(i = 0; i < m_debugInfo->m_lineInfoCount; ++i) + { + if(a_address < m_debugInfo->m_lineInfo[i].m_address) + { + // return entry before + if(i > 0) --i; + return m_debugInfo->m_lineInfo[i].m_lineNumber; + } + } + return m_debugInfo->m_lineInfo[i - 1].m_lineNumber; + } + return 0; +} + + + +const void * gmFunctionObject::GetInstructionAtLine(int a_line) const +{ + if(m_debugInfo && m_debugInfo->m_lineInfo && m_byteCode) + { + // serach for the first address using this line. + int i; + for(i = 0; i < m_debugInfo->m_lineInfoCount; ++i) + { + if(m_debugInfo->m_lineInfo[i].m_lineNumber == a_line) + { + return (void *) ((char *) m_byteCode + m_debugInfo->m_lineInfo[i].m_address); + } + } + } + return NULL; +} + + + +gmuint32 gmFunctionObject::GetSourceId() const +{ + if(m_debugInfo) + { + return m_debugInfo->m_sourceId; + } + return 0; +} + diff --git a/vscript/languages/gm/src/gm/gmFunctionObject.h b/vscript/languages/gm/src/gm/gmFunctionObject.h new file mode 100644 index 00000000..ce6dfd69 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmFunctionObject.h @@ -0,0 +1,163 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMFUNCTIONOBJECT_H_ +#define _GMFUNCTIONOBJECT_H_ + +#include "gmConfig.h" +#include "gmVariable.h" +#include "gmCodeGenHooks.h" +#include "gmMem.h" + +// fwd decls +class gmThread; + +enum gmCFunctionReturn +{ + GM_OK = 0, + GM_EXCEPTION = -1, + GM_SYS_YIELD = -2, // system only + GM_SYS_BLOCK = -3, // system only + GM_SYS_SLEEP = -4, // system only + GM_SYS_KILL = -5, // system only + GM_SYS_STATE = -6, // system only +}; + +/*! + \brief gmCFunction is the function type for binding c functions to gm. + \return gmCFunctionReturn +*/ +typedef int (GM_CDECL *gmCFunction)(gmThread *); + +/*! + \class gmFunctionObject + \brief +*/ +class gmFunctionObject : public gmObject +{ +public: + + virtual int GetType() const { return GM_FUNCTION; } + + virtual void Destruct(gmMachine * a_machine); +#if GM_USE_INCGC + virtual bool Trace(gmMachine * a_machine, gmGarbageCollector* a_gc, const int a_workLeftToGo, int& a_workDone); +#else //GM_USE_INCGC + virtual void Mark(gmMachine * a_machine, gmuint32 a_mark); +#endif //GM_USE_INCGC + + + /*! + \brief Init() will initialise a function object. + \param a_debug is true if this is a debug build + \param a_info is a function info struct as built by gmCodeGenHooks. + \param a_sourceId is an unique id specifiying the source code of the function, is used for debugging. + \return true on success. + */ + bool Init(gmMachine * a_machine, bool a_debug, gmFunctionInfo &a_info, gmuint32 a_sourceId = 0); + + /*! + \brief GetMaxStackSize + \return the maximum stack growth not including parameters or locals + */ + inline int GetMaxStackSize() const { return m_maxStackSize; } + + /// \brief GetNumLocals + inline int GetNumLocals() const { return m_numLocals; } + + /// \brief GetNumParams + inline int GetNumParams() const { return m_numParams; } + + /// \brief GetNumParamsLocals() + inline int GetNumParamsLocals() const { return m_numParamsLocals; } + + /// \brief GetByteCode() + inline const void * GetByteCode() const { return m_byteCode; } + + /// \brief GetDebugName() + inline const char * GetDebugName() const; + + /// \brief GetLine() will return the source line for the given address + int GetLine(int a_address) const; + int GetLine(const void * a_instruction) const { return GetLine((const char * ) a_instruction - (char *) m_byteCode); } + + /// \brief GetInstructionAtLine() will return the instruction at the given line, or NULL of line was not within this function + const void * GetInstructionAtLine(int a_line) const; + + /// \brief GetSourceId() will get the source code id when in debug mode, else 0 + gmuint32 GetSourceId() const; + + /// \brief GetSymbol() will return the symbol name at the given offset. + inline const char * GetSymbol(int a_offset) const; + + // public data + gmCFunction m_cFunction; + const void* m_cUserData; + +protected: + + /// \brief Non-public constructor. Create via gmMachine. + gmFunctionObject(); + friend class gmMachine; + +private: + + /*! + \brief gmFunctionObjectDebugInfo stores debugging info for a debug build + */ + struct gmFunctionObjectDebugInfo + { + char * m_debugName; + char ** m_symbols; + int m_lineInfoCount; + gmuint32 m_sourceId; // source code id. + gmLineInfo * m_lineInfo; + }; + + gmFunctionObjectDebugInfo * m_debugInfo; + void * m_byteCode; + int m_byteCodeLength; + int m_maxStackSize; + int m_numLocals; + int m_numParams; + int m_numParamsLocals; //!< m_numLocals + m_numParams + int m_numReferences; //!< number of references within the byte code. + gmptr * m_references; //!< references from the byte code +}; + +// +// +// INLINE IMPLEMENTATION +// +// + +inline const char * gmFunctionObject::GetDebugName() const +{ + if(m_debugInfo && m_debugInfo->m_debugName) + { + return m_debugInfo->m_debugName; + } + return "__unknown"; +} + + + +inline const char * gmFunctionObject::GetSymbol(int a_offset) const +{ + if(m_debugInfo && m_debugInfo->m_symbols && (a_offset >= 0) && (a_offset < m_numParamsLocals)) + { + return m_debugInfo->m_symbols[a_offset]; + } + return "__unknown"; +} + + +#endif // _GMFUNCTIONOBJECT_H_ diff --git a/vscript/languages/gm/src/gm/gmHash.cpp b/vscript/languages/gm/src/gm/gmHash.cpp new file mode 100644 index 00000000..9357d875 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmHash.cpp @@ -0,0 +1,17 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmHash.h" + + +// Must be last header +#include "memdbgon.h" diff --git a/vscript/languages/gm/src/gm/gmHash.h b/vscript/languages/gm/src/gm/gmHash.h new file mode 100644 index 00000000..1016d334 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmHash.h @@ -0,0 +1,348 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMHASH_H_ +#define _GMHASH_H_ + +#include "gmConfig.h" +#include "gmIterator.h" + +#define TMPL template +#define QUAL gmHash +#define NQUAL gmHashNode + +TMPL class gmHash; +class gmDefaultHasher; + +/// \class gmHashNode +/// \brief inherit gmHashNode +template +class gmHashNode +{ +public: + inline gmHashNode() {} + + /// \brief Return whatever is the 'key' for this type. Used by gmHash + //const KEY& GetKey() const = 0; + +private: + + T * m_next; + friend class QUAL; +}; + +/// \class gmHash +/// \brief templated intrusive hash class +/// HASHER must provide static gmuint ::Hash(const KEY &a_key) and int ::Compare(const KEY &a_key, const KEY &a_key) +template +class gmHash +{ +public: + + /// \class Iterator + class Iterator + { + public: + + GM_INCLUDE_ITERATOR_KERNEL(T) + + inline Iterator() + { + m_hash = NULL; + m_elem = NULL; + m_slot = 0; + } + + inline Iterator(const gmHash * a_hash) + { + m_hash = a_hash; + m_slot = 0; + m_elem = NULL; + Inc(); + } + + inline void Inc(void) + { + GM_ASSERT(m_hash); + if(m_elem) + { + m_elem = m_hash->GetNext(m_elem); + } + while(m_elem == NULL && m_slot < m_hash->m_size) + { + m_elem = m_hash->m_table[m_slot++]; + } + } + + inline void Dec(void) { GM_ASSERT(false); } + inline T * Resolve(void) { return m_elem; } + inline const T * Resolve(void) const { return m_elem; } + inline bool IsValid() const { return (m_elem != NULL); } + + private: + + const gmHash * m_hash; + T * m_elem; + unsigned int m_slot; + }; + + // members + + gmHash(gmuint a_size); + ~gmHash(); + + void RemoveAll(); + void RemoveAndDeleteAll(); + + /// \brief Insert() will insert an item into the hash table. + /// \return non-null on failure, in which case the returned item is the duplicate existing in the hash + T * Insert(T * a_node); + + /// \brief Remove() will remove an item from the hash table + /// \return the removed item + T * Remove(T * a_node); + + /// \brief Remove() will remove an item from the hash table via an iterator + /// \return the removed item + T * Remove(Iterator & a_it); + + /// \brief RemoveKey() will remove an item by key + /// \return the removed item + T * RemoveKey(const KEY &a_key); + + /// \brief Find() + T * Find(const KEY &a_key); + + inline gmuint Count() const { return m_count; } + inline Iterator First() const { return Iterator(this); } + +private: + + T * GetNext(T * a_elem) const { return a_elem->NQUAL::m_next; } + T ** m_table; + gmuint m_count; + gmuint m_size; + + friend class Iterator; +}; + + +/// \class gmDefaultHasher +/// \brief use the gmDefaultHasher as the HASHER template arg for the common hashing keys +class gmDefaultHasher +{ +public: + + static inline gmuint Hash(const char * a_key) + { + gmuint key = 0; + const char * cp = (const char *) a_key; + + while(*cp != '\0') + { + key = (key + ((key << 5) + *cp)); + ++cp; + } + return key; + } + + static inline int Compare(const char * a_keyA, const char * a_keyB) + { + return strcmp(a_keyA, a_keyB); + } + + static inline gmuint Hash(int a_key) + { + return (gmuint) a_key; + } + + static inline int Compare(int a_keyA, int a_keyB) + { + return (a_keyA - a_keyB); + } + + static inline gmuint Hash(const void * a_key) + { + return (gmuint) (((gmuint) a_key) / sizeof(double)); + } + + static inline int Compare(const void * a_keyA, const void * a_keyB) + { + return (int) ((char *) a_keyA - (char *) a_keyB); + } +}; + + + +TMPL +QUAL::gmHash(gmuint a_size) +{ + // make sure size is power of 2 + GM_ASSERT((a_size & (a_size - 1)) == 0); + m_size = a_size; + m_table = GM_NEW(T * [a_size]); + int i = m_size; + while(i--) + { + m_table[i] = NULL; + } + m_count = 0; +} + +TMPL +QUAL::~gmHash() +{ + delete [] m_table; +} + + +TMPL +void QUAL::RemoveAll() +{ + int i = m_size; + while(i--) + { + m_table[i] = NULL; + } + m_count = 0; +} + + +TMPL +void QUAL::RemoveAndDeleteAll() +{ + // iterate over table and delete all + int i = m_size; + T * node, * next; + while(i--) + { + node = m_table[i]; + while(node) + { + next = node->NQUAL::m_next; + delete node; + node = next; + } + m_table[i] = NULL; + } + m_count = 0; +} + + +TMPL +T * QUAL::Insert(T * a_node) +{ + gmuint slot = HASHER::Hash(a_node->GetKey()) & (m_size - 1); + T ** node = &m_table[slot]; + + while(*node) + { + int compare = HASHER::Compare(a_node->GetKey(), (*node)->GetKey()); + if(compare == 0) return (*node); + else if(compare < 0) break; + node = &((*node)->NQUAL::m_next); + } + + a_node->NQUAL::m_next = *node; + *node = a_node; + ++m_count; + return NULL; +} + + +TMPL +T * QUAL::Remove(T * a_node) +{ + gmuint slot = HASHER::Hash(a_node->GetKey()) & (m_size - 1); + T ** node = &m_table[slot]; + + while(*node) + { + if(a_node == *node) + { + *node = a_node->NQUAL::m_next; + --m_count; + return a_node; + } + node = &((*node)->NQUAL::m_next); + } + return NULL; +} + + +TMPL +T * QUAL::Remove(Iterator & a_it) +{ + T * node = a_it.Resolve(); + if(node) + { + a_it.Inc(); + return Remove(node); + } + return NULL; +} + + + +TMPL +T * QUAL::RemoveKey(const KEY &a_key) +{ + gmuint slot = HASHER::Hash(a_key) & (m_size - 1); + T ** node = &m_table[slot]; + T * found; + + while(*node) + { + int compare = HASHER::Compare((*node)->GetKey(), a_key); + if(compare == 0) + { + --m_count; + found = *node; + *node = found->NQUAL::m_next; + return (found); + } + else if(compare > 0) + { + return NULL; + } + node = &((*node)->NQUAL::m_next); + } + return NULL; +} + + +TMPL +T * QUAL::Find(const KEY &a_key) +{ + gmuint slot = HASHER::Hash(a_key) & (m_size - 1); + T * node = m_table[slot]; + + while(node) + { + int compare = HASHER::Compare(static_cast(node)->GetKey(), a_key); + if(compare == 0) + { + return node; + } + else if(compare > 0) + { + return NULL; + } + node = node->NQUAL::m_next; + } + return NULL; +} + +#undef TMPL +#undef QUAL +#undef NQUAL + +#endif // _GMHASH_H_ diff --git a/vscript/languages/gm/src/gm/gmIncGC.cpp b/vscript/languages/gm/src/gm/gmIncGC.cpp new file mode 100644 index 00000000..2a48861b --- /dev/null +++ b/vscript/languages/gm/src/gm/gmIncGC.cpp @@ -0,0 +1,838 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmIncGC.h" + +// Must be last header +#include "memdbgon.h" + +// NOTES: + +// o Q: What about when we turn GC off manually to prevent new objects from disappearing ? +// A: This can't happen with allocate black AS LONG AS the collect is not called during processing, only at yield. +// Still, would be nice to put this functionality in for non-game use. +// + +// How to make new types compatible with GC. +// +// 1) Implement the following user type callbacks: +// typedef void (GM_CDECL *gmGCDestructCallback)(gmMachine * a_machine, gmUserObject* a_object); +// typedef bool (GM_CDECL *gmGCTraceCallback)(gmMachine * a_machine, gmUserObject* a_object, gmGarbageCollector* a_gc, const int a_workLeftToGo, int& a_workDone); +// +// o The Destruct function merely destructs and frees the user object. (Same as it used to.) +// +// o The Trace function calls gc->GetNextObject(obj) where obj is each gmObject* at that level. +// You should increment a_workDone for each call and once extra (so min value should be +1). +// The Trace has the potential to be re-called for multiple increments, but this functionality is not necessary and has not been tested. +// Always return true when finished tracing. Returning false signals that you are not finished and it should be re-called. +// +// 2) If you make a table or array type class that contains variables that could be gmObjects, +// call gc->WriteBarrier(obj) where obj is the old gmObject about to be overwritten in a SetInd or SetDot call etc. +// +// Note that permanant strings are stored in a separate list so they are ignored by the GC. + +////////////////////////////////////////////////// +// gmGCColorSet +////////////////////////////////////////////////// + +gmGCColorSet::gmGCColorSet() +{ + Init(NULL); +} + + +gmGCColorSet::~gmGCColorSet() +{ +} + + +void gmGCColorSet::Init(gmGarbageCollector* a_gc) +{ + m_gc = a_gc; + + // Note that only the Scan and Free markers actually move + // + // | GRAY BLACK FREE | WHITE | + // ^ ^ ^ ^ ^ + // G S F W T + // + m_gray = &m_headObject; + m_white = &m_separatorObject; + m_free = m_white; + m_scan = m_free; + m_tail = &m_tailObject; + + m_tailObject.SetPrev(&m_separatorObject); + m_tailObject.SetNext(NULL); + + m_separatorObject.SetPrev(&m_headObject); + m_separatorObject.SetNext(&m_tailObject); + + m_headObject.SetPrev(NULL); + m_headObject.SetNext(&m_separatorObject); + + // Make persistList into a list node + m_persistList.SetNext(&m_persistList); + m_persistList.SetPrev(&m_persistList); + +#if GM_GC_STATS + m_numAllocated = 0; +#endif //GM_GC_STATS +} + + +#if GM_GC_DEBUG +bool gmGCColorSet::VerifyIntegrity() +{ + // Scan through list make sure all pointers are in valid positions and all objects are colored correctly + gmGCObjBase* curObj = m_gray->GetNext(); + int curCol = GM_GC_DEBUG_COL_GRAY; + while(curObj != m_tail) + { + if(curObj == m_scan) + { + curCol = GM_GC_DEBUG_COL_BLACK; + } + if(curObj == m_free) + { + curCol = GM_GC_DEBUG_COL_FREE; + } + if(curObj == m_white) + { + curCol = GM_GC_DEBUG_COL_WHITE; + } + if(curObj != &m_separatorObject) + { + GM_ASSERT(curObj->m_curPosColor == curCol); + } + + curObj = curObj->GetNext(); + } + + return true; +} +#endif //GM_GC_DEBUG + + +void gmGCColorSet::DestructPersistantObjects() +{ + int count=0; + + gmGCObjBase* curObj = m_persistList.GetNext(); + while(curObj != &m_persistList) + { + gmGCObjBase* objToDestruct = curObj; + curObj = curObj->GetNext(); + + objToDestruct->Destruct(m_gc->GetVM()); + ++count; + } + + // Reset persist list (Make persistList into a list node) + m_persistList.SetNext(&m_persistList); + m_persistList.SetPrev(&m_persistList); +} + + +int gmGCColorSet::FollowPointers(int a_maxBytesToTrace) +{ + int workDone = 0; + + if(m_gc->GetTraceState().m_object->Trace(m_gc->GetVM(), m_gc, a_maxBytesToTrace, workDone)) + { + m_gc->GetTraceState().m_done = true; + } + + return workDone; +} + + +bool gmGCColorSet::BlackenNextGray(int& a_workDone, int a_workLeftToGo) +{ + if(m_gc->GetTraceState().m_done == true) + { + if(m_scan->GetPrev() == m_gray) // No grays to blacken. + { + a_workDone = 0; + return false; + } + else + { + m_scan = m_scan->GetPrev(); + m_gc->GetTraceState().m_object = m_scan; + +#if GM_GC_DEBUG + GM_ASSERT(m_scan->m_curPosColor == GM_GC_DEBUG_COL_GRAY); + m_scan->m_curPosColor = GM_GC_DEBUG_COL_BLACK; +#endif //GM_GC_DEBUG + + a_workDone = FollowPointers(a_workLeftToGo); + + return true; // Gray was blackened + } + } + else + { + // Resume previously interrupted scanning of an object + a_workDone = FollowPointers(a_workLeftToGo); + return true; + } +} + + +void gmGCColorSet::GrayThisObject(gmGCObjBase* a_obj) +{ + gmGCObjBase* objPrev = a_obj->GetPrev(); + gmGCObjBase* objNext = a_obj->GetNext(); + + // This routine should never get called with a shaded object + GM_ASSERT(!m_gc->IsShaded(a_obj)); + +#if GM_GC_DEBUG + GM_ASSERT(a_obj->m_curPosColor == GM_GC_DEBUG_COL_WHITE); + a_obj->m_curPosColor = GM_GC_DEBUG_COL_GRAY; +#endif //GM_GC_DEBUG + + // Set object`s color to shaded first. + a_obj->SetColor(m_gc->GetCurShadeColor()); + + // The object must be shaded + GM_ASSERT(m_gc->IsShaded(a_obj)); + + // Splice the object out of the white list + // This can be done unconditionally as no set pointers can point to any object in this set. + objPrev->SetNext(objNext); + objNext->SetPrev(objPrev); + + // Put the object into the correct place in the gray list + +#if DEPTH_FIRST + // Put the gray object at the head of the gray list. + a_obj->SetPrev(m_scan->GetPrev()); + a_obj->SetNext(m_scan); + m_scan->GetPrev()->SetNext(a_obj); + m_scan->SetPrev(a_obj); +#else // BREADTH_FIRST + // Put the gray object at the tail of the gray list. + a_obj->SetPrev(m_gray); + a_obj->SetNext(m_gray->GetNext()); + m_gray->GetNext()->SetPrev(a_obj); + m_gray->SetNext(a_obj); +#endif // BREADTH_FIRST + +#if GM_GC_DEBUG + // Slow, paranoid check + VerifyIntegrity(); +#endif //GM_GC_DEBUG +} + + +void gmGCColorSet::Revive(gmGCObjBase* a_obj) +{ + // NOTE: Once objects are in the free list, we can't trust the color mark, + // it may have been set either side of the flip. + // We should only revive 'free', but we can't simply tell where in the list the object is. + + // Always mark black, this is only done for strings, and we are logically re-allocating the dead object + +#if GM_GC_DEBUG + a_obj->m_curPosColor = GM_GC_DEBUG_COL_BLACK; // Blacken as if re-allocated +#endif //GM_GC_DEBUG + + // Set object`s color to shaded first. + a_obj->SetColor(m_gc->GetCurShadeColor()); + + // Fix scan (NOTE: If scan == obj, obj must already be black, so could skip rest of this function) + if( m_scan == a_obj ) + { + m_scan = m_scan->GetNext(); // Not Prev as scan should be the start of black inclusive + } + // We don't care if (m_gc->GetTraceState().m_object == a_obj ) as this is Done and write only, and can only be string, not potentially a resumable object. +#if GM_GC_DEBUG + if( m_gc->GetTraceState().m_object == a_obj ) + { + GM_ASSERT( m_gc->GetTraceState().m_done ); + } +#endif // GM_GC_DEBUG + + // Fix sentinels + if( m_free == a_obj ) + { + m_free = m_free->GetNext(); + } + + // Splice the object out of the free/white list (Or anywhere in this case) + gmGCObjBase* objPrev = a_obj->GetPrev(); + gmGCObjBase* objNext = a_obj->GetNext(); + objPrev->SetNext(objNext); + objNext->SetPrev(objPrev); + + // Insert at the end of black list + a_obj->SetNext(m_free); // Next is first Free + a_obj->SetPrev(m_free->GetPrev()); // Prev is last Black + m_free->GetPrev()->SetNext(a_obj); // Last Black next is now this + m_free->SetPrev(a_obj); // Free prev is now this + + // If there were no blacks, move scan forward to prevent scanning this new black + if( m_scan == m_free ) + { + m_scan = a_obj; + } +} + + +void gmGCColorSet::ReclaimGarbage() +{ + GM_ASSERT(m_scan->GetPrev() == m_gray); + +#if GM_GC_DEBUG + { + // Traverse the newly found garbage objects just to make sure there + // aren't any live objects in there. Used for debugging only. + for(gmGCObjBase* temp = m_white->GetNext(); + temp != m_tail; + temp = temp->GetNext()) + { + GM_ASSERT(!m_gc->IsShaded(temp)); + } + } +#endif + + if (m_white->GetNext() != m_tail) // There are garbage objects + { +#if GM_GC_DEBUG + //flag white->tail as white? + for(gmGCObjBase* temp = m_white->GetNext(); + temp != m_tail; + temp = temp->GetNext()) + { + GM_ASSERT(temp->m_curPosColor == GM_GC_DEBUG_COL_WHITE); + temp->m_curPosColor = GM_GC_DEBUG_COL_FREE; + } +#endif //GM_GC_DEBUG + + bool fixScan = false; + if( m_scan == m_free ) // There are no black objects + { + fixScan = true; + } + + // Reclaim the garbage. + // Insert old White->Tail at start of Free (Free may == White) + gmGCObjBase* firstFree = m_white->GetNext(); + + firstFree->SetPrev(m_free->GetPrev()); + m_free->GetPrev()->SetNext(firstFree); + + m_tail->GetPrev()->SetNext(m_free); + m_free->SetPrev(m_tail->GetPrev()); + + m_free = firstFree; + + if( fixScan ) + { + m_scan = m_free; + } + + m_white->SetNext(m_tail); + m_tail->SetPrev(m_white); + } + + // Whiten the live objects. + if (m_scan != m_free) // There are live (black) objects + { + +#if GM_GC_DEBUG + //flag scan->free as white? + for(gmGCObjBase* temp = m_scan;//m_scan->GetNext(); + temp != m_free; + temp = temp->GetNext()) + { + GM_ASSERT(temp->m_curPosColor == GM_GC_DEBUG_COL_BLACK); + temp->m_curPosColor = GM_GC_DEBUG_COL_WHITE; + } +#endif //GM_GC_DEBUG + + GM_ASSERT(m_white->GetNext() == m_tail); + GM_ASSERT(m_tail->GetPrev() == m_white); + + m_scan->GetPrev()->SetNext(m_free); + m_free->GetPrev()->SetNext(m_tail); + m_tail->SetPrev(m_free->GetPrev()); + m_free->SetPrev(m_scan->GetPrev()); + m_scan->SetPrev(m_white); + m_white->SetNext(m_scan); + m_scan = m_free; + } + + GM_ASSERT(m_gray->GetNext() == m_scan); + +#if GM_GC_DEBUG + { + int count = 0; + for(gmGCObjBase* temp = m_free; temp != m_white; temp = temp->GetNext()) + { + ++count; + } + } +#endif +} + + +int gmGCColorSet::DestructSomeFreeObjects(int a_maxToDestruct) +{ + int numDestructed = 0; + // Go through the free list (perhaps over multiple installments in future) and call Destruct() on them. + if(m_free != m_white) + { + gmGCObjBase* beforeFree = m_free->GetPrev(); // Save previous node so we can relink after removing some + bool fixScan = false; + if(m_scan == m_free) // Will need to fix the scan ptr later if this is so. + { + fixScan = true; + } + + while(m_free != m_white) + { + gmGCObjBase* objToRecycle = m_free; + m_free = m_free->GetNext(); + +#if GM_GC_DEBUG + //GM_ASSERT(objToRecycle->m_curPosColor == GM_GC_DEBUG_COL_WHITE); + GM_ASSERT(objToRecycle->m_curPosColor == GM_GC_DEBUG_COL_FREE); + objToRecycle->m_curPosColor = GM_GC_DEBUG_COL_INVALID; +#endif //GM_GC_DEBUG + +#if GM_GC_KEEP_PERSISTANT_SEPARATE + GM_ASSERT(!objToRecycle->GetPersist()); +#endif //GM_GC_KEEP_PERSISTANT_SEPARATE +#if GM_GC_STATS + --m_numAllocated; +#endif //GM_GC_STATS + + objToRecycle->Destruct(m_gc->GetVM()); + ++numDestructed; + --a_maxToDestruct; + if(a_maxToDestruct <= 0) + { + // Relink since we removed elements + beforeFree->SetNext(m_free); + m_free->SetPrev(beforeFree); + if(fixScan) + { + m_scan = m_free; + } + return numDestructed; // Work is done for now. + } + } + // Relink since we removed elements + beforeFree->SetNext(m_free); + m_free->SetPrev(beforeFree); + if(fixScan) + { + m_scan = m_free; + } + } + return numDestructed; +} + + +void gmGCColorSet::Allocate(gmGCObjBase* a_obj) +{ +#if GM_GC_STATS + ++m_numAllocated; +#endif //GM_GC_STATS + + a_obj->SetPersist(false); + + a_obj->SetColor(m_gc->GetCurShadeColor()); + +#if GM_GC_DEBUG + GM_ASSERT(a_obj->m_curPosColor == GM_GC_DEBUG_COL_INVALID); + a_obj->m_curPosColor = GM_GC_DEBUG_COL_BLACK; +#endif //GM_GC_DEBUG + + //Insert at the end of black list + a_obj->SetNext(m_free); //Next is first Free + a_obj->SetPrev(m_free->GetPrev()); //Prev is last Black + m_free->GetPrev()->SetNext(a_obj); //Last Black next is now this + m_free->SetPrev(a_obj); //Free prev is now this + + //If there were no blacks, move scan forward to prevent scanning this new black + if(m_scan == m_free) + { + m_scan = a_obj; + } +} + + +void gmGCColorSet::DestructAll() +{ + int count = 0; + + DestructPersistantObjects(); + + // Black and Gray + gmGCObjBase* curGrayOrBlack = m_gray->GetNext(); + while(curGrayOrBlack != m_free) + { + gmGCObjBase* objToRecycle = curGrayOrBlack; + curGrayOrBlack = curGrayOrBlack->GetNext(); +#if GM_GC_KEEP_PERSISTANT_SEPARATE + GM_ASSERT(!objToRecycle->GetPersist()); +#endif //GM_GC_KEEP_PERSISTANT_SEPARATE + objToRecycle->Destruct(m_gc->GetVM()); +#if GM_GC_STATS + --m_numAllocated; +#endif //GM_GC_STATS + ++count; + } + + // Whites + gmGCObjBase* curWhite = m_white->GetNext(); + while(curWhite != m_tail) + { + gmGCObjBase* objToRecycle = curWhite; + curWhite = curWhite->GetNext(); + +#if GM_GC_KEEP_PERSISTANT_SEPARATE + GM_ASSERT(!objToRecycle->GetPersist()); +#endif //GM_GC_KEEP_PERSISTANT_SEPARATE + objToRecycle->Destruct(m_gc->GetVM()); +#if GM_GC_STATS + --m_numAllocated; +#endif //GM_GC_STATS + ++count; + } + + // Free list + gmGCObjBase* curFree = m_free; + while(curFree != m_white) + { + gmGCObjBase* objToRecycle = curFree; + curFree = curFree->GetNext(); + { +#if GM_GC_KEEP_PERSISTANT_SEPARATE + GM_ASSERT(!objToRecycle->GetPersist()); +#endif //GM_GC_KEEP_PERSISTANT_SEPARATE + objToRecycle->Destruct(m_gc->GetVM()); +#if GM_GC_STATS + --m_numAllocated; +#endif //GM_GC_STATS + ++count; + } + } + + Init(m_gc); +} + +////////////////////////////////////////////////// +// gmGarbageCollector +////////////////////////////////////////////////// + +gmGarbageCollector::gmGarbageCollector() +{ + Init(NULL, NULL); +} + + +gmGarbageCollector::~gmGarbageCollector() +{ +} + + +void gmGarbageCollector::Init(gmGCScanRootsCallBack a_scanRootsCallback, gmMachine* a_gmMachine) +{ + m_curShadeColor = 0; // Another color is !0 + m_workPerIncrement = GM_GC_DEFAULT_WORK_INCREMENT; + m_maxObjsToDestructPerIncrement = GM_GC_DEFAULT_DESTRUCT_INCREMENT; + m_workLeftToGo = 0; + m_fullThrottle = false; + m_gcTurnedOff = true; // Start in OFF state, machine will turn on when needed. + m_firstCollectionIncrement = true; + m_doneTracing = false; + m_colorSet.Init(this); + m_traceState.Reset(); + m_flipCallback = NULL; + m_scanRootsCallback = a_scanRootsCallback; + m_gmMachine = a_gmMachine; +} + + +bool gmGarbageCollector::BlackenGrays() +{ + int workDone; + + while(m_colorSet.AnyGrays()) + { + // gmGCColorSet::BlackenNextGray returns 1 if there was a gray to + // blacken (even if it couldn't finish blackening it), and a 0 otherwise. + + workDone = m_workLeftToGo; + + while(m_colorSet.BlackenNextGray(workDone, m_workLeftToGo)) + { + m_workLeftToGo -= workDone; + if (m_workLeftToGo <= 0) + { + // Quit early + return true; // We have completed one increment of work + } + } + }; + + return false; +} + + +bool gmGarbageCollector::Collect() +{ + if(m_fullThrottle) + { + m_workLeftToGo = GM_MAX_INT32; + } + else + { + m_workLeftToGo = m_workPerIncrement; + } + + m_doneTracing = false; + + if(m_firstCollectionIncrement) + { + // Scan each root object and gray it + GM_ASSERT(m_scanRootsCallback); + m_scanRootsCallback(m_gmMachine, this); + + m_firstCollectionIncrement = false; + return false; + } + + // If any grays exist, scan them first + if(m_colorSet.AnyGrays()) + { + if(BlackenGrays()) // Returns 0 if no more grays, and 1 if done with an increment of collection. + { + return false; // Out of time, so exit function + } + } + + m_doneTracing = true; + + // Let the collect continue until garbage memory has been reclaimed + // This could be done as an external phase + if(ReclaimSomeFreeObjects()) + { + return false; + } + +#if GM_GC_TURN_OFF_ABLE + // Turn off gc until almost out of memory. + // Can only do when allocating black. + m_gcTurnedOff = true; +#else //GM_GC_TURN_OFF_ABLE + Flip(); +#endif //GM_GC_TURN_OFF_ABLE + + return true; +} + + +void gmGarbageCollector::Flip() +{ + m_firstCollectionIncrement = true; + + if(m_flipCallback) + { + m_flipCallback(); + } + +#if GM_GC_TURN_OFF_ABLE + // The garbage collector can only be turned off if we are allocating black. + m_gcTurnedOff = false; // Turn the garbage collector back on. +#endif //GM_GC_TURN_OFF_ABLE + + m_colorSet.ReclaimGarbage(); + + ToggleCurShadeColor(); +} + + +// This function is called when there are no free objects in the colorset. +// If the gc is turned off, it calls flip to reclaim any garbage objects +// that have been found by the garbage collector. +void gmGarbageCollector::ReclaimObjectsAndRestartCollection() +{ +#if GM_GC_TURN_OFF_ABLE + // The garbage collector only gets turned off if we are allocating + // black. GC is turned off after finishing tracing and before + // doing a gc flip. So if there are no free objects left, first + // flip the GC and turn white objects into free. Hopefully, this + // will provide more free objects for allocation. + + if(m_gcTurnedOff) + { + Flip(); + } +#endif //GM_GC_TURN_OFF_ABLE +} + + +/// \brief Destruct all objects. +void gmGarbageCollector::DestructAll() +{ + m_colorSet.DestructAll(); + + //Reset some of our members + m_curShadeColor = 0; + m_workPerIncrement = 100; + m_maxObjsToDestructPerIncrement = 100; + m_workLeftToGo = 0; + m_doneTracing = false; + m_fullThrottle = false; + m_firstCollectionIncrement = true; + m_traceState.Reset(); +} + + +void gmGarbageCollector::FullCollect() +{ + m_fullThrottle = true; + + if(IsOff()) // If GC is off + { + ReclaimObjectsAndRestartCollection(); // Do flip and turn it back on + } + + while(!Collect()) + { + // Do the collect phase + } + ReclaimObjectsAndRestartCollection(); // Do flip and turn it back on + + // Collect a second time to catch floating black objects + while(!Collect()) + { + // Do the collect phase + } + ReclaimObjectsAndRestartCollection(); // Do flip and turn it back on + + // NOTE: The GC is now restarted and in an 'On' state, meaning it will now collect again from the machine. + // This behavior may not be desirable, so this function really needs more analysis to determine the + // optimum sequence for a full collect with minimal redundancy. + + // Free memory of garbage objects + while(ReclaimSomeFreeObjects()) + { + // Reclaim all garbage + } + m_fullThrottle = false; +} + + + +////////////////////////////////////////////////// +// Helper functions for VM and debugger +////////////////////////////////////////////////// +#include "gmVariable.h" +#include "gmFunctionObject.h" + +const void* gmGCColorSet::GetInstructionAtBreakPoint(gmuint32 a_sourceId, int a_line) +{ + gmGCObjBase* cur; + + // Search Gray to Free + cur = m_gray->GetNext(); + while(cur != m_free) + { + gmObject* object = (gmObject*)cur; + if(object->GetType() == GM_FUNCTION) + { + gmFunctionObject * function = (gmFunctionObject *) object; + if(function->GetSourceId() == a_sourceId) + { + const void * instr = function->GetInstructionAtLine(a_line); + if(instr) + { + return instr; + } + } + } + cur = cur->GetNext(); + } + + // Search White + cur = m_white->GetNext(); + while(cur != m_tail) + { + gmObject* object = (gmObject*)cur; + if(object->GetType() == GM_FUNCTION) + { + gmFunctionObject * function = (gmFunctionObject *) object; + if(function->GetSourceId() == a_sourceId) + { + const void * instr = function->GetInstructionAtLine(a_line); + if(instr) + { + return instr; + } + } + } + cur = cur->GetNext(); + } + + return NULL; +} + + +gmObject* gmGCColorSet::CheckReference(gmptr a_ref) +{ + gmGCObjBase* cur; + + // Search Gray to Free + cur = m_gray->GetNext(); + while(cur != m_free) + { + gmObject* object = (gmObject*)cur; + if((gmptr)object == a_ref) + { + return object; + } + cur = cur->GetNext(); + } + + // Search White + cur = m_white->GetNext(); + while(cur != m_tail) + { + gmObject* object = (gmObject*)cur; + if((gmptr)object == a_ref) + { + return object; + } + cur = cur->GetNext(); + } + + // Search Persistant list + cur = m_persistList.GetNext(); + while(cur != &m_persistList) + { + gmObject* object = (gmObject*)cur; + if((gmptr)object == a_ref) + { + return object; + } + cur = cur->GetNext(); + } + + return NULL; +} diff --git a/vscript/languages/gm/src/gm/gmIncGC.h b/vscript/languages/gm/src/gm/gmIncGC.h new file mode 100644 index 00000000..e00e6240 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmIncGC.h @@ -0,0 +1,436 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMINCGC_H_ +#define _GMINCGC_H_ + +#include "gmConfig.h" + +// Configuration options +#define GM_GC_TURN_OFF_ABLE 1 // Let GC turn off after completion, can be turned back on when memory low +#define GM_GC_KEEP_PERSISTANT_SEPARATE 1 // Keep persistant object in separate list for efficiency +#define DEPTH_FIRST 1 // Depth first or bredth first tracing +#ifdef GM_DEBUG_BUILD + #define GM_GC_STATS 1 // Some stats +#else //GM_DEBUG_BUILD + #define GM_GC_STATS 0 +#endif //GM_DEBUG_BUILD + +#define GM_GC_DEBUG 0 // GC Debugging paranoid check code. Only set to 1 when debugging the GC routines. + +// Fwd decls +class gmgmGCObjBase; +class gmGarbageCollector; +class gmMachine; +class gmObject; + +typedef void (GM_CDECL *GCFlipCallBack)(); +typedef void (GM_CDECL *gmGCScanRootsCallBack)(gmMachine* a_machine, gmGarbageCollector* a_gc); + + +// Incremental garbage collection method: +// +// A tricolor marking scheme is used with new objects allocated Black. +// A write barrier is used to maintain integrity of the list. +// The list looks like: +// +// | GRAY BLACK FREE | WHITE | +// ^ ^ ^ ^ ^ +// G S F W T +// +// Legend: +// G Gray (head) pointer +// S Scan pointer +// F Free pointer +// W White pointer +// T Tail pointer +// | List sentinels +// +// Note that only the Scan and Free markers actually move +// The objects are classified between the pointer pairs as follows: +// +// GRAY: Gray (exclusive) to Scan (exclusive) +// BLACK: Scan (inclusive) to Free (exclusive) +// FREE: Free (inclusive) to White (exclusive) +// WHITE: White (exclusive) to Tail (exclusive) +// + +////////////////////////////////////////////////// +// gmgmGCObjBase +////////////////////////////////////////////////// + +#if GM_GC_DEBUG +enum +{ + GM_GC_DEBUG_COL_INVALID, //0 + GM_GC_DEBUG_COL_GRAY, //1 + GM_GC_DEBUG_COL_BLACK, //2 + GM_GC_DEBUG_COL_WHITE, //3 + GM_GC_DEBUG_COL_FREE, //4 +}; +#endif //GM_GC_DEBUG + +/// \brief All GC objects are dervied from this class +class gmGCObjBase +{ +public: + +#if GM_GC_DEBUG + gmGCObjBase() + { + m_curPosColor = GM_GC_DEBUG_COL_INVALID; + } + int m_curPosColor; +#endif //GM_GC_DEBUG + + inline void SetColor(int a_color) {m_color = (char)a_color;} + inline int GetColor() {return (int)m_color;} + inline gmGCObjBase* GetPrev() const {return m_prev;} + inline void SetPrev(gmGCObjBase* a_prev) {m_prev = a_prev;} + inline gmGCObjBase* GetNext() const {return m_next;} + inline void SetNext(gmGCObjBase* a_next) {m_next = a_next;} + + inline char GetPersist() {return m_persist;} + inline void SetPersist(bool a_flag) {m_persist = a_flag;} + + /// \brief Called when GC wants to free this memory + virtual void Destruct(gmMachine * a_machine) {} + + /// \brief Trace pointers this object contains to other objects. + /// It must call gmGarbageCollector::GetNextObject() on each pointer, + /// until it has traced all pointers, or used up the a_workLeftToGo count. + /// \param a_workLeftToGo Number of pointers to trace. + /// \param a_workDone, The number of pointers traced. + /// \return true if finished tracing this object, false if not finished. + virtual bool Trace(gmMachine * a_machine, gmGarbageCollector* a_gc, const int a_workLeftToGo, int& a_workDone) + { + //NOTE: Use a_gc->GetTraceState().m_context to help resume incremental tracing. + a_workDone = 1; + return true; + } + +private: + + gmGCObjBase* m_prev; ///< Point to previous object in color set + gmGCObjBase* m_next; ///< Point to next object in color set + char m_color; ///< Is gray or black flag, really only need by 1 bit + char m_persist; ///< This object is persistant + char m_pad[2]; ///< Pad to dword +}; + +////////////////////////////////////////////////// +// gmGCColorSet +////////////////////////////////////////////////// + +/// \brief Tri color managing class +class gmGCColorSet +{ +public: + + /// \brief Constructor + gmGCColorSet(); + /// \brief Destructor + virtual ~gmGCColorSet(); + + /// \brief Initialize members + void Init(gmGarbageCollector* a_gc); + + /// \brief Returns true if there are any gray objects in this size class, false otherwise. + inline bool AnyGrays(void) + { + return (m_gray->GetNext() != m_scan); + } + + int FollowPointers(int a_maxBytesToTrace); + + /// \brief Blacken the next object (at the scan pointer) in the gray set. + /// Object is blackened and its children are grayed. + /// Returns 0 when no grays are left. + bool BlackenNextGray(int& a_workDone, int a_workLeftToGo); + + /// \brief Called by GCGetNextObject() that is called by user code while tracing over a object. + inline void GrayAWhite(gmGCObjBase* a_obj); + + /// \brief Gray this object. + void GrayThisObject(gmGCObjBase* a_obj); + + /// \brief Called on a new object being allocated. + void Allocate(gmGCObjBase* a_obj); + + /// \brief This routine reclaims the garbage memory for the system. + void ReclaimGarbage(); + + /// \brief Destruct some free objects + /// \return The number of objects destructed + int DestructSomeFreeObjects(int a_maxToDestruct); + + /// \brief Destruct all objects. + void DestructAll(); + + /// \brief Make an object persistant by moving it into the persistant list. + void MakePersistant(gmGCObjBase* a_obj) + { + // Fix scan (If scan == obj, obj must already be black, as we have just allocated or revived this string) + if( m_scan == a_obj ) + { + m_scan = m_scan->GetNext(); // Not Prev as scan should be the start of black inclusive + } + // Fix sentinels + if( m_free == a_obj ) + { + m_free = m_free->GetNext(); + } + + // Unlink from current list + a_obj->GetNext()->SetPrev(a_obj->GetPrev()); + a_obj->GetPrev()->SetNext(a_obj->GetNext()); + + // Insert at start of persist list + a_obj->SetNext(m_persistList.GetNext()); + a_obj->SetPrev(&m_persistList); + + m_persistList.GetNext()->SetPrev(a_obj); + m_persistList.SetNext(a_obj); + } + + /// \brief Destruct all objects in persistant list + void DestructPersistantObjects(); + + /// \brief Revive an object before it is finalized + void Revive(gmGCObjBase* a_obj); + + /// \brief Check if reference is valid for VM + gmObject* CheckReference(gmptr a_ref); + + /// \brief Get instruction at point for VM Debugger. + const void * GetInstructionAtBreakPoint(gmuint32 a_sourceId, int a_line); + +#if GM_GC_DEBUG + bool VerifyIntegrity(); +#endif //GM_GC_DEBUG + +protected: + + gmGCObjBase* m_gray; + gmGCObjBase* m_scan; + gmGCObjBase* m_free; + gmGCObjBase* m_white; + gmGCObjBase* m_tail; + + gmGCObjBase m_tailObject; + gmGCObjBase m_headObject; + gmGCObjBase m_separatorObject; + + gmGCObjBase m_persistList; + + gmGarbageCollector* m_gc; +#if GM_GC_STATS + int m_numAllocated; +#endif //GM_GC_STATS +}; + + +////////////////////////////////////////////////// +// gmGarbageCollector +////////////////////////////////////////////////// + +struct gmGCTraceState +{ + gmGCTraceState() + { + Reset(); + } + + void Reset() + { + m_done = true; + m_object = NULL; + m_context = NULL; + } + + bool m_done; + gmGCObjBase* m_object; + void* m_context; +}; + + +/// \brief Incremental garbage collection +/// Method: Tri-Color, Non-copying, Write barrier, Root Snapshot. +class gmGarbageCollector +{ +public: + + /// \brief Constructor + gmGarbageCollector(); + + /// \brief Destructor + virtual ~gmGarbageCollector(); + + /// \brief Initialize the garbage collection system + void Init(gmGCScanRootsCallBack a_scanRootsCallback, gmMachine* a_gmMachine); + + /// \brief Perform write barrier operation on Left and/or Right side objects. + inline void WriteBarrier(gmGCObjBase* a_lObj /*, gmGCObjBase* a_rObj*/); + + /// \brief Call to start collection + /// \return true if collection completed, false if more work to do. + bool Collect(); + + /// \brief Do a full collect and don't return until done. + void FullCollect(); + + /// \brief Called during trace by client code, and by scan roots callback. + /// This grays a white object. + inline void GetNextObject(gmGCObjBase* a_obj) {m_colorSet.GrayAWhite(a_obj);} + + /// \brief Called on a new object being allocated + inline void AllocateObject(gmGCObjBase* a_obj) {m_colorSet.Allocate(a_obj);} + + /// \brief Get the current shade color since it is flipped each cycle. + inline int GetCurShadeColor() {return (m_curShadeColor);} + + /// \brief Is the object colored gray or black? + inline bool IsShaded(gmGCObjBase* a_obj) {return (a_obj->GetColor() == m_curShadeColor);} + + /// \brief if GC is turned off, reclaim garbage memory + void ReclaimObjectsAndRestartCollection(); + + /// \brief Get the trace state to resume incremental collecting + inline gmGCTraceState& GetTraceState() {return m_traceState;} + + /// \brief Set the amount of work to do per increment of collecting + inline void SetWorkPerIncrement(int a_workPerIncrement) {m_workPerIncrement = a_workPerIncrement;} + /// \brief Set the amount of objects to destruct per increment of collecting + inline void SetDestructPerIncrement(int a_destructPerIncrement) {m_maxObjsToDestructPerIncrement = a_destructPerIncrement;} + + /// \brief Get the amount of work to do per increment of collecting + inline int GetWorkPerIncrement() {return m_workPerIncrement;} + /// \brief Get the amount of objects to destruct per increment of collecting + inline int GetDestructPerIncrement() {return m_maxObjsToDestructPerIncrement;} + + /// \brief Set function to be called before flip when dead objects are reclaimed. + /// Optional, so pass NULL to disable. + inline void SetFlipCallback(GCFlipCallBack a_flipCallback) {m_flipCallback = a_flipCallback;} + + /// \brief Is collector currently turned off? + inline bool IsOff() {return m_gcTurnedOff;} + + /// \brief Destruct all objects. + void DestructAll(); + + /// \brief Reclaim some free objects. + int ReclaimSomeFreeObjects() {return m_colorSet.DestructSomeFreeObjects(m_maxObjsToDestructPerIncrement);} + + /// \brief Make an object persistant by moving it into the persistant list. + void MakeObjectPersistant(gmGCObjBase* a_obj) {m_colorSet.MakePersistant(a_obj);} + + /// \brief Get the virtual machine for language + inline gmMachine* GetVM() {return m_gmMachine;} + + /// \brief Check if reference is valid for VM + gmObject* CheckReference(gmptr a_ref) {return m_colorSet.CheckReference(a_ref);} + + /// \brief Get instruction at point for VM Debugger. + const void * GetInstructionAtBreakPoint(gmuint32 a_sourceId, int a_line) {return m_colorSet.GetInstructionAtBreakPoint(a_sourceId, a_line);} + + /// \brief Revive a dead object (only used to re-live a shared string before it is finalized) + void Revive(gmGCObjBase* a_obj) + { + if( !a_obj->GetPersist() ) + { + m_colorSet.Revive(a_obj); + } + } + +protected: + + /// \brief Has Collect() completed yet? + inline bool IsDoneTracing() {return m_doneTracing;} + + /// \brief Called by Collect() + bool BlackenGrays(); + + /// \brief Flip system and reclaim garbage. + void Flip(); + + /// \brief Toggle bit used to represent 'colored' + inline void ToggleCurShadeColor() {m_curShadeColor = !m_curShadeColor;} + + gmGCColorSet m_colorSet; ///< Tri color helper class + int m_curShadeColor; ///< Cur color used to shade this generation + int m_workPerIncrement; ///< How much work to do per increment + int m_workLeftToGo; ///< How much work left in this increment + int m_maxObjsToDestructPerIncrement; ///< How much destructing work to do this frame? + bool m_gcTurnedOff; ///< Is the GC currently turned off? + bool m_firstCollectionIncrement; ///< Using snapshot method, scan roots atomically first + bool m_fullThrottle; ///< Set to true when forcing a full collection + bool m_doneTracing; ///< Has Collect() completed yet? + gmGCTraceState m_traceState; ///< Allows trace to resume where it left off + + GCFlipCallBack m_flipCallback; ///< Called before flip, when dead objects are reclaimed. Default is NULL. + gmGCScanRootsCallBack m_scanRootsCallback; ///< Called at start of Collect() to add gray all roots. MUST be implemented. + gmMachine* m_gmMachine; ///< Virtual machine to pass around +}; + +////////////////////////////////////////////////// +// inline functions +////////////////////////////////////////////////// + +void gmGCColorSet::GrayAWhite(gmGCObjBase* a_obj) +{ +#if GM_GC_KEEP_PERSISTANT_SEPARATE + if(a_obj->GetPersist()) // Don't do anything with persistant objects + { + return; + } +#endif //GM_GC_KEEP_PERSISTANT_SEPARATE + + // If right object is not shaded, shade it + if(!m_gc->IsShaded(a_obj)) + { + GrayThisObject(a_obj); + } +} + + +void gmGarbageCollector::WriteBarrier(gmGCObjBase* a_lObj/*, gmGCObjBase* a_rObj*/) +{ + // If we are allocating black and the collector is off, do nothing + if(m_gcTurnedOff) + { + return; + } + + // We don't need to use write barrier on root objects, so check for it if we can. + // if(IsRoot(a_lObj)) { return; } + + // Note: Left side is logically the old right side + + // This is a snapshot write barrier. There is not old pointer to overwrite, so do nothing. + if(!a_lObj) + { + return; + } + +#if GM_GC_KEEP_PERSISTANT_SEPARATE + if(a_lObj->GetPersist()) // Don't do anything with persistant objects + { + return; + } +#endif //GM_GC_KEEP_PERSISTANT_SEPARATE + + if(!IsShaded(a_lObj)) + { + m_colorSet.GrayThisObject(a_lObj); + } +} + +#endif //_GMINCGC_H_ diff --git a/vscript/languages/gm/src/gm/gmIterator.h b/vscript/languages/gm/src/gm/gmIterator.h new file mode 100644 index 00000000..3c809728 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmIterator.h @@ -0,0 +1,51 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMITERATOR_H_ +#define _GMITERATOR_H_ + +// +// Intrusive Container Iterator +// + +// +// Iterator must declare the following functions +// +// void Inc() +// void Dec() +// T* Resolve() +// const T* Resolve() const +// bool IsValid() const +// + +#define GM_INCLUDE_ITERATOR_KERNEL(T) \ +inline void operator++() { Inc(); } \ +inline void operator--() { Dec(); } \ +inline void operator++(int) { Inc(); } \ +inline void operator--(int) { Dec(); } \ +inline T& operator*(void) { return *Resolve(); } \ +inline const T& operator*(void) const { return *Resolve(); } \ +inline T* operator->(void) { return Resolve(); } \ +inline const T* operator->(void) const { return Resolve(); } \ + \ +inline operator bool(void) { return IsValid(); } \ +inline operator bool(void) const { return IsValid(); } \ +inline bool operator !(void) { return !IsValid(); } \ +inline bool operator !(void) const { return !IsValid(); } \ + \ +private: \ +inline operator unsigned int(void) { return 0xDEADBEEF; } \ +inline operator int(void) { return 0xDEADBEEF; } \ +inline operator unsigned int(void) const { return 0xDEADBEEF; } \ +inline operator int(void) const { return 0xDEADBEEF; } \ +public: + +#endif // _GMITERATOR_H_ diff --git a/vscript/languages/gm/src/gm/gmLibHooks.cpp b/vscript/languages/gm/src/gm/gmLibHooks.cpp new file mode 100644 index 00000000..ecc17759 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmLibHooks.cpp @@ -0,0 +1,447 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmLibHooks.h" +#include "gmMachine.h" +#include "gmFunctionObject.h" +#include "gmStringObject.h" + +// Must be last header +#include "memdbgon.h" + + +#define ID_func GM_MAKE_ID32('f','u','n','c') +#define ID_gml0 GM_MAKE_ID32('g','m','l','0') + + +gmLibHooks::gmLibHooks(gmStream &a_stream, const char * a_source) : + m_allocator(1, GMCODETREE_CHAINSIZE) +{ + m_stream = &a_stream; + m_source = a_source; + m_swapEndian = m_stream->GetSwapEndianOnWrite(); +} + + +gmLibHooks::~gmLibHooks() +{ +} + + +bool gmLibHooks::Begin(bool a_debug) +{ + m_debug = a_debug; + m_symbolOffset = 0; + m_functionId = 0; + m_functionStream.Reset(); + m_functionStream.SetSwapEndianOnWrite(m_swapEndian); + return true; +} + + +bool gmLibHooks::AddFunction(gmFunctionInfo &a_info) +{ + // write the function into the stream + m_functionStream << (gmuint32) ID_func; + m_functionStream << (gmuint32) a_info.m_id; + m_functionStream << (gmuint32) ((a_info.m_root) ? 1 : 0); + m_functionStream << (gmuint32) a_info.m_numParams; + m_functionStream << (gmuint32) a_info.m_numLocals; + m_functionStream << (gmuint32) a_info.m_maxStackSize; + m_functionStream << (gmuint32) a_info.m_byteCodeLength; + m_functionStream.Write(a_info.m_byteCode, a_info.m_byteCodeLength); + + if(m_debug) + { + int numSymbols = a_info.m_numLocals + a_info.m_numParams, i; + + // debug name + m_functionStream << (gmuint32) GetSymbolId(a_info.m_debugName); + + // line info + m_functionStream << (gmuint32) a_info.m_lineInfoCount; + for(i = 0; i < a_info.m_lineInfoCount; ++i) + { + m_functionStream << (gmuint32) a_info.m_lineInfo[i].m_address; + m_functionStream << (gmuint32) a_info.m_lineInfo[i].m_lineNumber; + } + + // symbol info + for(i = 0; i < numSymbols; ++i) + { + if(a_info.m_symbols) + { + m_functionStream << (gmuint32) GetSymbolId(a_info.m_symbols[i]); + } + else + { + m_functionStream << (gmuint32) (~0); + } + } + } + return true; +} + + +bool gmLibHooks::End(int a_errors) +{ + if(a_errors == 0) + { + gmuint32 offsets[3] = {0}, offsetPos; + + gmuint32 t = ID_gml0, t1 = 0; + *m_stream << t; + t = (m_debug) ? 1 : 0; + *m_stream << t; + + offsetPos = m_stream->Tell(); + *m_stream << offsets[0] << offsets[1] << offsets[2]; + + // write the string table + offsets[0] = m_stream->Tell(); + t = m_symbolOffset; + *m_stream << t; + USymbol * symbol = m_symbols.GetLast(); + while(m_symbols.IsValid(symbol)) + { + m_stream->Write(symbol->m_string, strlen(symbol->m_string) + 1); + symbol = m_symbols.GetPrev(symbol); + } + GM_ASSERT(m_stream->Tell() == m_symbolOffset + offsets[0] + sizeof(gmuint32)); + + // write the source code + if(m_debug && m_source) + { + offsets[1] = m_stream->Tell(); + t = strlen(m_source) + 1; + t1 = 0; + *m_stream << t << t1; + m_stream->Write(m_source, t); + } + else + { + offsets[1] = 0; + } + + // write the functions + offsets[2] = m_stream->Tell(); + t = m_functionId; + *m_stream << t; + m_stream->Write(m_functionStream.GetData(), m_functionStream.GetSize()); + m_functionStream.ResetAndFreeMemory(); + + // write the offsets + m_stream->Seek(offsetPos); + *m_stream << offsets[0] << offsets[1] << offsets[2]; + + return true; + } + return false; +} + + +gmptr gmLibHooks::GetFunctionId() +{ + return m_functionId++; +} + + +gmptr gmLibHooks::GetSymbolId(const char * a_symbol) +{ + if(a_symbol == NULL) a_symbol = ""; + + // see if we already have sybmol + USymbol * symbol = m_symbols.GetFirst(); + while(m_symbols.IsValid(symbol)) + { + if(strcmp(symbol->m_string, a_symbol) == 0) + { + return symbol->m_offset; + } + symbol = m_symbols.GetNext(symbol); + } + + // add a new symbol + unsigned int len = strlen(a_symbol) + 1; + symbol = (USymbol *) m_allocator.AllocBytes(sizeof(USymbol), GM_DEFAULT_ALLOC_ALIGNMENT); + symbol->m_string = (char *) m_allocator.AllocBytes(len, GM_DEFAULT_ALLOC_ALIGNMENT); + memcpy(symbol->m_string, a_symbol, len); + symbol->m_offset = m_symbolOffset; + m_symbolOffset += len; + m_symbols.InsertFirst(symbol); + return symbol->m_offset; +} + + +gmptr gmLibHooks::GetStringId(const char * a_string) +{ + return GetSymbolId(a_string); +} + + +// +// +// Library Loading +// +// + +struct gmlHeader +{ + gmuint32 m_id; + gmuint32 m_flags; + gmuint32 m_stOffset; + gmuint32 m_scOffset; + gmuint32 m_fnOffset; +}; + +struct gmlStrings +{ + gmuint32 m_size; +}; + +struct gmlLineInfo +{ + gmuint32 m_byteCodeAddress; + gmuint32 m_lineNumber; +}; + +struct gmlSource +{ + gmuint32 m_size; + gmuint32 m_flags; +}; + +struct gmlFunction +{ + gmuint32 m_func; + gmuint32 m_id; + gmuint32 m_flags; + gmuint32 m_numParams; + gmuint32 m_numLocals; + gmuint32 m_maxStackSize; + gmuint32 m_byteCodeLen; +}; + + +gmFunctionObject * gmLibHooks::BindLib(gmMachine &a_machine, gmStream &a_stream, const char * a_filename) +{ + gmlHeader header; + gmlStrings strings; + gmlSource source; + gmlFunction function; + gmFunctionObject * functionObject = NULL; + gmFunctionObject ** functionObjects = NULL; + bool error = true, debug = false; + char * stringTable = NULL; + char * sourceCode = NULL; + char * byteCode = NULL; + unsigned int i, j; + gmuint32 numFunctions = 0; + gmuint32 sourceCodeId = 0; + gmuint32 scratchSize = 2048; + gmuint8 * scratch = GM_NEW( gmuint8[scratchSize] ); + + // Turn garbage collection off. + bool gc = a_machine.IsGCEnabled(); + a_machine.EnableGC(false); + + // Ensure stream is read from the start + a_stream.Seek( 0 ); + + // Load the gmlib header + if((a_stream.Read(&header, sizeof(header)) != sizeof(header)) || header.m_id != ID_gml0) { goto done; } + debug = (header.m_flags & 1); + + // Load the string table + a_stream.Seek(header.m_stOffset); + if(a_stream.Read(&strings, sizeof(strings)) != sizeof(strings)) { goto done; } + stringTable = GM_NEW( char[strings.m_size] ); + if(a_stream.Read(stringTable, strings.m_size) != strings.m_size) { goto done; } + + // Read the source code + if(header.m_scOffset && a_machine.GetDebugMode()) + { + a_stream.Seek(header.m_scOffset); + if(a_stream.Read(&source, sizeof(source)) != sizeof(source)) { goto done; } + sourceCode = GM_NEW( char[source.m_size] ); + if(a_stream.Read(sourceCode, source.m_size) != source.m_size) { goto done; } + sourceCodeId = a_machine.AddSourceCode(sourceCode, a_filename); + delete[] sourceCode; + sourceCode = NULL; + } + + // Read in the functions + a_stream.Seek(header.m_fnOffset); + if(a_stream.Read(&numFunctions, sizeof(numFunctions)) != sizeof(numFunctions)) { goto done; } + + // Allocate n function objects. + functionObjects = GM_NEW( gmFunctionObject *[numFunctions] ); + for(i = 0; i < numFunctions; ++i) + { + functionObjects[i] = a_machine.AllocFunctionObject(); + } + + // Load each function + for(i = 0; i < numFunctions; ++i) + { + if((a_stream.Read(&function, sizeof(function)) != sizeof(function)) || function.m_func != ID_func) { goto done; } + // Read in the byte code + if(byteCode) { delete[] byteCode; } + // use the byte code allocation for the debug params and locals symbol array + byteCode = GM_NEW( char[function.m_byteCodeLen] ); + if(a_stream.Read(byteCode, function.m_byteCodeLen) != function.m_byteCodeLen) { goto done; } + + // Load all symbols + union + { + gmuint8 * instruction; + gmuint32 * instruction32; + }; + + instruction = (gmuint8 *) byteCode; + gmuint8 * end = instruction + function.m_byteCodeLen; + for(;instruction < end;) + { + switch(*(instruction32++)) + { + case BC_BRA : + case BC_BRZ : + case BC_BRNZ : + case BC_BRZK : + case BC_BRNZK : + case BC_FOREACH : + case BC_PUSHINT : + case BC_PUSHFP : instruction += sizeof(gmfloat); break; + + case BC_CALL : + case BC_GETLOCAL : + case BC_SETLOCAL : instruction += sizeof(gmuint32); break; + + case BC_GETDOT : + case BC_SETDOT : + case BC_GETTHIS : + case BC_SETTHIS : + case BC_GETGLOBAL : + case BC_SETGLOBAL : + { + gmptr * reference = (gmptr *) instruction; + GM_ASSERT(*reference >= 0 && *reference < (gmptr) strings.m_size); + *reference = a_machine.AllocPermanantStringObject(&stringTable[*reference])->GetRef(); + instruction += sizeof(gmptr); + break; + } + case BC_PUSHSTR : + { + gmptr * reference = (gmptr *) instruction; + GM_ASSERT(*reference >= 0 && *reference < (gmptr) strings.m_size); + *reference = a_machine.AllocStringObject(&stringTable[*reference])->GetRef(); + instruction += sizeof(gmptr); + break; + } + + case BC_PUSHFN : + { + gmptr * reference = (gmptr *) instruction; + GM_ASSERT(*reference >= 0 && *reference < (gmptr) numFunctions); + *reference = functionObjects[*reference]->GetRef(); + instruction += sizeof(gmptr); + break; + } + + default : break; + } + } + + // Initialise our function object. + gmFunctionInfo functionInfo; + gmFunctionObject * currFunction = functionObjects[function.m_id]; + functionInfo.m_id = currFunction->GetRef(); + functionInfo.m_root = (function.m_flags & 1); + functionInfo.m_byteCode = byteCode; + functionInfo.m_byteCodeLength = function.m_byteCodeLen; + functionInfo.m_numParams = function.m_numParams; + functionInfo.m_numLocals = function.m_numLocals; + functionInfo.m_maxStackSize = function.m_maxStackSize; + functionInfo.m_symbols = NULL; + functionInfo.m_lineInfo = NULL; + + // We have now loaded all objects into the byte code.... Load the debug info + if(debug) + { + gmuint32 stringOffset, lineInfoCount, numSymbols = function.m_numLocals + function.m_numParams; + + // debug name + if(a_stream.Read(&stringOffset, sizeof(stringOffset)) != sizeof(stringOffset)) { goto done; } + GM_ASSERT(stringOffset < strings.m_size); + functionInfo.m_debugName = &stringTable[stringOffset]; + + // Make sure our scratch memory is large enough + if(a_stream.Read(&lineInfoCount, sizeof(lineInfoCount)) != sizeof(lineInfoCount)) { goto done; } + gmuint32 reqdScratchSize = (lineInfoCount * sizeof(gmLineInfo)) + (sizeof(const char *) * numSymbols); + if(scratchSize < reqdScratchSize) + { + scratchSize = reqdScratchSize; + delete[] scratch; + scratch = GM_NEW( gmuint8[scratchSize] ); + } + gmLineInfo * lineInfo = (gmLineInfo *) scratch; + functionInfo.m_lineInfo = lineInfo; + functionInfo.m_symbols = (const char **) (scratch + (lineInfoCount * sizeof(gmLineInfo))); + functionInfo.m_lineInfoCount = lineInfoCount; + + // Debug line info + for(j = 0; j < lineInfoCount; ++j) + { + gmlLineInfo libLineInfo; + if(a_stream.Read(&libLineInfo, sizeof(libLineInfo)) != sizeof(libLineInfo)) { goto done; } + lineInfo[j].m_address = libLineInfo.m_byteCodeAddress; + lineInfo[j].m_lineNumber = libLineInfo.m_lineNumber; + } + + // Debug symbols + for(j = 0; j < numSymbols; ++j) + { + if(a_stream.Read(&stringOffset, sizeof(stringOffset)) != sizeof(stringOffset)) { goto done; } + GM_ASSERT(stringOffset < strings.m_size); + functionInfo.m_symbols[j] = &stringTable[stringOffset]; + } + + } + + // AND FINALLY, INITIALISE OUR FUNCTION + currFunction->Init(&a_machine, debug && a_machine.GetDebugMode(), functionInfo, sourceCodeId); + if(functionInfo.m_root) + { + functionObject = currFunction; + } + } + + error = false; + +done: + + // turn gc off. + a_machine.EnableGC(gc); + if(stringTable) { delete[] stringTable; } + if(sourceCode) { delete[] sourceCode; } + if(functionObjects) { delete[] functionObjects; } + if(byteCode) { delete[] byteCode; } + if(scratch) { delete[] scratch; } + + if(error) + { + a_machine.GetLog().LogEntry("Error loading library"); + return NULL; + } + return functionObject; +} + diff --git a/vscript/languages/gm/src/gm/gmLibHooks.h b/vscript/languages/gm/src/gm/gmLibHooks.h new file mode 100644 index 00000000..850e61e0 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmLibHooks.h @@ -0,0 +1,124 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmCodeGenHooks.h" +#include "gmListDouble.h" +#include "gmMemChain.h" +#include "gmStream.h" +#include "gmStreamBuffer.h" + +class gmMachine; +class gmFunctionObject; + +/// \class gmLibHooks +/// \brief gmLibHooks is a compiler hook class that allows compiling to a lib for disk storage. +class gmLibHooks : public gmCodeGenHooks +{ +public: + + // a_source and must exist untill destruction of the libhooks + gmLibHooks(gmStream &a_stream, const char * a_source); + virtual ~gmLibHooks(); + + virtual bool Begin(bool a_debug); + virtual bool AddFunction(gmFunctionInfo &a_info); + virtual bool End(int a_errors); + virtual gmptr GetFunctionId(); + virtual gmptr GetSymbolId(const char * a_symbol); + virtual gmptr GetStringId(const char * a_string); + virtual bool SwapEndian() const { return m_swapEndian; } + + /// \brief BindLib will bind the lib to the machine, and return the root function for executing. + static gmFunctionObject * BindLib(gmMachine &a_machine, gmStream &a_stream, const char * a_filename); + +private: + + class USymbol : public gmListDoubleNode + { + public: + USymbol(); + ~USymbol(); + char * m_string; + gmptr m_offset; // offset into symbol table. + }; + + gmStream * m_stream; + bool m_swapEndian; + bool m_debug; + const char * m_source; + gmptr m_symbolOffset; + gmptr m_functionId; + gmStreamBufferDynamic m_functionStream; + gmListDouble m_symbols; + gmMemChain m_allocator; +}; + +/* + + Library file format for .gmlib files (gm library files) (native endian) + + // header + + 'gml0' [4 bytes] + flags [4 bytes] // 0x01 - debug lib, + + string_table_offset [4 bytes] // relative to start of lib + source_code_offset [4 bytes] // 0 for not there, otherwise relative to start of lib + functions_offset [4 bytes] // relative to start of lib + + string_table + { + string_table_size [4 bytes] + data [1 byte ] * string_table_size of 0 terminated strings + } + + source_code + { + source_code_size [4 bytes] + flags [4 bytes] // possibly encryption and compression flags + data [1 byte ] * source code size. + } + + functions + { + num_functions [4 bytes] // number of functions + + function[] + { + 'func' [4 bytes] + function_id [4 bytes] // FUNCTION IDS ARE FROM 0-(num_functions-1), BC_PUSHFN calls reference this id. + flags [4 bytes] // 0x01 - is root + num_params [4 bytes] + num_locals [4 bytes] + max_stack_size [4 bytes] + byte_code_length [4 bytes] + byte_code [1 byte ] * byte_code_length // contains offsets rel to string tab + // and function ids for certian op codes. + + // byte code must be changed on load such that BC_PUSHFN calls reference their respective function object, + // and BC_PUSHSTR reference their string object created by their string table offset. + + if(debug lib) + { + debug_name_offset [4 bytes] + line_info_count [4 bytes] + line_info[] + { + byte_code_address [4 bytes] + line_number [4 bytes] + } + symbol_name_offsets[] [4 bytes] * (num_params + num_locals) (~0) on no offset + } + } + } + +*/ diff --git a/vscript/languages/gm/src/gm/gmListDouble.cpp b/vscript/languages/gm/src/gm/gmListDouble.cpp new file mode 100644 index 00000000..0a14a4b4 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmListDouble.cpp @@ -0,0 +1,16 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmListDouble.h" + +// Must be last header +#include "memdbgon.h" diff --git a/vscript/languages/gm/src/gm/gmListDouble.h b/vscript/languages/gm/src/gm/gmListDouble.h new file mode 100644 index 00000000..0f93bf07 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmListDouble.h @@ -0,0 +1,377 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMLISTDOUBLEI_H_ +#define _GMLISTDOUBLEI_H_ + +#include "gmConfig.h" +#include "gmIterator.h" + +template +class gmListDouble; + +/// \class gmListDoubleNode +/// \brief intrusive node, must inherit this class templated to your class +template +class gmListDoubleNode +{ +public: + + inline gmListDoubleNode() {} + + /// \brief Nullify() + inline void Nullify() + { + m_next = m_prev = NULL; + } + + /// \brief Remove from list. Allows node to unlink from unknown list. + inline void RemoveAndNullify() + { + m_next->m_prev = m_prev; + m_prev->m_next = m_next; + this->Nullify(); + } + + /// \brief Remove from list, must be in list. + inline void Remove() + { + m_next->m_prev = m_prev; + m_prev->m_next = m_next; + } + + /// \brief Returns true if node is linked to list, assumes the list is being managed correctly with nullify() + inline bool IsLinked() const + { + return (m_next != NULL); + } + +private: + + gmListDoubleNode * m_next; + gmListDoubleNode * m_prev; + + friend class gmListDouble; +}; + + +/// \class gmListDoubleNodeObj +/// \brief List node that stores object pointer. +/// Allows node to be contained rather than be inherited. +template +class gmListDoubleNodeObj : public gmListDoubleNode< gmListDoubleNodeObj > +{ +public: + + /// \brief Construct, Nullifies link and object + inline gmListDoubleNodeObj() + { + this->Nullify(); + SetObject(NULL); + } + + /// \brief Construct, Nullifies link and set object + inline gmListDoubleNodeObj(T* a_obj) + { + this->Nullify(); + SetObject(a_obj); + } + + inline T* GetObject() { return m_object; } + inline void SetObject(T* a_obj) { m_object = a_obj; } + +private: + + T* m_object; +}; + +/// \class gmListDouble +/// \brief Templated intrusive doubly linked list using a sentinal node +template +class gmListDouble +{ +public: + + /// \class Iterator + class Iterator + { + public: + + GM_INCLUDE_ITERATOR_KERNEL(T) + + inline Iterator() { m_node = NULL; m_list = NULL; } + inline Iterator(T * a_node, const gmListDouble * a_list) { m_node = a_node; m_list = a_list; } + + inline void Inc() { m_node = m_list->GetNext(m_node); } + inline void Dec() { m_node = m_list->GetPrev(m_node); } + inline T* Resolve() { return m_node; } + inline const T* Resolve() const { return m_node; } + inline bool IsValid() const { return (m_list && m_list->IsValid(m_node)); } + + private: + + T * m_node; + const gmListDouble * m_list; + }; + + // methods + + inline gmListDouble(); + inline ~gmListDouble(); + + inline void InsertAfter(T * a_cursor, T * a_elem); + inline void InsertBefore(T * a_cursor, T * a_elem); + inline void InsertLast(T * a_elem); + inline void InsertFirst(T * a_elem); + inline void Remove(T * a_elem); + inline void RemoveAndNullify(T * a_elem); + inline T * Remove(Iterator &a_it); // iterator is incremented + inline T * RemoveAndNullify(Iterator &a_it); // iterator is incremented + inline T * RemoveGetNext(T * a_elem); + inline T * RemoveLast(); // returns NULL if no elements left in list + inline T * RemoveLastAndNullify(); + inline T * RemoveFirst(); // returns NULL if no elements left in list + inline T * RemoveFirstAndNullify(); + inline void RemoveAll(); + inline void RemoveAndNullifyAll(); + inline void RemoveAndDeleteAll(); + inline int Count() const; + inline bool IsValid(const T* a_elem) const { return (a_elem != &m_sentinel); } + inline T* GetFirst() const { return (T*) m_sentinel.m_next; } + inline T* GetLast() const { return (T*) m_sentinel.m_prev; } + inline T* GetNext(const T* a_elem) const { return (T*) a_elem->gmListDoubleNode::m_next; } + inline T* GetPrev(const T* a_elem) const { return (T*) a_elem->gmListDoubleNode::m_prev; } + inline bool IsEmpty() const { return (m_sentinel.m_next == &m_sentinel); } + inline Iterator First(void) const { return Iterator(static_cast(m_sentinel.m_next), this); } + inline Iterator Last(void) const { return Iterator(static_cast(m_sentinel.m_prev), this); } + +private: + + gmListDoubleNode m_sentinel; +}; + +// +// implementation of gmListDouble +// + +template +inline gmListDouble::gmListDouble() +{ + m_sentinel.m_next = &m_sentinel; + m_sentinel.m_prev = &m_sentinel; +} + + +template +inline gmListDouble::~gmListDouble() +{ +} + + +template +inline void gmListDouble::InsertAfter(T * a_cursor, T * a_elem) +{ + a_elem->gmListDoubleNode::m_next = a_cursor->gmListDoubleNode::m_next; + a_elem->gmListDoubleNode::m_prev = a_cursor; + a_elem->gmListDoubleNode::m_prev->m_next = a_elem; + a_elem->gmListDoubleNode::m_next->m_prev = a_elem; +} + + +template +inline void gmListDouble::InsertBefore(T * a_cursor, T * a_elem) +{ + a_elem->gmListDoubleNode::m_next = a_cursor; + a_elem->gmListDoubleNode::m_prev = a_cursor->gmListDoubleNode::m_prev; + a_elem->gmListDoubleNode::m_prev->m_next = a_elem; + a_elem->gmListDoubleNode::m_next->m_prev = a_elem; +} + + +template +inline void gmListDouble::InsertLast(T * a_elem) +{ + a_elem->gmListDoubleNode::m_prev = m_sentinel.m_prev; + a_elem->gmListDoubleNode::m_next = &m_sentinel; + m_sentinel.m_prev->m_next = a_elem; + m_sentinel.m_prev = a_elem; +} + + +template +inline void gmListDouble::InsertFirst(T * a_elem) +{ + a_elem->gmListDoubleNode::m_prev = &m_sentinel; + a_elem->gmListDoubleNode::m_next = m_sentinel.m_next; + m_sentinel.m_next->m_prev = a_elem; + m_sentinel.m_next = a_elem; +} + + +template +inline void gmListDouble::Remove(T * a_elem) +{ + a_elem->gmListDoubleNode::m_next->m_prev = a_elem->gmListDoubleNode::m_prev; + a_elem->gmListDoubleNode::m_prev->m_next = a_elem->gmListDoubleNode::m_next; +} + + +template +inline void gmListDouble::RemoveAndNullify(T * a_elem) +{ + a_elem->gmListDoubleNode::m_next->m_prev = a_elem->gmListDoubleNode::m_prev; + a_elem->gmListDoubleNode::m_prev->m_next = a_elem->gmListDoubleNode::m_next; + a_elem->gmListDoubleNode::m_next = a_elem->gmListDoubleNode::m_prev = NULL; +} + + +template +inline T * gmListDouble::Remove(Iterator &a_it) +{ + T* node = a_it.Resolve(); + a_it.Inc(); + Remove(node); + return node; +} + + +template +inline T * gmListDouble::RemoveAndNullify(Iterator &a_it) +{ + T* node = a_it.Resolve(); + a_it.Inc(); + RemoveAndNullify(node); + return node; +} + + +template +inline T * gmListDouble::RemoveGetNext(T * a_elem) +{ + gmListDoubleNode * next = a_elem->gmListDoubleNode::m_next; + + a_elem->gmListDoubleNode::m_next->m_prev = a_elem->gmListDoubleNode::m_prev; + a_elem->gmListDoubleNode::m_prev->m_next = a_elem->gmListDoubleNode::m_next; + a_elem->gmListDoubleNode::m_next = a_elem->gmListDoubleNode::m_prev = NULL; + + return static_cast(next); +} + + +template +inline T * gmListDouble::RemoveLast() +{ + if(m_sentinel.m_prev == &m_sentinel) return NULL; + + gmListDoubleNode * temp; + temp = m_sentinel.m_prev; + temp->m_next->m_prev = temp->m_prev; + temp->m_prev->m_next = temp->m_next; + return static_cast(temp); +} + + +template +inline T * gmListDouble::RemoveLastAndNullify() +{ + if(m_sentinel.m_prev == &m_sentinel) return NULL; + + gmListDoubleNode * temp; + temp = m_sentinel.m_prev; + + temp->m_next->m_prev = temp->m_prev; + temp->m_prev->m_next = temp->m_next; + temp->m_next = temp->m_prev = NULL; + + return static_cast(temp); +} + + +template +inline T * gmListDouble::RemoveFirst() +{ + if(m_sentinel.m_next == &m_sentinel) return NULL; + + gmListDoubleNode * temp; + temp = m_sentinel.m_next; + temp->m_next->m_prev = temp->m_prev; + temp->m_prev->m_next = temp->m_next; + return static_cast(temp); +} + + +template +inline T * gmListDouble::RemoveFirstAndNullify() +{ + if(m_sentinel.m_next == &m_sentinel) return NULL; + + gmListDoubleNode * temp; + temp = m_sentinel.m_next; + temp->m_next->m_prev = temp->m_prev; + temp->m_prev->m_next = temp->m_next; + temp->m_next = temp->m_prev = NULL; + return static_cast(temp); +} + + +template +inline void gmListDouble::RemoveAll() +{ + m_sentinel.m_next = &m_sentinel; + m_sentinel.m_prev = &m_sentinel; +} + + +template +inline void gmListDouble::RemoveAndNullifyAll() +{ + gmListDoubleNode * node = m_sentinel.m_next, * temp; + while(node != &m_sentinel) + { + temp = node; + node = node->m_next; + temp->m_next = temp->m_prev = NULL; + } + m_sentinel.m_next = &m_sentinel; + m_sentinel.m_prev = &m_sentinel; +} + + +template +inline void gmListDouble::RemoveAndDeleteAll() +{ + gmListDoubleNode * node = m_sentinel.m_next, * temp; + while(node != &m_sentinel) + { + temp = node; + node = node->m_next; + delete ((T *) temp); + } + m_sentinel.m_next = &m_sentinel; + m_sentinel.m_prev = &m_sentinel; +} + + +template +inline int gmListDouble::Count() const +{ + int count = 0; + gmListDoubleNode * node = m_sentinel.m_next; + while(node != &m_sentinel) + { + node = node->m_next; + ++count; + } + return count; +} + + +#endif // _GMLISTDOUBLEI_H_ diff --git a/vscript/languages/gm/src/gm/gmLog.cpp b/vscript/languages/gm/src/gm/gmLog.cpp new file mode 100644 index 00000000..8f50ac87 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmLog.cpp @@ -0,0 +1,120 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmLog.h" +#include "gmMem.h" + +// Must be last header +#include "memdbgon.h" + +gmLog::gmLog() : + m_mem(1, GMLOG_CHAINSIZE) +{ + m_first = NULL; + m_last = NULL; + m_curr = NULL; + + m_memApproxLimit = -1; +} + + + +gmLog::~gmLog() +{ +} + + + +void gmLog::Reset() +{ + m_first = NULL; + m_last = NULL; + m_curr = NULL; + m_mem.Reset(); +} + + + +void gmLog::ResetAndFreeMemory() +{ + m_first = NULL; + m_last = NULL; + m_curr = NULL; + m_mem.ResetAndFreeMemory(); +} + + + +void GM_CDECL gmLog::LogEntry(const char * a_format, ...) +{ + va_list ap; + char buffer[GMLOG_CHAINSIZE]; + + va_start(ap, a_format); + _gmvsnprintf(buffer, GMLOG_CHAINSIZE, a_format, ap); + va_end(ap); + strcat(buffer, GM_NL); + + if( (m_memApproxLimit > 0) && (m_mem.GetSystemMemUsed() > (unsigned int)m_memApproxLimit) ) + { + m_mem.Reset(); + } + + // add to entry list + Entry * entry = (Entry *) m_mem.AllocBytes(sizeof(Entry) + sizeof(int), GM_DEFAULT_ALLOC_ALIGNMENT); + if(entry != NULL) + { + char * text = (char *) m_mem.AllocBytes(strlen(buffer) + 1, GM_DEFAULT_ALLOC_ALIGNMENT); + if(text) + { + strcpy(text, buffer); + entry->m_text = text; + entry->m_next = NULL; + if(m_last) + { + m_last->m_next = entry; + m_last = entry; + } + else + { + m_first = m_last = entry; + } + } + } +} + + + +const char * gmLog::GetEntry(bool &a_first) +{ + if(a_first == true) + { + a_first = false; + m_curr = m_first; + } + + if(m_curr) + { + const char * text = m_curr->m_text; + m_curr = m_curr->m_next; + return text; + } + + return NULL; +} + + +void gmLog::SetMemLimit(int a_limit) +{ + m_memApproxLimit = a_limit; +} + diff --git a/vscript/languages/gm/src/gm/gmLog.h b/vscript/languages/gm/src/gm/gmLog.h new file mode 100644 index 00000000..7ddc7c2d --- /dev/null +++ b/vscript/languages/gm/src/gm/gmLog.h @@ -0,0 +1,61 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMLOG_H_ +#define _GMLOG_H_ + +#include "gmConfig.h" +#include "gmMemChain.h" + +/// \class gmLog is a log class for the compiler. The log is passed between the parser, analyser, and code generator. +/// the log class will batch the errors into a list of error strings. +class gmLog +{ +public: + gmLog(); + ~gmLog(); + + /// \brief Reset() will remove log entries, but not free the chain mem. + void Reset(); + + /// \brief ResetAndFreeMemory() + void ResetAndFreeMemory(); + + /// \brief LogEntry() will log an entry to the log. the length of log must not exceed GMLOG_CHAINSIZE + /// \param a_format + void GM_CDECL LogEntry(const char * a_format, ...); + + /// \brief GetEntry() will return a log entry, or NULL if there are no more entries. + /// \param a_first is true for the first call to get entry, this will be set to false for successive calls. + /// \return a log entry, or NULL if no more entries exist + const char * GetEntry(bool &a_first); + + /// \brief Set approximate memory limit for error logs. + /// \param a_limit The approximate memory limit in bytes or <= 0 for no limit. + void SetMemLimit(int a_limit); + +private: + + struct Entry + { + const char * m_text; + Entry * m_next; + }; + + Entry * m_first; ///< Message list first ptr + Entry * m_last; ///< Message list last ptr + Entry * m_curr; ///< Current message + int m_memApproxLimit; ///< Approximate memory limit + + gmMemChain m_mem; +}; + +#endif // _GMLOG_H_ diff --git a/vscript/languages/gm/src/gm/gmMachine.cpp b/vscript/languages/gm/src/gm/gmMachine.cpp new file mode 100644 index 00000000..36639f4e --- /dev/null +++ b/vscript/languages/gm/src/gm/gmMachine.cpp @@ -0,0 +1,1953 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmMachine.h" +#include "gmThread.h" +#include "gmTableObject.h" +#include "gmStringObject.h" +#include "gmUserObject.h" +#include "gmFunctionObject.h" +#if !GMMACHINE_REMOVECOMPILER + #include "gmCodeTree.h" + #include "gmCodeGen.h" +#endif //GMMACHINE_REMOVECOMPILER +#include "gmOperators.h" +#include "gmMachineLib.h" +#include "gmCrc.h" +#include "gmStream.h" +#include "gmLibHooks.h" + + +#if GM_USE_INCGC + #include "gmIncGC.h" +#endif //GM_USE_INCGC + +#if !GM_USE_INCGC + #define GM_ADDOBJECT(A) { (A)->m_sysNext = m_objects; m_objects = (A); } +#endif //!GM_USE_INCGC + +// Must be last header +#include "memdbgon.h" + +// +// +// gmHooks is an implementation of gmCodeGenHooks and is used by gmMachine to compile gm scripts. +// +// + +class gmHooks : public gmCodeGenHooks +{ +public: + gmHooks(gmMachine * a_machine, const char * a_source, const char * a_filename); + virtual ~gmHooks(); + + virtual bool Begin(bool a_debug); + virtual bool AddFunction(gmFunctionInfo &a_info); + virtual bool End(int a_errors); + virtual gmptr GetFunctionId(); + virtual gmptr GetSymbolId(const char * a_symbol); + virtual gmptr GetStringId(const char * a_string); + + gmFunctionObject * GetRootFunction() { return m_rootFunction; } + +private: + + gmFunctionObject * m_rootFunction; + int m_errors; + bool m_debug; + bool m_gcEnabled; + gmMachine * m_machine; + const char * m_source; + const char * m_filename; + gmuint32 m_sourceId; +}; + +// +// +// Implementation of gmSourceEntry, used for storing source code in debug mode +// +// + +class gmSourceEntry : public gmListDoubleNode +{ +public: + + gmSourceEntry(const char * a_source, const char * a_filename) + { + int slen = strlen(a_source); + int flen = strlen(a_filename); + m_id = gmCrc32String(a_source); + + m_source = GM_NEW( char[slen + flen + 2] ); + memcpy(m_source, a_source, slen + 1); + m_filename = m_source + slen + 1; + memcpy(m_filename, a_filename, flen + 1); + } + + ~gmSourceEntry() + { + if(m_source) + delete[] m_source; + } + + gmuint32 m_id; + char * m_source; + char * m_filename; +}; + +// +// +// Implementation of gmBlock, gmSignal, gmBlocklist for thread blocking +// +// + +class gmBlockList : public gmHashNode +{ +public: + + gmBlockList() {} + virtual ~gmBlockList() {} + + virtual const gmVariable &GetKey() const + { + return m_block; + } + + gmVariable m_block; + gmListDouble m_blocks; +}; + +// +// +// Default Print Callback +// +// +void gmDefaultPrintCallback(gmMachine * a_machine, const char * a_string) +{ + GM_PRINTF("%s"GM_NL, a_string); +} + +// +// +// Implementation of gmMachine +// +// + +gmMachineCallback gmMachine::s_machineCallback = NULL; +gmPrintCallback gmMachine::s_printCallback = gmDefaultPrintCallback; +gmUserBreakCallback gmMachine::s_userBreakCallback = NULL; + + +#if GM_USE_INCGC +void GM_CDECL gmMachine::ScanRootsCallBack(gmMachine* a_machine, gmGarbageCollector* a_gc) +{ + gmThread * tit; + + // call the gc callback + if(s_machineCallback) s_machineCallback(a_machine, MC_COLLECT_GARBAGE, NULL); + + // iterate cpp owned gmObjects + gmHash::Iterator cgmoIt; + for(cgmoIt = a_machine->m_cppOwnedGMObjs.First(); cgmoIt; ++cgmoIt) + { + gmObject* curObj = cgmoIt->m_obj; + a_gc->GetNextObject(curObj); + } + + // iterate over all threads and mark the stacks. + for(tit = a_machine->m_runningThreads.GetFirst(); a_machine->m_runningThreads.IsValid(tit); tit = a_machine->m_runningThreads.GetNext(tit)) tit->GCScanRoots(a_machine, a_gc); + for(tit = a_machine->m_blockedThreads.GetFirst(); a_machine->m_blockedThreads.IsValid(tit); tit = a_machine->m_blockedThreads.GetNext(tit)) tit->GCScanRoots(a_machine, a_gc); + for(tit = a_machine->m_sleepingThreads.GetFirst(); a_machine->m_sleepingThreads.IsValid(tit); tit = a_machine->m_sleepingThreads.GetNext(tit)) tit->GCScanRoots(a_machine, a_gc); + for(tit = a_machine->m_exceptionThreads.GetFirst(); a_machine->m_exceptionThreads.IsValid(tit); tit = a_machine->m_sleepingThreads.GetNext(tit)) tit->GCScanRoots(a_machine, a_gc); + + // iterate over global variables and mark + if(a_machine->m_global) + { + a_gc->GetNextObject(a_machine->m_global); + } + // iterate over type variables and mark + gmuint i; + for(i = 0; i < a_machine->m_types.Count(); ++i) + { + a_gc->GetNextObject(a_machine->m_types[i].m_variables); + } + +#if !GM_GC_KEEP_PERSISTANT_SEPARATE + //NOTE This needs to be spread over time perhaps. + for(i=0; i<(gmuint)a_machine->m_numPermanantStrings; ++i) + { + a_gc->GetNextObject(a_machine->m_permanantStrings[i]); + } +#endif //!GM_GC_KEEP_PERSISTANT_SEPARATE +} + +#endif //GM_USE_INCGC + +gmMachine::gmMachine() + : + m_threads(128), + m_memStringObj(sizeof(gmStringObject), GMMACHINE_STRINGCHUNKSIZE), + m_memTableObj(sizeof(gmTableObject), GMMACHINE_TBLCHUNKSIZE), + m_memFunctionObj(sizeof(gmFunctionObject), GMMACHINE_OBJECTCHUNKSIZE), + m_memUserObj(sizeof(gmUserObject), GMMACHINE_OBJECTCHUNKSIZE), + m_memStackFrames(sizeof(gmStackFrame), GMMACHINE_STACKFCHUNKSIZE), + + m_strings(GMMACHINE_STRINGHASHSIZE), + m_blocks(64), + m_cppOwnedGMObjs(GMMACHINE_CPPOWNEDGMOBJHASHSIZE) + +{ + m_line = NULL; + m_call = NULL; + m_return = NULL; + m_isBroken = NULL; + +#if GM_USE_INCGC + m_gc = GM_NEW( gmGarbageCollector ); + m_gc->Init(ScanRootsCallBack, this); + #if !GM_GC_KEEP_PERSISTANT_SEPARATE + m_permanantStrings.SetCount(0); + #endif //!GM_GC_KEEP_PERSISTANT_SEPARATE +#endif //GM_USE_INCGC + m_trueGlobal = m_global = NULL; + + m_objects = NULL; + m_threadId = 0; + m_nextThread = NULL; + m_nextThreadValid = false; + m_autoMem = GMMACHINE_AUTOMEM; + m_currentMemoryUsage = 0; + m_desiredByteMemoryUsageHard = GMMACHINE_INITIALGCHARDLIMIT; + m_desiredByteMemoryUsageSoft = GMMACHINE_INITIALGCSOFTLIMIT; + m_mark = GM_MARK_START; + + m_framesSinceLastIncCollect = 0; + m_gcPhaseCount = 0; + m_statsGCFullCollect = 0; + m_statsGCIncCollect = 0; + m_statsGCWarnings = 0; + + m_debug = false; + m_debugUser = NULL; + + m_gcEnabled = true; + + m_trueGlobal = m_global = AllocTableObject(); // Alloc global table + + m_types.SetCount(0); + + ResetDefaultTypes(); + m_time = 0; + + gmMachineLib(this); +} + + + +gmMachine::~gmMachine() +{ + ResetAndFreeMemory(); +#if GM_USE_INCGC + delete m_gc; +#endif //GM_USE_INCGC +} + + + +void gmMachine::ResetAndFreeMemory() +{ + +#if GM_USE_INCGC + + m_gc->DestructAll(); + + #if !GM_GC_KEEP_PERSISTANT_SEPARATE + m_permanantStrings.SetCount(0); + #endif //!GM_GC_KEEP_PERSISTANT_SEPARATE + + m_trueGlobal = m_global = NULL; + gmuint i; + for(i = 0; i < m_types.Count(); ++i) + { + m_types[i].m_variables = NULL; + m_types[i].m_name = NULL; + } + + //FindMissingCountObj(); + +#else //GM_USE_INCGC + // destruct all objects + for(gmObject* it = m_objects; it; ) + { + gmObject * nit = it->m_sysNext; + it->Destruct(this); + FreeObject(it); + it = nit; + } + m_trueGlobal = m_global = NULL; //Global was freed with the rest + // operators\types + gmuint i; + for(i = 0; i < m_types.Count(); ++i) + { + m_types[i].m_variables = NULL; + m_types[i].m_name = NULL; + } +#endif //GM_USE_INCGC + m_objects = NULL; + + // string table + GM_ASSERT(m_strings.Count() == 0); + m_strings.RemoveAll(); + + // threads + m_runningThreads.RemoveAll(); + m_blockedThreads.RemoveAll(); + m_sleepingThreads.RemoveAll(); + m_exceptionThreads.RemoveAll(); + m_killedThreads.RemoveAndDeleteAll(); + m_threads.RemoveAndDeleteAll(); + m_threadId = 0; + m_time = 0; + m_nextThread = NULL; + m_nextThreadValid = false; + GM_ASSERT(m_blocks.Count() == 0); + + // CPP owned gmObjects + m_cppOwnedGMObjs.RemoveAll(); + + // memory allocators (make sure we arent leaking memory) + + GM_ASSERT(m_memStringObj.GetMemUsed() == 0); + m_memStringObj.ResetAndFreeMemory(); + + GM_ASSERT(m_memTableObj.GetMemUsed() == 0); + m_memTableObj.ResetAndFreeMemory(); + + GM_ASSERT(m_memFunctionObj.GetMemUsed() == 0); + m_memFunctionObj.ResetAndFreeMemory(); + + GM_ASSERT(m_memUserObj.GetMemUsed() == 0); + m_memUserObj.ResetAndFreeMemory(); + + GM_ASSERT(m_memStackFrames.GetMemUsed() == 0); + m_memStackFrames.ResetAndFreeMemory(); + + GM_ASSERT(m_fixedSet.GetMemUsed() == 0); + m_fixedSet.ResetAndFreeMemory(); + + m_debug = false; + m_debugUser = NULL; + m_source.RemoveAndDeleteAll(); + + // types + m_types.ResetAndFreeMemory(); + + // compiler + m_log.ResetAndFreeMemory(); +#if !GMMACHINE_REMOVECOMPILER + gmCodeTree::Get().FreeMemory(); + gmCodeGen::Get().FreeMemory(); +#endif //GMMACHINE_REMOVECOMPILER + + // garbage collection + m_autoMem = GMMACHINE_AUTOMEM; + m_currentMemoryUsage = 0; + m_desiredByteMemoryUsageHard = GMMACHINE_INITIALGCHARDLIMIT; + m_desiredByteMemoryUsageSoft = GMMACHINE_INITIALGCSOFTLIMIT; + m_mark = GM_MARK_START; + m_gcEnabled = true; +} + + +void gmMachine::Init() +{ + m_gcEnabled = true; + m_threadId = 0; + m_autoMem = GMMACHINE_AUTOMEM; + m_currentMemoryUsage = 0; + m_desiredByteMemoryUsageHard = GMMACHINE_INITIALGCHARDLIMIT; + m_desiredByteMemoryUsageSoft = GMMACHINE_INITIALGCSOFTLIMIT; + m_mark = GM_MARK_START; + m_trueGlobal = m_global = AllocTableObject(); // Alloc global table + m_types.SetCount(0); + ResetDefaultTypes(); + m_blocks.RemoveAll(); + m_cppOwnedGMObjs.RemoveAll(); + m_time = 0; + + m_debug = false; + + gmMachineLib(this); +} + + +void gmMachine::RegisterLibrary(gmFunctionEntry * a_functions, int a_numFunctions, const char * a_asTable, bool a_newTable) +{ + gmTableObject * table = m_global; + + if( a_asTable ) + { +#if GM_CASE_INSENSITIVE + + char * asTable = (char *) gmNewStackArray(char, strlen(a_asTable) + 1); + strcpy(asTable, a_asTable); + _strlwr(asTable); + a_asTable = asTable; + +#endif // GM_CASE_INSENSITIVE + + if( a_newTable == true ) + { + table = AllocTableObject(); + } + else + { + gmVariable tabVar = m_global->Get(this, a_asTable); + if( tabVar.m_type == GM_TABLE ) + { + // Existing table found, use this + table = (gmTableObject *)tabVar.m_value.m_ref; + } + else + { + // Otherwise create a new table afterall + table = AllocTableObject(); + } + } + m_global->Set(this, a_asTable, gmVariable(GM_TABLE, (gmptr) table)); + } + + GM_ASSERT(table); + + for(int index = 0; index < a_numFunctions; ++index ) + { + gmFunctionObject* funcObj = AllocFunctionObject(a_functions[index].m_function); + funcObj->m_cUserData = a_functions[index].m_userData; + +#if GM_CASE_INSENSITIVE + + char * funcNameLower = (char *) gmNewStackArray(char, strlen(a_functions[index].m_name) + 1); + strcpy(funcNameLower, a_functions[index].m_name); + _strlwr(funcNameLower); + + m_cFuncUserData + table->Set(this, funcNameLower, gmVariable(GM_FUNCTION, (gmptr)funcObj)); + +#else // !GM_CASE_INSENSITIVE + + table->Set(this, a_functions[index].m_name, gmVariable(GM_FUNCTION, (gmptr)funcObj)); + +#endif // !GM_CASE_INSENSITIVE + } +} + + + +void gmMachine::RegisterTypeLibrary(gmType a_type, gmFunctionEntry * a_functions, int a_numFunctions) +{ + int i; + for(i = 0; i < a_numFunctions; ++i) + { + gmFunctionObject* funcObj = AllocFunctionObject(a_functions[i].m_function); + funcObj->m_cUserData = a_functions[i].m_userData; + + RegisterTypeVariable(a_type, a_functions[i].m_name, gmVariable(GM_FUNCTION, (gmptr)funcObj)); + } +} + + + +gmType gmMachine::CreateUserType(const char * a_name) +{ + bool enabled = IsGCEnabled(); + EnableGC(false); //Disable GC as user types are roots and we are in the middle of creating a new one + + gmType type = (gmType) m_types.Count(); + m_types.InsertLast(); + m_types[type].Init(); + m_types[type].m_name = AllocPermanantStringObject(a_name); + gmInitBasicType(GM_USER, m_types[type].m_nativeOperators); + + // Alloc user type table + m_types[type].m_variables = AllocTableObject(); + + EnableGC(enabled); //Restore GC + + return type; +} + + +#if GM_USE_INCGC +void gmMachine::RegisterUserCallbacks(gmType a_type, gmGCTraceCallback a_gcTrace, gmGCDestructCallback a_gcDestruct, gmAsStringCallback a_asString) +{ + m_types[a_type].m_gcTrace = a_gcTrace; + m_types[a_type].m_gcDestruct = a_gcDestruct; + m_types[a_type].m_asString = a_asString; +} + +#else //GM_USE_INCGC +void gmMachine::RegisterUserCallbacks(gmType a_type, gmGarbageCollectCallback a_mark, gmGarbageCollectCallback a_gc, gmAsStringCallback a_asString) +{ + m_types[a_type].m_mark = a_mark; + m_types[a_type].m_gc = a_gc; + m_types[a_type].m_asString = a_asString; +} +#endif //GM_USE_INCGC + + +void gmMachine::RegisterTypeVariable(gmType a_type, const char * a_variableName, const gmVariable &a_variable) +{ +#if GM_CASE_INSENSITIVE + + char * varNameLower = (char *) gmNewStackArray(char, strlen(a_variableName) + 1); + strcpy(varNameLower, a_variableName); + _strlwr(varNameLower); + m_types[a_type].m_variables->Set(this, varNameLower, a_variable); + +#else // !GM_CASE_INSENSITIVE + m_types[a_type].m_variables->Set(this, a_variableName, a_variable); +#endif // !GM_CASE_INSENSITIVE +} + + + +bool gmMachine::RegisterTypeOperator(gmType a_type, gmOperator a_operator, gmFunctionObject * a_function, gmOperatorFunction a_nativeFunction) +{ +// if(a_type < GM_USER) return false; //Prevent overriding default operators + + if(a_function) + { + m_types[a_type].m_operators[a_operator] = a_function->GetRef(); + } + else if(a_nativeFunction) + { + m_types[a_type].m_nativeOperators[a_operator] = a_nativeFunction; + } + return true; +} + + + +const char * gmMachine::GetTypeName(gmType a_type) +{ + return (const char *) *m_types[a_type].m_name; +} + + + +int gmMachine::CheckSyntax(const char * a_string) +{ +#if GMMACHINE_REMOVECOMPILER + GetLog().LogEntry("No compiler in build"); + return 1; +#else // GMMACHINE_REMOVECOMPILER + gmCodeGenHooksNull nullHooks; + + // parse + int errors = gmCodeTree::Get().Lock(a_string, &m_log); + if(errors > 0) + { + gmCodeTree::Get().Unlock(); + return errors; + } + + // compile + errors = gmCodeGen::Get().Lock(gmCodeTree::Get().GetCodeTree(), &nullHooks, true, &m_log); + if(errors > 0) + { + gmCodeTree::Get().Unlock(); + gmCodeGen::Get().Unlock(); + return errors; + } + + gmCodeTree::Get().Unlock(); + gmCodeGen::Get().Unlock(); + + return errors; +#endif //GMMACHINE_REMOVECOMPILER +} + + + +int gmMachine::ExecuteString(const char * a_string, int * a_threadId, bool a_now, const char * a_filename, gmVariable* a_this) +{ +#if GMMACHINE_REMOVECOMPILER + GetLog().LogEntry("No compiler in build"); + return 1; +#else // GMMACHINE_REMOVECOMPILER + if(a_threadId) { *a_threadId = GM_INVALID_THREAD; } + + // parse + int errors = gmCodeTree::Get().Lock(a_string, &m_log); + if(errors > 0) + { + gmCodeTree::Get().Unlock(); + return errors; + } + + // compile + gmHooks hooks(this, a_string, a_filename); + errors = gmCodeGen::Get().Lock(gmCodeTree::Get().GetCodeTree(), &hooks, m_debug, &m_log); + if(errors > 0) + { + gmCodeTree::Get().Unlock(); + gmCodeGen::Get().Unlock(); + return errors; + } + + gmCodeTree::Get().Unlock(); + gmCodeGen::Get().Unlock(); + + // null or this + gmVariable thisVar; + if(!a_this) + { + thisVar.Nullify(); + } + else + { + thisVar = *a_this; + } + + // execute + gmThread * thread = CreateThread(thisVar, gmVariable(GM_FUNCTION, (gmptr) hooks.GetRootFunction()), a_threadId); + + if(a_now) + { + thread->Sys_Execute(); + } + + return 0; +#endif // GMMACHINE_REMOVECOMPILER +} + + +bool gmMachine::ExecuteLib(gmStream &a_stream, int * a_threadId, bool a_now, const char * a_filename, gmVariable* a_this) +{ + gmFunctionObject * rootFunction = gmLibHooks::BindLib(*this, a_stream, a_filename); + if(rootFunction) + { + // null or this + gmVariable thisVar; + if(!a_this) + { + thisVar.Nullify(); + } + else + { + thisVar = *a_this; + } + + gmThread * thread = CreateThread(thisVar, gmVariable(GM_FUNCTION, rootFunction->GetRef()), a_threadId); + if(a_now) + { + thread->Sys_Execute(); + } + return true; + } + return false; +} + + +bool gmMachine::ExecuteFunction(gmFunctionObject * a_function, int * a_threadId, bool a_now, gmVariable* a_this) +{ + gmVariable thisVar; + if(!a_this) + { + thisVar.Nullify(); + } + else + { + thisVar = *a_this; + } + + gmThread * thread = CreateThread(thisVar, gmVariable(GM_FUNCTION, a_function->GetRef()), a_threadId); + if(a_now) + { + thread->Sys_Execute(); + } + return true; +} + + +int gmMachine::CompileStringToLib(const char * a_string, gmStream &a_stream) +{ +#if GMMACHINE_REMOVECOMPILER + GetLog().LogEntry("No compiler in build"); + return 1; +#else // GMMACHINE_REMOVECOMPILER + // parse + int errors = gmCodeTree::Get().Lock(a_string, &m_log); + if(errors > 0) + { + gmCodeTree::Get().Unlock(); + return errors; + } + + #if 0 // Dump code tree to file for debugging + FILE * fp = fopen("c:/codetree.txt", "wb"); + gmCodeTree::Get().Print(fp); + fclose(fp); + #endif + + // compile + gmLibHooks hooks(a_stream, a_string); + errors = gmCodeGen::Get().Lock(gmCodeTree::Get().GetCodeTree(), &hooks, m_debug, &m_log); + + gmCodeTree::Get().Unlock(); + gmCodeGen::Get().Unlock(); + + return errors; +#endif // GMMACHINE_REMOVECOMPILER +} + + +gmFunctionObject * gmMachine::CompileStringToFunction(const char * a_string, int *a_errorCount, const char * a_filename) +{ +#if GMMACHINE_REMOVECOMPILER + GetLog().LogEntry("No compiler in build"); + if(a_errorCount) + { + *a_errorCount++; + } + return NULL; +#else // GMMACHINE_REMOVECOMPILER + // parse + int errors = gmCodeTree::Get().Lock(a_string, &m_log); + if(errors > 0) + { + gmCodeTree::Get().Unlock(); + if(a_errorCount) + *a_errorCount = errors; + return NULL; + } + + // compile + gmHooks hooks(this, a_string, a_filename); + errors = gmCodeGen::Get().Lock(gmCodeTree::Get().GetCodeTree(), &hooks, m_debug, &m_log); + if(errors > 0) + { + gmCodeTree::Get().Unlock(); + gmCodeGen::Get().Unlock(); + if(a_errorCount) + *a_errorCount = errors; + return NULL; + } + + gmCodeTree::Get().Unlock(); + gmCodeGen::Get().Unlock(); + + if(a_errorCount) + *a_errorCount = errors; + + return hooks.GetRootFunction(); +#endif //GMMACHINE_REMOVECOMPILER +} + + +gmFunctionObject * gmMachine::BindLibToFunction(gmStream &a_stream, const char * a_filename) +{ + gmFunctionObject * rootFunction = gmLibHooks::BindLib(*this, a_stream, a_filename); + return rootFunction; +} + + +gmThread * gmMachine::CreateThread(const gmVariable &a_this, const gmVariable &a_function, int * a_threadId) +{ + gmThread * thread = CreateThread(a_threadId); + thread->Push(a_this); + thread->Push(a_function); + if(thread->PushStackFrame(0, 0) == gmThread::RUNNING) return thread; + return NULL; +} + + +void gmMachine::Sys_SignalCreateThread(gmThread * a_thread) +{ + // Send create thread message + if(s_machineCallback) + { + s_machineCallback(this, MC_THREAD_CREATE, a_thread); + } +} + + +gmThread * gmMachine::CreateThread(int * a_threadId) +{ + gmThread * thread = m_killedThreads.RemoveFirst(); + if(thread == NULL) + { + thread = GM_NEW( gmThread(this) ); + } + thread->Sys_Reset(GetThreadId()); + if(a_threadId) *a_threadId = thread->GetId(); + m_threads.Insert(thread); + thread->Sys_SetState(gmThread::RUNNING); + thread->Sys_SetStartTime(m_time); + m_runningThreads.InsertLast(thread); // insert last to maintain propper execution order. + + if( m_nextThreadValid + && (!m_runningThreads.IsValid(m_nextThread)) ) + { + m_nextThread = thread; // Inserted last, but iterator was at last pos, if we don't do this, we'll miss skip this thread until next cycle. + } + + return thread; +} + + + +gmThread * gmMachine::GetThread(int a_threadId) +{ + return m_threads.Find(a_threadId); +} + + + +bool gmMachine::Signal(const gmVariable &a_signal, int a_dstThreadId, int a_srcThreadId) +{ + gmBlockList * blockList = m_blocks.Find(a_signal); + bool used = false; + + if(blockList) + { + // iterate over all threads in the block list, and add the signal to the appropriate threads. + gmBlock * block = blockList->m_blocks.GetFirst(); + while(blockList->m_blocks.IsValid(block)) + { + gmThread * thread = block->m_thread; + if(a_dstThreadId == GM_INVALID_THREAD || a_dstThreadId == thread->GetId()) + { + gmSignal * signal = NULL; + used = true; + + // allocate a signal + if(thread->GetState() == gmThread::SYS_PENDING) + { + signal = (gmSignal *) Sys_Alloc(sizeof(gmSignal)); + signal->m_signal = a_signal; + signal->m_srcThreadId = a_srcThreadId; + signal->m_dstThreadId = a_dstThreadId; + signal->m_nextSignal = thread->Sys_GetSignals(); + thread->Sys_SetSignals(signal); + } + else + { + block->m_signalled = true; + block->m_srcThreadId = a_srcThreadId; + thread->Sys_SetState(gmThread::SYS_PENDING); + } + + if(a_dstThreadId != GM_INVALID_THREAD) break; + } + block = blockList->m_blocks.GetNext(block); + } + } + return used; +} + + + +int gmMachine::Sys_Block(gmThread * a_thread, int m_numBlocks, const gmVariable * a_blocks) +{ + // use up our signals. + gmSignal * signal = a_thread->Sys_GetSignals(), * next; + + while(signal) + { + int i; + for(i = 0; i < m_numBlocks; ++i) + { + if(a_blocks[i].m_type == signal->m_signal.m_type && + a_blocks[i].m_value.m_ref == signal->m_signal.m_value.m_ref) + { + // remove the signal + a_thread->Sys_SetSignals(signal->m_nextSignal); + Sys_Free(signal); + + // return the block + return i; + } + } + + // we didnt fire on the signal, so remove it. + next = signal->m_nextSignal; + a_thread->Sys_SetSignals(next); + Sys_Free(signal); + signal = next; + } + + // add the blocks. + int i; + for(i = 0; i < m_numBlocks; ++i) + { + gmBlockList * blockList = m_blocks.Find(a_blocks[i]); + if(blockList == NULL) + { + blockList = (gmBlockList *) Sys_Alloc(sizeof(gmBlockList)); + blockList = gmConstructElement(blockList); + blockList->m_block = a_blocks[i]; + m_blocks.Insert(blockList); + } + + gmBlock * block = (gmBlock *) Sys_Alloc(sizeof(gmBlock)); + block->m_list = blockList; + block->m_block = a_blocks[i]; + block->m_signalled = false; + block->m_thread = a_thread; + block->m_nextBlock = a_thread->Sys_GetBlocks(); + a_thread->Sys_SetBlocks(block); + blockList->m_blocks.InsertFirst(block); + } + return -1; +} + + + +void gmMachine::KillThread(int a_threadId) +{ + gmThread * thread = GetThread(a_threadId); + if(thread) + { + Sys_SwitchState(thread, gmThread::KILLED); + } +} + + +void gmMachine::ForEachThread(gmThreadIteratorCallback a_callback, void * a_context) +{ + gmListDouble::Iterator it; + + for(it = m_runningThreads.First(); it;) + { + gmThread * thread = it.Resolve(); + ++it; + if(!a_callback(thread, a_context)) return; + } + + for(it = m_blockedThreads.First(); it;) + { + gmThread * thread = it.Resolve(); + ++it; + if(!a_callback(thread, a_context)) return; + } + + for(it = m_sleepingThreads.First(); it;) + { + gmThread * thread = it.Resolve(); + ++it; + if(!a_callback(thread, a_context)) return; + } + + for(it = m_exceptionThreads.First(); it;) + { + gmThread * thread = it.Resolve(); + ++it; + if(!a_callback(thread, a_context)) return; + } +} + + + +void gmMachine::Sys_SwitchState(gmThread * a_thread, int a_to) +{ + if(a_thread->GetState() == (gmThread::State) a_to) return; + switch(a_thread->GetState()) + { + case gmThread::RUNNING : + { + Sys_RemoveSignals(a_thread); + if(a_thread == m_nextThread) + { + m_nextThread = m_runningThreads.GetNext(a_thread); + } + m_runningThreads.Remove(a_thread); + break; + } + case gmThread::BLOCKED : + case gmThread::SYS_PENDING : + { + // remove and clean up the blocks. + Sys_RemoveBlocks(a_thread); + m_blockedThreads.Remove(a_thread); + break; + } + case gmThread::SLEEPING : m_sleepingThreads.Remove(a_thread); break; + case gmThread::KILLED : m_killedThreads.Remove(a_thread); break; + case gmThread::EXCEPTION : m_exceptionThreads.Remove(a_thread); break; + default : GM_ASSERT(0); break; + } + switch(a_to) + { + case gmThread::RUNNING : m_runningThreads.InsertLast(a_thread); break; + case gmThread::BLOCKED : m_blockedThreads.InsertFirst(a_thread); break; + case gmThread::EXCEPTION : m_exceptionThreads.InsertFirst(a_thread); break; + case gmThread::SLEEPING : + { + // insert ordered by thread time stamp (GetTimeStamp) + gmListDouble::Iterator it = m_sleepingThreads.First(); + bool inserted = false; + while(it) + { + if(it->GetTimeStamp() > a_thread->GetTimeStamp()) + { + m_sleepingThreads.InsertBefore(it.Resolve(), a_thread); + inserted = true; + break; + } + ++it; + } + if(!inserted) m_sleepingThreads.InsertLast(a_thread); + break; + } + case gmThread::KILLED : + { + // Change the thread state before resetting the thread for consistency. + // The reset will clear the state. + a_thread->Sys_SetState(gmThread::KILLED); + + // send destroy thread message + if(s_machineCallback) + { + s_machineCallback(this, MC_THREAD_DESTROY, a_thread); + } + + m_threads.Remove(a_thread); + a_thread->Sys_Reset(0); + + if(m_killedThreads.Count() < GMMACHINE_MAXKILLEDTHREADS) + { + m_killedThreads.InsertFirst(a_thread); + // Thread is dead and we don't want to set it's state (already set). + // Besides it's ID is now invalid. + return; + } + // NOTE: Might be good to always delay thread deletion so killed threads are valid in nested call stacks. + // Would we need to take care not to reuse a recent thread if it could still be read/written to? + delete a_thread; + return; + } + default : GM_ASSERT(0); break; + } + a_thread->Sys_SetState((gmThread::State) a_to); +} + + +void gmMachine::KillExceptionThreads() +{ + gmThread * thread = m_exceptionThreads.GetLast(); + while(m_exceptionThreads.IsValid(thread)) + { + Sys_SwitchState(thread, gmThread::KILLED); + thread = m_exceptionThreads.GetLast(); + } +} + + + +int gmMachine::Execute(gmuint32 a_delta) +{ + m_time += a_delta; + + // + // Wake up any sleeping threads at their timestamp + // + for(;;) + { + gmThread * thread = m_sleepingThreads.GetFirst(); + if(m_sleepingThreads.IsValid(thread) && (thread->GetTimeStamp() <= m_time)) + { + Sys_SwitchState(thread, gmThread::RUNNING); + continue; + } + break; + } + + // + // Move all SYS_PENDING threads from the blocked list to the front of the RUNNING list. + // + gmThread * it, * nit; + for(it = m_blockedThreads.GetFirst(); m_blockedThreads.IsValid(it);) + { + nit = m_blockedThreads.GetNext(it); + if(it->GetState() == gmThread::SYS_PENDING) + { + // get the unblocking signal + gmBlock * block = it->Sys_GetBlocks(); + while(block) + { + if(block->m_signalled) break; + block = block->m_nextBlock; + } + GM_ASSERT(block); + it->Pop(); + it->Push(block->m_block); + + // move the thread to the running state + Sys_SwitchState(it, gmThread::RUNNING); + } + it = nit; + } + + // + // Execute running threads + // + m_nextThreadValid = true; + for(it = m_runningThreads.GetFirst(); m_runningThreads.IsValid(it);) + { + m_nextThread = m_runningThreads.GetNext(it); + it->Sys_Execute(); + it = m_nextThread; + } + m_nextThreadValid = false; + + CollectGarbage(); + + return m_threads.Count(); +} + + +void gmMachine::Presize(int a_pool8, + int a_pool16, + int a_pool24, + int a_pool32, + int a_pool64, + int a_pool128, + int a_pool256, + int a_pool512, + int a_gmStringObj, + int a_gmTableObj, + int a_gmFunctionObj, + int a_gmUserObj, + int a_gmStackFrame + ) +{ + m_fixedSet.Presize(a_pool8, a_pool16, a_pool24, a_pool32, a_pool64, a_pool128, a_pool256, a_pool512); + if( a_gmStringObj ) { m_memStringObj.Presize(a_gmStringObj); } + if( a_gmTableObj) { m_memTableObj.Presize(a_gmTableObj); } + if( a_gmFunctionObj ) { m_memFunctionObj.Presize(a_gmFunctionObj); } + if( a_gmUserObj ) { m_memUserObj.Presize(a_gmUserObj); } + if( a_gmStackFrame ) { m_memStackFrames.Presize(a_gmStackFrame); } +} + + +#if GM_USE_INCGC + +bool gmMachine::CollectGarbage(bool a_forceFullCollect) +{ + // NOTES: + // + // 1) If the desired hard memory limit is set high and the + // desired soft memory limit collects before ever reaching the hard limit + // the actual amount of memory used is unknown as there is always some + // slack memory in use or being classified. This is normal, but may not + // help calibrate memory limits. + // + // 2) You may want to calibrate memory usage by setting the hard limit too low + // then letting it grow as it needs to. After that, adjust the soft limit + // until the full collects never occur. + // + // 3) The hard and soft limits should be set well above the actual used memory limit + // for efficient operation (wheather manually or automatically). If this is not + // the case, the GC may occur unnecessarily often. + // + + bool result = false; + if(m_gcEnabled) + { + GM_ASSERT(GetDesiredByteMemoryUsageSoft() <= GetDesiredByteMemoryUsageHard()); + GM_ASSERT(GetDesiredByteMemoryUsageHard() > 0); + + // Even with assert, to prevent undefined behaviour, don't let soft limit be set above hard limit here. + if(GetDesiredByteMemoryUsageSoft() > GetDesiredByteMemoryUsageHard()) + { + SetDesiredByteMemoryUsageSoft(GetDesiredByteMemoryUsageHard()); + } + + ++m_framesSinceLastIncCollect; + + // Have we exceeded the hard limit? + if(a_forceFullCollect || (GetCurrentMemoryUsage() > GetDesiredByteMemoryUsageHard())) + { + //int beforeMemUsage = GetCurrentMemoryUsage(); + ++m_statsGCFullCollect; + result = true; + + // Perform full collection & reclaimation now + m_gc->FullCollect(); + + if(m_autoMem) + { + int afterMemUsage = GetCurrentMemoryUsage(); + if(afterMemUsage < GetDesiredByteMemoryUsageSoft()) // Used must be below both soft and hard + { + float fracMemUsed = ((float)afterMemUsage / (float)GetDesiredByteMemoryUsageHard()); + + // If we hardly used any of our memory, let the memory limit shrink + if(fracMemUsed < GMMACHINE_GC_HARD_MEM_SHRINK_THRESH) + { + if( GMMACHINE_AUTOMEMALLOWSHRINK ) + { + SetDesiredByteMemoryUsageHard( (int)(GMMACHINE_GC_HARD_MEM_DEC_FRAC_OF_USED * (float)afterMemUsage) ); + SetDesiredByteMemoryUsageSoft( (int)(GMMACHINE_GC_SOFT_MEM_DEFAULT_FRAC_OF_HARD * (float)GetDesiredByteMemoryUsageHard()) ); + } + } + else + { + float softFrac = (float)GetDesiredByteMemoryUsageSoft() / (float)GetDesiredByteMemoryUsageHard(); + softFrac -= GMMACHINE_GC_SOFT_MEM_DEC_FRAC; + if(softFrac > GMMACHINE_GC_SOFT_MEM_MIN_FRAC) + { + // We ran out of memory, but the machine didn't need to, we should have started inc GC earlier + int desired = (int)(softFrac * (float)GetDesiredByteMemoryUsageHard()); + if(desired > afterMemUsage) + { + SetDesiredByteMemoryUsageSoft(desired); + // NOTE: Not using GMMACHINE_AUTOMEMALLOWSHRINK here because hard limit is the critical + // one and soft limit was badly set, so allow soft to be shrunk in this case only. + } + } + else + { + // This should never occur. + // The GC needs to be configured to collect more per cycle so it finishes faster + // Check out the values of m_gc.GetWorkPerIncrement() and m_gc.GetDestructPerIncrement() + ++m_statsGCWarnings; + } + } + } + else + { + // We ran out of memory because we needed more than our limit, so increase limit + int newHard = (int)(GMMACHINE_GC_HARD_MEM_INC_FRAC_OF_USED * (float)afterMemUsage); + int newSoft = (int)(GMMACHINE_GC_SOFT_MEM_DEFAULT_FRAC_OF_HARD * (float)GetDesiredByteMemoryUsageHard()); + + if( !GMMACHINE_AUTOMEMALLOWSHRINK ) + { + // Don't allow shrink + newSoft = gmMax(newSoft, GetDesiredByteMemoryUsageSoft()); + newHard = gmMax(newHard, GetDesiredByteMemoryUsageHard()); + // We can only size up, so make sure hard limit is at least this fraction above soft + float softFracHard = (float)newSoft / (float)newHard; + if( softFracHard < GMMACHINE_GC_SOFT_MEM_DEFAULT_FRAC_OF_HARD ) + { + newHard = (int)(newSoft * (1.0f / GMMACHINE_GC_SOFT_MEM_DEFAULT_FRAC_OF_HARD) ); + } + } + + SetDesiredByteMemoryUsageHard( newHard ); + SetDesiredByteMemoryUsageSoft( newSoft ); + } + } + } + else + { + // If we are not collecting, see if we need to start + if(m_gc->IsOff()) + { + // Have esceeded the soft limit? + if(GetCurrentMemoryUsage() > GetDesiredByteMemoryUsageSoft()) + { + // Reclaim memory from known garbage if we can + if(!m_gc->ReclaimSomeFreeObjects()) + { + ++m_gcPhaseCount; + + // Turn GC back on + m_gc->ReclaimObjectsAndRestartCollection(); + } + } + } + // If we are collecting, then collect some more this opportunity + if(!m_gc->IsOff()) + { + if(m_gc->Collect()) + { + // We have finished collecting. The to-be-freed memory will still be waiting for reclaimation. + if( m_gcPhaseCount == 2 ) + { + m_gcPhaseCount = 0; + if(m_framesSinceLastIncCollect < GMMACHINE_GC_MIN_FRAMES_SINCE_RESTART) + { + // Since we got here and we have been collecting very regularly, + // the soft limit may be set too close to the actual memory usage + // causing oscilation. Both the hard and soft limits should be set higher. + ++m_statsGCWarnings; + } + m_framesSinceLastIncCollect = 0; + } + ++m_statsGCIncCollect; + + // Note that this point is not the low memory after a GC cycle. + // It may be half of the two part process after restarting due to the alloc black method. + // If GC took a while, lots of new allocs may have built up also. + // This is the reason auto-calibrating memory limits in the soft range is difficult. + } + } + } + } + + return result; +} + + +bool gmMachine::IsGCRunning() +{ + return !m_gc->IsOff(); +} + + +#else //GM_USE_INCGC + +bool gmMachine::CollectGarbage(bool a_forceFullCollect) +{ + gmThread * tit; + gmObject * obj; + + // do we need to garbage collect? + if(m_gcEnabled && (a_forceFullCollect || (GetCurrentMemoryUsage() > m_desiredByteMemoryUsageHard)) ) + { + //printf("************* COLLECTING GARBAGE ****************"GM_NL); + + if(++m_mark == GM_MARK_PERSIST) m_mark = GM_MARK_START + 1; + + // call the gc callback + if(s_machineCallback) s_machineCallback(this, MC_COLLECT_GARBAGE, (void *) &m_mark); + + // iterate cpp owned gmObjects + gmHash::Iterator cgmoIt; + for(cgmoIt = a_machine->m_cppOwnedGMObjs.First(); cgmoIt; ++cgmoIt) + { + gmObject* curObj = cgmoIt->m_obj; + curObj->Mark(a_machine, mark); + } + + // iterate over all threads and mark the stacks. + for(tit = m_runningThreads.GetFirst(); m_runningThreads.IsValid(tit); tit = m_runningThreads.GetNext(tit)) tit->Mark(m_mark); + for(tit = m_blockedThreads.GetFirst(); m_blockedThreads.IsValid(tit); tit = m_blockedThreads.GetNext(tit)) tit->Mark(m_mark); + for(tit = m_sleepingThreads.GetFirst(); m_sleepingThreads.IsValid(tit); tit = m_sleepingThreads.GetNext(tit)) tit->Mark(m_mark); + for(tit = m_exceptionThreads.GetFirst(); m_exceptionThreads.IsValid(tit); tit = m_exceptionThreads.GetNext(tit)) tit->Mark(m_mark); + + // iterate over global variables and mark + m_global->Mark(this, m_mark); + gmuint i; + for(i = 0; i < m_types.Count(); ++i) + { + m_types[i].m_variables->Mark(this, m_mark); + } + +#if GMMACHINE_THREEPASSGC + // mark any persisting objects such that they may mark their children + obj = m_objects; + while(obj) + { + if(obj->m_mark == GM_MARK_PERSIST) + { + obj->Mark(this, m_mark); + } + obj = obj->m_sysNext; + } +#endif // GMMACHINE_THREEPASSGC + + // iterate over all objects, destruct any old object and free it. + gmObject ** objnext = &m_objects; + while(*objnext) + { + obj = *objnext; + if(obj->m_mark != m_mark && obj->m_mark != GM_MARK_PERSIST) + { + *objnext = obj->m_sysNext; + obj->Destruct(this); + FreeObject(obj); + } + else + { + objnext = &obj->m_sysNext; + } + } + + if(m_autoMem) + { + m_desiredByteMemoryUsageHard = (int) (GMMACHINE_AUTOMEMMULTIPY * (float) GetCurrentMemoryUsage()); + } + + return true; + } + + return false; +} + + +bool gmMachine::IsGCRunning() +{ + return false; +} + + +#endif //GM_USE_INCGC + + +unsigned int gmMachine::GetSystemMemUsed() const +{ + unsigned int total = 0; + total += m_memStringObj.GetSystemMemUsed(); + total += m_memTableObj.GetSystemMemUsed(); + total += m_memFunctionObj.GetSystemMemUsed(); + total += m_memUserObj.GetSystemMemUsed(); + total += m_memStackFrames.GetSystemMemUsed(); + total += m_fixedSet.GetSystemMemUsed(); + + // threads + gmThread * tit; + for(tit = m_runningThreads.GetFirst(); m_runningThreads.IsValid(tit); tit = m_runningThreads.GetNext(tit)) total += tit->GetSystemMemUsed(); + for(tit = m_blockedThreads.GetFirst(); m_blockedThreads.IsValid(tit); tit = m_blockedThreads.GetNext(tit)) total += tit->GetSystemMemUsed(); + for(tit = m_sleepingThreads.GetFirst(); m_sleepingThreads.IsValid(tit); tit = m_sleepingThreads.GetNext(tit)) total += tit->GetSystemMemUsed(); + for(tit = m_killedThreads.GetFirst(); m_killedThreads.IsValid(tit); tit = m_killedThreads.GetNext(tit)) total += tit->GetSystemMemUsed(); + for(tit = m_exceptionThreads.GetFirst(); m_exceptionThreads.IsValid(tit); tit = m_exceptionThreads.GetNext(tit)) total += tit->GetSystemMemUsed(); + + return total; +} + +#include "memdbgoff.h" + +gmStringObject * gmMachine::AllocStringObject(const char * a_string, int a_length) +{ + gmStringObject * newStringObj = m_strings.Find(a_string); + if(newStringObj) + { + m_gc->Revive(newStringObj); // If string was in free list waiting to be finalized, revive it. + return newStringObj; + } + + if(a_length < 0) + { + a_length = strlen(a_string); + } + char * string = (char *) Sys_Alloc(a_length + 1); + memcpy(string, a_string, a_length + 1); + +#if GMMACHINE_GCEVERYALLOC + CollectGarbage(); +#endif + newStringObj = (gmStringObject *) m_memStringObj.Alloc(); + + GM_PLACEMENT_NEW( gmStringObject(string, a_length), newStringObj ); + +#if GM_USE_INCGC + m_gc->AllocateObject(newStringObj); + //AddCountObj(newStringObj); +#else //GM_USE_INCGC + GM_ADDOBJECT(newStringObj); +#endif //GM_USE_INCGC + + // insert into hash + m_strings.Insert(newStringObj); + + m_currentMemoryUsage += sizeof(gmStringObject); + return newStringObj; +} + + + +gmStringObject * gmMachine::AllocPermanantStringObject(const char * a_string, int a_length) +{ + gmStringObject * newStringObj = AllocStringObject(a_string, a_length); +#if GM_USE_INCGC + newStringObj->SetPersist(true); + #if GM_GC_KEEP_PERSISTANT_SEPARATE + m_gc->MakeObjectPersistant(newStringObj); + #else //GM_GC_KEEP_PERSISTANT_SEPARATE + m_permanantStrings.InsertLast(newStringObj); + #endif //GM_GC_KEEP_PERSISTANT_SEPARATE +#else //GM_USE_INCGC + newStringObj->m_mark = GM_MARK_PERSIST; +#endif //GM_USE_INCGC + + return newStringObj; +} + + + +gmTableObject * gmMachine::AllocTableObject() +{ +#if GMMACHINE_GCEVERYALLOC + CollectGarbage(); +#endif + gmTableObject * newTableObj = (gmTableObject *) m_memTableObj.Alloc(); + GM_PLACEMENT_NEW(gmTableObject, newTableObj); + +#if GM_USE_INCGC + m_gc->AllocateObject(newTableObj); + //AddCountObj(newTableObj); +#else //GM_USE_INCGC + GM_ADDOBJECT(newTableObj); +#endif //GM_USE_INCGC + + m_currentMemoryUsage += sizeof(gmTableObject); + return newTableObj; +} + +gmFunctionObject * gmMachine::AllocFunctionObject(gmCFunction a_function) +{ +#if GMMACHINE_GCEVERYALLOC + CollectGarbage(); +#endif + gmFunctionObject * newFunctionObj = (gmFunctionObject *) m_memFunctionObj.Alloc(); + GM_PLACEMENT_NEW(gmFunctionObject, newFunctionObj); + +#if GM_USE_INCGC + m_gc->AllocateObject(newFunctionObj); + //AddCountObj(newFunctionObj); +#else //GM_USE_INCGC + GM_ADDOBJECT(newFunctionObj); +#endif //GM_USE_INCGC + + newFunctionObj->m_cFunction = a_function; + + m_currentMemoryUsage += sizeof(gmFunctionObject); + return newFunctionObj; +} + +#include "memdbgon.h" + + + +gmUserObject * gmMachine::AllocUserObject(void * a_user, int a_userType) +{ +#if GMMACHINE_GCEVERYALLOC + CollectGarbage(); +#endif + gmUserObject * newUserObj = (gmUserObject *) m_memUserObj.Alloc(); + gmConstructElement(newUserObj); + +#if GM_USE_INCGC + m_gc->AllocateObject(newUserObj); + //AddCountObj(newUserObj); +#else //GM_USE_INCGC + GM_ADDOBJECT(newUserObj); +#endif //GM_USE_INCGC + + newUserObj->m_userType = a_userType; + newUserObj->m_user = a_user; + m_currentMemoryUsage += sizeof(gmUserObject); + return newUserObj; +} + + + +void gmMachine::Sys_FreeUniqueString(const char * a_string) +{ + if(m_strings.RemoveKey(a_string)) + { + Sys_Free(const_cast(a_string)); + } +} + + + +int gmMachine::GetThreadId() +{ + while(GetThread(++m_threadId)) {} + return m_threadId; +} + + + +void gmMachine::FreeObject(gmObject * a_obj) +{ + //RemoveCountObj(a_obj); + + switch(a_obj->GetType()) + { + case GM_STRING: + { + m_memStringObj.Free(a_obj); + m_currentMemoryUsage -= sizeof(gmStringObject); + break; + } + case GM_TABLE: + { + m_memTableObj.Free(a_obj); + m_currentMemoryUsage -= sizeof(gmTableObject); + break; + } + case GM_FUNCTION: + { + m_memFunctionObj.Free(a_obj); + m_currentMemoryUsage -= sizeof(gmFunctionObject); + break; + } + default: // >= GM_USER types + { + m_memUserObj.Free(a_obj); + m_currentMemoryUsage -= sizeof(gmUserObject); + break; + } + } +} + + +#if GM_USE_INCGC +gmObject * gmMachine::CheckReference(gmptr a_ref) +{ + return m_gc->CheckReference(a_ref); +} +#else //GM_USE_INCGC +gmObject * gmMachine::CheckReference(gmptr a_ref) +{ + for(gmObject* it = m_objects; it; it = it->m_sysNext) + { + if((gmptr)it == a_ref) + { + return it; + } + } + + // check global refs + if(a_ref == (gmptr) m_global) return m_global; + + GM_ASSERT(0); + return NULL; +} +#endif //GM_USE_INCGC + + +void gmMachine::Type::Init() +{ + m_variables = NULL; + m_name = NULL; + memset(m_nativeOperators, 0, sizeof(gmOperatorFunction) * O_MAXOPERATORS); + memset(m_operators, 0, sizeof(gmptr) * O_MAXOPERATORS); + m_asString = NULL; +#if GM_USE_INCGC + m_gcDestruct = NULL; + m_gcTrace = NULL; +#else + m_mark = NULL; + m_gc = NULL; +#endif + m_asString = NULL; +} + + + +void gmMachine::ResetDefaultTypes() +{ + // clean up old types + gmuint i; + for(i = 0; i < m_types.Count(); ++i) + { +#if GM_USE_INCGC + //Note, old objects must be null or already destructed by GC + m_types[i].m_variables = NULL; + m_types[i].m_name = NULL; +#else //GM_USE_INCGC + m_types[i].m_variables->Destruct(this); + FreeObject(m_types[i].m_variables); + m_types[i].m_name = NULL; +#endif //GM_USE_INCGC + } + + // init the basic types + m_types.SetCount(GM_USER); + // Alloc type table + for(i=0; iSys_GetBlocks(), * next; + while(block) + { + next = block->m_nextBlock; + gmBlockList * list = block->m_list; + block->Remove(); + if(list->m_blocks.IsEmpty()) + { + list = (gmBlockList *) m_blocks.Remove(list); + Sys_Free(list); + } + Sys_Free(block); + block = next; + } + a_thread->Sys_SetBlocks(NULL); +} + + + +void gmMachine::Sys_RemoveSignals(gmThread * a_thread) +{ + gmSignal * signal = a_thread->Sys_GetSignals(), * next; + while(signal) + { + next = signal->m_nextSignal; + Sys_Free(signal); + signal = next; + } + a_thread->Sys_SetSignals(NULL); +} + + + +gmuint32 gmMachine::AddSourceCode(const char * a_source, const char * a_filename) +{ + gmuint32 id = 0; + + if(a_filename == NULL) { a_filename = "unknown"; } + + if(m_debug) + { + // calculate the id. + id = gmCrc32String(a_source); + + // see if we already have the source. + gmSourceEntry * entry = m_source.GetFirst(); + while(m_source.IsValid(entry)) + { + if(entry->m_id == id) + { + return id; + } + entry = m_source.GetNext(entry); + } + + // we dont have it, add it + m_source.InsertFirst( GM_NEW( gmSourceEntry(a_source, a_filename) ) ); + } + return id; +} + + + +bool gmMachine::GetSourceCode(gmuint32 a_id, const char * &a_source, const char * &a_filename) +{ + if(m_debug) + { + gmSourceEntry * entry = m_source.GetFirst(); + while(m_source.IsValid(entry)) + { + if(entry->m_id == a_id) + { + a_source = entry->m_source; + a_filename = entry->m_filename; + return true; + } + entry = m_source.GetNext(entry); + } + } + return false; +} + + + +#if GM_USE_INCGC +const void * gmMachine::GetInstructionAtBreakPoint(gmuint32 a_sourceId, int a_line) +{ + return m_gc->GetInstructionAtBreakPoint(a_sourceId, a_line); +} +#else //GM_INC_GM +const void * gmMachine::GetInstructionAtBreakPoint(gmuint32 a_sourceId, int a_line) +{ + gmObject * object = m_objects; + while(object) + { + if(object->GetType() == GM_FUNCTION) + { + gmFunctionObject * function = (gmFunctionObject *) object; + if(function->GetSourceId() == a_sourceId) + { + const void * i = function->GetInstructionAtLine(a_line); + if(i) return i; + } + } + object = object->m_sysNext; + } + return NULL; +} +#endif //GM_INC_GM + + +bool gmMachine::IsCPPOwnedGMObject(gmObject * a_obj) +{ + ObjHashNode * foundNode = m_cppOwnedGMObjs.Find(a_obj); + return (foundNode != NULL); +} + + +void gmMachine::AddCPPOwnedGMObject(gmObject * a_obj) +{ + if( !a_obj ) + { + return; // Ignore NULL + } + +#ifdef GM_DEBUG_BUILD + // Should not already exist + ObjHashNode * foundNode = m_cppOwnedGMObjs.Find(a_obj); + GM_ASSERT( !foundNode ); +#endif //GM_DEBUG_BUILD + + ObjHashNode * newNode = (ObjHashNode *)Sys_Alloc( sizeof(ObjHashNode) ); + newNode->m_obj = a_obj; + m_cppOwnedGMObjs.Insert(newNode); +} + + +void gmMachine::RemoveCPPOwnedGMObject(gmObject * a_obj) +{ + if( !a_obj ) + { + return; // Ignore NULL + } + + ObjHashNode * foundNode = m_cppOwnedGMObjs.Find(a_obj); + if( foundNode ) + { + m_cppOwnedGMObjs.Remove(foundNode); + Sys_Free(foundNode); + + // Apply write barrier for this logical LHS + m_gc->WriteBarrier(a_obj); + } +} + + +void gmMachine::RemoveAllCPPOwnedGMObjects() +{ + gmHash::Iterator iter( &m_cppOwnedGMObjs ); + while ( iter.IsValid() ) + { + ObjHashNode *pNode = iter.Resolve(); + iter.Inc(); + Sys_Free(pNode); + } + m_cppOwnedGMObjs.RemoveAll(); +} + + +gmTableObject * gmMachine::GetTypeTable(gmType a_type) +{ + if( (a_type >= 0) && (a_type < (int)m_types.Count()) ) + { + return m_types[a_type].m_variables; + } + return NULL; +} + +// +// +// Implementation of gmHooks +// +// + + + +gmHooks::gmHooks(gmMachine * a_machine, const char * a_source, const char * a_filename) : + m_machine(a_machine), + m_source(a_source), + m_filename(a_filename) +{ + m_gcEnabled = a_machine->IsGCEnabled(); + m_debug = false; + m_errors = 0; + m_rootFunction = NULL; + m_sourceId = 0; +} + + + +gmHooks::~gmHooks() +{ +} + + + +bool gmHooks::Begin(bool a_debug) +{ + m_gcEnabled = m_machine->IsGCEnabled(); + m_machine->EnableGC(false); + + // add the source code. if we are debugging + if(a_debug) + { + m_sourceId = m_machine->AddSourceCode(m_source, m_filename); + } + + m_debug = a_debug; + return true; +} + + + +bool gmHooks::AddFunction(gmFunctionInfo &a_info) +{ + gmObject * object = GM_MOBJECT(m_machine, a_info.m_id); + if(object->GetType() == GM_FUNCTION) + { + gmFunctionObject * function = (gmFunctionObject *) object; + if(a_info.m_root) { m_rootFunction = function; } + return function->Init(m_machine, m_debug, a_info, m_sourceId); + } + return false; +} + + + +bool gmHooks::End(int a_errors) +{ + m_machine->EnableGC(m_gcEnabled); + m_errors = a_errors; + return true; +} + + + +gmptr gmHooks::GetFunctionId() +{ + return (gmptr) m_machine->AllocFunctionObject(NULL); +} + + + +gmptr gmHooks::GetSymbolId(const char * a_symbol) +{ + return (gmptr) m_machine->AllocPermanantStringObject(a_symbol); +} + + + +gmptr gmHooks::GetStringId(const char * a_string) +{ + return (gmptr) m_machine->AllocStringObject(a_string); +} diff --git a/vscript/languages/gm/src/gm/gmMachine.h b/vscript/languages/gm/src/gm/gmMachine.h new file mode 100644 index 00000000..463eb5a8 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmMachine.h @@ -0,0 +1,692 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in this file + +*/ + +#ifndef _GMMACHINE_H_ +#define _GMMACHINE_H_ + +/********************************************************** + GameMonkey Script + created by + Matthew Riek and Greg Douglas +**********************************************************/ + +/********************************************************** +GameMonkey Script License + +Copyright (c) 2003 Auran Development Ltd. + +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. +**********************************************************/ + +#include "gmConfig.h" +#include "gmMemFixed.h" +#include "gmMemFixedSet.h" +#include "gmLog.h" +#include "gmVariable.h" +#include "gmTableObject.h" +#include "gmOperators.h" +#include "gmFunctionObject.h" +#include "gmHash.h" +#include "gmArraySimple.h" +#include "gmIncGC.h" + +#undef GetObject //Argh Windows defines this in WINGDI.H + +#define GM_VERSION "1.24" + +// fwd decls +class gmStringObject; +class gmUserObject; +class gmMachine; +class gmThread; +struct gmStackFrame; +struct gmSignal; +class gmSourceEntry; +class gmStream; +class gmBlockList; + +enum gmMachineCommand +{ + MC_COLLECT_GARBAGE = 0, // called when a gc cycle is run, a_context is the gc mark + + MC_THREAD_EXCEPTION, // called when a thread causes an exception. a_context is the thread. (which is about to die) return false to kill thread, else it will hang around for debugging + MC_THREAD_CREATE, // called when a thread is created. a_context is the thread. + MC_THREAD_DESTROY, // called when a thread is destroyed. a_context is the thread. (which is about to die) +}; + +/// \brief gmMachineCallback is a callback used for debugger tie ins etc. +/// \return depends on a_command +typedef bool (GM_CDECL *gmMachineCallback)(gmMachine * a_machine, gmMachineCommand a_command, const void * a_context); +#if GM_USE_INCGC + typedef void (GM_CDECL *gmGCDestructCallback)(gmMachine * a_machine, gmUserObject* a_object); + typedef bool (GM_CDECL *gmGCTraceCallback)(gmMachine * a_machine, gmUserObject* a_object, gmGarbageCollector* a_gc, const int a_workLeftToGo, int& a_workDone); +#else //GM_USE_INCGC + typedef void (GM_CDECL *gmGarbageCollectCallback)(gmMachine * a_machine, gmUserObject * a_object, gmuint32 a_mark); +#endif //GM_USE_INCGC + +/// \brief gmAsStringCallback is a callback registered with a gm type, which will convert the type to a string for print and debug purposes, the callback must +/// convert the type to a string < 256 characters long. +/// \param a_bufferSize at least 256 chars +typedef void (GM_CDECL *gmAsStringCallback)(gmUserObject * a_userObj, char * a_buffer, int a_bufferSize); +typedef void (GM_CDECL *gmPrintCallback)(gmMachine * a_machine, const char * a_string); +typedef bool (GM_CDECL *gmThreadIteratorCallback)(gmThread * a_thread, void * a_context); +typedef bool (GM_CDECL *gmUserBreakCallback)(gmThread * a_thread); + +// the following callbacks return true if the thread is to yield after completion of the callback. +typedef bool (GM_CDECL *gmDebugLineCallback)(gmThread * a_thread); +typedef bool (GM_CDECL *gmDebugCallCallback)(gmThread * a_thread); +typedef bool (GM_CDECL *gmDebugRetCallback)(gmThread * a_thread); +typedef bool (GM_CDECL *gmDebugIsBrokenCallback)(gmThread * a_thread); // returns true if the thread is broken, or if the thread is pending delete after exception + +/// \struct gmFunctionEntry +struct gmFunctionEntry +{ + const char * m_name; + gmCFunction m_function; + const void * m_userData; ///< Optional user ptr or value to assist binding +}; + +/// \struct gmThreadInfo +struct gmThreadInfo +{ + int m_threadId; + int m_threadState; + void * m_threadDebugUser; +}; + +/// \struct gmSignal +struct gmSignal +{ + int m_srcThreadId; ///< id of the signalling thread. + int m_dstThreadId; ///< id of dst thread. + gmVariable m_signal; ///< signal. + gmSignal * m_nextSignal; ///< next thread in the threads signal list. +}; + +/// \class gmBlock +class gmBlock : public gmListDoubleNode +{ +public: + bool m_signalled; ///< has this block been signalled? + int m_srcThreadId; ///< id of the thread to cause the unblock + gmVariable m_block; ///< the block object, this will be pushed on the stack if unblocked. + gmThread * m_thread; ///< the thread this block belongs to + gmBlock * m_nextBlock; ///< next block on this thread + class gmBlockList * m_list; ///< parent block list. +}; + + +/// \class gmMachine +/// \brief the gmMachine object represents a scripting instance. many script threads may run on the one gmMachine. +/// gmMachine manages script source, script memory, garbage collection, function type overrides, operator overrides, +/// threads etc. +class gmMachine +{ +public: + + gmMachine(); + virtual ~gmMachine(); + + /// \brief ResetAndFreeMemory() will reset the gmMachine. + void ResetAndFreeMemory(); + + /// \brief Init() will recreate the machine... only need to call this if you have called ResetAndFreeMemory() + /// \sa ResetAndFreeMemory(); + void Init(); + + static gmMachineCallback s_machineCallback; ///< global machine callback + static gmPrintCallback s_printCallback; ///< global print callback + static gmUserBreakCallback s_userBreakCallback; ///< global execution break callback + + // + // + // Registry + // + // + + /// \brief RegisterLibrary() will register an array of functions to the machine as globals. + /// \param a_asTable as non-null will create a table in global scope and place the functions in the table. + /// \param a_newTable will create a new table for the functions; if false it will insert them into the existing table (if found) + void RegisterLibrary(gmFunctionEntry * a_functions, int a_numFunctions, const char * a_asTable = NULL, bool a_newTable = true); + + /// \brief RegisterTypeLibrary() will register an array of functions to the machine as type variables. + void RegisterTypeLibrary(gmType a_type, gmFunctionEntry * a_functions, int a_numFunctions); + + /// \brief RegisterLibraryFunction() will register a single functions to the machine as global. + /// \param a_name Script function name + /// \param a_function C function + /// \param a_asTable as non-null will use/create a table in global scope and place the functions in the table. + void RegisterLibraryFunction(const char * a_name, gmCFunction a_function, const char * a_asTable = NULL, const void* a_userData = NULL) + { + gmFunctionEntry entry = {a_name, a_function, a_userData}; + RegisterLibrary(&entry, 1, a_asTable, false); + } + + /// \brief RegisterTypeLibraryFunction() will register a single functions to the machine as type variable. + /// \param a_type Valid/Registered type identifier + /// \param a_name Script function name + /// \param a_function C function + void RegisterTypeLibraryFunction(gmType a_type, const char * a_name, gmCFunction a_function, const void* a_userData = NULL) + { + gmFunctionEntry entry = {a_name, a_function, a_userData}; + RegisterTypeLibrary(a_type, &entry, 1); + } + + /// \brief CreateUserType() will create a new user type such that you may bind your own operator functions etc. + /// \return the new user type. + gmType CreateUserType(const char * a_name); + + /// \brief RegisterTypeVariable() will register a variable for a given gm type. This allows a default library + /// to bind type specific functions and constants to that type. ie, binding a ToFloat() function to the + /// int type. + void RegisterTypeVariable(gmType a_type, const char * a_variableName, const gmVariable &a_variable); + + /// \brief RegisterTypeOperator() will let you regiester operators for user types only. + /// \param a_operator + /// \param a_function + /// \param a_nativeFunction + bool RegisterTypeOperator(gmType a_type, gmOperator a_operator, gmFunctionObject * a_function, gmOperatorFunction a_nativeFunction = NULL); + + /// \brief GetTypeVariable() will lookup the type variables for the given variable key. + inline gmVariable GetTypeVariable(gmType a_type, const gmVariable &a_key) const; + + /// \brief GetTypeNativeOperator() will lookup a type for a native operator + inline gmOperatorFunction GetTypeNativeOperator(gmType a_type, gmOperator a_operator); + + /// \brief GetTypeOperator() will lookup a type for a GM function operator + inline gmFunctionObject * GetTypeOperator(gmType a_type, gmOperator a_operator); + + /// \brief GetTypeName() will return the name of a_type + const char * GetTypeName(gmType a_type); + + /// \brief Access the table for a 'type', or return NULL. + gmTableObject * GetTypeTable(gmType a_type); + + // + // + // Thread Interface + // + // + + /// \brief CheckSyntax() + /// \brief return the number of errors + int CheckSyntax(const char * a_string); + + /// \brief ExecuteString() will compile a_string to byte code. If no errors occured, the code will be executed + /// in a new thread. + /// \param a_string is null terminated script string. + /// \param a_threadId is set to the id of the thread and may be NULL. + /// \param a_now is true, and execution will occur immediataly, and not at the next Execute() call. + /// \param a_filename Name of the source file, used for debug purposes, or NULL. + /// \param a_this The 'this' pointer passed to the un-named function. Or NULL to pass a null gmVariable. + /// \return the number of errors from compiling the script. + /// \sa GetCompileLog() + int ExecuteString(const char * a_string, int * a_threadId = NULL, bool a_now = true, const char * a_filename = NULL, gmVariable* a_this = NULL); + + /// \brief ExecuteLib() will execute a pre-compiled lib in a new thread + /// \param a_stream is a stream to pull the lib from + /// \param a_threadId is set to the id of the thread and may be NULL. + /// \param a_now is true, and execution will occur immediataly, and not at the next Execute() call. + /// \param a_filename is the filename the lib came from for debugging purposes. + /// \return false on lib error + bool ExecuteLib(gmStream &a_stream, int * a_threadId = NULL, bool a_now = true, const char * a_filename = NULL, gmVariable* a_this = NULL); + + /// \brief ExecuteFunction() will execute a thread on the passed function + bool ExecuteFunction(gmFunctionObject * a_function, int * a_threadId = NULL, bool a_now = true, gmVariable* a_this = NULL); + + /// \brief CompileStringToLib() will compile a_string to byte code suitable for storage in a file. + /// \param a_string is null terminated script string. + /// \param a_stream is the file stream to compile the lib to + /// \return the number of errors from compiling the script. + /// \sa GetCompileLog() + int CompileStringToLib(const char * a_string, gmStream &a_stream); + + /// \brief CompileStringToFunction() + gmFunctionObject * CompileStringToFunction(const char * a_string, int *a_errorCount = NULL, const char * a_filename = NULL); + + /// \brief BindLibToFunction() Bind a precompiled library to a function. + /// \param a_stream is a stream to pull the lib from + /// \param a_filename is the filename the lib came from for debugging purposes. + /// \return Root function from Lib or NULL if failed + gmFunctionObject * BindLibToFunction(gmStream &a_stream, const char * a_filename = NULL); + + /// \brief GetLog() will get the compile and runtime log of the last script compiled. log any runtime errors from + /// linked c functions to this log. + inline gmLog &GetLog() { return m_log; } + + /// \brief CreateThread() will create a new thread. This thread will be placed in the running thread list. + /// \param a_this + /// \param a_function + /// \param a_threadId is set to the id of the created thread and may be NULL. + /// \return a thread, or NULL if the thread finished executing or could not be created. + gmThread * CreateThread(const gmVariable &a_this, const gmVariable &a_function, int * a_threadId = NULL); + gmThread * CreateThread(int * a_threadId = NULL); + + /// \brief GetThread() will return the thread given a thread id. + /// \return NULL on error. + gmThread * GetThread(int a_threadId); + + /// \brief Signal() will signal a single thread with the given variable + /// \param a_signal is the signal var + /// \param a_dstThreadId is the thread id we wish to unblock. dstThread id of GM_INVALID_THREAD is all threads + /// \param a_srcThreadId is the thread id of the signaling object + /// \param a_persist is true and the signal may persist if it had the potential to unblock a SYS_PENDING thread. + /// \return true if the signal fired, false otherwise + bool Signal(const gmVariable &a_signal, int a_dstThreadId, int a_srcThreadId); + + /// \brief Sys_Block() will add a block to a thread. + /// \return the index of the block that was signalled, or -1 if the blocks were added and the thread is to enter a blocked state. + int Sys_Block(gmThread * a_thread, int m_numBlocks, const gmVariable * a_blocks); + + /// \brief KillThread() + void KillThread(int a_threadId); + + /// \brief ForEachThread() + void ForEachThread(gmThreadIteratorCallback a_callback, void * a_context); + + /// \brief Sys_SwitchState() will change the executing state of a thread. if a_to is gmThread::KILLED, the thread + /// is reset. + void Sys_SwitchState(gmThread * a_thread, int a_to); + + /// \brief KillExceptionThreads() + void KillExceptionThreads(); + + /// \brief Execute() will execute all running threads + /// \param m_deltaTime is the time in milliseconds since the machine was last updated. + /// \return number of running sleeping and blocked threads. + int Execute(gmuint32 a_delta); + + /// \brief GetTime() will return the machine time in milliseconds. + inline gmuint32 GetTime() const { return m_time; } + + /// \brief Presize() will presize the pools + void Presize(int a_pool8, + int a_pool16, + int a_pool24, + int a_pool32, + int a_pool64, + int a_pool128, + int a_pool256, + int a_pool512, + int a_gmStringObj, + int a_gmTableObj, + int a_gmFunctionObj, + int a_gmUserObj, + int a_gmStackFrame + ); + + // + // + // Garbage Collection Interface + // + // + + /// \brief EnableGC() allows you to turn garbage collection on and off.... useful for when you are allocating many + /// objects from c \ c++, but have not yet added them to a thread stack or referenced table \ object such that + /// they will be marked should the garbage collection fire. make sure you turn gc back on again!!! + inline void EnableGC(bool a_state = true) { m_gcEnabled = a_state; } + inline bool IsGCEnabled() const { return m_gcEnabled; } + + /// \brief CollectGarbage() will perform a garbage collection sweep iff the desired byte memory usage is less than + /// the current memory usage. + /// NOTE: If incremental collector is used, this may perform a FULL collect immediately. + /// \param a_forceFullCollect Force full collection immediately if garbage collection is not disabled + /// \return true if the garbage collector was run. + bool CollectGarbage(bool a_forceFullCollect = false); + + /// \brief GetCurrentMemoryUsage() will return the number of bytes currently allocated by the system. + inline int GetCurrentMemoryUsage() const { return m_currentMemoryUsage + m_fixedSet.GetMemUsed(); } + + /// \brief Set the machine to run a gc sweep whenever memory exceeds this limit. + inline void SetDesiredByteMemoryUsageHard(int a_desiredByteMemoryUsageHard); + + /// \brief Set the machine to run a gc sweep whenever memory exceeds this limit. + inline void SetDesiredByteMemoryUsageSoft(int a_desiredByteMemoryUsageSoft); + + /// \brief Return the number of bytes currently allocated by the system. + inline int GetDesiredByteMemoryUsageHard() const { return m_desiredByteMemoryUsageHard; } + + /// \brief Return the number of bytes currently allocated by the system. + inline int GetDesiredByteMemoryUsageSoft() const { return m_desiredByteMemoryUsageSoft; } + + /// \brief SetAutoMemoryUsage() will enable auto adjustment of the memory limit occuring with subsequent garbage collects. + inline void SetAutoMemoryUsage(bool a_enableAutoAdjust); + + /// \brief Is automatic memory limit calculation enabled? + inline bool GetAutoMemoryUsage() const { return m_autoMem; } + + /// \brief GetSystemMemUsed will return the number of bytes allocated by the system. This is slow, call for debug only + unsigned int GetSystemMemUsed() const; + + /// \brief Adjust the amount of memory known to be used by the machine. + /// Use this function carefully with user types to allow the machine + /// to consider external memory allocated or freed in association + /// with a user type that will be garbage collected by the machine. + /// Make sure the function is called as positive on the alloc and negative on the free. + inline void AdjustKnownMemoryUsed(int a_amountUsedOrFreed) { m_currentMemoryUsage += a_amountUsedOrFreed; } + + /// \brief RegisterUserCallbacks() will register user type garbage collect methods. +#if GM_USE_INCGC + void RegisterUserCallbacks(gmType a_type, gmGCTraceCallback a_gcTrace, gmGCDestructCallback a_gcDestruct, gmAsStringCallback a_asString = NULL); + + /// \brief GetUserMarkCallback() will return the gc mark call back for a user type + inline gmGCTraceCallback GetUserGCTraceCallback(gmType a_type) const { return m_types[a_type].m_gcTrace; } + + /// \brief GetUserGCCallback() will return the gc destruct call back for a user type + inline gmGCDestructCallback GetUserGCDestructCallback(gmType a_type) const { return m_types[a_type].m_gcDestruct; } + +#else //GM_USE_INCGC + + void RegisterUserCallbacks(gmType a_type, gmGarbageCollectCallback a_mark, gmGarbageCollectCallback a_gc, gmAsStringCallback a_asString = NULL); + + /// \brief GetUserMarkCallback() will return the gc mark call back for a user type + inline gmGarbageCollectCallback GetUserMarkCallback(gmType a_type) const { return m_types[a_type].m_mark; } + + /// \brief GetUserGCCallback() will return the gc destruct call back for a user type + inline gmGarbageCollectCallback GetUserGCCallback(gmType a_type) const { return m_types[a_type].m_gc; } + +#endif //GM_USE_INCGC + + /// \brief Return the callback associated with a_type + inline gmAsStringCallback GetUserAsStringCallback(gmType a_type) const { return m_types[a_type].m_asString; } + + // + // + // Object Interface + // + // + + /// \brief GetGlobals() will return the gmTableObject used to store global variables. note that global variables + /// are common to all threads. + inline gmTableObject * GetGlobals() { return m_global; } + + inline gmTableObject * GetTrueGlobals() { return m_trueGlobal; } + + void SetGlobals( gmTableObject *pNewGlobals ) { m_global = pNewGlobals; } + + /// \brief GetObject() will convert a gmptr (machine pointer size int) into an object pointer. use this whenever + /// converting from a gmVariable m_value.m_ref to an object. + inline gmObject * GetObject(gmptr a_ref); + + /// \brief AllocStringObject() will create a constant string object from the unique string pool. + /// \param a_length is the string length not including '\0' terminator, (-1) if unknown + gmStringObject * AllocStringObject(const char * a_string, int a_length = -1); + + /// \brief AllocPermanantStringObject() will create a constant string object from the unique string pool. this + /// string will not be garbage collected. (m_mark == GM_PERSIST) + /// \param a_length is the string length not including '\0' terminator, (-1) if unknown + gmStringObject * AllocPermanantStringObject(const char * a_string, int a_length = -1); + + /// \brief AllocTableObject() will create a new empty table. + gmTableObject * AllocTableObject(); + + /// \brief AllocFunctionObject() will create a new function. + gmFunctionObject * AllocFunctionObject(gmCFunction a_function = NULL); + + /// \brief AllocUserObject() will create a new user object. + /// \param a_user is a hook to tie the user object to any system. + /// \param a_userType is the user type user for operator binding etc. + /// \sa CreateUserType() + gmUserObject * AllocUserObject(void * a_user, int a_userType); + + // + // + // Debug Interface + // + // + + void * m_debugUser; ///< user hook for debugger + + /// \brief SetDebugMode() will compile byte code with debug info. + /// This includes storing the source code in the gmMachine, and compiling line and symbol information + /// into the gmFunctionObjects. + inline void SetDebugMode(bool a_debug) { m_debug = a_debug; } + + /// \brief GetDebugMode() + inline bool GetDebugMode() const { return m_debug; } + + /// \brief AddSourceCode() will add source code to the machine, and return a unique id. + /// This is used when debug mode is set so the remote debugger can retrieve source as needed + /// for debugging. + /// \return a unique id for the source code, or 0 on error. + gmuint32 AddSourceCode(const char * a_source, const char * a_filename); + + /// \brief GetSourceCode() will get source code debugging purposes. + /// \return true if the source was found, a_source and a_filename are set to the source and filname for the unique id. + bool GetSourceCode(gmuint32 a_id, const char * &a_source, const char * &a_filename); + + /// \brief GetInstructionAtBreakPoint will return the insturction at the given break point, or NULL if the break + /// point could not be found. only works in debug mode. This is quite slow. + const void * GetInstructionAtBreakPoint(gmuint32 a_sourceId, int a_line); + + // debugger hooks + + gmDebugLineCallback m_line; + gmDebugCallCallback m_call; + gmDebugRetCallback m_return; + gmDebugIsBrokenCallback m_isBroken; + + // + // + // Implementation allocators + // + // + + inline gmStackFrame * Sys_AllocStackFrame() { return (gmStackFrame *) m_memStackFrames.Alloc(); } + inline void Sys_FreeStackFrame(gmStackFrame * a_frame) { m_memStackFrames.Free(a_frame); } + void Sys_FreeUniqueString(const char * a_string); + inline void * Sys_Alloc(int a_size); + inline void Sys_Free(void * a_mem) { m_fixedSet.Free(a_mem); } + + void Sys_RemoveBlocks(gmThread * a_thread); + void Sys_RemoveSignals(gmThread * a_thread); + + void Sys_SignalCreateThread(gmThread * a_thread); + +#if GM_USE_INCGC + static void GM_CDECL ScanRootsCallBack(gmMachine* a_machine, gmGarbageCollector* a_gc); + inline gmGarbageCollector* GetGC() {GM_ASSERT(m_gc); return m_gc;} + inline void DestructDeleteObject(gmObject* a_object) {FreeObject(a_object);} + + gmGarbageCollector* m_gc; +#endif //GM_USE_INCGC + + inline int GetStatsGCNumFullCollects() { return m_statsGCFullCollect; } + inline int GetStatsGCNumIncCollects() { return m_statsGCIncCollect; } + inline int GetStatsGCNumWarnings() { return m_statsGCWarnings; } + /// \brief Is GC actually running a cycle + bool IsGCRunning(); + + /// \brief Add a CPP owned gmObject so machine knows about it to handle GC. + void AddCPPOwnedGMObject(gmObject * a_obj); + /// \brief Remove a CPP owned gmObject. + void RemoveCPPOwnedGMObject(gmObject * a_obj); + /// \brief Check if gmObject is in CPP owned list + bool IsCPPOwnedGMObject(gmObject * a_obj); + /// \brief Remove all CPP owned gmObjects. + void RemoveAllCPPOwnedGMObjects(); + +protected: + + // Threads + int m_threadId; ///< cycling thread number + gmListDouble m_runningThreads; + gmListDouble m_blockedThreads; + gmListDouble m_sleepingThreads; ///< sorted by timez + gmListDouble m_killedThreads; + gmListDouble m_exceptionThreads; ///< dead threads, hanging around for debugging + gmHash m_threads; + int GetThreadId(); + gmuint32 m_time; ///< machine time in milliseconds. (gives us 50 days) + gmThread * m_nextThread; ///< Set when cycling through threads, allows remove during iteration + bool m_nextThreadValid; ///< Set to true when m_nextThread is in use, even if it is null, which occurs on last thread. + + // Objects + void FreeObject(gmObject * a_obj); ///< FreeObject() does not Destruct the object. + gmObject * CheckReference(gmptr a_ref); + gmTableObject * m_global; ///< global variables + gmTableObject * m_trueGlobal; + gmObject * m_objects; ///< list of all objects + + // Allocators + gmMemFixed m_memStringObj; ///< memory for String objects + gmMemFixed m_memTableObj; ///< memory for Table objects + gmMemFixed m_memFunctionObj; ///< memory for Function objects + gmMemFixed m_memUserObj; ///< memory for User objects + gmMemFixed m_memStackFrames; ///< memory for stack frame structures + gmMemFixedSet m_fixedSet; ///< string and small variable sized stuff allocator. + + // Garbage Collection + int m_desiredByteMemoryUsageHard; ///< The hard upper memory limit + int m_desiredByteMemoryUsageSoft; ///< The soft limit where incremental GC may start + int m_currentMemoryUsage; ///< Current (known) used memory + bool m_autoMem; ///< Automatically adjust memory limit(s) + gmuint32 m_mark; ///< The mark phase Id for atomic GC + bool m_gcEnabled; ///< GC enabled/disabled + int m_framesSinceLastIncCollect; ///< number of frames or oportunities since last inc GC end + int m_gcPhaseCount; ///< GC phase, 2 phases required for full GC + int m_statsGCFullCollect; ///< How many times a full collect has occured + int m_statsGCIncCollect; ///< How many times incremental collect has started + int m_statsGCWarnings; ///< The incGC thinks it is being used inefficiently. It this number is large and growing rapidly the hard and soft limits may need calibrating. + + // String Table + gmHash m_strings; + + // Types + class Type + { + public: + gmStringObject * m_name; ///< type name + gmOperatorFunction m_nativeOperators[O_MAXOPERATORS]; ///< stack operators + gmptr m_operators[O_MAXOPERATORS]; ///< slow script call operators + gmTableObject * m_variables; ///< user type variables +#if GM_USE_INCGC + gmGCDestructCallback m_gcDestruct; ///< user type gc destruct callback + gmGCTraceCallback m_gcTrace; ///< user type gc trace callback +#else //GM_USE_INCGC + gmGarbageCollectCallback m_mark; ///< user type gc mark callback + gmGarbageCollectCallback m_gc; ///< user type gc callback +#endif //GM_USE_INCGC + gmAsStringCallback m_asString; ///< user type AsString callback + + void Init(); + }; + + gmArraySimple m_types; ///< Variable types +#if GM_USE_INCGC + #if !GC_KEEP_PERSISTANT_SEPARATE + gmArraySimple m_permanantStrings; + #endif //!GC_KEEP_PERSISTANT_SEPARATE +#endif //GM_USE_INCGC + + void ResetDefaultTypes(); + + // Blocking + gmHash m_blocks; // current registered blocks. + + // C++ owned gmObjects + class ObjHashNode : public gmHashNode + { + public: + gmObject * m_obj; + const gmObject * GetKey() const { return m_obj; } + }; + gmHash m_cppOwnedGMObjs; ///< cpp owned gmObjects + + // Debugging + bool m_debug; + gmListDouble m_source; + gmLog m_log; +}; + +// +// +// INLINE IMPLEMENTATION +// +// + + +inline void gmMachine::SetDesiredByteMemoryUsageHard(int a_desiredByteMemoryUsageHard) +{ + m_desiredByteMemoryUsageHard = a_desiredByteMemoryUsageHard; +} + + +inline void gmMachine::SetDesiredByteMemoryUsageSoft(int a_desiredByteMemoryUsageSoft) +{ + m_desiredByteMemoryUsageSoft = a_desiredByteMemoryUsageSoft; +} + + +inline void gmMachine::SetAutoMemoryUsage(bool a_enableAutoAdjust) +{ + m_autoMem = a_enableAutoAdjust; +} + + +inline gmObject * gmMachine::GetObject(gmptr a_ref) +{ +#if GMMACHINE_SUPERPARANOIDGC + return CheckReference(a_ref); +#else // GMMACHINE_SUPERPARANOIDGC + return (gmObject *) a_ref; +#endif // GMMACHINE_SUPERPARANOIDGC +} + + + +inline gmVariable gmMachine::GetTypeVariable(gmType a_type, const gmVariable &a_key) const +{ + return m_types[a_type].m_variables->Get(a_key); +} + + + +inline gmOperatorFunction gmMachine::GetTypeNativeOperator(gmType a_type, gmOperator a_operator) +{ + return m_types[a_type].m_nativeOperators[a_operator]; +} + + + +inline gmFunctionObject * gmMachine::GetTypeOperator(gmType a_type, gmOperator a_operator) +{ + return (gmFunctionObject *) GetObject(m_types[a_type].m_operators[a_operator]); +} + + + +inline void * gmMachine::Sys_Alloc(int a_size) +{ + return m_fixedSet.Alloc(a_size); +} + +#endif // _GMMACHINE_H_ diff --git a/vscript/languages/gm/src/gm/gmMachineLib.cpp b/vscript/languages/gm/src/gm/gmMachineLib.cpp new file mode 100644 index 00000000..250d0ea4 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmMachineLib.cpp @@ -0,0 +1,1223 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmMachineLib.h" +#include "gmThread.h" +#include "gmMachine.h" +#include "gmUtil.h" + +// Must be last header +#include "memdbgon.h" + +// +// machine +// + +static int GM_CDECL gmVersion(gmThread * a_thread) +{ + a_thread->PushNewString(GM_VERSION); + return GM_OK; +} + + +static int GM_CDECL gmTypeId(gmThread * a_thread) // return int, or null +{ + if(a_thread->GetNumParams() > 0) + { + a_thread->PushInt((gmptr) a_thread->Param(0).m_type); + } + return GM_OK; +} + + + +static int GM_CDECL gmTypeName(gmThread * a_thread) // return string, or null +{ + if(a_thread->GetNumParams() > 0) + { + const char * name = a_thread->GetMachine()->GetTypeName(a_thread->Param(0).m_type); + a_thread->PushNewString(name); + } + return GM_OK; +} + + + +static int GM_CDECL gmRegisterTypeOperator(gmThread * a_thread) // typeid, operatorname, function, returns true on success +{ + GM_CHECK_NUM_PARAMS(3); + GM_CHECK_INT_PARAM(typeId, 0); + GM_CHECK_STRING_PARAM(operatorName, 1); + GM_CHECK_FUNCTION_PARAM(function, 2); + + gmOperator op = gmGetOperator(operatorName); + if(op != O_MAXOPERATORS) + { + a_thread->PushInt(a_thread->GetMachine()->RegisterTypeOperator((gmType) typeId, op, function) ? 1 : 0); + return GM_OK; + } + a_thread->PushInt(0); + return GM_OK; +} + + + +static int GM_CDECL gmRegisterTypeVariable(gmThread * a_thread) // typeid, key (string), value +{ + GM_CHECK_NUM_PARAMS(3); + GM_CHECK_INT_PARAM(typeId, 0); + GM_CHECK_STRING_PARAM(variable, 1); + + a_thread->GetMachine()->RegisterTypeVariable((gmType) typeId, variable, a_thread->Param(2)); + + return GM_OK; +} + + + +static int GM_CDECL gmCollectGarbage(gmThread * a_thread) // returns true if gc was run +{ + GM_INT_PARAM(forceFullCollect, 0, false); + + a_thread->PushInt(a_thread->GetMachine()->CollectGarbage(forceFullCollect != 0) ? 1 : 0); + return GM_OK; +} + + + +static int GM_CDECL gmGetCurrentMemoryUsage(gmThread * a_thread) // returns current memory usage in bytes +{ + a_thread->PushInt(a_thread->GetMachine()->GetCurrentMemoryUsage()); + return GM_OK; +} + + +static int GM_CDECL gmSetDesiredMemoryUsageHard(gmThread * a_thread) // mem usage in bytes +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_INT_PARAM(mem, 0); + + a_thread->GetMachine()->SetDesiredByteMemoryUsageHard(mem); + return GM_OK; +} + + +static int GM_CDECL gmSetDesiredMemoryUsageSoft(gmThread * a_thread) // mem usage in bytes +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_INT_PARAM(mem, 0); + + a_thread->GetMachine()->SetDesiredByteMemoryUsageSoft(mem); + return GM_OK; +} + + +static int GM_CDECL gmGetDesiredMemoryUsageHard(gmThread * a_thread) +{ + a_thread->PushInt(a_thread->GetMachine()->GetDesiredByteMemoryUsageHard()); + return GM_OK; +} + + +static int GM_CDECL gmGetDesiredMemoryUsageSoft(gmThread * a_thread) +{ + a_thread->PushInt(a_thread->GetMachine()->GetDesiredByteMemoryUsageSoft()); + return GM_OK; +} + + +static int GM_CDECL gmSetDesiredMemoryUsageAuto(gmThread * a_thread) // mem usage in bytes +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_INT_PARAM(autoEnable, 0); + + a_thread->GetMachine()->SetAutoMemoryUsage(autoEnable != 0); + return GM_OK; +} + + +static int GM_CDECL gmSysGetStatsGCNumFullCollects(gmThread * a_thread) +{ + a_thread->PushInt(a_thread->GetMachine()->GetStatsGCNumFullCollects()); + return GM_OK; +} + + +static int GM_CDECL gmSysGetStatsGCNumIncCollects(gmThread * a_thread) +{ + a_thread->PushInt(a_thread->GetMachine()->GetStatsGCNumIncCollects()); + return GM_OK; +} + + +static int GM_CDECL gmSysGetStatsGCNumWarnings(gmThread * a_thread) +{ + a_thread->PushInt(a_thread->GetMachine()->GetStatsGCNumWarnings()); + return GM_OK; +} + + +static int GM_CDECL gmSysIsGCRunning(gmThread * a_thread) +{ + a_thread->PushInt(a_thread->GetMachine()->IsGCRunning()); + return GM_OK; +} + + +static int GM_CDECL gmDoString(gmThread * a_thread) // string, now(int), returns thread id, null on error, exception on compile error +{ + GM_CHECK_NUM_PARAMS(1); // Need at least 1 parameter + GM_CHECK_STRING_PARAM(script, 0); // 1st param is script string + GM_INT_PARAM(now, 1, 1); // 2nd param is execute now flag + gmVariable paramThis = a_thread->Param(2, gmVariable::s_null); // 3rd param is 'this' + + int id = GM_INVALID_THREAD; + if( script ) + { + int errors = a_thread->GetMachine()->ExecuteString(script, &id, (now) ? true : false, NULL, ¶mThis); + if( errors ) + { + return GM_EXCEPTION; + } + a_thread->PushInt(id); + } + return GM_OK; +} + + + +static int GM_CDECL gmGlobals(gmThread * a_thread) // return table +{ + a_thread->PushTable(a_thread->GetMachine()->GetGlobals()); + return GM_OK; +} + + + +static int GM_CDECL gmMachineTime(gmThread * a_thread) // return machine time +{ + a_thread->PushInt(a_thread->GetMachine()->GetTime()); + return GM_OK; +} + + + +// +// thread +// + + + +static int GM_CDECL gmSleep(gmThread * a_thread) // float\int param time in seconds +{ + GM_CHECK_NUM_PARAMS(1); + gmType type = a_thread->ParamType(0); + gmuint32 ms = 0; + + if(type == GM_INT) ms = a_thread->Param(0).m_value.m_int * 1000; + else if(type == GM_FLOAT) ms = (gmuint32) floorf(a_thread->Param(0).m_value.m_float * 1000.0f); + + a_thread->Sys_SetTimeStamp(a_thread->GetMachine()->GetTime() + ms); + return GM_SYS_SLEEP; +} + + + +static int GM_CDECL gmYield(gmThread * a_thread) +{ + return GM_SYS_YIELD; +} + + + +static int GM_CDECL gmThreadTime(gmThread * a_thread) +{ + a_thread->PushInt(a_thread->GetThreadTime()); + return GM_OK; +} + + + +static int GM_CDECL gmThreadId(gmThread * a_thread) // return thread id +{ + a_thread->PushInt(a_thread->GetId()); + return GM_OK; +} + + +// Callback iteration function for gmThreadAllIds +static bool gmThreadIdIter(gmThread * a_thread, void * a_context) +{ + gmTableObject* table = (gmTableObject*)a_context; + gmVariable threadId; + threadId.SetInt(a_thread->GetId()); + table->Set(a_thread->GetMachine(), table->Count(), threadId); + return true; +} + + + +static int GM_CDECL gmThreadAllIds(gmThread * a_thread) // thread id +{ + gmTableObject * threadIds = a_thread->PushNewTable(); + a_thread->GetMachine()->ForEachThread(gmThreadIdIter, threadIds); + return GM_OK; +} + + + +static int GM_CDECL gmExit(gmThread * a_thread) +{ + return GM_SYS_KILL; +} + + + +static int GM_CDECL gmKillThread(gmThread * a_thread) // thread id +{ + GM_INT_PARAM(id, 0, GM_INVALID_THREAD); // 1 optional param, default is this thread + + // Kill this thread + if( (id == GM_INVALID_THREAD) || (id == a_thread->GetId()) ) + { + return GM_SYS_KILL; // Kill this thread + } + + // Attempt to kill other thread by Id + gmThread * thread = a_thread->GetMachine()->GetThread(id); + if( thread ) + { + thread->GetMachine()->Sys_SwitchState(thread, gmThread::KILLED); // Kill other thread + } + + return GM_OK; +} + + +// Callback iteration function for gmKillAllThreads() +// Kills all threads except current, current thread is passed in as context. +static bool threadIterKill(gmThread * a_thread, void * a_context) +{ + gmThread* caller = (gmThread*)a_context; + + if(a_thread != caller) // Ignore calling thread + { + switch(a_thread->GetState()) + { + case gmThread::RUNNING: + case gmThread::SLEEPING: + case gmThread::BLOCKED: + { + // Kill the thread + a_thread->GetMachine()->Sys_SwitchState(a_thread, gmThread::KILLED); + break; + } + case gmThread::EXCEPTION: + case gmThread::KILLED: + default: + { + // Ignore threads of these states + break; + } + } + } + + return true; +} + + +static int GM_CDECL gmKillAllThreads(gmThread * a_thread) // thread id +{ + GM_INT_PARAM(killCurrent, 0, 0); + + a_thread->GetMachine()->ForEachThread(threadIterKill, a_thread); + + if(killCurrent) + { + return GM_SYS_KILL; + } + + return GM_OK; +} + + + +static int GM_CDECL gmfThread(gmThread * a_thread) // fn, params, returns thread id (0) on error, else returns new thread id +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_FUNCTION_PARAM(function, 0); + + int id, i; + gmThread * thread = a_thread->GetMachine()->CreateThread(&id); + if(thread) + { + thread->Push(*a_thread->GetThis()); + thread->PushFunction(function); + int numParameters = a_thread->GetNumParams() - 1; + for(i = 0; i < numParameters; ++i) + thread->Push(a_thread->Param(i + 1)); + thread->PushStackFrame(numParameters, 0); + } + a_thread->PushInt(id); + return GM_OK; +} + + + +static int GM_CDECL gmAssert(gmThread * a_thread) +{ + if(a_thread->GetNumParams() > 0) + { + if(a_thread->Param(0).m_value.m_int) + { + return GM_OK; + } + } + GM_STRING_PARAM(message, 1, "assert failed"); + a_thread->GetMachine()->GetLog().LogEntry("%s", message); + return GM_EXCEPTION; +} + + + +static gmType s_gmStateUserType = GM_NULL; + +struct gmStateUserType +{ + gmFunctionObject * m_lastState; // last state + gmFunctionObject * m_currentState; // current state + gmFunctionObject * m_setExitState; // leave hanlder +}; + + +static int GM_CDECL gmSetState(gmThread * a_thread) // fp, params +{ + GM_CHECK_NUM_PARAMS(GM_STATE_NUM_PARAMS); + GM_CHECK_FUNCTION_PARAM(function, 0); + + // make sure we have our state type. + GM_ASSERT(s_gmStateUserType != GM_NULL); + + // save off the parameters to the new state + gmVariable thisVar = *a_thread->GetThis(); + int i, numParameters = a_thread->GetNumParams() - GM_STATE_NUM_PARAMS; + gmVariable * params = (gmVariable *) alloca(sizeof(gmVariable) * numParameters); + for(i = 0; i < numParameters; ++i) + { + params[i] = a_thread->Param(i + GM_STATE_NUM_PARAMS); + } + + // get the current state + gmVariable newStateVariable; + gmVariable * currentStateVariable = a_thread->GetBottom(); + if(currentStateVariable->m_type == s_gmStateUserType) + { + gmUserObject * userObj = (gmUserObject *) GM_OBJECT(currentStateVariable->m_value.m_ref); + gmStateUserType * currentState = (gmStateUserType *) userObj->m_user; + + // call the on state leave if one exists. + if(currentState->m_setExitState) + { + gmThread * thread = a_thread->GetMachine()->CreateThread(thisVar, gmVariable(GM_FUNCTION, currentState->m_setExitState->GetRef())); + if(thread) + { + thread->Sys_Execute(); + } + } + + currentState->m_setExitState = NULL; + currentState->m_lastState = currentState->m_currentState; + currentState->m_currentState = function; + newStateVariable = *currentStateVariable; + } + else + { + gmStateUserType * state = (gmStateUserType *) a_thread->GetMachine()->Sys_Alloc(sizeof(gmStateUserType)); + state->m_setExitState = NULL; + state->m_currentState = function; + state->m_lastState = NULL; + + // create a new state variable + newStateVariable.SetUser(a_thread->GetMachine()->AllocUserObject(state, s_gmStateUserType)); + } + + // reset the stack. and push new state + int user = a_thread->m_user; + a_thread->Sys_Reset(a_thread->GetId()); + a_thread->m_user = user; + a_thread->Sys_SetStartTime(a_thread->GetMachine()->GetTime()); + a_thread->Touch(4 + numParameters); + a_thread->Push(newStateVariable); + a_thread->Push(thisVar); + a_thread->PushFunction(function); + for(i = 0; i < numParameters; ++i) + { + a_thread->Push(params[i]); + } + + return GM_SYS_STATE; +} + + +static int GM_CDECL gmSetStateOnThread(gmThread * a_thread) // (threadid, fp, params...) returns true or false. +{ + GM_CHECK_NUM_PARAMS(2); + GM_CHECK_INT_PARAM(threadId, 0); + GM_CHECK_FUNCTION_PARAM(function, 1); + + // make sure we have our state type. + GM_ASSERT(s_gmStateUserType != GM_NULL); + + // get the target thread + gmThread * thread = a_thread->GetMachine()->GetThread(threadId); + if(thread == a_thread) + { + a_thread->GetMachine()->GetLog().LogEntry("use setstate() on own thread"); + return GM_EXCEPTION; + } + + if(thread == NULL) + { + return GM_OK; + } + + // get the current state of the thread + gmVariable newStateVariable; + gmVariable thisVar = *thread->GetThis(); + gmVariable * currentStateVariable = thread->GetBottom(); + if(currentStateVariable->m_type == s_gmStateUserType) + { + gmUserObject * userObj = (gmUserObject *) GM_OBJECT(currentStateVariable->m_value.m_ref); + gmStateUserType * currentState = (gmStateUserType *) userObj->m_user; + + // call the on state leave if one exists. + if(currentState->m_setExitState) + { + gmThread * thread = a_thread->GetMachine()->CreateThread(thisVar, gmVariable(GM_FUNCTION, currentState->m_setExitState->GetRef())); + if(thread) + { + thread->Sys_Execute(); + } + } + + currentState->m_setExitState = NULL; + currentState->m_lastState = currentState->m_currentState; + currentState->m_currentState = function; + newStateVariable = *currentStateVariable; + } + else + { + gmStateUserType * state = (gmStateUserType *) a_thread->GetMachine()->Sys_Alloc(sizeof(gmStateUserType)); + state->m_setExitState = NULL; + state->m_currentState = function; + state->m_lastState = NULL; + + // create a new state variable + newStateVariable.SetUser(a_thread->GetMachine()->AllocUserObject(state, s_gmStateUserType)); + } + + // reset the stack. and push new state + int numParameters = a_thread->GetNumParams() - 2; + + int user = thread->m_user; + thread->Sys_Reset(thread->GetId()); + thread->m_user = user; + thread->Sys_SetStartTime(thread->GetMachine()->GetTime()); + thread->Touch(4 + numParameters); + thread->Push(newStateVariable); + thread->Push(thisVar); + thread->PushFunction(function); + + int i; + for(i = 0; i < numParameters; ++i) + { + thread->Push(a_thread->Param(i+2)); + } + + thread->PushStackFrame(numParameters); + a_thread->GetMachine()->Sys_SwitchState(thread, gmThread::RUNNING); + + return GM_OK; +} + + + +static int GM_CDECL gmGetState(gmThread * a_thread) // return var +{ + GM_ASSERT(s_gmStateUserType != GM_NULL); + + gmThread * testThread = a_thread; + + //Optional parameter, threadId + if(a_thread->GetNumParams() >= 1) + { + GM_CHECK_INT_PARAM(testThreadId, 0); + testThread = a_thread->GetMachine()->GetThread(testThreadId); + if(!testThread) + { + a_thread->PushNull(); + return GM_OK; + } + } + + gmVariable * currentStateVariable = testThread->GetBottom(); + if(currentStateVariable->m_type == s_gmStateUserType) + { + gmUserObject * userObj = (gmUserObject *) GM_OBJECT(currentStateVariable->m_value.m_ref); + gmStateUserType * currentState = (gmStateUserType *) userObj->m_user; + a_thread->PushFunction(currentState->m_currentState); + } + return GM_OK; +} + + +static int GM_CDECL gmGetLastState(gmThread * a_thread) // return var +{ + GM_ASSERT(s_gmStateUserType != GM_NULL); + + gmThread * testThread = a_thread; + + //Optional parameter, threadId + if(a_thread->GetNumParams() >= 1) + { + GM_CHECK_INT_PARAM(testThreadId, 0); + testThread = a_thread->GetMachine()->GetThread(testThreadId); + if(!testThread) + { + a_thread->PushNull(); + return GM_OK; + } + } + + gmVariable * currentStateVariable = testThread->GetBottom(); + if(currentStateVariable->m_type == s_gmStateUserType) + { + gmUserObject * userObj = (gmUserObject *) GM_OBJECT(currentStateVariable->m_value.m_ref); + gmStateUserType * currentState = (gmStateUserType *) userObj->m_user; + if(currentState->m_lastState) + { + a_thread->PushFunction(currentState->m_lastState); + } + } + return GM_OK; +} + + + +static int GM_CDECL gmSetExitState(gmThread * a_thread) // function +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_FUNCTION_PARAM(function, 0); + + GM_ASSERT(s_gmStateUserType != GM_NULL); + + gmVariable * currentStateVariable = a_thread->GetBottom(); + if(currentStateVariable->m_type == s_gmStateUserType) + { + gmUserObject * userObj = (gmUserObject *) GM_OBJECT(currentStateVariable->m_value.m_ref); + gmStateUserType * currentState = (gmStateUserType *) userObj->m_user; + currentState->m_setExitState = function; + } + return GM_OK; +} + + + +static int GM_CDECL gmSignal(gmThread * a_thread) // var, dest thread id +{ + GM_CHECK_NUM_PARAMS(1); + GM_INT_PARAM(dstThreadId, 1, GM_INVALID_THREAD); + a_thread->GetMachine()->Signal(a_thread->Param(0), dstThreadId, a_thread->GetId()); + return GM_OK; +} + + + +static int GM_CDECL gmBlock(gmThread * a_thread) // var, ... +{ + GM_CHECK_NUM_PARAMS(1); + + int res = a_thread->GetMachine()->Sys_Block(a_thread, a_thread->GetNumParams(), a_thread->GetBase()); + if(res == -1) + { + return GM_SYS_BLOCK; + } + else if(res == -2) + { + return GM_SYS_YIELD; + } + a_thread->Push(a_thread->Param(res)); + return GM_OK; +} + + +#if GM_USE_INCGC + +static void GM_CDECL gmGCDestructStateUserType(gmMachine * a_machine, gmUserObject* a_object) +{ + gmStateUserType * state = (gmStateUserType *) a_object->m_user; + a_machine->Sys_Free(state); +} + +static bool GM_CDECL gmGCTraceStateUserType(gmMachine * a_machine, gmUserObject* a_object, gmGarbageCollector* a_gc, const int a_workLeftToGo, int& a_workDone) +{ + gmStateUserType * state = (gmStateUserType *) a_object->m_user; + if(state->m_currentState) a_gc->GetNextObject(state->m_currentState); + if(state->m_lastState) a_gc->GetNextObject(state->m_lastState); + if(state->m_setExitState) a_gc->GetNextObject(state->m_setExitState); + + a_workDone += 4; //contents + this + + return true; +} + +#else //GM_USE_INCGC + +static void GM_CDECL gmGCStateUserType(gmMachine * a_machine, gmUserObject * a_object, gmuint32 a_mark) +{ + gmStateUserType * state = (gmStateUserType *) a_object->m_user; + a_machine->Sys_Free(state); +} + +static void GM_CDECL gmMarkStateUserType(gmMachine * a_machine, gmUserObject * a_object, gmuint32 a_mark) +{ + gmStateUserType * state = (gmStateUserType *) a_object->m_user; + if(state->m_currentState && state->m_currentState->NeedsMark(a_mark)) state->m_currentState->Mark(a_machine, a_mark); + if(state->m_lastState && state->m_lastState->NeedsMark(a_mark)) state->m_lastState->Mark(a_machine, a_mark); + if(state->m_setExitState && state->m_setExitState->NeedsMark(a_mark)) state->m_setExitState->Mark(a_machine, a_mark); +} + +#endif //GM_USE_INCGC + +// +// table +// + +static int GM_CDECL gmTableCount(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_TABLE_PARAM(table, 0); + a_thread->PushInt(table->Count()); + return GM_OK; +} + +static int GM_CDECL gmTableDuplicate(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_TABLE_PARAM(table, 0); + a_thread->PushTable(table->Duplicate(a_thread->GetMachine())); + return GM_OK; +} + +// +// std +// + +void gmConcat(gmMachine * a_machine, char * &a_dst, int &a_len, int &a_size, const char * a_src, int a_growBy = 32) +{ + int len = strlen(a_src); + + if((a_len + len + 1) >= a_size) + { + a_size = a_len + len + a_growBy + 1; + char * str = (char *) a_machine->Sys_Alloc(a_size); + if(a_dst != NULL) + { + memcpy(str, a_dst, a_len); + a_machine->Sys_Free(a_dst); + } + a_dst = str; + a_dst[a_len] = '\0'; + } + memcpy(a_dst + a_len, a_src, len); + a_len += len; + a_dst[a_len] = '\0'; +} + + + +static int GM_CDECL gmPrint(gmThread * a_thread) +{ + const int bufferSize = 256; + int len = 0, size = 0, i; + char * str = NULL, buffer[bufferSize]; + + // build the string + for(i = 0; i < a_thread->GetNumParams(); ++i) + { + gmConcat(a_thread->GetMachine(), str, len, size, a_thread->Param(i).AsString(a_thread->GetMachine(), buffer, bufferSize), 64); + + if(str) + { + GM_ASSERT(len < size); + str[len++] = ' '; + str[len] = '\0'; + } + } + + // print the string + if(str) + { + if(gmMachine::s_printCallback) + { + gmMachine::s_printCallback(a_thread->GetMachine(), str); + } + a_thread->GetMachine()->Sys_Free(str); + } + + return GM_OK; +} + + + +static int GM_CDECL gmfFormat(gmThread * a_thread) // string, params ... +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_STRING_PARAM(format, 0); + int param = 1; + int len = 0, size = 0; + const int bufferSize = 128; + char * str = NULL, buffer[bufferSize]; + + while(*format) + { + if(*format == '%') + { + switch(format[1]) + { + case 'S' : + case 's' : + { + GM_STRING_PARAM(pstr, param, ""); + ++param; + gmConcat(a_thread->GetMachine(), str, len, size, pstr, 64); + break; + } + case 'C' : + case 'c' : + { + GM_INT_PARAM(ival, param, 0); + ++param; + V_snprintf(buffer, 64, "%c", ival); + gmConcat(a_thread->GetMachine(), str, len, size, buffer, 64); + break; + } + case 'D' : + case 'd' : + { + GM_INT_PARAM(ival, param, 0); + ++param; + V_snprintf(buffer, 64, "%d", ival); + gmConcat(a_thread->GetMachine(), str, len, size, buffer, 64); + break; + } + case 'U' : + case 'u' : + { + GM_INT_PARAM(ival, param, 0); + ++param; + V_snprintf(buffer, 64, "%u", ival); + gmConcat(a_thread->GetMachine(), str, len, size, buffer, 64); + break; + } + case 'B' : + case 'b' : + { + GM_INT_PARAM(ival, param, 0); + ++param; + gmItoa(ival, buffer, 2); + gmConcat(a_thread->GetMachine(), str, len, size, buffer, 64); + break; + } + case 'X' : + case 'x' : + { + GM_INT_PARAM(ival, param, 0); + ++param; + V_snprintf(buffer, 64, "%x", ival); + gmConcat(a_thread->GetMachine(), str, len, size, buffer, 64); + break; + } + case 'F' : + case 'f' : + { + GM_FLOAT_PARAM(fval, param, 0); + ++param; + V_snprintf(buffer, 64, "%f", fval); + gmConcat(a_thread->GetMachine(), str, len, size, buffer, 64); + break; + } + case 'e' : + case 'E' : + { + GM_FLOAT_PARAM(fval, param, 0); + ++param; + V_snprintf(buffer, 64, "%e", fval); + gmConcat(a_thread->GetMachine(), str, len, size, buffer, 64); + break; + } + case '%' : + { + if(len + 2 < size) + str[len++] = '%'; + else + gmConcat(a_thread->GetMachine(), str, len, size, "%", 64); + break; + } + default : + break; + } + format += 2; + } + else + { + if(len + 2 < size) + str[len++] = *(format++); + else + { + buffer[0] = *(format++); + buffer[1] = '\0'; + gmConcat(a_thread->GetMachine(), str, len, size, buffer, 64); + } + } + } + + if(str) + { + str[len] = '\0'; + a_thread->PushNewString(str); + a_thread->GetMachine()->Sys_Free(str); + } + return GM_OK; +} + + +// +// lib +// + +static gmFunctionEntry s_binding[] = +{ + /*gm + \lib gm + \brief functions in the gm lib are all global scope + */ + + /*gm + \function gmVersion + \brief gmVersion will return the gmMachine version string. version string is major type . minor type as a string + and was added at version 1.1 + \return string + */ + {"gmVersion", gmVersion}, + /*gm + \function typeId + \brief typeId will return the type id of the passed var + \param var + \return integer type + */ + {"typeId", gmTypeId}, + /*gm + \function typeName + \brief typeName will return the type name of the passed var + \param var + \return string + */ + {"typeName", gmTypeName}, + /*gm + \function typeRegisterOperator + \brief typeRegisterOperator will register an operator for a type + \param int typeid + \param string operator name is one of + + "getdot", "setdot", "getind", "setind", "add", "sub", "mul", "div", "mod", + "inc", "dec", "bitor", "bitxor", "bitand", "shiftleft", "shiftright", "bitinv", + "lt", "gt", "lte", "gte", "eq", "neq", "neg", "pos", "not" + + \param function + \return 1 on success, otherwise 0 + */ + {"typeRegisterOperator", gmRegisterTypeOperator}, + /*gm + \function typeRegisterVariable + \brief typeRegisterVariable will register a variable with a type such that (type).varname will return the variable + \param int typeid + \param string var name + \param var + \return 1 on success, otherwise 0 + */ + {"typeRegisterVariable", gmRegisterTypeVariable}, + + /*gm + \function sysCollectGarbage + \brief sysCollectGarbage will run the garbage collector iff the current mem used is over the desired mem used + \param forceFullCollect (false) Optionally perform full garbage collection immediately if garbage collection is not disabled. + \return 1 if the gc was run, 0 otherwise + */ + {"sysCollectGarbage", gmCollectGarbage}, + /*gm + \function sysGetMemoryUsage + \brief sysGetMemoryUsage will return the current memory used in bytes + \return int memory usage + */ + {"sysGetMemoryUsage", gmGetCurrentMemoryUsage}, + + /*gm + \function sysSetDesiredMemoryUsageHard + \brief sysSetDesiredMemoryUsageHard will set the desired memory useage in bytes. when this is exceeded the garbage collector will be run. + \param int desired mem usage in bytes + */ + {"sysSetDesiredMemoryUsageHard", gmSetDesiredMemoryUsageHard}, + + /*gm + \function sysSetDesiredMemoryUsageSoft + \brief sysSetDesiredMemoryUsageSoft will set the desired memory useage in bytes. when this is exceeded the garbage collector will be run. + \param int desired mem usage in bytes + */ + {"sysSetDesiredMemoryUsageSoft", gmSetDesiredMemoryUsageSoft}, + + /*gm + \function sysGetDesiredMemoryUsageHard + \brief sysGetDesiredMemoryUsageHard will get the desired memory useage in bytes. + Note that this value is used to start garbage collection, it is not a strict limit. + \return int Desired memory usage in bytes. + */ + {"sysGetDesiredMemoryUsageHard", gmGetDesiredMemoryUsageHard}, + + /*gm + \function sysGetDesiredMemoryUsageSoft + \brief sysGetDesiredMemoryUsageSoft will get the desired memory useage in bytes. + Note that this value is used to start garbage collection, it is not a strict limit. + \return int Desired memory usage in bytes. + */ + {"sysGetDesiredMemoryUsageSoft", gmGetDesiredMemoryUsageSoft}, + + + /*gm + \function sysSetDesiredMemoryUsageAuto + \brief sysSetDesiredMemoryUsageAuto will enable auto adjustment of the memory limit(s) for subsequent garbage collections. + \param int enable or disable flag + */ + {"sysSetDesiredMemoryUsageAuto", gmSetDesiredMemoryUsageAuto}, + + + /*gm + \function sysGetStatsGCNumFullCollects + \brief sysGetStatsGCNumFullCollects Return the number of times full garbage collection has occured. + \return int Number of times full collect has occured. + */ + {"sysGetStatsGCNumFullCollects", gmSysGetStatsGCNumFullCollects}, + + /*gm + \function sysGetStatsGCNumIncCollects + \brief sysGetStatsGCNumIncCollects Return the number of times incremental garbage collection has occured. + This number may increase in twos as the GC has multiple phases which appear as restarts. + \return int Number of times incremental collect has occured. + */ + {"sysGetStatsGCNumIncCollects", gmSysGetStatsGCNumIncCollects}, + + /*gm + \function sysGetStatsGCNumWarnings + \brief sysGetStatsGCNumWarnings Return the number of warnings because the GC or VM thought the GC was poorly configured. + If this number is large and growing rapidly, the GC soft and hard limits need to be configured better. + Do not be concerned if this number grows slowly. + \return int Number of warnings garbage collect has generated. + */ + {"sysGetStatsGCNumWarnings", gmSysGetStatsGCNumWarnings}, + + /*gm + \function sysIsGCRunning + \brief Returns true if GC is running a cycle. + */ + {"sysIsGCRunning", gmSysIsGCRunning}, + + /*gm + \function sysTime + \brief sysTime will return the machine time in milli seconds + \return int + */ + {"sysTime", gmMachineTime}, + + /*gm + \function doString + \brief doString will execute the passed gm script + \param string script + \param int optional (1) set as true and the string will execute before returning to this thread + \param ref optional (null) set 'this' + \return int thread id of thread created for string execution + */ + {"doString", gmDoString}, + /*gm + \function globals + \brief globals will return the globals table + \return table containing all global variables + */ + {"globals", gmGlobals}, + + /*gm + \function threadTime + \brief threadTime will return the thread execution time in milliseconds + \return int + */ + {"threadTime", gmThreadTime}, + /*gm + \function threadId + \brief threadId will return the thread id of the current executing script + \return int + */ + {"threadId", gmThreadId}, + /*gm + \function threadAllIds + \brief threadIds returns a table of thread Ids + \return table of thread Ids + */ + {"threadAllIds", gmThreadAllIds}, + /*gm + \function threadKill + \brief threadKill will kill the thread with the given id + \param int threadId optional (0) will kill this thread + */ + {"threadKill", gmKillThread}, + /*gm + \function threadKillAll + \brief threadKillAll will kill all the threads except the current one + \param bool optional (false) will kill this thread if true + */ + {"threadKillAll", gmKillAllThreads}, + /*gm + \function thread + \brief thread will start a new thread + \param function entry point of the thread + \param ... parameters to pass to the entry function + \return int threadid + */ + {"thread", gmfThread}, + /*gm + \function yield + \brief yield will hand execution control to the next thread + */ + {"yield", gmYield}, + /*gm + \function exit + \brief exit will kill this thread + */ + {"exit", gmExit}, + /*gm + \function assert + \brief assert + \param int expression if true, will do nothing, if false, will cause an exception + */ + {"assert", gmAssert}, + /*gm + \function sleep + \brief sleep will sleep this thread for the given number of seconds + \param int\float seconds + */ + {"sleep", gmSleep}, + /*gm + \function signal + \brief signal will signal the given variable, this will unblock dest threads that are blocked on the same variable. + \param var + \param int destThreadId optional (0) 0 will signal all threads + */ + {"signal", gmSignal}, + /*gm + \function block + \brief block will block on all passed vars, execution will halt until another thread signals one of the block variables. Will yield on null and return null. + \param ... vars + \return the unblocking var + */ + {"block", gmBlock}, + + /*gm + \function stateSet + \brief stateSet will collapse the stack to nothing, and push the passed functions. + \param function new state function to execute + \param ... params for new state function + */ + {"stateSet", gmSetState}, + /*gm + \function stateSetOnThread + \brief stateSetOnThread will collapse the stack of the given thread id to nothing, and push the passed functions. + \param int thread id + \param function new state function to execute + \param ... params for new state function + */ + {"stateSetOnThread", gmSetStateOnThread}, + /*gm + \function stateGet + \brief stateGet will return the function on the bottom of this threads execution stack iff it was pushed using stateSet + \param a_threadId Optional Id of thread to get state on. + \reutrn function \ null + */ + {"stateGet", gmGetState}, + /*gm + \function stateGetLast + \brief stateGetLast will return the last state function of this thread + \param a_threadId Optional Id of thread to get last state on. + \reutrn function \ null + */ + {"stateGetLast", gmGetLastState}, + /*gm + \function stateSetExitFunction + \brief stateSetExitFunction will set an exit function for this state, that will be called with no parameters if this thread + switches state + \param function + */ + {"stateSetExitFunction", gmSetExitState}, + + /*gm + \function tableCount + \brief tableCount will return the number of elements in a table object + \param table + \return int + */ + {"tableCount", gmTableCount}, + /*gm + \function tableDuplicate + \brief tableDuplicate will duplicate the passed table object + \param table + \return table + */ + {"tableDuplicate", gmTableDuplicate}, + + /*gm + \function print + \brief print will print the given vars to the print handler. passed strings are concatinated together with a seperating space. + \param ... strings + */ + {"print", gmPrint}, + /*gm + \function format + \brief format (like sprintf, but returns a string) %d, %s, %f, %c, %b, %x, %e + \param string + */ + {"format", gmfFormat}, +}; + + + +void gmMachineLib(gmMachine * a_machine) +{ + // create the state type + s_gmStateUserType = a_machine->CreateUserType("gmState"); + +#if GM_USE_INCGC + a_machine->RegisterUserCallbacks(s_gmStateUserType, gmGCTraceStateUserType, gmGCDestructStateUserType); +#else //GM_USE_INCGC + a_machine->RegisterUserCallbacks(s_gmStateUserType, gmMarkStateUserType, gmGCStateUserType); +#endif //GM_USE_INCGC + + // default lib + a_machine->RegisterLibrary(s_binding, sizeof(s_binding) / sizeof(gmFunctionEntry), NULL); +} + diff --git a/vscript/languages/gm/src/gm/gmMachineLib.h b/vscript/languages/gm/src/gm/gmMachineLib.h new file mode 100644 index 00000000..3132562a --- /dev/null +++ b/vscript/languages/gm/src/gm/gmMachineLib.h @@ -0,0 +1,21 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMMACHINELIB_H_ +#define _GMMACHINELIB_H_ + +class gmMachine; + +#define GM_STATE_NUM_PARAMS 1 // requried for gmThread::PushStackFrame() for state(fp) implementation + +void gmMachineLib(gmMachine * a_machine); + +#endif // _GMMACHINELIB_H_ diff --git a/vscript/languages/gm/src/gm/gmMem.cpp b/vscript/languages/gm/src/gm/gmMem.cpp new file mode 100644 index 00000000..27b29356 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmMem.cpp @@ -0,0 +1,16 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmMem.h" + +// Must be last header +#include "memdbgon.h" diff --git a/vscript/languages/gm/src/gm/gmMem.h b/vscript/languages/gm/src/gm/gmMem.h new file mode 100644 index 00000000..de8df40d --- /dev/null +++ b/vscript/languages/gm/src/gm/gmMem.h @@ -0,0 +1,71 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMMEM_H_ +#define _GMMEM_H_ + +// include malloc and alloca if required within gmconfig_p.h + +#include "gmConfig.h" + +// define _gmDumpLeaks within gmconfig_p.h to dump memory leaks + +#ifndef _gmDumpLeaks +#define _gmDumpLeaks() +#endif + +/// \brief Align pointer +#define _gmAlignMem(PTR, ALIGN) (void*)(((gmuptr)(PTR) + (ALIGN) - 1) & ~((ALIGN)-1)) + + +/// \brief gmConstructElement will construct a single object at location +template +inline TYPE* gmConstructElement(TYPE* a_element) +{ + return (TYPE*) GM_PLACEMENT_NEW( TYPE, (void*)a_element ); +} + + + +/// \brief gmDestructElement will destruct a single object at location +template +inline void gmDestructElement(TYPE* a_element) +{ + a_element->~TYPE(); +} + + + +/// \brief gmConstructElements will construct multiple objects at location +template +inline void gmConstructElements(TYPE* a_elements, int a_count) +{ + // Call the constructor(s) + for (; a_count--; a_elements++) + { + GM_PLACEMENT_NEW( TYPE, (void*)a_elements ); + } +} + + + +/// \brief gmDestructElements will destruct multiple objects at location +template +inline void gmDestructElements(TYPE* a_elements, int a_count) +{ + // Call the destructor(s) + for (; a_count--; a_elements++) + { + a_elements->~TYPE(); + } +} + +#endif // _GMMEM_H_ diff --git a/vscript/languages/gm/src/gm/gmMemChain.cpp b/vscript/languages/gm/src/gm/gmMemChain.cpp new file mode 100644 index 00000000..a93ac29c --- /dev/null +++ b/vscript/languages/gm/src/gm/gmMemChain.cpp @@ -0,0 +1,238 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmMemChain.h" +#include "gmMem.h" + +// Must be last header +#include "memdbgon.h" + + +gmMemChain::gmMemChain(unsigned int a_elementSize, unsigned int a_numElementsInChunk) +{ + m_chunkSize = a_numElementsInChunk * a_elementSize; + m_elementSize = a_elementSize; + m_rootChunk = NULL; + m_currentChunk = NULL; +} + + + +gmMemChain::~gmMemChain() +{ + FreeChunks(); +} + + + +void gmMemChain::FreeChunks() +{ + if(m_rootChunk) + { + MemChunk *curChunk; + + curChunk = m_rootChunk; + while(curChunk) + { + MemChunk *chunkToFree; + + chunkToFree = curChunk; + curChunk = curChunk->m_nextChunk; + + delete [] (char*)chunkToFree; + } + } +} + + + +void gmMemChain::ResetAndFreeMemory() +{ + //Actually free the memory + FreeChunks(); + + //Clear pointers to chunk chain + m_rootChunk = NULL; + m_currentChunk = NULL; +} + + + +void gmMemChain::Presize(int a_kbytes) +{ + int numChunks = ((a_kbytes + 1) * 1024) / m_chunkSize; + MemChunk *curChunk; + curChunk = m_rootChunk; + while(curChunk) + { + --numChunks; + curChunk = curChunk->m_nextChunk; + } + MemChunk * currentChunk = m_currentChunk; + while(numChunks > 0) + { + NewChunk(); + --numChunks; + } + if(currentChunk) + { + m_currentChunk = currentChunk; + } +} + + +gmMemChain::MemChunk* gmMemChain::NewChunk() +{ + MemChunk* newChunk; + + //Is an unused chunk already allocated? + if(m_currentChunk && m_currentChunk->m_nextChunk) + { + newChunk = m_currentChunk->m_nextChunk; + newChunk->m_curAddress = newChunk->m_minAddress; + m_currentChunk = newChunk; + } + else //No, allocate a new one + { + char * mem = (char *) GM_NEW( char[sizeof(MemChunk) + m_chunkSize] ); + newChunk = (MemChunk *) mem; + + //Allocate memory and set address space + newChunk->m_minAddress = mem + sizeof(MemChunk); + newChunk->m_lastAddress = (void*)((unsigned int)newChunk->m_minAddress + m_chunkSize); + newChunk->m_curAddress = newChunk->m_minAddress; + + //Link new chunk to chain + newChunk->m_lastChunk = m_currentChunk; + newChunk->m_nextChunk = NULL; + if(m_currentChunk) + { + m_currentChunk->m_nextChunk = newChunk; + } + m_currentChunk = newChunk; + if(!m_rootChunk) + { + m_rootChunk = m_currentChunk; + } + } + return newChunk; +} + + + +void* gmMemChain::Alloc() +{ + void *retPtr; + + //Allocate first chunk if none exist + if(!m_rootChunk) + { + NewChunk(); + } + + //Advance ptr, allocate new chunk if necessary + if(((gmuptr)m_currentChunk->m_curAddress + m_elementSize) > (gmuptr)m_currentChunk->m_lastAddress) + { + NewChunk(); + } + retPtr = m_currentChunk->m_curAddress; + m_currentChunk->m_curAddress = (void*)((gmuptr)m_currentChunk->m_curAddress + m_elementSize); + + return retPtr; +} + + +void* gmMemChain::AllocBytes(unsigned int a_numBytes, unsigned int a_alignNumBytes) +{ + GM_ASSERT((a_numBytes + a_alignNumBytes) <= m_chunkSize); // Chunk size is too small to alloc that many elements at once and should be increased + + void *retPtr; + + //Allocate first chunk if none exist + if(!m_rootChunk) + { + NewChunk(); + } + + //Align and record the pointer. + retPtr = _gmAlignMem(m_currentChunk->m_curAddress, a_alignNumBytes); + + //Create new chunk if not enough memory in this one. + if(((gmuptr)retPtr + a_numBytes) > (gmuptr)m_currentChunk->m_lastAddress) + { + NewChunk(); + + //Align and record the pointer. + retPtr = _gmAlignMem(m_currentChunk->m_curAddress, a_alignNumBytes); + } + + //Advance memory ptr for next allocation. + m_currentChunk->m_curAddress = (void*)((gmuptr)retPtr + a_numBytes); + + return retPtr; +} + + + +void* gmMemChain::Alloc(unsigned int a_numElementsToAlloc) +{ + unsigned int allocSize; + void *retPtr; + + //Allocate first chunk if none exist + if(!m_rootChunk) + { + NewChunk(); + } + + //Advance ptr, allocate new chunk if necessary + allocSize = a_numElementsToAlloc * m_elementSize; + + GM_ASSERT(allocSize <= m_chunkSize); // Chunk size is too small to alloc that many elements at once and should be increased + + if(((unsigned int)m_currentChunk->m_curAddress + allocSize) > (unsigned int)m_currentChunk->m_lastAddress) + { + NewChunk(); + } + retPtr = m_currentChunk->m_curAddress; + m_currentChunk->m_curAddress = (void*)((unsigned int)m_currentChunk->m_curAddress + allocSize); + + return retPtr; +} + + + +void gmMemChain::Reset() +{ + m_currentChunk = m_rootChunk; + if(m_currentChunk) + { + m_currentChunk->m_curAddress = m_currentChunk->m_minAddress; + } +} + + + +unsigned int gmMemChain::GetSystemMemUsed() const +{ + MemChunk * chunk = m_rootChunk; + unsigned int total = 0; + + while(chunk) + { + total += m_chunkSize; + chunk = chunk->m_nextChunk; + } + + return total; +} + diff --git a/vscript/languages/gm/src/gm/gmMemChain.h b/vscript/languages/gm/src/gm/gmMemChain.h new file mode 100644 index 00000000..b5ca0490 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmMemChain.h @@ -0,0 +1,71 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMMEMCHAIN_H_ +#define _GMMEMCHAIN_H_ + +#include "gmConfig.h" + +/// \class gmMemChain +/// \brief gmMemChain is a simple memory allocator that allows many small allocations from one heap allocation. +class gmMemChain +{ +public: + + gmMemChain(unsigned int a_elementSize, unsigned int a_numElementsInChunk); + virtual ~gmMemChain(); + + /// \brief Alloc() + void* Alloc(unsigned int a_numElements); + void* Alloc(); + + /// \brief Alloc memory + /// \param a_numBytes Number of bytes ot allocate. + /// \param a_alignNumBytes Number of bytes to align to. + void* AllocBytes(unsigned int a_numBytes, unsigned int a_alignNumBytes = 1); + + /// \brief Reset() + void Reset(); + + /// \brief ResetAndFreeMemory() + void ResetAndFreeMemory(); + + /// \brief Presize + void Presize(int a_kbytes); + + /// \brief GetElementSize() + inline unsigned int GetElementSize() { return m_elementSize; } + + /// \brief GetSystemMemUsed will return the number of bytes allocated by the system. + unsigned int GetSystemMemUsed() const; + +protected: + + struct MemChunk + { + MemChunk* m_nextChunk; + MemChunk* m_lastChunk; + void* m_curAddress; + void* m_minAddress; + void* m_lastAddress; + }; + + unsigned int m_chunkSize; //!< Size of memory chunk + unsigned int m_elementSize; //!< Size of element + MemChunk* m_rootChunk; //!< First chunk in chain + MemChunk* m_currentChunk; //!< Current chunk alloc's use + + inline MemChunk* NewChunk(); + inline void FreeChunks(); +}; + + +#endif // _GMMEMCHAIN_H_ diff --git a/vscript/languages/gm/src/gm/gmMemFixed.cpp b/vscript/languages/gm/src/gm/gmMemFixed.cpp new file mode 100644 index 00000000..78f32b37 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmMemFixed.cpp @@ -0,0 +1,17 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmMemFixed.h" + + +// Must be last header +#include "memdbgon.h" diff --git a/vscript/languages/gm/src/gm/gmMemFixed.h b/vscript/languages/gm/src/gm/gmMemFixed.h new file mode 100644 index 00000000..b43e77f5 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmMemFixed.h @@ -0,0 +1,182 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMMEMFIXED_H_ +#define _GMMEMFIXED_H_ + +#include "gmMemChain.h" + +/// \class gmMemFixed +/// \brief Fixed memory allocator, wrapper on chain memory allocator to provide memory reuse. +/// Performance note: use can cause more random memory access +class gmMemFixed +{ +public: + + inline gmMemFixed(unsigned int a_elementSize, unsigned int a_growSize = 64); + inline ~gmMemFixed(); + + /// \brief Alloc() an element + inline void* Alloc(); + + /// \brief Free() an element + inline void Free(void* a_ptr); + + /// \brief Reset() + inline void Reset(); + + /// \brief ResetAndFreeMemory() + inline void ResetAndFreeMemory(); + + /// \brief Presize + inline void Presize(int a_kbytes) { m_memChain.Presize(a_kbytes); } + + inline unsigned int GetElementSize(); + + /// \brief GetSystemMemUsed will return the number of bytes allocated by the system. + inline unsigned int GetSystemMemUsed() const { return m_memChain.GetSystemMemUsed(); } + +#ifdef GM_DEBUG_BUILD + /// \brief GetMemUsed() + inline unsigned int GetMemUsed() const { return m_memUsed; } +#endif // GM_DEBUG_BUILD + +protected: + + // Free list node structure to simplify coding of recycle list. + struct FreeListNode + { + FreeListNode * m_next; + }; + + FreeListNode* m_freeList; //!< List of memory block we can reuse + gmMemChain m_memChain; //!< The chain memory used to actually allocate chunks + +#ifdef GM_DEBUG_BUILD + int m_memUsed; +#endif // GM_DEBUG_BUILD +}; + + + +gmMemFixed::gmMemFixed(unsigned int a_elementSize, unsigned int a_growSize) + : m_memChain(a_elementSize, a_growSize) +{ + GM_ASSERT(a_elementSize >= sizeof(FreeListNode)); + m_freeList = NULL; +#ifdef GM_DEBUG_BUILD + m_memUsed = 0; +#endif // GM_DEBUG_BUILD +} + + + +gmMemFixed::~gmMemFixed() +{ + ResetAndFreeMemory(); +} + + + +void* gmMemFixed::Alloc() +{ + void* newMemPtr; + + //Is one available on the free list? + newMemPtr = m_freeList; + if(m_freeList) + { + m_freeList = m_freeList->m_next; + } + else + { + //No, so get chain to alloc a new one + newMemPtr = m_memChain.Alloc(); + } + +#ifdef GM_DEBUG_BUILD + m_memUsed += m_memChain.GetElementSize(); +#endif // GM_DEBUG_BUILD + +#if 0 + // clear new mem pointer to 0xB00BFEED + int * n = (int *) newMemPtr; + int c = m_memChain.GetElementSize() / sizeof(int); + while(c--) *(n++) = 0xB00BFEED; +#endif + + return newMemPtr; +} + + + +void gmMemFixed::Free(void* a_ptr) +{ +#if 0 + // make sure a_ptr is not already in list (freeing something twice) + FreeListNode * node = m_freeList; + while(node) + { + GM_ASSERT(a_ptr != node); + node = node->m_next; + } +#endif + + if(a_ptr) + { +#if 0 + // clear new mem pointer to 0xFEEDFACE + int * n = (int *) a_ptr; + int c = m_memChain.GetElementSize() / sizeof(int); + while(c--) *(n++) = 0xFEEDFACE; +#endif + + //Add pointer to free list so we can reuse it + ((FreeListNode*)a_ptr)->m_next = m_freeList; + m_freeList = (FreeListNode*)a_ptr; +#ifdef GM_DEBUG_BUILD + m_memUsed -= m_memChain.GetElementSize(); + GM_ASSERT(m_memUsed >= 0); +#endif // GM_DEBUG_BUILD + } +} + + + +void gmMemFixed::ResetAndFreeMemory() +{ + m_freeList = NULL; +#ifdef GM_DEBUG_BUILD + m_memUsed = 0; +#endif // GM_DEBUG_BUILD + m_memChain.ResetAndFreeMemory(); +} + + + +void gmMemFixed::Reset() +{ + m_freeList = NULL; +#ifdef GM_DEBUG_BUILD + m_memUsed = 0; +#endif // GM_DEBUG_BUILD + m_memChain.Reset(); +} + + + +unsigned int gmMemFixed::GetElementSize() +{ + return (unsigned int)m_memChain.GetElementSize(); +} + + +#endif // _GMMEMFIXED_H_ diff --git a/vscript/languages/gm/src/gm/gmMemFixedSet.cpp b/vscript/languages/gm/src/gm/gmMemFixedSet.cpp new file mode 100644 index 00000000..b5abe8fe --- /dev/null +++ b/vscript/languages/gm/src/gm/gmMemFixedSet.cpp @@ -0,0 +1,140 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmMemFixedSet.h" + +// Must be last header +#include "memdbgon.h" + + +void gmMemFixedSet::Reset() +{ + m_mem8.Reset(); + m_mem16.Reset(); + m_mem24.Reset(); + m_mem32.Reset(); + m_mem64.Reset(); + m_mem128.Reset(); + m_mem256.Reset(); + m_mem512.Reset(); + FreeBigAllocs(); //This actually frees the big fellas +} + + + +void gmMemFixedSet::ResetAndFreeMemory() +{ + m_mem8.ResetAndFreeMemory(); + m_mem16.ResetAndFreeMemory(); + m_mem24.ResetAndFreeMemory(); + m_mem32.ResetAndFreeMemory(); + m_mem64.ResetAndFreeMemory(); + m_mem128.ResetAndFreeMemory(); + m_mem256.ResetAndFreeMemory(); + m_mem512.ResetAndFreeMemory(); + FreeBigAllocs(); +} + + + +unsigned int gmMemFixedSet::GetSystemMemUsed() const +{ + unsigned int total = 0; + total += m_mem8.GetSystemMemUsed(); + total += m_mem16.GetSystemMemUsed(); + total += m_mem24.GetSystemMemUsed(); + total += m_mem32.GetSystemMemUsed(); + total += m_mem64.GetSystemMemUsed(); + total += m_mem128.GetSystemMemUsed(); + total += m_mem256.GetSystemMemUsed(); + total += m_mem512.GetSystemMemUsed(); + + + BigMemNode* curNode = m_bigAllocs.GetFirst(); + while(m_bigAllocs.IsValid(curNode)) + { + total += curNode->m_size; + curNode = m_bigAllocs.GetNext(curNode); + } + return total; +} + + +void gmMemFixedSet::PrintStats() const +{ +#ifdef GM_DEBUG_BUILD + + int used; + const char * msg = "%d btye pool uses %dk of memory, thats %d allocations\n"; + + used = m_mem8.GetSystemMemUsed(); + GM_PRINTF(msg, 8, used / 1024, used / 8); + + used = m_mem16.GetSystemMemUsed(); + GM_PRINTF(msg, 16, used / 1024, used / 16); + + used = m_mem24.GetSystemMemUsed(); + GM_PRINTF(msg, 24, used / 1024, used / 24); + + used = m_mem32.GetSystemMemUsed(); + GM_PRINTF(msg, 32, used / 1024, used / 32); + + used = m_mem64.GetSystemMemUsed(); + GM_PRINTF(msg, 64, used / 1024, used / 64); + + used = m_mem128.GetSystemMemUsed(); + GM_PRINTF(msg, 128, used / 1024, used / 128); + + used = m_mem256.GetSystemMemUsed(); + GM_PRINTF(msg, 256, used / 1024, used / 256); + + used = m_mem512.GetSystemMemUsed(); + GM_PRINTF(msg, 512, used / 1024, used / 512); + +#endif //GM_DEBUG_BUILD +} + + +void gmMemFixedSet::Presize(int a_pool8, + int a_pool16, + int a_pool24, + int a_pool32, + int a_pool64, + int a_pool128, + int a_pool256, + int a_pool512 + ) +{ + if( a_pool8 ) { m_mem8.Presize(a_pool8); } + if( a_pool16 ) { m_mem16.Presize(a_pool16); } + if( a_pool24 ) { m_mem24.Presize(a_pool24); } + if( a_pool32 ) { m_mem32.Presize(a_pool32); } + if( a_pool64 ) { m_mem64.Presize(a_pool64); } + if( a_pool128 ) { m_mem128.Presize(a_pool128); } + if( a_pool256 ) { m_mem256.Presize(a_pool256); } + if( a_pool512 ) { m_mem512.Presize(a_pool512); } +} + + +void gmMemFixedSet::FreeBigAllocs() +{ + BigMemNode* curNode = m_bigAllocs.GetFirst(); + while(m_bigAllocs.IsValid(curNode)) + { + BigMemNode* nodeToDelete = curNode; + curNode = m_bigAllocs.GetNext(curNode); + + delete [] (char*)nodeToDelete; + } + m_bigAllocs.RemoveAll(); +} + diff --git a/vscript/languages/gm/src/gm/gmMemFixedSet.h b/vscript/languages/gm/src/gm/gmMemFixedSet.h new file mode 100644 index 00000000..e14db308 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmMemFixedSet.h @@ -0,0 +1,258 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMMEMFIXEDSET_H_ +#define _GMMEMFIXEDSET_H_ + +#include "gmMemFixed.h" +#include "gmListDouble.h" + + +/// \class gmMemFixedSet +/// \brief Fixed memory allocator, Allows varying size allocations using a set of fixed allocators. +class gmMemFixedSet +{ +public: + + inline gmMemFixedSet(); + inline ~gmMemFixedSet(); + + /// \brief Alloc() an element + /// \param a_size size of allocation + inline void* Alloc(int a_size); + + /// \brief Free() an element + /// \param a_size size of allocation + inline void Free(void* a_ptr); + + /// \brief Reset() + void Reset(); + + /// \brief ResetAndFreeMemory() + void ResetAndFreeMemory(); + + /// \brief GetMemUsed() will return the number of bytes allocated and returned, not + /// the total number of bytes allocated by the memFixedSet object. + inline unsigned int GetMemUsed() const { return m_memUsed; } + + /// \brief GetSystemMemUsed will return the number of bytes allocated by the system. + unsigned int GetSystemMemUsed() const; + + /// \brief Presize() will presize the memfixed pools + void Presize(int a_pool8, + int a_pool16, + int a_pool24, + int a_pool32, + int a_pool64, + int a_pool128, + int a_pool256, + int a_pool512 + ); + + /// \brief PrintStats() will print out the stats for gm memory + void PrintStats() const; + +protected: + + /// \brief Internal data structure for small allocations + struct SmallMemNode + { + int m_size; ///< Allocation size + char* Data() {return (char*)(this + 1);} ///< Get ptr after this structure + }; + + /// \brief Internal data structure for large allocations + struct BigMemNode: public gmListDoubleNode + { + int m_size; ///< Allocation size + char* Data() {return (char*)(this + 1);} ///< Get ptr after this structure + }; + + void FreeBigAllocs(); ///< Free the big allocations + inline SmallMemNode* GetSmallNodeData(void* a_ptr) { return ((SmallMemNode*)a_ptr)-1; } + inline BigMemNode* GetBigNodeData(void* a_ptr) { return ((BigMemNode*)a_ptr)-1; } + + gmMemFixed m_mem8; ///< Memory for 8 bytes and less + gmMemFixed m_mem16; ///< Memory for 16 bytes and less + gmMemFixed m_mem24; ///< Memory for 24 bytes and less + gmMemFixed m_mem32; ///< Memory for 32 bytes and less + gmMemFixed m_mem64; ///< Memory for 64 bytes and less + gmMemFixed m_mem128; ///< Memory for 128 bytes and less + gmMemFixed m_mem256; ///< Memory for 256 bytes and less + gmMemFixed m_mem512; ///< Memory for 512 bytes and less + gmListDouble m_bigAllocs; ///< List holding memory for more than 512 bytes + int m_memUsed; + +}; + + +gmMemFixedSet::gmMemFixedSet() + : m_mem8(8 + sizeof(SmallMemNode), 64), + m_mem16(16 + sizeof(SmallMemNode), 64), + m_mem24(24 + sizeof(SmallMemNode), 64), + m_mem32(32 + sizeof(SmallMemNode), 64), + m_mem64(64 + sizeof(SmallMemNode), 32), + m_mem128(128 + sizeof(SmallMemNode), 32), + m_mem256(256 + sizeof(SmallMemNode), 16), + m_mem512(512 + sizeof(SmallMemNode), 16) +{ + m_memUsed = 0; +} + + +gmMemFixedSet::~gmMemFixedSet() +{ + FreeBigAllocs(); +} + + +void* gmMemFixedSet::Alloc(int a_size) +{ + SmallMemNode* node; + + if (a_size <= 32) + { + if (a_size <= 8) + { + node = (SmallMemNode*)m_mem8.Alloc(); + node->m_size = 8; + m_memUsed += 8; + } + else if (a_size <= 16) + { + node = (SmallMemNode*)m_mem16.Alloc(); + node->m_size = 16; + m_memUsed += 16; + } + else if (a_size <= 24) + { + node = (SmallMemNode*)m_mem24.Alloc(); + node->m_size = 24; + m_memUsed += 24; + } + else // if (a_size <= 32) + { + GM_ASSERT(a_size <= 32); + + node = (SmallMemNode*)m_mem32.Alloc(); + node->m_size = 32; + m_memUsed += 32; + } + } + else + { + if (a_size <= 64) + { + node = (SmallMemNode*)m_mem64.Alloc(); + node->m_size = 64; + m_memUsed += 64; + } + else if (a_size <= 128) + { + node = (SmallMemNode*)m_mem128.Alloc(); + node->m_size = 128; + m_memUsed += 128; + } + else if (a_size <= 256) + { + node = (SmallMemNode*)m_mem256.Alloc(); + node->m_size = 256; + m_memUsed += 256; + } + else if (a_size <= 512) + { + node = (SmallMemNode*)m_mem512.Alloc(); + node->m_size = 512; + m_memUsed += 512; + } + else + { + BigMemNode* bigNode; + + bigNode = (BigMemNode*)GM_NEW( char[a_size + sizeof(*bigNode)] ); // This will be aligned as it calls sys new + + m_bigAllocs.InsertFirst(bigNode); + bigNode->m_size = a_size; + m_memUsed += a_size; + + return bigNode->Data(); + } + } + + return node->Data(); +} + + +void gmMemFixedSet::Free(void* a_ptr) +{ + SmallMemNode* node = GetSmallNodeData(a_ptr); + int size = node->m_size; + + if (size <= 32) + { + if (size == 8) + { + m_mem8.Free(node); + m_memUsed -= 8; + } + else if (size == 16) + { + m_mem16.Free(node); + m_memUsed -= 16; + } + else if (size == 24) + { + m_mem24.Free(node); + m_memUsed -= 24; + } + else // if (size == 32) + { + GM_ASSERT(size == 32); + + m_mem32.Free(node); + m_memUsed -= 32; + } + } + else + { + if (size == 64) + { + m_mem64.Free(node); + m_memUsed -= 64; + } + else if (size == 128) + { + m_mem128.Free(node); + m_memUsed -= 128; + } + else if (size == 256) + { + m_mem256.Free(node); + m_memUsed -= 256; + } + else if (size == 512) + { + m_mem512.Free(node); + m_memUsed -= 512; + } + else + { + BigMemNode* bigNode = GetBigNodeData(a_ptr); + m_memUsed -= bigNode->m_size; + m_bigAllocs.Remove(bigNode); + delete [] (char*) bigNode; + } + } + + GM_ASSERT(m_memUsed >= 0); +} + +#endif // _GMMEMFIXEDSET_H_ diff --git a/vscript/languages/gm/src/gm/gmOperators.cpp b/vscript/languages/gm/src/gm/gmOperators.cpp new file mode 100644 index 00000000..cfd99ce3 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmOperators.cpp @@ -0,0 +1,603 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmOperators.h" +#include "gmThread.h" +#include "gmStringObject.h" +//#include + +// Must be last header +#include "memdbgon.h" + + +const char * gmGetOperatorName(gmOperator a_operator) +{ + switch(a_operator) + { + case O_GETDOT : return "getdot"; + case O_SETDOT : return "setdot"; + case O_GETIND : return "getind"; + case O_SETIND : return "setind"; + case O_ADD : return "add"; + case O_SUB : return "sub"; + case O_MUL : return "mul"; + case O_DIV : return "div"; + case O_REM : return "mod"; + case O_BIT_OR : return "bitor"; + case O_BIT_XOR : return "bitxor"; + case O_BIT_AND : return "bitand"; + case O_BIT_SHIFTLEFT : return "shiftleft"; + case O_BIT_SHIFTRIGHT : return "shiftright"; + case O_BIT_INV : return "bitinv"; + case O_LT : return "lt"; + case O_GT : return "gt"; + case O_LTE : return "lte"; + case O_GTE : return "gte"; + case O_EQ : return "eq"; + case O_NEQ : return "neq"; + case O_NEG : return "neg"; + case O_POS : return "pos"; + case O_NOT : return "not"; +#if GM_BOOL_OP + case O_BOOL : return "bool"; +#endif // GM_BOOL_OP + default :; + } + return "undefined"; +} + +gmOperator gmGetOperator(const char * a_operatorName) +{ + if(_gmstricmp(a_operatorName, "getdot") == 0) return O_GETDOT; + if(_gmstricmp(a_operatorName, "setdot") == 0) return O_SETDOT; + if(_gmstricmp(a_operatorName, "getind") == 0) return O_GETIND; + if(_gmstricmp(a_operatorName, "setind") == 0) return O_SETIND; + if(_gmstricmp(a_operatorName, "add") == 0) return O_ADD; + if(_gmstricmp(a_operatorName, "sub") == 0) return O_SUB; + if(_gmstricmp(a_operatorName, "mul") == 0) return O_MUL; + if(_gmstricmp(a_operatorName, "div") == 0) return O_DIV; + if(_gmstricmp(a_operatorName, "mod") == 0) return O_REM; + if(_gmstricmp(a_operatorName, "bitor") == 0) return O_BIT_OR; + if(_gmstricmp(a_operatorName, "bitxor") == 0) return O_BIT_XOR; + if(_gmstricmp(a_operatorName, "bitand") == 0) return O_BIT_AND; + if(_gmstricmp(a_operatorName, "shiftleft") == 0) return O_BIT_SHIFTLEFT; + if(_gmstricmp(a_operatorName, "shiftright") == 0) return O_BIT_SHIFTRIGHT; + if(_gmstricmp(a_operatorName, "bitinv") == 0) return O_BIT_INV; + if(_gmstricmp(a_operatorName, "lt") == 0) return O_LT; + if(_gmstricmp(a_operatorName, "gt") == 0) return O_GT; + if(_gmstricmp(a_operatorName, "lte") == 0) return O_LTE; + if(_gmstricmp(a_operatorName, "gte") == 0) return O_GTE; + if(_gmstricmp(a_operatorName, "eq") == 0) return O_EQ; + if(_gmstricmp(a_operatorName, "neq") == 0) return O_NEQ; + if(_gmstricmp(a_operatorName, "neg") == 0) return O_NEG; + if(_gmstricmp(a_operatorName, "pos") == 0) return O_POS; + if(_gmstricmp(a_operatorName, "not") == 0) return O_NOT; +#if GM_BOOL_OP + if(_gmstricmp(a_operatorName, "bool") == 0) return O_BOOL; +#endif // GM_BOOL_OP + return O_MAXOPERATORS; +} + + +// +// GM_NULL +// + +// +// GM_INT +// + +void GM_CDECL gmIntOpAdd(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands[0].m_value.m_int += a_operands[1].m_value.m_int; +} +void GM_CDECL gmIntOpSub(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands[0].m_value.m_int -= a_operands[1].m_value.m_int; +} +void GM_CDECL gmIntOpMul(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands[0].m_value.m_int *= a_operands[1].m_value.m_int; +} +void GM_CDECL gmIntOpDiv(gmThread * a_thread, gmVariable * a_operands) +{ +#if GMMACHINE_GMCHECKDIVBYZERO + if(a_operands[1].m_value.m_int != 0) + { + a_operands[0].m_value.m_int /= a_operands[1].m_value.m_int; + } + else + { + a_thread->GetMachine()->GetLog().LogEntry("Divide by zero."); + a_operands[0].Nullify(); + // NOTE: No proper way to signal exception from here at present + } +#else // GMMACHINE_GMCHECKDIVBYZERO + a_operands[0].m_value.m_int /= a_operands[1].m_value.m_int; +#endif // GMMACHINE_GMCHECKDIVBYZERO +} +void GM_CDECL gmIntOpRem(gmThread * a_thread, gmVariable * a_operands) +{ +#if GMMACHINE_GMCHECKDIVBYZERO + if(a_operands[1].m_value.m_int != 0) + { + a_operands[0].m_value.m_int %= a_operands[1].m_value.m_int; + } + else + { + a_thread->GetMachine()->GetLog().LogEntry("Divide by zero."); + a_operands[0].Nullify(); + // NOTE: No proper way to signal exception from here at present + } +#else // GMMACHINE_GMCHECKDIVBYZERO + a_operands[0].m_value.m_int %= a_operands[1].m_value.m_int; +#endif // GMMACHINE_GMCHECKDIVBYZERO +} +void GM_CDECL gmIntOpBitOr(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands[0].m_value.m_int |= a_operands[1].m_value.m_int; +} +void GM_CDECL gmIntOpBitXor(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands[0].m_value.m_int ^= a_operands[1].m_value.m_int; +} +void GM_CDECL gmIntOpBitAnd(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands[0].m_value.m_int &= a_operands[1].m_value.m_int; +} +void GM_CDECL gmIntOpBitShiftLeft(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands[0].m_value.m_int <<= a_operands[1].m_value.m_int; +} +void GM_CDECL gmIntOpBitShiftRight(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands[0].m_value.m_int >>= a_operands[1].m_value.m_int; +} +void GM_CDECL gmIntOpInv(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands[0].m_value.m_int = ~a_operands[0].m_value.m_int; +} +void GM_CDECL gmIntOpLT(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands[0].m_value.m_int = a_operands[0].m_value.m_int < a_operands[1].m_value.m_int; +} +void GM_CDECL gmIntOpGT(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands[0].m_value.m_int = a_operands[0].m_value.m_int > a_operands[1].m_value.m_int; +} +void GM_CDECL gmIntOpLTE(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands[0].m_value.m_int = a_operands[0].m_value.m_int <= a_operands[1].m_value.m_int; +} +void GM_CDECL gmIntOpGTE(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands[0].m_value.m_int = a_operands[0].m_value.m_int >= a_operands[1].m_value.m_int; +} +void GM_CDECL gmIntOpEQ(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands[0].m_value.m_int = (a_operands[0].m_value.m_int == a_operands[1].m_value.m_int); +} +void GM_CDECL gmIntOpNEQ(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands[0].m_value.m_int = (a_operands[0].m_value.m_int != a_operands[1].m_value.m_int); +} +void GM_CDECL gmIntOpNEG(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands[0].m_value.m_int = -a_operands[0].m_value.m_int; +} +void GM_CDECL gmIntOpPOS(gmThread * a_thread, gmVariable * a_operands) +{ +} +void GM_CDECL gmIntOpNOT(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands[0].m_value.m_int = !a_operands[0].m_value.m_int; +} + +// +// GM_FLOAT +// + +#define INTTOFLOAT(A) (((A)->m_type == GM_FLOAT) ? (A)->m_value.m_float : (float) (A)->m_value.m_int) + +void GM_CDECL gmFloatOpAdd(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands->m_value.m_float = INTTOFLOAT(a_operands) + INTTOFLOAT(a_operands + 1); + a_operands->m_type = GM_FLOAT; +} +void GM_CDECL gmFloatOpSub(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands->m_value.m_float = INTTOFLOAT(a_operands) - INTTOFLOAT(a_operands + 1); + a_operands->m_type = GM_FLOAT; +} +void GM_CDECL gmFloatOpMul(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands->m_value.m_float = INTTOFLOAT(a_operands) * INTTOFLOAT(a_operands + 1); + a_operands->m_type = GM_FLOAT; +} +void GM_CDECL gmFloatOpDiv(gmThread * a_thread, gmVariable * a_operands) +{ +#if GMMACHINE_GMCHECKDIVBYZERO + if(INTTOFLOAT(a_operands + 1) != 0) + { + a_operands->m_value.m_float = INTTOFLOAT(a_operands) / INTTOFLOAT(a_operands + 1); + a_operands->m_type = GM_FLOAT; + } + else + { + a_thread->GetMachine()->GetLog().LogEntry("Divide by zero."); + a_operands->Nullify(); // NOTE: Should probably return +/- INF, not null + // NOTE: No proper way to signal exception from here at present + } +#else // GMMACHINE_GMCHECKDIVBYZERO + a_operands->m_value.m_float = INTTOFLOAT(a_operands) / INTTOFLOAT(a_operands + 1); + a_operands->m_type = GM_FLOAT; +#endif // GMMACHINE_GMCHECKDIVBYZERO +} +void GM_CDECL gmFloatOpRem(gmThread * a_thread, gmVariable * a_operands) +{ +#if GMMACHINE_GMCHECKDIVBYZERO + if(INTTOFLOAT(a_operands + 1) != 0) + { + a_operands->m_value.m_float = fmodf(INTTOFLOAT(a_operands), INTTOFLOAT(a_operands + 1)); + a_operands->m_type = GM_FLOAT; + } + else + { + a_thread->GetMachine()->GetLog().LogEntry("Divide by zero."); + a_operands->Nullify(); + // NOTE: No proper way to signal exception from here at present + } +#else // GMMACHINE_GMCHECKDIVBYZERO + a_operands->m_value.m_float = fmodf(INTTOFLOAT(a_operands), INTTOFLOAT(a_operands + 1)); + a_operands->m_type = GM_FLOAT; +#endif // GMMACHINE_GMCHECKDIVBYZERO +} +void GM_CDECL gmFloatOpInc(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands->m_value.m_float = INTTOFLOAT(a_operands) + 1.0f; + a_operands->m_type = GM_FLOAT; +} +void GM_CDECL gmFloatOpDec(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands->m_value.m_float = INTTOFLOAT(a_operands) - 1.0f; + a_operands->m_type = GM_FLOAT; +} +void GM_CDECL gmFloatOpLT(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands->m_value.m_int = (INTTOFLOAT(a_operands) < INTTOFLOAT(a_operands + 1)); + a_operands->m_type = GM_INT; +} +void GM_CDECL gmFloatOpGT(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands->m_value.m_int = (INTTOFLOAT(a_operands) > INTTOFLOAT(a_operands + 1)); + a_operands->m_type = GM_INT; +} +void GM_CDECL gmFloatOpLTE(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands->m_value.m_int = (INTTOFLOAT(a_operands) <= INTTOFLOAT(a_operands + 1)); + a_operands->m_type = GM_INT; +} +void GM_CDECL gmFloatOpGTE(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands->m_value.m_int = (INTTOFLOAT(a_operands) >= INTTOFLOAT(a_operands + 1)); + a_operands->m_type = GM_INT; +} +void GM_CDECL gmFloatOpEQ(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands->m_value.m_int = (INTTOFLOAT(a_operands) == INTTOFLOAT(a_operands + 1)); + a_operands->m_type = GM_INT; +} +void GM_CDECL gmFloatOpNEQ(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands->m_value.m_int = (INTTOFLOAT(a_operands) != INTTOFLOAT(a_operands + 1)); + a_operands->m_type = GM_INT; +} +void GM_CDECL gmFloatOpNEG(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands->m_value.m_float = -INTTOFLOAT(a_operands); + a_operands->m_type = GM_FLOAT; +} +void GM_CDECL gmFloatOpPOS(gmThread * a_thread, gmVariable * a_operands) +{ +} +void GM_CDECL gmFloatOpNOT(gmThread * a_thread, gmVariable * a_operands) +{ + if(a_operands->m_value.m_float == 0.0f) + { + a_operands->m_value.m_int = 1; a_operands->m_type = GM_INT; + } + else + { + a_operands->m_value.m_int = 0; a_operands->m_type = GM_INT; + } +} + +// +// GM_STRING +// + +#define GMSTRING_BUFFERSIZE 64 + +// we could use gmVariable::AsString here, but this is for types <= string.... is a little more efficient. +// a_buffer must be >= 64 +inline const char * gmUnknownToString(gmMachine * a_machine, gmVariable * a_unknown, char * a_buffer, int * a_len = NULL) +{ + if(a_unknown->m_type == GM_STRING) + { + gmStringObject * str = (gmStringObject *) GM_MOBJECT(a_machine, a_unknown->m_value.m_ref); + if(a_len) { *a_len = str->GetLength(); } + return (const char *) *str; + } + if(a_unknown->m_type == GM_INT) + { + V_snprintf(a_buffer, 64, "%d", a_unknown->m_value.m_int); // this won't be > 64 chars + } + else if(a_unknown->m_type == GM_FLOAT) + { + V_snprintf(a_buffer, 64, "%f", a_unknown->m_value.m_float); // this won't be > 64 chars + } + else + { + strcpy(a_buffer, "null"); + } + if(a_len) { *a_len = strlen(a_buffer); } + return a_buffer; +} +void GM_CDECL gmStringOpAdd(gmThread * a_thread, gmVariable * a_operands) +{ + gmMachine * machine = a_thread->GetMachine(); + char buffer1[GMSTRING_BUFFERSIZE]; + char buffer2[GMSTRING_BUFFERSIZE]; + int len1 = 0, len2 = 0; + const char * str1 = gmUnknownToString(machine, a_operands, buffer1, &len1); + const char * str2 = gmUnknownToString(machine, a_operands + 1, buffer2, &len2); + char * buffer = (char *) alloca(len1 + len2 + 1); + memcpy(buffer, str1, len1); + memcpy(buffer + len1, str2, len2 + 1); + a_thread->SetTop(a_operands); // so the garbage collector works + a_operands->m_type = GM_STRING; + a_operands->m_value.m_ref = (gmptr) machine->AllocStringObject(buffer, len1 + len2); +} +void GM_CDECL gmStringOpLT(gmThread * a_thread, gmVariable * a_operands) +{ + gmMachine * machine = a_thread->GetMachine(); + char buffer1[GMSTRING_BUFFERSIZE]; + char buffer2[GMSTRING_BUFFERSIZE]; + const char * str1 = gmUnknownToString(machine, a_operands, buffer1); + const char * str2 = gmUnknownToString(machine, a_operands + 1, buffer2); + int res = strcmp(str1, str2); + a_operands->m_type = GM_INT; + a_operands->m_value.m_ref = (res == -1) ? 1 : 0; +} +void GM_CDECL gmStringOpGT(gmThread * a_thread, gmVariable * a_operands) +{ + gmMachine * machine = a_thread->GetMachine(); + char buffer1[GMSTRING_BUFFERSIZE]; + char buffer2[GMSTRING_BUFFERSIZE]; + const char * str1 = gmUnknownToString(machine, a_operands, buffer1); + const char * str2 = gmUnknownToString(machine, a_operands + 1, buffer2); + int res = strcmp(str1, str2); + a_operands->m_type = GM_INT; + a_operands->m_value.m_ref = (res == 1) ? 1 : 0; +} +void GM_CDECL gmStringOpLTE(gmThread * a_thread, gmVariable * a_operands) +{ + gmMachine * machine = a_thread->GetMachine(); + char buffer1[GMSTRING_BUFFERSIZE]; + char buffer2[GMSTRING_BUFFERSIZE]; + const char * str1 = gmUnknownToString(machine, a_operands, buffer1); + const char * str2 = gmUnknownToString(machine, a_operands + 1, buffer2); + int res = strcmp(str1, str2); + a_operands->m_type = GM_INT; + a_operands->m_value.m_ref = (res == 1) ? 0 : 1; +} +void GM_CDECL gmStringOpGTE(gmThread * a_thread, gmVariable * a_operands) +{ + gmMachine * machine = a_thread->GetMachine(); + char buffer1[GMSTRING_BUFFERSIZE]; + char buffer2[GMSTRING_BUFFERSIZE]; + const char * str1 = gmUnknownToString(machine, a_operands, buffer1); + const char * str2 = gmUnknownToString(machine, a_operands + 1, buffer2); + int res = strcmp(str1, str2); + a_operands->m_type = GM_INT; + a_operands->m_value.m_ref = (res == -1) ? 0 : 1; +} +void GM_CDECL gmStringOpEQ(gmThread * a_thread, gmVariable * a_operands) +{ + gmMachine * machine = a_thread->GetMachine(); + char buffer1[GMSTRING_BUFFERSIZE]; + char buffer2[GMSTRING_BUFFERSIZE]; + const char * str1 = gmUnknownToString(machine, a_operands, buffer1); + const char * str2 = gmUnknownToString(machine, a_operands + 1, buffer2); + int res = strcmp(str1, str2); + a_operands->m_type = GM_INT; + a_operands->m_value.m_ref = (res == 0) ? 1 : 0; +} +void GM_CDECL gmStringOpNEQ(gmThread * a_thread, gmVariable * a_operands) +{ + gmMachine * machine = a_thread->GetMachine(); + char buffer1[GMSTRING_BUFFERSIZE]; + char buffer2[GMSTRING_BUFFERSIZE]; + const char * str1 = gmUnknownToString(machine, a_operands, buffer1); + const char * str2 = gmUnknownToString(machine, a_operands + 1, buffer2); + int res = strcmp(str1, str2); + a_operands->m_type = GM_INT; + a_operands->m_value.m_ref = (res == 0) ? 0 : 1; +} + +void GM_CDECL gmStringOpNOT(gmThread * a_thread, gmVariable * a_operands) +{ + a_operands->m_value.m_int = 0; a_operands->m_type = GM_INT; +} + +// +// GM_TABLE +// + +void GM_CDECL gmTableGetDot(gmThread * a_thread, gmVariable * a_operands) +{ + gmTableObject * table = (gmTableObject *) GM_OBJECT(a_operands->m_value.m_ref); + *a_operands = table->Get(a_operands[1]); +} +void GM_CDECL gmTableSetDot(gmThread * a_thread, gmVariable * a_operands) +{ + gmMachine * machine = a_thread->GetMachine(); + gmTableObject * table = (gmTableObject *) GM_MOBJECT(machine, a_operands->m_value.m_ref); + table->Set(machine, a_operands[2], a_operands[1]); +} +void GM_CDECL gmTableGetInd(gmThread * a_thread, gmVariable * a_operands) +{ + gmTableObject * table = (gmTableObject *) GM_OBJECT(a_operands->m_value.m_ref); + *a_operands = table->Get(a_operands[1]); +} +void GM_CDECL gmTableSetInd(gmThread * a_thread, gmVariable * a_operands) +{ + gmMachine * machine = a_thread->GetMachine(); + gmTableObject * table = (gmTableObject *) GM_MOBJECT(machine, a_operands->m_value.m_ref); + table->Set(machine, a_operands[1], a_operands[2]); +} + +// +// GM_USER +// + +// +// MISC. +// + +void GM_CDECL gmRefOpEQ(gmThread * a_thread, gmVariable * a_operands) +{ + if(a_operands[0].m_type == a_operands[1].m_type && a_operands[0].m_value.m_ref == a_operands[1].m_value.m_ref) + { + a_operands->m_type = GM_INT; + a_operands->m_value.m_int = 1; + } + else + { + a_operands->m_type = GM_INT; + a_operands->m_value.m_int = 0; + } +} +void GM_CDECL gmRefOpNEQ(gmThread * a_thread, gmVariable * a_operands) +{ + if(a_operands[0].m_type == a_operands[1].m_type && a_operands[0].m_value.m_ref == a_operands[1].m_value.m_ref) + { + a_operands->m_type = GM_INT; + a_operands->m_value.m_int = 0; + } + else + { + a_operands->m_type = GM_INT; + a_operands->m_value.m_int = 1; + } +} +void GM_CDECL gmRefOpNOT(gmThread * a_thread, gmVariable * a_operands) +{ + if(a_operands->m_type == GM_NULL) + { + a_operands->m_type = GM_INT; + a_operands->m_value.m_int = 1; + } + else + { + a_operands->m_type = GM_INT; + a_operands->m_value.m_int = 0; + } +} + + + +void gmInitBasicType(gmType a_type, gmOperatorFunction * a_operators) +{ + memset(a_operators, 0, sizeof(gmOperatorFunction) * O_MAXOPERATORS); + + if(a_type == GM_NULL) + { + a_operators[O_EQ] = gmRefOpEQ; + a_operators[O_NEQ] = gmRefOpNEQ; + a_operators[O_NOT] = gmRefOpNOT; + } + else if(a_type == GM_INT) + { + a_operators[O_ADD] = gmIntOpAdd; + a_operators[O_SUB] = gmIntOpSub; + a_operators[O_MUL] = gmIntOpMul; + a_operators[O_DIV] = gmIntOpDiv; + a_operators[O_REM] = gmIntOpRem; + a_operators[O_BIT_OR] = gmIntOpBitOr; + a_operators[O_BIT_XOR] = gmIntOpBitXor; + a_operators[O_BIT_AND] = gmIntOpBitAnd; + a_operators[O_BIT_SHIFTLEFT] = gmIntOpBitShiftLeft; + a_operators[O_BIT_SHIFTRIGHT] = gmIntOpBitShiftRight; + a_operators[O_BIT_INV] = gmIntOpInv; + a_operators[O_LT] = gmIntOpLT; + a_operators[O_GT] = gmIntOpGT; + a_operators[O_LTE] = gmIntOpLTE; + a_operators[O_GTE] = gmIntOpGTE; + a_operators[O_EQ] = gmIntOpEQ; + a_operators[O_NEQ] = gmIntOpNEQ; + a_operators[O_NEG] = gmIntOpNEG; + a_operators[O_POS] = gmIntOpPOS; + a_operators[O_NOT] = gmIntOpNOT; + } + else if(a_type == GM_FLOAT) + { + a_operators[O_ADD] = gmFloatOpAdd; + a_operators[O_SUB] = gmFloatOpSub; + a_operators[O_MUL] = gmFloatOpMul; + a_operators[O_DIV] = gmFloatOpDiv; + a_operators[O_REM] = gmFloatOpRem; + a_operators[O_LT] = gmFloatOpLT; + a_operators[O_GT] = gmFloatOpGT; + a_operators[O_LTE] = gmFloatOpLTE; + a_operators[O_GTE] = gmFloatOpGTE; + a_operators[O_EQ] = gmFloatOpEQ; + a_operators[O_NEQ] = gmFloatOpNEQ; + a_operators[O_NEG] = gmFloatOpNEG; + a_operators[O_POS] = gmFloatOpPOS; + a_operators[O_NOT] = gmFloatOpNOT; + } + else if(a_type == GM_STRING) + { + a_operators[O_ADD] = gmStringOpAdd; + a_operators[O_LT] = gmStringOpLT; + a_operators[O_GT] = gmStringOpGT; + a_operators[O_LTE] = gmStringOpLTE; + a_operators[O_GTE] = gmStringOpGTE; + a_operators[O_EQ] = gmStringOpEQ; + a_operators[O_NEQ] = gmStringOpNEQ; + a_operators[O_NOT] = gmStringOpNOT; + } + else if(a_type == GM_TABLE) + { + a_operators[O_GETDOT] = gmTableGetDot; + a_operators[O_SETDOT] = gmTableSetDot; + a_operators[O_GETIND] = gmTableGetInd; + a_operators[O_SETIND] = gmTableSetInd; + a_operators[O_EQ] = gmRefOpEQ; + a_operators[O_NEQ] = gmRefOpNEQ; + a_operators[O_NOT] = gmRefOpNOT; + } + else if(a_type == GM_FUNCTION) + { + a_operators[O_EQ] = gmRefOpEQ; + a_operators[O_NEQ] = gmRefOpNEQ; + a_operators[O_NOT] = gmRefOpNOT; + } + else if(a_type >= GM_USER) + { + a_operators[O_EQ] = gmRefOpEQ; + a_operators[O_NEQ] = gmRefOpNEQ; + a_operators[O_NOT] = gmRefOpNOT; + } +} + diff --git a/vscript/languages/gm/src/gm/gmOperators.h b/vscript/languages/gm/src/gm/gmOperators.h new file mode 100644 index 00000000..55dcc2fd --- /dev/null +++ b/vscript/languages/gm/src/gm/gmOperators.h @@ -0,0 +1,79 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMOPERATORS_H_ +#define _GMOPERATORS_H_ + +#include "gmConfig.h" +#include "gmVariable.h" +#include "gmByteCode.h" + +struct gmVariable; +class gmThread; + + +/// \enum gmOperator +enum gmOperator +{ + // O_GETDOT to O_NOT MUST MATCH gmByteCode enum + + O_GETDOT = 0, // object, "member" (tos is a_operands + 2) + O_SETDOT, // object, value, "member" (tos is a_operands + 3) + O_GETIND, // object, index + O_SETIND, // object, index, value + + O_ADD, // op1, op2 (tos is a_operands + 2) + O_SUB, // op1, op2 + O_MUL, // op1, op2 + O_DIV, // op1, op2 + O_REM, // op1, op2 + + O_BIT_OR, // op1, op2 + O_BIT_XOR, // op1, op2 + O_BIT_AND, // op1, op2 + O_BIT_SHIFTLEFT, // op1, op2 (shift) + O_BIT_SHIFTRIGHT, // op1, op2 (shift) + O_BIT_INV, // op1 + + O_LT, // op1, op2 + O_GT, // op1, op2 + O_LTE, // op1, op2 + O_GTE, // op1, op2 + O_EQ, // op1, op2 + O_NEQ, // op1, op2 + + O_NEG, // op1 + O_POS, // op1 + O_NOT, // op1 + +#if GM_BOOL_OP + O_BOOL, // Special case for use in branch tests. Unary +#endif // GM_BOOL_OP + + O_MAXOPERATORS, +}; + +const char * gmGetOperatorName(gmOperator a_operator); +gmOperator gmGetOperator(const char * a_operatorName); // return O_MAXOPERATORS on error + +// +// gmOperatorFunction is an operator function that may be used instead of binding a c funciton. +// This style of operator is much quicker, as it does not require a full stack frame push and pop. +// Note though, that if you are creating gmObjects from within one of these operators, you must call +// a_thread->SetTop() with the known top of stack before you allocate your gmObject such that the garbage +// collector can mark all objects properly. +// Be careful using this style of operator and GC. +// +typedef void (GM_CDECL *gmOperatorFunction)(gmThread * a_thread, gmVariable * a_operands); + +void gmInitBasicType(gmType a_type, gmOperatorFunction * a_operators); + +#endif // _GMOPERATORS_H_ diff --git a/vscript/languages/gm/src/gm/gmParser.cpp b/vscript/languages/gm/src/gm/gmParser.cpp new file mode 100644 index 00000000..2f3ab9b2 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmParser.cpp @@ -0,0 +1,2021 @@ + +/* A Bison parser, made from gmparser.y with Bison version GNU Bison version 1.24 + */ + +#define YYBISON 1 /* Identify Bison output. */ + +#define yyparse gmparse +#define yylex gmlex +#define yyerror gmerror +#define yylval gmlval +#define yychar gmchar +#define yydebug gmdebug +#define yynerrs gmnerrs +#define KEYWORD_LOCAL 258 +#define KEYWORD_GLOBAL 259 +#define KEYWORD_MEMBER 260 +#define KEYWORD_AND 261 +#define KEYWORD_OR 262 +#define KEYWORD_IF 263 +#define KEYWORD_ELSE 264 +#define KEYWORD_WHILE 265 +#define KEYWORD_FOR 266 +#define KEYWORD_FOREACH 267 +#define KEYWORD_IN 268 +#define KEYWORD_BREAK 269 +#define KEYWORD_CONTINUE 270 +#define KEYWORD_NULL 271 +#define KEYWORD_DOWHILE 272 +#define KEYWORD_RETURN 273 +#define KEYWORD_FUNCTION 274 +#define KEYWORD_TABLE 275 +#define KEYWORD_THIS 276 +#define KEYWORD_TRUE 277 +#define KEYWORD_FALSE 278 +#define IDENTIFIER 279 +#define CONSTANT_HEX 280 +#define CONSTANT_BINARY 281 +#define CONSTANT_INT 282 +#define CONSTANT_CHAR 283 +#define CONSTANT_FLOAT 284 +#define CONSTANT_STRING 285 +#define SYMBOL_ASGN_BSR 286 +#define SYMBOL_ASGN_BSL 287 +#define SYMBOL_ASGN_ADD 288 +#define SYMBOL_ASGN_MINUS 289 +#define SYMBOL_ASGN_TIMES 290 +#define SYMBOL_ASGN_DIVIDE 291 +#define SYMBOL_ASGN_REM 292 +#define SYMBOL_ASGN_BAND 293 +#define SYMBOL_ASGN_BOR 294 +#define SYMBOL_ASGN_BXOR 295 +#define SYMBOL_RIGHT_SHIFT 296 +#define SYMBOL_LEFT_SHIFT 297 +#define SYMBOL_LTE 298 +#define SYMBOL_GTE 299 +#define SYMBOL_EQ 300 +#define SYMBOL_NEQ 301 +#define TOKEN_ERROR 302 + + + +#define YYPARSER +#include "gmConfig.h" +#include "gmCodeTree.h" +#define YYSTYPE gmCodeTreeNode * + +extern gmCodeTreeNode * g_codeTree; + +#define GM_BISON_DEBUG +#ifdef GM_BISON_DEBUG +#define YYDEBUG 1 +#define YYERROR_VERBOSE +#endif // GM_BISON_DEBUG + +// Must be last header +#include "memdbgon.h" + + +// +// HELPERS +// + +void ATTACH(gmCodeTreeNode * &a_res, gmCodeTreeNode * a_a, gmCodeTreeNode * a_b) +{ + YYSTYPE t = a_a; + if(t != NULL) + { + while(t->m_sibling != NULL) + { + t = t->m_sibling; + } + t->m_sibling = a_b; + if(a_b) { a_b->m_parent = t; } + a_res = a_a; + } + else + { + a_res = a_b; + } +} + +gmCodeTreeNode * CreateOperation(int a_subTypeType, gmCodeTreeNode * a_left = NULL, gmCodeTreeNode * a_right = NULL) +{ + gmCodeTreeNode * node = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_OPERATION, gmlineno, a_subTypeType); + node->SetChild(0, a_left); + node->SetChild(1, a_right); + return node; +} + +gmCodeTreeNode * CreateAsignExpression(int a_subTypeType, gmCodeTreeNode * a_left, gmCodeTreeNode * a_right) +{ + // we need to evaluate the complexety of the l-value... if it is a function call, index or dot to the left of a dot or index, we need to cache + // into a hidden variable. + + // todo + + gmCodeTreeNode * opNode = CreateOperation(a_subTypeType, a_left, a_right); + return CreateOperation(CTNOT_ASSIGN, a_left, opNode); +} + + +#ifndef YYLTYPE +typedef + struct yyltype + { + int timestamp; + int first_line; + int first_column; + int last_line; + int last_column; + char *text; + } + yyltype; + +#define YYLTYPE yyltype +#endif + +#ifndef YYSTYPE +#define YYSTYPE int +#endif +#include + +#ifndef __cplusplus +#ifndef __STDC__ +#define const +#endif +#endif + + + +#define YYFINAL 228 +#define YYFLAG -32768 +#define YYNTBASE 71 + +#define YYTRANSLATE(x) ((unsigned)(x) <= 302 ? yytranslate[x] : 108) + +static const char yytranslate[] = { 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 65, 2, 2, 2, 63, 56, 2, 52, + 53, 61, 59, 70, 60, 69, 62, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 68, 50, 57, + 51, 58, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 66, 2, 67, 55, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 48, 54, 49, 64, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47 +}; + +#if YYDEBUG != 0 +static const short yyprhs[] = { 0, + 0, 2, 4, 7, 9, 11, 13, 15, 17, 20, + 24, 28, 34, 36, 38, 40, 42, 45, 51, 59, + 67, 73, 79, 86, 94, 102, 112, 115, 118, 121, + 125, 127, 131, 135, 139, 143, 147, 151, 155, 159, + 163, 167, 171, 173, 176, 178, 180, 184, 186, 190, + 192, 196, 198, 202, 204, 208, 210, 214, 218, 220, + 224, 228, 232, 236, 238, 242, 246, 248, 252, 256, + 258, 262, 266, 270, 272, 275, 277, 279, 281, 283, + 285, 290, 294, 299, 305, 312, 316, 318, 322, 326, + 331, 334, 338, 343, 349, 354, 356, 360, 362, 366, + 368, 372, 374, 378, 380, 383, 385, 387, 389, 391, + 395, 397, 399, 401, 403, 405, 407, 409, 411, 413, + 415, 417 +}; + +static const short yyrhs[] = { 72, + 0, 73, 0, 72, 73, 0, 77, 0, 75, 0, + 78, 0, 79, 0, 80, 0, 48, 49, 0, 48, + 72, 49, 0, 76, 105, 50, 0, 76, 105, 51, + 83, 50, 0, 3, 0, 4, 0, 5, 0, 50, + 0, 81, 50, 0, 8, 52, 83, 53, 74, 0, + 8, 52, 83, 53, 74, 9, 74, 0, 8, 52, + 83, 53, 74, 9, 78, 0, 10, 52, 83, 53, + 74, 0, 17, 52, 83, 53, 74, 0, 11, 52, + 77, 82, 53, 74, 0, 11, 52, 77, 82, 81, + 53, 74, 0, 12, 52, 105, 13, 83, 53, 74, + 0, 12, 52, 105, 6, 105, 13, 83, 53, 74, + 0, 15, 50, 0, 14, 50, 0, 18, 50, 0, + 18, 83, 50, 0, 84, 0, 96, 51, 84, 0, + 96, 31, 84, 0, 96, 32, 84, 0, 96, 33, + 84, 0, 96, 34, 84, 0, 96, 35, 84, 0, + 96, 36, 84, 0, 96, 37, 84, 0, 96, 38, + 84, 0, 96, 39, 84, 0, 96, 40, 84, 0, + 50, 0, 83, 50, 0, 84, 0, 85, 0, 84, + 7, 85, 0, 86, 0, 85, 6, 86, 0, 87, + 0, 86, 54, 87, 0, 88, 0, 87, 55, 88, + 0, 89, 0, 88, 56, 89, 0, 90, 0, 89, + 45, 90, 0, 89, 46, 90, 0, 91, 0, 90, + 57, 91, 0, 90, 58, 91, 0, 90, 43, 91, + 0, 90, 44, 91, 0, 92, 0, 91, 42, 92, + 0, 91, 41, 92, 0, 93, 0, 92, 59, 93, + 0, 92, 60, 93, 0, 94, 0, 93, 61, 94, + 0, 93, 62, 94, 0, 93, 63, 94, 0, 96, + 0, 95, 94, 0, 59, 0, 60, 0, 64, 0, + 65, 0, 104, 0, 96, 66, 83, 67, 0, 96, + 52, 53, 0, 96, 52, 97, 53, 0, 96, 68, + 105, 52, 53, 0, 96, 68, 105, 52, 97, 53, + 0, 96, 69, 105, 0, 83, 0, 97, 70, 83, + 0, 20, 52, 53, 0, 20, 52, 100, 53, 0, + 48, 49, 0, 48, 100, 49, 0, 48, 100, 70, + 49, 0, 19, 52, 102, 53, 74, 0, 19, 52, + 53, 74, 0, 101, 0, 100, 70, 101, 0, 83, + 0, 105, 51, 83, 0, 103, 0, 102, 70, 103, + 0, 105, 0, 105, 51, 83, 0, 105, 0, 69, + 105, 0, 21, 0, 106, 0, 98, 0, 99, 0, + 52, 83, 53, 0, 24, 0, 25, 0, 26, 0, + 27, 0, 22, 0, 23, 0, 28, 0, 29, 0, + 107, 0, 16, 0, 30, 0, 107, 30, 0 +}; + +#endif + +#if YYDEBUG != 0 +static const short yyrline[] = { 0, + 122, 129, 133, 140, 144, 148, 152, 156, 163, 167, + 175, 180, 189, 193, 197, 203, 207, 214, 220, 227, + 237, 243, 249, 256, 264, 271, 282, 286, 290, 294, + 302, 310, 314, 318, 322, 326, 330, 334, 338, 342, + 346, 350, 358, 362, 369, 376, 380, 387, 391, 398, + 402, 410, 414, 422, 426, 434, 438, 442, 449, 453, + 457, 461, 465, 472, 476, 481, 489, 493, 498, 506, + 510, 515, 520, 528, 532, 541, 545, 549, 553, 560, + 564, 568, 573, 579, 585, 592, 599, 603, 610, 614, + 619, 623, 628, 636, 642, 650, 654, 661, 665, 672, + 676, 683, 688, 697, 701, 706, 710, 714, 718, 722, + 729, 738, 743, 748, 753, 758, 763, 809, 814, 818, + 826, 840 +}; + +static const char * const yytname[] = { "$","error","$undefined.","KEYWORD_LOCAL", +"KEYWORD_GLOBAL","KEYWORD_MEMBER","KEYWORD_AND","KEYWORD_OR","KEYWORD_IF","KEYWORD_ELSE", +"KEYWORD_WHILE","KEYWORD_FOR","KEYWORD_FOREACH","KEYWORD_IN","KEYWORD_BREAK", +"KEYWORD_CONTINUE","KEYWORD_NULL","KEYWORD_DOWHILE","KEYWORD_RETURN","KEYWORD_FUNCTION", +"KEYWORD_TABLE","KEYWORD_THIS","KEYWORD_TRUE","KEYWORD_FALSE","IDENTIFIER","CONSTANT_HEX", +"CONSTANT_BINARY","CONSTANT_INT","CONSTANT_CHAR","CONSTANT_FLOAT","CONSTANT_STRING", +"SYMBOL_ASGN_BSR","SYMBOL_ASGN_BSL","SYMBOL_ASGN_ADD","SYMBOL_ASGN_MINUS","SYMBOL_ASGN_TIMES", +"SYMBOL_ASGN_DIVIDE","SYMBOL_ASGN_REM","SYMBOL_ASGN_BAND","SYMBOL_ASGN_BOR", +"SYMBOL_ASGN_BXOR","SYMBOL_RIGHT_SHIFT","SYMBOL_LEFT_SHIFT","SYMBOL_LTE","SYMBOL_GTE", +"SYMBOL_EQ","SYMBOL_NEQ","TOKEN_ERROR","'{'","'}'","';'","'='","'('","')'","'|'", +"'^'","'&'","'<'","'>'","'+'","'-'","'*'","'/'","'%'","'~'","'!'","'['","']'", +"':'","'.'","','","program","statement_list","statement","compound_statement", +"var_statement","var_type","expression_statement","selection_statement","iteration_statement", +"jump_statement","assignment_expression","constant_expression_statement","constant_expression", +"logical_or_expression","logical_and_expression","inclusive_or_expression","exclusive_or_expression", +"and_expression","equality_expression","relational_expression","shift_expression", +"additive_expression","multiplicative_expression","unary_expression","unary_operator", +"postfix_expression","argument_expression_list","table_constructor","function_constructor", +"field_list","field","parameter_list","parameter","primary_expression","identifier", +"constant","constant_string_list","" +}; +#endif + +static const short yyr1[] = { 0, + 71, 72, 72, 73, 73, 73, 73, 73, 74, 74, + 75, 75, 76, 76, 76, 77, 77, 78, 78, 78, + 79, 79, 79, 79, 79, 79, 80, 80, 80, 80, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 82, 82, 83, 84, 84, 85, 85, 86, + 86, 87, 87, 88, 88, 89, 89, 89, 90, 90, + 90, 90, 90, 91, 91, 91, 92, 92, 92, 93, + 93, 93, 93, 94, 94, 95, 95, 95, 95, 96, + 96, 96, 96, 96, 96, 96, 97, 97, 98, 98, + 98, 98, 98, 99, 99, 100, 100, 101, 101, 102, + 102, 103, 103, 104, 104, 104, 104, 104, 104, 104, + 105, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 107, 107 +}; + +static const short yyr2[] = { 0, + 1, 1, 2, 1, 1, 1, 1, 1, 2, 3, + 3, 5, 1, 1, 1, 1, 2, 5, 7, 7, + 5, 5, 6, 7, 7, 9, 2, 2, 2, 3, + 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 1, 2, 1, 1, 3, 1, 3, 1, + 3, 1, 3, 1, 3, 1, 3, 3, 1, 3, + 3, 3, 3, 1, 3, 3, 1, 3, 3, 1, + 3, 3, 3, 1, 2, 1, 1, 1, 1, 1, + 4, 3, 4, 5, 6, 3, 1, 3, 3, 4, + 2, 3, 4, 5, 4, 1, 3, 1, 3, 1, + 3, 1, 3, 1, 2, 1, 1, 1, 1, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2 +}; + +static const short yydefact[] = { 0, + 13, 14, 15, 0, 0, 0, 0, 0, 0, 120, + 0, 0, 0, 0, 106, 115, 116, 111, 112, 113, + 114, 117, 118, 121, 0, 16, 0, 76, 77, 78, + 79, 0, 1, 2, 5, 0, 4, 6, 7, 8, + 0, 31, 46, 48, 50, 52, 54, 56, 59, 64, + 67, 70, 0, 74, 108, 109, 80, 104, 107, 119, + 0, 0, 0, 0, 28, 27, 0, 29, 0, 45, + 74, 0, 0, 91, 98, 0, 96, 104, 0, 105, + 3, 0, 17, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, + 0, 0, 0, 30, 0, 0, 100, 102, 89, 0, + 92, 0, 0, 110, 11, 0, 47, 49, 51, 53, + 55, 57, 58, 62, 63, 60, 61, 66, 65, 68, + 69, 71, 72, 73, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 32, 82, 87, 0, 0, 0, + 86, 0, 0, 43, 0, 0, 0, 0, 0, 0, + 95, 0, 0, 0, 90, 0, 93, 97, 99, 0, + 83, 0, 81, 0, 18, 21, 0, 0, 44, 0, + 0, 22, 9, 0, 94, 101, 103, 12, 88, 84, + 0, 0, 23, 0, 0, 0, 10, 85, 19, 20, + 24, 0, 25, 0, 26, 0, 0, 0 +}; + +static const short yydefgoto[] = { 226, + 33, 34, 181, 35, 36, 37, 38, 39, 40, 41, + 175, 75, 70, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 71, 168, 55, 56, 76, 77, + 126, 127, 57, 58, 59, 60 +}; + +static const short yypact[] = { 332, +-32768,-32768,-32768, 15, 17, 27, 31, -10, -1,-32768, + 34, 383, 35, 36,-32768,-32768,-32768,-32768,-32768,-32768, +-32768,-32768,-32768,-32768, 434,-32768, 683,-32768,-32768,-32768, +-32768, 32, 332,-32768,-32768, 32,-32768,-32768,-32768,-32768, + 8, 82, 84, 37, 38, 39, -2, 16, 6, 2, + -51,-32768, 683, 722,-32768,-32768,-32768,-32768,-32768, 62, + 683, 683, 485, 32,-32768,-32768, 683,-32768, 44, 82, + -27, -16, 126,-32768,-32768, -43,-32768, 45, 47,-32768, +-32768, 25,-32768, 683, 683, 683, 683, 683, 683, 683, + 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, + 683,-32768, 683, 683, 683, 683, 683, 683, 683, 683, + 683, 683, 683, 500, 683, 32, 32,-32768, 48, 49, + 551, 11, 63,-32768, 67, -44,-32768, 46,-32768, -40, +-32768, 602, 683,-32768,-32768, 683, 84, 37, 38, 39, + -2, 16, 16, 6, 6, 6, 6, 2, 2, -51, + -51,-32768,-32768,-32768, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82,-32768,-32768, -38, 50, 68, +-32768, 67, 67,-32768, 617, 71, 32, 683, 67, 206, +-32768, 67, 32, 683,-32768, 683,-32768,-32768,-32768, 72, +-32768, 683,-32768, 668, 114,-32768, 67, 73,-32768, 111, + 74,-32768,-32768, 269,-32768,-32768,-32768,-32768,-32768,-32768, + -34, -3,-32768, 67, 683, 67,-32768,-32768,-32768,-32768, +-32768, 75,-32768, 67,-32768, 129, 130,-32768 +}; + +static const short yypgoto[] = {-32768, + -48, -31, -144,-32768,-32768, 70, -81,-32768,-32768, -41, +-32768, 4, 0, 51, 53, 55, 52, 56, -12, -71, + -14, -13, -49,-32768, 1, -58,-32768,-32768, 85, -129, +-32768, -26,-32768, -18,-32768,-32768 +}; + + +#define YYLAST 791 + + +static const short yytable[] = { 42, + 54, 81, 188, 102, 4, 131, 78, 18, 182, 99, + 100, 101, 185, 80, 191, 69, 177, 82, 218, 144, + 145, 146, 147, 178, 114, 183, 132, 195, 196, 186, + 79, 192, 42, 54, 202, 192, 125, 205, 115, 65, + 116, 117, 89, 90, 180, 122, 95, 96, 66, 152, + 153, 154, 213, 128, 78, 18, 188, 83, 91, 92, + 97, 98, 42, 54, 119, 120, 61, 219, 62, 221, + 123, 223, 93, 94, 135, 136, 142, 143, 63, 225, + 148, 149, 64, 150, 151, 67, 72, 73, 84, 85, + 86, 118, 87, 124, 88, 133, 184, 170, 171, 134, + 172, 173, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 78, 180, 179, 193, 167, 169, 194, + 199, 208, 212, 215, 176, 214, 216, 224, 227, 228, + 220, 204, 121, 198, 137, 211, 189, 138, 140, 190, + 139, 10, 0, 141, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 206, 130, 200, 0, + 0, 0, 0, 0, 128, 0, 0, 78, 0, 0, + 0, 0, 81, 25, 42, 54, 0, 27, 129, 42, + 54, 201, 0, 0, 28, 29, 0, 207, 0, 30, + 31, 0, 0, 0, 32, 209, 0, 167, 0, 0, + 0, 0, 0, 42, 54, 0, 0, 0, 1, 2, + 3, 0, 0, 4, 0, 5, 6, 7, 222, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 25, 203, 26, 0, 27, 0, 0, + 0, 0, 0, 0, 28, 29, 0, 0, 0, 30, + 31, 1, 2, 3, 32, 0, 4, 0, 5, 6, + 7, 0, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 25, 217, 26, 0, + 27, 0, 0, 0, 0, 0, 0, 28, 29, 0, + 0, 0, 30, 31, 1, 2, 3, 32, 0, 4, + 0, 5, 6, 7, 0, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, + 0, 26, 0, 27, 0, 0, 0, 0, 0, 0, + 28, 29, 0, 0, 0, 30, 31, 0, 10, 0, + 32, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 68, 0, 27, 0, 0, 0, 0, 0, + 0, 28, 29, 0, 0, 0, 30, 31, 0, 10, + 0, 32, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 25, 74, 0, 0, 27, 0, 0, 0, 0, + 0, 0, 28, 29, 0, 0, 0, 30, 31, 0, + 10, 0, 32, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 10, 0, 0, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 0, 0, 25, 0, 26, 0, 27, 0, 0, 0, + 0, 0, 0, 28, 29, 0, 0, 25, 30, 31, + 0, 27, 166, 32, 0, 0, 0, 0, 28, 29, + 0, 0, 0, 30, 31, 0, 10, 0, 32, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, + 174, 0, 27, 0, 0, 0, 0, 0, 0, 28, + 29, 0, 0, 0, 30, 31, 0, 10, 0, 32, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 10, 0, 0, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 0, 0, 25, + 187, 0, 0, 27, 0, 0, 0, 0, 0, 0, + 28, 29, 0, 0, 25, 30, 31, 0, 27, 197, + 32, 0, 0, 0, 0, 28, 29, 0, 0, 0, + 30, 31, 0, 10, 0, 32, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 10, 0, + 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 0, 0, 25, 0, 0, 0, 27, + 210, 0, 0, 0, 0, 0, 28, 29, 0, 0, + 25, 30, 31, 0, 27, 0, 32, 0, 0, 0, + 0, 28, 29, 0, 0, 0, 30, 31, 0, 0, + 0, 32, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 114, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 115, 0, 116, + 117 +}; + +static const short yycheck[] = { 0, + 0, 33, 132, 53, 8, 49, 25, 24, 53, 61, + 62, 63, 53, 32, 53, 12, 6, 36, 53, 91, + 92, 93, 94, 13, 52, 70, 70, 172, 173, 70, + 27, 70, 33, 33, 179, 70, 53, 182, 66, 50, + 68, 69, 45, 46, 48, 64, 41, 42, 50, 99, + 100, 101, 197, 72, 73, 24, 186, 50, 43, 44, + 59, 60, 63, 63, 61, 62, 52, 212, 52, 214, + 67, 216, 57, 58, 50, 51, 89, 90, 52, 224, + 95, 96, 52, 97, 98, 52, 52, 52, 7, 6, + 54, 30, 55, 50, 56, 51, 51, 116, 117, 53, + 53, 53, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 132, 48, 53, 67, 114, 115, 52, + 50, 50, 9, 13, 121, 53, 53, 53, 0, 0, + 212, 180, 63, 175, 84, 194, 133, 85, 87, 136, + 86, 16, -1, 88, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 183, 73, 177, -1, + -1, -1, -1, -1, 183, -1, -1, 186, -1, -1, + -1, -1, 204, 48, 175, 175, -1, 52, 53, 180, + 180, 178, -1, -1, 59, 60, -1, 184, -1, 64, + 65, -1, -1, -1, 69, 192, -1, 194, -1, -1, + -1, -1, -1, 204, 204, -1, -1, -1, 3, 4, + 5, -1, -1, 8, -1, 10, 11, 12, 215, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 48, 49, 50, -1, 52, -1, -1, + -1, -1, -1, -1, 59, 60, -1, -1, -1, 64, + 65, 3, 4, 5, 69, -1, 8, -1, 10, 11, + 12, -1, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 48, 49, 50, -1, + 52, -1, -1, -1, -1, -1, -1, 59, 60, -1, + -1, -1, 64, 65, 3, 4, 5, 69, -1, 8, + -1, 10, 11, 12, -1, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 48, + -1, 50, -1, 52, -1, -1, -1, -1, -1, -1, + 59, 60, -1, -1, -1, 64, 65, -1, 16, -1, + 69, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 48, -1, 50, -1, 52, -1, -1, -1, -1, -1, + -1, 59, 60, -1, -1, -1, 64, 65, -1, 16, + -1, 69, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 48, 49, -1, -1, 52, -1, -1, -1, -1, + -1, -1, 59, 60, -1, -1, -1, 64, 65, -1, + 16, -1, 69, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 16, -1, -1, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + -1, -1, 48, -1, 50, -1, 52, -1, -1, -1, + -1, -1, -1, 59, 60, -1, -1, 48, 64, 65, + -1, 52, 53, 69, -1, -1, -1, -1, 59, 60, + -1, -1, -1, 64, 65, -1, 16, -1, 69, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 48, -1, + 50, -1, 52, -1, -1, -1, -1, -1, -1, 59, + 60, -1, -1, -1, 64, 65, -1, 16, -1, 69, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 16, -1, -1, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, -1, -1, 48, + 49, -1, -1, 52, -1, -1, -1, -1, -1, -1, + 59, 60, -1, -1, 48, 64, 65, -1, 52, 53, + 69, -1, -1, -1, -1, 59, 60, -1, -1, -1, + 64, 65, -1, 16, -1, 69, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 16, -1, + -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, -1, -1, 48, -1, -1, -1, 52, + 53, -1, -1, -1, -1, -1, 59, 60, -1, -1, + 48, 64, 65, -1, 52, -1, 69, -1, -1, -1, + -1, 59, 60, -1, -1, -1, 64, 65, -1, -1, + -1, 69, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 51, 52, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 66, -1, 68, + 69 +}; +/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ + + +/* Skeleton output parser for bison, + Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +#ifndef alloca +#ifdef __GNUC__ +#define alloca __builtin_alloca +#else /* not GNU C. */ +#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) +#include +#else /* not sparc */ +#if defined (MSDOS) && !defined (__TURBOC__) +#include +#else /* not MSDOS, or __TURBOC__ */ +#if defined(_AIX) +#include + #pragma alloca +#else /* not MSDOS, __TURBOC__, or _AIX */ +#ifdef __hpux +#ifdef __cplusplus +extern "C" { +void *alloca (unsigned int); +}; +#else /* not __cplusplus */ +void *alloca (); +#endif /* not __cplusplus */ +#endif /* __hpux */ +#endif /* not _AIX */ +#endif /* not MSDOS, or __TURBOC__ */ +#endif /* not sparc. */ +#endif /* not GNU C. */ +#endif /* alloca not defined. */ + +/* This is the parser code that is written into each bison parser + when the %semantic_parser declaration is not specified in the grammar. + It was written by Richard Stallman by simplifying the hairy parser + used when %semantic_parser is specified. */ + +/* Note: there must be only one dollar sign in this file. + It is replaced by the list of actions, each action + as one case of the switch. */ + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY -2 +#define YYEOF 0 +#define YYACCEPT return(0) +#define YYABORT return(1) +#define YYERROR goto yyerrlab1 +/* Like YYERROR except do call yyerror. + This remains here temporarily to ease the + transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ +#define YYFAIL goto yyerrlab +#define YYRECOVERING() (!!yyerrstatus) +#define YYBACKUP(token, value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { yychar = (token), yylval = (value); \ + yychar1 = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { yyerror ("syntax error: cannot back up"); YYERROR; } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +#ifndef YYPURE +#define YYLEX yylex() +#endif + +#ifdef YYPURE +#ifdef YYLSP_NEEDED +#ifdef YYLEX_PARAM +#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) +#else +#define YYLEX yylex(&yylval, &yylloc) +#endif +#else /* not YYLSP_NEEDED */ +#ifdef YYLEX_PARAM +#define YYLEX yylex(&yylval, YYLEX_PARAM) +#else +#define YYLEX yylex(&yylval) +#endif +#endif /* not YYLSP_NEEDED */ +#endif + +/* If nonreentrant, generate the variables here */ + +#ifndef YYPURE + +int yychar; /* the lookahead symbol */ +YYSTYPE yylval; /* the semantic value of the */ + /* lookahead symbol */ + +#ifdef YYLSP_NEEDED +YYLTYPE yylloc; /* location data for the lookahead */ + /* symbol */ +#endif + +int yynerrs; /* number of parse errors so far */ +#endif /* not YYPURE */ + +#if YYDEBUG != 0 +int yydebug; /* nonzero means print parse trace */ +/* Since this is uninitialized, it does not stop multiple parsers + from coexisting. */ +#endif + +/* YYINITDEPTH indicates the initial size of the parser's stacks */ + +#ifndef YYINITDEPTH +#define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH is the maximum size the stacks can grow to + (effective only if the built-in stack extension method is used). */ + +#if YYMAXDEPTH == 0 +#undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +#define YYMAXDEPTH 10000 +#endif + +/* Prevent warning if -Wstrict-prototypes. */ +#ifdef __GNUC__ +int yyparse (void); +#endif + +#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +#define __yy_memcpy(FROM,TO,COUNT) memcpy(TO,FROM,COUNT) +#else /* not GNU C or C++ */ +#ifndef __cplusplus + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__yy_memcpy (from, to, count) + char *from; + char *to; + int count; +{ + register char *f = from; + register char *t = to; + register int i = count; + + while (i-- > 0) + *t++ = *f++; +} + +#else /* __cplusplus */ + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__yy_memcpy (char *from, char *to, int count) +{ + register char *f = from; + register char *t = to; + register int i = count; + + while (i-- > 0) + *t++ = *f++; +} + +#endif +#endif + + + +/* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. + It should actually point to an object. + Grammar actions can access the variable by casting it + to the proper pointer type. */ + +#ifdef YYPARSE_PARAM +#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; +#else +#define YYPARSE_PARAM +#define YYPARSE_PARAM_DECL +#endif + +int +yyparse(YYPARSE_PARAM) + YYPARSE_PARAM_DECL +{ + register int yystate; + register int yyn; + register short *yyssp; + register YYSTYPE *yyvsp; + int yyerrstatus; /* number of tokens to shift before error messages enabled */ + int yychar1 = 0; /* lookahead token as an internal (translated) token number */ + + short yyssa[YYINITDEPTH]; /* the state stack */ + YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ + + short *yyss = yyssa; /* refer to the stacks thru separate pointers */ + YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ + +#ifdef YYLSP_NEEDED + YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ + YYLTYPE *yyls = yylsa; + YYLTYPE *yylsp; + +#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) +#else +#define YYPOPSTACK (yyvsp--, yyssp--) +#endif + + int yystacksize = YYINITDEPTH; + +#ifdef YYPURE + int yychar; + YYSTYPE yylval; + int yynerrs; +#ifdef YYLSP_NEEDED + YYLTYPE yylloc; +#endif +#endif + + YYSTYPE yyval; /* the variable used to return */ + /* semantic values from the action */ + /* routines */ + + int yylen; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Starting parse\n"); +#endif + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss - 1; + yyvsp = yyvs; +#ifdef YYLSP_NEEDED + yylsp = yyls; +#endif + +/* Push a new state, which is found in yystate . */ +/* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. */ +yynewstate: + + *++yyssp = (short) yystate; + + if (yyssp >= yyss + yystacksize - 1) + { + /* Give user a chance to reallocate the stack */ + /* Use copies of these so that the &'s don't force the real ones into memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; +#ifdef YYLSP_NEEDED + YYLTYPE *yyls1 = yyls; +#endif + + /* Get the current used size of the three stacks, in elements. */ + int size = yyssp - yyss + 1; + +#ifdef yyoverflow + /* Each stack pointer address is followed by the size of + the data in use in that stack, in bytes. */ +#ifdef YYLSP_NEEDED + /* This used to be a conditional around just the two extra args, + but that might be undefined if yyoverflow is a macro. */ + yyoverflow("parser stack overflow", + &yyss1, size * sizeof (*yyssp), + &yyvs1, size * sizeof (*yyvsp), + &yyls1, size * sizeof (*yylsp), + &yystacksize); +#else + yyoverflow("parser stack overflow", + &yyss1, size * sizeof (*yyssp), + &yyvs1, size * sizeof (*yyvsp), + &yystacksize); +#endif + + yyss = yyss1; yyvs = yyvs1; +#ifdef YYLSP_NEEDED + yyls = yyls1; +#endif +#else /* no yyoverflow */ + /* Extend the stack our own way. */ + if (yystacksize >= YYMAXDEPTH) + { + yyerror("parser stack overflow"); + return 2; + } + yystacksize *= 2; + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); + __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); + __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); +#ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); + __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); +#endif +#endif /* no yyoverflow */ + + yyssp = yyss + size - 1; + yyvsp = yyvs + size - 1; +#ifdef YYLSP_NEEDED + yylsp = yyls + size - 1; +#endif + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Stack size increased to %d\n", yystacksize); +#endif + + if (yyssp >= yyss + yystacksize - 1) + YYABORT; + } + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Entering state %d\n", yystate); +#endif + + goto yybackup; + yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* yychar is either YYEMPTY or YYEOF + or a valid token in external form. */ + + if (yychar == YYEMPTY) + { +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Reading a token: "); +#endif + yychar = YYLEX; + } + + /* Convert token to internal form (in yychar1) for indexing tables with */ + + if (yychar <= 0) /* This means end of input. */ + { + yychar1 = 0; + yychar = YYEOF; /* Don't call YYLEX any more */ + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Now at end of input.\n"); +#endif + } + else + { + yychar1 = YYTRANSLATE(yychar); + +#if YYDEBUG != 0 + if (yydebug) + { + fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); + /* Give the individual parser a way to print the precise meaning + of a token, for further debugging info. */ +#ifdef YYPRINT + YYPRINT (stderr, yychar, yylval); +#endif + fprintf (stderr, ")\n"); + } +#endif + } + + yyn += yychar1; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) + goto yydefault; + + yyn = yytable[yyn]; + + /* yyn is what to do for this token type in this state. + Negative => reduce, -yyn is rule number. + Positive => shift, yyn is new state. + New state is final state => don't bother to shift, + just return success. + 0, or most negative number => error. */ + + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrlab; + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); +#endif + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; +#ifdef YYLSP_NEEDED + *++yylsp = yylloc; +#endif + + /* count tokens shifted since error; after three, turn off error status. */ + if (yyerrstatus) yyerrstatus--; + + yystate = yyn; + goto yynewstate; + +/* Do the default action for the current state. */ +yydefault: + + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + +/* Do a reduction. yyn is the number of a rule to reduce with. */ +yyreduce: + yylen = yyr2[yyn]; + if (yylen > 0) + yyval = yyvsp[1-yylen]; /* implement default value of the action */ + +#if YYDEBUG != 0 + if (yydebug) + { + int i; + + fprintf (stderr, "Reducing via rule %d (line %d), ", + yyn, yyrline[yyn]); + + /* Print the symbols being reduced, and their result. */ + for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) + fprintf (stderr, "%s ", yytname[yyrhs[i]]); + fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); + } +#endif + + + switch (yyn) { + +case 1: +{ + g_codeTree = yyvsp[0]; + ; + break;} +case 2: +{ + yyval = yyvsp[0]; + ; + break;} +case 3: +{ + ATTACH(yyval, yyvsp[-1], yyvsp[0]); + ; + break;} +case 4: +{ + yyval = yyvsp[0]; + ; + break;} +case 5: +{ + yyval = yyvsp[0]; + ; + break;} +case 6: +{ + yyval = yyvsp[0]; + ; + break;} +case 7: +{ + yyval = yyvsp[0]; + ; + break;} +case 8: +{ + yyval = yyvsp[0]; + ; + break;} +case 9: +{ + yyval = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_COMPOUND, gmlineno); + ; + break;} +case 10: +{ + yyval = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_COMPOUND, gmlineno); + yyval->SetChild(0, yyvsp[-1]); + ; + break;} +case 11: +{ + yyval = gmCodeTreeNode::Create(CTNT_DECLARATION, CTNDT_VARIABLE, gmlineno, (int) yyvsp[-2]); + yyval->SetChild(0, yyvsp[-1]); + ; + break;} +case 12: +{ + yyval = gmCodeTreeNode::Create(CTNT_DECLARATION, CTNDT_VARIABLE, gmlineno, (int) yyvsp[-4]); + yyval->SetChild(0, yyvsp[-3]); + ATTACH(yyval, yyval, CreateOperation(CTNOT_ASSIGN, yyvsp[-3], yyvsp[-1])); + ; + break;} +case 13: +{ + yyval = (YYSTYPE) CTVT_LOCAL; + ; + break;} +case 14: +{ + yyval = (YYSTYPE) CTVT_GLOBAL; + ; + break;} +case 15: +{ + yyval = (YYSTYPE) CTVT_MEMBER; + ; + break;} +case 16: +{ + yyval = NULL; + ; + break;} +case 17: +{ + yyval = yyvsp[-1]; + ; + break;} +case 18: +{ + yyval = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_IF, (yyvsp[-2]) ? yyvsp[-2]->m_lineNumber : gmlineno); + yyval->SetChild(0, yyvsp[-2]); + yyval->SetChild(1, yyvsp[0]); + ; + break;} +case 19: +{ + yyval = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_IF, (yyvsp[-4]) ? yyvsp[-4]->m_lineNumber : gmlineno); + yyval->SetChild(0, yyvsp[-4]); + yyval->SetChild(1, yyvsp[-2]); + yyval->SetChild(2, yyvsp[0]); + ; + break;} +case 20: +{ + yyval = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_IF, (yyvsp[-4]) ? yyvsp[-4]->m_lineNumber : gmlineno); + yyval->SetChild(0, yyvsp[-4]); + yyval->SetChild(1, yyvsp[-2]); + yyval->SetChild(2, yyvsp[0]); + ; + break;} +case 21: +{ + yyval = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_WHILE, (yyvsp[-2]) ? yyvsp[-2]->m_lineNumber : gmlineno); + yyval->SetChild(0, yyvsp[-2]); + yyval->SetChild(1, yyvsp[0]); + ; + break;} +case 22: +{ + yyval = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_DOWHILE, (yyvsp[-2]) ? yyvsp[-2]->m_lineNumber : gmlineno); + yyval->SetChild(0, yyvsp[-2]); + yyval->SetChild(1, yyvsp[0]); + ; + break;} +case 23: +{ + yyval = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_FOR, (yyvsp[-3]) ? yyvsp[-3]->m_lineNumber : gmlineno); + yyval->SetChild(0, yyvsp[-3]); + yyval->SetChild(1, yyvsp[-2]); + yyval->SetChild(3, yyvsp[0]); + ; + break;} +case 24: +{ + yyval = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_FOR, (yyvsp[-4]) ? yyvsp[-4]->m_lineNumber : gmlineno); + yyval->SetChild(0, yyvsp[-4]); + yyval->SetChild(1, yyvsp[-3]); + yyval->SetChild(2, yyvsp[-2]); + yyval->SetChild(3, yyvsp[0]); + ; + break;} +case 25: +{ + yyval = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_FOREACH, (yyvsp[-2]) ? yyvsp[-2]->m_lineNumber : gmlineno); + yyval->SetChild(0, yyvsp[-2]); + yyval->SetChild(1, yyvsp[-4]); + yyval->SetChild(3, yyvsp[0]); + ; + break;} +case 26: +{ + yyval = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_FOREACH, (yyvsp[-2]) ? yyvsp[-2]->m_lineNumber : gmlineno); + yyval->SetChild(0, yyvsp[-2]); + yyval->SetChild(1, yyvsp[-4]); + yyval->SetChild(2, yyvsp[-6]); + yyval->SetChild(3, yyvsp[0]); + ; + break;} +case 27: +{ + yyval = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_CONTINUE, gmlineno); + ; + break;} +case 28: +{ + yyval = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_BREAK, gmlineno); + ; + break;} +case 29: +{ + yyval = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_RETURN, gmlineno); + ; + break;} +case 30: +{ + yyval = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_RETURN, gmlineno); + yyval->SetChild(0, yyvsp[-1]); + ; + break;} +case 31: +{ + yyval = yyvsp[0]; + if(yyval) + { + yyval->m_flags |= gmCodeTreeNode::CTN_POP; + } + ; + break;} +case 32: +{ + yyval = CreateOperation(CTNOT_ASSIGN, yyvsp[-2], yyvsp[0]); + ; + break;} +case 33: +{ + yyval = CreateAsignExpression(CTNOT_SHIFT_RIGHT, yyvsp[-2], yyvsp[0]); + ; + break;} +case 34: +{ + yyval = CreateAsignExpression(CTNOT_SHIFT_LEFT, yyvsp[-2], yyvsp[0]); + ; + break;} +case 35: +{ + yyval = CreateAsignExpression(CTNOT_ADD, yyvsp[-2], yyvsp[0]); + ; + break;} +case 36: +{ + yyval = CreateAsignExpression(CTNOT_MINUS, yyvsp[-2], yyvsp[0]); + ; + break;} +case 37: +{ + yyval = CreateAsignExpression(CTNOT_TIMES, yyvsp[-2], yyvsp[0]); + ; + break;} +case 38: +{ + yyval = CreateAsignExpression(CTNOT_DIVIDE, yyvsp[-2], yyvsp[0]); + ; + break;} +case 39: +{ + yyval = CreateAsignExpression(CTNOT_REM, yyvsp[-2], yyvsp[0]); + ; + break;} +case 40: +{ + yyval = CreateAsignExpression(CTNOT_BIT_AND, yyvsp[-2], yyvsp[0]); + ; + break;} +case 41: +{ + yyval = CreateAsignExpression(CTNOT_BIT_OR, yyvsp[-2], yyvsp[0]); + ; + break;} +case 42: +{ + yyval = CreateAsignExpression(CTNOT_BIT_XOR, yyvsp[-2], yyvsp[0]); + ; + break;} +case 43: +{ + yyval = NULL; + ; + break;} +case 44: +{ + yyval = yyvsp[-1]; + ; + break;} +case 45: +{ + yyval = yyvsp[0]; + ; + break;} +case 46: +{ + yyval = yyvsp[0]; + ; + break;} +case 47: +{ + yyval = CreateOperation(CTNOT_OR, yyvsp[-2], yyvsp[0]); + ; + break;} +case 48: +{ + yyval = yyvsp[0]; + ; + break;} +case 49: +{ + yyval = CreateOperation(CTNOT_AND, yyvsp[-2], yyvsp[0]); + ; + break;} +case 50: +{ + yyval = yyvsp[0]; + ; + break;} +case 51: +{ + yyval = CreateOperation(CTNOT_BIT_OR, yyvsp[-2], yyvsp[0]); + yyval->ConstantFold(); + ; + break;} +case 52: +{ + yyval = yyvsp[0]; + ; + break;} +case 53: +{ + yyval = CreateOperation(CTNOT_BIT_XOR, yyvsp[-2], yyvsp[0]); + yyval->ConstantFold(); + ; + break;} +case 54: +{ + yyval = yyvsp[0]; + ; + break;} +case 55: +{ + yyval = CreateOperation(CTNOT_BIT_AND, yyvsp[-2], yyvsp[0]); + yyval->ConstantFold(); + ; + break;} +case 56: +{ + yyval = yyvsp[0]; + ; + break;} +case 57: +{ + yyval = CreateOperation(CTNOT_EQ, yyvsp[-2], yyvsp[0]); + ; + break;} +case 58: +{ + yyval = CreateOperation(CTNOT_NEQ, yyvsp[-2], yyvsp[0]); + ; + break;} +case 59: +{ + yyval = yyvsp[0]; + ; + break;} +case 60: +{ + yyval = CreateOperation(CTNOT_LT, yyvsp[-2], yyvsp[0]); + ; + break;} +case 61: +{ + yyval = CreateOperation(CTNOT_GT, yyvsp[-2], yyvsp[0]); + ; + break;} +case 62: +{ + yyval = CreateOperation(CTNOT_LTE, yyvsp[-2], yyvsp[0]); + ; + break;} +case 63: +{ + yyval = CreateOperation(CTNOT_GTE, yyvsp[-2], yyvsp[0]); + ; + break;} +case 64: +{ + yyval = yyvsp[0]; + ; + break;} +case 65: +{ + yyval = CreateOperation(CTNOT_SHIFT_LEFT, yyvsp[-2], yyvsp[0]); + yyval->ConstantFold(); + ; + break;} +case 66: +{ + yyval = CreateOperation(CTNOT_SHIFT_RIGHT, yyvsp[-2], yyvsp[0]); + yyval->ConstantFold(); + ; + break;} +case 67: +{ + yyval = yyvsp[0]; + ; + break;} +case 68: +{ + yyval = CreateOperation(CTNOT_ADD, yyvsp[-2], yyvsp[0]); + yyval->ConstantFold(); + ; + break;} +case 69: +{ + yyval = CreateOperation(CTNOT_MINUS, yyvsp[-2], yyvsp[0]); + yyval->ConstantFold(); + ; + break;} +case 70: +{ + yyval = yyvsp[0]; + ; + break;} +case 71: +{ + yyval = CreateOperation(CTNOT_TIMES, yyvsp[-2], yyvsp[0]); + yyval->ConstantFold(); + ; + break;} +case 72: +{ + yyval = CreateOperation(CTNOT_DIVIDE, yyvsp[-2], yyvsp[0]); + yyval->ConstantFold(); + ; + break;} +case 73: +{ + yyval = CreateOperation(CTNOT_REM, yyvsp[-2], yyvsp[0]); + yyval->ConstantFold(); + ; + break;} +case 74: +{ + yyval = yyvsp[0]; + ; + break;} +case 75: +{ + yyval = yyvsp[-1]; + yyval->SetChild(0, yyvsp[0]); + yyval->ConstantFold(); + ; + break;} +case 76: +{ + yyval = CreateOperation(CTNOT_UNARY_PLUS); + ; + break;} +case 77: +{ + yyval = CreateOperation(CTNOT_UNARY_MINUS); + ; + break;} +case 78: +{ + yyval = CreateOperation(CTNOT_UNARY_COMPLEMENT); + ; + break;} +case 79: +{ + yyval = CreateOperation(CTNOT_UNARY_NOT); + ; + break;} +case 80: +{ + yyval = yyvsp[0]; + ; + break;} +case 81: +{ + yyval = CreateOperation(CTNOT_ARRAY_INDEX, yyvsp[-3], yyvsp[-1]); + ; + break;} +case 82: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CALL, gmlineno); + yyval->SetChild(0, yyvsp[-2]); + ; + break;} +case 83: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CALL, gmlineno); + yyval->SetChild(0, yyvsp[-3]); + yyval->SetChild(1, yyvsp[-1]); + ; + break;} +case 84: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CALL, gmlineno); + yyval->SetChild(0, yyvsp[-2]); + yyval->SetChild(2, yyvsp[-4]); + ; + break;} +case 85: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CALL, gmlineno); + yyval->SetChild(0, yyvsp[-3]); + yyval->SetChild(1, yyvsp[-1]); + yyval->SetChild(2, yyvsp[-5]); + ; + break;} +case 86: +{ + yyval = CreateOperation(CTNOT_DOT, yyvsp[-2], yyvsp[0]); + ; + break;} +case 87: +{ + yyval = yyvsp[0]; + ; + break;} +case 88: +{ + ATTACH(yyval, yyvsp[-2], yyvsp[0]); + ; + break;} +case 89: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_TABLE, gmlineno); + ; + break;} +case 90: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_TABLE, gmlineno); + yyval->SetChild(0, yyvsp[-1]); + ; + break;} +case 91: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_TABLE, gmlineno); + ; + break;} +case 92: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_TABLE, gmlineno); + yyval->SetChild(0, yyvsp[-1]); + ; + break;} +case 93: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_TABLE, gmlineno); + yyval->SetChild(0, yyvsp[-2]); + ; + break;} +case 94: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_FUNCTION, gmlineno); + yyval->SetChild(0, yyvsp[-2]); + yyval->SetChild(1, yyvsp[0]); + ; + break;} +case 95: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_FUNCTION, gmlineno); + yyval->SetChild(1, yyvsp[0]); + ; + break;} +case 96: +{ + yyval = yyvsp[0]; + ; + break;} +case 97: +{ + ATTACH(yyval, yyvsp[-2], yyvsp[0]); + ; + break;} +case 98: +{ + yyval = yyvsp[0]; + ; + break;} +case 99: +{ + yyval = CreateOperation(CTNOT_ASSIGN_FIELD, yyvsp[-2], yyvsp[0]); + ; + break;} +case 100: +{ + yyval = yyvsp[0]; + ; + break;} +case 101: +{ + ATTACH(yyval, yyvsp[-2], yyvsp[0]); + ; + break;} +case 102: +{ + yyval = gmCodeTreeNode::Create(CTNT_DECLARATION, CTNDT_PARAMETER, gmlineno); + yyval->SetChild(0, yyvsp[0]); + ; + break;} +case 103: +{ + yyval = gmCodeTreeNode::Create(CTNT_DECLARATION, CTNDT_PARAMETER, gmlineno); + yyval->SetChild(0, yyvsp[-2]); + yyval->SetChild(1, yyvsp[0]); + ; + break;} +case 104: +{ + yyval = yyvsp[0]; + ; + break;} +case 105: +{ + yyval = yyvsp[0]; + yyval->m_flags |= gmCodeTreeNode::CTN_MEMBER; + ; + break;} +case 106: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_THIS, gmlineno); + ; + break;} +case 107: +{ + yyval = yyvsp[0]; + ; + break;} +case 108: +{ + yyval = yyvsp[0]; + ; + break;} +case 109: +{ + yyval = yyvsp[0]; + ; + break;} +case 110: +{ + yyval = yyvsp[-1]; + ; + break;} +case 111: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_IDENTIFIER, gmlineno); + yyval->m_data.m_string = (char *) gmCodeTree::Get().Alloc(strlen(gmtext) + 1); + strcpy(yyval->m_data.m_string, gmtext); + ; + break;} +case 112: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CONSTANT, gmlineno, CTNCT_INT); + yyval->m_data.m_iValue = strtoul(gmtext + 2, NULL, 16); + ; + break;} +case 113: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CONSTANT, gmlineno, CTNCT_INT); + yyval->m_data.m_iValue = strtoul(gmtext + 2, NULL, 2); + ; + break;} +case 114: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CONSTANT, gmlineno, CTNCT_INT); + yyval->m_data.m_iValue = atoi(gmtext); + ; + break;} +case 115: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CONSTANT, gmlineno, CTNCT_INT); + yyval->m_data.m_iValue = 1; + ; + break;} +case 116: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CONSTANT, gmlineno, CTNCT_INT); + yyval->m_data.m_iValue = 0; + ; + break;} +case 117: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CONSTANT, gmlineno, CTNCT_INT); + + char * c = (char *) gmCodeTree::Get().Alloc(strlen(gmtext) + 1); + strcpy(c, gmtext); + int result = 0; + int shr = 0; + + while(*c) + { + if(c[0] == '\'') + { + ++c; + continue; + } + else if(c[0] == '\\') + { + if(shr) result <<= 8; + switch(c[1]) + { + case 'a' : result |= (unsigned char) '\a'; break; + case 'b' : result |= (unsigned char) '\b'; break; + case 'f' : result |= (unsigned char) '\f'; break; + case 'n' : result |= (unsigned char) '\n'; break; + case 'r' : result |= (unsigned char) '\r'; break; + case 't' : result |= (unsigned char) '\t'; break; + case 'v' : result |= (unsigned char) '\v'; break; + case '\'' : result |= (unsigned char) '\''; break; + case '\"' : result |= (unsigned char) '\"'; break; + case '\\' : result |= (unsigned char) '\\'; break; + default: result |= (unsigned char) c[1]; + } + ++shr; + c += 2; + continue; + } + if(shr) result <<= 8; + result |= (unsigned char) *(c++); + ++shr; + } + + if(shr > 4 && gmCodeTree::Get().GetLog()) gmCodeTree::Get().GetLog()->LogEntry("truncated char, line %d", gmlineno); + + yyval->m_data.m_iValue = result; + ; + break;} +case 118: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CONSTANT, gmlineno, CTNCT_FLOAT); + yyval->m_data.m_fValue = (float) atof(gmtext); + ; + break;} +case 119: +{ + yyval = yyvsp[0]; + ; + break;} +case 120: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CONSTANT, gmlineno, CTNCT_NULL); + yyval->m_data.m_iValue = 0; + ; + break;} +case 121: +{ + yyval = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CONSTANT, gmlineno, CTNCT_STRING); + yyval->m_data.m_string = (char *) gmCodeTree::Get().Alloc(strlen(gmtext) + 1); + strcpy(yyval->m_data.m_string, gmtext); + if(gmtext[0] == '"') + { + gmProcessDoubleQuoteString(yyval->m_data.m_string); + } + else if(gmtext[0] == '`') + { + gmProcessSingleQuoteString(yyval->m_data.m_string); + } + ; + break;} +case 122: +{ + yyval = yyvsp[-1]; + int alen = strlen(yyval->m_data.m_string); + int blen = strlen(gmtext); + char * str = (char *) gmCodeTree::Get().Alloc(alen + blen + 1); + if(str) + { + memcpy(str, yyvsp[-1]->m_data.m_string, alen); + memcpy(str + alen, gmtext, blen); + str[alen + blen] = '\0'; + if(str[alen] == '"') + { + gmProcessDoubleQuoteString(str + alen); + } + else if(str[alen] == '`') + { + gmProcessSingleQuoteString(str + alen); + } + yyval->m_data.m_string = str; + } + ; + break;} +} + /* the action file gets copied in in place of this dollarsign */ + + + yyvsp -= yylen; + yyssp -= yylen; +#ifdef YYLSP_NEEDED + yylsp -= yylen; +#endif + +#if YYDEBUG != 0 + if (yydebug) + { + short *ssp1 = yyss - 1; + fprintf (stderr, "state stack now"); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif + + *++yyvsp = yyval; + +#ifdef YYLSP_NEEDED + yylsp++; + if (yylen == 0) + { + yylsp->first_line = yylloc.first_line; + yylsp->first_column = yylloc.first_column; + yylsp->last_line = (yylsp-1)->last_line; + yylsp->last_column = (yylsp-1)->last_column; + yylsp->text = 0; + } + else + { + yylsp->last_line = (yylsp+yylen-1)->last_line; + yylsp->last_column = (yylsp+yylen-1)->last_column; + } +#endif + + /* Now "shift" the result of the reduction. + Determine what state that goes to, + based on the state we popped back to + and the rule number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTBASE] + *yyssp; + if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTBASE]; + + goto yynewstate; + +yyerrlab: /* here on detecting error */ + + if (! yyerrstatus) + /* If not already recovering from an error, report this error. */ + { + ++yynerrs; + +#ifdef YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (yyn > YYFLAG && yyn < YYLAST) + { + int size = 0; + char *msg; + int x, count; + + count = 0; + /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ + for (x = (yyn < 0 ? -yyn : 0); + x < (int)(sizeof(yytname) / sizeof(char *)); x++) //_GD_ + if (yycheck[x + yyn] == x) + size += strlen(yytname[x]) + 15, count++; + //_GD_ msg = (char *) malloc(size + 15); + msg = GM_NEW( char [size + 15] ); + if (msg != 0) + { + strcpy(msg, "parse error"); + + if (count < 5) + { + count = 0; + for (x = (yyn < 0 ? -yyn : 0); + x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) + { + strcat(msg, count == 0 ? ", expecting `" : " or `"); + strcat(msg, yytname[x]); + strcat(msg, "'"); + count++; + } + } + yyerror(msg); + //_GD_ free(msg); + delete [] msg; + } + else + yyerror ("parse error; also virtual memory exceeded"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror("parse error"); + } + + goto yyerrlab1; +yyerrlab1: /* here on error raised explicitly by an action */ + + if (yyerrstatus == 3) + { + /* if just tried and failed to reuse lookahead token after an error, discard it. */ + + /* return failure if at end of input */ + if (yychar == YYEOF) + YYABORT; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); +#endif + + yychar = YYEMPTY; + } + + /* Else will try to reuse lookahead token + after shifting the error token. */ + + yyerrstatus = 3; /* Each real token shifted decrements this */ + + goto yyerrhandle; + +yyerrdefault: /* current state does not do anything special for the error token. */ + +#if 0 + /* This is wrong; only states that explicitly want error tokens + should shift them. */ + yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ + if (yyn) goto yydefault; +#endif + +yyerrpop: /* pop the current state because it cannot handle the error token */ + + if (yyssp == yyss) YYABORT; + yyvsp--; + yystate = *--yyssp; +#ifdef YYLSP_NEEDED + yylsp--; +#endif + +#if YYDEBUG != 0 + if (yydebug) + { + short *ssp1 = yyss - 1; + fprintf (stderr, "Error: state stack now"); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif + +yyerrhandle: + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yyerrdefault; + + yyn += YYTERROR; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) + goto yyerrdefault; + + yyn = yytable[yyn]; + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrpop; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrpop; + + if (yyn == YYFINAL) + YYACCEPT; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Shifting error token, "); +#endif + + *++yyvsp = yylval; +#ifdef YYLSP_NEEDED + *++yylsp = yylloc; +#endif + + yystate = yyn; + goto yynewstate; +} + + +#include + + + + + + + + + + + diff --git a/vscript/languages/gm/src/gm/gmParser.cpp.h b/vscript/languages/gm/src/gm/gmParser.cpp.h new file mode 100644 index 00000000..835f40c4 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmParser.cpp.h @@ -0,0 +1,51 @@ +#ifndef YYSTYPE +#define YYSTYPE int +#endif +#define KEYWORD_LOCAL 258 +#define KEYWORD_GLOBAL 259 +#define KEYWORD_MEMBER 260 +#define KEYWORD_AND 261 +#define KEYWORD_OR 262 +#define KEYWORD_IF 263 +#define KEYWORD_ELSE 264 +#define KEYWORD_WHILE 265 +#define KEYWORD_FOR 266 +#define KEYWORD_FOREACH 267 +#define KEYWORD_IN 268 +#define KEYWORD_BREAK 269 +#define KEYWORD_CONTINUE 270 +#define KEYWORD_NULL 271 +#define KEYWORD_DOWHILE 272 +#define KEYWORD_RETURN 273 +#define KEYWORD_FUNCTION 274 +#define KEYWORD_TABLE 275 +#define KEYWORD_THIS 276 +#define KEYWORD_TRUE 277 +#define KEYWORD_FALSE 278 +#define IDENTIFIER 279 +#define CONSTANT_HEX 280 +#define CONSTANT_BINARY 281 +#define CONSTANT_INT 282 +#define CONSTANT_CHAR 283 +#define CONSTANT_FLOAT 284 +#define CONSTANT_STRING 285 +#define SYMBOL_ASGN_BSR 286 +#define SYMBOL_ASGN_BSL 287 +#define SYMBOL_ASGN_ADD 288 +#define SYMBOL_ASGN_MINUS 289 +#define SYMBOL_ASGN_TIMES 290 +#define SYMBOL_ASGN_DIVIDE 291 +#define SYMBOL_ASGN_REM 292 +#define SYMBOL_ASGN_BAND 293 +#define SYMBOL_ASGN_BOR 294 +#define SYMBOL_ASGN_BXOR 295 +#define SYMBOL_RIGHT_SHIFT 296 +#define SYMBOL_LEFT_SHIFT 297 +#define SYMBOL_LTE 298 +#define SYMBOL_GTE 299 +#define SYMBOL_EQ 300 +#define SYMBOL_NEQ 301 +#define TOKEN_ERROR 302 + + +extern YYSTYPE gmlval; diff --git a/vscript/languages/gm/src/gm/gmParser.y b/vscript/languages/gm/src/gm/gmParser.y new file mode 100644 index 00000000..e3dd1315 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmParser.y @@ -0,0 +1,877 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +%{ + +#define YYPARSER +#include "gmConfig.h" +#include "gmCodeTree.h" +#define YYSTYPE gmCodeTreeNode * + +extern gmCodeTreeNode * g_codeTree; + +#define GM_BISON_DEBUG +#ifdef GM_BISON_DEBUG +#define YYDEBUG 1 +#define YYERROR_VERBOSE +#endif // GM_BISON_DEBUG + +// +// HELPERS +// + +void ATTACH(gmCodeTreeNode * &a_res, gmCodeTreeNode * a_a, gmCodeTreeNode * a_b) +{ + YYSTYPE t = a_a; + if(t != NULL) + { + while(t->m_sibling != NULL) + { + t = t->m_sibling; + } + t->m_sibling = a_b; + if(a_b) { a_b->m_parent = t; } + a_res = a_a; + } + else + { + a_res = a_b; + } +} + +gmCodeTreeNode * CreateOperation(int a_subTypeType, gmCodeTreeNode * a_left = NULL, gmCodeTreeNode * a_right = NULL) +{ + gmCodeTreeNode * node = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_OPERATION, gmlineno, a_subTypeType); + node->SetChild(0, a_left); + node->SetChild(1, a_right); + return node; +} + +gmCodeTreeNode * CreateAsignExpression(int a_subTypeType, gmCodeTreeNode * a_left, gmCodeTreeNode * a_right) +{ + // we need to evaluate the complexety of the l-value... if it is a function call, index or dot to the left of a dot or index, we need to cache + // into a hidden variable. + + // todo + + gmCodeTreeNode * opNode = CreateOperation(a_subTypeType, a_left, a_right); + return CreateOperation(CTNOT_ASSIGN, a_left, opNode); +} + +%} + +%token KEYWORD_LOCAL +%token KEYWORD_GLOBAL +%token KEYWORD_MEMBER +%token KEYWORD_AND +%token KEYWORD_OR +%token KEYWORD_IF +%token KEYWORD_ELSE +%token KEYWORD_WHILE +%token KEYWORD_FOR +%token KEYWORD_FOREACH +%token KEYWORD_IN +%token KEYWORD_BREAK +%token KEYWORD_CONTINUE +%token KEYWORD_NULL +%token KEYWORD_DOWHILE +%token KEYWORD_RETURN +%token KEYWORD_FUNCTION +%token KEYWORD_TABLE +%token KEYWORD_THIS +%token KEYWORD_TRUE +%token KEYWORD_FALSE +%token IDENTIFIER +%token CONSTANT_HEX +%token CONSTANT_BINARY +%token CONSTANT_INT +%token CONSTANT_CHAR +%token CONSTANT_FLOAT +%token CONSTANT_FLOAT +%token CONSTANT_STRING +%token SYMBOL_ASGN_BSR +%token SYMBOL_ASGN_BSL +%token SYMBOL_ASGN_ADD +%token SYMBOL_ASGN_MINUS +%token SYMBOL_ASGN_TIMES +%token SYMBOL_ASGN_DIVIDE +%token SYMBOL_ASGN_REM +%token SYMBOL_ASGN_BAND +%token SYMBOL_ASGN_BOR +%token SYMBOL_ASGN_BXOR +%token SYMBOL_RIGHT_SHIFT +%token SYMBOL_LEFT_SHIFT +%token SYMBOL_LTE +%token SYMBOL_GTE +%token SYMBOL_EQ +%token SYMBOL_NEQ +%token TOKEN_ERROR + +%start program +%% + +program + : statement_list + { + g_codeTree = $1; + } + ; + +statement_list + : statement + { + $$ = $1; + } + | statement_list statement + { + ATTACH($$, $1, $2); + } + ; + +statement + : expression_statement + { + $$ = $1; + } + | var_statement + { + $$ = $1; + } + | selection_statement + { + $$ = $1; + } + | iteration_statement + { + $$ = $1; + } + | jump_statement + { + $$ = $1; + } + ; + +compound_statement + : '{' '}' + { + $$ = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_COMPOUND, gmlineno); + } + | '{' statement_list '}' + { + $$ = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_COMPOUND, gmlineno); + $$->SetChild(0, $2); + } + ; + +var_statement + : var_type identifier ';' + { + $$ = gmCodeTreeNode::Create(CTNT_DECLARATION, CTNDT_VARIABLE, gmlineno, (int) $1); + $$->SetChild(0, $2); + } + | var_type identifier '=' constant_expression ';' + { + $$ = gmCodeTreeNode::Create(CTNT_DECLARATION, CTNDT_VARIABLE, gmlineno, (int) $1); + $$->SetChild(0, $2); + ATTACH($$, $$, CreateOperation(CTNOT_ASSIGN, $2, $4)); + } + ; + +var_type + : KEYWORD_LOCAL + { + $$ = (YYSTYPE) CTVT_LOCAL; + } + | KEYWORD_GLOBAL + { + $$ = (YYSTYPE) CTVT_GLOBAL; + } + | KEYWORD_MEMBER + { + $$ = (YYSTYPE) CTVT_MEMBER; + } + ; +expression_statement + : ';' + { + $$ = NULL; + } + | assignment_expression ';' + { + $$ = $1; + } + ; + +selection_statement + : KEYWORD_IF '(' constant_expression ')' compound_statement + { + $$ = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_IF, ($3) ? $3->m_lineNumber : gmlineno); + $$->SetChild(0, $3); + $$->SetChild(1, $5); + } + | KEYWORD_IF '(' constant_expression ')' compound_statement KEYWORD_ELSE compound_statement + { + $$ = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_IF, ($3) ? $3->m_lineNumber : gmlineno); + $$->SetChild(0, $3); + $$->SetChild(1, $5); + $$->SetChild(2, $7); + } + | KEYWORD_IF '(' constant_expression ')' compound_statement KEYWORD_ELSE selection_statement + { + $$ = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_IF, ($3) ? $3->m_lineNumber : gmlineno); + $$->SetChild(0, $3); + $$->SetChild(1, $5); + $$->SetChild(2, $7); + } + ; + +iteration_statement + : KEYWORD_WHILE '(' constant_expression ')' compound_statement + { + $$ = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_WHILE, ($3) ? $3->m_lineNumber : gmlineno); + $$->SetChild(0, $3); + $$->SetChild(1, $5); + } + | KEYWORD_DOWHILE '(' constant_expression ')' compound_statement + { + $$ = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_DOWHILE, ($3) ? $3->m_lineNumber : gmlineno); + $$->SetChild(0, $3); + $$->SetChild(1, $5); + } + | KEYWORD_FOR '(' expression_statement constant_expression_statement ')' compound_statement + { + $$ = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_FOR, ($3) ? $3->m_lineNumber : gmlineno); + $$->SetChild(0, $3); + $$->SetChild(1, $4); + $$->SetChild(3, $6); + } + | KEYWORD_FOR '(' expression_statement constant_expression_statement assignment_expression ')' compound_statement + { + $$ = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_FOR, ($3) ? $3->m_lineNumber : gmlineno); + $$->SetChild(0, $3); + $$->SetChild(1, $4); + $$->SetChild(2, $5); + $$->SetChild(3, $7); + } + | KEYWORD_FOREACH '(' identifier KEYWORD_IN constant_expression ')' compound_statement + { + $$ = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_FOREACH, ($5) ? $5->m_lineNumber : gmlineno); + $$->SetChild(0, $5); + $$->SetChild(1, $3); + $$->SetChild(3, $7); + } + | KEYWORD_FOREACH '(' identifier KEYWORD_AND identifier KEYWORD_IN constant_expression')' compound_statement + { + $$ = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_FOREACH, ($7) ? $7->m_lineNumber : gmlineno); + $$->SetChild(0, $7); + $$->SetChild(1, $5); + $$->SetChild(2, $3); + $$->SetChild(3, $9); + } + ; + +jump_statement + : KEYWORD_CONTINUE ';' + { + $$ = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_CONTINUE, gmlineno); + } + | KEYWORD_BREAK ';' + { + $$ = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_BREAK, gmlineno); + } + | KEYWORD_RETURN ';' + { + $$ = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_RETURN, gmlineno); + } + | KEYWORD_RETURN constant_expression ';' + { + $$ = gmCodeTreeNode::Create(CTNT_STATEMENT, CTNST_RETURN, gmlineno); + $$->SetChild(0, $2); + } + ; + +assignment_expression + : logical_or_expression + { + $$ = $1; + if($$) + { + $$->m_flags |= gmCodeTreeNode::CTN_POP; + } + } + | postfix_expression '=' logical_or_expression + { + $$ = CreateOperation(CTNOT_ASSIGN, $1, $3); + } + | postfix_expression SYMBOL_ASGN_BSR logical_or_expression + { + $$ = CreateAsignExpression(CTNOT_SHIFT_RIGHT, $1, $3); + } + | postfix_expression SYMBOL_ASGN_BSL logical_or_expression + { + $$ = CreateAsignExpression(CTNOT_SHIFT_LEFT, $1, $3); + } + | postfix_expression SYMBOL_ASGN_ADD logical_or_expression + { + $$ = CreateAsignExpression(CTNOT_ADD, $1, $3); + } + | postfix_expression SYMBOL_ASGN_MINUS logical_or_expression + { + $$ = CreateAsignExpression(CTNOT_MINUS, $1, $3); + } + | postfix_expression SYMBOL_ASGN_TIMES logical_or_expression + { + $$ = CreateAsignExpression(CTNOT_TIMES, $1, $3); + } + | postfix_expression SYMBOL_ASGN_DIVIDE logical_or_expression + { + $$ = CreateAsignExpression(CTNOT_DIVIDE, $1, $3); + } + | postfix_expression SYMBOL_ASGN_REM logical_or_expression + { + $$ = CreateAsignExpression(CTNOT_REM, $1, $3); + } + | postfix_expression SYMBOL_ASGN_BAND logical_or_expression + { + $$ = CreateAsignExpression(CTNOT_BIT_AND, $1, $3); + } + | postfix_expression SYMBOL_ASGN_BOR logical_or_expression + { + $$ = CreateAsignExpression(CTNOT_BIT_OR, $1, $3); + } + | postfix_expression SYMBOL_ASGN_BXOR logical_or_expression + { + $$ = CreateAsignExpression(CTNOT_BIT_XOR, $1, $3); + } + ; + + +constant_expression_statement + : ';' + { + $$ = NULL; + } + | constant_expression ';' + { + $$ = $1; + } + ; + +constant_expression + : logical_or_expression + { + $$ = $1; + } + ; + +logical_or_expression + : logical_and_expression + { + $$ = $1; + } + | logical_or_expression KEYWORD_OR logical_and_expression + { + $$ = CreateOperation(CTNOT_OR, $1, $3); + } + ; + +logical_and_expression + : inclusive_or_expression + { + $$ = $1; + } + | logical_and_expression KEYWORD_AND inclusive_or_expression + { + $$ = CreateOperation(CTNOT_AND, $1, $3); + } + ; + +inclusive_or_expression + : exclusive_or_expression + { + $$ = $1; + } + | inclusive_or_expression '|' exclusive_or_expression + { + $$ = CreateOperation(CTNOT_BIT_OR, $1, $3); + $$->ConstantFold(); + } + ; + +exclusive_or_expression + : and_expression + { + $$ = $1; + } + | exclusive_or_expression '^' and_expression + { + $$ = CreateOperation(CTNOT_BIT_XOR, $1, $3); + $$->ConstantFold(); + } + ; + +and_expression + : equality_expression + { + $$ = $1; + } + | and_expression '&' equality_expression + { + $$ = CreateOperation(CTNOT_BIT_AND, $1, $3); + $$->ConstantFold(); + } + ; + +equality_expression + : relational_expression + { + $$ = $1; + } + | equality_expression SYMBOL_EQ relational_expression + { + $$ = CreateOperation(CTNOT_EQ, $1, $3); + } + | equality_expression SYMBOL_NEQ relational_expression + { + $$ = CreateOperation(CTNOT_NEQ, $1, $3); + } + ; + +relational_expression + : shift_expression + { + $$ = $1; + } + | relational_expression '<' shift_expression + { + $$ = CreateOperation(CTNOT_LT, $1, $3); + } + | relational_expression '>' shift_expression + { + $$ = CreateOperation(CTNOT_GT, $1, $3); + } + | relational_expression SYMBOL_LTE shift_expression + { + $$ = CreateOperation(CTNOT_LTE, $1, $3); + } + | relational_expression SYMBOL_GTE shift_expression + { + $$ = CreateOperation(CTNOT_GTE, $1, $3); + } + ; + +shift_expression + : additive_expression + { + $$ = $1; + } + | shift_expression SYMBOL_LEFT_SHIFT additive_expression + { + $$ = CreateOperation(CTNOT_SHIFT_LEFT, $1, $3); + $$->ConstantFold(); + } + | shift_expression SYMBOL_RIGHT_SHIFT additive_expression + { + $$ = CreateOperation(CTNOT_SHIFT_RIGHT, $1, $3); + $$->ConstantFold(); + } + ; + +additive_expression + : multiplicative_expression + { + $$ = $1; + } + | additive_expression '+' multiplicative_expression + { + $$ = CreateOperation(CTNOT_ADD, $1, $3); + $$->ConstantFold(); + } + | additive_expression '-' multiplicative_expression + { + $$ = CreateOperation(CTNOT_MINUS, $1, $3); + $$->ConstantFold(); + } + ; + +multiplicative_expression + : unary_expression + { + $$ = $1; + } + | multiplicative_expression '*' unary_expression + { + $$ = CreateOperation(CTNOT_TIMES, $1, $3); + $$->ConstantFold(); + } + | multiplicative_expression '/' unary_expression + { + $$ = CreateOperation(CTNOT_DIVIDE, $1, $3); + $$->ConstantFold(); + } + | multiplicative_expression '%' unary_expression + { + $$ = CreateOperation(CTNOT_REM, $1, $3); + $$->ConstantFold(); + } + ; + +unary_expression + : postfix_expression + { + $$ = $1; + } + | unary_operator unary_expression + { + $$ = $1; + $$->SetChild(0, $2); + $$->ConstantFold(); + } + ; + +unary_operator + : '+' + { + $$ = CreateOperation(CTNOT_UNARY_PLUS); + } + | '-' + { + $$ = CreateOperation(CTNOT_UNARY_MINUS); + } + | '~' + { + $$ = CreateOperation(CTNOT_UNARY_COMPLEMENT); + } + | '!' + { + $$ = CreateOperation(CTNOT_UNARY_NOT); + } + ; + +postfix_expression + : primary_expression + { + $$ = $1; + } + | postfix_expression '[' constant_expression ']' + { + $$ = CreateOperation(CTNOT_ARRAY_INDEX, $1, $3); + } + | postfix_expression '(' ')' + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CALL, gmlineno); + $$->SetChild(0, $1); + } + | postfix_expression '(' argument_expression_list ')' + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CALL, gmlineno); + $$->SetChild(0, $1); + $$->SetChild(1, $3); + } + | postfix_expression ':' identifier '(' ')' + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CALL, gmlineno); + $$->SetChild(0, $3); + $$->SetChild(2, $1); + } + | postfix_expression ':' identifier '(' argument_expression_list ')' + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CALL, gmlineno); + $$->SetChild(0, $3); + $$->SetChild(1, $5); + $$->SetChild(2, $1); + } + | postfix_expression '.' identifier + { + $$ = CreateOperation(CTNOT_DOT, $1, $3); + } + ; + +argument_expression_list + : constant_expression + { + $$ = $1; + } + | argument_expression_list ',' constant_expression + { + ATTACH($$, $1, $3); + } + ; + +table_constructor + : KEYWORD_TABLE '(' ')' + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_TABLE, gmlineno); + } + | KEYWORD_TABLE '(' field_list ')' + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_TABLE, gmlineno); + $$->SetChild(0, $3); + } + | '{' '}' + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_TABLE, gmlineno); + } + | '{' field_list '}' + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_TABLE, gmlineno); + $$->SetChild(0, $2); + } + | '{' field_list ',' '}' + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_TABLE, gmlineno); + $$->SetChild(0, $2); + } + ; + +function_constructor + : KEYWORD_FUNCTION '(' parameter_list ')' compound_statement + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_FUNCTION, gmlineno); + $$->SetChild(0, $3); + $$->SetChild(1, $5); + } + | KEYWORD_FUNCTION '(' ')' compound_statement + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_FUNCTION, gmlineno); + $$->SetChild(1, $4); + } + ; + +field_list + : field + { + $$ = $1; + } + | field_list ',' field + { + ATTACH($$, $1, $3); + } + ; + +field + : constant_expression + { + $$ = $1; + } + | identifier '=' constant_expression + { + $$ = CreateOperation(CTNOT_ASSIGN_FIELD, $1, $3); + } + ; + +parameter_list + : parameter + { + $$ = $1; + } + | parameter_list ',' parameter + { + ATTACH($$, $1, $3); + } + ; + +parameter + : identifier + { + $$ = gmCodeTreeNode::Create(CTNT_DECLARATION, CTNDT_PARAMETER, gmlineno); + $$->SetChild(0, $1); + } + | identifier '=' constant_expression + { + $$ = gmCodeTreeNode::Create(CTNT_DECLARATION, CTNDT_PARAMETER, gmlineno); + $$->SetChild(0, $1); + $$->SetChild(1, $3); + } + ; + +primary_expression + : identifier + { + $$ = $1; + } + | '.' identifier + { + $$ = $2; + $$->m_flags |= gmCodeTreeNode::CTN_MEMBER; + } + | KEYWORD_THIS + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_THIS, gmlineno); + } + | constant + { + $$ = $1; + } + | table_constructor + { + $$ = $1; + } + | function_constructor + { + $$ = $1; + } + | '(' constant_expression ')' + { + $$ = $2; + } + ; + +identifier + : IDENTIFIER + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_IDENTIFIER, gmlineno); + $$->m_data.m_string = (char *) gmCodeTree::Get().Alloc(strlen(gmtext) + 1); + strcpy($$->m_data.m_string, gmtext); + } + ; + +constant + : CONSTANT_HEX + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CONSTANT, gmlineno, CTNCT_INT); + $$->m_data.m_iValue = strtoul(gmtext + 2, NULL, 16); + } + | CONSTANT_BINARY + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CONSTANT, gmlineno, CTNCT_INT); + $$->m_data.m_iValue = strtoul(gmtext + 2, NULL, 2); + } + | CONSTANT_INT + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CONSTANT, gmlineno, CTNCT_INT); + $$->m_data.m_iValue = atoi(gmtext); + } + | KEYWORD_TRUE + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CONSTANT, gmlineno, CTNCT_INT); + $$->m_data.m_iValue = 1; + } + | KEYWORD_FALSE + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CONSTANT, gmlineno, CTNCT_INT); + $$->m_data.m_iValue = 0; + } + | CONSTANT_CHAR + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CONSTANT, gmlineno, CTNCT_INT); + + char * c = (char *) gmCodeTree::Get().Alloc(strlen(gmtext) + 1); + strcpy(c, gmtext); + int result = 0; + int shr = 0; + + while(*c) + { + if(c[0] == '\'') + { + ++c; + continue; + } + else if(c[0] == '\\') + { + if(shr) result <<= 8; + switch(c[1]) + { + case 'a' : result |= (unsigned char) '\a'; break; + case 'b' : result |= (unsigned char) '\b'; break; + case 'f' : result |= (unsigned char) '\f'; break; + case 'n' : result |= (unsigned char) '\n'; break; + case 'r' : result |= (unsigned char) '\r'; break; + case 't' : result |= (unsigned char) '\t'; break; + case 'v' : result |= (unsigned char) '\v'; break; + case '\'' : result |= (unsigned char) '\''; break; + case '\"' : result |= (unsigned char) '\"'; break; + case '\\' : result |= (unsigned char) '\\'; break; + default: result |= (unsigned char) c[1]; + } + ++shr; + c += 2; + continue; + } + if(shr) result <<= 8; + result |= (unsigned char) *(c++); + ++shr; + } + + if(shr > 4 && gmCodeTree::Get().GetLog()) gmCodeTree::Get().GetLog()->LogEntry("truncated char, line %d", gmlineno); + + $$->m_data.m_iValue = result; + } + | CONSTANT_FLOAT + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CONSTANT, gmlineno, CTNCT_FLOAT); + $$->m_data.m_fValue = (float) atof(gmtext); + } + | constant_string_list + { + $$ = $1; + } + | KEYWORD_NULL + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CONSTANT, gmlineno, CTNCT_NULL); + $$->m_data.m_iValue = 0; + } + ; + +constant_string_list + : CONSTANT_STRING + { + $$ = gmCodeTreeNode::Create(CTNT_EXPRESSION, CTNET_CONSTANT, gmlineno, CTNCT_STRING); + $$->m_data.m_string = (char *) gmCodeTree::Get().Alloc(strlen(gmtext) + 1); + strcpy($$->m_data.m_string, gmtext); + if(gmtext[0] == '"') + { + gmProcessDoubleQuoteString($$->m_data.m_string); + } + else if(gmtext[0] == '`') + { + gmProcessSingleQuoteString($$->m_data.m_string); + } + } + | constant_string_list CONSTANT_STRING + { + $$ = $1; + int alen = strlen($$->m_data.m_string); + int blen = strlen(gmtext); + char * str = (char *) gmCodeTree::Get().Alloc(alen + blen + 1); + if(str) + { + memcpy(str, $1->m_data.m_string, alen); + memcpy(str + alen, gmtext, blen); + str[alen + blen] = '\0'; + if(str[alen] == '"') + { + gmProcessDoubleQuoteString(str + alen); + } + else if(str[alen] == '`') + { + gmProcessSingleQuoteString(str + alen); + } + $$->m_data.m_string = str; + } + } + ; + +%% + +#include + + + + + + + + + + + diff --git a/vscript/languages/gm/src/gm/gmScanner.cpp b/vscript/languages/gm/src/gm/gmScanner.cpp new file mode 100644 index 00000000..2aff0eef --- /dev/null +++ b/vscript/languages/gm/src/gm/gmScanner.cpp @@ -0,0 +1,2089 @@ +#define yy_create_buffer gm_create_buffer +#define yy_delete_buffer gm_delete_buffer +#define yy_scan_buffer gm_scan_buffer +#define yy_scan_string gm_scan_string +#define yy_scan_bytes gm_scan_bytes +#define yy_flex_debug gm_flex_debug +#define yy_init_buffer gm_init_buffer +#define yy_flush_buffer gm_flush_buffer +#define yy_load_buffer_state gm_load_buffer_state +#define yy_switch_to_buffer gm_switch_to_buffer +#define yyin gmin +#define yyleng gmleng +#define yylex gmlex +#define yyout gmout +#define yyrestart gmrestart +#define yytext gmtext +#define yylineno gmlineno +#define yywrap gmwrap + +#line 21 "gmScanner.cpp" +/* A lexical scanner generated by flex */ + +/* Scanner skeleton version: + * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.85 95/04/24 10:48:47 vern Exp $ + */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_NEVER_INTERACTIVE 1 + +#include +#include + + +#ifdef __cplusplus + +#include + +/* Use prototypes in function declarations. */ +#define YY_USE_PROTOS + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_PROTOS +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef __TURBOC__ + #pragma warn -rch + #pragma warn -use +#include +#include +#define YY_USE_CONST +#define YY_USE_PROTOS +#endif + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + + +#ifdef YY_USE_PROTOS +#define YY_PROTO(proto) proto +#else +#define YY_PROTO(proto) () +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#define YY_BUF_SIZE 16384 + +typedef struct yy_buffer_state *YY_BUFFER_STATE; + +extern int yyleng; +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +/* The funky do-while in the following #define is used to turn the definition + * int a single C statement (which needs a semi-colon terminator). This + * avoids problems with code like: + * + * if ( condition_holds ) + * yyless( 5 ); + * else + * do_something_else(); + * + * Prior to using the do-while the compiler would get upset at the + * "else" because it interpreted the "if" statement as being all + * done when it reached the ';' after the yyless() call. + */ + +/* Return all but the first 'n' matched characters back to the input stream. */ + +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yytext_ptr ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ +typedef unsigned int yy_size_t; + + +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + }; + +static YY_BUFFER_STATE yy_current_buffer = 0; + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + */ +#define YY_CURRENT_BUFFER yy_current_buffer + + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; + +static int yy_n_chars; /* number of characters read into yy_ch_buf */ + + +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart YY_PROTO(( FILE *input_file )); + +void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); +void yy_load_buffer_state YY_PROTO(( void )); +YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); +void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); +void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); +void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); +#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) + +YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); +YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *str )); +YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); + +static void *yy_flex_alloc YY_PROTO(( yy_size_t )); +static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); +static void yy_flex_free YY_PROTO(( void * )); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) + + +#define YY_USES_REJECT +typedef unsigned char YY_CHAR; +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; +typedef int yy_state_type; +extern int yylineno; +int yylineno = 1; +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state YY_PROTO(( void )); +static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); +static int yy_get_next_buffer YY_PROTO(( void )); +static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yytext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 78 +#define YY_END_OF_BUFFER 79 +static yyconst short int yy_acclist[280] = + { 0, + 79, 77, 78, 76, 77, 78, 76, 78, 62, 77, + 78, 77, 78, 67, 77, 78, 70, 77, 78, 77, + 78, 57, 77, 78, 58, 77, 78, 65, 77, 78, + 64, 77, 78, 55, 77, 78, 63, 77, 78, 61, + 77, 78, 66, 77, 78, 27, 77, 78, 27, 77, + 78, 74, 75, 77, 78, 52, 77, 78, 68, 77, + 78, 56, 77, 78, 69, 77, 78, 24, 77, 78, + 59, 77, 78, 60, 77, 78, 72, 77, 78, 77, + 78, 24, 77, 78, 24, 77, 78, 24, 77, 78, + 24, 77, 78, 24, 77, 78, 24, 77, 78, 24, + + 77, 78, 24, 77, 78, 24, 77, 78, 24, 77, + 78, 24, 77, 78, 24, 77, 78, 24, 77, 78, + 24, 77, 78, 24, 77, 78, 53, 77, 78, 71, + 77, 78, 54, 77, 78, 73, 77, 78, 51, 32, + 42, 34, 43, 40, 38, 39, 30, 1, 2, 41, + 31, 27, 47, 48, 50, 49, 46, 24, 45, 33, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 8, + 24, 13, 24, 24, 24, 24, 7, 24, 24, 24, + 24, 24, 24, 44, 35, 28, 30, 2, 30, 31, + 31, 26, 29, 25, 37, 36, 6, 24, 24, 24, + + 24, 24, 24, 11, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 30, 30, 31, 31, 29, + 24, 24, 24, 9, 24, 24, 24, 24, 24, 24, + 24, 17, 24, 24, 24, 21, 24, 22, 24, 24, + 30, 31, 15, 24, 24, 24, 23, 24, 24, 24, + 24, 3, 24, 24, 24, 20, 24, 10, 24, 24, + 24, 24, 24, 4, 24, 5, 24, 18, 24, 24, + 14, 24, 12, 24, 24, 16, 24, 19, 24 + } ; + +static yyconst short int yy_accept[185] = + { 0, + 1, 1, 1, 2, 4, 7, 9, 12, 14, 17, + 20, 22, 25, 28, 31, 34, 37, 40, 43, 46, + 49, 52, 56, 59, 62, 65, 68, 71, 74, 77, + 80, 82, 85, 88, 91, 94, 97, 100, 103, 106, + 109, 112, 115, 118, 121, 124, 127, 130, 133, 136, + 139, 140, 140, 141, 141, 142, 143, 144, 144, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 153, + 153, 153, 154, 155, 156, 157, 158, 159, 160, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 172, 174, 175, 176, 177, 179, 180, 181, 182, 183, + + 184, 185, 186, 187, 187, 188, 189, 191, 191, 192, + 193, 193, 194, 195, 196, 197, 199, 200, 201, 202, + 203, 204, 206, 207, 208, 209, 210, 211, 212, 213, + 214, 215, 216, 216, 217, 217, 219, 219, 220, 221, + 222, 223, 224, 226, 227, 228, 229, 230, 231, 232, + 234, 235, 236, 238, 240, 241, 241, 243, 245, 246, + 247, 249, 250, 251, 252, 254, 255, 256, 258, 260, + 261, 262, 263, 264, 266, 268, 270, 271, 273, 275, + 276, 278, 280, 280 + } ; + +static yyconst int yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 4, 5, 1, 1, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 19, 19, 19, 19, 19, 19, 19, 20, 21, 22, + 23, 24, 1, 1, 25, 26, 25, 25, 27, 28, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 30, 29, 29, + 31, 32, 33, 34, 29, 35, 36, 37, 38, 39, + + 40, 41, 42, 43, 44, 29, 45, 46, 47, 48, + 49, 29, 29, 50, 51, 52, 53, 29, 54, 30, + 29, 29, 55, 56, 57, 58, 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, 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 + } ; + +static yyconst int yy_meta[59] = + { 0, + 1, 1, 2, 1, 1, 1, 1, 3, 1, 1, + 1, 1, 1, 1, 1, 1, 4, 4, 4, 1, + 1, 1, 1, 1, 4, 4, 4, 4, 5, 5, + 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, + 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 1, 1, 1, 1 + } ; + +static yyconst short int yy_base[190] = + { 0, + 0, 0, 292, 293, 293, 293, 268, 54, 267, 53, + 257, 293, 293, 265, 264, 293, 263, 44, 54, 72, + 54, 293, 293, 44, 262, 51, 0, 293, 293, 261, + 248, 234, 231, 231, 230, 232, 43, 231, 37, 227, + 235, 221, 223, 232, 57, 228, 293, 41, 293, 293, + 293, 63, 293, 267, 293, 293, 293, 72, 80, 293, + 293, 293, 96, 293, 0, 293, 99, 114, 88, 130, + 0, 246, 293, 293, 293, 245, 0, 293, 232, 231, + 226, 224, 215, 208, 210, 214, 209, 210, 208, 0, + 0, 218, 208, 205, 0, 188, 194, 186, 176, 184, + + 293, 293, 293, 138, 293, 0, 141, 153, 293, 93, + 102, 145, 0, 293, 293, 0, 191, 174, 182, 184, + 172, 182, 183, 181, 181, 179, 169, 161, 167, 161, + 171, 160, 157, 160, 173, 293, 176, 179, 293, 160, + 156, 155, 0, 149, 148, 131, 144, 120, 121, 0, + 103, 111, 0, 0, 106, 185, 191, 0, 97, 97, + 0, 100, 91, 88, 0, 80, 80, 0, 0, 72, + 82, 65, 54, 0, 0, 0, 61, 0, 0, 36, + 0, 0, 293, 232, 237, 239, 244, 249, 78 + } ; + +static yyconst short int yy_def[190] = + { 0, + 183, 1, 183, 183, 183, 183, 183, 184, 183, 183, + 185, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 186, 183, 183, 183, + 187, 186, 186, 186, 186, 186, 186, 186, 186, 186, + 186, 186, 186, 186, 186, 186, 183, 183, 183, 183, + 183, 184, 183, 184, 183, 183, 183, 185, 185, 183, + 183, 183, 183, 183, 188, 183, 183, 183, 183, 183, + 189, 183, 183, 183, 183, 183, 186, 183, 187, 183, + 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + + 183, 183, 183, 183, 183, 188, 183, 183, 183, 183, + 183, 183, 189, 183, 183, 186, 186, 186, 186, 186, + 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + 186, 186, 183, 183, 183, 183, 183, 183, 183, 186, + 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + 186, 186, 186, 186, 186, 183, 183, 186, 186, 186, + 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + 186, 186, 0, 183, 183, 183, 183, 183, 183 + } ; + +static yyconst short int yy_nxt[352] = + { 0, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 21, 22, + 23, 24, 25, 26, 27, 27, 27, 27, 27, 27, + 28, 4, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 27, 39, 27, 40, 41, 42, 43, 44, + 27, 45, 27, 46, 47, 48, 49, 50, 53, 56, + 63, 63, 63, 101, 64, 72, 73, 53, 67, 65, + 68, 68, 68, 75, 76, 57, 66, 90, 86, 103, + 70, 113, 183, 182, 91, 54, 67, 58, 68, 68, + 68, 87, 97, 70, 54, 88, 102, 69, 70, 98, + + 181, 71, 180, 59, 110, 110, 99, 179, 69, 110, + 110, 70, 63, 63, 63, 107, 107, 107, 112, 112, + 112, 178, 104, 105, 177, 108, 109, 176, 67, 175, + 68, 68, 68, 174, 173, 104, 105, 172, 108, 109, + 70, 111, 171, 111, 170, 169, 112, 112, 112, 133, + 168, 133, 167, 70, 134, 134, 134, 107, 107, 107, + 166, 112, 112, 112, 137, 165, 137, 135, 136, 138, + 138, 138, 139, 134, 134, 134, 134, 134, 134, 164, + 135, 136, 163, 162, 156, 139, 156, 105, 161, 157, + 157, 157, 138, 138, 138, 138, 138, 138, 160, 159, + + 105, 157, 157, 157, 158, 155, 109, 157, 157, 157, + 154, 153, 152, 151, 150, 149, 148, 147, 136, 109, + 146, 145, 144, 143, 142, 141, 140, 132, 131, 130, + 129, 136, 52, 52, 52, 52, 52, 58, 58, 128, + 58, 58, 77, 77, 79, 79, 79, 79, 79, 106, + 127, 106, 106, 106, 126, 125, 124, 123, 122, 121, + 120, 119, 118, 117, 116, 79, 80, 115, 114, 183, + 100, 96, 95, 94, 93, 92, 89, 85, 84, 83, + 82, 81, 80, 78, 74, 62, 61, 60, 59, 55, + 51, 183, 3, 183, 183, 183, 183, 183, 183, 183, + + 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183 + } ; + +static yyconst short int yy_chk[352] = + { 0, + 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, 8, 10, + 18, 18, 18, 48, 19, 24, 24, 52, 21, 19, + 21, 21, 21, 26, 26, 10, 19, 39, 37, 58, + 21, 189, 59, 180, 39, 8, 20, 59, 20, 20, + 20, 37, 45, 21, 52, 37, 48, 20, 20, 45, + + 177, 20, 173, 58, 69, 69, 45, 172, 20, 110, + 110, 20, 63, 63, 63, 67, 67, 67, 111, 111, + 111, 171, 63, 63, 170, 67, 67, 167, 68, 166, + 68, 68, 68, 164, 163, 63, 63, 162, 67, 67, + 68, 70, 160, 70, 159, 155, 70, 70, 70, 104, + 152, 104, 151, 68, 104, 104, 104, 107, 107, 107, + 149, 112, 112, 112, 108, 148, 108, 107, 107, 108, + 108, 108, 112, 133, 133, 133, 134, 134, 134, 147, + 107, 107, 146, 145, 135, 112, 135, 134, 144, 135, + 135, 135, 137, 137, 137, 138, 138, 138, 142, 141, + + 134, 156, 156, 156, 140, 132, 138, 157, 157, 157, + 131, 130, 129, 128, 127, 126, 125, 124, 157, 138, + 123, 122, 121, 120, 119, 118, 117, 100, 99, 98, + 97, 157, 184, 184, 184, 184, 184, 185, 185, 96, + 185, 185, 186, 186, 187, 187, 187, 187, 187, 188, + 94, 188, 188, 188, 93, 92, 89, 88, 87, 86, + 85, 84, 83, 82, 81, 80, 79, 76, 72, 54, + 46, 44, 43, 42, 41, 40, 38, 36, 35, 34, + 33, 32, 31, 30, 25, 17, 15, 14, 11, 9, + 7, 3, 183, 183, 183, 183, 183, 183, 183, 183, + + 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183 + } ; + +static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr; +static char *yy_full_match; +static int yy_lp; +#define REJECT \ +{ \ +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \ +yy_cp = yy_full_match; /* restore poss. backed-over text */ \ +++yy_lp; \ +goto find_rule; \ +} +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +char *yytext; +#line 1 "gmScanner.l" +#define INITIAL 0 +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ +#line 22 "gmScanner.l" + +#include +#include "gmConfig.h" +#include "gmParser.cpp.h" + +#line 569 "gmScanner.cpp" + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap YY_PROTO(( void )); +#else +extern int yywrap YY_PROTO(( void )); +#endif +#endif + +#ifndef YY_NO_UNPUT +static void yyunput YY_PROTO(( int c, char *buf_ptr )); +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput YY_PROTO(( void )); +#else +static int input YY_PROTO(( void )); +#endif +#endif + +#if YY_STACK_USED +static int yy_start_stack_ptr = 0; +static int yy_start_stack_depth = 0; +static int *yy_start_stack = 0; +#ifndef YY_NO_PUSH_STATE +static void yy_push_state YY_PROTO(( int new_state )); +#endif +#ifndef YY_NO_POP_STATE +static void yy_pop_state YY_PROTO(( void )); +#endif +#ifndef YY_NO_TOP_STATE +static int yy_top_state YY_PROTO(( void )); +#endif + +#else +#define YY_NO_PUSH_STATE 1 +#define YY_NO_POP_STATE 1 +#define YY_NO_TOP_STATE 1 +#endif + +#ifdef YY_MALLOC_DECL +YY_MALLOC_DECL +#else +#if __STDC__ +#ifndef __cplusplus +#include +#endif +#else +/* Just try to get by without declaring the routines. This will fail + * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) + * or sizeof(void*) != sizeof(int). + */ +#endif +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ + +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( yy_current_buffer->yy_is_interactive ) \ + { \ + int c = '*', n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ + && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL int yylex YY_PROTO(( void )) +#endif + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +YY_DECL + { + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 29 "gmScanner.l" + + +#line 719 "gmScanner.cpp" + + if ( yy_init ) + { + yy_init = 0; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yy_start ) + yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! yy_current_buffer ) + yy_current_buffer = + yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_load_buffer_state(); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yy_start; + yy_state_ptr = yy_state_buf; + *yy_state_ptr++ = yy_current_state; +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 184 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + *yy_state_ptr++ = yy_current_state; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 293 ); + +yy_find_action: + yy_current_state = *--yy_state_ptr; + yy_lp = yy_accept[yy_current_state]; +find_rule: /* we branch to this label when backing up */ + for ( ; ; ) /* until we find what rule we matched */ + { + if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] ) + { + yy_act = yy_acclist[yy_lp]; + { + yy_full_match = yy_cp; + break; + } + } + --yy_cp; + yy_current_state = *--yy_state_ptr; + yy_lp = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + + if ( yy_act != YY_END_OF_BUFFER ) + { + int yyl; + for ( yyl = 0; yyl < yyleng; ++yyl ) + if ( yytext[yyl] == '\n' ) + ++yylineno; + } + +do_action: /* This label is used only to access EOF actions. */ + + + switch ( yy_act ) + { /* beginning of action switch */ +case 1: +YY_RULE_SETUP +#line 31 "gmScanner.l" +{ + int c; + + while((c = yyinput()) != 0) + { + if(c == '*') + { + if((c = yyinput()) == '/') + break; + else + unput(c); + } + } + } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 46 "gmScanner.l" +{ /* eat up comments */ } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 48 "gmScanner.l" +{ return(KEYWORD_LOCAL); } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 49 "gmScanner.l" +{ return(KEYWORD_GLOBAL); } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 50 "gmScanner.l" +{ return(KEYWORD_MEMBER); } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 51 "gmScanner.l" +{ return(KEYWORD_AND); } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 52 "gmScanner.l" +{ return(KEYWORD_OR); } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 53 "gmScanner.l" +{ return(KEYWORD_IF); } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 54 "gmScanner.l" +{ return(KEYWORD_ELSE); } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 55 "gmScanner.l" +{ return(KEYWORD_WHILE); } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 56 "gmScanner.l" +{ return(KEYWORD_FOR); } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 57 "gmScanner.l" +{ return(KEYWORD_FOREACH); } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 58 "gmScanner.l" +{ return(KEYWORD_IN); } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 59 "gmScanner.l" +{ return(KEYWORD_DOWHILE); } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 60 "gmScanner.l" +{ return(KEYWORD_BREAK); } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 61 "gmScanner.l" +{ return(KEYWORD_CONTINUE); } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 62 "gmScanner.l" +{ return(KEYWORD_NULL); } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 63 "gmScanner.l" +{ return(KEYWORD_RETURN); } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 64 "gmScanner.l" +{ return(KEYWORD_FUNCTION); } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 65 "gmScanner.l" +{ return(KEYWORD_TABLE); } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 66 "gmScanner.l" +{ return(KEYWORD_THIS); } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 67 "gmScanner.l" +{ return(KEYWORD_TRUE); } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 68 "gmScanner.l" +{ return(KEYWORD_FALSE); } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 70 "gmScanner.l" +{ return(IDENTIFIER); } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 72 "gmScanner.l" +{ return(CONSTANT_HEX); } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 73 "gmScanner.l" +{ return(CONSTANT_BINARY); } + YY_BREAK +case 27: +YY_RULE_SETUP +#line 74 "gmScanner.l" +{ return(CONSTANT_INT); } + YY_BREAK +case 28: +YY_RULE_SETUP +#line 75 "gmScanner.l" +{ return(CONSTANT_CHAR); } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 76 "gmScanner.l" +{ return(CONSTANT_FLOAT); } + YY_BREAK +case 30: +YY_RULE_SETUP +#line 77 "gmScanner.l" +{ return(CONSTANT_FLOAT); } + YY_BREAK +case 31: +YY_RULE_SETUP +#line 78 "gmScanner.l" +{ return(CONSTANT_FLOAT); } + YY_BREAK +case 32: +YY_RULE_SETUP +#line 79 "gmScanner.l" +{ return(CONSTANT_STRING); } + YY_BREAK +case 33: +YY_RULE_SETUP +#line 80 "gmScanner.l" +{ return(CONSTANT_STRING); } + YY_BREAK +case 34: +YY_RULE_SETUP +#line 82 "gmScanner.l" +{ return(KEYWORD_AND); } + YY_BREAK +case 35: +YY_RULE_SETUP +#line 83 "gmScanner.l" +{ return(KEYWORD_OR); } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 84 "gmScanner.l" +{ return(SYMBOL_ASGN_BSR); } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 85 "gmScanner.l" +{ return(SYMBOL_ASGN_BSL); } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 86 "gmScanner.l" +{ return(SYMBOL_ASGN_ADD); } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 87 "gmScanner.l" +{ return(SYMBOL_ASGN_MINUS); } + YY_BREAK +case 40: +YY_RULE_SETUP +#line 88 "gmScanner.l" +{ return(SYMBOL_ASGN_TIMES); } + YY_BREAK +case 41: +YY_RULE_SETUP +#line 89 "gmScanner.l" +{ return(SYMBOL_ASGN_DIVIDE); } + YY_BREAK +case 42: +YY_RULE_SETUP +#line 90 "gmScanner.l" +{ return(SYMBOL_ASGN_REM); } + YY_BREAK +case 43: +YY_RULE_SETUP +#line 91 "gmScanner.l" +{ return(SYMBOL_ASGN_BAND); } + YY_BREAK +case 44: +YY_RULE_SETUP +#line 92 "gmScanner.l" +{ return(SYMBOL_ASGN_BOR); } + YY_BREAK +case 45: +YY_RULE_SETUP +#line 93 "gmScanner.l" +{ return(SYMBOL_ASGN_BXOR); } + YY_BREAK +case 46: +YY_RULE_SETUP +#line 94 "gmScanner.l" +{ return(SYMBOL_RIGHT_SHIFT); } + YY_BREAK +case 47: +YY_RULE_SETUP +#line 95 "gmScanner.l" +{ return(SYMBOL_LEFT_SHIFT); } + YY_BREAK +case 48: +YY_RULE_SETUP +#line 96 "gmScanner.l" +{ return(SYMBOL_LTE); } + YY_BREAK +case 49: +YY_RULE_SETUP +#line 97 "gmScanner.l" +{ return(SYMBOL_GTE); } + YY_BREAK +case 50: +YY_RULE_SETUP +#line 98 "gmScanner.l" +{ return(SYMBOL_EQ); } + YY_BREAK +case 51: +YY_RULE_SETUP +#line 99 "gmScanner.l" +{ return(SYMBOL_NEQ); } + YY_BREAK +case 52: +YY_RULE_SETUP +#line 100 "gmScanner.l" +{ return(';'); } + YY_BREAK +case 53: +YY_RULE_SETUP +#line 101 "gmScanner.l" +{ return('{'); } + YY_BREAK +case 54: +YY_RULE_SETUP +#line 102 "gmScanner.l" +{ return('}'); } + YY_BREAK +case 55: +YY_RULE_SETUP +#line 103 "gmScanner.l" +{ return(','); } + YY_BREAK +case 56: +YY_RULE_SETUP +#line 104 "gmScanner.l" +{ return('='); } + YY_BREAK +case 57: +YY_RULE_SETUP +#line 105 "gmScanner.l" +{ return('('); } + YY_BREAK +case 58: +YY_RULE_SETUP +#line 106 "gmScanner.l" +{ return(')'); } + YY_BREAK +case 59: +YY_RULE_SETUP +#line 107 "gmScanner.l" +{ return('['); } + YY_BREAK +case 60: +YY_RULE_SETUP +#line 108 "gmScanner.l" +{ return(']'); } + YY_BREAK +case 61: +YY_RULE_SETUP +#line 109 "gmScanner.l" +{ return('.'); } + YY_BREAK +case 62: +YY_RULE_SETUP +#line 110 "gmScanner.l" +{ return('!'); } + YY_BREAK +case 63: +YY_RULE_SETUP +#line 111 "gmScanner.l" +{ return('-'); } + YY_BREAK +case 64: +YY_RULE_SETUP +#line 112 "gmScanner.l" +{ return('+'); } + YY_BREAK +case 65: +YY_RULE_SETUP +#line 113 "gmScanner.l" +{ return('*'); } + YY_BREAK +case 66: +YY_RULE_SETUP +#line 114 "gmScanner.l" +{ return('/'); } + YY_BREAK +case 67: +YY_RULE_SETUP +#line 115 "gmScanner.l" +{ return('%'); } + YY_BREAK +case 68: +YY_RULE_SETUP +#line 116 "gmScanner.l" +{ return('<'); } + YY_BREAK +case 69: +YY_RULE_SETUP +#line 117 "gmScanner.l" +{ return('>'); } + YY_BREAK +case 70: +YY_RULE_SETUP +#line 118 "gmScanner.l" +{ return('&'); } + YY_BREAK +case 71: +YY_RULE_SETUP +#line 119 "gmScanner.l" +{ return('|'); } + YY_BREAK +case 72: +YY_RULE_SETUP +#line 120 "gmScanner.l" +{ return('^'); } + YY_BREAK +case 73: +YY_RULE_SETUP +#line 121 "gmScanner.l" +{ return('~'); } + YY_BREAK +case 74: +YY_RULE_SETUP +#line 122 "gmScanner.l" +{ return(':'); } + YY_BREAK +case 75: +YY_RULE_SETUP +#line 123 "gmScanner.l" +{ return(':'); } + YY_BREAK +case 76: +YY_RULE_SETUP +#line 125 "gmScanner.l" +{ } + YY_BREAK +case 77: +YY_RULE_SETUP +#line 126 "gmScanner.l" +{ return(TOKEN_ERROR); } + YY_BREAK +case 78: +YY_RULE_SETUP +#line 128 "gmScanner.l" +ECHO; + YY_BREAK +#line 1213 "gmScanner.cpp" + case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yy_c_buf_p; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of yylex */ + + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ + +static int yy_get_next_buffer() + { + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( yy_current_buffer->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a singled characater, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_n_chars = 0; + + else + { + int num_to_read = + yy_current_buffer->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ +#ifdef YY_USES_REJECT + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); +#else + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = yy_current_buffer; + + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + //_GD_ + int oldSize = b->yy_buf_size; + + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + /* Include room in for 2 EOB chars. */ + //_GD_ b->yy_ch_buf = (char *) + //_GD_ yy_flex_realloc( (void *) b->yy_ch_buf, + //_GD_ b->yy_buf_size + 2 ); + //_GD_ + void* newBytes = yy_flex_alloc( b->yy_buf_size + 2 ); + memcpy(newBytes, b->yy_ch_buf, oldSize)); + yy_flex_free(b->yy_ch_buf); + b->yy_ch_buf = newBytes; + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = yy_current_buffer->yy_buf_size - + number_to_move - 1; +#endif + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); + } + + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; + + return ret_val; + } + + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +static yy_state_type yy_get_previous_state() + { + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = yy_start; + yy_state_ptr = yy_state_buf; + *yy_state_ptr++ = yy_current_state; + + for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 184 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + *yy_state_ptr++ = yy_current_state; + } + + return yy_current_state; + } + + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + +#ifdef YY_USE_PROTOS +static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) +#else +static yy_state_type yy_try_NUL_trans( yy_current_state ) +yy_state_type yy_current_state; +#endif + { + register int yy_is_jam; + + register YY_CHAR yy_c = 1; + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 184 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + *yy_state_ptr++ = yy_current_state; + yy_is_jam = (yy_current_state == 183); + + return yy_is_jam ? 0 : yy_current_state; + } + + +#ifndef YY_NO_UNPUT +#ifdef YY_USE_PROTOS +static void yyunput( int c, register char *yy_bp ) +#else +static void yyunput( c, yy_bp ) +int c; +register char *yy_bp; +#endif + { + register char *yy_cp = yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; + + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + yy_n_chars = yy_current_buffer->yy_buf_size; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + if ( c == '\n' ) + --yylineno; + + yytext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; + } +#endif /* ifndef YY_NO_UNPUT */ + + +#ifdef __cplusplus +static int yyinput() +#else +static int input() +#endif + { + int c; + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + yytext_ptr = yy_c_buf_p; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + { + yy_c_buf_p = + yytext_ptr + YY_MORE_ADJ; + return EOF; + } + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + break; + + case EOB_ACT_LAST_MATCH: +#ifdef __cplusplus + YY_FATAL_ERROR( + "unexpected last match in yyinput()" ); +#else + YY_FATAL_ERROR( + "unexpected last match in input()" ); +#endif + } + } + } + + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; + + if ( c == '\n' ) + ++yylineno; + + return c; + } + + +#ifdef YY_USE_PROTOS +void yyrestart( FILE *input_file ) +#else +void yyrestart( input_file ) +FILE *input_file; +#endif + { + if ( ! yy_current_buffer ) + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_init_buffer( yy_current_buffer, input_file ); + yy_load_buffer_state(); + } + + +#ifdef YY_USE_PROTOS +void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +#else +void yy_switch_to_buffer( new_buffer ) +YY_BUFFER_STATE new_buffer; +#endif + { + if ( yy_current_buffer == new_buffer ) + return; + + if ( yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + yy_current_buffer = new_buffer; + yy_load_buffer_state(); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } + + +#ifdef YY_USE_PROTOS +void yy_load_buffer_state( void ) +#else +void yy_load_buffer_state() +#endif + { + yy_n_chars = yy_current_buffer->yy_n_chars; + yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } + + +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) +#else +YY_BUFFER_STATE yy_create_buffer( file, size ) +FILE *file; +int size; +#endif + { + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; + } + + +#ifdef YY_USE_PROTOS +void yy_delete_buffer( YY_BUFFER_STATE b ) +#else +void yy_delete_buffer( b ) +YY_BUFFER_STATE b; +#endif + { + if ( ! b ) + return; + + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yy_flex_free( (void *) b->yy_ch_buf ); + + yy_flex_free( (void *) b ); + } + + +#ifndef YY_ALWAYS_INTERACTIVE +#ifndef YY_NEVER_INTERACTIVE +extern int isatty YY_PROTO(( int )); +#endif +#endif + +#ifdef YY_USE_PROTOS +void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) +#else +void yy_init_buffer( b, file ) +YY_BUFFER_STATE b; +FILE *file; +#endif + + + { + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + +#if YY_ALWAYS_INTERACTIVE + b->yy_is_interactive = 1; +#else +#if YY_NEVER_INTERACTIVE + b->yy_is_interactive = 0; +#else + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; +#endif +#endif + } + + +#ifdef YY_USE_PROTOS +void yy_flush_buffer( YY_BUFFER_STATE b ) +#else +void yy_flush_buffer( b ) +YY_BUFFER_STATE b; +#endif + + { + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == yy_current_buffer ) + yy_load_buffer_state(); + } + + +#ifndef YY_NO_SCAN_BUFFER +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) +#else +YY_BUFFER_STATE yy_scan_buffer( base, size ) +char *base; +yy_size_t size; +#endif + { + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; + } +#endif + + +#ifndef YY_NO_SCAN_STRING +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_string( yyconst char *str ) +#else +YY_BUFFER_STATE yy_scan_string( str ) +yyconst char *str; +#endif + { + int len; + for ( len = 0; str[len]; ++len ) + ; + + return yy_scan_bytes( str, len ); + } +#endif + + +#ifndef YY_NO_SCAN_BYTES +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) +#else +YY_BUFFER_STATE yy_scan_bytes( bytes, len ) +yyconst char *bytes; +int len; +#endif + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yy_flex_alloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; + } +#endif + + +#ifndef YY_NO_PUSH_STATE +#ifdef YY_USE_PROTOS +static void yy_push_state( int new_state ) +#else +static void yy_push_state( new_state ) +int new_state; +#endif + { + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; + + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); + + if ( ! yy_start_stack ) + yy_start_stack = (int *) yy_flex_alloc( new_size ); + + else + yy_start_stack = (int *) yy_flex_realloc( + (void *) yy_start_stack, new_size ); + + if ( ! yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + yy_start_stack[yy_start_stack_ptr++] = YY_START; + + BEGIN(new_state); + } +#endif + + +#ifndef YY_NO_POP_STATE +static void yy_pop_state() + { + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN(yy_start_stack[yy_start_stack_ptr]); + } +#endif + + +#ifndef YY_NO_TOP_STATE +static int yy_top_state() + { + return yy_start_stack[yy_start_stack_ptr - 1]; + } +#endif + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +#ifdef YY_USE_PROTOS +static void yy_fatal_error( yyconst char msg[] ) +#else +static void yy_fatal_error( msg ) +char msg[]; +#endif + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); + } + + + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n - YY_MORE_ADJ; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) + + +/* Internal utility routines. */ + +#ifndef yytext_ptr +#ifdef YY_USE_PROTOS +static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) +#else +static void yy_flex_strncpy( s1, s2, n ) +char *s1; +yyconst char *s2; +int n; +#endif + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } +#endif + + +#ifdef YY_USE_PROTOS +static void *yy_flex_alloc( yy_size_t size ) +#else +static void *yy_flex_alloc( size ) +yy_size_t size; +#endif + { + //_GD_ return (void *) malloc( size ); + return (void *) GM_NEW( char [size] ); + } + +#ifdef YY_USE_PROTOS +static void *yy_flex_realloc( void *ptr, yy_size_t size ) +#else +static void *yy_flex_realloc( ptr, size ) +void *ptr; +yy_size_t size; +#endif + { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + //_GD_ return (void *) realloc( (char *) ptr, size ); + } + +#ifdef YY_USE_PROTOS +static void yy_flex_free( void *ptr ) +#else +static void yy_flex_free( ptr ) +void *ptr; +#endif + { + //_GD_ free( ptr ); + delete [] (char*) ptr; + } + +#if YY_MAIN +int main() + { + yylex(); + return 0; + } +#endif +#line 128 "gmScanner.l" + + +// yywrap +int gmwrap() +{ + return(1); +} + + + diff --git a/vscript/languages/gm/src/gm/gmScanner.h b/vscript/languages/gm/src/gm/gmScanner.h new file mode 100644 index 00000000..49b3e38c --- /dev/null +++ b/vscript/languages/gm/src/gm/gmScanner.h @@ -0,0 +1,32 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMSCANNER_H_ +#define _GMSCANNER_H_ + +#include "gmConfig.h" + +// +// gmscanner.cpp, gmparser.cpp.h and gmparser.cpp are created by flex and bison +// see fontend.bat for more details. +// + +// fwd decl for flex +typedef struct yy_buffer_state * YY_BUFFER_STATE; +YY_BUFFER_STATE gm_scan_string(const char * str); +YY_BUFFER_STATE gm_scan_bytes(const char *bytes, int len); +void gm_delete_buffer(YY_BUFFER_STATE b); +int gmlex(); +extern char * gmtext; +extern int gmlineno; + +#endif // _GMSCANNER_H_ + diff --git a/vscript/languages/gm/src/gm/gmScanner.l b/vscript/languages/gm/src/gm/gmScanner.l new file mode 100644 index 00000000..4b6b2bcb --- /dev/null +++ b/vscript/languages/gm/src/gm/gmScanner.l @@ -0,0 +1,137 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +%option yylineno + +DIGIT [0-9] +LETTER [a-zA-Z_] +HEX [a-fA-F0-9] +BINARY [0-1] +SCI [Ee][+-]?{DIGIT}+ +FL (f|F) + +%{ + +#include +#include "gmConfig.h" +#include "gmParser.cpp.h" + +%} + +%% + +"/*" { + int c; + + while((c = yyinput()) != 0) + { + if(c == '*') + { + if((c = yyinput()) == '/') + break; + else + unput(c); + } + } + } + +"//"[^\n]* { /* eat up comments */ } + +"local" { return(KEYWORD_LOCAL); } +"global" { return(KEYWORD_GLOBAL); } +"member" { return(KEYWORD_MEMBER); } +"and" { return(KEYWORD_AND); } +"or" { return(KEYWORD_OR); } +"if" { return(KEYWORD_IF); } +"else" { return(KEYWORD_ELSE); } +"while" { return(KEYWORD_WHILE); } +"for" { return(KEYWORD_FOR); } +"foreach" { return(KEYWORD_FOREACH); } +"in" { return(KEYWORD_IN); } +"dowhile" { return(KEYWORD_DOWHILE); } +"break" { return(KEYWORD_BREAK); } +"continue" { return(KEYWORD_CONTINUE); } +"null" { return(KEYWORD_NULL); } +"return" { return(KEYWORD_RETURN); } +"function" { return(KEYWORD_FUNCTION); } +"table" { return(KEYWORD_TABLE); } +"this" { return(KEYWORD_THIS); } +"true" { return(KEYWORD_TRUE); } +"false" { return(KEYWORD_FALSE); } + +{LETTER}({LETTER}|{DIGIT})* { return(IDENTIFIER); } + +0[xX]{HEX}+ { return(CONSTANT_HEX); } +0[bB]{BINARY}+ { return(CONSTANT_BINARY); } +{DIGIT}+ { return(CONSTANT_INT); } +'(\\.|[^\\'])+' { return(CONSTANT_CHAR); } +{DIGIT}+{SCI}{FL}? { return(CONSTANT_FLOAT); } +{DIGIT}*"."{DIGIT}+({SCI})?{FL}? { return(CONSTANT_FLOAT); } +{DIGIT}+"."{DIGIT}*({SCI})?{FL}? { return(CONSTANT_FLOAT); } +\"(\\.|[^\\"])*\" { return(CONSTANT_STRING); } +`([^`]|`{2})*` { return(CONSTANT_STRING); } + +"&&" { return(KEYWORD_AND); } +"||" { return(KEYWORD_OR); } +">>=" { return(SYMBOL_ASGN_BSR); } +"<<=" { return(SYMBOL_ASGN_BSL); } +"+=" { return(SYMBOL_ASGN_ADD); } +"-=" { return(SYMBOL_ASGN_MINUS); } +"*=" { return(SYMBOL_ASGN_TIMES); } +"/=" { return(SYMBOL_ASGN_DIVIDE); } +"%=" { return(SYMBOL_ASGN_REM); } +"&=" { return(SYMBOL_ASGN_BAND); } +"|=" { return(SYMBOL_ASGN_BOR); } +"^=" { return(SYMBOL_ASGN_BXOR); } +">>" { return(SYMBOL_RIGHT_SHIFT); } +"<<" { return(SYMBOL_LEFT_SHIFT); } +"<=" { return(SYMBOL_LTE); } +">=" { return(SYMBOL_GTE); } +"==" { return(SYMBOL_EQ); } +"!=" { return(SYMBOL_NEQ); } +";" { return(';'); } +"{" { return('{'); } +"}" { return('}'); } +"," { return(','); } +"=" { return('='); } +"(" { return('('); } +")" { return(')'); } +"[" { return('['); } +"]" { return(']'); } +"." { return('.'); } +"!" { return('!'); } +"-" { return('-'); } +"+" { return('+'); } +"*" { return('*'); } +"/" { return('/'); } +"%" { return('%'); } +"<" { return('<'); } +">" { return('>'); } +"&" { return('&'); } +"|" { return('|'); } +"^" { return('^'); } +"~" { return('~'); } +":" { return(':'); } +":" { return(':'); } + +[ \t\v\r\n\f] { } +. { return(TOKEN_ERROR); } + +%% + +// yywrap +int gmwrap() +{ + return(1); +} + + + diff --git a/vscript/languages/gm/src/gm/gmStream.cpp b/vscript/languages/gm/src/gm/gmStream.cpp new file mode 100644 index 00000000..dd5b306f --- /dev/null +++ b/vscript/languages/gm/src/gm/gmStream.cpp @@ -0,0 +1,14 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmStream.h" + diff --git a/vscript/languages/gm/src/gm/gmStream.h b/vscript/languages/gm/src/gm/gmStream.h new file mode 100644 index 00000000..ee7704b8 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmStream.h @@ -0,0 +1,143 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMSTREAM_H_ +#define _GMSTREAM_H_ + +#include "gmMem.h" +#include "gmUtil.h" + +/// \class gmStream +/// \brief gmStream is an abstract stream class +class gmStream +{ +public: + + enum + { + ILLEGAL_POS = -1, + }; + + enum Flags + { + F_EOS = (1 << 0), ///< is the stream at End Of Stream + F_READ = (1 << 1), ///< is the stream readable + F_WRITE = (1 << 2), ///< is the stream writable + F_ERROR = (1 << 3), ///< has a stream error occured + F_SIZE = (1 << 4), ///< are size operations valid on this stream? + F_SEEK = (1 << 5), ///< are seeking operations valid on this stream? + F_TELL = (1 << 6), ///< are tell operations valid on this stream? + F_USER = (1 << 6), + }; + + gmStream() : m_flags(0), m_swapEndian(false) {} + virtual ~gmStream() {} + + /// \brief Seek() + /// \return the p_pos before the seek if seek is supported, else ILLEGAL_POS. + virtual unsigned int Seek(unsigned int p_pos) = 0; + + /// \brief Tell() + /// \return the p_pos if tell is supported, else ILLEGAL_POS + virtual unsigned int Tell() const { return (unsigned int) ILLEGAL_POS; } + + /// \brief GetSize() will return the size of the stream if the stream supports this feature. + /// \return ILLEGAL_POS if GetSize is not supported + virtual unsigned int GetSize() const { return (unsigned int) ILLEGAL_POS; } + + /// \brief Read() will read p_n bytes from the stream into p_buffer. + /// \return the number of bytes successfully read. + virtual unsigned int Read(void * p_buffer, unsigned int p_n) = 0; + + /// \brief Write() will write p_n bytes from p_buffer to the stream. + /// \return the number of bytes successfully written + virtual unsigned int Write(const void * p_buffer, unsigned int p_n) = 0; + + /// \brief GetFlags() will return the current stream flags + inline Flags GetFlags() const { return (Flags) m_flags; } + + // + // Streaming interface (quite slow, but helpful...) + // + + /// \brief SetSwapEndianOnWrite() + inline void SetSwapEndianOnWrite(bool a_state) { m_swapEndian = a_state; } + inline bool GetSwapEndianOnWrite() const { return m_swapEndian; } + + /// \brief Explicitly set endian, will swap if necessary. + inline void SetEndianOnWrite(gmEndian a_endian) + { + int isLittle = gmIsLittleEndian(); + bool needSwap = false; + + if( ((a_endian == GM_ENDIAN_LITTLE) && !isLittle) + || ((a_endian == GM_ENDIAN_BIG) && isLittle) ) + { + needSwap = true; + } + + SetSwapEndianOnWrite(needSwap); + }; + + /// \brief Get the endian based on current machine and swap flag. + inline gmEndian GetEndianOnWrite() const + { + int isLittle = gmIsLittleEndian(); + + if(m_swapEndian) + { + isLittle = !isLittle; + } + + if(isLittle) + { + return GM_ENDIAN_LITTLE; + } + else + { + return GM_ENDIAN_BIG; + } + } + + template + gmStream &operator <<(T a_v) + { + if(m_swapEndian) + SwapEndian(a_v); + Write(&a_v, sizeof(T)); + return *this; + } + + template + gmStream &operator >>(T &a_v) + { + Read(&a_v, sizeof(T)); + return *this; + } + +protected: + + unsigned int m_flags; + bool m_swapEndian; + +private: + + inline void SwapEndian(gmuint8 &a_x) { } + inline void SwapEndian(gmint8 &a_x) { } + inline void SwapEndian(gmuint16 &a_x) { a_x = (gmuint16)((a_x << 8) | ((a_x >> 8) & 0xff)); } + inline void SwapEndian(gmint16 &a_x) { a_x = (gmint16)((a_x << 8) | ((a_x >> 8) & 0xff)); } + inline void SwapEndian(gmuint32 &a_x) { a_x = (a_x << 24) | ((a_x << 8) & 0x00ff0000) | ((a_x >> 8) & 0x0000ff00) | ((a_x >> 24) & 0x000000ff); } + inline void SwapEndian(gmint32 &a_x) { a_x = (a_x << 24) | ((a_x << 8) & 0x00ff0000) | ((a_x >> 8) & 0x0000ff00) | ((a_x >> 24) & 0x000000ff); } + inline void SwapEndian(gmfloat &a_x) { SwapEndian((gmuint32 &) a_x); } +}; + + +#endif // _GMSTREAM_H_ diff --git a/vscript/languages/gm/src/gm/gmStreamBuffer.cpp b/vscript/languages/gm/src/gm/gmStreamBuffer.cpp new file mode 100644 index 00000000..84280fbf --- /dev/null +++ b/vscript/languages/gm/src/gm/gmStreamBuffer.cpp @@ -0,0 +1,173 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmStreamBuffer.h" + + +gmStreamBufferStatic::gmStreamBufferStatic() +{ + m_cursor = 0; + m_size = 0; + m_stream = NULL; +} + + +gmStreamBufferStatic::gmStreamBufferStatic(const void * p_buffer, unsigned int a_size) +{ + Open(p_buffer, a_size); +} + + +gmStreamBufferStatic::~gmStreamBufferStatic() +{ +} + + +unsigned int gmStreamBufferStatic::Seek(unsigned int p_pos) +{ + int oldCursor = m_cursor; + int cursor = p_pos; + if(cursor < 0) return (unsigned int)ILLEGAL_POS; + if((unsigned int) cursor > m_size) return (unsigned int)ILLEGAL_POS; + m_cursor = cursor; + return oldCursor; +} + + +unsigned int gmStreamBufferStatic::Tell() const +{ + return m_cursor; +} + + +unsigned int gmStreamBufferStatic::GetSize() const +{ + return m_size; +} + + +unsigned int gmStreamBufferStatic::Read(void * p_buffer, unsigned int p_n) +{ + unsigned int remain = m_size - m_cursor; + if(p_n > remain) + { + m_flags |= F_EOS; + p_n = remain; + } + memcpy(p_buffer, &m_stream[m_cursor], p_n); + m_cursor += p_n; + return p_n; +} + + +unsigned int gmStreamBufferStatic::Write(const void * p_buffer, unsigned int p_n) +{ + m_flags |= F_ERROR; + return 0; +} + + +void gmStreamBufferStatic::Open(const void * p_buffer, unsigned int a_size) +{ + m_cursor = 0; + m_size = a_size; + m_stream = (const char *) p_buffer; + m_flags = F_READ | F_SIZE | F_SEEK | F_TELL; +} + + +// +// gmStreamBufferDynamic +// + + +gmStreamBufferDynamic::gmStreamBufferDynamic() +{ + m_cursor = 0; + m_flags = F_READ | F_WRITE | F_SIZE | F_SEEK | F_TELL; +} + + +gmStreamBufferDynamic::~gmStreamBufferDynamic() +{ +} + + +unsigned int gmStreamBufferDynamic::Seek(unsigned int p_pos) +{ + int oldCursor = m_cursor; + int cursor = p_pos; + if(cursor < 0) + return (unsigned int)ILLEGAL_POS; + if((unsigned int) cursor > m_stream.Count()) + return (unsigned int)ILLEGAL_POS; + m_cursor = cursor; + return oldCursor; +} + + +unsigned int gmStreamBufferDynamic::Tell() const +{ + return m_cursor; +} + + +unsigned int gmStreamBufferDynamic::GetSize() const +{ + return m_stream.Count(); +} + + +unsigned int gmStreamBufferDynamic::Read(void * p_buffer, unsigned int p_n) +{ + unsigned int remain = m_stream.Count() - m_cursor; + if(p_n > remain) + { + // set eof + m_flags |= F_EOS; + p_n = remain; + } + memcpy(p_buffer, m_stream.GetData() + m_cursor, p_n); + m_cursor += p_n; + return p_n; +} + + +unsigned int gmStreamBufferDynamic::Write(const void * p_buffer, unsigned int p_n) +{ + unsigned int remain = m_stream.Count() - m_cursor; + if(p_n > remain) + { + // grow the stream + m_stream.SetCount(m_cursor + p_n); + } + memcpy(m_stream.GetData() + m_cursor, p_buffer, p_n); + m_cursor += p_n; + return p_n; +} + + +void gmStreamBufferDynamic::Reset() +{ + m_cursor = 0; + m_flags = F_READ | F_WRITE | F_SIZE | F_SEEK | F_TELL; + m_stream.Reset(); +} + + +void gmStreamBufferDynamic::ResetAndFreeMemory() +{ + m_cursor = 0; + m_flags = F_READ | F_WRITE | F_SIZE | F_SEEK | F_TELL; + m_stream.ResetAndFreeMemory(); +} + diff --git a/vscript/languages/gm/src/gm/gmStreamBuffer.h b/vscript/languages/gm/src/gm/gmStreamBuffer.h new file mode 100644 index 00000000..5e0b24d3 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmStreamBuffer.h @@ -0,0 +1,76 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMSTREAMMEM_H_ +#define _GMSTREAMMEM_H_ + +#include "gmConfig.h" +#include "gmStream.h" +#include "gmArraySimple.h" + +/// \class gmStreamBufferStatic +/// \brief gmStreamBufferStatic is a read only stream constructed from a const void * +class gmStreamBufferStatic : public gmStream +{ +public: + + gmStreamBufferStatic(); + gmStreamBufferStatic(const void * a_buffer, unsigned int a_size); + virtual ~gmStreamBufferStatic(); + + virtual unsigned int Seek(unsigned int p_pos); + virtual unsigned int Tell() const; + virtual unsigned int GetSize() const; + virtual unsigned int Read(void * p_buffer, unsigned int p_n); + virtual unsigned int Write(const void * p_buffer, unsigned int p_n); + + void Open(const void * a_buffer, unsigned int a_size); + inline const char* GetData() const { return m_stream; } + +private: + + unsigned int m_cursor; + unsigned int m_size; + const char * m_stream; +}; + + +/// \class gmStreamBufferDynamic +/// \brief gmStreamBufferDynamic is a read\write memory stream +class gmStreamBufferDynamic : public gmStream +{ +public: + + gmStreamBufferDynamic(); + virtual ~gmStreamBufferDynamic(); + + virtual unsigned int Seek(unsigned int p_pos); + virtual unsigned int Tell() const; + virtual unsigned int GetSize() const; + virtual unsigned int Read(void * p_buffer, unsigned int p_n); + virtual unsigned int Write(const void * p_buffer, unsigned int p_n); + + void Reset() ; + void ResetAndFreeMemory(); + inline void SetBlockSize(unsigned int a_blockSize) { m_stream.SetBlockSize(a_blockSize); } + inline const char* GetData() const { return m_stream.GetData(); } + inline char* GetUnsafeData() { return m_stream.GetData(); } + void SetSize(unsigned int a_size) { m_stream.SetCount(a_size); } + void SetCursor(unsigned int a_cursor) { m_cursor = a_cursor; } + +private: + + unsigned int m_cursor; + gmArraySimple m_stream; +}; + + +#endif // _GMSTREAMMEM_H_ diff --git a/vscript/languages/gm/src/gm/gmStringObject.cpp b/vscript/languages/gm/src/gm/gmStringObject.cpp new file mode 100644 index 00000000..cbce8bda --- /dev/null +++ b/vscript/languages/gm/src/gm/gmStringObject.cpp @@ -0,0 +1,26 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmStringObject.h" +#include "gmMachine.h" + +// Must be last header +#include "memdbgon.h" + +void gmStringObject::Destruct(gmMachine * a_machine) +{ + a_machine->Sys_FreeUniqueString(m_string); +#if GM_USE_INCGC + a_machine->DestructDeleteObject(this); +#endif //GM_USE_INCGC +} + diff --git a/vscript/languages/gm/src/gm/gmStringObject.h b/vscript/languages/gm/src/gm/gmStringObject.h new file mode 100644 index 00000000..96dd0987 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmStringObject.h @@ -0,0 +1,48 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMSTRINGOBJECT_H_ +#define _GMSTRINGOBJECT_H_ + +#include "gmConfig.h" +#include "gmVariable.h" +#include "gmHash.h" + +class gmMachine; + +/// \class gmStringObject +/// \brief +class gmStringObject : public gmObject, public gmHashNode +{ +public: + + inline const char * GetKey() const { return m_string; } + + virtual int GetType() const { return GM_STRING; } + virtual void Destruct(gmMachine * a_machine); + + inline operator const char *() const { return m_string; } + inline const char * GetString() const { return m_string; } + inline int GetLength() const { return m_length; } + +protected: + + /// \brief Non-public constructor. Create via gmMachine. + gmStringObject(const char * a_string, int a_length) { m_string = a_string; m_length = a_length; } + friend class gmMachine; + +private: + + const char * m_string; + int m_length; +}; + +#endif // _GMSTRINGOBJECT_H_ diff --git a/vscript/languages/gm/src/gm/gmTableObject.cpp b/vscript/languages/gm/src/gm/gmTableObject.cpp new file mode 100644 index 00000000..77a1c339 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmTableObject.cpp @@ -0,0 +1,434 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmTableObject.h" +#include "gmMachine.h" +#include "gmThread.h" + +// Must be last header +#include "memdbgon.h" + + + +gmTableObject::gmTableObject() +{ + m_nodes = NULL; + m_firstFree = NULL; + m_tableSize = 0; + m_slotsUsed = 0; +} + + +#if GM_USE_INCGC + + +bool gmTableObject::Trace(gmMachine * a_machine, gmGarbageCollector* a_gc, const int a_workLeftToGo, int& a_workDone) +{ + gmTableNode * curNode; + int index; + for(index = 0; index < m_tableSize; ++index) + { + if(m_nodes[index].m_key.m_type != GM_NULL) + { + curNode = &m_nodes[index]; + if(curNode->m_key.IsReference()) + { + gmObject* object = GM_MOBJECT(a_machine, curNode->m_key.m_value.m_ref); + a_gc->GetNextObject(object); + ++a_workDone; + } + if(curNode->m_value.IsReference()) + { + gmObject* object = GM_MOBJECT(a_machine, curNode->m_value.m_value.m_ref); + a_gc->GetNextObject(object); + ++a_workDone; + } + } + } + + ++a_workDone; + return true; +} + +#else //GM_USE_INCGC + +void gmTableObject::Mark(gmMachine * a_machine, gmuint32 a_mark) +{ + if(m_mark != GM_MARK_PERSIST) m_mark = a_mark; + + gmTableNode * curNode; + int index; + for(index = 0; index < m_tableSize; ++index) + { + if(m_nodes[index].m_key.m_type != GM_NULL) + { + curNode = &m_nodes[index]; + if(curNode->m_key.IsReference()) + { + gmObject* object = GM_MOBJECT(a_machine, curNode->m_key.m_value.m_ref); + if(object->NeedsMark(a_mark)) object->Mark(a_machine, a_mark); + } + if(curNode->m_value.IsReference()) + { + gmObject* object = GM_MOBJECT(a_machine, curNode->m_value.m_value.m_ref); + if(object->NeedsMark(a_mark)) object->Mark(a_machine, a_mark); + } + } + } +} +#endif //GM_USE_INCGC + + +void gmTableObject::Destruct(gmMachine * a_machine) +{ + if(m_nodes) + { + a_machine->Sys_Free(m_nodes); + m_nodes = NULL; + } + + m_firstFree = NULL; + m_tableSize = 0; + m_slotsUsed = 0; + +#if GM_USE_INCGC + a_machine->DestructDeleteObject(this); +#endif //GM_USE_INCGC +} + + + +gmVariable gmTableObject::Get(const gmVariable &a_key) const +{ + gmTableNode* foundNode = NULL; + + if(m_nodes && a_key.m_type != GM_NULL) + { + foundNode = GetAtHashPos(&a_key); + + do + { + if(a_key.m_value.m_ref == foundNode->m_key.m_value.m_ref && + a_key.m_type == foundNode->m_key.m_type) + { + return foundNode->m_value; + } + foundNode = foundNode->m_nextInHashTable; + } while (foundNode); + } + + return gmVariable::s_null; +} + + +gmVariable gmTableObject::Get(gmMachine * a_machine, const char * a_key) const +{ + return Get(gmVariable(GM_STRING, a_machine->AllocStringObject(a_key)->GetRef())); +} + + +#if GM_USE_INCGC +void gmTableObject::Set(gmMachine * a_machine, const gmVariable &a_key, const gmVariable &a_value, bool a_disableWriteBarrier) +#else //GM_USE_INCGC +void gmTableObject::Set(gmMachine * a_machine, const gmVariable &a_key, const gmVariable &a_value) +#endif //GM_USE_INCGC +{ + GM_ASSERT(m_firstFree >= &m_nodes[0] && m_firstFree <= &m_nodes[m_tableSize-1]); + + if(!m_tableSize) + { + Construct(a_machine); + } + + if(a_key.m_type == GM_NULL) + { + return; + } + + gmTableNode* origHashNode = GetAtHashPos(&a_key); + gmTableNode* foundNode = origHashNode; + gmTableNode* lastNode = NULL; + + GM_ASSERT(foundNode); + + // find key, if it exists + do + { + if( (a_key.m_value.m_ref == foundNode->m_key.m_value.m_ref) && + (a_key.m_type == foundNode->m_key.m_type)) + { + //If found and value is null, remove it + if(GM_NULL == a_value.m_type) + { +#if GM_USE_INCGC + if( !a_disableWriteBarrier ) + { + // Both key and value are going, write barrier them both + if(foundNode->m_key.IsReference()) + { + a_machine->GetGC()->WriteBarrier((gmObject*)foundNode->m_key.m_value.m_ref); + } + if(foundNode->m_value.IsReference()) + { + a_machine->GetGC()->WriteBarrier((gmObject*)foundNode->m_value.m_value.m_ref); + } + } +#endif //GM_USE_INCGC + + if(lastNode) + { + lastNode->m_nextInHashTable = foundNode->m_nextInHashTable; + + foundNode->m_key.m_type = GM_NULL; + foundNode->m_nextInHashTable = NULL; + } + else if(foundNode->m_nextInHashTable) + { + gmTableNode* nextSlot = foundNode->m_nextInHashTable; + + *foundNode = *nextSlot; + + nextSlot->m_key.m_type = GM_NULL; + nextSlot->m_nextInHashTable = NULL; + } + else + { + foundNode->m_key.m_type = GM_NULL; + } + --m_slotsUsed; + return; + } +#if GM_USE_INCGC + if( !a_disableWriteBarrier ) + { + // Value is going, write barrier value only + if(foundNode->m_value.IsReference()) + { + a_machine->GetGC()->WriteBarrier((gmObject*)foundNode->m_value.m_value.m_ref); + } + } +#endif //GM_USE_INCGC + foundNode->m_value = a_value; + return; + } + lastNode = foundNode; + foundNode = foundNode->m_nextInHashTable; + } while (foundNode); + + //If not found, but value is null, don't add it + if(GM_NULL == a_value.m_type) + { + return; + } + + // key was not found, insert it + if(origHashNode->m_key.m_type != GM_NULL) //Main pos is not free + { + gmTableNode * other; + + if( (other = GetAtHashPos(&origHashNode->m_key)) != origHashNode ) //Colliding node is out of its desired position. + { + while(other->m_nextInHashTable != origHashNode) + { + other = other->m_nextInHashTable; + } + other->m_nextInHashTable = m_firstFree; + *m_firstFree = *origHashNode; //Copy colliding node into free pos + origHashNode->m_nextInHashTable = NULL; //original is now completely free + } + else + { + //Colliding node is in its desired pos, new node will go into free pos + m_firstFree->m_nextInHashTable = origHashNode->m_nextInHashTable; + origHashNode->m_nextInHashTable = m_firstFree; + origHashNode = m_firstFree; + } + } + + // Fill new value + origHashNode->m_key = a_key; + origHashNode->m_value = a_value; + + ++m_slotsUsed; + + // Update m_firstFree + for(;;) + { + if(m_firstFree->m_key.m_type == GM_NULL) + { + //Free place still exists + return; + } + else if(m_firstFree == &m_nodes[0]) + { + break; //We hit the start of the table, resize/rehash it + } + else + { + --m_firstFree; //Try moving toward table start + } + } + + Resize(a_machine); +} + + + +void gmTableObject::Set(gmMachine * a_machine, const char * a_key, const gmVariable &a_value) +{ + bool enabled = a_machine->IsGCEnabled(); + a_machine->EnableGC(false); + Set(a_machine, gmVariable(GM_STRING, a_machine->AllocStringObject(a_key)->GetRef()), a_value); + a_machine->EnableGC(enabled); +} + + + +gmTableObject * gmTableObject::Duplicate(gmMachine * a_machine) +{ + gmTableObject * object = a_machine->AllocTableObject(); + + if(m_tableSize) + { + object->AllocSize(a_machine, m_tableSize); + + int index; + for(index = 0; index < m_tableSize; ++index) + { + if(m_nodes[index].m_key.m_type != GM_NULL) + { + object->Set(a_machine, m_nodes[index].m_key, m_nodes[index].m_value); + } + } + } + + return object; +} + + + +void gmTableObject::Construct(gmMachine * a_machine) +{ + AllocSize(a_machine, MIN_TABLE_SIZE); +} + + + +gmTableNode* gmTableObject::GetNext(gmTableIterator& a_it) const +{ + int index = a_it; + if(index == IT_NULL) + { + return NULL; + } + if(index == IT_FIRST) + { + index = 0; + } + while(index= m_tableSize - ( m_tableSize / 4 )) + { + newSize = m_tableSize * 2; + } + else if((m_slotsUsed <= ( m_tableSize / 4 )) && (m_tableSize > 4)) + { + newSize = m_tableSize / 2; + } + else + { + //No need to resize, but need to reset m_firstFree + int index; + for(index = m_tableSize-1; index>=0; --index) + { + if(m_nodes[index].m_key.m_type == GM_NULL) + { + m_firstFree = &m_nodes[index]; + return; + } + } + GM_ASSERT(0); //Shouldn't ever get here + } + + gmTableNode* oldNodes = m_nodes; + int oldTableSize = m_tableSize; + + AllocSize(a_machine, newSize); + + int index; + for(index = 0; index < oldTableSize; ++index) + { + if(oldNodes[index].m_key.m_type != GM_NULL) + { +#if GM_USE_INCGC + Set(a_machine, oldNodes[index].m_key, oldNodes[index].m_value, true); +#else //GM_USE_INCGC + Set(a_machine, oldNodes[index].m_key, oldNodes[index].m_value); +#endif //GM_USE_INCGC + } + } + + a_machine->Sys_Free(oldNodes); +} + + + +void gmTableObject::AllocSize(gmMachine * a_machine, int a_size) +{ + GM_ASSERT((a_size & (a_size-1)) == 0 ); //Check for power of 2 size + + int memSize = sizeof(m_nodes[0]) * a_size; + //WARNING: Sys_Alloc may call Mark and access this class before returning a new pointer! + m_nodes = (gmTableNode*)a_machine->Sys_Alloc(memSize); + m_tableSize = a_size; + m_slotsUsed = 0; + + memset(m_nodes, 0, memSize); + m_firstFree = &m_nodes[m_tableSize-1]; +} + + + +gmVariable gmTableObject::GetLinearSearch(const char * a_key) const +{ + gmTableIterator it; + for( gmTableNode * node = GetFirst(it); + !IsNull(it); + node = GetNext(it) ) + { + if( GM_STRING == node->m_key.m_type ) + { + if( strcmp(((gmStringObject*)node->m_key.m_value.m_ref)->GetString(), a_key) == 0 ) + { + return node->m_value; + } + } + } + return gmVariable::s_null; +} diff --git a/vscript/languages/gm/src/gm/gmTableObject.h b/vscript/languages/gm/src/gm/gmTableObject.h new file mode 100644 index 00000000..c24b0b79 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmTableObject.h @@ -0,0 +1,143 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMTABLEOBJECT_H_ +#define _GMTABLEOBJECT_H_ + +#include "gmConfig.h" +#include "gmVariable.h" +//#include "gmMem.h" + +typedef int gmTableIterator; ///< Table iterator, is actually the array index, or a reserved value + + +/// \class gmTableNode +/// \brief Values stored in the table are wrapped in these nodes. +struct gmTableNode +{ + gmTableNode* m_nextInHashTable; ///< The next node in the hash table + + gmVariable m_key; ///< The key used to find a value. + gmVariable m_value; ///< The value associated with the key +}; + + +/// \class gmTable +/// \brief +class gmTableObject : public gmObject +{ +public: + + // + // object + // + +#if GM_USE_INCGC + virtual bool Trace(gmMachine * a_machine, gmGarbageCollector* a_gc, const int a_workLeftToGo, int& a_workDone); +#else //GM_USE_INCGC + virtual void Mark(gmMachine * a_machine, gmuint32 a_mark); +#endif //GM_USE_INCGC + virtual void Destruct(gmMachine * a_machine); + virtual int GetType() const { return GM_TABLE; } + + // + // table set, get + // + + // Get by variable + gmVariable Get(const gmVariable &a_key) const; + // Get by c string (uses table search) + gmVariable Get(gmMachine * a_machine, const char * a_key) const; + // Get by array index (uses table search) + gmVariable Get(int a_indexKey) const { return Get(gmVariable(a_indexKey)); } + // Get by c string (uses linear search) + gmVariable GetLinearSearch(const char * a_key) const; + +#if GM_USE_INCGC + void Set(gmMachine * a_machine, const gmVariable &a_key, const gmVariable &a_value, bool a_disableWriteBarrier = false); +#else //GM_USE_INCGC + void Set(gmMachine * a_machine, const gmVariable &a_key, const gmVariable &a_value); +#endif //GM_USE_INCGC + void Set(gmMachine * a_machine, const char * a_key, const gmVariable &a_value); + inline void Set(gmMachine * a_machine, int a_index, const gmVariable &a_value) + { + Set(a_machine, gmVariable(GM_INT, (gmptr)a_index), a_value); + } + + inline int Count() const { return m_slotsUsed; } + gmTableObject * Duplicate(gmMachine * a_machine); + + + // + // iterator + // + + inline gmTableNode * GetFirst(gmTableIterator& a_it) const + { + a_it = IT_FIRST; + + return GetNext(a_it); + } + + inline bool IsNull(gmTableIterator a_it) const + { + if(a_it == IT_NULL) + { + return true; + } + return false; + } + + gmTableNode * GetNext(gmTableIterator& a_it) const; + +protected: + + /// \brief Non-public constructor. Create via gmMachine. + gmTableObject(); + friend class gmMachine; + +private: + + enum + { + IT_NULL = -1, + IT_FIRST = -2, + MIN_TABLE_SIZE = 4, + }; + + void Construct(gmMachine * a_machine); + + void RemoveAndDeleteAll(gmMachine * a_machine); + inline gmTableNode * GetAtHashPos(const gmVariable* a_key) const + { + unsigned int hash = a_key->m_value.m_ref; + + if(a_key->IsReference()) + { + hash >>= 2; // Remove 4 byte pointer alignment (may not be optimal) + } + + hash &= (unsigned int)(m_tableSize - 1); //mod/and to table size + + return &m_nodes[hash]; + } + + + void Resize(gmMachine * a_machine); + void AllocSize(gmMachine * a_machine, int a_size); + + gmTableNode * m_nodes; + gmTableNode * m_firstFree; + int m_tableSize; + int m_slotsUsed; +}; + +#endif // _GMTABLEOBJECT_H_ diff --git a/vscript/languages/gm/src/gm/gmThread.cpp b/vscript/languages/gm/src/gm/gmThread.cpp new file mode 100644 index 00000000..ed8c0fad --- /dev/null +++ b/vscript/languages/gm/src/gm/gmThread.cpp @@ -0,0 +1,1192 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmThread.h" +#include "gmByteCode.h" +#include "gmMachine.h" +#include "gmFunctionObject.h" +#include "gmOperators.h" +#include "gmMachineLib.h" + +// helper macros + +#define OPCODE_PTR(I) *((gmptr *) (I)); (I) += sizeof(gmptr); +#define OPCODE_PTR_NI(I) *((gmptr *) I); +#define OPCODE_FLOAT(I) *((gmfloat *) I); I += sizeof(gmfloat); +#define OPERATOR(TYPE, OPERATOR) (m_machine->GetTypeNativeOperator((TYPE), (OPERATOR))) +#define CALLOPERATOR(TYPE, OPERATOR) (m_machine->GetTypeOperator((TYPE), (OPERATOR))) +#define GMTHREAD_LOG m_machine->GetLog().LogEntry +#define PUSHNULL top->m_type = GM_NULL; top->m_value.m_int = 0; ++top; + +// helper functions +void gmGetLineFromString(const char * a_string, int a_line, char * a_buffer, int a_len) +{ + const char * cp = a_string, * eol; + int line = 1; + while(a_line > line) + { + while(*cp && *cp != '\n' && *cp != '\r') ++cp; + if(*cp == '\n') { ++cp; while(*cp == '\r') ++cp; ++line; } + else if(*cp == '\r') { ++cp; if(*cp == '\n') ++cp; ++line; } + if(*cp == '\0') { a_buffer[0] = '\0'; return; } + } + + eol = cp; + while(*eol && *eol != '\n' && *eol != '\r') ++eol; + int len = eol - cp; + len = ((a_len - 1) < len) ? (a_len - 1) : len; + memcpy(a_buffer, cp, len); + a_buffer[len] = '\0'; +} + +// +// +// Implementation of gmThread +// +// + +gmThread::gmThread(gmMachine * a_machine, int a_initialByteSize) +{ + m_frame = NULL; + m_machine = a_machine; + m_size = a_initialByteSize / sizeof(gmVariable); + m_stack = GM_NEW( gmVariable[m_size] ); + m_top = 0; + m_base = 0; + m_numParameters = 0; +#if GMDEBUG_SUPPORT + m_debugUser = 0; + m_debugFlags = 0; +#endif // GMDEBUG_SUPPORT + + m_timeStamp = 0; + m_startTime = 0; + m_instruction = NULL; + m_state = KILLED; + m_id = GM_INVALID_THREAD; + m_blocks = NULL; + m_signals = NULL; + + m_user = 0; +} + + + +gmThread::~gmThread() +{ + Sys_Reset(0); + if(m_stack) + { + delete [] m_stack; + } +} + + +#if GM_USE_INCGC +void gmThread::GCScanRoots(gmMachine* a_machine, gmGarbageCollector* a_gc) +{ + // mark stack + int i; + for(i = 0; i < m_top; ++i) + { + if(m_stack[i].IsReference()) + { + gmObject * object = GM_MOBJECT(m_machine, m_stack[i].m_value.m_ref); + a_gc->GetNextObject(object); + } + } + + // mark signals + gmSignal * signal = m_signals; + while(signal) + { + if(signal->m_signal.IsReference()) + { + gmObject * object = GM_MOBJECT(m_machine, signal->m_signal.m_value.m_ref); + a_gc->GetNextObject(object); + } + signal = signal->m_nextSignal; + } + + // mark blocks + gmBlock * block = m_blocks; + while(block) + { + if(block->m_block.IsReference()) + { + gmObject * object = GM_MOBJECT(m_machine, block->m_block.m_value.m_ref); + a_gc->GetNextObject(object); + } + block = block->m_nextBlock; + } +} +#else //GM_USE_INCGC +void gmThread::Mark(gmuint32 a_mark) +{ + // mark stack + int i; + for(i = 0; i < m_top; ++i) + { + if(m_stack[i].IsReference()) + { + gmObject * object = GM_MOBJECT(m_machine, m_stack[i].m_value.m_ref); + if(object->NeedsMark(a_mark)) object->Mark(m_machine, a_mark); + } + } + + // mark signals + gmSignal * signal = m_signals; + while(signal) + { + if(signal->m_signal.IsReference()) + { + gmObject * object = GM_MOBJECT(m_machine, signal->m_signal.m_value.m_ref); + if(object->NeedsMark(a_mark)) object->Mark(m_machine, a_mark); + } + signal = signal->m_nextSignal; + } + + // mark blocks + gmBlock * block = m_blocks; + while(block) + { + if(block->m_block.IsReference()) + { + gmObject * object = GM_MOBJECT(m_machine, block->m_block.m_value.m_ref); + if(object->NeedsMark(a_mark)) object->Mark(m_machine, a_mark); + } + block = block->m_nextBlock; + } +} +#endif //GM_USE_INCGC + +// RAGE AGAINST THE VIRTUAL MACHINE =) +gmThread::State gmThread::Sys_Execute(gmVariable * a_return) +{ + register union + { + const gmuint8 * instruction; + const gmuint32 * instruction32; + }; + register gmVariable * top; + gmVariable * base; + gmVariable * operand; + const gmuint8 * code; + + if(m_state != RUNNING) return m_state; + +#if GMDEBUG_SUPPORT + + if(m_debugFlags && m_machine->GetDebugMode() && m_machine->m_isBroken) + { + if(m_machine->m_isBroken(this)) + return RUNNING; + } + +#endif // GMDEBUG_SUPPORT + + // make sure we have a stack frame + GM_ASSERT(m_frame); + GM_ASSERT(GetFunction()->m_type == GM_FUNCTION); + + // cache our "registers" + gmFunctionObject * fn = (gmFunctionObject *) GM_MOBJECT(m_machine, GetFunction()->m_value.m_ref); + code = (const gmuint8 *) fn->GetByteCode(); + if(m_instruction == NULL) instruction = code; + else instruction = m_instruction; + top = GetTop(); + base = GetBase(); + + // + // start byte code execution + // + for(;;) + { + +#ifdef GM_CHECK_USER_BREAK_CALLBACK // This may be defined in gmConfig_p.h + // Check external source to break execution with exception eg. Check for CTRL-BREAK + // Endless loop protection could be implemented with this, or in a similar manner. + if( gmMachine::s_userBreakCallback && gmMachine::s_userBreakCallback(this) ) + { + GMTHREAD_LOG("User break. Execution halted."); + goto LabelException; + } +#endif //GM_CHECK_USER_BREAK_CALLBACK + + switch(*(instruction32++)) + { + // + // unary operator + // + + case BC_BIT_INV : + case BC_OP_NEG : + case BC_OP_POS : + case BC_OP_NOT : + { + operand = top - 1; + gmOperatorFunction op = OPERATOR(operand->m_type, (gmOperator) instruction32[-1]); + if(op) + { + op(this, operand); + } + else if((fn = CALLOPERATOR(operand->m_type, (gmOperator) instruction32[-1]))) + { + operand[2] = operand[0]; + operand[0] = gmVariable(GM_NULL, 0); + operand[1] = gmVariable(GM_FUNCTION, fn->GetRef()); + SetTop(operand + 3); + State res = PushStackFrame(1, &instruction, &code); + top = GetTop(); + base = GetBase(); + if(res == RUNNING) break; + if(res == SYS_YIELD) return RUNNING; + if(res == SYS_EXCEPTION) goto LabelException; + if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread + return res; + } + else + { + GMTHREAD_LOG("unary operator %s undefined for type %s", gmGetOperatorName((gmOperator) instruction32[-1]), m_machine->GetTypeName(operand->m_type)); + goto LabelException; + } + break; + } + + // + // operator + // + + case BC_OP_ADD : + case BC_OP_SUB : + case BC_OP_MUL : + case BC_OP_DIV : + case BC_OP_REM : + case BC_BIT_OR : + case BC_BIT_XOR : + case BC_BIT_AND : + case BC_BIT_SHL : + case BC_BIT_SHR : + case BC_OP_LT : + case BC_OP_GT : + case BC_OP_LTE : + case BC_OP_GTE : + case BC_OP_EQ : + case BC_OP_NEQ : + case BC_GETIND : + { + operand = top - 2; + --top; + register gmType t1 = operand[1].m_type; + if(operand->m_type > t1) t1 = operand->m_type; + gmOperatorFunction op = OPERATOR(t1, (gmOperator) instruction32[-1]); + if(op) + { + op(this, operand); + } + else if((fn = CALLOPERATOR(t1, (gmOperator) instruction32[-1]))) + { + operand[2] = operand[0]; + operand[3] = operand[1]; + operand[0] = gmVariable(GM_NULL, 0); + operand[1] = gmVariable(GM_FUNCTION, fn->GetRef()); + SetTop(operand + 4); + State res = PushStackFrame(2, &instruction, &code); + top = GetTop(); + base = GetBase(); + if(res == RUNNING) break; + if(res == SYS_YIELD) return RUNNING; + if(res == SYS_EXCEPTION) goto LabelException; + if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread + return res; + } + else + { + GMTHREAD_LOG("operator %s undefined for type %s and %s", gmGetOperatorName((gmOperator) instruction32[-1]), m_machine->GetTypeName(operand->m_type), m_machine->GetTypeName((operand + 1)->m_type)); + goto LabelException; + } + + break; + } + case BC_SETIND : + { + operand = top - 3; + top -= 3; + gmOperatorFunction op = OPERATOR(operand->m_type, O_SETIND); + if(op) + { + op(this, operand); + } + else if((fn = CALLOPERATOR(operand->m_type, O_SETIND))) + { + operand[4] = operand[2]; + operand[3] = operand[1]; + operand[2] = operand[0]; + operand[0] = gmVariable(GM_NULL, 0); + operand[1] = gmVariable(GM_FUNCTION, fn->GetRef()); + SetTop(operand + 5); + State res = PushStackFrame(3, &instruction, &code); + top = GetTop(); + base = GetBase(); + if(res == RUNNING) break; + if(res == SYS_YIELD) return RUNNING; + if(res == SYS_EXCEPTION) goto LabelException; + if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread + return res; + } + else + { + GMTHREAD_LOG("setind failed."); + goto LabelException; + } + break; + } + case BC_NOP : + { + break; + } + case BC_LINE : + { + +#if GMDEBUG_SUPPORT + + if(m_machine->GetDebugMode() && m_machine->m_line) + { + SetTop(top); + m_instruction = instruction; + if(m_machine->m_line(this)) return RUNNING; + } + +#endif // GMDEBUG_SUPPORT + + break; + } + case BC_GETDOT : + { + operand = top - 1; + gmptr member = OPCODE_PTR(instruction); + top->m_type = GM_STRING; + top->m_value.m_ref = member; + gmType t1 = operand->m_type; + gmOperatorFunction op = OPERATOR(t1, O_GETDOT); + if(op) + { + op(this, operand); + if(operand->m_type) break; + } + if(t1 == GM_NULL) + { + GMTHREAD_LOG("getdot failed."); + goto LabelException; + } + *operand = m_machine->GetTypeVariable(t1, gmVariable(GM_STRING, member)); + break; + } + case BC_SETDOT : + { + operand = top - 2; + gmptr member = OPCODE_PTR(instruction); + top->m_type = GM_STRING; + top->m_value.m_ref = member; + top -= 2; + gmOperatorFunction op = OPERATOR(operand->m_type, O_SETDOT); + if(op) + { + op(this, operand); + } + else + { + GMTHREAD_LOG("setdot failed."); + goto LabelException; + } + break; + } + case BC_BRA : + { + instruction = code + OPCODE_PTR_NI(instruction); + break; + } + case BC_BRZ : + { +#if GM_BOOL_OP + operand = top - 1; + --top; + if (operand->m_type > GM_USER) + { + // Look for overridden operator. + gmOperatorFunction op = OPERATOR(operand->m_type, O_BOOL); + + if (op) + { + op(this, operand); + } + else if ((fn = CALLOPERATOR(operand->m_type, O_BOOL))) + { + operand[2] = operand[0]; + operand[0] = gmVariable(GM_NULL, 0); + operand[1] = gmVariable(GM_FUNCTION, fn->GetRef()); + SetTop(operand + 3); + // Return to the same instruction after making the call but it will be testing the results of the call. + --instruction32; + State res = PushStackFrame(1, &instruction, &code); + top = GetTop(); + base = GetBase(); + if(res == RUNNING) break; + if(res == SYS_YIELD) return RUNNING; + if(res == SYS_EXCEPTION) goto LabelException; + if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread + return res; + } + } + + if(operand->m_value.m_int == 0) + { + instruction = code + OPCODE_PTR_NI(instruction); + } + else instruction += sizeof(gmptr); +#else // !GM_BOOL_OP + --top; + if(top->m_value.m_int == 0) + { + instruction = code + OPCODE_PTR_NI(instruction); + } + else instruction += sizeof(gmptr); +#endif // !GM_BOOL_OP + break; + } + case BC_BRNZ : + { +#if GM_BOOL_OP + operand = top - 1; + --top; + if (operand->m_type > GM_USER) + { + // Look for overridden operator. + gmOperatorFunction op = OPERATOR(operand->m_type, O_BOOL); + + if (op) + { + op(this, operand); + } + else if ((fn = CALLOPERATOR(operand->m_type, O_BOOL))) + { + operand[2] = operand[0]; + operand[0] = gmVariable(GM_NULL, 0); + operand[1] = gmVariable(GM_FUNCTION, fn->GetRef()); + SetTop(operand + 3); + // Return to the same instruction after making the call but it will be testing the results of the call. + --instruction32; + State res = PushStackFrame(1, &instruction, &code); + top = GetTop(); + base = GetBase(); + if(res == RUNNING) break; + if(res == SYS_YIELD) return RUNNING; + if(res == SYS_EXCEPTION) goto LabelException; + if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread + return res; + } + } + + if(operand->m_value.m_int != 0) + { + instruction = code + OPCODE_PTR_NI(instruction); + } + else instruction += sizeof(gmptr); +#else // !GM_BOOL_OP + --top; + if(top->m_value.m_int != 0) + { + instruction = code + OPCODE_PTR_NI(instruction); + } + else instruction += sizeof(gmptr); +#endif // !GM_BOOL_OP + break; + } + case BC_BRZK : + { +#if GM_BOOL_OP + operand = top - 1; + if (operand->m_type > GM_USER) + { + // Look for overridden operator. + gmOperatorFunction op = OPERATOR(operand->m_type, O_BOOL); + + if (op) + { + op(this, operand); + } + else if ((fn = CALLOPERATOR(operand->m_type, O_BOOL))) + { + operand[2] = operand[0]; + operand[0] = gmVariable(GM_NULL, 0); + operand[1] = gmVariable(GM_FUNCTION, fn->GetRef()); + SetTop(operand + 3); + // Return to the same instruction after making the call but it will be testing the results of the call. + --instruction32; + State res = PushStackFrame(1, &instruction, &code); + top = GetTop(); + base = GetBase(); + if(res == RUNNING) break; + if(res == SYS_YIELD) return RUNNING; + if(res == SYS_EXCEPTION) goto LabelException; + if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread + return res; + } + } + + if(operand->m_value.m_int == 0) + { + instruction = code + OPCODE_PTR_NI(instruction); + } + else instruction += sizeof(gmptr); +#else // !GM_BOOL_OP + if(top[-1].m_value.m_int == 0) + { + instruction = code + OPCODE_PTR_NI(instruction); + } + else instruction += sizeof(gmptr); +#endif // !GM_BOOL_OP + break; + } + case BC_BRNZK : + { +#if GM_BOOL_OP + operand = top - 1; + if (operand->m_type > GM_USER) + { + // Look for overridden operator. + gmOperatorFunction op = OPERATOR(operand->m_type, O_BOOL); + + if (op) + { + op(this, operand); + } + else if ((fn = CALLOPERATOR(operand->m_type, O_BOOL))) + { + operand[2] = operand[0]; + operand[0] = gmVariable(GM_NULL, 0); + operand[1] = gmVariable(GM_FUNCTION, fn->GetRef()); + SetTop(operand + 3); + // Return to the same instruction after making the call but it will be testing the results of the call. + --instruction32; + State res = PushStackFrame(1, &instruction, &code); + top = GetTop(); + base = GetBase(); + if(res == RUNNING) break; + if(res == SYS_YIELD) return RUNNING; + if(res == SYS_EXCEPTION) goto LabelException; + if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread + return res; + } + } + + if(operand->m_value.m_int != 0) + { + instruction = code + OPCODE_PTR_NI(instruction); + } + else instruction += sizeof(gmptr); +#else // !GM_BOOL_OP + if(top[-1].m_value.m_int != 0) + { + instruction = code + OPCODE_PTR_NI(instruction); + } + else instruction += sizeof(gmptr); +#endif // !GM_BOOL_OP + break; + } + case BC_CALL : + { + SetTop(top); + + int numParams = (int) OPCODE_PTR(instruction); + + State res = PushStackFrame(numParams, &instruction, &code); + top = GetTop(); + base = GetBase(); + + if(res == RUNNING) + { + +#if GMDEBUG_SUPPORT + + if(m_debugFlags && m_machine->GetDebugMode() && m_machine->m_call) + { + m_instruction = instruction; + if(m_machine->m_call(this)) return RUNNING; + } + +#endif // GMDEBUG_SUPPORT + + break; + } + if(res == SYS_YIELD) return RUNNING; + if(res == SYS_EXCEPTION) goto LabelException; + if(res == KILLED) + { + if(a_return) *a_return = m_stack[m_top - 1]; + m_machine->Sys_SwitchState(this, KILLED); + } + return res; + } + case BC_RET : + { + PUSHNULL; + } + case BC_RETV : + { + SetTop(top); + int res = Sys_PopStackFrame(instruction, code); + top = GetTop(); + base = GetBase(); + + if(res == RUNNING) + { + +#if GMDEBUG_SUPPORT + + if(m_debugFlags && m_machine->GetDebugMode() && m_machine->m_return) + { + m_instruction = instruction; + if(m_machine->m_return(this)) return RUNNING; + } + +#endif // GMDEBUG_SUPPORT + + break; + } + if(res == KILLED) + { + if(a_return) *a_return = *(top - 1); + m_machine->Sys_SwitchState(this, KILLED); + return KILLED; + } + if(res == SYS_EXCEPTION) goto LabelException; + break; + } + case BC_FOREACH : + { + gmuint32 localvalue = OPCODE_PTR(instruction); + gmuint32 localkey = localvalue >> 16; + localvalue &= 0xffff; + + // iterator is at tos-1, table is at tos -2, push int 1 if continuing loop. write key and value into localkey and localvalue + if(top[-2].m_type != GM_TABLE) + { + GMTHREAD_LOG("foreach expression is not table type"); + goto LabelException; + } + GM_ASSERT(top[-1].m_type == GM_INT); + gmTableIterator it = (gmTableIterator) top[-1].m_value.m_int; + gmTableObject * table = (gmTableObject *) GM_MOBJECT(m_machine, top[-2].m_value.m_ref); + gmTableNode * node = table->GetNext(it); + top[-1].m_value.m_int = it; + if(node) + { + base[localkey] = node->m_key; + base[localvalue] = node->m_value; + top->m_type = GM_INT; top->m_value.m_int = 1; + } + else + { + top->m_type = GM_INT; top->m_value.m_int = 0; + } + ++top; + break; + } + case BC_POP : + { + --top; + break; + } + case BC_POP2 : + { + top -= 2; + break; + } + case BC_DUP : + { + top[0] = top[-1]; + ++top; + break; + } + case BC_DUP2 : + { + top[0] = top[-2]; + top[1] = top[-1]; + top += 2; + break; + } + case BC_SWAP : + { + top[0] = top[-1]; + top[-1] = top[-2]; + top[-2] = top[0]; + break; + } + case BC_PUSHNULL : + { + PUSHNULL; + break; + } + case BC_PUSHINT : + { + top->m_type = GM_INT; + top->m_value.m_int = OPCODE_PTR(instruction); + ++top; + break; + } + case BC_PUSHINT0 : + { + top->m_type = GM_INT; + top->m_value.m_int = 0; + ++top; + break; + } + case BC_PUSHINT1 : + { + top->m_type = GM_INT; + top->m_value.m_int = 1; + ++top; + break; + } + case BC_PUSHFP : + { + top->m_type = GM_FLOAT; + top->m_value.m_float = OPCODE_FLOAT(instruction); + ++top; + break; + } + case BC_PUSHSTR : + { + top->m_type = GM_STRING; + top->m_value.m_ref = OPCODE_PTR(instruction); + ++top; + break; + } + case BC_PUSHTBL : + { + SetTop(top); + top->m_type = GM_TABLE; + top->m_value.m_ref = m_machine->AllocTableObject()->GetRef(); + ++top; + break; + } + case BC_PUSHFN : + { + top->m_type = GM_FUNCTION; + top->m_value.m_ref = OPCODE_PTR(instruction); + ++top; + break; + } + case BC_PUSHTHIS : + { + *top = *GetThis(); + ++top; + break; + } + case BC_GETLOCAL : + { + gmuint32 offset = OPCODE_PTR(instruction); + *(top++) = base[offset]; + break; + } + case BC_SETLOCAL : + { + gmuint32 offset = OPCODE_PTR(instruction); + base[offset] = *(--top); + break; + } + case BC_GETGLOBAL : + { + top->m_type = GM_STRING; + top->m_value.m_ref = OPCODE_PTR(instruction); + gmTableObject *pTable = m_machine->GetGlobals(); + gmVariable globalVar = pTable->Get(*top); + + if ( globalVar.IsNull() && pTable != m_machine->GetTrueGlobals()) + { + pTable = m_machine->GetTrueGlobals(); + globalVar = pTable->Get(*top); + } + *top = globalVar; + ++top; + + break; + } + case BC_SETGLOBAL : + { + top->m_type = GM_STRING; + top->m_value.m_ref = OPCODE_PTR(instruction); + m_machine->GetGlobals()->Set(m_machine, *top, *(top-1)); --top; + break; + } + case BC_GETTHIS : + { + gmptr member = OPCODE_PTR(instruction); + const gmVariable * thisVar = GetThis(); + *top = *thisVar; + top[1].m_type = GM_STRING; + top[1].m_value.m_ref = member; + gmOperatorFunction op = OPERATOR(thisVar->m_type, O_GETDOT); + if(op) + { + op(this, top); + if(top->m_type) { ++top; break; } + } + if(thisVar->m_type == GM_NULL) + { + GMTHREAD_LOG("getthis failed. this is null"); + goto LabelException; + } + *top = m_machine->GetTypeVariable(thisVar->m_type, top[1]); + ++top; + break; + } + case BC_SETTHIS : + { + gmptr member = OPCODE_PTR(instruction); + const gmVariable * thisVar = GetThis(); + operand = top - 1; + *top = *operand; + *operand = *thisVar; + top[1].m_type = GM_STRING; + top[1].m_value.m_ref = member; + --top; + gmOperatorFunction op = OPERATOR(thisVar->m_type, O_SETDOT); + if(op) + { + op(this, operand); + } + else + { + GMTHREAD_LOG("setthis failed."); + goto LabelException; + } + break; + } + default : + { + break; + } + } + } + +LabelException: + + // + // exception handler + // + m_instruction = instruction; + + // spit out error info + LogLineFile(); + LogCallStack(); + + // call machine exception handler + if(gmMachine::s_machineCallback) + { + if(gmMachine::s_machineCallback(m_machine, MC_THREAD_EXCEPTION, this)) + { +#if GMDEBUG_SUPPORT + // if we are being debugged, put this thread into a limbo state, waiting for delete. + if(m_machine->GetDebugMode() && m_machine->m_debugUser) + { + m_machine->Sys_SwitchState(this, EXCEPTION); + return EXCEPTION; + } +#endif + } + } + + // kill the thread + m_machine->Sys_SwitchState(this, KILLED); + return KILLED; +} + + + +void gmThread::Sys_Reset(int a_id) +{ + m_machine->Sys_RemoveBlocks(this); + m_machine->Sys_RemoveSignals(this); + + gmStackFrame * frame; + while(m_frame) + { + frame = m_frame->m_prev; + m_machine->Sys_FreeStackFrame(m_frame); + m_frame = frame; + } + m_top = 0; + m_base = 0; + m_instruction = NULL; + m_timeStamp = 0; + m_startTime = 0; + m_id = a_id; + m_numParameters = 0; + m_user = 0; +} + + + +gmThread::State gmThread::PushStackFrame(int a_numParameters, const gmuint8 ** a_ip, const gmuint8 ** a_cp) +{ + // calculate new stack base + int base = m_top - a_numParameters; + + if( base == 2 ) // When initial thread function is ready, signal thread creation + { + // This may not be the best place to signal, but we at least want a valid 'this' + m_base = base; // Init so some thread queries work + m_machine->Sys_SignalCreateThread(this); + } + + gmVariable * fnVar = &m_stack[base - 1]; + if(fnVar->m_type != GM_FUNCTION) + { + m_machine->GetLog().LogEntry("attempt to call non function type"); + return SYS_EXCEPTION; + } + gmFunctionObject * fn = (gmFunctionObject *) GM_MOBJECT(m_machine, fnVar->m_value.m_ref); + + if(fn->m_cFunction) + { + // + // Its a native function call, call it now as we cannot stack wind natives. this avoids + // pushing a gmStackFrame. + // + + m_numParameters = (short) a_numParameters; + int lastBase = m_base; + int lastTop = m_top; + m_base = base; + + int result = fn->m_cFunction(this); + + // handle state + if(result == GM_SYS_STATE) + { + // this is special case, a bit messy. + return PushStackFrame(a_numParameters - GM_STATE_NUM_PARAMS, a_ip, a_cp); + } + + // NOTE: It is not currently safe for a C binding to kill this thread. + // Since we cant unwind mixed script and native functions anyway, + // perhaps the safest thing would be for ALWAYS delay killed threads + // from deletion. + + // push a null if the function did not return anything + if(lastTop == m_top) + { + m_stack[m_base - 2] = gmVariable(GM_NULL, 0); + } + else + { + m_stack[m_base - 2] = m_stack[m_top - 1]; + } + + // Restore the stack + m_top = m_base - 1; + m_base = lastBase; + + // check the call result + if(result != GM_OK) + { + const gmuint8 * returnAddress = (a_ip) ? *a_ip : NULL; + + if(result == GM_SYS_YIELD) + { + m_machine->Sys_RemoveSignals(this); + m_instruction = returnAddress; + return SYS_YIELD; + } + else if(result == GM_SYS_BLOCK) + { + m_instruction = returnAddress; + m_machine->Sys_SwitchState(this, BLOCKED); + return BLOCKED; + } + else if(result == GM_SYS_SLEEP) + { + m_instruction = returnAddress; + m_machine->Sys_SwitchState(this, SLEEPING); + return SLEEPING; + } + else if(result == GM_SYS_KILL) + { + return KILLED; + } + return SYS_EXCEPTION; + } + + if(!m_frame) // C called C function, no stack frame, so signal killed. + { + return KILLED; + } + + // return result + return RUNNING; + } + + // + // Its a script function call, push a stack frame + // + + int clearSize = fn->GetNumParamsLocals() - a_numParameters; + if(!Touch(clearSize + fn->GetMaxStackSize())) + { + m_machine->GetLog().LogEntry("stack overflow"); + return SYS_EXCEPTION; + } + + // zero missing params and locals. + if(a_numParameters <= fn->GetNumParams()) + { + memset(GetTop(), 0, sizeof(gmVariable) * clearSize); + } + else + { + memset(&m_stack[base + fn->GetNumParams()], 0, sizeof(gmVariable) * fn->GetNumLocals()); + } + + // push a new stack frame + gmStackFrame * frame = m_machine->Sys_AllocStackFrame(); + frame->m_prev = m_frame; + m_frame = frame; + + // cache new frame variables + m_frame->m_returnBase = m_base; + + if(a_ip) + { + m_frame->m_returnAddress = *a_ip; + *a_ip = (const gmuint8 *) fn->GetByteCode(); + *a_cp = *a_ip; + } + else + { + m_frame->m_returnAddress = NULL; + } + m_base = base; + m_top = base + fn->GetNumParamsLocals(); + + return RUNNING; +} + + + +gmThread::State gmThread::Sys_PopStackFrame(const gmuint8 * &a_ip, const gmuint8 * &a_cp) +{ + if(m_frame == NULL) + { + m_machine->GetLog().LogEntry("stack underflow"); + return SYS_EXCEPTION; + } + + gmStackFrame * frame = m_frame->m_prev; + if( frame == NULL ) // Final frame, we will exit now + { + return KILLED; // Don't clean up stack, let the machine reset it as state changes to killed (so Exit callback can examine valid thread contents) + } + a_ip = m_frame->m_returnAddress; + // Copy old tos to new tos + m_stack[m_base - 2] = m_stack[m_top - 1]; + m_top = m_base - 1; + m_base = m_frame->m_returnBase; + m_machine->Sys_FreeStackFrame(m_frame); + m_frame = frame; + + // Update instruction and code pointers + GM_ASSERT(GetFunction()->m_type == GM_FUNCTION); + gmFunctionObject * fn = (gmFunctionObject *) GM_MOBJECT(m_machine, GetFunction()->m_value.m_ref); + a_cp = (const gmuint8 *) fn->GetByteCode(); + + return RUNNING; +} + + + +void gmThread::LogLineFile() +{ + // spit out the source and line info for the exception. + if(m_base >= 2 && GetFunction()->m_type == GM_FUNCTION) + { + gmFunctionObject * fn = (gmFunctionObject *) GM_MOBJECT(m_machine, GetFunction()->m_value.m_ref); + if(fn) + { + int line = fn->GetLine(m_instruction); + gmuint32 id = fn->GetSourceId(); + const char * source, * filename; + if(m_machine->GetSourceCode(id, source, filename)) + { + char buffer[80]; + gmGetLineFromString(source, line, buffer, 80); + m_machine->GetLog().LogEntry(GM_NL"%s(%d) : %s", filename, line, buffer); + } + else + { + m_machine->GetLog().LogEntry(GM_NL"unknown(%d) : ", line); + } + } + } +} + + + +bool gmThread::Touch(int a_extra) +{ + // Grow stack if necessary. NOTE: Use better growth metric if needed. + bool reAlloc = false; + while((m_top + a_extra + GMTHREAD_SLACKSPACE) >= m_size) + { + if(sizeof(gmVariable) * m_size > GMTHREAD_MAXBYTESIZE) return false; + m_size *= 2; + reAlloc = true; + } + + if(reAlloc) + { + gmVariable * stack = new gmVariable[m_size]; + //memset(stack, 0, sizeof(gmVariable) * m_size); + memcpy(stack, m_stack, m_top * sizeof(gmVariable)); + if(m_stack) + delete[] m_stack; + m_stack = stack; + } + return true; +} + + + +void gmThread::LogCallStack() +{ + m_machine->GetLog().LogEntry(GM_NL"callstack.."); + gmStackFrame * frame = m_frame; + int base = m_base; + const gmuint8 * ip = m_instruction; + + while(frame) + { + // get the function object + gmVariable * fnVar = &m_stack[base - 1]; + if(fnVar->m_type == GM_FUNCTION) + { + gmFunctionObject * fn = (gmFunctionObject *) GM_MOBJECT(m_machine, fnVar->m_value.m_ref); + m_machine->GetLog().LogEntry("%3d: %s", fn->GetLine(ip), fn->GetDebugName()); + } + base = frame->m_returnBase; + ip = frame->m_returnAddress; + frame = frame->m_prev; + } + m_machine->GetLog().LogEntry(""); +} + diff --git a/vscript/languages/gm/src/gm/gmThread.h b/vscript/languages/gm/src/gm/gmThread.h new file mode 100644 index 00000000..e9dcedcd --- /dev/null +++ b/vscript/languages/gm/src/gm/gmThread.h @@ -0,0 +1,879 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMTHREAD_H_ +#define _GMTHREAD_H_ + +#include "gmConfig.h" +#include "gmListDouble.h" +#include "gmHash.h" +#include "gmVariable.h" +#include "gmMachine.h" +#include "gmStringObject.h" +#include "gmUserObject.h" + +class gmFunctionObject; +class gmStringObject; +class gmTableObject; +class gmUserObject; +class gmBlock; +struct gmSignal; + +#define GMTHREAD_SLACKSPACE 6 // floating slack space above tos for operator calls +#define GM_INVALID_THREAD 0 + +/// \struct gmStackFrame +/// \brief The stack order is as follows: this, fp, p0..pn-1, l0..ln-1. gmStackFrame objects are allocated from the gmMachine. +/// Base pointer is at the first parameter. +struct gmStackFrame +{ + gmStackFrame * m_prev; + const gmuint8 * m_returnAddress; + int m_returnBase; +}; + +/// \class gmThread +/// \brief gmThread.. try to keep this class's memory footprint small.. at the time of this comment, its +/// 76 bytes. +class gmThread : public gmListDoubleNode, public gmHashNode +{ +public: + gmThread(gmMachine * a_machine, int a_initialByteSize = GMTHREAD_INITIALBYTESIZE); + virtual ~gmThread(); + + enum State + { + RUNNING = 0, + SLEEPING, + BLOCKED, + KILLED, + + EXCEPTION, //!< exception state, for debugging + + SYS_PENDING, + SYS_YIELD, + SYS_EXCEPTION, + }; + + inline const int GetKey() const { return m_id; } + +#if GM_USE_INCGC + void GCScanRoots(gmMachine* a_machine, gmGarbageCollector* a_gc); +#else //GM_USE_INCGC + /// \brief Mark() will call Mark() for all objects in the stack. + void Mark(gmuint32 a_mark); +#endif //GM_USE_INCGC + + /// \brief Sys_Execute() will perform execution on this thread. a this, function references, params and stack + /// frame must be pushed before a call to execute will succeed. + /// \param a_return will be set to the return variable iff Sys_Execute returns gmThread::KILLED. + /// \return the new thread state. + State Sys_Execute(gmVariable * a_return = NULL); + + /// \brief Sys_Reset() will reset the thread. + void Sys_Reset(int a_id); + + /// \brief Sys_SetState() will set the thread state. + inline void Sys_SetState(State a_state) { m_state = a_state; } + + /// \brief PushStackFrame will push a stack frame and adjust the instruction and code pointers. + /// If the function to be called is a c bound function, the call will occur within PushStackFrame. + /// Before PushStackFrame is called, this, fp, and params must be pushed on the stack. + /// \param a_numParameters is the number of params pushed after the function ref. + /// \param a_ip is the current instruction pointer (pointing to instruction after call.) will be adjusted for new function. + /// \param a_cp is the current code pointer. will be adjusted for the new function. a_cp MUST be valid if a_ip is valid. + /// \return gmThreadState + State PushStackFrame(int a_numParameters, const gmuint8 ** a_ip = NULL, const gmuint8 ** a_cp = NULL); + + /// \brief GetTop() will return the top of stack + inline gmVariable * GetTop() const { return &m_stack[m_top]; } + + /// \brief GetBottom() will return the bottom of stact + inline gmVariable * GetBottom() const { return m_stack; } + + /// \brief SetTop() will set the top of stack + inline void SetTop(gmVariable * a_top) { m_top = a_top - m_stack; } + + /// \brief GetBase() will return the current stack base. + inline gmVariable * GetBase() const { return &m_stack[m_base]; } + inline int GetIntBase() const { return m_base; } + + /// \brief GetMachine() will return the stacks parent machine. + inline gmMachine * GetMachine() const { return m_machine; } + + /// \brief GetThis() will return the this variable for the current stack frame. + inline const gmVariable * GetThis() const { return &m_stack[m_base - 2]; } + + /// \brief GetFunction() will return the current executing function. + inline const gmVariable * GetFunction() const { return &m_stack[m_base - 1]; } + inline const gmFunctionObject * GetFunctionObject() const; + + /// \brief GetNumParams() returns the number parameters pushed into the current cFunction call. + inline int GetNumParams() const { return m_numParameters; } + + /// \brief GetFrame() will return the top stack frame. + inline const gmStackFrame * GetFrame() const { return m_frame; } + + // + // Push methods + // + + inline gmVariable &Pop() { return m_stack[--m_top]; } + inline void Push(const gmVariable &a_variable) { m_stack[m_top++] = a_variable; } + inline void PushNull(); + inline void PushInt(gmptr a_value); + inline void PushFloat(gmfloat a_value); + inline void PushString(gmStringObject * a_string); + inline void PushTable(gmTableObject * a_table); + inline void PushFunction(gmFunctionObject * a_function); + inline void PushUser(gmUserObject * a_user); + + inline gmStringObject * PushNewString(const char * a_value, int a_len = -1); //!< PushNewString() will push a new string object onto tos. + inline gmTableObject * PushNewTable(); //!< PushNewTable() will push a new table onto tos. + inline gmUserObject * PushNewUser(void * a_user, int a_userType); //!< PushNewUser() will push a new user object onto tos. + + // + // Parameter methods. (do not cause an error if the desired parameter is incorrect type) + // Versions that return bool return false if type was invalid, otherwise true, even if param was out of range. NOTE: Could switch to more complex return code, but user could simply check num params for range check if needed. + // + + inline int ParamInt(int a_param, gmptr a_default = 0) const; + inline bool ParamInt(int a_param, int& a_value, gmptr a_default = 0) const; + inline gmfloat ParamFloat(int a_param, gmfloat a_default = 0.0f) const; + inline bool ParamFloat(int a_param, gmfloat& a_value, gmfloat a_default = 0.0f) const; + inline gmfloat ParamFloatOrInt(int a_param, gmfloat a_default = 0.0f) const; + inline bool ParamFloatOrInt(int a_param, gmfloat& a_value, gmfloat a_default = 0.0f) const; + inline const char * ParamString(int a_param, const char * a_default = "") const; + inline bool ParamString(int a_param, const char *& a_value, const char * a_default = "") const; + inline gmStringObject * ParamStringObject(int a_param) const; + inline bool ParamStringObject(int a_param, gmStringObject *& a_value) const; + inline gmTableObject * ParamTable(int a_param) const; + inline bool ParamTable(int a_param, gmTableObject *& a_value ) const; + inline gmFunctionObject * ParamFunction(int a_param) const; + inline bool ParamFunction(int a_param, gmFunctionObject *& a_value) const; + inline void * ParamUser(int a_param, int * a_userType = NULL) const; + inline bool ParamUser(int a_param, void *& a_value, int * a_userType = NULL) const; + inline void * ParamUserCheckType(int a_param, int a_userType) const; + inline void * ParamUser_NoCheckTypeOrParam(int a_param) const; //For macro + inline gmUserObject * ParamUserObject(int a_param) const; + inline bool ParamUserObject(int a_param, gmUserObject *& a_value) const; + inline gmVariable& Param(int a_param); + inline const gmVariable& Param(int a_param) const; + inline gmVariable Param(int a_param, const gmVariable& a_default); + inline gmType ParamType(int a_param) const; + inline gmptr ParamRef(int a_param) const; + + // + // This methods. (get this as a given type) + // + + inline gmptr ThisInt(gmptr a_default = 0); + inline gmfloat ThisFloat(gmfloat a_default = 0.0f); + inline const char * ThisString(const char * a_default = ""); + inline gmTableObject * ThisTable(); + inline gmFunctionObject * ThisFunction(); + inline void * ThisUser(int * a_userType = NULL); + inline void * ThisUserCheckType(int a_userType); + inline void * ThisUser_NoChecks(); //For use with type functions where type is already certain + inline gmUserObject * ThisUserObject(); + + /// \brief Touch() will make sure that you can push a_extra variables on the stack + /// \return true on success + bool Touch(int a_extra); + + inline int GetId() const { return m_id; } + inline const gmuint8 * GetInstruction() const { return m_instruction; } + inline State GetState() const { return m_state; } + inline gmuint32 GetTimeStamp() const { return m_timeStamp; } + inline gmuint32 GetThreadTime() const { return m_machine->GetTime() - m_startTime; } + inline void Sys_SetTimeStamp(gmuint32 a_timeStamp) { m_timeStamp = a_timeStamp; } + inline void Sys_SetStartTime(gmuint32 a_startTime) { m_startTime = a_startTime; } + + /// \brief GetSystemMemUsed will return the number of bytes allocated by the system. + inline unsigned int GetSystemMemUsed() const { return (m_size * sizeof(gmVariable)) + sizeof(this); } + + void LogCallStack(); + + /// \brief Sys_SetBlocks() will set the blocking list for the thread. + inline void Sys_SetBlocks(gmBlock * a_block) { m_blocks = a_block; } + + /// \brief Sys_GetBlocks() will return the list of blocks on a thread + inline gmBlock * Sys_GetBlocks() { return m_blocks; } + + /// \brief Sys_SetSignals() will set the signal list for this thread + inline void Sys_SetSignals(gmSignal * a_signals) { m_signals = a_signals; } + + /// \brief Sys_GetSignals() will return the list of signals on a thread + inline gmSignal * Sys_GetSignals() { return m_signals; } + + // public data +#if GMDEBUG_SUPPORT + mutable int m_debugFlags; //!< non-zero when thread is being debugged + mutable int m_debugUser; +#endif // GMDEBUG_SUPPORT + mutable int m_user; + +private: + + /// \brief Sys_PopStackFrame() will pop a frame off the stack. + /// \param a_ip is the current instruction pointer (pointing to instruction after call.) will be adjusted for new function. + /// \param a_cp is the current code pointer. will be adjusted for the new function. + /// \return RUNNING, KILLED or SYS_EXCEPTION + State Sys_PopStackFrame(const gmuint8 * &a_ip, const gmuint8 * &a_cp); + + void LogLineFile(); + + // stack members + gmMachine * m_machine; + gmVariable * m_stack; + int m_size; + int m_top; + int m_base; + gmStackFrame * m_frame; + + // thread members + State m_state; + gmuint32 m_timeStamp; // wake up at this time stamp. + gmuint32 m_startTime; // time this thread was started. + const gmuint8 * m_instruction; + int m_id; + gmSignal * m_signals; // list of potentially active signals on this thread. + gmBlock * m_blocks; // list of active blocks when thread is in BLOCKED state. + short m_numParameters; +}; + + +// +// +// INLINE IMPLEMENTATION +// +// + + +inline const gmFunctionObject * gmThread::GetFunctionObject() const +{ + const gmVariable * fnVar = GetFunction(); + GM_ASSERT(fnVar->m_type == GM_FUNCTION); + return (gmFunctionObject *) m_machine->GetObject(fnVar->m_value.m_ref); +} + +// +// Push methods +// + +inline void gmThread::PushNull() +{ + m_stack[m_top].m_type = GM_NULL; + m_stack[m_top++].m_value.m_int = 0; +} + + +inline void gmThread::PushInt(gmptr a_value) +{ + m_stack[m_top].m_type = GM_INT; + m_stack[m_top++].m_value.m_int = a_value; +} + + +inline void gmThread::PushFloat(gmfloat a_value) +{ + m_stack[m_top].m_type = GM_FLOAT; + m_stack[m_top++].m_value.m_float = a_value; +} + + +inline void gmThread::PushString(gmStringObject * a_string) +{ + m_stack[m_top].m_type = GM_STRING; + m_stack[m_top++].m_value.m_ref = (gmptr) a_string; +} + + +inline void gmThread::PushTable(gmTableObject * a_table) +{ + m_stack[m_top].m_type = GM_TABLE; + m_stack[m_top++].m_value.m_ref = (gmptr) a_table; +} + + +inline void gmThread::PushFunction(gmFunctionObject * a_function) +{ + m_stack[m_top].m_type = GM_FUNCTION; + m_stack[m_top++].m_value.m_ref = (gmptr) a_function; +} + + +inline void gmThread::PushUser(gmUserObject * a_user) +{ + m_stack[m_top].m_type = (gmType)a_user->GetType(); + m_stack[m_top++].m_value.m_ref = a_user->GetRef(); +} + + +gmStringObject * gmThread::PushNewString(const char * a_value, int a_len) +{ + m_stack[m_top].m_type = GM_STRING; + return (gmStringObject *) (m_stack[m_top++].m_value.m_ref = (gmptr) m_machine->AllocStringObject(a_value, a_len)); +} + + +gmTableObject * gmThread::PushNewTable() +{ + m_stack[m_top].m_type = GM_TABLE; + return (gmTableObject *) (m_stack[m_top++].m_value.m_ref = (gmptr) m_machine->AllocTableObject()); +} + + +gmUserObject * gmThread::PushNewUser(void * a_user, int a_userType) +{ + m_stack[m_top].m_type = (gmType) a_userType; + return (gmUserObject *) (m_stack[m_top++].m_value.m_ref = (gmptr) m_machine->AllocUserObject(a_user, a_userType)); +} + +// +// Parameter methods. (do not cause an error if the desired parameter is incorrect type) +// + +inline int gmThread::ParamInt(int a_param, gmptr a_default) const +{ + if(a_param >= m_numParameters) return a_default; + gmVariable * var = m_stack + m_base + a_param; + if(var->m_type == GM_INT) return var->m_value.m_int; + return a_default; +} + +inline bool gmThread::ParamInt(int a_param, int& a_value, gmptr a_default) const +{ + // Out of range + if( a_param >= m_numParameters ) + { + a_value = a_default; + return true; + } + // Valid + gmVariable * var = m_stack + m_base + a_param; + if( var->m_type == GM_INT ) + { + a_value = var->m_value.m_int; + return true; + } + // Invalid + a_value = a_default; + return false; +} + + +inline gmfloat gmThread::ParamFloat(int a_param, gmfloat a_default) const +{ + if(a_param >= m_numParameters) return a_default; + gmVariable * var = m_stack + m_base + a_param; + if(var->m_type == GM_FLOAT) return var->m_value.m_float; + return a_default; +} + +inline bool gmThread::ParamFloat(int a_param, gmfloat& a_value, gmfloat a_default) const +{ + // Out of range + if( a_param >= m_numParameters ) + { + a_value = a_default; + return true; + } + // Valid + gmVariable * var = m_stack + m_base + a_param; + if( var->m_type == GM_FLOAT ) + { + a_value = var->m_value.m_float; + return true; + } + // Invalid + a_value = a_default; + return false; +} + +inline gmfloat gmThread::ParamFloatOrInt(int a_param, gmfloat a_default) const +{ + if(a_param >= m_numParameters) return a_default; + gmVariable * var = m_stack + m_base + a_param; + if(var->m_type == GM_FLOAT) + { return var->m_value.m_float; } + else if(var->m_type == GM_INT) + { return (gmfloat)var->m_value.m_int; } + return a_default; +} + +inline bool gmThread::ParamFloatOrInt(int a_param, gmfloat& a_value, gmfloat a_default) const +{ + // Out of range + if( a_param >= m_numParameters ) + { + a_value = a_default; + return true; + } + // Valid + gmVariable * var = m_stack + m_base + a_param; + if( var->m_type == GM_FLOAT ) + { + a_value = var->m_value.m_float; + return true; + } + else if(var->m_type == GM_INT) + { + a_value = (gmfloat)var->m_value.m_int; + return true; + } + // Invalid + a_value = a_default; + return false; +} + +const char * gmThread::ParamString(int a_param, const char * a_default) const +{ + if(a_param >= m_numParameters) return a_default; + gmVariable * var = m_stack + m_base + a_param; + if(var->m_type == GM_STRING) + { + return (const char *) *((gmStringObject *) m_machine->GetObject(var->m_value.m_ref)); + } + return a_default; +} + +bool gmThread::ParamString(int a_param, const char *& a_value, const char * a_default) const +{ + // Out of range + if( a_param >= m_numParameters) + { + a_value = a_default; + return true; + } + // Valid + gmVariable * var = m_stack + m_base + a_param; + if( var->m_type == GM_STRING ) + { + a_value = (const char *) *((gmStringObject *) m_machine->GetObject(var->m_value.m_ref)); + return true; + } + // Invalid + a_value = a_default; + return false; +} + + +gmStringObject * gmThread::ParamStringObject(int a_param) const +{ + if(a_param >= m_numParameters) return NULL; + gmVariable * var = m_stack + m_base + a_param; + if(var->m_type == GM_STRING) + { + return (gmStringObject *) m_machine->GetObject(var->m_value.m_ref); + } + return NULL; +} + +bool gmThread::ParamStringObject(int a_param, gmStringObject *& a_value) const +{ + // Out of range + if( a_param >= m_numParameters ) + { + a_value = NULL; + return true; + } + // Valid + gmVariable * var = m_stack + m_base + a_param; + if(var->m_type == GM_STRING) + { + a_value = (gmStringObject *) m_machine->GetObject(var->m_value.m_ref); + return true; + } + // Invalid + a_value = NULL; + return false; +} + +gmTableObject * gmThread::ParamTable(int a_param) const +{ + if(a_param >= m_numParameters) return NULL; + gmVariable * var = m_stack + m_base + a_param; + if(var->m_type == GM_TABLE) + { + return (gmTableObject *) m_machine->GetObject(var->m_value.m_ref); + } + return NULL; +} + +bool gmThread::ParamTable(int a_param, gmTableObject *& a_value ) const +{ + // Out of range + if( a_param >= m_numParameters ) + { + a_value = NULL; + return true; + } + // Valid + gmVariable * var = m_stack + m_base + a_param; + if( var->m_type == GM_TABLE ) + { + a_value = (gmTableObject *) m_machine->GetObject(var->m_value.m_ref); + return true; + } + // Invalid + a_value = NULL; + return false; +} + + +gmFunctionObject * gmThread::ParamFunction(int a_param) const +{ + if(a_param >= m_numParameters) return NULL; + gmVariable * var = m_stack + m_base + a_param; + if(var->m_type == GM_FUNCTION) + { + return (gmFunctionObject *) m_machine->GetObject(var->m_value.m_ref); + } + return NULL; +} + + +bool gmThread::ParamFunction(int a_param, gmFunctionObject *& a_value) const +{ + // Out of range + if( a_param >= m_numParameters ) + { + a_value = NULL; + return true; + } + // Valid + gmVariable * var = m_stack + m_base + a_param; + if( var->m_type == GM_FUNCTION ) + { + a_value = (gmFunctionObject *) m_machine->GetObject(var->m_value.m_ref); + return true; + } + // Invalid + a_value = NULL; + return false; +} + +void * gmThread::ParamUser(int a_param, int * a_userType) const +{ + if(a_param >= m_numParameters) return NULL; + gmVariable * var = m_stack + m_base + a_param; + if(var->m_type >= GM_USER) + { + gmUserObject * user = (gmUserObject *) m_machine->GetObject(var->m_value.m_ref); + GM_ASSERT(var->m_type == user->m_userType); + if(a_userType) + { + *a_userType = user->m_userType; + } + return user->m_user; + } + return NULL; +} + +bool gmThread::ParamUser(int a_param, void *& a_value, int * a_userType) const +{ + // Out of range + if( a_param >= m_numParameters ) + { + a_value = NULL; + return true; + } + // Valid + gmVariable * var = m_stack + m_base + a_param; + if( var->m_type >= GM_USER ) + { + gmUserObject * user = (gmUserObject *) m_machine->GetObject(var->m_value.m_ref); + GM_ASSERT( var->m_type == user->m_userType ); + if( a_userType ) + { + *a_userType = user->m_userType; + } + a_value = user->m_user; + return true; + } + // Invalid + a_value = NULL; + return false; +} + +void * gmThread::ParamUserCheckType(int a_param, int a_userType) const +{ + if(a_param >= m_numParameters) return NULL; + gmVariable * var = m_stack + m_base + a_param; + if(a_userType == var->m_type) + { + GM_ASSERT(var->m_type >= GM_USER); + gmUserObject * user = (gmUserObject *) m_machine->GetObject(var->m_value.m_ref); + GM_ASSERT(var->m_type == user->m_userType); + return user->m_user; + } + return NULL; +} + + +void * gmThread::ParamUser_NoCheckTypeOrParam(int a_param) const +{ + GM_ASSERT(a_param < m_numParameters); + gmVariable * var = m_stack + m_base + a_param; + GM_ASSERT(var->m_type >= GM_USER); + gmUserObject * user = (gmUserObject *) m_machine->GetObject(var->m_value.m_ref); + return user->m_user; +} + + +gmUserObject * gmThread::ParamUserObject(int a_param) const +{ + if(a_param >= m_numParameters) return NULL; + gmVariable * var = m_stack + m_base + a_param; + if(var->m_type >= GM_USER) + { + return (gmUserObject *) m_machine->GetObject(var->m_value.m_ref); + } + return NULL; +} + + +bool gmThread::ParamUserObject(int a_param, gmUserObject *& a_value) const +{ + // Out of range + if( a_param >= m_numParameters ) + { + a_value = NULL; + return true; + } + // Valid + gmVariable * var = m_stack + m_base + a_param; + if( var->m_type >= GM_USER ) + { + a_value = (gmUserObject *) m_machine->GetObject(var->m_value.m_ref); + return true; + } + // Invalid + a_value = NULL; + return false; +} + +inline gmVariable& gmThread::Param(int a_param) +{ + return *(m_stack + m_base + a_param); +} + + +inline const gmVariable& gmThread::Param(int a_param) const +{ + return *(m_stack + m_base + a_param); +} + +gmVariable gmThread::Param(int a_param, const gmVariable& a_default) +{ + if( a_param >= m_numParameters ) + { + return a_default; + } + return *(m_stack + m_base + a_param); +} + +inline gmType gmThread::ParamType(int a_param) const +{ + return (m_stack + m_base + a_param)->m_type; +} + + +inline gmptr gmThread::ParamRef(int a_param) const +{ + return (m_stack + m_base + a_param)->m_value.m_ref; +} + + +// +// This methods. +// + +inline gmptr gmThread::ThisInt(gmptr a_default) +{ + const gmVariable * var = GetThis(); + if(var->m_type == GM_INT) return var->m_value.m_int; + return a_default; +} + + +inline gmfloat gmThread::ThisFloat(gmfloat a_default) +{ + const gmVariable * var = GetThis(); + if(var->m_type == GM_FLOAT) return var->m_value.m_float; + return a_default; +} + + +inline const char * gmThread::ThisString(const char * a_default) +{ + const gmVariable * var = GetThis(); + if(var->m_type == GM_STRING) + { + return (const char *) *((gmStringObject *) m_machine->GetObject(var->m_value.m_ref)); + } + return a_default; +} + + +inline gmTableObject * gmThread::ThisTable() +{ + const gmVariable * var = GetThis(); + if(var->m_type == GM_TABLE) + { + return (gmTableObject *) m_machine->GetObject(var->m_value.m_ref); + } + return NULL; +} + + +inline gmFunctionObject * gmThread::ThisFunction() +{ + const gmVariable * var = GetThis(); + if(var->m_type == GM_FUNCTION) + { + return (gmFunctionObject *) m_machine->GetObject(var->m_value.m_ref); + } + return NULL; +} + + +inline void * gmThread::ThisUser(int * a_userType) +{ + const gmVariable * var = GetThis(); + if(var->m_type >= GM_USER) + { + gmUserObject * user = (gmUserObject *) m_machine->GetObject(var->m_value.m_ref); + if(a_userType) *a_userType = user->m_userType; + return user->m_user; + } + return NULL; +} + + +inline void * gmThread::ThisUserCheckType(int a_userType) +{ + const gmVariable * var = GetThis(); + if(var->m_type >= GM_USER) + { + gmUserObject * user = (gmUserObject *) m_machine->GetObject(var->m_value.m_ref); + if(a_userType != user->m_userType) + { + return NULL; + } + return user->m_user; + } + return NULL; +} + + +inline void * gmThread::ThisUser_NoChecks() +{ + return ((gmUserObject*)m_machine->GetObject(GetThis()->m_value.m_ref))->m_user; +} + + +inline gmUserObject * gmThread::ThisUserObject() +{ + const gmVariable * var = GetThis(); + if(var->m_type >= GM_USER) + { + return (gmUserObject *) m_machine->GetObject(var->m_value.m_ref); + } + return NULL; +} + +// +// +// Helper macros +// +// + +#define GM_THREAD_ARG a_thread + +#ifdef GM_DEBUG_BUILD + #define GM_OBJECT(A) GM_THREAD_ARG->GetMachine()->GetObject((A)) + #define GM_MOBJECT(M, A) (M)->GetObject((A)) +#else //GM_DEBUG_BUILD + #if GMMACHINE_SUPERPARANOIDGC + #define GM_OBJECT(A) GM_THREAD_ARG->GetMachine()->GetObject((A)) + #define GM_MOBJECT(M, A) (M)->GetObject((A)) + #else //GMMACHINE_SUPERPARANOIDGC + #define GM_OBJECT(A) (gmObject *) (A) + #define GM_MOBJECT(M, A) (gmObject *) (A) + #endif //GMMACHINE_SUPERPARANOIDGC +#endif //GM_DEBUG_BUILD + +#define GM_NUM_PARAMS GM_THREAD_ARG->GetNumParams() +#if 1 // These macros only exception if param is present but type does not match + #define GM_INT_PARAM(VAR, PARAM, DEFAULT) int VAR; if( !GM_THREAD_ARG->ParamInt((PARAM), (VAR), (DEFAULT)) ) { return GM_EXCEPTION; } + #define GM_FLOAT_PARAM(VAR, PARAM, DEFAULT) float VAR; if( !GM_THREAD_ARG->ParamFloat((PARAM), (VAR), (DEFAULT)) ) { return GM_EXCEPTION; } + #define GM_STRING_PARAM(VAR, PARAM, DEFAULT) const char * VAR; if( !GM_THREAD_ARG->ParamString((PARAM), (VAR), (DEFAULT)) ) { return GM_EXCEPTION; } + #define GM_FUNCTION_PARAM(VAR, PARAM) gmFunctionObject * VAR; if( !GM_THREAD_ARG->ParamFunction((PARAM), (VAR)) ) { return GM_EXCEPTION; } + #define GM_TABLE_PARAM(VAR, PARAM) gmTableObject * VAR; if( !GM_THREAD_ARG->ParamTable((PARAM), (VAR)) ) { return GM_EXCEPTION; } + #define GM_USER_PARAM(OBJECT, VAR, PARAM) OBJECT VAR; if( !GM_THREAD_ARG->ParamUser((PARAM), (void*&)(VAR)) ) { return GM_EXCEPTION; } + #define GM_FLOAT_OR_INT_PARAM(VAR, PARAM, DEFAULT) float VAR; if( !GM_THREAD_ARG->ParamFloatOrInt((PARAM), (VAR), (DEFAULT)) ) { return GM_EXCEPTION; } +#else // Old versions + #define GM_INT_PARAM(VAR, PARAM, DEFAULT) int VAR = GM_THREAD_ARG->ParamInt((PARAM), (DEFAULT)) + #define GM_FLOAT_PARAM(VAR, PARAM, DEFAULT) float VAR = GM_THREAD_ARG->ParamFloat((PARAM), (DEFAULT)) + #define GM_STRING_PARAM(VAR, PARAM, DEFAULT) const char * VAR = GM_THREAD_ARG->ParamString((PARAM), (DEFAULT)) + #define GM_FUNCTION_PARAM(VAR, PARAM) gmFunctionObject * VAR = GM_THREAD_ARG->ParamFunction((PARAM)) + #define GM_TABLE_PARAM(VAR, PARAM) gmTableObject * VAR = GM_THREAD_ARG->ParamTable((PARAM)) + #define GM_USER_PARAM(OBJECT, VAR, PARAM) OBJECT VAR = (OBJECT) GM_THREAD_ARG->ParamUser((PARAM)); + #define GM_FLOAT_OR_INT_PARAM(VAR, PARAM, DEFAULT) float VAR = GM_THREAD_ARG->ParamFloatOrInt((PARAM), (DEFAULT)) +#endif + +// +// EXCEPTION VERSIONS +// + +#define GM_EXCEPTION_MSG GM_THREAD_ARG->GetMachine()->GetLog().LogEntry + +#define GM_CHECK_NUM_PARAMS(A) \ + if(GM_THREAD_ARG->GetNumParams() < (A)) { GM_EXCEPTION_MSG("expecting %d param(s)", (A)); return GM_EXCEPTION; } + +#define GM_CHECK_INT_PARAM(VAR, PARAM) \ + if(GM_THREAD_ARG->ParamType((PARAM)) != GM_INT) { GM_EXCEPTION_MSG("expecting param %d as int", (PARAM)); return GM_EXCEPTION; } \ + int VAR = GM_THREAD_ARG->Param((PARAM)).m_value.m_int; + +#define GM_CHECK_FLOAT_PARAM(VAR, PARAM) \ + if(GM_THREAD_ARG->ParamType((PARAM)) != GM_FLOAT) \ + { GM_EXCEPTION_MSG("expecting param %d as float", (PARAM)); return GM_EXCEPTION; } \ + float VAR = GM_THREAD_ARG->Param((PARAM)).m_value.m_float; + +#define GM_CHECK_STRING_PARAM(VAR, PARAM) \ + if(GM_THREAD_ARG->ParamType((PARAM)) != GM_STRING) { GM_EXCEPTION_MSG("expecting param %d as string", (PARAM)); return GM_EXCEPTION; } \ + const char * VAR = (const char *) *((gmStringObject *) GM_OBJECT(GM_THREAD_ARG->ParamRef((PARAM)))); + +#define GM_CHECK_FUNCTION_PARAM(VAR, PARAM) \ + if(GM_THREAD_ARG->ParamType((PARAM)) != GM_FUNCTION) { GM_EXCEPTION_MSG("expecting param %d as function", (PARAM)); return GM_EXCEPTION; } \ + gmFunctionObject * VAR = (gmFunctionObject *) GM_OBJECT(GM_THREAD_ARG->ParamRef((PARAM))); + +#define GM_CHECK_TABLE_PARAM(VAR, PARAM) \ + if(GM_THREAD_ARG->ParamType((PARAM)) != GM_TABLE) { GM_EXCEPTION_MSG("expecting param %d as table", (PARAM)); return GM_EXCEPTION; } \ + gmTableObject * VAR = (gmTableObject *) GM_OBJECT(GM_THREAD_ARG->ParamRef((PARAM))); + +#define GM_CHECK_USER_PARAM(OBJECT, TYPE, VAR, PARAM) \ + if(GM_THREAD_ARG->ParamType((PARAM)) != (TYPE)) { GM_EXCEPTION_MSG("expecting param %d as user type %d", (PARAM), (TYPE)); return GM_EXCEPTION; } \ + OBJECT VAR = (OBJECT) GM_THREAD_ARG->ParamUser_NoCheckTypeOrParam((PARAM)); + +// float or int param as float variable +#define GM_CHECK_FLOAT_OR_INT_PARAM(VAR, PARAM) \ + float VAR; \ + if( GM_THREAD_ARG->ParamType((PARAM)) == GM_FLOAT ) \ + { VAR = GM_THREAD_ARG->Param((PARAM)).m_value.m_float; } \ + else if( GM_THREAD_ARG->ParamType((PARAM)) == GM_INT ) \ + { VAR = (gmfloat)GM_THREAD_ARG->Param((PARAM)).m_value.m_int; } \ + else \ + { GM_EXCEPTION_MSG("expecting param %d as float or int", (PARAM)); return GM_EXCEPTION; } + +#endif // _GMTHREAD_H_ diff --git a/vscript/languages/gm/src/gm/gmUserObject.cpp b/vscript/languages/gm/src/gm/gmUserObject.cpp new file mode 100644 index 00000000..4a3eb2a2 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmUserObject.cpp @@ -0,0 +1,63 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmUserObject.h" +#include "gmMachine.h" + +// Must be last header +#include "memdbgon.h" + +#if GM_USE_INCGC + +void gmUserObject::Destruct(gmMachine * a_machine) +{ + gmGCDestructCallback gcDestruct = a_machine->GetUserGCDestructCallback((gmType) m_userType); + if(gcDestruct) + { + gcDestruct(a_machine, this); + } + +#if GM_USE_INCGC + a_machine->DestructDeleteObject(this); +#endif //GM_USE_INCGC +} + +bool gmUserObject::Trace(gmMachine * a_machine, gmGarbageCollector* a_gc, const int a_workLeftToGo, int& a_workDone) +{ + gmGCTraceCallback gcTrace = a_machine->GetUserGCTraceCallback((gmType) m_userType); + if(gcTrace) + { + return gcTrace(a_machine, this, a_gc, a_workLeftToGo, a_workDone); + } + else + { + ++a_workDone; + return true; + } +} + +#else //GM_USE_INCGC + +void gmUserObject::Destruct(gmMachine * a_machine) +{ + gmGarbageCollectCallback gc = a_machine->GetUserGCCallback((gmType) m_userType); + if(gc) gc(a_machine, this, GM_MARK_PERSIST); +} + +void gmUserObject::Mark(gmMachine * a_machine, gmuint32 a_mark) +{ + if(m_mark != GM_MARK_PERSIST) m_mark = a_mark; + gmGarbageCollectCallback mark = a_machine->GetUserMarkCallback((gmType) m_userType); + if(mark) mark(a_machine, this, a_mark); +} +#endif //GM_USE_INCGC + diff --git a/vscript/languages/gm/src/gm/gmUserObject.h b/vscript/languages/gm/src/gm/gmUserObject.h new file mode 100644 index 00000000..53578020 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmUserObject.h @@ -0,0 +1,37 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMUSEROBJECT_H_ +#define _GMUSEROBJECT_H_ + +#include "gmConfig.h" +#include "gmVariable.h" + +/// \class gmUserObject +/// \brief +class gmUserObject : public gmObject +{ +public: + + virtual int GetType() const { return m_userType; } + + virtual void Destruct(gmMachine * a_machine); +#if GM_USE_INCGC + virtual bool Trace(gmMachine * a_machine, gmGarbageCollector* a_gc, const int a_workLeftToGo, int& a_workDone); +#else //GM_USE_INCGC + virtual void Mark(gmMachine * a_machine, gmuint32 a_mark); +#endif //GM_USE_INCGC + + int m_userType; + void * m_user; +}; + +#endif // _GMUSEROBJECT_H_ diff --git a/vscript/languages/gm/src/gm/gmUtil.cpp b/vscript/languages/gm/src/gm/gmUtil.cpp new file mode 100644 index 00000000..368ab07d --- /dev/null +++ b/vscript/languages/gm/src/gm/gmUtil.cpp @@ -0,0 +1,55 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmUtil.h" + +// Must be last header +#include "memdbgon.h" + + +static char s_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +char * gmItoa(int a_val, char * a_dst, int a_radix) +{ + char * dst = a_dst; + char buffer[65]; + char *p; + int new_val; + + if (a_radix < 0) { + if (a_radix < -36 || a_radix > -2) return NULL; + if (a_val < 0) { + *dst++ = '-'; + a_val = -a_val; + } + a_radix = -a_radix; + } + else + { + if (a_radix > 36 || a_radix < 2) return NULL; + } + p = &buffer[sizeof(buffer)-1]; + *p = '\0'; + new_val = (gmuint32) a_val / (gmuint32) a_radix; + *--p = s_digits[(gmuint8) ((gmuint32) a_val- (gmuint32) new_val*(gmuint32) a_radix)]; + a_val = new_val; + while (a_val != 0) + { + new_val=a_val/a_radix; + *--p = s_digits[(gmuint8) (a_val-new_val*a_radix)]; + a_val= new_val; + } + + while ((*dst++ = *p++) != 0) ; + return a_dst; +} + diff --git a/vscript/languages/gm/src/gm/gmUtil.h b/vscript/languages/gm/src/gm/gmUtil.h new file mode 100644 index 00000000..e984c677 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmUtil.h @@ -0,0 +1,58 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMUTIL_H_ +#define _GMUTIL_H_ + +#include "gmConfig.h" + +template +T gmMin(const T &a_a, const T &a_b) +{ + if(a_a < a_b) return a_a; + return a_b; +} + + +template +T gmMax(const T &a_a, const T &a_b) +{ + if(a_a > a_b) return a_a; + return a_b; +} + + +/// \brief gmLog2ge() returns the next power of 2, greater than or equal to the given number. +inline unsigned int gmLog2ge(unsigned int n) +{ + --n; + + n |= n >> 16; + n |= n >> 8; + n |= n >> 4; + n |= n >> 2; + n |= n >> 1; + + return n + 1; +} + +/// \brief gmItoa() +char * gmItoa(int a_val, char * a_dst, int a_radix); + +/// \brief Is this system LittleEndian? +inline char gmIsLittleEndian() +{ + unsigned int fourBytes = 1; + return *((unsigned char*)&fourBytes); +} + + +#endif diff --git a/vscript/languages/gm/src/gm/gmVariable.cpp b/vscript/languages/gm/src/gm/gmVariable.cpp new file mode 100644 index 00000000..b764e757 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmVariable.cpp @@ -0,0 +1,127 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#include "gmConfig.h" +#include "gmVariable.h" +#include "gmThread.h" +#include "gmStringObject.h" +#include "gmUserObject.h" + +// Must be last header +#include "memdbgon.h" + + +// Init statics and constants +gmVariable gmVariable::s_null = gmVariable(GM_NULL, 0); + + +const char * gmVariable::AsString(gmMachine * a_machine, char * a_buffer, int a_len) const +{ + switch(m_type) + { + case GM_NULL : + _gmsnprintf(a_buffer, a_len, "null"); + break; + case GM_INT : + _gmsnprintf(a_buffer, a_len, "%d", m_value.m_int); + break; + case GM_FLOAT : + _gmsnprintf(a_buffer, a_len, "%g", m_value.m_float); + break; + case GM_STRING : + return ((gmStringObject *) GM_MOBJECT(a_machine, m_value.m_ref))->GetString(); + default: + gmAsStringCallback asStringCallback = a_machine->GetUserAsStringCallback(m_type); + if(asStringCallback) + { + asStringCallback((gmUserObject *) GM_MOBJECT(a_machine, m_value.m_ref), a_buffer, a_len ); + } + else + { + _gmsnprintf(a_buffer, a_len, "%s:0x%x", a_machine->GetTypeName(m_type), m_value.m_ref); + } + break; + } + return a_buffer; +} + + +const char * gmVariable::AsStringWithType(gmMachine * a_machine, char * a_buffer, int a_len) const +{ + // Copy the type first + _gmsnprintf(a_buffer, a_len, "%s: ", a_machine->GetTypeName(m_type)); + + // Update for used portion + int usedLen = strlen(a_buffer); + char* newBufferPos = a_buffer + usedLen; + int newLen = a_len - usedLen; + + if(newLen > 0) //Paranoid check some string buffer remaining + { + const char * str = AsString(a_machine, newBufferPos, newLen); + if(str != newBufferPos) + { + // copy what we can... this is used for debug purposes so it doesnt matter if we chop some off + V_strncpy(newBufferPos, str, newLen); + } + } + + return a_buffer; +} + + +void gmVariable::SetUser(gmUserObject * a_object) +{ + m_type = (gmType) a_object->m_userType; + m_value.m_ref = ((gmObject *) a_object)->GetRef(); +} + + +void gmVariable::SetUser(gmMachine * a_machine, void * a_userPtr, int a_userType) +{ + SetUser( a_machine->AllocUserObject(a_userPtr, a_userType) ); +} + + +void gmVariable::SetString(gmMachine * a_machine, const char * a_cString) +{ + SetString( a_machine->AllocStringObject(a_cString) ); +} + + +const char * gmVariable::GetCStringSafe() const +{ + if( m_type == GM_STRING ) + { + return ((gmStringObject *)m_value.m_ref)->GetString(); + } + return ""; +} + + +void * gmVariable::GetUserSafe(int a_userType) const +{ + if( m_type == a_userType ) + { + return ((gmUserObject *)m_value.m_ref)->m_user; + } + return NULL; +} + +gmUserObject* gmVariable::GetUserObjectSafe(int a_userType) const +{ + if( m_type == a_userType ) + { + return ((gmUserObject *)m_value.m_ref); + } + return NULL; +} + diff --git a/vscript/languages/gm/src/gm/gmVariable.h b/vscript/languages/gm/src/gm/gmVariable.h new file mode 100644 index 00000000..e5dc02f4 --- /dev/null +++ b/vscript/languages/gm/src/gm/gmVariable.h @@ -0,0 +1,266 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMVARIABLE_H_ +#define _GMVARIABLE_H_ + +#include "gmConfig.h" +#if GM_USE_INCGC +#include "gmIncGC.h" +#endif //GM_USE_INCGC + +#define GM_MARK_PERSIST 0 +#define GM_MARK_START 1 + +// fwd decls +class gmMachine; +class gmStringObject; +class gmTableObject; +class gmFunctionObject; +class gmUserObject; + +/// \enum gmType +/// \brief gmType is an enum of the possible scripting types. +typedef int gmType; + +enum +{ + GM_NULL = 0, // GM_NULL must be 0 as i have relied on this in expression testing. + GM_INT, + GM_FLOAT, + + GM_STRING, + GM_TABLE, + GM_FUNCTION, + GM_USER, // User types continue from here. + + GM_FORCEINT = GM_MAX_INT, +}; + + + +/// \struct gmVariable +/// \brief a variable is the basic type passed around on the stack, and used as storage in the symbol tables. +/// A variable is either a reference to a gmObject type, or it is a direct value such as null, int or float. +/// The gm runtime stack operates on gmVariable types. +struct gmVariable +{ + static gmVariable s_null; + + gmType m_type; + union + { + int m_int; + float m_float; + gmptr m_ref; + } m_value; + + inline gmVariable() + { +#if GMMACHINE_NULL_VAR_CTOR // Disabled by default + Nullify(); +#endif //GMMACHINE_NULL_VAR_CTOR + } + inline gmVariable(gmType a_type, gmptr a_ref) : m_type(a_type) { m_value.m_ref = a_ref; } + + explicit inline gmVariable(int a_val) : m_type(GM_INT) { m_value.m_int = a_val; } + explicit inline gmVariable(float a_val) : m_type(GM_FLOAT) { m_value.m_float = a_val; } + explicit inline gmVariable(gmStringObject * a_string) { SetString(a_string); } + explicit inline gmVariable(gmTableObject * a_table) { SetTable(a_table); } + explicit inline gmVariable(gmFunctionObject * a_func) { SetFunction(a_func); } + explicit inline gmVariable(gmUserObject * a_user) { SetUser(a_user); } + + inline void SetInt(int a_value) { m_type = GM_INT; m_value.m_int = a_value; } + inline void SetFloat(float a_value) { m_type = GM_FLOAT; m_value.m_float = a_value; } + inline void SetString(gmStringObject * a_string); + void SetString(gmMachine * a_machine, const char * a_cString); + inline void SetTable(gmTableObject * a_table); + inline void SetFunction(gmFunctionObject * a_function); + void SetUser(gmUserObject * a_object); + void SetUser(gmMachine * a_machine, void * a_userPtr, int a_userType); + + + inline bool IsReference() const { return m_type > GM_FLOAT; } + inline void Nullify() { m_type = GM_NULL; m_value.m_int = 0; } + inline bool IsNull() { return m_type == GM_NULL; } + + /// \brief AsString will get this gm variable as a string if possible. AsString is used for the gm "print" and system.Exec function bindings. + /// \param a_buffer is a buffer you must provide for the function to write into. this buffer needs only be 256 characters long as it is stated that + /// user types should give an AsString conversion < 256 characters. If the type has a longer string type, it may return an interal string + /// \param a_len must be >= 256 + /// \return a_buffer or internal variable string + const char * AsString(gmMachine * a_machine, char * a_buffer, int a_len) const; + + /// \brief AsStringWithType will get the gm variable as a string with type name in front of value. AsStringWithType is used for debugging, and may cut + /// the end off some string types. + /// \sa AsString + /// \return a_buffer always + const char * AsStringWithType(gmMachine * a_machine, char * a_buffer, int a_len) const; + + /// Return int/float or zero + inline int GetIntSafe() const; + /// Return float/int or zero + inline float GetFloatSafe() const; + /// Return string object or null + inline gmStringObject* GetStringObjectSafe() const; + /// Return table object or null + inline gmTableObject* GetTableObjectSafe() const; + /// Return function object or null + inline gmFunctionObject* GetFunctionObjectSafe() const; + /// Return c string or empty string + const char* GetCStringSafe() const; + /// Return user type ptr or null + void* GetUserSafe(int a_userType) const; + /// Return user type ptr or null + gmUserObject* GetUserObjectSafe(int a_userType) const; + + static inline gmuint Hash(const gmVariable &a_key) + { + gmuint hash = (gmuint) a_key.m_value.m_ref; + if(a_key.IsReference()) + { + hash >>= 2; // Reduce pointer address aliasing + } + return hash; + } + + static inline int Compare(const gmVariable &a_keyA, const gmVariable &a_keyB) + { + if(a_keyA.m_type < a_keyB.m_type) return -1; + if(a_keyA.m_type > a_keyB.m_type) return 1; + if(a_keyA.m_value.m_int < a_keyB.m_value.m_int) return -1; + if(a_keyA.m_value.m_int > a_keyB.m_value.m_int) return 1; + return 0; + } + +}; + + + +/// \class gmObject +/// \brief gmObject is the base class for gm reference types. All gmObject types are allocated from the gmMachine +class gmObject +#if GM_USE_INCGC + : public gmGCObjBase +#endif //GM_USE_INCGC +{ +public: + + inline gmptr GetRef() const { return (gmptr) this; } + virtual int GetType() const = 0; + +#if !GM_USE_INCGC + /// \brief Only call Mark() if NeedsMark() returns true. + virtual void Mark(gmMachine * a_machine, gmuint32 a_mark) { if(m_mark != GM_MARK_PERSIST) m_mark = a_mark; } + inline bool NeedsMark(gmuint32 a_mark) { return ((m_mark != GM_MARK_PERSIST) && (m_mark != a_mark)); } + virtual void Destruct(gmMachine * a_machine) = 0; + +protected: + + gmuint32 m_mark; + +private: + + gmObject * m_sysNext; +#endif //!GM_USE_INCGC + +protected: + + /// \brief Non-public constructor. Create via gmMachine. + inline gmObject() +#if !GM_USE_INCGC + : m_mark(GM_MARK_START) +#endif //!GM_USE_INCGC + {} + friend class gmMachine; +}; + + +// +// INLINE IMPLEMENTATION +// + + +inline void gmVariable::SetString(gmStringObject * a_string) +{ + m_type = GM_STRING; + m_value.m_ref = ((gmObject *) a_string)->GetRef(); +} + +inline void gmVariable::SetTable(gmTableObject * a_table) +{ + m_type = GM_TABLE; + m_value.m_ref = ((gmObject *) a_table)->GetRef(); +} + +inline void gmVariable::SetFunction(gmFunctionObject * a_function) +{ + m_type = GM_FUNCTION; + m_value.m_ref = ((gmObject *) a_function)->GetRef(); +} + +int gmVariable::GetIntSafe() const +{ + if( GM_INT == m_type ) + { + return m_value.m_int; + } + else if( GM_FLOAT == m_type ) + { + return (int)m_value.m_float; + } + return 0; +} + +float gmVariable::GetFloatSafe() const +{ + if( GM_FLOAT == m_type ) + { + return m_value.m_float; + } + else if( GM_INT == m_type ) + { + return (float)m_value.m_int; + } + return 0.0f; + +} + +gmStringObject * gmVariable::GetStringObjectSafe() const +{ + if( GM_STRING == m_type ) + { + return (gmStringObject *)m_value.m_ref; + } + return NULL; +} + + +inline gmTableObject * gmVariable::GetTableObjectSafe() const +{ + if( GM_TABLE == m_type ) + { + return (gmTableObject *)m_value.m_ref; + } + return NULL; +} + +inline gmFunctionObject * gmVariable::GetFunctionObjectSafe() const +{ + if( GM_FUNCTION == m_type ) + { + return (gmFunctionObject *)m_value.m_ref; + } + return NULL; +} + + +#endif // _GMVARIABLE_H_ diff --git a/vscript/languages/gm/src/gm/gmfrontend.bat b/vscript/languages/gm/src/gm/gmfrontend.bat new file mode 100644 index 00000000..36d203cf --- /dev/null +++ b/vscript/languages/gm/src/gm/gmfrontend.bat @@ -0,0 +1,16 @@ +rem Strip CR from compiler script files +..\..\bin\StripCR gmParser.y /nobak +..\..\bin\StripCR gmScanner.l /nobak +..\..\bin\StripCR flex.skl /nobak +..\..\bin\StripCR bison.hairy /nobak +..\..\bin\StripCR bison.simple /nobak +rem generate compiler +..\..\bin\bison -o gmParser.cpp -d -l -p gm gmParser.y +..\..\bin\flex -ogmScanner.cpp -Pgm -Sflex.skl gmScanner.l + +rem Strip CR generated files +..\..\bin\StripCR gmParser.cpp /nobak +..\..\bin\StripCR gmScanner.cpp /nobak + +rem use following for verbose bison +rem ..\..\bin\bison -o gmParser.cpp -d -l -v -p gm gmParser.y diff --git a/vscript/languages/gm/src/gmd/ChildView.cpp b/vscript/languages/gm/src/gmd/ChildView.cpp new file mode 100644 index 00000000..ad8c81d6 --- /dev/null +++ b/vscript/languages/gm/src/gmd/ChildView.cpp @@ -0,0 +1,1076 @@ +// ChildView.cpp : implementation of the CChildView class +// +// See Copyright Notice in gmMachine.h + +#include "StdAfx.h" +#include "gmd.h" +#include "ChildView.h" +#include "GMLangSettings.h" + + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#define LOCALS_ID 10 +#define CALLSTACK_ID 11 +#define THREADS_ID 12 + + +void gmDebuggerBreak(gmDebuggerSession * a_session, int a_threadId, int a_sourceId, int a_lineNumber) +{ + CChildView * view = (CChildView *) a_session->m_user; + gmMachineGetContext(a_session, a_threadId, 0); +} + + +void gmDebuggerRun(gmDebuggerSession * a_session, int a_threadId) +{ + CChildView * view = (CChildView *) a_session->m_user; + char buffer[128]; + sprintf(buffer, "thread %d started.\r\n", a_threadId); + view->Log(buffer); + view->FindAddThread(a_threadId, 0); +} + + +void gmDebuggerStop(gmDebuggerSession * a_session, int a_threadId) +{ + CChildView * view = (CChildView *) a_session->m_user; + char buffer[128]; + sprintf(buffer, "thread %d stopped.\r\n", a_threadId); + view->Log(buffer); + if(a_threadId == view->m_currentDebugThread) + view->ClearCurrentContext(); + view->RemoveThread(a_threadId); +} + + +void gmDebuggerSource(gmDebuggerSession * a_session, int a_sourceId, const char * a_sourceName, const char * a_source) +{ + CChildView * view = (CChildView *) a_session->m_user; + view->SetSource(a_sourceId, a_source); + if(view->m_lineNumberOnSourceRcv != -1) + { + view->SetLine(view->m_lineNumberOnSourceRcv); + view->m_lineNumberOnSourceRcv = -1; + } +} + + +#include +void gmDebuggerException(gmDebuggerSession * a_session, int a_threadId) +{ + // play exception sound. + //PlaySound("critical"); + //PlaySound(MAKEINTRESOURCE(IDR_WAV_ERROR), NULL, SND_ASYNC | SND_RESOURCE); + CChildView * view = (CChildView *) a_session->m_user; + gmMachineGetContext(a_session, a_threadId, 0); +} + + +void gmDebuggerBeginContext(gmDebuggerSession * a_session, int a_threadId, int a_callFrame) +{ + CChildView * view = (CChildView *) a_session->m_user; + view->m_currentDebugThread = a_threadId; + view->FindAddThread(view->m_currentDebugThread, 4, true); + view->m_callstack.DeleteAllItems(); + view->m_locals.DeleteAllItems(); + view->m_currentCallFrame = a_callFrame; +} + + +void gmDebuggerContextCallFrame(gmDebuggerSession * a_session, int a_callFrame, const char * a_functionName, int a_sourceId, int a_lineNumber, const char * a_thisSymbol, const char * a_thisValue, int a_thisId) +{ + CChildView * view = (CChildView *) a_session->m_user; + char buffer[256]; + _snprintf(buffer, 256, "%s (%d)", a_functionName, a_lineNumber); + view->m_callstack.InsertItem(view->m_callstack.GetItemCount(), buffer); + + if(view->m_currentCallFrame == a_callFrame) + { + // add "this" + int index = view->m_locals.GetItemCount(); + view->m_locals.InsertItem(index, a_thisSymbol); + view->m_locals.SetItemText(index, 1, a_thisValue); + + // do we have the source code? + view->m_lineNumberOnSourceRcv = -1; + if(!view->SetSource(a_sourceId)) + { + // request source + gmMachineGetSource(a_session, a_sourceId); + view->m_lineNumberOnSourceRcv = a_lineNumber; + } + else + { + // update the position cursor. + view->SetLine(a_lineNumber); + } + } +} + + +void gmDebuggerContextVariable(gmDebuggerSession * a_session, const char * a_varSymbol, const char * a_varValue, int a_varId) +{ + CChildView * view = (CChildView *) a_session->m_user; + int index = view->m_locals.GetItemCount(); + view->m_locals.InsertItem(index, a_varSymbol); + view->m_locals.SetItemText(index, 1, a_varValue); +} + + +void gmDebuggerEndContext(gmDebuggerSession * a_session) +{ + CChildView * view = (CChildView *) a_session->m_user; +} + + +void gmDebuggerBeginSourceInfo(gmDebuggerSession * a_session) +{ + CChildView * view = (CChildView *) a_session->m_user; +} + + +void gmDebuggerSourceInfo(gmDebuggerSession * a_session, int a_sourceId, const char * a_sourceName) +{ + CChildView * view = (CChildView *) a_session->m_user; +} + + +void gmDebuggerEndSourceInfo(gmDebuggerSession * a_session) +{ + CChildView * view = (CChildView *) a_session->m_user; +} + + +void gmDebuggerBeginThreadInfo(gmDebuggerSession * a_session) +{ + CChildView * view = (CChildView *) a_session->m_user; + while(!view->m_threads.empty()) view->m_threads.pop_front(); +} + + +void gmDebuggerThreadInfo(gmDebuggerSession * a_session, int a_threadId, int a_threadState) +{ + CChildView * view = (CChildView *) a_session->m_user; + CChildView::ThreadInfo info; + info.m_id = a_threadId; + info.m_state = a_threadState; + view->m_threads.push_front(info); +} + + +void gmDebuggerEndThreadInfo(gmDebuggerSession * a_session) +{ + CChildView * view = (CChildView *) a_session->m_user; + view->UpdateThreadWindow(); +} + + +void gmDebuggerError(gmDebuggerSession * a_session, const char * a_error) +{ + CChildView * view = (CChildView *) a_session->m_user; + view->Log(a_error); +} + + +void gmDebuggerMessage(gmDebuggerSession * a_session, const char * a_message) +{ + CChildView * view = (CChildView *) a_session->m_user; + view->Log(a_message); +} + + +void gmDebuggerAck(gmDebuggerSession * a_session, int a_response, int a_posNeg) +{ + CChildView * view = (CChildView *) a_session->m_user; + if(a_response == view->m_responseId && a_posNeg) + { + if(view->m_breakPoint.m_enabled) + { + view->m_scintillaEdit.MarkerAdd(view->m_breakPoint.m_lineNumber-1, 0); + } + else + { + view->m_scintillaEdit.MarkerDelete(view->m_breakPoint.m_lineNumber-1, 0); + } + } +} + + +void gmDebuggerQuit(gmDebuggerSession * a_session) +{ + CChildView * view = (CChildView *) a_session->m_user; + view->Disconnect(); +} + + +void SendMachineMessage(gmDebuggerSession * a_session, const void * a_command, int a_len) +{ + CChildView * view = (CChildView *) a_session->m_user; + view->m_networkServer.nSendMessage((const char *) a_command, a_len); +} + +const void * PumpMachineMessage(gmDebuggerSession * a_session, int &a_len) +{ + CChildView * view = (CChildView *) a_session->m_user; + return view->m_networkServer.PumpMessage(a_len); +} + + + +///////////////////////////////////////////////////////////////////////////// +// CChildView + +CChildView::CChildView() +{ + m_session.m_pumpMessage = PumpMachineMessage; + m_session.m_sendMessage = SendMachineMessage; + m_session.m_user = this; + m_scintillaDll = NULL; + m_currentDebugThread = 0; + m_currentPos = -1; + m_responseId = 100; + m_sources = NULL; + m_sourceId = 0; + m_unpackBuffer = NULL; + m_unpackBufferSize = 0; + m_connected = false; + m_debugging = false; + m_lineNumberOnSourceRcv = -1; +} + +CChildView::~CChildView() +{ + if(m_scintillaDll) + FreeLibrary(m_scintillaDll); + + // free the source code + Source * source = m_sources; + while(source) + { + m_sources = source->m_next; + delete[] source->m_source; + delete source; + source = m_sources; + } + + if(m_unpackBuffer) + delete[] m_unpackBuffer; +} + + +BEGIN_MESSAGE_MAP(CChildView,CWnd ) + //{{AFX_MSG_MAP(CChildView) + ON_WM_CREATE() + ON_WM_DESTROY() + ON_WM_SIZE() + ON_WM_PAINT() + ON_COMMAND(ID_STEP_INTO, OnStepInto) + ON_UPDATE_COMMAND_UI(ID_STEP_INTO, OnUpdateStepInto) + ON_COMMAND(ID_STEP_OUT, OnStepOut) + ON_UPDATE_COMMAND_UI(ID_STEP_OUT, OnUpdateStepOut) + ON_COMMAND(ID_STEP_OVER, OnStepOver) + ON_UPDATE_COMMAND_UI(ID_STEP_OVER, OnUpdateStepOver) + ON_COMMAND(ID_GO, OnGo) + ON_UPDATE_COMMAND_UI(ID_GO, OnUpdateGo) + ON_COMMAND(ID_STOP_DEBUGGING, OnStopDebugging) + ON_UPDATE_COMMAND_UI(ID_STOP_DEBUGGING, OnUpdateStopDebugging) + ON_COMMAND(ID_TOGGLE_BREAKPOINT, OnToggleBreakpoint) + ON_UPDATE_COMMAND_UI(ID_TOGGLE_BREAKPOINT, OnUpdateToggleBreakpoint) + ON_NOTIFY(NM_DBLCLK, CALLSTACK_ID, OnNMDblclkCallstack) + ON_NOTIFY(NM_DBLCLK, THREADS_ID, OnNMDblclkThreadstack) + ON_NOTIFY(NM_CLICK, THREADS_ID, OnNMClkThreadstack) + ON_COMMAND(ID_BREAK_ALL_THREADS, OnBreakAllThreads) + ON_UPDATE_COMMAND_UI(ID_BREAK_ALL_THREADS, OnUpdateBreakAllThreads) + ON_COMMAND(ID_RESUME_ALL_THREADS, OnResumeAllThreads) + ON_UPDATE_COMMAND_UI(ID_RESUME_ALL_THREADS, OnUpdateResumeAllThreads) + ON_COMMAND(ID_BREAK_CURRENT_THREAD, OnBreakCurrentThread) + ON_UPDATE_COMMAND_UI(ID_BREAK_CURRENT_THREAD, OnUpdateBreakCurrentThread) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +///////////////////////////////////////////////////////////////////////////// +// CChildView message handlers + +BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) +{ + if (!CWnd::PreCreateWindow(cs)) + return FALSE; + + cs.dwExStyle |= WS_EX_CLIENTEDGE; + cs.style &= ~WS_BORDER; + cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, + ::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1), NULL); + + return TRUE; +} + +void CChildView::OnPaint() +{ + CPaintDC dc(this); // device context for painting +} + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// +// OnCreate +// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + // + // Create Scintilla + // + + m_scintillaDll = LoadLibrary("SciLexer.dll"); + if (!m_scintillaDll) + return -1; + + HWND hwnd = ::CreateWindowEx(0, "Scintilla", NULL, WS_CHILD | WS_VISIBLE |WS_TABSTOP, 0, 0, 100, 100, m_hWnd, NULL, AfxGetInstanceHandle(), NULL); + + if (!hwnd) + return -1; + + m_scintillaEdit.Attach(hwnd); + + m_scintillaEdit.MarkerDefine(0, ScintillaEdit::MS_Circle); + m_scintillaEdit.MarkerDefine(1, ScintillaEdit::MS_Arrow); + m_scintillaEdit.MarkerSetFGColour(0, RGB(0,0,0)); + m_scintillaEdit.MarkerSetGGColour(0, RGB(255,0,0)); + + m_scintillaEdit.MarkerSetFGColour(1, RGB(0,0,0)); + m_scintillaEdit.MarkerSetGGColour(1, RGB(0,0,255)); + m_scintillaEdit.SetEOLMode(ScintillaEdit::EOL_CrLf); + + m_scintillaEdit.SetReadOnly(true); + + #if 1 + // Show line numbers + // Code based on Scite + // TODO, put markers to left of line numbers if possible + { + int lineCount = m_scintillaEdit.SendMessage(SCI_GETLINECOUNT,(WPARAM)0, (LPARAM)0); + int lineNumWidth = 1; + int lineNumbersWidth = 4; + while (lineCount >= 10) + { + lineCount /= 10; + ++lineNumWidth; + } + if (lineNumWidth < lineNumbersWidth) + { + lineNumWidth = lineNumbersWidth; + } + + // The 4 here allows for spacing: 1 pixel on left and 3 on right. + int pixelWidth = 4 + lineNumWidth * m_scintillaEdit.SendMessage(SCI_TEXTWIDTH, (WPARAM)STYLE_LINENUMBER, (LPARAM)"9"); + m_scintillaEdit.SendMessage(SCI_SETMARGINWIDTHN, (WPARAM)0, (LPARAM)pixelWidth); + } + #endif + + + + m_langSettings = new GMLangSettings; + m_langSettings->Apply(m_scintillaEdit); + + // + // Create Output Window + // + + if(!m_outputWindow.Create( + WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_LEFT | ES_AUTOVSCROLL | ES_READONLY + , CRect(0,0,0,0), this, 0)) return -1; + m_outputWindow.ShowScrollBar(SB_VERT, TRUE); + + // + // Create Locals Window + // + + if(!m_locals.Create(WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SINGLESEL | WS_BORDER, CRect(0,0,0,0), this, LOCALS_ID)) + return -1; + + m_locals.InsertColumn(0, "Variable"); + m_locals.InsertColumn(1, "Value"); + m_locals.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); + + // + // Create Callstack Window + // + + if(!m_callstack.Create(WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SINGLESEL | WS_BORDER, CRect(0,0,0,0), this, CALLSTACK_ID)) + return -1; + + m_callstack.InsertColumn(0, "Call stack"); + m_callstack.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); + + // + // Create Thread Window + // + + if(!m_threadsWindow.Create(WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SINGLESEL | WS_BORDER, CRect(0,0,0,0), this, THREADS_ID)) + return -1; + + m_threadsWindow.InsertColumn(0, "Thread ID"); + m_threadsWindow.InsertColumn(1, "Status"); + m_threadsWindow.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); + + // start listening for network connections. + Open(GM_DEBUGGER_PORT); + + return 0; +} + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// +// OnDestroy +// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +void CChildView::OnDestroy() +{ + delete m_langSettings; + + CWnd::OnDestroy(); + + if (m_scintillaEdit) + { + HWND hwnd = m_scintillaEdit.Detach(); + ::SendMessage(hwnd, WM_DESTROY, 0, 0); + } +} + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// +// OnDestroy +// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +void CChildView::OnSize(UINT nType, int cx, int cy) +{ + CWnd::OnSize(nType, cx, cy); + + CRect rect; + GetClientRect(rect); + + CRect scintillaRect(rect); + CRect outputRect(rect); + CRect localRect(rect), callstackRect(rect); + CRect threadRect(rect); + + scintillaRect.right = (int) (0.7f * (float) rect.right); + callstackRect.left = scintillaRect.right; + localRect.left = scintillaRect.right; + threadRect.left = scintillaRect.right; + + outputRect.right = scintillaRect.right; + scintillaRect.bottom = (int) (0.85f * (float) rect.bottom); + outputRect.top = scintillaRect.bottom; + + localRect.bottom = (int) (0.333333f * (float) rect.bottom); + callstackRect.top = localRect.bottom; + callstackRect.bottom = (int) (0.666666f * (float) rect.bottom); + threadRect.top = callstackRect.bottom; + + m_scintillaEdit.MoveWindow(scintillaRect); + m_outputWindow.MoveWindow(outputRect); + m_locals.MoveWindow(localRect); + m_callstack.MoveWindow(callstackRect); + m_threadsWindow.MoveWindow(threadRect); + + // Set column widths on windows. + int width; + m_locals.GetWindowRect(rect); + width = rect.Width()/2; + m_locals.SetColumnWidth(0, width); + m_locals.SetColumnWidth(1, width); + + m_callstack.GetWindowRect(rect); + width = rect.Width(); + m_callstack.SetColumnWidth(0, width); + + m_threadsWindow.GetWindowRect(rect); + width = rect.Width()/2; + m_threadsWindow.SetColumnWidth(0, width); + m_threadsWindow.SetColumnWidth(1, width); +} + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// +// Log +// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +void CChildView::Log(const char * a_message) +{ + if(m_outputLines.size() > 20) + { + m_outputLines.pop_front(); + } + m_outputLines.push_back(CString(a_message)); + + std::list::iterator it; + + CString text = ""; + for(it = m_outputLines.begin(); it != m_outputLines.end(); ++it) + { + text += *it; + } + + m_outputWindow.SetWindowText(text); + int nlines = m_outputWindow.GetLineCount(); + m_outputWindow.LineScroll(nlines); +} + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// +// SetSource +// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +bool CChildView::SetSource(unsigned int a_sourceId, const char * a_source) +{ + if(a_sourceId == m_sourceId) return true; + + // do we have the source + Source * source = m_sources; + while(source) + { + if(source->m_id == a_sourceId) + { + m_scintillaEdit.SetReadOnly(false); + m_scintillaEdit.SetText(source->m_source); + m_scintillaEdit.SetReadOnly(true); + m_sourceId = a_sourceId; + return true; + } + source = source->m_next; + } + + // we dont have the source, add it + if(a_source) + { + m_scintillaEdit.SetReadOnly(false); + m_scintillaEdit.SetText(a_source); + m_scintillaEdit.SetReadOnly(true); + m_sourceId = a_sourceId; + + int len = strlen(a_source) + 1; + source = new Source; + source->m_source = new char[len]; + memcpy(source->m_source, a_source, len); + source->m_id = a_sourceId; + source->m_next = m_sources; + m_sources = source; + return true; + } + return false; +} + + + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// +// SetLine +// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +void CChildView::SetLine(int a_line) +{ + if(m_currentPos >= 0) + { + m_scintillaEdit.MarkerDelete(m_currentPos, 1); + m_currentPos = -1; + } + m_currentPos = a_line - 1; + m_scintillaEdit.MarkerAdd(m_currentPos, 1); + + // center the source view around the cursor + int topLine = m_scintillaEdit.GetFirstVisibleLine(); + int visLines = m_scintillaEdit.GetLinesOnScreen(); + int scrollLines = 0; + int centre = (topLine + (visLines >> 1)); + int lq = centre - (visLines >> 2); + int hq = centre + (visLines >> 2); + + if(m_currentPos < lq) + scrollLines = m_currentPos - centre; + else if(m_currentPos > hq) + scrollLines = m_currentPos - centre; + m_scintillaEdit.LineScroll(0, scrollLines); +} + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// +// FindAddThread +// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +void CChildView::FindAddThread(int a_threadId, int a_state, bool a_select) +{ + if(a_threadId <= 0) return; + std::list::iterator it; + + char buffer[128]; + sprintf(buffer, "%d", a_threadId); + const char * state = ""; + + switch(a_state) + { + case 0 : state = "running"; break; + case 1 : state = "blocked"; break; + case 2 : state = "sleeping"; break; + case 3 : state = "exception"; break; + case 4 : state = "debug"; break; + default : break; + } + + // find in list + + for(it = m_threads.begin(); it != m_threads.end(); ++it) + { + if(it->m_id == a_threadId) + { + // update state + if(it->m_state != a_state || a_select) + { + if(it->m_state != a_state) it->m_state = a_state; + ThreadInfo &info = *it; + LVFINDINFO findInfo; + findInfo.flags = LVFI_PARAM; + findInfo.lParam = (LPARAM)&info; + int index = m_threadsWindow.FindItem(&findInfo); + ASSERT(index != -1); + if(it->m_state != a_state) m_threadsWindow.SetItemText(index, 1, state); + if(a_select) + { + m_threadsWindow.SetSelectionMark(index); + m_threadsWindow.SetItemState(index, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); + } + } + return; + } + } + + // add + ThreadInfo info; + info.m_id = a_threadId; + info.m_state = a_state; + m_threads.push_front(info); + m_threadsWindow.InsertItem(0, buffer); + m_threadsWindow.SetItemText(0, 1, state); + m_threadsWindow.SetItemData(0, (DWORD)&m_threads.front()); + if(a_select) + { + m_threadsWindow.SetSelectionMark(0); + m_threadsWindow.SetItemState(0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); + } +} + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// +// RemoveThread +// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +void CChildView::RemoveThread(int a_threadId) +{ + if(a_threadId <= 0) return; + std::list::iterator it; + + for(it = m_threads.begin(); it != m_threads.end(); ++it) + { + if(it->m_id == a_threadId) + { + ThreadInfo &info = *it; + + LVFINDINFO findInfo; + findInfo.flags = LVFI_PARAM; + findInfo.lParam = (LPARAM)&info; + int index = m_threadsWindow.FindItem(&findInfo); + ASSERT(index != -1); + m_threadsWindow.DeleteItem(index); + + m_threads.erase(it); + return; + } + } +} + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// +// UpdateThreadWindow +// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +void CChildView::UpdateThreadWindow() +{ + + m_threadsWindow.DeleteAllItems(); + std::list::iterator it; + + for(it = m_threads.begin(); it != m_threads.end(); ++it) + { + char buffer[128]; + sprintf(buffer, "%d", it->m_id); + const char * state = ""; + + switch(it->m_state) + { + case 0 : state = "running"; break; + case 1 : state = "blocked"; break; + case 2 : state = "sleeping"; break; + case 3 : state = "exception"; break; + case 4 : state = "broken"; break; + default : break; + } + + m_threadsWindow.InsertItem(0, buffer); + m_threadsWindow.SetItemText(0, 1, state); + m_threadsWindow.SetItemData(0, (DWORD)&*it); + + if(m_currentDebugThread == it->m_id) + { + m_threadsWindow.SetSelectionMark(0); + m_threadsWindow.SetItemState(0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); + } + } +} + + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// +// Open() +// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +bool CChildView::Open(unsigned short a_port) +{ + Disconnect(); + if(m_networkServer.Open(a_port)) + { + m_connected = true; + char buffer[256]; + sprintf(buffer, "Listening for gmMachines on port %d\r\n", GM_DEBUGGER_PORT); + Log(buffer); + return true; + } + return false; +} + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// +// ClearCurrentContext() +// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +void CChildView::ClearCurrentContext() +{ + int sel = m_threadsWindow.GetSelectionMark(); + if(sel != -1) + { + m_threadsWindow.SetItemState(sel, 0, LVIS_SELECTED | LVIS_FOCUSED); + } + + m_currentDebugThread = 0; + m_threadsWindow.SetSelectionMark(-1); + m_currentPos = -1; + + // clear the windows + SetSource(0, ""); // hackorama + m_locals.DeleteAllItems(); + m_callstack.DeleteAllItems(); +} + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// +// Disconnect() +// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +void CChildView::Disconnect() +{ + while(!m_threads.empty()) m_threads.pop_front(); + m_threadsWindow.DeleteAllItems(); + ClearCurrentContext(); + if(m_connected) + { + m_networkServer.Close(); + m_connected = false; + } +} + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// +// OnIdle() +// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +BOOL CChildView::OnIdle() +{ + static int ut = 0; + + // process network messages + if(m_networkServer.IsConnected()) + { + m_debugging = true; + // pump messages from server + m_session.Update(); + + if(--ut <= 0) + { + ut = 500; + gmMachineGetThreadInfo(&m_session); + } + + return TRUE; + } + else + { + if(m_debugging) + { + m_debugging = false; + Open(GM_DEBUGGER_PORT); + } + } + return FALSE; +} + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// +// Handlers +// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +void CChildView::OnStepInto() +{ + if(m_currentDebugThread && m_debugging) + { + // send run command + gmMachineStepInto(&m_session, m_currentDebugThread); + } + +} + +void CChildView::OnUpdateStepInto(CCmdUI* pCmdUI) +{ + pCmdUI->Enable((m_currentDebugThread != 0)); +} + +void CChildView::OnStepOut() +{ + if(m_currentDebugThread && m_debugging) + { + // send run command + gmMachineStepOut(&m_session, m_currentDebugThread); + } +} + +void CChildView::OnUpdateStepOut(CCmdUI* pCmdUI) +{ + pCmdUI->Enable((m_currentDebugThread != 0)); +} + +void CChildView::OnStepOver() +{ + if(m_currentDebugThread && m_debugging) + { + // send run command + gmMachineStepOver(&m_session, m_currentDebugThread); + } +} + +void CChildView::OnUpdateStepOver(CCmdUI* pCmdUI) +{ + pCmdUI->Enable((m_currentDebugThread != 0)); +} + +void CChildView::OnGo() +{ + if(m_currentDebugThread && m_debugging) + { + // send run command + gmMachineRun(&m_session, m_currentDebugThread); + } +} + +void CChildView::OnUpdateGo(CCmdUI* pCmdUI) +{ + pCmdUI->Enable((m_currentDebugThread != 0)); +} + +void CChildView::OnStopDebugging() +{ + if(m_connected && m_debugging) + { + gmMachineQuit(&m_session); + Sleep(500); // wait for quit message to post (hack) + Disconnect(); + } +} + +void CChildView::OnUpdateStopDebugging(CCmdUI* pCmdUI) +{ + pCmdUI->Enable((m_debugging != 0)); +} + +void CChildView::OnToggleBreakpoint() +{ + // add a break point at the current line. + int line = m_scintillaEdit.GetCurrentPos(); + line = m_scintillaEdit.LineFromPosition(line); + bool enabled = true; + + // do we have a break point at this line already??? + if(m_scintillaEdit.MarkerGet(line) & 0x01) + enabled = false; + + if(m_currentDebugThread && m_debugging) + { + + m_breakPoint.m_enabled = enabled; + m_breakPoint.m_allThreads = true; + m_breakPoint.m_responseId = ++m_responseId; + m_breakPoint.m_sourceId = m_sourceId; + m_breakPoint.m_lineNumber = line + 1; + m_breakPoint.m_threadId = 0; + + gmMachineSetBreakPoint(&m_session, m_responseId, m_sourceId, line + 1, 0, enabled ? 1 : 0); + } +} + +void CChildView::OnUpdateToggleBreakpoint(CCmdUI* pCmdUI) +{ + pCmdUI->Enable((m_currentDebugThread != 0)); +} + + +void CChildView::OnBreakAllThreads() +{ + if(m_connected && m_debugging) + { + std::list::iterator it; + for(it = m_threads.begin(); it != m_threads.end(); ++it) + { + gmMachineBreak(&m_session, it->m_id); + } + } +} + +void CChildView::OnUpdateBreakAllThreads(CCmdUI* pCmdUI) +{ + pCmdUI->Enable((m_debugging != 0)); +} + +void CChildView::OnResumeAllThreads() +{ + if(m_connected && m_debugging) + { + std::list::iterator it; + for(it = m_threads.begin(); it != m_threads.end(); ++it) + { + // send run command + gmMachineRun(&m_session, it->m_id); + } + } +} + +void CChildView::OnUpdateResumeAllThreads(CCmdUI* pCmdUI) +{ + pCmdUI->Enable((m_debugging != 0)); +} + + +void CChildView::OnNMDblclkCallstack(NMHDR *pNMHDR, LRESULT *pResult) +{ + int selected = m_callstack.GetSelectionMark(); + if (selected != -1 && m_currentDebugThread > 0) + { + gmMachineGetContext(&m_session, m_currentDebugThread, selected); + } + + *pResult = 0; +} + +void CChildView::OnNMDblclkThreadstack(NMHDR *pNMHDR, LRESULT *pResult) +{ + // they have selected a thread, break + *pResult = 0; +} + + +void CChildView::OnNMClkThreadstack(NMHDR *pNMHDR, LRESULT *pResult) +{ + int selected = m_threadsWindow.GetSelectionMark(); + if(selected != -1) + { + DWORD user = m_threadsWindow.GetItemData(selected); + if(user) + { + + ThreadInfo * info = (ThreadInfo *) user; + gmMachineGetContext(&m_session, info->m_id, 0); + } + } + *pResult = 0; +} + + +void CChildView::OnBreakCurrentThread() +{ + if(m_currentDebugThread != 0) + { + gmMachineBreak(&m_session, m_currentDebugThread); + } +} + +void CChildView::OnUpdateBreakCurrentThread(CCmdUI* pCmdUI) +{ + pCmdUI->Enable((m_currentDebugThread != 0)); +} diff --git a/vscript/languages/gm/src/gmd/ChildView.h b/vscript/languages/gm/src/gmd/ChildView.h new file mode 100644 index 00000000..ab4b8cb2 --- /dev/null +++ b/vscript/languages/gm/src/gmd/ChildView.h @@ -0,0 +1,157 @@ +// ChildView.h : interface of the CChildView class +// +///////////////////////////////////////////////////////////////////////////// +// See Copyright Notice in gmMachine.h + +#if !defined(AFX_CHILDVIEW_H__43C2AE53_727B_457A_B67D_FB0A1B5D1BE4__INCLUDED_) +#define AFX_CHILDVIEW_H__43C2AE53_727B_457A_B67D_FB0A1B5D1BE4__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "gmDebugger.h" +#include "NetServer.h" +#include "ScintillaEdit.h" +#include + + +#define GM_DEBUGGER_PORT 49001 + +// Fwd decls +class GMLangSettings; + +struct gmdBreakPoint +{ + int m_enabled; + int m_allThreads; + int m_responseId; + int m_lineNumber; + int m_threadId; + int m_sourceId; +}; +///////////////////////////////////////////////////////////////////////////// +// CChildView window + +class CChildView : public CWnd +{ +// Construction +public: + CChildView(); + +// Attributes +public: + +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CChildView) + protected: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CChildView(); + + // + // GM Debug Members + // + + nServer m_networkServer; // network server + + CListCtrl m_locals; // local variable window + CListCtrl m_callstack; // callstack window + CEdit m_outputWindow; // output message window + ScintillaEdit m_scintillaEdit; // source window + HMODULE m_scintillaDll; + GMLangSettings * m_langSettings; + + std::list m_outputLines; + + // Source + struct Source + { + char * m_source; + unsigned int m_id; + Source * m_next; + }; + + int m_currentCallFrame; + Source * m_sources; // list of source code retrieved from the gm machine being debugged + unsigned int m_sourceId; // source id of the source code currently being viewed, 0 for none + int m_currentDebugThread; // thread id of the current context thread + int m_currentPos; // execute pos. -1 for invalid. + gmdBreakPoint m_breakPoint; // last break point command + int m_responseId; // current rolling response id + char * m_unpackBuffer; // current message unpacking buffer + int m_unpackBufferSize; // current message unpacking buffer size + bool m_connected; // is our network port open??? + bool m_debugging; + int m_lineNumberOnSourceRcv; + + gmDebuggerSession m_session; + + // Threads + struct ThreadInfo + { + int m_id; + int m_state; + }; + std::list m_threads; // current running threads. + + void Log(const char * a_message); + bool SetSource(unsigned int a_sourceId, const char * a_source = NULL); + bool Open(unsigned short a_port); + void SetLine(int a_line); + void ClearCurrentContext(); + void Disconnect(); + + // threads + CListCtrl m_threadsWindow; // thread window + void FindAddThread(int a_threadId, int a_state, bool a_select = false); // + void RemoveThread(int a_threadId); + void UpdateThreadWindow(); + + BOOL OnIdle(); + + // Generated message map functions +protected: + //{{AFX_MSG(CChildView) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnPaint(); + afx_msg void OnStepInto(); + afx_msg void OnUpdateStepInto(CCmdUI* pCmdUI); + afx_msg void OnStepOut(); + afx_msg void OnUpdateStepOut(CCmdUI* pCmdUI); + afx_msg void OnStepOver(); + afx_msg void OnUpdateStepOver(CCmdUI* pCmdUI); + afx_msg void OnGo(); + afx_msg void OnUpdateGo(CCmdUI* pCmdUI); + afx_msg void OnStopDebugging(); + afx_msg void OnUpdateStopDebugging(CCmdUI* pCmdUI); + afx_msg void OnToggleBreakpoint(); + afx_msg void OnUpdateToggleBreakpoint(CCmdUI* pCmdUI); + afx_msg void OnNMDblclkCallstack(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnNMDblclkThreadstack(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnNMClkThreadstack(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnBreakAllThreads(); + afx_msg void OnUpdateBreakAllThreads(CCmdUI* pCmdUI); + afx_msg void OnResumeAllThreads(); + afx_msg void OnUpdateResumeAllThreads(CCmdUI* pCmdUI); + afx_msg void OnBreakCurrentThread(); + afx_msg void OnUpdateBreakCurrentThread(CCmdUI* pCmdUI); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_CHILDVIEW_H__43C2AE53_727B_457A_B67D_FB0A1B5D1BE4__INCLUDED_) diff --git a/vscript/languages/gm/src/gmd/GMLangSettings.cpp b/vscript/languages/gm/src/gmd/GMLangSettings.cpp new file mode 100644 index 00000000..0f7f9605 --- /dev/null +++ b/vscript/languages/gm/src/gmd/GMLangSettings.cpp @@ -0,0 +1,136 @@ +#include "StdAfx.h" +#include "gmlangsettings.h" +#include "include/SciLexer.h" + + +#ifdef _DEBUG + #define new DEBUG_NEW + #undef THIS_FILE + static char THIS_FILE[] = __FILE__; +#endif + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +GMLangSettings::GMLangSettings(void) +{ + // Just using the C++ Lexer. It is not perfect, but a pretty close match without modification + lexerId = SCLEX_CPP; + +#if 1 + // Black on White scheme + defaultStyle.background = RGB(255, 255, 255); + defaultStyle.foreground = RGB(0, 0, 0); + + AddStyle(new StyleSettings("Default", SCE_C_DEFAULT)); + AddStyle(new StyleSettings("Comment", SCE_C_COMMENT, RGB( 0, 150, 0))); + AddStyle(new StyleSettings("Comment Line", SCE_C_COMMENTLINE, RGB( 0, 150, 0))); + AddStyle(new StyleSettings("Comment Doc", SCE_C_COMMENTDOC, RGB( 0, 150, 0))); + AddStyle(new StyleSettings("Comment line doc", SCE_C_COMMENTLINEDOC, RGB( 0, 150, 0))); + AddStyle(new StyleSettings("Number", SCE_C_NUMBER, RGB(150, 0, 150))); + AddStyle(new StyleSettings("UUID", SCE_C_UUID)); + AddStyle(new StyleSettings("Preprocessor", SCE_C_PREPROCESSOR, RGB( 0, 150, 150))); + AddStyle(new StyleSettings("Operator", SCE_C_OPERATOR)); + AddStyle(new StyleSettings("Identifier", SCE_C_IDENTIFIER)); + AddStyle(new StyleSettings("String", SCE_C_STRING, RGB(150, 0, 150))); + AddStyle(new StyleSettings("String EOL", SCE_C_STRINGEOL, RGB(150, 0, 150))); + AddStyle(new StyleSettings("Character", SCE_C_CHARACTER, RGB(150, 0, 150))); + AddStyle(new StyleSettings("Verbatim", SCE_C_VERBATIM)); + AddStyle(new StyleSettings("Reg Ex", SCE_C_REGEX)); + AddStyle(new StyleSettings("Keyword 1", SCE_C_WORD, RGB( 0, 0, 150))); + AddStyle(new StyleSettings("Keyword 2", SCE_C_WORD2, RGB(150, 0, 0))); + AddStyle(new StyleSettings("Commented Doc Keyword", SCE_C_COMMENTDOCKEYWORD, RGB( 0, 150, 0))); + AddStyle(new StyleSettings("Commented Doc Keyword Error", SCE_C_COMMENTDOCKEYWORDERROR, RGB( 0, 150, 0))); +#endif + +#if 0 + // White on Blue scheme + defaultStyle.background = RGB(0, 0, 128); + defaultStyle.foreground = RGB(192, 192, 192); + + AddStyle(new StyleSettings("Default", SCE_C_DEFAULT)); + AddStyle(new StyleSettings("Comment", SCE_C_COMMENT, RGB(128, 128, 128))); + AddStyle(new StyleSettings("Comment Line", SCE_C_COMMENTLINE, RGB(128, 128, 128))); + AddStyle(new StyleSettings("Comment Doc", SCE_C_COMMENTDOC, RGB(128, 128, 128))); + AddStyle(new StyleSettings("Comment line doc", SCE_C_COMMENTLINEDOC, RGB(128, 128, 128))); + AddStyle(new StyleSettings("Number", SCE_C_NUMBER, RGB( 0, 222, 222))); + AddStyle(new StyleSettings("UUID", SCE_C_UUID)); + AddStyle(new StyleSettings("Preprocessor", SCE_C_PREPROCESSOR, RGB( 0, 222, 222))); + AddStyle(new StyleSettings("Operator", SCE_C_OPERATOR)); + AddStyle(new StyleSettings("Identifier", SCE_C_IDENTIFIER)); + AddStyle(new StyleSettings("String", SCE_C_STRING, RGB( 0, 236, 0))); + AddStyle(new StyleSettings("String EOL", SCE_C_STRINGEOL, RGB( 0, 236, 0))); + AddStyle(new StyleSettings("Character", SCE_C_CHARACTER, RGB( 0, 236, 0))); + AddStyle(new StyleSettings("Verbatim", SCE_C_VERBATIM)); + AddStyle(new StyleSettings("Reg Ex", SCE_C_REGEX)); + AddStyle(new StyleSettings("Keyword 1", SCE_C_WORD, RGB( 0, 222, 222))); + AddStyle(new StyleSettings("Keyword 2", SCE_C_WORD2, RGB( 0, 222, 222))); + AddStyle(new StyleSettings("Commented Doc Keyword", SCE_C_COMMENTDOCKEYWORD, RGB(128, 128, 128))); + AddStyle(new StyleSettings("Commented Doc Keyword Error", SCE_C_COMMENTDOCKEYWORDERROR, RGB(128, 128, 128))); +#endif + + int styleIndex; + StyleSettings *style; + + if ((styleIndex = FindStyle("Operator")) != -1) + { + style = GetStyle(styleIndex); + style->bold = true; + } + + if ((styleIndex = FindStyle("Operator")) != -1) + { + style = GetStyle(styleIndex); + style->bold = true; + } + + if ((styleIndex = FindStyle("Keyword 1")) != -1) + { + style = GetStyle(styleIndex); + style->bold = true; + } + + if ((styleIndex = FindStyle("Keyword 2")) != -1) + { + style = GetStyle(styleIndex); + style->bold = true; + } + + for (int i = 0; i < GetStyleCount(); ++i) + { + GetStyle(i)->SetFont("Courier New"); + } + + KeywordSet *keywords; + CString str; + + keywords = new KeywordSet; + keywords->setId = 0; + str = "if else for foreach in and or while dowhile function return" + " continue break null global local member table true false this"; + keywords->SetKeywords(str); + AddKeywordSet(keywords); + + keywords = new KeywordSet; + keywords->setId = 1; + + str = "debug typeId typeName typeRegisterOperator typeRegisterVariable" + "sysCollectGarbage sysGetMemoryUsage sysSetDesiredMemoryUsageHard" + "sysSetDesiredMemoryUsageSoft sysSetDesiredMemoryUsageAuto sysGetDesiredMemoryUsageHard" + "sysGetDesiredMemoryUsageSoft sysTime doString globals threadTime" + "threadId threadAllIds threadKill threadKillAll thread yield exit" + "assert sleep signal block stateSet stateSetOnThread stateGet" + "stateGetLast stateSetExitFunction tableCount tableDuplicate" + "print format"; + + keywords->SetKeywords(str); + AddKeywordSet(keywords); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +GMLangSettings::~GMLangSettings(void) +{ +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- diff --git a/vscript/languages/gm/src/gmd/GMLangSettings.h b/vscript/languages/gm/src/gmd/GMLangSettings.h new file mode 100644 index 00000000..0ed184ad --- /dev/null +++ b/vscript/languages/gm/src/gmd/GMLangSettings.h @@ -0,0 +1,10 @@ +#pragma once + +#include "LanguageSettings.h" + +class GMLangSettings : public LanguageSettings +{ +public: + GMLangSettings(); + virtual ~GMLangSettings(); +}; diff --git a/vscript/languages/gm/src/gmd/LanguageSettings.cpp b/vscript/languages/gm/src/gmd/LanguageSettings.cpp new file mode 100644 index 00000000..cfcc1509 --- /dev/null +++ b/vscript/languages/gm/src/gmd/LanguageSettings.cpp @@ -0,0 +1,452 @@ +#include "StdAfx.h" +#include "languagesettings.h" + + +#ifdef _DEBUG + #define new DEBUG_NEW + #undef THIS_FILE + static char THIS_FILE[] = __FILE__; +#endif + + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +StyleSettings::StyleSettings() +{ + InitDefaults(); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +StyleSettings::StyleSettings(const CString &name, int typeId) +{ + font = NULL; + InitDefaults(); + this->name = name; + this->typeId = typeId; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +StyleSettings::StyleSettings(const CString &name, int typeId, COLORREF foreground) +{ + font = NULL; + InitDefaults(); + this->name = name; + this->typeId = typeId; + this->foreground = foreground; + defaultForeground = false; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +StyleSettings::StyleSettings(const CString &name, int typeId, COLORREF foreground, COLORREF background) +{ + font = NULL; + InitDefaults(); + this->name = name; + this->typeId = typeId; + this->foreground = foreground; + this->background = background; + defaultForeground = false; + defaultBackground = false; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +StyleSettings::~StyleSettings() +{ + delete [] font; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void StyleSettings::InitDefaults() +{ + name = ""; + typeId = 0; + foreground = RGB(0, 0, 0); + background = RGB(255, 255, 255); + defaultForeground = true; + defaultBackground = true; + size = -1; + delete [] font; + font = NULL; + bold = false; + italic = false; + underline = false; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void StyleSettings::SetFont(const char *str) +{ + delete [] font; + font = NULL; + if (str) + { + font = new char[strlen(str)+1]; + strcpy(font, str); + } +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +KeywordSet::KeywordSet() +: setId(-1), + keywords(NULL) +{ +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +KeywordSet::~KeywordSet() +{ + delete [] keywords; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void KeywordSet::SetKeywords(const char *str) +{ + delete [] keywords; + keywords = NULL; + if (str) + { + keywords = new char[strlen(str)+1]; + strcpy(keywords, str); + } +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +LanguageSettings::LanguageSettings(void) +: lexerId(0), + styleBits(5), + defaultStyle("Default", STYLE_DEFAULT, RGB(0, 0, 0), RGB(255, 255, 255)), + tabWidth(2), + tabsToSpaces(true) +{ + defaultStyle.size = 10; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +LanguageSettings::~LanguageSettings(void) +{ + int index; + for(index=0; index < styleSettings.GetSize(); ++index) + { + StyleSettings * ss = GetStyle(index); + delete ss; + } + styleSettings.RemoveAll(); + + for(index=0; index < keywordSets.GetSize(); ++index) + { + KeywordSet * ks = GetKeywordSet(index); + delete ks; + } + keywordSets.RemoveAll(); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool LanguageSettings::AddStyle(StyleSettings *settings) +{ + if (FindStyle(settings) == -1 && FindStyle(settings->name) == -1 && FindStyle(settings->typeId) == -1) + { + styleSettings.Add(settings); + return true; + } + return false; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool LanguageSettings::RemoveStyle(StyleSettings *settings, bool deleteData) +{ + int count = styleSettings.GetSize(); + for (int i = 0; i < count; ++i) + { + if (styleSettings.GetAt(i) == settings) + { + styleSettings.RemoveAt(i); + if (deleteData) + delete settings; + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool LanguageSettings::RemoveStyle(const CString &name, bool deleteData) +{ + int count = styleSettings.GetSize(); + for (int i = 0; i < count; ++i) + { + StyleSettings *c = GetStyle(i); + if (c->name.Compare(name) == 0) + { + styleSettings.RemoveAt(i); + if (deleteData) + delete c; + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool LanguageSettings::RemoveStyle(int typeId, bool deleteData) +{ + int count = styleSettings.GetSize(); + for (int i = 0; i < count; ++i) + { + StyleSettings *c = GetStyle(i); + if (c->typeId == typeId) + { + styleSettings.RemoveAt(i); + if (deleteData) + delete c; + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int LanguageSettings::FindStyle(StyleSettings *settings) const +{ + int count = styleSettings.GetSize(); + for (int i = 0; i < count; ++i) + { + if (GetStyle(i) == settings) + return i; + } + + return -1; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int LanguageSettings::FindStyle(const CString &name) const +{ + int count = styleSettings.GetSize(); + for (int i = 0; i < count; ++i) + { + if (GetStyle(i)->name.Compare(name) == 0) + return i; + } + + return -1; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int LanguageSettings::FindStyle(int typeId) const +{ + int count = styleSettings.GetSize(); + for (int i = 0; i < count; ++i) + { + if (GetStyle(i)->typeId == typeId) + return i; + } + + return -1; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int LanguageSettings::GetStyleCount() const +{ + return styleSettings.GetSize(); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +StyleSettings *LanguageSettings::GetStyle(int i) +{ + return reinterpret_cast(styleSettings.GetAt(i)); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +const StyleSettings *LanguageSettings::GetStyle(int i) const +{ + return reinterpret_cast(styleSettings.GetAt(i)); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool LanguageSettings::AddKeywordSet(KeywordSet *set) +{ + if (FindKeywordSet(set) == -1 && FindKeywordSet(set->setId) == -1) + { + keywordSets.Add(set); + return true; + } + return false; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool LanguageSettings::RemoveKeywordSet(KeywordSet *set, bool deleteData) +{ + int count = GetKeywordSetCount(); + for (int i = 0; i < count; ++i) + { + KeywordSet *ks = GetKeywordSet(i); + if (ks == set) + { + keywordSets.RemoveAt(i); + if (deleteData) + delete ks; + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool LanguageSettings::RemoveKeywordSet(int setId, bool deleteData) +{ + int count = GetKeywordSetCount(); + for (int i = 0; i < count; ++i) + { + KeywordSet *ks = GetKeywordSet(i); + if (ks->setId == setId) + { + keywordSets.RemoveAt(i); + if (deleteData) + delete ks; + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int LanguageSettings::FindKeywordSet(KeywordSet *set) const +{ + int count = GetKeywordSetCount(); + for (int i = 0; i < count; ++i) + { + const KeywordSet *ks = GetKeywordSet(i); + if (ks == set) + return i; + } + + return -1; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int LanguageSettings::FindKeywordSet(int setId) const +{ + int count = GetKeywordSetCount(); + for (int i = 0; i < count; ++i) + { + const KeywordSet *ks = GetKeywordSet(i); + if (ks->setId == setId) + return i; + } + + return -1; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int LanguageSettings::GetKeywordSetCount() const +{ + return keywordSets.GetSize(); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +KeywordSet *LanguageSettings::GetKeywordSet(int i) +{ + return reinterpret_cast(keywordSets.GetAt(i)); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +const KeywordSet *LanguageSettings::GetKeywordSet(int i) const +{ + return reinterpret_cast(keywordSets.GetAt(i)); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void LanguageSettings::Apply(ScintillaEdit &scintilla) const +{ + scintilla.SetLexer(lexerId); + scintilla.SetStyleBits(styleBits); + + scintilla.SetTabWidth(tabWidth); + scintilla.SetUseTabs(!tabsToSpaces); + + int i; + int count = GetKeywordSetCount(); + for (i = 0; i < count; ++i) + { + const KeywordSet *set = GetKeywordSet(i); + if (set->keywords) + scintilla.SetKeywords(set->setId, set->keywords); + } + +// scintilla.SetWhiteSpaceBGColour(true, defaultBackground); +// scintilla.SetWhiteSpaceFGColour(true, defaultForeground); + + ApplyStyle(scintilla, defaultStyle); + /// Copy default style to all. + scintilla.StyleClearAll(); + + scintilla.SetCaretColour(defaultStyle.foreground); + scintilla.SetSelectionBGColour(true, defaultStyle.foreground); + scintilla.SetSelectionFGColour(true, defaultStyle.background); + + count = GetStyleCount(); + for (i = 0; i < count; ++i) + { + const StyleSettings *style = GetStyle(i); + ASSERT(style); + ApplyStyle(scintilla, *style); + } + + scintilla.Colourise(0, -1); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void LanguageSettings::ApplyStyle(ScintillaEdit &scintilla, const StyleSettings &style) const +{ + if (!style.defaultForeground) + scintilla.StyleSetFGColour(style.typeId, style.foreground); + + if (!style.defaultBackground) + scintilla.StyleSetBGColour(style.typeId, style.background); + + if (style.size > 0) + scintilla.StyleSetSize(style.typeId, style.size); + if (style.font) + scintilla.StyleSetFont(style.typeId, style.font); + + scintilla.StyleSetBold(style.typeId, style.bold); + scintilla.StyleSetItalic(style.typeId, style.italic); + scintilla.StyleSetUnderline(style.typeId, style.underline); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- diff --git a/vscript/languages/gm/src/gmd/LanguageSettings.h b/vscript/languages/gm/src/gmd/LanguageSettings.h new file mode 100644 index 00000000..d46a103d --- /dev/null +++ b/vscript/languages/gm/src/gmd/LanguageSettings.h @@ -0,0 +1,101 @@ +#pragma once + +#include "ScintillaEdit.h" + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +struct StyleSettings +{ + CString name; + int typeId; + COLORREF foreground; + COLORREF background; + bool defaultForeground; + bool defaultBackground; + int size; + char * font; + bool bold; + bool italic; + bool underline; + + StyleSettings(); + StyleSettings(const CString &name, int typeId); + StyleSettings(const CString &name, int typeId, COLORREF foreground); + StyleSettings(const CString &name, int typeId, COLORREF foreground, COLORREF background); + ~StyleSettings(); + + void InitDefaults(); + + void SetFont(const char *str); +}; + +struct KeywordSet +{ + int setId; // 0 to 9. + char * keywords; // space, \t or \n separated. + + KeywordSet(); + virtual ~KeywordSet(); + + void SetKeywords(const char *str); +}; + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +class LanguageSettings +{ +public: + LanguageSettings(void); + virtual ~LanguageSettings(void); + + inline void SetLexerId(int id) { lexerId = id; } + inline int GetLexerId() const { return lexerId; } + + inline void SetStyleBits(int bits) { styleBits = bits; } + inline int GetStyleBits() const { return styleBits; } + + StyleSettings &GetDefaultStyle() { return defaultStyle; } + const StyleSettings &GetDefaultStyle() const { return defaultStyle; } + + bool AddStyle(StyleSettings *settings); + + bool RemoveStyle(StyleSettings *settings, bool deleteData = true); + bool RemoveStyle(const CString &name, bool deleteData = true); + bool RemoveStyle(int typeId, bool deleteData = true); + + int FindStyle(StyleSettings *settings) const; + int FindStyle(const CString &name) const; + int FindStyle(int typeId) const; + + int GetStyleCount() const; + StyleSettings *GetStyle(int i); + const StyleSettings *GetStyle(int i) const; + + bool AddKeywordSet(KeywordSet *set); + + bool RemoveKeywordSet(KeywordSet *set, bool deleteData = true); + bool RemoveKeywordSet(int setId, bool deleteData = true); + + int FindKeywordSet(KeywordSet *set) const; + int FindKeywordSet(int setId) const; + + int GetKeywordSetCount() const; + KeywordSet *GetKeywordSet(int i); + const KeywordSet *GetKeywordSet(int i) const; + + void Apply(ScintillaEdit &scintilla) const; + +protected: + int lexerId; + int tabWidth; + bool tabsToSpaces; + int styleBits; + CPtrArray styleSettings; + CPtrArray keywordSets; + StyleSettings defaultStyle; + + void ApplyStyle(ScintillaEdit &scintilla, const StyleSettings &style) const; +}; + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- diff --git a/vscript/languages/gm/src/gmd/MainFrm.cpp b/vscript/languages/gm/src/gmd/MainFrm.cpp new file mode 100644 index 00000000..102af89a --- /dev/null +++ b/vscript/languages/gm/src/gmd/MainFrm.cpp @@ -0,0 +1,150 @@ +// MainFrm.cpp : implementation of the CMainFrame class +// +// See Copyright Notice in gmMachine.h + +#include "StdAfx.h" +#include "gmd.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#define ID_TIMER_REFRESH 1 + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_WM_TIMER() + ON_WM_SETFOCUS() + ON_WM_CLOSE() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +static UINT indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ +} + +CMainFrame::~CMainFrame() +{ +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + // create a view to occupy the client area of the frame + if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, + CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL)) + { + TRACE0("Failed to create view window\n"); + return -1; + } + + if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP + | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || + !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) + { + TRACE0("Failed to create toolbar\n"); + return -1; // fail to create + } + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); + EnableDocking(CBRS_ALIGN_ANY); + DockControlBar(&m_wndToolBar); + + if(!SetTimer(ID_TIMER_REFRESH, 1, NULL)) + { + return -1; + } + + return 0; +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ + if( !CFrameWnd::PreCreateWindow(cs) ) + return FALSE; + cs.dwExStyle &= ~WS_EX_CLIENTEDGE; + cs.lpszClass = AfxRegisterWndClass(0); + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers +void CMainFrame::OnSetFocus(CWnd* pOldWnd) +{ + // forward focus to the view window + m_wndView.SetFocus(); +} + +BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) +{ + // let the view have first crack at the command + if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)) + return TRUE; + + // otherwise, do default handling + return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); +} + + +void CMainFrame::OnClose() +{ + KillTimer(ID_TIMER_REFRESH); + // TODO: Add your message handler code here and/or call default + gmMachineQuit(&m_wndView.m_session); + Sleep(500); // wait for quit message to post (hack) + m_wndView.Disconnect(); + CFrameWnd::OnClose(); +} + + +void CMainFrame::OnTimer(UINT nIDEvent) +{ + m_wndView.OnIdle(); + CFrameWnd::OnTimer(nIDEvent); +} diff --git a/vscript/languages/gm/src/gmd/MainFrm.h b/vscript/languages/gm/src/gmd/MainFrm.h new file mode 100644 index 00000000..040e9568 --- /dev/null +++ b/vscript/languages/gm/src/gmd/MainFrm.h @@ -0,0 +1,67 @@ +// MainFrm.h : interface of the CMainFrame class +// +///////////////////////////////////////////////////////////////////////////// +// See Copyright Notice in gmMachine.h + +#if !defined(AFX_MAINFRM_H__E661DED7_A894_4B2C_AD2C_D13F480A328B__INCLUDED_) +#define AFX_MAINFRM_H__E661DED7_A894_4B2C_AD2C_D13F480A328B__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "ChildView.h" + +class CMainFrame : public CFrameWnd +{ + +public: + CMainFrame(); +protected: + DECLARE_DYNAMIC(CMainFrame) + +// Attributes +public: + +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + + CChildView * GetChildView() { return &m_wndView; } + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + CToolBar m_wndToolBar; + CChildView m_wndView; + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSetFocus(CWnd *pOldWnd); + afx_msg void OnClose(); + afx_msg void OnTimer(UINT nIDEvent); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_MAINFRM_H__E661DED7_A894_4B2C_AD2C_D13F480A328B__INCLUDED_) diff --git a/vscript/languages/gm/src/gmd/NetServer.cpp b/vscript/languages/gm/src/gmd/NetServer.cpp new file mode 100644 index 00000000..d022e892 --- /dev/null +++ b/vscript/languages/gm/src/gmd/NetServer.cpp @@ -0,0 +1,388 @@ +// See Copyright Notice in gmMachine.h + +#include "StdAfx.h" +#include "NetServer.h" +#include +#include +#include +#include +#include +#include +#include + +#undef SendMessage // stupid windows + +struct nPacket +{ + int id; // id == 0x4fe27d9a + int len; +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// QUEUE +// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +struct nQueueNode +{ + char * m_buffer; + int m_len; + nQueueNode * m_next; +}; + +class nQueue +{ +public: + + nQueue() + { + m_queue = NULL; + m_lastDeQueue = NULL; + m_mutex = CreateMutex(NULL, FALSE, NULL); + } + + ~nQueue() + { + WaitForSingleObject(m_mutex, INFINITE); + + int a; + while(DeQueue(a)); + DeQueue(a); + + ReleaseMutex(m_mutex); + + // destroy mutex... todo + } + + bool EnQueue(const char * a_buffer, int a_len) + { + WaitForSingleObject(m_mutex, INFINITE); + + nQueueNode * node = new nQueueNode; + node->m_len = a_len; + node->m_buffer = new char[a_len]; + memcpy(node->m_buffer, a_buffer, a_len); + node->m_next = NULL; + + // add to end of list + nQueueNode ** n = &m_queue; + while(*n) n = &(*n)->m_next; + *n = node; + + ReleaseMutex(m_mutex); + + return true; + } + + const char * DeQueue(int &a_len) + { + const char * ret = NULL; + + WaitForSingleObject(m_mutex, INFINITE); + + if(m_lastDeQueue) + { + delete[] m_lastDeQueue->m_buffer; + delete m_lastDeQueue; + m_lastDeQueue = NULL; + } + + if(m_queue) + { + m_lastDeQueue = m_queue; + m_queue = m_queue->m_next; + a_len = m_lastDeQueue->m_len; + ret = m_lastDeQueue->m_buffer; + } + + ReleaseMutex(m_mutex); + + return ret; + } + + bool IsEmpty() { return (m_queue == NULL); } + +private: + + HANDLE m_mutex; + + nQueueNode * m_lastDeQueue; + nQueueNode * m_queue; +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// SERVER +// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +struct nServerData +{ + SOCKET server; + SOCKET client; + nQueue messages; + CRITICAL_SECTION criticalSection; + bool threadAlive; +}; + + + +nServer::nServer() +{ + nServerData * sd = new nServerData; + sd->threadAlive = false; + sd->server = sd->client = INVALID_SOCKET; + InitializeCriticalSection(&sd->criticalSection); + m_data = sd; +} + + + +nServer::~nServer() +{ + Done(); +} + + + +void nServer::Close() +{ + nServerData * sd = (nServerData *) m_data; + EnterCriticalSection(&sd->criticalSection); + bool wait = false; + + if(sd->client != INVALID_SOCKET) + { + wait = true; + closesocket(sd->client); + sd->client = INVALID_SOCKET; + } + if(sd->server != INVALID_SOCKET) + { + closesocket(sd->server); + sd->server = INVALID_SOCKET; + } + + LeaveCriticalSection(&sd->criticalSection); + + // wait for the thread to die. + while(wait && sd->threadAlive) + { + _sleep(0); + } + + WSACleanup(); +} + + + +void nServer::Done() +{ + if(m_data) + { + Close(); + nServerData * sd = (nServerData *) m_data; + DeleteCriticalSection(&sd->criticalSection); + delete sd; + m_data = NULL; + } +} + + + + +bool nServer::IsConnected() +{ + bool result = false; + nServerData * sd = (nServerData *) m_data; + EnterCriticalSection(&sd->criticalSection); + if(sd->client != INVALID_SOCKET) + { + result = true; + } + LeaveCriticalSection(&sd->criticalSection); + return result; +} + + + +bool nServer::nSendMessage(const char * a_buffer, int a_len) +{ + bool res = false; + nServerData * sd = (nServerData *) m_data; + nPacket packet; + packet.id = 0x4fe27d9a; + packet.len = a_len; + + EnterCriticalSection(&sd->criticalSection); + if(sd->client != INVALID_SOCKET) + { + send(sd->client, (const char *) &packet, sizeof(nPacket), 0); + send(sd->client, (const char *) a_buffer, a_len, 0); + res = true; + } + LeaveCriticalSection(&sd->criticalSection); + return res; +} + + + +const char * nServer::PumpMessage(int &a_len) +{ + nServerData * sd = (nServerData *) m_data; + const char * buffer = sd->messages.DeQueue(a_len); + return buffer; +} + + +// +// nServerThread +// + +void nServerThread(void * param) +{ + nServerData * sd = (nServerData *) param; + EnterCriticalSection(&sd->criticalSection); + sd->threadAlive = true; + SOCKET client = INVALID_SOCKET; + SOCKET server = sd->server; + LeaveCriticalSection(&sd->criticalSection); + + sockaddr_in from; + int fromlen = sizeof(from), n; + char * dbuffer = NULL; + + while(true) + { + client = accept(server, (struct sockaddr*) &from, &fromlen); + + if(client != INVALID_SOCKET) + { + EnterCriticalSection(&sd->criticalSection); + sd->client = client; + LeaveCriticalSection(&sd->criticalSection); + + char buffer[4096]; + char * sbp; + int state = 0; // 0 searching for packet, 1 getting message + int need = sizeof(nPacket); + + // packet header + nPacket packet; + char * dbp = (char *) &packet; + + // packet data + int dbufferSize = 0; + + // read loop + for(;;) + { + // read + n = recv(client, buffer, 4096, 0); + if(n == SOCKET_ERROR || n == 0) break; + sbp = buffer; + + // consume + while(n > 0) + { + int have = (n > need) ? need : n; + need -= have; + n -= have; + memcpy(dbp, sbp, have); + sbp += have; + dbp += have; + + // can we change state? + if(need == 0) + { + if(state == 0) + { + if(packet.id != 0x4fe27d9a) goto terror; + state = 1; + need = packet.len; + + // allocate the dbuffer + if(need > dbufferSize) + { + if(dbuffer) { delete[] dbuffer; } + dbufferSize = need + 512; + dbuffer = new char[dbufferSize]; + } + dbp = dbuffer; + } + else if(state == 1) + { + sd->messages.EnQueue(dbuffer, packet.len); + dbp = (char *) &packet; + need = sizeof(nPacket); + state = 0; + } + } + } + } + + break; + } + } + +terror: + + if(dbuffer) { delete[] dbuffer; } + + EnterCriticalSection(&sd->criticalSection); + sd->threadAlive = false; + LeaveCriticalSection(&sd->criticalSection); + + _endthread(); +} + + + +bool nServer::Open(short a_port) +{ + nServerData * sd = (nServerData *) m_data; + + WSADATA wsaData; + sockaddr_in local; + int wsaret = WSAStartup(0x101, &wsaData); + if(wsaret != 0) + { + return false; + } + + local.sin_family = AF_INET; + local.sin_addr.s_addr = INADDR_ANY; + local.sin_port=htons((u_short) a_port); + sd->server = socket(AF_INET, SOCK_STREAM, 0); + + if(sd->server == INVALID_SOCKET) + { + return false; + } + + if(bind(sd->server, (sockaddr*) &local, sizeof(local)) != 0) + { + closesocket(sd->server); + sd->server = INVALID_SOCKET; + return false; + } + + if(listen(sd->server, 10) != 0) + { + closesocket(sd->server); + sd->server = INVALID_SOCKET; + return false; + } + + // start the listener thread. + _beginthread(nServerThread, 0, sd); + _sleep(0); + + return true; +} diff --git a/vscript/languages/gm/src/gmd/NetServer.h b/vscript/languages/gm/src/gmd/NetServer.h new file mode 100644 index 00000000..39aa2cd4 --- /dev/null +++ b/vscript/languages/gm/src/gmd/NetServer.h @@ -0,0 +1,29 @@ +#ifndef _NETSERVER_H_ +#define _NETSERVER_H_ + +// See Copyright Notice in gmMachine.h + +// +// nServer +// +class nServer +{ +public: + + nServer(); + ~nServer(); + + bool Open(short a_port); + void Close(); + void Done(); + bool IsConnected(); + + bool nSendMessage(const char * a_buffer, int a_len); + const char * PumpMessage(int &a_len); + +private: + + void * m_data; +}; + +#endif //_NETSERVER_H_ \ No newline at end of file diff --git a/vscript/languages/gm/src/gmd/Resource.h b/vscript/languages/gm/src/gmd/Resource.h new file mode 100644 index 00000000..5f934398 --- /dev/null +++ b/vscript/languages/gm/src/gmd/Resource.h @@ -0,0 +1,29 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by gmd.rc +// +#define IDD_ABOUTBOX 100 +#define IDR_MAINFRAME 128 +#define IDR_GMDTYPE 129 +#define IDR_WAV_ERROR 130 +#define ID_STEP_INTO 32771 +#define ID_STEP_OVER 32772 +#define ID_STEP_OUT 32773 +#define ID_GO 32774 +#define ID_STOP_DEBUGGING 32775 +#define ID_TOGGLE_BREAKPOINT 32776 +#define ID_BREAK_ALL_THREADS 32777 +#define ID_RESUME_ALL_THREADS 32778 +#define ID_BREAK_CURRENT_THREAD 32779 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 131 +#define _APS_NEXT_COMMAND_VALUE 32780 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/vscript/languages/gm/src/gmd/ScintillaEdit.cpp b/vscript/languages/gm/src/gmd/ScintillaEdit.cpp new file mode 100644 index 00000000..737b0ee6 --- /dev/null +++ b/vscript/languages/gm/src/gmd/ScintillaEdit.cpp @@ -0,0 +1,1817 @@ + +#include "StdAfx.h" +#include "ScintillaEdit.h" + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +ScintillaEdit::ScintillaEdit() +: CWnd() +{ +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +BOOL ScintillaEdit::Attach(HWND hwnd) +{ + static const char *scintillaStr = "Scintilla"; + static const int maxChars = 16; + char className[maxChars]; // Only need enough to match "Scintilla". + if (hwnd) + { + // Get the name of the class used by the hwnd. + GetClassName(hwnd, className, maxChars); + // Now ensure it's of the right type. + if (_stricmp(className, scintillaStr) == 0) + { + return CWnd::Attach(hwnd); + } + } + + return FALSE; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::GetText(int maxChars, char *text) +{ + SendMessage(SCI_GETTEXT, (WPARAM)maxChars, (LPARAM)text); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetText(const char *text) +{ + SendMessage(SCI_SETTEXT, (WPARAM)0, (LPARAM)text); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetSavePoint() +{ + SendMessage(SCI_SETSAVEPOINT); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::GetLine(int line, char *text) +{ + SendMessage(SCI_GETLINE, (WPARAM)line, (LPARAM)text); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::ReplaceSelection(const char *text) +{ + SendMessage(SCI_REPLACESEL, (WPARAM)0, (LPARAM)text); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::GetReadOnly() +{ + return (SendMessage(SCI_GETREADONLY) != 0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetReadOnly(bool readOnly) +{ + SendMessage(SCI_SETREADONLY, (WPARAM)readOnly); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::GetTextRange(TextRange &textRange) +{ + SendMessage(SCI_GETTEXTRANGE, (WPARAM)0, (LPARAM)&textRange); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::GetStyledText(TextRange &textRange) +{ + SendMessage(SCI_GETSTYLEDTEXT, (WPARAM)0, (LPARAM)&textRange); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::AddText(int length, char *text) +{ + SendMessage(SCI_ADDTEXT, (WPARAM)length, (LPARAM)text); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::AddStyledText(int length, char *text) +{ + SendMessage(SCI_ADDSTYLEDTEXT, (WPARAM)length, (LPARAM)text); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::AppendText(int length, char *text) +{ + SendMessage(SCI_APPENDTEXT, (WPARAM)length, (LPARAM)text); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::InsertText(int pos, const char *text) +{ + SendMessage(SCI_INSERTTEXT, (WPARAM)pos, (LPARAM)text); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::ClearAll() +{ + SendMessage(SCI_CLEARALL); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::ClearDocumentStyle() +{ + SendMessage(SCI_CLEARDOCUMENTSTYLE); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +char ScintillaEdit::GetCharAt(int pos) +{ + return (char)SendMessage(SCI_GETCHARAT, (WPARAM)pos); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +char ScintillaEdit::GetStyleAt(int pos) +{ + return (char)SendMessage(SCI_GETSTYLEAT, (WPARAM)pos); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetStyleBits(int bits) +{ + SendMessage(SCI_SETSTYLEBITS, (WPARAM)bits); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetStyleBits() +{ + return (int)SendMessage(SCI_GETSTYLEBITS); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::FindText(int searchFlags, TextToFind &ttf) +{ + return (int)SendMessage(SCI_FINDTEXT, (WPARAM)searchFlags, (LPARAM)&ttf); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetSearchAnchor() +{ + SendMessage(SCI_SEARCHANCHOR); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::SearchNext(int searchFlags, const char *forText) +{ + return (int)SendMessage(SCI_SEARCHNEXT, (WPARAM)searchFlags, (LPARAM)forText); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::SearchPrev(int searchFlags, const char *forText) +{ + return (int)SendMessage(SCI_SEARCHPREV, (WPARAM)searchFlags, (LPARAM)forText); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetTargetStart() +{ + return (int)SendMessage(SCI_GETTARGETSTART); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetTargetStart(int pos) +{ + SendMessage(SCI_SETTARGETSTART, (WPARAM)pos); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetTargetEnd() +{ + return (int)SendMessage(SCI_GETTARGETEND); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetTargetEnd(int pos) +{ + SendMessage(SCI_SETTARGETEND, (WPARAM)pos); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::ReplaceTarget(int length, const char *text) +{ + return (int)SendMessage(SCI_REPLACETARGET, (WPARAM)length, (LPARAM)text); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::ReplaceTargetRegularExpression(int length, const char *text) +{ + return (int)SendMessage(SCI_REPLACETARGETRE, (WPARAM)length, (LPARAM)text); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetSearchFlags() +{ + return (int)SendMessage(SCI_GETSEARCHFLAGS); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetSearchFlags(int flags) +{ + SendMessage(SCI_SETSEARCHFLAGS, (WPARAM)flags); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::SearchInTarget(int length, const char *text) +{ + return (int)SendMessage(SCI_SEARCHINTARGET, (WPARAM)length, (LPARAM)text); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::GetOverType() +{ + return (SendMessage(SCI_GETOVERTYPE) != 0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetOvertType(bool overType) +{ + SendMessage(SCI_SETOVERTYPE, (WPARAM)overType); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::Cut() +{ + SendMessage(SCI_CUT); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::Copy() +{ + SendMessage(SCI_COPY); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::Paste() +{ + SendMessage(SCI_PASTE); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::Clear() +{ + SendMessage(SCI_CLEAR); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::CanPaste() +{ + return SendMessage(SCI_CANPASTE) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetTextLength() +{ + return (int)SendMessage(SCI_GETTEXTLENGTH); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetLineCount() +{ + return (int)SendMessage(SCI_GETLINECOUNT); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetFirstVisibleLine() +{ + return (int)SendMessage(SCI_GETFIRSTVISIBLELINE); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetLinesOnScreen() +{ + return (int)SendMessage(SCI_LINESONSCREEN); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::GetModified() +{ + return SendMessage(SCI_GETMODIFY) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetSelection(int anchorPos, int currentPos) +{ + SendMessage(SCI_SETSEL, (WPARAM)anchorPos, (LPARAM)currentPos); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::GotoPos(int pos) +{ + SendMessage(SCI_GOTOPOS, (WPARAM)pos); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::GotoLine(int line) +{ + SendMessage(SCI_GOTOLINE, (WPARAM)line); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetCurrentPos() +{ + return (int)SendMessage(SCI_GETCURRENTPOS); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetCurrentPos(int pos) +{ + SendMessage(SCI_SETCURRENTPOS, (WPARAM)pos); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetAnchor() +{ + return (int)SendMessage(SCI_GETANCHOR); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetAnchor(int pos) +{ + SendMessage(SCI_SETANCHOR, (WPARAM)pos); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetSelectionStart() +{ + return (int)SendMessage(SCI_GETSELECTIONSTART); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetSelectionStart(int pos) +{ + SendMessage(SCI_SETSELECTIONSTART, (WPARAM)pos); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetSelectionEnd() +{ + return (int)SendMessage(SCI_GETSELECTIONEND); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetSelectionEnd(int pos) +{ + SendMessage(SCI_SETSELECTIONEND, (WPARAM)pos); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SelectAll() +{ + SendMessage(SCI_SELECTALL); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::LineFromPosition(int pos) +{ + return (int)SendMessage(SCI_LINEFROMPOSITION, (WPARAM)pos); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::PositionFromLine(int line) +{ + return (int)SendMessage(SCI_POSITIONFROMLINE, (WPARAM)line); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetLineEndPosition(int line) +{ + return (int)SendMessage(SCI_GETLINEENDPOSITION, (WPARAM)line); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetLineLength(int line) +{ + return (int)SendMessage(SCI_LINELENGTH, (WPARAM)line); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::GetSelectedText(char *text) +{ + SendMessage(SCI_GETSELTEXT, (WPARAM)0, (LPARAM)text); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::GetCurrentLine(int maxChars, char *text) +{ + SendMessage(SCI_GETCURLINE, (WPARAM)maxChars, (LPARAM)text); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::SelectionIsRectangle() +{ + return SendMessage(SCI_SELECTIONISRECTANGLE) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::MoveCaretInsideView() +{ + SendMessage(SCI_MOVECARETINSIDEVIEW); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::WordEndPosition(int position, bool onlyWordCharacters) +{ + return (int)SendMessage(SCI_WORDENDPOSITION, (WPARAM)position, (LPARAM)onlyWordCharacters); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::WordStartPosition(int position, bool onlyWordCharacters) +{ + return (int)SendMessage(SCI_WORDSTARTPOSITION, (WPARAM)position, (LPARAM)onlyWordCharacters); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::TextWidth(int styleNumber, char *text) +{ + return (int)SendMessage(SCI_TEXTWIDTH, (WPARAM)styleNumber, (LPARAM)text); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::TextHeight(int line) +{ + return (int)SendMessage(SCI_TEXTHEIGHT, (WPARAM)line); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetColumn(int pos) +{ + return (int)SendMessage(SCI_GETCOLUMN, (WPARAM)pos); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::PositionFromPoint(int x, int y) +{ + return (int)SendMessage(SCI_POSITIONFROMPOINT, (WPARAM)x, (LPARAM)y); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::PositionFromPointClose(int x, int y) +{ + return (int)SendMessage(SCI_POSITIONFROMPOINTCLOSE, (WPARAM)x, (LPARAM)y); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::PointXFromPosition(int pos) +{ + return (int)SendMessage(SCI_POINTXFROMPOSITION, (WPARAM)0, (LPARAM)pos); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::PointYFromPosition(int pos) +{ + return (int)SendMessage(SCI_POINTYFROMPOSITION, (WPARAM)0, (LPARAM)pos); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::HideSelection(bool hide) +{ + return SendMessage(SCI_HIDESELECTION, (WPARAM)hide) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::LineScroll(int column, int line) +{ + SendMessage(SCI_LINESCROLL, (WPARAM)column, (LPARAM)line); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::ScrollToCaret() +{ + SendMessage(SCI_SCROLLCARET); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetXCaretPolicy(int caretPolicy, int caretStop) +{ + SendMessage(SCI_SETXCARETPOLICY, (WPARAM)caretPolicy, (LPARAM)caretStop); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetYCaretPolicy(int caretPolicy, int caretStop) +{ + SendMessage(SCI_SETYCARETPOLICY, (WPARAM)caretPolicy, (LPARAM)caretStop); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetVisiblePolicy(int caretPolicy, int caretStop) +{ + SendMessage(SCI_SETVISIBLEPOLICY, (WPARAM)caretPolicy, (LPARAM)caretStop); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::GetHScrollBar() +{ + return SendMessage(SCI_GETHSCROLLBAR, (WPARAM)0, (LPARAM)0) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetHScrollBar(bool visible) +{ + SendMessage(SCI_SETHSCROLLBAR, (WPARAM)visible, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetXOffset() +{ + return (int)SendMessage(SCI_GETXOFFSET, (WPARAM)0, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetXOffset(int offset) +{ + SendMessage(SCI_SETXOFFSET, (WPARAM)offset, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetScrollWidth() +{ + return (int)SendMessage(SCI_GETSCROLLWIDTH, (WPARAM)0, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetScrollWidth(int pixelWidth) +{ + SendMessage(SCI_SETSCROLLWIDTH, (WPARAM)pixelWidth, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::GetEndAtLastLine() +{ + return SendMessage(SCI_GETENDATLASTLINE, (WPARAM)0, (LPARAM)0) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetEndAtLastLine(bool end) +{ + SendMessage(SCI_SETENDATLASTLINE, (WPARAM)end, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetWhiteSpaceMode() +{ + return (int)SendMessage(SCI_GETVIEWWS, (WPARAM)0, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetWhiteSpaceMode(int mode) +{ + SendMessage(SCI_SETVIEWWS, (WPARAM)mode, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetWhiteSpaceFGColour(bool useWhiteSpaceFGColour, int colour) +{ + SendMessage(SCI_SETWHITESPACEFORE, (WPARAM)useWhiteSpaceFGColour, (LPARAM)colour); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetWhiteSpaceBGColour(bool useWhiteSpaceBGColour, int colour) +{ + SendMessage(SCI_SETWHITESPACEBACK, (WPARAM)useWhiteSpaceBGColour, (LPARAM)colour); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetWhiteSpaceColour(bool useWhiteSpaceColour, int fgColour, int bgColour) +{ + SetWhiteSpaceFGColour(useWhiteSpaceColour, fgColour); + SetWhiteSpaceBGColour(useWhiteSpaceColour, bgColour); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetCursorType() +{ + return (int)SendMessage(SCI_GETCURSOR); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetCursorType(int type) +{ + SendMessage(SCI_SETCURSOR, (WPARAM)type); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::GetMouseDownCaptures() +{ + return SendMessage(SCI_GETMOUSEDOWNCAPTURES) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetMouseDownCaptures(bool captures) +{ + SendMessage(SCI_SETMOUSEDOWNCAPTURES, (WPARAM)captures); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +ScintillaEdit::EOLMode ScintillaEdit::GetEOLMode() +{ + return (EOLMode)SendMessage(SCI_GETEOLMODE); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetEOLMode(EOLMode mode) +{ + SendMessage(SCI_SETEOLMODE, (WPARAM)mode); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::ConvertEOLs(int eolMode) +{ + SendMessage(SCI_SETMOUSEDOWNCAPTURES, (WPARAM)eolMode); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::GetViewEOL() +{ + return SendMessage(SCI_GETVIEWEOL) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetViewEOL(bool view) +{ + SendMessage(SCI_SETVIEWEOL, (WPARAM)view); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::GetEndStyled() +{ + return SendMessage(SCI_GETENDSTYLED) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::StartStyling(int pos, int mask) +{ + SendMessage(SCI_STARTSTYLING, (WPARAM)pos, (LPARAM)mask); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetStyling(int length, int style) +{ + SendMessage(SCI_SETSTYLING, (WPARAM)length, (LPARAM)style); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetStylingEx(int length, const char *styles) +{ + SendMessage(SCI_SETSTYLINGEX, (WPARAM)length, (LPARAM)styles); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetLineState(int line) +{ + return (int)SendMessage(SCI_GETLINESTATE, (WPARAM)line); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetLineState(int line, int state) +{ + SendMessage(SCI_SETLINESTATE, (WPARAM)line, (LPARAM)state); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- + +int ScintillaEdit::GetMaxLineState() +{ + return (int)SendMessage(SCI_GETMAXLINESTATE); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::StyleResetDefault() +{ + SendMessage(SCI_STYLERESETDEFAULT); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::StyleClearAll() +{ + SendMessage(SCI_STYLECLEARALL); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::StyleSetFont(int styleNumber, char *fontName) +{ + SendMessage(SCI_STYLESETFONT, (WPARAM)styleNumber, (LPARAM)fontName); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::StyleSetSize(int styleNumber, int pointSize) +{ + SendMessage(SCI_STYLESETSIZE, (WPARAM)styleNumber, (LPARAM)pointSize); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::StyleSetBold(int styleNumber, bool bold) +{ + SendMessage(SCI_STYLESETBOLD, (WPARAM)styleNumber, (LPARAM)bold); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::StyleSetItalic(int styleNumber, bool italic) +{ + SendMessage(SCI_STYLESETITALIC, (WPARAM)styleNumber, (LPARAM)italic); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::StyleSetUnderline(int styleNumber, bool underline) +{ + SendMessage(SCI_STYLESETUNDERLINE, (WPARAM)styleNumber, (LPARAM)underline); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::StyleSetFont(int styleNumber, char *fontName, int pointSize, bool bold, bool italic, bool underline) +{ + StyleSetFont(styleNumber, fontName); + StyleSetSize(styleNumber, pointSize); + StyleSetBold(styleNumber, bold); + StyleSetItalic(styleNumber, italic); + StyleSetUnderline(styleNumber, underline); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::StyleSetFGColour(int styleNumber, int colour) +{ + SendMessage(SCI_STYLESETFORE, (WPARAM)styleNumber, (LPARAM)colour); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::StyleSetBGColour(int styleNumber, int colour) +{ + SendMessage(SCI_STYLESETBACK, (WPARAM)styleNumber, (LPARAM)colour); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::StyleSetColour(int styleNumber, int fgColour, int bgColour) +{ + StyleSetFGColour(styleNumber, fgColour); + StyleSetBGColour(styleNumber, bgColour); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::StyleSetEOLFilled(int styleNumber, bool eolFilled) +{ + SendMessage(SCI_STYLESETEOLFILLED, (WPARAM)styleNumber, (LPARAM)eolFilled); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::StyleSetCharacterSet(int styleNumber, StyleCharSet charSet) +{ + SendMessage(SCI_STYLESETCHARACTERSET, (WPARAM)styleNumber, (LPARAM)charSet); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::StyleSetCase(int styleNumber, StyleCaseMode mode) +{ + SendMessage(SCI_STYLESETCASE, (WPARAM)styleNumber, (LPARAM)mode); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::StyleSetVisible(int styleNumber, bool visible) +{ + SendMessage(SCI_STYLESETVISIBLE, (WPARAM)styleNumber, (LPARAM)visible); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::StyleSetChangeable(int styleNumber, bool changeable) +{ + SendMessage(SCI_STYLESETCHANGEABLE, (WPARAM)styleNumber, (LPARAM)changeable); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetSelectionFGColour(bool useSelectionFGColour, int colour) +{ + SendMessage(SCI_SETSELFORE, (WPARAM)useSelectionFGColour, (LPARAM)colour); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetSelectionBGColour(bool useSelectionBGColour, int colour) +{ + SendMessage(SCI_SETSELBACK, (WPARAM)useSelectionBGColour, (LPARAM)colour); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetCaretColour() +{ + return (int)SendMessage(SCI_GETCARETFORE); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetCaretColour(int colour) +{ + SendMessage(SCI_SETCARETFORE, (WPARAM)colour); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::GetCaretLineVisible() +{ + return SendMessage(SCI_GETCARETLINEVISIBLE) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetCaretLineVisible(bool show) +{ + SendMessage(SCI_SETCARETLINEVISIBLE, (WPARAM)show); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetCaretLineColour() +{ + return (int)SendMessage(SCI_GETCARETLINEBACK); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetCaretLineColour(int colour) +{ + SendMessage(SCI_SETCARETLINEBACK, (WPARAM)colour); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetCaretPeriod() +{ + return (int)SendMessage(SCI_GETCARETPERIOD); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetCaretPeriod(int ms) +{ + SendMessage(SCI_SETCARETPERIOD, (WPARAM)ms); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetCaretWidth() +{ + return (int)SendMessage(SCI_GETCARETWIDTH); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetCaretWidth(int pixels) +{ + SendMessage(SCI_SETCARETWIDTH, (WPARAM)pixels); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetControlCharSymbol() +{ + return (int)SendMessage(SCI_GETCONTROLCHARSYMBOL); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetControlCharSymbol(int symbol) +{ + SendMessage(SCI_SETCONTROLCHARSYMBOL, (WPARAM)symbol); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetMarginType(Margin margin) +{ + return (int)SendMessage(SCI_GETMARGINTYPEN, (WPARAM)margin); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetMarginType(Margin margin, int iType) +{ + SendMessage(SCI_SETMARGINTYPEN, (WPARAM)margin, (LPARAM)iType); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetMarginWidth(Margin margin) +{ + return (int)SendMessage(SCI_GETMARGINWIDTHN, (WPARAM)margin); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetMarginWidth(Margin margin, int pixelWidth) +{ + SendMessage(SCI_SETMARGINWIDTHN, (WPARAM)margin, (LPARAM)pixelWidth); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetMarginMask(Margin margin) +{ + return (int)SendMessage(SCI_GETMARGINMASKN, (WPARAM)margin); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetMarginMask(Margin margin, int mask) +{ + SendMessage(SCI_SETMARGINMASKN, (WPARAM)margin, (LPARAM)mask); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::GetMarginSensitive(Margin margin) +{ + return SendMessage(SCI_GETMARGINSENSITIVEN, (WPARAM)margin) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetMarginSensitive(Margin margin, bool sensitive) +{ + SendMessage(SCI_SETMARGINSENSITIVEN, (WPARAM)margin, (LPARAM)sensitive); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetMarginLeft() +{ + return (int)SendMessage(SCI_GETMARGINLEFT); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetMarginRight() +{ + return (int)SendMessage(SCI_GETMARGINRIGHT); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetMarginLeft(int pixels) +{ + SendMessage(SCI_SETMARGINLEFT, (WPARAM)0, (LPARAM)pixels); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetMarginRight(int pixels) +{ + SendMessage(SCI_SETMARGINRIGHT, (WPARAM)0, (LPARAM)pixels); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::GetUsePalette() +{ + return SendMessage(SCI_GETUSEPALETTE) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetUszePalette(bool allowPalette) +{ + SendMessage(SCI_SETUSEPALETTE, (WPARAM)allowPalette); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::GetBufferedDraw() +{ + return SendMessage(SCI_GETBUFFEREDDRAW) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetBufferedDraw(bool buffer) +{ + SendMessage(SCI_SETBUFFEREDDRAW, (WPARAM)buffer); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetCodePage() +{ + return (int)SendMessage(SCI_GETCODEPAGE); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetCodePage(int codePage) +{ + SendMessage(SCI_SETCODEPAGE, (WPARAM)codePage); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetWordChars(const char *chars) +{ + SendMessage(SCI_SETWORDCHARS, (WPARAM)0, (LPARAM)chars); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::GrabFocus() +{ + SendMessage(SCI_GRABFOCUS, (WPARAM)0, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::GetFocus() +{ + SendMessage(SCI_GETFOCUS, (WPARAM)0, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetFocus(bool focus) +{ + SendMessage(SCI_SETFOCUS, (WPARAM)focus, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::BraceHighlight(int pos1, int pos2) +{ + SendMessage(SCI_BRACEHIGHLIGHT, (WPARAM)pos1, (LPARAM)pos2); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::BraceBadLight(int pos) +{ + SendMessage(SCI_BRACEBADLIGHT, (WPARAM)pos, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::BraceMatch(int pos, int maxReStyle) +{ + return (int)SendMessage(SCI_BRACEMATCH, (WPARAM)pos, (LPARAM)maxReStyle); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetTabWidth() +{ + return (int)SendMessage(SCI_GETTABWIDTH, (WPARAM)0, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetTabWidth(int numChars) +{ + SendMessage(SCI_SETTABWIDTH, (WPARAM)numChars, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::GetUseTabs() +{ + return SendMessage(SCI_GETUSETABS, (WPARAM)0, (LPARAM)0) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetUseTabs(bool useTabs) +{ + SendMessage(SCI_SETUSETABS, (WPARAM)useTabs, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetIndent() +{ + return (int)SendMessage(SCI_GETINDENT, (WPARAM)0, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetIndent(int numChars) +{ + SendMessage(SCI_SETINDENT, (WPARAM)numChars, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::GetTabIndents() +{ + return SendMessage(SCI_GETTABINDENTS, (WPARAM)0, (LPARAM)0) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetTabIndents(bool tabIndents) +{ + SendMessage(SCI_SETTABINDENTS, (WPARAM)tabIndents, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::GetBackSpaceUnindents() +{ + return SendMessage(SCI_GETBACKSPACEUNINDENTS, (WPARAM)0, (LPARAM)0) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetBackSpaceUnindents(bool unindents) +{ + SendMessage(SCI_SETBACKSPACEUNINDENTS, (WPARAM)unindents, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetLineIndentation(int line) +{ + return (int)SendMessage(SCI_GETLINEINDENTATION, (WPARAM)line, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetLineIndentation(int line, int indentation) +{ + SendMessage(SCI_SETLINEINDENTATION, (WPARAM)line, (LPARAM)indentation); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetLineIndentPosition(int line) +{ + return (int)SendMessage(SCI_GETLINEINDENTPOSITION, (WPARAM)line, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::GetIndentationGuides() +{ + return SendMessage(SCI_GETINDENTATIONGUIDES, (WPARAM)0, (LPARAM)0) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetIndentationGuides(bool view) +{ + SendMessage(SCI_SETINDENTATIONGUIDES, (WPARAM)view, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetHighlightGuide() +{ + return (int)SendMessage(SCI_GETHIGHLIGHTGUIDE, (WPARAM)0, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetHighlightGuide(int column) +{ + SendMessage(SCI_SETHIGHLIGHTGUIDE, (WPARAM)column, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::MarkerDefine(int markerNumber, MarkerSymbol marker) +{ + SendMessage(SCI_MARKERDEFINE, (WPARAM)markerNumber, (LPARAM)marker); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::MarkerSetFGColour(int markerNumber, int colour) +{ + SendMessage(SCI_MARKERSETFORE, (WPARAM)markerNumber, (LPARAM)colour); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::MarkerSetGGColour(int markerNumber, int colour) +{ + SendMessage(SCI_MARKERSETBACK, (WPARAM)markerNumber, (LPARAM)colour); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::MarkerAdd(int line, int markerNumber) +{ + return (int)SendMessage(SCI_MARKERADD, (WPARAM)line, (LPARAM)markerNumber); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::MarkerDelete(int line, int markerNumber) +{ + SendMessage(SCI_MARKERDELETE, (WPARAM)line, (LPARAM)markerNumber); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::MarkerDeleteAll(int markerNumber) +{ + SendMessage(SCI_MARKERDELETEALL, (WPARAM)markerNumber); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::MarkerGet(int line) +{ + return (int)SendMessage(SCI_MARKERGET, (WPARAM)line, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::MarkerNext(int lineStart, int markerMask) +{ + return (int)SendMessage(SCI_MARKERNEXT, (WPARAM)lineStart, (LPARAM)markerMask); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::MarkerPrev(int lineStart, int markerMask) +{ + return (int)SendMessage(SCI_MARKERPREVIOUS, (WPARAM)lineStart, (LPARAM)markerMask); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::MarkerLineFromHandle(int markerHandle) +{ + return (int)SendMessage(SCI_MARKERLINEFROMHANDLE, (WPARAM)markerHandle, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::MarkerDeleteFromHandle(int markerHandle) +{ + SendMessage(SCI_MARKERDELETEHANDLE, (WPARAM)markerHandle, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::MarkerDefinePixMap(int markerNumber, const char *xpm) +{ + SendMessage(SCI_MARKERDEFINEPIXMAP, (WPARAM)markerNumber, (LPARAM)xpm); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::IndicatorSetStyle(int indicatorNumber, int indicatorStyle) +{ + SendMessage(SCI_INDICSETSTYLE, (WPARAM)indicatorNumber, (LPARAM)indicatorStyle); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::IndicatorGetStyle(int indicatorNumber) +{ + return (int)SendMessage(SCI_INDICGETSTYLE, (WPARAM)indicatorNumber, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetIndicatorFGColour(int indicatorNumber) +{ + return (int)SendMessage(SCI_INDICGETFORE, (WPARAM)indicatorNumber, (LPARAM)0); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetIndicatorFGColour(int indicatorNumber, int colour) +{ + SendMessage(SCI_INDICSETFORE, (WPARAM)indicatorNumber, (LPARAM)colour); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::AutoCompleteShow(int lenEntered, const char *list) +{ + SendMessage(SCI_AUTOCSHOW, (WPARAM)lenEntered, (LPARAM)list); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::AutoCompleteCancel() +{ + SendMessage(SCI_AUTOCCANCEL); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::AutoCompleteActive() +{ + return SendMessage(SCI_AUTOCACTIVE) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::AutoCompletePosStart() +{ + return (int)SendMessage(SCI_AUTOCPOSSTART); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::AutoComplete() +{ + SendMessage(SCI_AUTOCCOMPLETE); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::AutoCompleteStops(const char *chars) +{ + SendMessage(SCI_AUTOCSTOPS, (WPARAM)0, (LPARAM)chars); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +char ScintillaEdit::AutoCompleteGetSeparator() +{ + return (char)SendMessage(SCI_AUTOCGETSEPARATOR); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::AutoCompleteSetSeparator(char separator) +{ + SendMessage(SCI_AUTOCSETSEPARATOR, (WPARAM)separator); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::AutoCompleteSelect(const char *select) +{ + SendMessage(SCI_AUTOCSELECT, (WPARAM)0, (LPARAM)select); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::AutoCompleteGetCancelAtStart() +{ + return SendMessage(SCI_AUTOCGETCANCELATSTART) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::AutoCompleteSetCancelAtStart(bool cancel) +{ + SendMessage(SCI_AUTOCSETCANCELATSTART, (WPARAM)cancel); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::AutoCompleteSetFillUps(const char *chars) +{ + SendMessage(SCI_AUTOCSETFILLUPS, (WPARAM)0, (LPARAM)chars); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::AutoCompleteGetChooseSingle() +{ + return SendMessage(SCI_AUTOCGETCHOOSESINGLE) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::AutoCompleteSetChooseSingle(bool single) +{ + SendMessage(SCI_AUTOCSETCHOOSESINGLE, (WPARAM)single); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::AutoCompleteGetIgnoreCase() +{ + return SendMessage(SCI_AUTOCGETIGNORECASE) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::AutoCompleteSetIgnoreCase(bool ignore) +{ + SendMessage(SCI_AUTOCSETIGNORECASE, (WPARAM)ignore); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::AutoCompleteGetAutoHide() +{ + return SendMessage(SCI_AUTOCGETAUTOHIDE) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::AutoCompleteSetAutoHide(bool autoHide) +{ + SendMessage(SCI_AUTOCSETAUTOHIDE, (WPARAM)autoHide); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::AutoCompleteGetDropRestOfWord() +{ + return SendMessage(SCI_AUTOCGETDROPRESTOFWORD) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::AutoCompleteSetDropRestOfWord(bool drop) +{ + SendMessage(SCI_AUTOCSETDROPRESTOFWORD, (WPARAM)drop); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::UserListShow(int listType, const char *list) +{ + SendMessage(SCI_USERLISTSHOW, (WPARAM)listType, (LPARAM)list); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::CallTipShow(int posStart, const char *definition) +{ + SendMessage(SCI_CALLTIPSHOW, (WPARAM)posStart, (LPARAM)definition); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::CallTipCancel() +{ + SendMessage(SCI_CALLTIPCANCEL); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +bool ScintillaEdit::CallTipActive() +{ + return SendMessage(SCI_CALLTIPACTIVE) != 0; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::CallTipPosStart() +{ + return (int)SendMessage(SCI_CALLTIPPOSSTART); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::CallTipSetHighlight(int hlStart, int hlEnd) +{ + SendMessage(SCI_CALLTIPSETHLT, (WPARAM)hlStart, (LPARAM)hlEnd); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::CallTipSetBGColour(int colour) +{ + SendMessage(SCI_CALLTIPSETBACK, (WPARAM)colour); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::AssignCommandKey(int keyDefinition, int sciCommand) +{ + SendMessage(SCI_ASSIGNCMDKEY, (WPARAM)keyDefinition, (LPARAM)sciCommand); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::ClearCommandKey(int keyDefinition) +{ + SendMessage(SCI_CLEARCMDKEY, (WPARAM)keyDefinition); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::ClearAllCommandKeys() +{ + SendMessage(SCI_CLEARALLCMDKEYS); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::UsePopup(bool enable) +{ + SendMessage(SCI_USEPOPUP, (WPARAM)enable); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::MarcroStartRecord() +{ + SendMessage(SCI_STARTRECORD); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::MarcoStopRecord() +{ + SendMessage(SCI_STOPRECORD); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::PrintFormatRange() +{ + SendMessage(SCI_FORMATRANGE); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetPrintMagnification() +{ + return (int)SendMessage(SCI_GETPRINTMAGNIFICATION); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetPrintMagnification(int magnification) +{ + SendMessage(SCI_SETPRINTMAGNIFICATION, (WPARAM)magnification); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetPrintColourMode() +{ + return (int)SendMessage(SCI_GETPRINTCOLOURMODE); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetPrintColourMode(int mode) +{ + SendMessage(SCI_SETPRINTCOLOURMODE, (WPARAM)mode); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +ScintillaEdit::WrapMode ScintillaEdit::GetWrapMode() +{ + return (WrapMode)SendMessage(SCI_GETWRAPMODE); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetWrapMode(WrapMode mode) +{ + SendMessage(SCI_SETWRAPMODE, (WPARAM)mode); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +ScintillaEdit::LayoutCache ScintillaEdit::GetLayoutCache() +{ + return (LayoutCache)SendMessage(SCI_GETLAYOUTCACHE); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetLayoutCache(LayoutCache cache) +{ + SendMessage(SCI_SETLAYOUTCACHE, (WPARAM)cache); +} + +void ScintillaEdit::ZoomIn() +{ + SendMessage(SCI_ZOOMIN); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::ZoomOut() +{ + SendMessage(SCI_ZOOMOUT); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetZoom() +{ + return (int)SendMessage(SCI_GETZOOM); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetZoom(int zoom) +{ + SendMessage(SCI_SETZOOM, (WPARAM)zoom); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetEdgeColumn() +{ + return (int)SendMessage(SCI_GETEDGECOLUMN); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetEdgeColumn(int column) +{ + SendMessage(SCI_SETEDGECOLUMN, (WPARAM)column); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +ScintillaEdit::EdgeMode ScintillaEdit::GetEdgeMode() +{ + return (EdgeMode)SendMessage(SCI_GETEDGEMODE); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetEdgeMode(EdgeMode mode) +{ + SendMessage(SCI_SETEDGEMODE, (WPARAM)mode); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetEdgeColour() +{ + return (int)SendMessage(SCI_GETEDGECOLOUR); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetEdgeColour(int colour) +{ + SendMessage(SCI_SETEDGECOLOUR, (WPARAM)colour); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +int ScintillaEdit::GetLexer() +{ + return (int)SendMessage(SCI_GETLEXER); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetLexer(int lexer) +{ + SendMessage(SCI_SETLEXER, (WPARAM)lexer); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetLexerLanguage(char *name) +{ + SendMessage(SCI_SETLEXERLANGUAGE, (WPARAM)0, (LPARAM)name); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::Colourise(int start, int end) +{ + SendMessage(SCI_COLOURISE, (WPARAM)start, (LPARAM)end); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetProperty(char *key, char *value) +{ + SendMessage(SCI_SETPROPERTY, (WPARAM)key, (LPARAM)value); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +void ScintillaEdit::SetKeywords(int keywordSet, char *keywordList) +{ + SendMessage(SCI_SETKEYWORDS, (WPARAM)keywordSet, (LPARAM)keywordList); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- diff --git a/vscript/languages/gm/src/gmd/ScintillaEdit.h b/vscript/languages/gm/src/gmd/ScintillaEdit.h new file mode 100644 index 00000000..3e0dc1f8 --- /dev/null +++ b/vscript/languages/gm/src/gmd/ScintillaEdit.h @@ -0,0 +1,738 @@ +#ifndef __SCINTILLAEDIT_H +#define __SCINTILLAEDIT_H + +#include "include/Scintilla.h" + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +/// Utility class for simplifying communication with a Scintilla edit control. Usage is to create +/// the Scintilla editor using CreateWindowEx (see Scintilla documentation) then to call +/// Attach(HWND) to associate this class with the window. Don't forget to call Detach() when done. +/// +/// The utility functions herein are wrappers for Scintilla messages. Consult Scintilla +/// doccumentation for further information on the utility functions. +class ScintillaEdit : public CWnd +{ +public: + /// Constructor. Calls CWnd contructor. + ScintillaEdit(); + + /// Attaches this class to the given window handle. This version checks that the given handle is + /// for a Scintilla control. See MFC doccumentation for further details. + /// \return TRUE on successful attachment. + BOOL Attach(HWND hwnd); + + //---------------------------------------------- + // Scintilla text message functions. + //---------------------------------------------- + + /// Gets the window text. Sends SCI_GETTEXT. Retrieves maxChars-1 characters. + /// \param maxChars maximum number of characters +1 to get. + /// \param text text buffer to retrieve text into. + void GetText(int maxChars, char *text); + + /// Sets the window text. Sends SCI_SETTEXT. + void SetText(const char *text); + + /// Sets the changed status of the doccument to false. + void SetSavePoint(); + + /// Gets the a single line of text. Sends SCI_GETLINE. Buffer must be long enough to hold line. + /// Use GetLineLength to determine the required buffer size. + /// \param line line number of text to retrieve. Zero based. + /// \param text text buffer to retrieve line into. Must be long enough. Will not be + /// null terminated. + void GetLine(int line, char *text); + + /// Replaces the selected text. Text is replaced between the current anchor and current position. + /// Inserts text at the caret position if the anchor and current position are equal. + /// Uses SCI_REPLACESEL message. + /// \param text text to replace/insert with. Must be NULL terminated. + void ReplaceSelection(const char *text); + + /// Returns true if in read only mode. Uses SCI_GETREADONLY message. + /// \return true if read only. + bool GetReadOnly(); + + /// Sets the read only state of the control. Uses SCI_SETREADONLY message. + /// \param readOnly new read only state. + void SetReadOnly(bool readOnly); + + /// Collects text between cpMin and cpMax in textRange. Text is copied into lpstrText in + /// textRange, which must be large enough to hold the text and a NULL character. Retrieves to the + /// end of the doccument if cpMax is -1. + /// Uses SCI_GETTEXTRANGE message. + /// \param textRange details of text to retrieve and the buffer to retrieve into. + void GetTextRange(TextRange &textRange); + + /// Collects text with style information. Text is collected in a similar fashion to GetTextRange. + /// However, two bytes are used per character with the lower byte being the character and the + /// upper byte the style information. Two 0 bytes are used to terminate the string. Once again + /// the lpstrText buffer must be large enough. + /// Uses the SCI_GETSTYLEDTEXT message. + /// \param textRange details of text to retrieve and the buffer to retrieve into. + void GetStyledText(TextRange &textRange); + + /// Adds text at the caret position. Adds length characters regarless of whether the text buffer + /// is shorter that this value. Does not scroll text into view. + /// Uses the SCI_ADDTEXT message. + /// \param length number of characters to insert. + /// \param text text to insert. Can this be a const char *??? + void AddText(int length, char *text); + + /// Adds styled text at the caret position. Behaves similarly to AddText, but uses the two byte + /// styled format (low byte character, high byte style). + /// Uses the SCI_ADDSTYLEDTEXT message. + /// \param length number of characters to insert. + /// \param text text to insert. Can this be a const char *??? + void AddStyledText(int length, char *text); + + /// Adds text to the end of the document without affecting the selection. + /// Uses SCI_APPENDTEXT. + /// \param length number of characters to insert. + /// \param text text to append. Can this be a const char *??? + void AppendText(int length, char *text); + + /// Inserts the NULL terminated string at the given position. Adds to current position if pos is' + /// -1. + /// Uses SCI_INSERTTEXT. + /// \param pos position to insert at. -1 to insert at current position. + /// \param text text to insert. + void InsertText(int pos, const char *text); + + /// Deletes doccument text, but only if not read only. Uses SCI_CLEARALL. + void ClearAll(); + + /// Clears current style information and resets folding state. May be used when changing styles. + /// Uses SCI_CLEARDOCUMENTSTYLE message. + void ClearDocumentStyle(); + + /// Retrieves a single character. Uses SCI_GETCHARAT message. + /// \param pos position of character to retrieve. + /// \return the character at this position or 0 if pos is out of range. + char GetCharAt(int pos); + + /// Retrieves a single character's style. Uses SCI_GETSTYLEAT message. + /// \param pos position of character to retrieve. + /// \return the style at this position or 0 if pos is out of range. + char GetStyleAt(int pos); + + /// Sets the number of bits to use for style information. A maximum of 7 bits may be used. Other + /// bits may still be used as indicators. Set to 5 by default. + /// Uses SCI_SETSTYLEBITS message. + /// \param bits number of style bits to use. + void SetStyleBits(int bits); + + /// Gets the number of bits to use for style information. + /// Uses SCI_GETSTYLEBITS message. + /// \return number of style bits in use. Maximum of 7, 5 by default. + int GetStyleBits(); + + //---------------------------------------------- + // Scintilla search message functions. + // See Scintilla documentation for search flags. + //---------------------------------------------- + + /// Searches for particular text within the document. Returns -1 on failure to find the text or + /// the position of the start of the text when found. + /// + /// Search flags are explained below as taken from Scintilla documentation: + /// + /// Several of the search routines use flag options which include a simple regular expression + /// search. Combine the flag options by adding them: + /// + /// SCFIND_MATCHCASE A match only occurs with text that matches the case of the search string. + /// SCFIND_WHOLEWORD A match only occurs if the characters before and after are not word characters. + /// SCFIND_WORDSTART A match only occurs if the character before is not a word character. + /// SCFIND_REGEXP The search string should be interpreted as a regular expression. + /// + /// If SCFIND_REGEXP is not included in the searchFlags, you can search backwards to find the + /// previous occurance of a search string by setting the end of the search range before the start. + /// If SCFIND_REGEXP is included searches are always from a lower position to a higher position, + /// even if the search range is backwards. + /// + /// In a regular expression, special characters interpreted are: + /// + /// . Matches any character + /// \( This marks the start of a region for tagging a match. + /// \) This marks the end of a tagged region. + /// \n Where n is 1 through 9 refers to the first through ninth tagged region when replacing. + /// For example if the search string was Fred\([1-9]\)XXX and the replace string was Sam\1YYY + /// applied to Fred2XXX this would generate Sam2YYY. + /// \< This matches the start of a word using Scintilla's definitions of words. + /// \> This matches the end of a word using Scintilla's definition of words. + /// \x This allows you to use a character x that would otherwise have a special meaning. For + /// example, \[ would be interpreted as [ and not as the start of a character set. + /// [...] This indicates a set of characters, for example [abc] means any of the characters a, b + /// or c. You can also use ranges, for example [a-z] for any lower case character. + /// [^...] The complement of the characters in the set. For example, [^A-Za-z] means any + /// character except an alphabetic character. + /// ^ This matches the start of a line (unless used inside a set, see above). + /// $ This matches the end of a line. + /// * This matches 0 or more times. For example Sa*m matches Sm, Sam, Saam, Saaam and so on. + /// + This matches 1 or more times. For example Sa+m matches Sam, Saam, Saaam and so on. + /// + /// Uses SCI_FINDTEXT message. + /// \param searchFlags flags to search with. + /// \param ttf search text details. Use chrg.cpMin and max to set search range. + /// \return the position of the found text or -1 if not found. + int FindText(int searchFlags, TextToFind &ttf); + + /// Sets the search anchor for SearchNext and SearchPrev to the start of the current selection. + /// Uses SCI_SEARCHANCHOR message. + void SetSearchAnchor(); + + /// Searches for the next occurence of the given text. + /// Uses SCI_SEARCHNEXT message. + /// \param searchFlags flags to search with. + /// \param ttf search text details. Use chrg.cpMin and max to set search range. + /// \return the position of the found text or -1 if not found. + int SearchNext(int searchFlags, const char *forText); + + /// Searches for the previous occurence of the given text. + /// Uses SCI_SEARCHPREV message. + /// \param searchFlags flags to search with. + /// \param ttf search text details. Use chrg.cpMin and max to set search range. + /// \return the position of the found text or -1 if not found. + int SearchPrev(int searchFlags, const char *forText); + + // Note: there are too many functions for me to bother redocumenting all of them. Consult + // Scintilla documentation. Generally, the name of the function directly corresponds to an + // equivalent SCI_message. + + //---------------------------------------------- + // Scintilla search and replace message functions. + //---------------------------------------------- + int GetTargetStart(); + void SetTargetStart(int pos); + + int GetTargetEnd(); + void SetTargetEnd(int pos); + + int ReplaceTarget(int length, const char *text); + int ReplaceTargetRegularExpression(int length, const char *text); + + int GetSearchFlags(); + void SetSearchFlags(int flags); + + int SearchInTarget(int length, const char *text); + + //---------------------------------------------- + // Scintilla over type message functions. + //---------------------------------------------- + bool GetOverType(); + void SetOvertType(bool overType); + + //---------------------------------------------- + // Scintilla cut & paste message functions. + //---------------------------------------------- + void Cut(); + void Copy(); + void Paste(); + void Clear(); + bool CanPaste(); + + //---------------------------------------------- + // Scintilla error handling message functions. + // TODO - not supported yet. + //---------------------------------------------- + + //---------------------------------------------- + // Scintilla undo/redo message functions. + // TODO + //---------------------------------------------- + + //---------------------------------------------- + // Scintilla selection message functions. + //---------------------------------------------- + int GetTextLength(); + int GetLineCount(); + int GetFirstVisibleLine(); + int GetLinesOnScreen(); + bool GetModified(); + void SetSelection(int anchorPos, int currentPos); + void GotoPos(int pos); + void GotoLine(int line); + + int GetCurrentPos(); + void SetCurrentPos(int pos); + int GetAnchor(); + void SetAnchor(int pos); + + int GetSelectionStart(); + void SetSelectionStart(int pos); + int GetSelectionEnd(); + void SetSelectionEnd(int pos); + + void SelectAll(); + + int LineFromPosition(int pos); + int PositionFromLine(int line); + int GetLineEndPosition(int line); + int GetLineLength(int line); + + void GetSelectedText(char *text); + + void GetCurrentLine(int maxChars, char *text); + + bool SelectionIsRectangle(); + void MoveCaretInsideView(); + int WordEndPosition(int position, bool onlyWordCharacters = true); + int WordStartPosition(int position, bool onlyWordCharacters = true); + + int TextWidth(int styleNumber, char *text); + int TextHeight(int line); + int GetColumn(int pos); + + int PositionFromPoint(int x, int y); + int PositionFromPointClose(int x, int y); + int PointXFromPosition(int pos); + int PointYFromPosition(int pos); + + bool HideSelection(bool hide); + + //---------------------------------------------- + // Scintilla scrolling message functions. + //---------------------------------------------- + void LineScroll(int column, int line); + void ScrollToCaret(); + + void SetXCaretPolicy(int caretPolicy, int caretStop); + void SetYCaretPolicy(int caretPolicy, int caretStop); + + void SetVisiblePolicy(int caretPolicy, int caretStop); + + bool GetHScrollBar(); + void SetHScrollBar(bool visible); + + int GetXOffset(); + void SetXOffset(int offset); + + int GetScrollWidth(); + void SetScrollWidth(int pixelWidth); + + bool GetEndAtLastLine(); + void SetEndAtLastLine(bool end); + + //---------------------------------------------- + // Scintilla white space message functions. + //---------------------------------------------- + int GetWhiteSpaceMode(); + void SetWhiteSpaceMode(int mode); + + void SetWhiteSpaceFGColour(bool useWhiteSpaceFGColour, int colour); + void SetWhiteSpaceBGColour(bool useWhiteSpaceBGColour, int colour); + void SetWhiteSpaceColour(bool useWhiteSpaceColour, int fgColour, int bgColour); + + //---------------------------------------------- + // Scintilla cursor and mouse capture message functions. + //---------------------------------------------- + int GetCursorType(); + void SetCursorType(int type); + + bool GetMouseDownCaptures(); + void SetMouseDownCaptures(bool captures); + + //---------------------------------------------- + // Scintilla line endings capture message functions. + //---------------------------------------------- + enum EOLMode + { + EOL_CrLf = SC_EOL_CRLF, + EOL_Cr = SC_EOL_CR, + EOL_Lf = SC_EOL_LF, + }; + + EOLMode GetEOLMode(); + void SetEOLMode(EOLMode mode); + + void ConvertEOLs(int eolMode); + + bool GetViewEOL(); + void SetViewEOL(bool view); + + //---------------------------------------------- + // Scintilla styling endings capture message functions. + //---------------------------------------------- + bool GetEndStyled(); + + void StartStyling(int pos, int mask); + void SetStyling(int length, int style); + void SetStylingEx(int length, const char *styles); + + int GetLineState(int line); + void SetLineState(int line, int state); + + int GetMaxLineState(); + + //---------------------------------------------- + // Scintilla caret and selection style message functions. + //---------------------------------------------- + void StyleResetDefault(); + void StyleClearAll(); + + void StyleSetFont(int styleNumber, char *fontName); + void StyleSetSize(int styleNumber, int pointSize); + void StyleSetBold(int styleNumber, bool bold); + void StyleSetItalic(int styleNumber, bool italic); + void StyleSetUnderline(int styleNumber, bool underline); + void StyleSetFont(int styleNumber, char *fontName, int pointSize, bool bold, bool italic, bool underline); + + void StyleSetFGColour(int styleNumber, int colour); + void StyleSetBGColour(int styleNumber, int colour); + void StyleSetColour(int styleNumber, int fgColour, int bgColour); + + void StyleSetEOLFilled(int styleNumber, bool eolFilled); + + enum StyleCharSet + { + SCS_Ansi = SC_CHARSET_ANSI, + SCS_Arabic = SC_CHARSET_ARABIC, + SCS_Baltic = SC_CHARSET_BALTIC, + SCS_ChineseBig5 = SC_CHARSET_CHINESEBIG5, + SCS_Default = SC_CHARSET_DEFAULT, + SCS_EastEurope = SC_CHARSET_EASTEUROPE, + SCS_GB2312 = SC_CHARSET_GB2312, + SCS_Greek = SC_CHARSET_GREEK, + SCS_Hangul = SC_CHARSET_HANGUL, + SCS_Hebrew = SC_CHARSET_HEBREW, + SCS_Johab = SC_CHARSET_JOHAB, + SCS_Mac = SC_CHARSET_MAC, + SCS_OEM = SC_CHARSET_OEM, + SCS_ShiftJis = SC_CHARSET_SHIFTJIS, + SCS_Symbol = SC_CHARSET_SYMBOL, + SCS_Thai = SC_CHARSET_THAI, + SCS_Turkish = SC_CHARSET_TURKISH, + SCS_Vietnamese = SC_CHARSET_VIETNAMESE, + }; + + void StyleSetCharacterSet(int styleNumber, StyleCharSet charSet); + + enum StyleCaseMode + { + SCM_Mixed = SC_CASE_MIXED, + SCM_Upper = SC_CASE_UPPER, + SCM_Lower = SC_CASE_LOWER, + }; + + void StyleSetCase(int styleNumber, StyleCaseMode mode); + + void StyleSetVisible(int styleNumber, bool visible); + + void StyleSetChangeable(int styleNumber, bool changeable); + + //---------------------------------------------- + // Scintilla caret and selection style message functions. + //---------------------------------------------- + void SetSelectionFGColour(bool useSelectionFGColour, int colour); + void SetSelectionBGColour(bool useSelectionBGColour, int colour); + + int GetCaretColour(); + void SetCaretColour(int colour); + + bool GetCaretLineVisible(); + void SetCaretLineVisible(bool show); + int GetCaretLineColour(); + void SetCaretLineColour(int colour); + + int GetCaretPeriod(); + void SetCaretPeriod(int ms); + int GetCaretWidth(); + void SetCaretWidth(int pixels); + int GetControlCharSymbol(); + void SetControlCharSymbol(int symbol); + + //---------------------------------------------- + // Scintilla margin message functions. + //---------------------------------------------- + enum Margin + { + M_Number = 0, + M_Symbol1, + M_Symbol2, + }; + + int GetMarginType(Margin margin); + void SetMarginType(Margin margin, int iType); + + int GetMarginWidth(Margin margin); + void SetMarginWidth(Margin margin, int pixelWidth); + + int GetMarginMask(Margin margin); + void SetMarginMask(Margin margin, int mask); + + bool GetMarginSensitive(Margin margin); + void SetMarginSensitive(Margin margin, bool sensitive); + + int GetMarginLeft(); + int GetMarginRight(); + void SetMarginLeft(int pixels); + void SetMarginRight(int pixels); + + //---------------------------------------------- + // Scintilla other settings message functions. + //---------------------------------------------- + bool GetUsePalette(); + void SetUszePalette(bool allowPalette); + + bool GetBufferedDraw(); + void SetBufferedDraw(bool buffer); + + int GetCodePage(); + void SetCodePage(int codePage); + + void SetWordChars(const char *chars); + + void GrabFocus(); + void GetFocus(); + void SetFocus(bool focus); + + //---------------------------------------------- + // Scintilla brace highlighting message functions. + //---------------------------------------------- + void BraceHighlight(int pos1, int pos2); + void BraceBadLight(int pos); + int BraceMatch(int pos, int maxReStyle); + + //---------------------------------------------- + // Scintilla tab and indent message functions. + //---------------------------------------------- + int GetTabWidth(); + void SetTabWidth(int numChars); + bool GetUseTabs(); + void SetUseTabs(bool useTabs); + int GetIndent(); + void SetIndent(int numChars); + + bool GetTabIndents(); + void SetTabIndents(bool tabIndents); + bool GetBackSpaceUnindents(); + void SetBackSpaceUnindents(bool unindents); + int GetLineIndentation(int line); + void SetLineIndentation(int line, int indentation); + int GetLineIndentPosition(int line); + + bool GetIndentationGuides(); + void SetIndentationGuides(bool view); + int GetHighlightGuide(); + void SetHighlightGuide(int column); + + //---------------------------------------------- + // Scintilla marker message functions. + //---------------------------------------------- + enum MarkerSymbol + { + MS_Circle = SC_MARK_CIRCLE, + MS_RoundRect = SC_MARK_ROUNDRECT, + MS_Arrow = SC_MARK_ARROW, + MS_SmallRect = SC_MARK_SMALLRECT, + MS_ShortArrow = SC_MARK_SHORTARROW, + MS_Empty = SC_MARK_EMPTY, + MS_ArrowDown = SC_MARK_ARROWDOWN, + MS_Minus = SC_MARK_MINUS, + MS_Plus = SC_MARK_PLUS, + MS_VLine = SC_MARK_VLINE, + MS_LCorner = SC_MARK_LCORNER, + MS_TCorner = SC_MARK_TCORNER, + MS_BoxPlus = SC_MARK_BOXPLUS, + MS_BoxPlusConnected = SC_MARK_BOXPLUSCONNECTED, + MS_BoxMinus = SC_MARK_BOXMINUS, + MS_BoxMinusConncted = SC_MARK_BOXMINUSCONNECTED, + MS_LCornerCurve = SC_MARK_LCORNERCURVE, + MS_TCornerCurve = SC_MARK_TCORNERCURVE, + MS_CirclePlus = SC_MARK_CIRCLEPLUS, + MS_CirclePlusConnected = SC_MARK_CIRCLEPLUSCONNECTED, + MS_CircleMinus = SC_MARK_CIRCLEMINUS, + MS_CircleMinusConnected = SC_MARK_CIRCLEMINUSCONNECTED, + MS_MarkBackground = SC_MARK_BACKGROUND, + MS_Ellipsis = SC_MARK_DOTDOTDOT, + MS_Arrows = SC_MARK_ARROWS, + MS_PixMap = SC_MARK_PIXMAP, + MS_Character = SC_MARK_CHARACTER, + }; + + void MarkerDefine(int markerNumber, MarkerSymbol marker); + void MarkerSetFGColour(int markerNumber, int colour); + void MarkerSetGGColour(int markerNumber, int colour); + + int MarkerAdd(int line, int markerNumber); + void MarkerDelete(int line, int markerNumber); + void MarkerDeleteAll(int markerNumber); + + int MarkerGet(int line); + int MarkerNext(int lineStart, int markerMask); + int MarkerPrev(int lineStart, int markerMask); + + int MarkerLineFromHandle(int markerHandle); + void MarkerDeleteFromHandle(int markerHandle); + + void MarkerDefinePixMap(int markerNumber, const char *xpm); + + //---------------------------------------------- + // Scintilla indicator message functions. + //---------------------------------------------- + void IndicatorSetStyle(int indicatorNumber, int indicatorStyle); + int IndicatorGetStyle(int indicatorNumber); + int GetIndicatorFGColour(int indicatorNumber); + void SetIndicatorFGColour(int indicatorNumber, int colour); + + //---------------------------------------------- + // Scintilla auto completion message functions. + //---------------------------------------------- + void AutoCompleteShow(int lenEntered, const char *list); + void AutoCompleteCancel(); + bool AutoCompleteActive(); + int AutoCompletePosStart(); + void AutoComplete(); + void AutoCompleteStops(const char *chars); + + char AutoCompleteGetSeparator(); + void AutoCompleteSetSeparator(char separator); + + void AutoCompleteSelect(const char *select); + + bool AutoCompleteGetCancelAtStart(); + void AutoCompleteSetCancelAtStart(bool cancel); + + void AutoCompleteSetFillUps(const char *chars); + + bool AutoCompleteGetChooseSingle(); + void AutoCompleteSetChooseSingle(bool single); + bool AutoCompleteGetIgnoreCase(); + void AutoCompleteSetIgnoreCase(bool ignore); + bool AutoCompleteGetAutoHide(); + void AutoCompleteSetAutoHide(bool autoHide); + bool AutoCompleteGetDropRestOfWord(); + void AutoCompleteSetDropRestOfWord(bool drop); + + //---------------------------------------------- + // Scintilla use listmessage functions. + //---------------------------------------------- + void UserListShow(int listType, const char *list); + + //---------------------------------------------- + // Scintilla call tip message functions. + //---------------------------------------------- + void CallTipShow(int posStart, const char *definition); + void CallTipCancel(); + bool CallTipActive(); + int CallTipPosStart(); + void CallTipSetHighlight(int hlStart, int hlEnd); + void CallTipSetBGColour(int colour); + + //---------------------------------------------- + // Scintilla key binding message functions. + //---------------------------------------------- + void AssignCommandKey(int keyDefinition, int sciCommand); + void ClearCommandKey(int keyDefinition); + void ClearAllCommandKeys(); + + //---------------------------------------------- + // Scintilla popup edit message functions. + //---------------------------------------------- + void UsePopup(bool enable); + + //---------------------------------------------- + // Scintilla macro message functions. + //---------------------------------------------- + void MarcroStartRecord(); + void MarcoStopRecord(); + + //---------------------------------------------- + // Scintilla printing message functions. + //---------------------------------------------- + void PrintFormatRange(); + int GetPrintMagnification(); + void SetPrintMagnification(int magnification); + int GetPrintColourMode(); + void SetPrintColourMode(int mode); + + //---------------------------------------------- + // Scintilla multiple view message functions. + // TODO + //---------------------------------------------- + + //---------------------------------------------- + // Scintilla folding message functions. + // TODO + //---------------------------------------------- + + //---------------------------------------------- + // Scintilla line wrapping message functions. + //---------------------------------------------- + enum WrapMode + { + WM_None = SC_WRAP_NONE, + WM_Word = SC_WRAP_WORD, + }; + + enum LayoutCache + { + LC_None = SC_CACHE_NONE, + LC_Caret = SC_CACHE_CARET, + LC_Page = SC_CACHE_PAGE, + LC_Document = SC_CACHE_DOCUMENT, + }; + + WrapMode GetWrapMode(); + void SetWrapMode(WrapMode mode); + + LayoutCache GetLayoutCache(); + void SetLayoutCache(LayoutCache cache); + + //---------------------------------------------- + // Scintilla zooming message functions. + //---------------------------------------------- + void ZoomIn(); + void ZoomOut(); + int GetZoom(); + void SetZoom(int zoom); + + //---------------------------------------------- + // Scintilla long line message functions. + //---------------------------------------------- + enum EdgeMode + { + EM_None = EDGE_NONE, + EM_Line = EDGE_LINE, + EM_Background = EDGE_BACKGROUND, + }; + + int GetEdgeColumn(); + void SetEdgeColumn(int column); + EdgeMode GetEdgeMode(); + void SetEdgeMode(EdgeMode mode); + int GetEdgeColour(); + void SetEdgeColour(int colour); + + //---------------------------------------------- + // Scintilla lexer message functions. + //---------------------------------------------- + int GetLexer(); + void SetLexer(int lexer); + void SetLexerLanguage(char *name); + void Colourise(int start, int end); + void SetProperty(char *key, char *value); + void SetKeywords(int keywordSet, char *keywordList); + +protected: + /// Hidden to prevent misuse. + virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL) + { + return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); + } + + /// Hidden to prevent misuse. + BOOL CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hwndParent, HMENU nIDorHMenu, LPVOID lpParam = NULL) + { + return CWnd::CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle, x, y, nWidth, nHeight, hwndParent, nIDorHMenu, lpParam); + } + + /// Hidden to prevent misuse. + BOOL CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, LPVOID lpParam = NULL) + { + return CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, lpParam); + } +}; + +#endif // !__SCINTILLAEDIT_H diff --git a/vscript/languages/gm/src/gmd/StdAfx.cpp b/vscript/languages/gm/src/gmd/StdAfx.cpp new file mode 100644 index 00000000..d6a1a40d --- /dev/null +++ b/vscript/languages/gm/src/gmd/StdAfx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// gmd.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "StdAfx.h" + + + diff --git a/vscript/languages/gm/src/gmd/StdAfx.h b/vscript/languages/gm/src/gmd/StdAfx.h new file mode 100644 index 00000000..7efe7712 --- /dev/null +++ b/vscript/languages/gm/src/gmd/StdAfx.h @@ -0,0 +1,33 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__BC9F490A_DA38_4136_A8DC_E36F8BDE934C__INCLUDED_) +#define AFX_STDAFX_H__BC9F490A_DA38_4136_A8DC_E36F8BDE934C__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC support for Internet Explorer 4 Common Controls +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + +#define IM_A_DEBUGGER 1 +#define GMDEBUG_SUPPORT 1 + +// These two are for MSVS 2005 security consciousness until safe std lib funcs are available +#pragma warning(disable : 4996) // Deprecated functions +#define _CRT_SECURE_NO_DEPRECATE // Allow old unsecure standard library functions, Disable some 'warning C4996 - function was deprecated' + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__BC9F490A_DA38_4136_A8DC_E36F8BDE934C__INCLUDED_) diff --git a/vscript/languages/gm/src/gmd/gmd.cpp b/vscript/languages/gm/src/gmd/gmd.cpp new file mode 100644 index 00000000..1107d1cb --- /dev/null +++ b/vscript/languages/gm/src/gmd/gmd.cpp @@ -0,0 +1,138 @@ +// gmd.cpp : Defines the class behaviors for the application. +// +// See Copyright Notice in gmMachine.h + +#include "StdAfx.h" +#include "gmd.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CGmdApp + +BEGIN_MESSAGE_MAP(CGmdApp, CWinApp) + //{{AFX_MSG_MAP(CGmdApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CGmdApp construction + +CGmdApp::CGmdApp() +{ +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CGmdApp object + +CGmdApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CGmdApp initialization + +BOOL CGmdApp::InitInstance() +{ + // Standard initialization + +#if _MSC_VER < 1300 +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif +#endif + + // Change the registry key under which our settings are stored. + SetRegistryKey(_T("Local AppWizard-Generated Applications")); + + + + CMainFrame* pFrame = new CMainFrame; + m_pMainWnd = pFrame; + + // create and load the frame with its resources + + pFrame->LoadFrame(IDR_MAINFRAME, + WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, + NULL); + + + + pFrame->ShowWindow(SW_SHOW); + pFrame->UpdateWindow(); + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CGmdApp message handlers + + + + + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CGmdApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CGmdApp message handlers + +BOOL CGmdApp::OnIdle(LONG lCount) +{ + return CWinApp::OnIdle(lCount); +} \ No newline at end of file diff --git a/vscript/languages/gm/src/gmd/gmd.dsp b/vscript/languages/gm/src/gmd/gmd.dsp new file mode 100644 index 00000000..68e11159 --- /dev/null +++ b/vscript/languages/gm/src/gmd/gmd.dsp @@ -0,0 +1,253 @@ +# Microsoft Developer Studio Project File - Name="gmd" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=gmd - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gmd.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gmd.mak" CFG="gmd - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gmd - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "gmd - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "gmd" +# PROP Scc_LocalPath "." +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gmd - Win32 Release" + +# PROP BASE Use_MFC 6 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 6 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\gm" /I "..\gmd" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL" +# ADD RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386 +# ADD LINK32 Ws2_32.lib /nologo /subsystem:windows /machine:I386 /out:"..\..\bin\gmd.exe" + +!ELSEIF "$(CFG)" == "gmd - Win32 Debug" + +# PROP BASE Use_MFC 6 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 6 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\gm" /I "..\gmd" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" +# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Ws2_32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"..\..\bin\gmd.debug.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "gmd - Win32 Release" +# Name "gmd - Win32 Debug" +# Begin Group "src" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\ChildView.cpp +# End Source File +# Begin Source File + +SOURCE=.\ChildView.h +# End Source File +# Begin Source File + +SOURCE=.\gmd.cpp +# End Source File +# Begin Source File + +SOURCE=.\gmd.h +# End Source File +# Begin Source File + +SOURCE=.\gmd.rc +# End Source File +# Begin Source File + +SOURCE=.\GMLangSettings.cpp +# End Source File +# Begin Source File + +SOURCE=.\GMLangSettings.h +# End Source File +# Begin Source File + +SOURCE=.\LanguageSettings.cpp +# End Source File +# Begin Source File + +SOURCE=.\LanguageSettings.h +# End Source File +# Begin Source File + +SOURCE=.\MainFrm.cpp +# End Source File +# Begin Source File + +SOURCE=.\MainFrm.h +# End Source File +# Begin Source File + +SOURCE=.\NetServer.cpp +# End Source File +# Begin Source File + +SOURCE=.\NetServer.h +# End Source File +# Begin Source File + +SOURCE=.\Resource.h +# End Source File +# Begin Source File + +SOURCE=.\ScintillaEdit.cpp +# End Source File +# Begin Source File + +SOURCE=.\ScintillaEdit.h +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"stdafx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\res\gmd.ico +# End Source File +# Begin Source File + +SOURCE=.\res\gmd.rc2 +# End Source File +# Begin Source File + +SOURCE=.\res\Toolbar.bmp +# End Source File +# End Group +# Begin Group "scintilla" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\include\Accessor.h +# End Source File +# Begin Source File + +SOURCE=.\include\Face.py +# End Source File +# Begin Source File + +SOURCE=.\include\HFacer.py +# End Source File +# Begin Source File + +SOURCE=.\include\KeyWords.h +# End Source File +# Begin Source File + +SOURCE=.\include\Platform.h +# End Source File +# Begin Source File + +SOURCE=.\include\PropSet.h +# End Source File +# Begin Source File + +SOURCE=.\include\SciLexer.h +# End Source File +# Begin Source File + +SOURCE=.\include\Scintilla.h +# End Source File +# Begin Source File + +SOURCE=.\include\Scintilla.iface +# End Source File +# Begin Source File + +SOURCE=.\include\ScintillaWidget.h +# End Source File +# Begin Source File + +SOURCE=.\include\SString.h +# End Source File +# Begin Source File + +SOURCE=.\include\WindowAccessor.h +# End Source File +# End Group +# Begin Group "gm" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\gm\gmDebugger.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\gm\gmDebugger.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\res\bangbang.wav +# End Source File +# End Target +# End Project diff --git a/vscript/languages/gm/src/gmd/gmd.dsw b/vscript/languages/gm/src/gmd/gmd.dsw new file mode 100644 index 00000000..dfbfbe7e --- /dev/null +++ b/vscript/languages/gm/src/gmd/gmd.dsw @@ -0,0 +1,33 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "gmd"=.\gmd.dsp - Package Owner=<4> + +Package=<5> +{{{ + begin source code control + Perforce Project + . + end source code control +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/vscript/languages/gm/src/gmd/gmd.h b/vscript/languages/gm/src/gmd/gmd.h new file mode 100644 index 00000000..f6e2bc28 --- /dev/null +++ b/vscript/languages/gm/src/gmd/gmd.h @@ -0,0 +1,51 @@ +// gmd.h : main header file for the GMD application +// +// See Copyright Notice in gmMachine.h + +#if !defined(AFX_GMD_H__F4DE5F2C_627C_41AD_BBDC_F26D7E07343D__INCLUDED_) +#define AFX_GMD_H__F4DE5F2C_627C_41AD_BBDC_F26D7E07343D__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CGmdApp: +// See gmd.cpp for the implementation of this class +// + +class CGmdApp : public CWinApp +{ +public: + CGmdApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CGmdApp) + public: + virtual BOOL InitInstance(); + virtual BOOL OnIdle(LONG lCount); + //}}AFX_VIRTUAL + +// Implementation + +public: + //{{AFX_MSG(CGmdApp) + afx_msg void OnAppAbout(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_GMD_H__F4DE5F2C_627C_41AD_BBDC_F26D7E07343D__INCLUDED_) diff --git a/vscript/languages/gm/src/gmd/gmd.vcproj b/vscript/languages/gm/src/gmd/gmd.vcproj new file mode 100644 index 00000000..5235c2ec --- /dev/null +++ b/vscript/languages/gm/src/gmd/gmd.vcproj @@ -0,0 +1,563 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/gm/src/gmd/include/Accessor.h b/vscript/languages/gm/src/gmd/include/Accessor.h new file mode 100644 index 00000000..0b2c4bae --- /dev/null +++ b/vscript/languages/gm/src/gmd/include/Accessor.h @@ -0,0 +1,78 @@ +// Scintilla source code edit control +/** @file Accessor.h + ** Rapid easy access to contents of a Scintilla. + **/ +// Copyright 1998-2001 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +enum { wsSpace = 1, wsTab = 2, wsSpaceTab = 4, wsInconsistent=8}; + +class Accessor; + +typedef bool (*PFNIsCommentLeader)(Accessor &styler, int pos, int len); + +/** + * Interface to data in a Scintilla. + */ +class Accessor { +protected: + enum {extremePosition=0x7FFFFFFF}; + /** @a bufferSize is a trade off between time taken to copy the characters + * and retrieval overhead. + * @a slopSize positions the buffer before the desired position + * in case there is some backtracking. */ + enum {bufferSize=4000, slopSize=bufferSize/8}; + char buf[bufferSize+1]; + int startPos; + int endPos; + int codePage; + + virtual bool InternalIsLeadByte(char ch)=0; + virtual void Fill(int position)=0; + +public: + Accessor() : startPos(extremePosition), endPos(0), codePage(0) {} + virtual ~Accessor() {} + char operator[](int position) { + if (position < startPos || position >= endPos) { + Fill(position); + } + return buf[position - startPos]; + } + /** Safe version of operator[], returning a defined value for invalid position. */ + char SafeGetCharAt(int position, char chDefault=' ') { + if (position < startPos || position >= endPos) { + Fill(position); + if (position < startPos || position >= endPos) { + // Position is outside range of document + return chDefault; + } + } + return buf[position - startPos]; + } + bool IsLeadByte(char ch) { + return codePage && InternalIsLeadByte(ch); + } + void SetCodePage(int codePage_) { codePage = codePage_; } + + virtual bool Match(int pos, const char *s)=0; + virtual char StyleAt(int position)=0; + virtual int GetLine(int position)=0; + virtual int LineStart(int line)=0; + virtual int LevelAt(int line)=0; + virtual int Length()=0; + virtual void Flush()=0; + virtual int GetLineState(int line)=0; + virtual int SetLineState(int line, int state)=0; + virtual int GetPropertyInt(const char *key, int defaultValue=0)=0; + virtual char *GetProperties()=0; + + // Style setting + virtual void StartAt(unsigned int start, char chMask=31)=0; + virtual void SetFlags(char chFlags_, char chWhile_)=0; + virtual unsigned int GetStartSegment()=0; + virtual void StartSegment(unsigned int pos)=0; + virtual void ColourTo(unsigned int pos, int chAttr)=0; + virtual void SetLevel(int line, int level)=0; + virtual int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0)=0; +}; diff --git a/vscript/languages/gm/src/gmd/include/Face.py b/vscript/languages/gm/src/gmd/include/Face.py new file mode 100644 index 00000000..08ac7a93 --- /dev/null +++ b/vscript/languages/gm/src/gmd/include/Face.py @@ -0,0 +1,107 @@ +# Module for reading and parsing Scintilla.iface file +import string + +def sanitiseLine(line): + if line[-1:] == '\n': line = line[:-1] + if string.find(line, "##") != -1: + line = line[:string.find(line, "##")] + line = string.strip(line) + return line + +def decodeFunction(featureVal): + retType, rest = string.split(featureVal, " ", 1) + nameIdent, params = string.split(rest, "(") + name, value = string.split(nameIdent, "=") + params, rest = string.split(params, ")") + param1, param2 = string.split(params, ",")[0:2] + return retType, name, value, param1, param2 + +def decodeEvent(featureVal): + retType, rest = string.split(featureVal, " ", 1) + nameIdent, params = string.split(rest, "(") + name, value = string.split(nameIdent, "=") + return retType, name, value + +def decodeParam(p): + param = string.strip(p) + type = "" + name = "" + value = "" + if " " in param: + type, nv = string.split(param, " ") + if "=" in nv: + name, value = string.split(nv, "=") + else: + name = nv + return type, name, value + +class Face: + + def __init__(self): + self.order = [] + self.features = {} + self.values = {} + self.events = {} + + def ReadFromFile(self, name): + currentCategory = "" + currentComment = [] + currentCommentFinished = 0 + file = open(name) + for line in file.readlines(): + line = sanitiseLine(line) + if line: + if line[0] == "#": + if line[1] == " ": + if currentCommentFinished: + currentComment = [] + currentCommentFinished = 0 + currentComment.append(line[2:]) + else: + currentCommentFinished = 1 + featureType, featureVal = string.split(line, " ", 1) + if featureType in ["fun", "get", "set"]: + retType, name, value, param1, param2 = decodeFunction(featureVal) + p1 = decodeParam(param1) + p2 = decodeParam(param2) + self.features[name] = { + "FeatureType": featureType, + "ReturnType": retType, + "Value": value, + "Param1Type": p1[0], "Param1Name": p1[1], "Param1Value": p1[2], + "Param2Type": p2[0], "Param2Name": p2[1], "Param2Value": p2[2], + "Category": currentCategory, "Comment": currentComment + } + if self.values.has_key(value): + raise "Duplicate value " + value + " " + name + self.values[value] = 1 + self.order.append(name) + elif featureType == "evt": + retType, name, value = decodeEvent(featureVal) + self.features[name] = { + "FeatureType": featureType, + "ReturnType": retType, + "Value": value, + "Category": currentCategory, "Comment": currentComment + } + if self.events.has_key(value): + raise "Duplicate event " + value + " " + name + self.events[value] = 1 + self.order.append(name) + elif featureType == "cat": + currentCategory = featureVal + elif featureType == "val": + name, value = string.split(featureVal, "=", 1) + self.features[name] = { + "FeatureType": featureType, + "Category": currentCategory, + "Value": value } + self.order.append(name) + elif featureType == "enu" or featureType == "lex": + name, value = string.split(featureVal, "=", 1) + self.features[name] = { + "FeatureType": featureType, + "Category": currentCategory, + "Value": value } + self.order.append(name) + diff --git a/vscript/languages/gm/src/gmd/include/HFacer.py b/vscript/languages/gm/src/gmd/include/HFacer.py new file mode 100644 index 00000000..eb5c6973 --- /dev/null +++ b/vscript/languages/gm/src/gmd/include/HFacer.py @@ -0,0 +1,61 @@ +# HFacer.py - regenerate the Scintilla.h and SciLexer.h files from the Scintilla.iface interface +# definition file. +# The header files are copied to a temporary file apart from the section between a //++Autogenerated +# comment and a //--Autogenerated comment which is generated by the printHFile and printLexHFile +# functions. After the temporary file is created, it is copied back to the original file name. + +import string +import sys +import os +import Face + +def Contains(s,sub): + return string.find(s, sub) != -1 + +def printLexHFile(f,out): + for name in f.order: + v = f.features[name] + if v["FeatureType"] in ["val"]: + if Contains(name, "SCE_") or Contains(name, "SCLEX_"): + out.write("#define " + name + " " + v["Value"] + "\n") + +def printHFile(f,out): + for name in f.order: + v = f.features[name] + if v["Category"] != "Deprecated": + if v["FeatureType"] in ["fun", "get", "set"]: + featureDefineName = "SCI_" + string.upper(name) + out.write("#define " + featureDefineName + " " + v["Value"] + "\n") + elif v["FeatureType"] in ["evt"]: + featureDefineName = "SCN_" + string.upper(name) + out.write("#define " + featureDefineName + " " + v["Value"] + "\n") + elif v["FeatureType"] in ["val"]: + if not (Contains(name, "SCE_") or Contains(name, "SCLEX_")): + out.write("#define " + name + " " + v["Value"] + "\n") + +def CopyWithInsertion(input, output, genfn, definition): + copying = 1 + for line in input.readlines(): + if copying: + output.write(line) + if Contains(line, "//++Autogenerated"): + copying = 0 + genfn(definition, output) + if Contains(line, "//--Autogenerated"): + copying = 1 + output.write(line) + +def Regenerate(filename, genfn, definition): + tempname = "HFacer.tmp" + out = open(tempname,"w") + hfile = open(filename) + CopyWithInsertion(hfile, out, genfn, definition) + out.close() + hfile.close() + os.unlink(filename) + os.rename(tempname, filename) + +f = Face.Face() +f.ReadFromFile("Scintilla.iface") +Regenerate("Scintilla.h", printHFile, f) +Regenerate("SciLexer.h", printLexHFile, f) diff --git a/vscript/languages/gm/src/gmd/include/KeyWords.h b/vscript/languages/gm/src/gmd/include/KeyWords.h new file mode 100644 index 00000000..df4e870c --- /dev/null +++ b/vscript/languages/gm/src/gmd/include/KeyWords.h @@ -0,0 +1,74 @@ +// Scintilla source code edit control +/** @file KeyWords.h + ** Colourise for particular languages. + **/ +// Copyright 1998-2001 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle, + WordList *keywordlists[], Accessor &styler); + +/** + * A LexerModule is responsible for lexing and folding a particular language. + * The class maintains a list of LexerModules which can be searched to find a + * module appropriate to a particular language. + */ +class LexerModule { +protected: + const LexerModule *next; + int language; + LexerFunction fnLexer; + LexerFunction fnFolder; + const char * const * wordListDescriptions; + + static const LexerModule *base; + static int nextLanguage; + +public: + const char *languageName; + LexerModule(int language_, LexerFunction fnLexer_, + const char *languageName_=0, LexerFunction fnFolder_=0, + const char * const wordListDescriptions_[] = NULL); + int GetLanguage() const { return language; } + + // -1 is returned if no WordList information is available + int GetNumWordLists() const; + const char *GetWordListDescription(int index) const; + + virtual void Lex(unsigned int startPos, int lengthDoc, int initStyle, + WordList *keywordlists[], Accessor &styler) const; + virtual void Fold(unsigned int startPos, int lengthDoc, int initStyle, + WordList *keywordlists[], Accessor &styler) const; + static const LexerModule *Find(int language); + static const LexerModule *Find(const char *languageName); +}; + +/** + * Check if a character is a space. + * This is ASCII specific but is safe with chars >= 0x80. + */ +inline bool isspacechar(unsigned char ch) { + return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); +} + +inline bool iswordchar(char ch) { + return isascii(ch) && (isalnum(ch) || ch == '.' || ch == '_'); +} + +inline bool iswordstart(char ch) { + return isascii(ch) && (isalnum(ch) || ch == '_'); +} + +inline bool isoperator(char ch) { + if (isascii(ch) && isalnum(ch)) + return false; + // '.' left out as it is used to make up numbers + if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || + ch == '(' || ch == ')' || ch == '-' || ch == '+' || + ch == '=' || ch == '|' || ch == '{' || ch == '}' || + ch == '[' || ch == ']' || ch == ':' || ch == ';' || + ch == '<' || ch == '>' || ch == ',' || ch == '/' || + ch == '?' || ch == '!' || ch == '.' || ch == '~') + return true; + return false; +} diff --git a/vscript/languages/gm/src/gmd/include/Platform.h b/vscript/languages/gm/src/gmd/include/Platform.h new file mode 100644 index 00000000..1765c6a8 --- /dev/null +++ b/vscript/languages/gm/src/gmd/include/Platform.h @@ -0,0 +1,486 @@ +// Scintilla source code edit control +/** @file Platform.h + ** Interface to platform facilities. Also includes some basic utilities. + ** Implemented in PlatGTK.cxx for GTK+/Linux, PlatWin.cxx for Windows, and PlatWX.cxx for wxWindows. + **/ +// Copyright 1998-2002 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef PLATFORM_H +#define PLATFORM_H + +// PLAT_GTK = GTK+ on Linux or Win32 +// PLAT_GTK_WIN32 is defined additionally when running PLAT_GTK under Win32 +// PLAT_WIN = Win32 API on Win32 OS +// PLAT_WX is wxWindows on any supported platform + +#define PLAT_GTK 0 +#define PLAT_GTK_WIN32 0 +#define PLAT_WIN 1 +#define PLAT_WX 0 +#define PLAT_FOX 0 + +#if defined(FOX) +#undef PLAT_FOX +#define PLAT_FOX 1 + +#elif defined(__WX__) +#undef PLAT_WX +#define PLAT_WX 1 + +#elif defined(GTK) +#undef PLAT_GTK +#define PLAT_GTK 1 + +#ifdef _MSC_VER +#undef PLAT_GTK_WIN32 +#define PLAT_GTK_WIN32 1 +#endif + +#else +#undef PLAT_WIN +#define PLAT_WIN 1 + +#endif + + +// Underlying the implementation of the platform classes are platform specific types. +// Sometimes these need to be passed around by client code so they are defined here + +typedef void *FontID; +typedef void *SurfaceID; +typedef void *WindowID; +typedef void *MenuID; +typedef void *TickerID; + +/** + * A geometric point class. + * Point is exactly the same as the Win32 POINT and GTK+ GdkPoint so can be used interchangeably. + */ +class Point { +public: + int x; + int y; + + Point(int x_=0, int y_=0) : x(x_), y(y_) { + } + + // Other automatically defined methods (assignment, copy constructor, destructor) are fine + + static Point FromLong(long lpoint); +}; + +/** + * A geometric rectangle class. + * PRectangle is exactly the same as the Win32 RECT so can be used interchangeably. + * PRectangles contain their top and left sides, but not their right and bottom sides. + */ +class PRectangle { +public: + int left; + int top; + int right; + int bottom; + + PRectangle(int left_=0, int top_=0, int right_=0, int bottom_ = 0) : + left(left_), top(top_), right(right_), bottom(bottom_) { + } + + // Other automatically defined methods (assignment, copy constructor, destructor) are fine + + bool operator==(PRectangle &rc) { + return (rc.left == left) && (rc.right == right) && + (rc.top == top) && (rc.bottom == bottom); + } + bool Contains(Point pt) { + return (pt.x >= left) && (pt.x <= right) && + (pt.y >= top) && (pt.y <= bottom); + } + bool Contains(PRectangle rc) { + return (rc.left >= left) && (rc.right <= right) && + (rc.top >= top) && (rc.bottom <= bottom); + } + bool Intersects(PRectangle other) { + return (right > other.left) && (left < other.right) && + (bottom > other.top) && (top < other.bottom); + } + int Width() { return right - left; } + int Height() { return bottom - top; } +}; + +/** + * In some circumstances, including Win32 in paletted mode and GTK+, each colour + * must be allocated before use. The desired colours are held in the ColourDesired class, + * and after allocation the allocation entry is stored in the ColourAllocated class. In other + * circumstances, such as Win32 in true colour mode, the allocation process just copies + * the RGB values from the desired to the allocated class. + * As each desired colour requires allocation before it can be used, the ColourPair class + * holds both a ColourDesired and a ColourAllocated + * The Palette class is responsible for managing the palette of colours which contains a + * list of ColourPair objects and performs the allocation. + */ + +/** + * Holds a desired RGB colour. + */ +class ColourDesired { + long co; +public: + ColourDesired(long lcol=0) { + co = lcol; + } + + ColourDesired(unsigned int red, unsigned int green, unsigned int blue) { + Set(red, green, blue); + } + + bool operator==(const ColourDesired &other) const { + return co == other.co; + } + + void Set(long lcol) { + co = lcol; + } + + void Set(unsigned int red, unsigned int green, unsigned int blue) { + co = red | (green << 8) | (blue << 16); + } + + static inline unsigned int ValueOfHex(const char ch) { + if (ch >= '0' && ch <= '9') + return ch - '0'; + else if (ch >= 'A' && ch <= 'F') + return ch - 'A' + 10; + else if (ch >= 'a' && ch <= 'f') + return ch - 'a' + 10; + else + return 0; + } + + void Set(const char *val) { + if (*val == '#') { + val++; + } + unsigned int r = ValueOfHex(val[0]) * 16 + ValueOfHex(val[1]); + unsigned int g = ValueOfHex(val[2]) * 16 + ValueOfHex(val[3]); + unsigned int b = ValueOfHex(val[4]) * 16 + ValueOfHex(val[5]); + Set(r, g, b); + } + + long AsLong() const { + return co; + } + + unsigned int GetRed() { + return co & 0xff; + } + + unsigned int GetGreen() { + return (co >> 8) & 0xff; + } + + unsigned int GetBlue() { + return (co >> 16) & 0xff; + } +}; + +/** + * Holds an allocated RGB colour which may be an approximation to the desired colour. + */ +class ColourAllocated { + long coAllocated; + +public: + + ColourAllocated(long lcol=0) { + coAllocated = lcol; + } + + void Set(long lcol) { + coAllocated = lcol; + } + + long AsLong() const { + return coAllocated; + } +}; + +/** + * Colour pairs hold a desired colour and an allocated colour. + */ +struct ColourPair { + ColourDesired desired; + ColourAllocated allocated; + + ColourPair(ColourDesired desired_=ColourDesired(0,0,0)) { + desired = desired_; + allocated.Set(desired.AsLong()); + } +}; + +class Window; // Forward declaration for Palette + +/** + * Colour palette management. + */ +class Palette { + int used; + enum {numEntries = 100}; + ColourPair entries[numEntries]; +#if PLAT_GTK + void *allocatedPalette; // GdkColor * + int allocatedLen; +#endif +public: +#if PLAT_WIN + void *hpal; +#endif + bool allowRealization; + + Palette(); + ~Palette(); + + void Release(); + + /** + * This method either adds a colour to the list of wanted colours (want==true) + * or retrieves the allocated colour back to the ColourPair. + * This is one method to make it easier to keep the code for wanting and retrieving in sync. + */ + void WantFind(ColourPair &cp, bool want); + + void Allocate(Window &w); +}; + +/** + * Font management. + */ +class Font { +protected: + FontID id; +#if PLAT_WX + int ascent; +#endif + // Private so Font objects can not be copied + Font(const Font &) {} + Font &operator=(const Font &) { id=0; return *this; } +public: + Font(); + virtual ~Font(); + + virtual void Create(const char *faceName, int characterSet, int size, bool bold, bool italic); + virtual void Release(); + + FontID GetID() { return id; } + // Alias another font - caller guarantees not to Release + void SetID(FontID id_) { id = id_; } + friend class Surface; +}; + +/** + * A surface abstracts a place to draw. + */ +class Surface { +private: + // Private so Surface objects can not be copied + Surface(const Surface &) {} + Surface &operator=(const Surface &) { return *this; } +public: + Surface() {}; + virtual ~Surface() {}; + static Surface *Allocate(); + + virtual void Init()=0; + virtual void Init(SurfaceID sid)=0; + virtual void InitPixMap(int width, int height, Surface *surface_)=0; + + virtual void Release()=0; + virtual bool Initialised()=0; + virtual void PenColour(ColourAllocated fore)=0; + virtual int LogPixelsY()=0; + virtual int DeviceHeightFont(int points)=0; + virtual void MoveTo(int x_, int y_)=0; + virtual void LineTo(int x_, int y_)=0; + virtual void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back)=0; + virtual void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0; + virtual void FillRectangle(PRectangle rc, ColourAllocated back)=0; + virtual void FillRectangle(PRectangle rc, Surface &surfacePattern)=0; + virtual void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0; + virtual void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0; + virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0; + + virtual void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back)=0; + virtual void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back)=0; + virtual void MeasureWidths(Font &font_, const char *s, int len, int *positions)=0; + virtual int WidthText(Font &font_, const char *s, int len)=0; + virtual int WidthChar(Font &font_, char ch)=0; + virtual int Ascent(Font &font_)=0; + virtual int Descent(Font &font_)=0; + virtual int InternalLeading(Font &font_)=0; + virtual int ExternalLeading(Font &font_)=0; + virtual int Height(Font &font_)=0; + virtual int AverageCharWidth(Font &font_)=0; + + virtual int SetPalette(Palette *pal, bool inBackGround)=0; + virtual void SetClip(PRectangle rc)=0; + virtual void FlushCachedState()=0; + + virtual void SetUnicodeMode(bool unicodeMode_)=0; +}; + +/** + * A simple callback action passing one piece of untyped user data. + */ +typedef void (*CallBackAction)(void*); + +/** + * Class to hide the details of window manipulation. + * Does not own the window which will normally have a longer life than this object. + */ +class Window { +protected: + WindowID id; +public: + Window() : id(0), cursorLast(cursorInvalid) {} + Window(const Window &source) : id(source.id), cursorLast(cursorInvalid) {} + virtual ~Window(); + Window &operator=(WindowID id_) { + id = id_; + return *this; + } + WindowID GetID() { return id; } + bool Created() { return id != 0; } + void Destroy(); + bool HasFocus(); + PRectangle GetPosition(); + void SetPosition(PRectangle rc); + void SetPositionRelative(PRectangle rc, Window relativeTo); + PRectangle GetClientPosition(); + void Show(bool show=true); + void InvalidateAll(); + void InvalidateRectangle(PRectangle rc); + virtual void SetFont(Font &font); + enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow }; + void SetCursor(Cursor curs); + void SetTitle(const char *s); +private: + Cursor cursorLast; +}; + +/** + * Listbox management. + */ + +class ListBox : public Window { +private: +#if PLAT_GTK + WindowID list; + WindowID scroller; + int current; +#endif + int desiredVisibleRows; + unsigned int maxItemCharacters; + unsigned int aveCharWidth; +public: + CallBackAction doubleClickAction; + void *doubleClickActionData; +public: + ListBox(); + virtual ~ListBox(); + void Create(Window &parent, int ctrlID); + virtual void SetFont(Font &font); + void SetAverageCharWidth(int width); + void SetVisibleRows(int rows); + PRectangle GetDesiredRect(); + void Clear(); + void Append(char *s); + int Length(); + void Select(int n); + int GetSelection(); + int Find(const char *prefix); + void GetValue(int n, char *value, int len); + void Sort(); + void SetDoubleClickAction(CallBackAction action, void *data) { + doubleClickAction = action; + doubleClickActionData = data; + } +}; + +/** + * Menu management. + */ +class Menu { + MenuID id; +public: + Menu(); + MenuID GetID() { return id; } + void CreatePopUp(); + void Destroy(); + void Show(Point pt, Window &w); +}; + +class ElapsedTime { + long bigBit; + long littleBit; +public: + ElapsedTime(); + double Duration(bool reset=false); +}; + +/** + * Platform class used to retrieve system wide parameters such as double click speed + * and chrome colour. Not a creatable object, more of a module with several functions. + */ +class Platform { + // Private so Platform objects can not be copied + Platform(const Platform &) {} + Platform &operator=(const Platform &) { return *this; } +public: + // Should be private because no new Platforms are ever created + // but gcc warns about this + Platform() {} + ~Platform() {} + static ColourDesired Chrome(); + static ColourDesired ChromeHighlight(); + static const char *DefaultFont(); + static int DefaultFontSize(); + static unsigned int DoubleClickTime(); + static void DebugDisplay(const char *s); + static bool IsKeyDown(int key); + static long SendScintilla( + WindowID w, unsigned int msg, unsigned long wParam=0, long lParam=0); + static long SendScintillaPointer( + WindowID w, unsigned int msg, unsigned long wParam=0, void *lParam=0); + static bool IsDBCSLeadByte(int codePage, char ch); + + // These are utility functions not really tied to a platform + static int Minimum(int a, int b); + static int Maximum(int a, int b); + // Next three assume 16 bit shorts and 32 bit longs + static long LongFromTwoShorts(short a,short b) { + return (a) | ((b) << 16); + } + static short HighShortFromLong(long x) { + return static_cast(x >> 16); + } + static short LowShortFromLong(long x) { + return static_cast(x & 0xffff); + } + static void DebugPrintf(const char *format, ...); + static bool ShowAssertionPopUps(bool assertionPopUps_); + static void Assert(const char *c, const char *file, int line); + static int Clamp(int val, int minVal, int maxVal); +}; + +#ifdef NDEBUG +#define PLATFORM_ASSERT(c) ((void)0) +#else +#define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Platform::Assert(#c, __FILE__, __LINE__)) +#endif + +// Shut up annoying Visual C++ warnings: +#ifdef _MSC_VER +#pragma warning(disable: 4244 4309 4514 4710) +#endif + +#endif diff --git a/vscript/languages/gm/src/gmd/include/PropSet.h b/vscript/languages/gm/src/gmd/include/PropSet.h new file mode 100644 index 00000000..59588c62 --- /dev/null +++ b/vscript/languages/gm/src/gmd/include/PropSet.h @@ -0,0 +1,83 @@ +// Scintilla source code edit control +/** @file PropSet.h + ** A Java style properties file module. + **/ +// Copyright 1998-2002 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef PROPSET_H +#define PROPSET_H +#include "SString.h" + +bool EqualCaseInsensitive(const char *a, const char *b); + +bool isprefix(const char *target, const char *prefix); + +struct Property { + unsigned int hash; + char *key; + char *val; + Property *next; + Property() : hash(0), key(0), val(0), next(0) {} +}; + +/** + */ +class PropSet { +private: + enum { hashRoots=31 }; + Property *props[hashRoots]; + Property *enumnext; + int enumhash; +public: + PropSet *superPS; + PropSet(); + ~PropSet(); + void Set(const char *key, const char *val, int lenKey=-1, int lenVal=-1); + void Set(const char *keyVal); + void SetMultiple(const char *s); + SString Get(const char *key); + SString GetExpanded(const char *key); + SString Expand(const char *withVars); + int GetInt(const char *key, int defaultValue=0); + SString GetWild(const char *keybase, const char *filename); + SString GetNewExpand(const char *keybase, const char *filename=""); + void Clear(); + char *ToString(); // Caller must delete[] the return value + bool GetFirst(char **key, char **val); + bool GetNext(char **key, char **val); +}; + +/** + */ +class WordList { +public: + // Each word contains at least one character - a empty word acts as sentinel at the end. + char **words; + char **wordsNoCase; + char *list; + int len; + bool onlyLineEnds; ///< Delimited by any white space or only line ends + bool sorted; + int starts[256]; + WordList(bool onlyLineEnds_ = false) : + words(0), wordsNoCase(0), list(0), len(0), onlyLineEnds(onlyLineEnds_), sorted(false) {} + ~WordList() { Clear(); } + operator bool() { return len ? true : false; } + char *operator[](int ind) { return words[ind]; } + void Clear(); + void Set(const char *s); + char *Allocate(int size); + void SetFromAllocated(); + bool InList(const char *s); + const char *GetNearestWord(const char *wordStart, int searchLen = -1, + bool ignoreCase = false, SString wordCharacters=""); + char *GetNearestWords(const char *wordStart, int searchLen=-1, + bool ignoreCase=false, char otherSeparator='\0'); +}; + +inline bool IsAlphabetic(unsigned int ch) { + return ((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z')); +} + +#endif diff --git a/vscript/languages/gm/src/gmd/include/SString.h b/vscript/languages/gm/src/gmd/include/SString.h new file mode 100644 index 00000000..01602df7 --- /dev/null +++ b/vscript/languages/gm/src/gmd/include/SString.h @@ -0,0 +1,377 @@ +// SciTE - Scintilla based Text Editor +/** @file SString.h + ** A simple string class. + **/ +// Copyright 1998-2001 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef SSTRING_H +#define SSTRING_H + +// These functions are implemented because each platform calls them something different. +int CompareCaseInsensitive(const char *a, const char *b); +int CompareNCaseInsensitive(const char *a, const char *b, size_t len); +bool EqualCaseInsensitive(const char *a, const char *b); + +// Define another string class. +// While it would be 'better' to use std::string, that doubles the executable size. +// An SString may contain embedded nul characters. + +/** + * @brief A simple string class. + * + * Hold the length of the string for quick operations, + * can have a buffer bigger than the string to avoid too many memory allocations and copies. + * May have embedded zeroes as a result of @a substitute, but relies too heavily on C string + * functions to allow reliable manipulations of these strings, other than simple appends, etc. + **/ +class SString { +public: + /** Type of string lengths (sizes) and positions (indexes). */ + typedef size_t lenpos_t; + /** Out of bounds value indicating that the string argument should be measured. */ + enum { measure_length=0xffffffffU}; + +private: + char *s; ///< The C string + lenpos_t sSize; ///< The size of the buffer, less 1: ie. the maximum size of the string + lenpos_t sLen; ///< The size of the string in s + lenpos_t sizeGrowth; ///< Minimum growth size when appending strings + enum { sizeGrowthDefault = 64 }; + bool grow(lenpos_t lenNew) { + while (sizeGrowth * 6 < lenNew) { + sizeGrowth *= 2; + } + char *sNew = new char[lenNew + sizeGrowth + 1]; + if (sNew) { + if (s) { + memcpy(sNew, s, sLen); + delete []s; + } + s = sNew; + s[sLen] = '\0'; + sSize = lenNew + sizeGrowth; + } + return sNew != 0; + } + + SString &assign(const char *sOther, lenpos_t sSize_=measure_length) { + if (!sOther) { + sSize_ = 0; + } else if (sSize_ == measure_length) { + sSize_ = strlen(sOther); + } + if (sSize > 0 && sSize_ <= sSize) { // Does not allocate new buffer if the current is big enough + if (s && sSize_) { + memcpy(s, sOther, sSize_); + } + s[sSize_] = '\0'; + sLen = sSize_; + } else { + delete []s; + s = StringAllocate(sOther, sSize_); + if (s) { + sSize = sSize_; // Allow buffer bigger than real string, thus providing space to grow + sLen = strlen(s); + } else { + sSize = sLen = 0; + } + } + return *this; + } + +public: + SString() : s(0), sSize(0), sLen(0), sizeGrowth(sizeGrowthDefault) { + } + SString(const SString &source) : sizeGrowth(sizeGrowthDefault) { + s = StringAllocate(source.s); + sSize = sLen = (s) ? strlen(s) : 0; + } + SString(const char *s_) : sizeGrowth(sizeGrowthDefault) { + s = StringAllocate(s_); + sSize = sLen = (s) ? strlen(s) : 0; + } + SString(const char *s_, lenpos_t first, lenpos_t last) : sizeGrowth(sizeGrowthDefault) { + // note: expects the "last" argument to point one beyond the range end (a la STL iterators) + s = StringAllocate(s_ + first, last - first); + sSize = sLen = (s) ? strlen(s) : 0; + } + SString(int i) : sizeGrowth(sizeGrowthDefault) { + char number[32]; + sprintf(number, "%0d", i); + s = StringAllocate(number); + sSize = sLen = (s) ? strlen(s) : 0; + } + SString(double d, int precision) : sizeGrowth(sizeGrowthDefault) { + char number[32]; + sprintf(number, "%.*f", precision, d); + s = StringAllocate(number); + sSize = sLen = (s) ? strlen(s) : 0; + } + ~SString() { + delete []s; + s = 0; + sSize = 0; + sLen = 0; + } + void clear() { + if (s) { + *s = '\0'; + } + sLen = 0; + } + /** Size of buffer. */ + lenpos_t size() const { + if (s) + return sSize; + else + return 0; + } + /** Size of string in buffer. */ + lenpos_t length() const { + return sLen; + } + SString &operator=(const char *source) { + return assign(source); + } + SString &operator=(const SString &source) { + if (this != &source) { + assign(source.c_str()); + } + return *this; + } + bool operator==(const SString &sOther) const { + if ((s == 0) && (sOther.s == 0)) + return true; + if ((s == 0) || (sOther.s == 0)) + return false; + return strcmp(s, sOther.s) == 0; + } + bool operator!=(const SString &sOther) const { + return !operator==(sOther); + } + bool operator==(const char *sOther) const { + if ((s == 0) && (sOther == 0)) + return true; + if ((s == 0) || (sOther == 0)) + return false; + return strcmp(s, sOther) == 0; + } + bool operator!=(const char *sOther) const { + return !operator==(sOther); + } + bool contains(char ch) { + if (s && *s) + return strchr(s, ch) != 0; + else + return false; + } + void setsizegrowth(lenpos_t sizeGrowth_) { + sizeGrowth = sizeGrowth_; + } + const char *c_str() const { + if (s) + return s; + else + return ""; + } + /** Give ownership of buffer to caller which must use delete[] to free buffer. */ + char *detach() { + char *sRet = s; + s = 0; + sSize = 0; + sLen = 0; + return sRet; + } + char operator[](lenpos_t i) const { + if (s && i < sSize) // Or < sLen? Depends on the use, both are OK + return s[i]; + else + return '\0'; + } + SString substr(lenpos_t subPos, lenpos_t subLen=measure_length) const { + if (subPos >= sLen) { + return SString(); // return a null string if start index is out of bounds + } + if ((subLen == measure_length) || (subPos + subLen > sLen)) { + subLen = sLen - subPos; // can't substr past end of source string + } + return SString(s, subPos, subPos + subLen); + } + SString &lowercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length) { + if ((subLen == measure_length) || (subPos + subLen > sLen)) { + subLen = sLen - subPos; // don't apply past end of string + } + for (lenpos_t i = subPos; i < subPos + subLen; i++) { + if (s[i] < 'A' || s[i] > 'Z') + continue; + else + s[i] = static_cast(s[i] - 'A' + 'a'); + } + return *this; + } + SString &append(const char *sOther, lenpos_t sLenOther=measure_length, char sep = '\0') { + if (!sOther) { + return *this; + } + if (sLenOther == measure_length) { + sLenOther = strlen(sOther); + } + int lenSep = 0; + if (sLen && sep) { // Only add a separator if not empty + lenSep = 1; + } + lenpos_t lenNew = sLen + sLenOther + lenSep; + // Conservative about growing the buffer: don't do it, unless really needed + if ((lenNew + 1 < sSize) || (grow(lenNew))) { + if (lenSep) { + s[sLen] = sep; + sLen++; + } + memcpy(&s[sLen], sOther, sLenOther); + sLen += sLenOther; + s[sLen] = '\0'; + } + return *this; + } + SString &operator+=(const char *sOther) { + return append(sOther, static_cast(measure_length)); + } + SString &operator+=(const SString &sOther) { + return append(sOther.s, sOther.sLen); + } + SString &operator+=(char ch) { + return append(&ch, 1); + } + SString &appendwithseparator(const char *sOther, char sep) { + return append(sOther, strlen(sOther), sep); + } + SString &insert(lenpos_t pos, const char *sOther, lenpos_t sLenOther=measure_length) { + if (!sOther) { + return *this; + } + if (sLenOther == measure_length) { + sLenOther = strlen(sOther); + } + lenpos_t lenNew = sLen + sLenOther; + // Conservative about growing the buffer: don't do it, unless really needed + if ((lenNew + 1 < sSize) || grow(lenNew)) { + lenpos_t moveChars = sLen - pos + 1; + for (lenpos_t i = moveChars; i > 0; i--) { + s[pos + sLenOther + i - 1] = s[pos + i - 1]; + } + memcpy(s + pos, sOther, sLenOther); + sLen = lenNew; + } + return *this; + } + /** Remove @a len characters from the @a pos position, included. + * Characters at pos + len and beyond replace characters at pos. + * If @a len is 0, or greater than the length of the string + * starting at @a pos, the string is just truncated at @a pos. + */ + void remove(lenpos_t pos, lenpos_t len) { + if (len < 1 || pos + len >= sLen) { + s[pos] = '\0'; + sLen = pos; + } else { + for (lenpos_t i = pos; i < sLen - len + 1; i++) { + s[i] = s[i+len]; + } + sLen -= len; + } + } + SString &change(lenpos_t pos, char ch) { + if (pos >= sLen) { // character changed must be in string bounds + return *this; + } + *(s + pos) = ch; + return *this; + } + /** Read an integral numeric value from the string. */ + int value() const { + if (s) + return atoi(s); + else + return 0; + } + int search(const char *sFind, lenpos_t start=0) const { + if (start < sLen) { + const char *sFound = strstr(s + start, sFind); + if (sFound) { + return sFound - s; + } + } + return -1; + } + bool contains(const char *sFind) { + return search(sFind) >= 0; + } + int substitute(char chFind, char chReplace) { + int c = 0; + char *t = s; + while (t) { + t = strchr(t, chFind); + if (t) { + *t = chReplace; + t++; + c++; + } + } + return c; + } + int substitute(const char *sFind, const char *sReplace) { + int c = 0; + lenpos_t lenFind = strlen(sFind); + lenpos_t lenReplace = strlen(sReplace); + int posFound = search(sFind); + while (posFound >= 0) { + remove(posFound, lenFind); + insert(posFound, sReplace, lenReplace); + posFound = search(sFind, posFound + lenReplace); + c++; + } + return c; + } + int remove(const char *sFind) { + return substitute(sFind, ""); + } + /** + * Duplicate a C string. + * Allocate memory of the given size, or big enough to fit the string if length isn't given; + * then copy the given string in the allocated memory. + * @return the pointer to the new string + */ + static char *StringAllocate( + const char *s, ///< The string to duplicate + lenpos_t len=measure_length) ///< The length of memory to allocate. Optional. + { + if (s == 0) { + return 0; + } + if (len == measure_length) { + len = strlen(s); + } + char *sNew = new char[len + 1]; + if (sNew) { + memcpy(sNew, s, len); + sNew[len] = '\0'; + } + return sNew; + } +}; + +/** + * Duplicate a C string. + * Allocate memory of the given size, or big enough to fit the string if length isn't given; + * then copy the given string in the allocated memory. + * @return the pointer to the new string + */ +inline char *StringDup( + const char *s, ///< The string to duplicate + SString::lenpos_t len=SString::measure_length) ///< The length of memory to allocate. Optional. +{ + return SString::StringAllocate(s, len); +} + +#endif diff --git a/vscript/languages/gm/src/gmd/include/SciLexer.h b/vscript/languages/gm/src/gmd/include/SciLexer.h new file mode 100644 index 00000000..f3bd22d8 --- /dev/null +++ b/vscript/languages/gm/src/gmd/include/SciLexer.h @@ -0,0 +1,431 @@ +// Scintilla source code edit control +/** @file SciLexer.h + ** Interface to the added lexer functions in the SciLexer version of the edit control. + **/ +// Copyright 1998-2002 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +// Most of this file is automatically generated from the Scintilla.iface interface definition +// file which contains any comments about the definitions. HFacer.py does the generation. + +#ifndef SCILEXER_H +#define SCILEXER_H + +// SciLexer features - not in standard Scintilla + +//++Autogenerated -- start of section automatically generated from Scintilla.iface +#define SCLEX_CONTAINER 0 +#define SCLEX_NULL 1 +#define SCLEX_PYTHON 2 +#define SCLEX_CPP 3 +#define SCLEX_HTML 4 +#define SCLEX_XML 5 +#define SCLEX_PERL 6 +#define SCLEX_SQL 7 +#define SCLEX_VB 8 +#define SCLEX_PROPERTIES 9 +#define SCLEX_ERRORLIST 10 +#define SCLEX_MAKEFILE 11 +#define SCLEX_BATCH 12 +#define SCLEX_XCODE 13 +#define SCLEX_LATEX 14 +#define SCLEX_LUA 15 +#define SCLEX_DIFF 16 +#define SCLEX_CONF 17 +#define SCLEX_PASCAL 18 +#define SCLEX_AVE 19 +#define SCLEX_ADA 20 +#define SCLEX_LISP 21 +#define SCLEX_RUBY 22 +#define SCLEX_EIFFEL 23 +#define SCLEX_EIFFELKW 24 +#define SCLEX_TCL 25 +#define SCLEX_NNCRONTAB 26 +#define SCLEX_BULLANT 27 +#define SCLEX_VBSCRIPT 28 +#define SCLEX_ASP 29 +#define SCLEX_PHP 30 +#define SCLEX_BAAN 31 +#define SCLEX_MATLAB 32 +#define SCLEX_SCRIPTOL 33 +#define SCLEX_ASM 34 +#define SCLEX_CPPNOCASE 35 +#define SCLEX_FORTRAN 36 +#define SCLEX_F77 37 +#define SCLEX_AUTOMATIC 1000 +#define SCE_P_DEFAULT 0 +#define SCE_P_COMMENTLINE 1 +#define SCE_P_NUMBER 2 +#define SCE_P_STRING 3 +#define SCE_P_CHARACTER 4 +#define SCE_P_WORD 5 +#define SCE_P_TRIPLE 6 +#define SCE_P_TRIPLEDOUBLE 7 +#define SCE_P_CLASSNAME 8 +#define SCE_P_DEFNAME 9 +#define SCE_P_OPERATOR 10 +#define SCE_P_IDENTIFIER 11 +#define SCE_P_COMMENTBLOCK 12 +#define SCE_P_STRINGEOL 13 +#define SCE_C_DEFAULT 0 +#define SCE_C_COMMENT 1 +#define SCE_C_COMMENTLINE 2 +#define SCE_C_COMMENTDOC 3 +#define SCE_C_NUMBER 4 +#define SCE_C_WORD 5 +#define SCE_C_STRING 6 +#define SCE_C_CHARACTER 7 +#define SCE_C_UUID 8 +#define SCE_C_PREPROCESSOR 9 +#define SCE_C_OPERATOR 10 +#define SCE_C_IDENTIFIER 11 +#define SCE_C_STRINGEOL 12 +#define SCE_C_VERBATIM 13 +#define SCE_C_REGEX 14 +#define SCE_C_COMMENTLINEDOC 15 +#define SCE_C_WORD2 16 +#define SCE_C_COMMENTDOCKEYWORD 17 +#define SCE_C_COMMENTDOCKEYWORDERROR 18 +#define SCE_H_DEFAULT 0 +#define SCE_H_TAG 1 +#define SCE_H_TAGUNKNOWN 2 +#define SCE_H_ATTRIBUTE 3 +#define SCE_H_ATTRIBUTEUNKNOWN 4 +#define SCE_H_NUMBER 5 +#define SCE_H_DOUBLESTRING 6 +#define SCE_H_SINGLESTRING 7 +#define SCE_H_OTHER 8 +#define SCE_H_COMMENT 9 +#define SCE_H_ENTITY 10 +#define SCE_H_TAGEND 11 +#define SCE_H_XMLSTART 12 +#define SCE_H_XMLEND 13 +#define SCE_H_SCRIPT 14 +#define SCE_H_ASP 15 +#define SCE_H_ASPAT 16 +#define SCE_H_CDATA 17 +#define SCE_H_QUESTION 18 +#define SCE_H_VALUE 19 +#define SCE_H_XCCOMMENT 20 +#define SCE_H_SGML_DEFAULT 21 +#define SCE_H_SGML_COMMAND 22 +#define SCE_H_SGML_1ST_PARAM 23 +#define SCE_H_SGML_DOUBLESTRING 24 +#define SCE_H_SGML_SIMPLESTRING 25 +#define SCE_H_SGML_ERROR 26 +#define SCE_H_SGML_SPECIAL 27 +#define SCE_H_SGML_ENTITY 28 +#define SCE_H_SGML_COMMENT 29 +#define SCE_H_SGML_1ST_PARAM_COMMENT 30 +#define SCE_H_SGML_BLOCK_DEFAULT 31 +#define SCE_HJ_START 40 +#define SCE_HJ_DEFAULT 41 +#define SCE_HJ_COMMENT 42 +#define SCE_HJ_COMMENTLINE 43 +#define SCE_HJ_COMMENTDOC 44 +#define SCE_HJ_NUMBER 45 +#define SCE_HJ_WORD 46 +#define SCE_HJ_KEYWORD 47 +#define SCE_HJ_DOUBLESTRING 48 +#define SCE_HJ_SINGLESTRING 49 +#define SCE_HJ_SYMBOLS 50 +#define SCE_HJ_STRINGEOL 51 +#define SCE_HJ_REGEX 52 +#define SCE_HJA_START 55 +#define SCE_HJA_DEFAULT 56 +#define SCE_HJA_COMMENT 57 +#define SCE_HJA_COMMENTLINE 58 +#define SCE_HJA_COMMENTDOC 59 +#define SCE_HJA_NUMBER 60 +#define SCE_HJA_WORD 61 +#define SCE_HJA_KEYWORD 62 +#define SCE_HJA_DOUBLESTRING 63 +#define SCE_HJA_SINGLESTRING 64 +#define SCE_HJA_SYMBOLS 65 +#define SCE_HJA_STRINGEOL 66 +#define SCE_HJA_REGEX 67 +#define SCE_HB_START 70 +#define SCE_HB_DEFAULT 71 +#define SCE_HB_COMMENTLINE 72 +#define SCE_HB_NUMBER 73 +#define SCE_HB_WORD 74 +#define SCE_HB_STRING 75 +#define SCE_HB_IDENTIFIER 76 +#define SCE_HB_STRINGEOL 77 +#define SCE_HBA_START 80 +#define SCE_HBA_DEFAULT 81 +#define SCE_HBA_COMMENTLINE 82 +#define SCE_HBA_NUMBER 83 +#define SCE_HBA_WORD 84 +#define SCE_HBA_STRING 85 +#define SCE_HBA_IDENTIFIER 86 +#define SCE_HBA_STRINGEOL 87 +#define SCE_HP_START 90 +#define SCE_HP_DEFAULT 91 +#define SCE_HP_COMMENTLINE 92 +#define SCE_HP_NUMBER 93 +#define SCE_HP_STRING 94 +#define SCE_HP_CHARACTER 95 +#define SCE_HP_WORD 96 +#define SCE_HP_TRIPLE 97 +#define SCE_HP_TRIPLEDOUBLE 98 +#define SCE_HP_CLASSNAME 99 +#define SCE_HP_DEFNAME 100 +#define SCE_HP_OPERATOR 101 +#define SCE_HP_IDENTIFIER 102 +#define SCE_HPA_START 105 +#define SCE_HPA_DEFAULT 106 +#define SCE_HPA_COMMENTLINE 107 +#define SCE_HPA_NUMBER 108 +#define SCE_HPA_STRING 109 +#define SCE_HPA_CHARACTER 110 +#define SCE_HPA_WORD 111 +#define SCE_HPA_TRIPLE 112 +#define SCE_HPA_TRIPLEDOUBLE 113 +#define SCE_HPA_CLASSNAME 114 +#define SCE_HPA_DEFNAME 115 +#define SCE_HPA_OPERATOR 116 +#define SCE_HPA_IDENTIFIER 117 +#define SCE_HPHP_DEFAULT 118 +#define SCE_HPHP_HSTRING 119 +#define SCE_HPHP_SIMPLESTRING 120 +#define SCE_HPHP_WORD 121 +#define SCE_HPHP_NUMBER 122 +#define SCE_HPHP_VARIABLE 123 +#define SCE_HPHP_COMMENT 124 +#define SCE_HPHP_COMMENTLINE 125 +#define SCE_HPHP_HSTRING_VARIABLE 126 +#define SCE_HPHP_OPERATOR 127 +#define SCE_PL_DEFAULT 0 +#define SCE_PL_ERROR 1 +#define SCE_PL_COMMENTLINE 2 +#define SCE_PL_POD 3 +#define SCE_PL_NUMBER 4 +#define SCE_PL_WORD 5 +#define SCE_PL_STRING 6 +#define SCE_PL_CHARACTER 7 +#define SCE_PL_PUNCTUATION 8 +#define SCE_PL_PREPROCESSOR 9 +#define SCE_PL_OPERATOR 10 +#define SCE_PL_IDENTIFIER 11 +#define SCE_PL_SCALAR 12 +#define SCE_PL_ARRAY 13 +#define SCE_PL_HASH 14 +#define SCE_PL_SYMBOLTABLE 15 +#define SCE_PL_REGEX 17 +#define SCE_PL_REGSUBST 18 +#define SCE_PL_LONGQUOTE 19 +#define SCE_PL_BACKTICKS 20 +#define SCE_PL_DATASECTION 21 +#define SCE_PL_HERE_DELIM 22 +#define SCE_PL_HERE_Q 23 +#define SCE_PL_HERE_QQ 24 +#define SCE_PL_HERE_QX 25 +#define SCE_PL_STRING_Q 26 +#define SCE_PL_STRING_QQ 27 +#define SCE_PL_STRING_QX 28 +#define SCE_PL_STRING_QR 29 +#define SCE_PL_STRING_QW 30 +#define SCE_B_DEFAULT 0 +#define SCE_B_COMMENT 1 +#define SCE_B_NUMBER 2 +#define SCE_B_KEYWORD 3 +#define SCE_B_STRING 4 +#define SCE_B_PREPROCESSOR 5 +#define SCE_B_OPERATOR 6 +#define SCE_B_IDENTIFIER 7 +#define SCE_B_DATE 8 +#define SCE_PROPS_DEFAULT 0 +#define SCE_PROPS_COMMENT 1 +#define SCE_PROPS_SECTION 2 +#define SCE_PROPS_ASSIGNMENT 3 +#define SCE_PROPS_DEFVAL 4 +#define SCE_L_DEFAULT 0 +#define SCE_L_COMMAND 1 +#define SCE_L_TAG 2 +#define SCE_L_MATH 3 +#define SCE_L_COMMENT 4 +#define SCE_LUA_DEFAULT 0 +#define SCE_LUA_COMMENT 1 +#define SCE_LUA_COMMENTLINE 2 +#define SCE_LUA_COMMENTDOC 3 +#define SCE_LUA_NUMBER 4 +#define SCE_LUA_WORD 5 +#define SCE_LUA_STRING 6 +#define SCE_LUA_CHARACTER 7 +#define SCE_LUA_LITERALSTRING 8 +#define SCE_LUA_PREPROCESSOR 9 +#define SCE_LUA_OPERATOR 10 +#define SCE_LUA_IDENTIFIER 11 +#define SCE_LUA_STRINGEOL 12 +#define SCE_LUA_WORD2 13 +#define SCE_LUA_WORD3 14 +#define SCE_LUA_WORD4 15 +#define SCE_LUA_WORD5 16 +#define SCE_LUA_WORD6 17 +#define SCE_ERR_DEFAULT 0 +#define SCE_ERR_PYTHON 1 +#define SCE_ERR_GCC 2 +#define SCE_ERR_MS 3 +#define SCE_ERR_CMD 4 +#define SCE_ERR_BORLAND 5 +#define SCE_ERR_PERL 6 +#define SCE_ERR_NET 7 +#define SCE_ERR_LUA 8 +#define SCE_ERR_CTAG 9 +#define SCE_ERR_DIFF_CHANGED 10 +#define SCE_ERR_DIFF_ADDITION 11 +#define SCE_ERR_DIFF_DELETION 12 +#define SCE_ERR_DIFF_MESSAGE 13 +#define SCE_ERR_PHP 14 +#define SCE_BAT_DEFAULT 0 +#define SCE_BAT_COMMENT 1 +#define SCE_BAT_WORD 2 +#define SCE_BAT_LABEL 3 +#define SCE_BAT_HIDE 4 +#define SCE_BAT_COMMAND 5 +#define SCE_BAT_IDENTIFIER 6 +#define SCE_BAT_OPERATOR 7 +#define SCE_MAKE_DEFAULT 0 +#define SCE_MAKE_COMMENT 1 +#define SCE_MAKE_PREPROCESSOR 2 +#define SCE_MAKE_IDENTIFIER 3 +#define SCE_MAKE_OPERATOR 4 +#define SCE_MAKE_TARGET 5 +#define SCE_MAKE_IDEOL 9 +#define SCE_DIFF_DEFAULT 0 +#define SCE_DIFF_COMMENT 1 +#define SCE_DIFF_COMMAND 2 +#define SCE_DIFF_HEADER 3 +#define SCE_DIFF_POSITION 4 +#define SCE_DIFF_DELETED 5 +#define SCE_DIFF_ADDED 6 +#define SCE_CONF_DEFAULT 0 +#define SCE_CONF_COMMENT 1 +#define SCE_CONF_NUMBER 2 +#define SCE_CONF_IDENTIFIER 3 +#define SCE_CONF_EXTENSION 4 +#define SCE_CONF_PARAMETER 5 +#define SCE_CONF_STRING 6 +#define SCE_CONF_OPERATOR 7 +#define SCE_CONF_IP 8 +#define SCE_CONF_DIRECTIVE 9 +#define SCE_AVE_DEFAULT 0 +#define SCE_AVE_COMMENT 1 +#define SCE_AVE_NUMBER 2 +#define SCE_AVE_WORD 3 +#define SCE_AVE_KEYWORD 4 +#define SCE_AVE_STATEMENT 5 +#define SCE_AVE_STRING 6 +#define SCE_AVE_ENUM 7 +#define SCE_AVE_STRINGEOL 8 +#define SCE_AVE_IDENTIFIER 9 +#define SCE_AVE_OPERATOR 10 +#define SCE_ADA_DEFAULT 0 +#define SCE_ADA_WORD 1 +#define SCE_ADA_IDENTIFIER 2 +#define SCE_ADA_NUMBER 3 +#define SCE_ADA_DELIMITER 4 +#define SCE_ADA_CHARACTER 5 +#define SCE_ADA_CHARACTEREOL 6 +#define SCE_ADA_STRING 7 +#define SCE_ADA_STRINGEOL 8 +#define SCE_ADA_LABEL 9 +#define SCE_ADA_COMMENTLINE 10 +#define SCE_ADA_ILLEGAL 11 +#define SCE_BAAN_DEFAULT 0 +#define SCE_BAAN_COMMENT 1 +#define SCE_BAAN_COMMENTDOC 2 +#define SCE_BAAN_NUMBER 3 +#define SCE_BAAN_WORD 4 +#define SCE_BAAN_STRING 5 +#define SCE_BAAN_PREPROCESSOR 6 +#define SCE_BAAN_OPERATOR 7 +#define SCE_BAAN_IDENTIFIER 8 +#define SCE_BAAN_STRINGEOL 9 +#define SCE_BAAN_WORD2 10 +#define SCE_LISP_DEFAULT 0 +#define SCE_LISP_COMMENT 1 +#define SCE_LISP_NUMBER 2 +#define SCE_LISP_KEYWORD 3 +#define SCE_LISP_STRING 6 +#define SCE_LISP_STRINGEOL 8 +#define SCE_LISP_IDENTIFIER 9 +#define SCE_LISP_OPERATOR 10 +#define SCE_EIFFEL_DEFAULT 0 +#define SCE_EIFFEL_COMMENTLINE 1 +#define SCE_EIFFEL_NUMBER 2 +#define SCE_EIFFEL_WORD 3 +#define SCE_EIFFEL_STRING 4 +#define SCE_EIFFEL_CHARACTER 5 +#define SCE_EIFFEL_OPERATOR 6 +#define SCE_EIFFEL_IDENTIFIER 7 +#define SCE_EIFFEL_STRINGEOL 8 +#define SCE_NNCRONTAB_DEFAULT 0 +#define SCE_NNCRONTAB_COMMENT 1 +#define SCE_NNCRONTAB_TASK 2 +#define SCE_NNCRONTAB_SECTION 3 +#define SCE_NNCRONTAB_KEYWORD 4 +#define SCE_NNCRONTAB_MODIFIER 5 +#define SCE_NNCRONTAB_ASTERISK 6 +#define SCE_NNCRONTAB_NUMBER 7 +#define SCE_NNCRONTAB_STRING 8 +#define SCE_NNCRONTAB_ENVIRONMENT 9 +#define SCE_NNCRONTAB_IDENTIFIER 10 +#define SCE_MATLAB_DEFAULT 0 +#define SCE_MATLAB_COMMENT 1 +#define SCE_MATLAB_COMMAND 2 +#define SCE_MATLAB_NUMBER 3 +#define SCE_MATLAB_KEYWORD 4 +#define SCE_MATLAB_STRING 5 +#define SCE_MATLAB_OPERATOR 6 +#define SCE_MATLAB_IDENTIFIER 7 +#define SCE_SCRIPTOL_DEFAULT 0 +#define SCE_SCRIPTOL_COMMENT 1 +#define SCE_SCRIPTOL_COMMENTLINE 2 +#define SCE_SCRIPTOL_COMMENTDOC 3 +#define SCE_SCRIPTOL_NUMBER 4 +#define SCE_SCRIPTOL_WORD 5 +#define SCE_SCRIPTOL_STRING 6 +#define SCE_SCRIPTOL_CHARACTER 7 +#define SCE_SCRIPTOL_UUID 8 +#define SCE_SCRIPTOL_PREPROCESSOR 9 +#define SCE_SCRIPTOL_OPERATOR 10 +#define SCE_SCRIPTOL_IDENTIFIER 11 +#define SCE_SCRIPTOL_STRINGEOL 12 +#define SCE_SCRIPTOL_VERBATIM 13 +#define SCE_SCRIPTOL_REGEX 14 +#define SCE_SCRIPTOL_COMMENTLINEDOC 15 +#define SCE_SCRIPTOL_WORD2 16 +#define SCE_SCRIPTOL_COMMENTDOCKEYWORD 17 +#define SCE_SCRIPTOL_COMMENTDOCKEYWORDERROR 18 +#define SCE_SCRIPTOL_COMMENTBASIC 19 +#define SCE_ASM_DEFAULT 0 +#define SCE_ASM_COMMENT 1 +#define SCE_ASM_NUMBER 2 +#define SCE_ASM_STRING 3 +#define SCE_ASM_OPERATOR 4 +#define SCE_ASM_IDENTIFIER 5 +#define SCE_ASM_CPUINSTRUCTION 6 +#define SCE_ASM_MATHINSTRUCTION 7 +#define SCE_ASM_REGISTER 8 +#define SCE_ASM_DIRECTIVE 9 +#define SCE_ASM_DIRECTIVEOPERAND 10 +#define SCE_F_DEFAULT 0 +#define SCE_F_COMMENT 1 +#define SCE_F_NUMBER 2 +#define SCE_F_STRING1 3 +#define SCE_F_STRING2 4 +#define SCE_F_STRINGEOL 5 +#define SCE_F_OPERATOR 6 +#define SCE_F_IDENTIFIER 7 +#define SCE_F_WORD 8 +#define SCE_F_WORD2 9 +#define SCE_F_WORD3 10 +#define SCE_F_PREPROCESSOR 11 +#define SCE_F_OPERATOR2 12 +#define SCE_F_LABEL 13 +#define SCE_F_CONTINUATION 14 +//--Autogenerated -- end of section automatically generated from Scintilla.iface + +#endif diff --git a/vscript/languages/gm/src/gmd/include/Scintilla.h b/vscript/languages/gm/src/gmd/include/Scintilla.h new file mode 100644 index 00000000..3199aa20 --- /dev/null +++ b/vscript/languages/gm/src/gmd/include/Scintilla.h @@ -0,0 +1,640 @@ +// Scintilla source code edit control +/** @file Scintilla.h + ** Interface to the edit control. + **/ +// Copyright 1998-2002 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +// Most of this file is automatically generated from the Scintilla.iface interface definition +// file which contains any comments about the definitions. HFacer.py does the generation. + +#ifndef SCINTILLA_H +#define SCINTILLA_H + +#if PLAT_WIN +// Return false on failure: +bool Scintilla_RegisterClasses(void *hInstance); +bool Scintilla_ReleaseResources(); +#endif +int Scintilla_LinkLexers(); + +// Here should be placed typedefs for uptr_t, an unsigned integer type large enough to +// hold a pointer and sptr_t, a signed integer large enough to hold a pointer. +// May need to be changed for 64 bit platforms. +#if _MSC_VER >= 1300 +#include +#endif +#ifdef MAXULONG_PTR +typedef ULONG_PTR uptr_t; +typedef LONG_PTR sptr_t; +#else +typedef unsigned long uptr_t; +typedef long sptr_t; +#endif + +typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam); + +//++Autogenerated -- start of section automatically generated from Scintilla.iface +#define INVALID_POSITION -1 +#define SCI_START 2000 +#define SCI_OPTIONAL_START 3000 +#define SCI_LEXER_START 4000 +#define SCI_ADDTEXT 2001 +#define SCI_ADDSTYLEDTEXT 2002 +#define SCI_INSERTTEXT 2003 +#define SCI_CLEARALL 2004 +#define SCI_CLEARDOCUMENTSTYLE 2005 +#define SCI_GETLENGTH 2006 +#define SCI_GETCHARAT 2007 +#define SCI_GETCURRENTPOS 2008 +#define SCI_GETANCHOR 2009 +#define SCI_GETSTYLEAT 2010 +#define SCI_REDO 2011 +#define SCI_SETUNDOCOLLECTION 2012 +#define SCI_SELECTALL 2013 +#define SCI_SETSAVEPOINT 2014 +#define SCI_GETSTYLEDTEXT 2015 +#define SCI_CANREDO 2016 +#define SCI_MARKERLINEFROMHANDLE 2017 +#define SCI_MARKERDELETEHANDLE 2018 +#define SCI_GETUNDOCOLLECTION 2019 +#define SCWS_INVISIBLE 0 +#define SCWS_VISIBLEALWAYS 1 +#define SCWS_VISIBLEAFTERINDENT 2 +#define SCI_GETVIEWWS 2020 +#define SCI_SETVIEWWS 2021 +#define SCI_POSITIONFROMPOINT 2022 +#define SCI_POSITIONFROMPOINTCLOSE 2023 +#define SCI_GOTOLINE 2024 +#define SCI_GOTOPOS 2025 +#define SCI_SETANCHOR 2026 +#define SCI_GETCURLINE 2027 +#define SCI_GETENDSTYLED 2028 +#define SC_EOL_CRLF 0 +#define SC_EOL_CR 1 +#define SC_EOL_LF 2 +#define SCI_CONVERTEOLS 2029 +#define SCI_GETEOLMODE 2030 +#define SCI_SETEOLMODE 2031 +#define SCI_STARTSTYLING 2032 +#define SCI_SETSTYLING 2033 +#define SCI_GETBUFFEREDDRAW 2034 +#define SCI_SETBUFFEREDDRAW 2035 +#define SCI_SETTABWIDTH 2036 +#define SCI_GETTABWIDTH 2121 +#define SC_CP_UTF8 65001 +#define SCI_SETCODEPAGE 2037 +#define SCI_SETUSEPALETTE 2039 +#define MARKER_MAX 31 +#define SC_MARK_CIRCLE 0 +#define SC_MARK_ROUNDRECT 1 +#define SC_MARK_ARROW 2 +#define SC_MARK_SMALLRECT 3 +#define SC_MARK_SHORTARROW 4 +#define SC_MARK_EMPTY 5 +#define SC_MARK_ARROWDOWN 6 +#define SC_MARK_MINUS 7 +#define SC_MARK_PLUS 8 +#define SC_MARK_VLINE 9 +#define SC_MARK_LCORNER 10 +#define SC_MARK_TCORNER 11 +#define SC_MARK_BOXPLUS 12 +#define SC_MARK_BOXPLUSCONNECTED 13 +#define SC_MARK_BOXMINUS 14 +#define SC_MARK_BOXMINUSCONNECTED 15 +#define SC_MARK_LCORNERCURVE 16 +#define SC_MARK_TCORNERCURVE 17 +#define SC_MARK_CIRCLEPLUS 18 +#define SC_MARK_CIRCLEPLUSCONNECTED 19 +#define SC_MARK_CIRCLEMINUS 20 +#define SC_MARK_CIRCLEMINUSCONNECTED 21 +#define SC_MARK_BACKGROUND 22 +#define SC_MARK_DOTDOTDOT 23 +#define SC_MARK_ARROWS 24 +#define SC_MARK_PIXMAP 25 +#define SC_MARK_CHARACTER 10000 +#define SC_MARKNUM_FOLDEREND 25 +#define SC_MARKNUM_FOLDEROPENMID 26 +#define SC_MARKNUM_FOLDERMIDTAIL 27 +#define SC_MARKNUM_FOLDERTAIL 28 +#define SC_MARKNUM_FOLDERSUB 29 +#define SC_MARKNUM_FOLDER 30 +#define SC_MARKNUM_FOLDEROPEN 31 +#define SC_MASK_FOLDERS 0xFE000000 +#define SCI_MARKERDEFINE 2040 +#define SCI_MARKERSETFORE 2041 +#define SCI_MARKERSETBACK 2042 +#define SCI_MARKERADD 2043 +#define SCI_MARKERDELETE 2044 +#define SCI_MARKERDELETEALL 2045 +#define SCI_MARKERGET 2046 +#define SCI_MARKERNEXT 2047 +#define SCI_MARKERPREVIOUS 2048 +#define SCI_MARKERDEFINEPIXMAP 2049 +#define SC_MARGIN_SYMBOL 0 +#define SC_MARGIN_NUMBER 1 +#define SCI_SETMARGINTYPEN 2240 +#define SCI_GETMARGINTYPEN 2241 +#define SCI_SETMARGINWIDTHN 2242 +#define SCI_GETMARGINWIDTHN 2243 +#define SCI_SETMARGINMASKN 2244 +#define SCI_GETMARGINMASKN 2245 +#define SCI_SETMARGINSENSITIVEN 2246 +#define SCI_GETMARGINSENSITIVEN 2247 +#define STYLE_DEFAULT 32 +#define STYLE_LINENUMBER 33 +#define STYLE_BRACELIGHT 34 +#define STYLE_BRACEBAD 35 +#define STYLE_CONTROLCHAR 36 +#define STYLE_INDENTGUIDE 37 +#define STYLE_LASTPREDEFINED 39 +#define STYLE_MAX 127 +#define SC_CHARSET_ANSI 0 +#define SC_CHARSET_DEFAULT 1 +#define SC_CHARSET_BALTIC 186 +#define SC_CHARSET_CHINESEBIG5 136 +#define SC_CHARSET_EASTEUROPE 238 +#define SC_CHARSET_GB2312 134 +#define SC_CHARSET_GREEK 161 +#define SC_CHARSET_HANGUL 129 +#define SC_CHARSET_MAC 77 +#define SC_CHARSET_OEM 255 +#define SC_CHARSET_RUSSIAN 204 +#define SC_CHARSET_SHIFTJIS 128 +#define SC_CHARSET_SYMBOL 2 +#define SC_CHARSET_TURKISH 162 +#define SC_CHARSET_JOHAB 130 +#define SC_CHARSET_HEBREW 177 +#define SC_CHARSET_ARABIC 178 +#define SC_CHARSET_VIETNAMESE 163 +#define SC_CHARSET_THAI 222 +#define SCI_STYLECLEARALL 2050 +#define SCI_STYLESETFORE 2051 +#define SCI_STYLESETBACK 2052 +#define SCI_STYLESETBOLD 2053 +#define SCI_STYLESETITALIC 2054 +#define SCI_STYLESETSIZE 2055 +#define SCI_STYLESETFONT 2056 +#define SCI_STYLESETEOLFILLED 2057 +#define SCI_STYLERESETDEFAULT 2058 +#define SCI_STYLESETUNDERLINE 2059 +#define SC_CASE_MIXED 0 +#define SC_CASE_UPPER 1 +#define SC_CASE_LOWER 2 +#define SCI_STYLESETCASE 2060 +#define SCI_STYLESETCHARACTERSET 2066 +#define SCI_SETSELFORE 2067 +#define SCI_SETSELBACK 2068 +#define SCI_SETCARETFORE 2069 +#define SCI_ASSIGNCMDKEY 2070 +#define SCI_CLEARCMDKEY 2071 +#define SCI_CLEARALLCMDKEYS 2072 +#define SCI_SETSTYLINGEX 2073 +#define SCI_STYLESETVISIBLE 2074 +#define SCI_GETCARETPERIOD 2075 +#define SCI_SETCARETPERIOD 2076 +#define SCI_SETWORDCHARS 2077 +#define SCI_BEGINUNDOACTION 2078 +#define SCI_ENDUNDOACTION 2079 +#define INDIC_MAX 7 +#define INDIC_PLAIN 0 +#define INDIC_SQUIGGLE 1 +#define INDIC_TT 2 +#define INDIC_DIAGONAL 3 +#define INDIC_STRIKE 4 +#define INDIC0_MASK 0x20 +#define INDIC1_MASK 0x40 +#define INDIC2_MASK 0x80 +#define INDICS_MASK 0xE0 +#define SCI_INDICSETSTYLE 2080 +#define SCI_INDICGETSTYLE 2081 +#define SCI_INDICSETFORE 2082 +#define SCI_INDICGETFORE 2083 +#define SCI_SETWHITESPACEFORE 2084 +#define SCI_SETWHITESPACEBACK 2085 +#define SCI_SETSTYLEBITS 2090 +#define SCI_GETSTYLEBITS 2091 +#define SCI_SETLINESTATE 2092 +#define SCI_GETLINESTATE 2093 +#define SCI_GETMAXLINESTATE 2094 +#define SCI_GETCARETLINEVISIBLE 2095 +#define SCI_SETCARETLINEVISIBLE 2096 +#define SCI_GETCARETLINEBACK 2097 +#define SCI_SETCARETLINEBACK 2098 +#define SCI_STYLESETCHANGEABLE 2099 +#define SCI_AUTOCSHOW 2100 +#define SCI_AUTOCCANCEL 2101 +#define SCI_AUTOCACTIVE 2102 +#define SCI_AUTOCPOSSTART 2103 +#define SCI_AUTOCCOMPLETE 2104 +#define SCI_AUTOCSTOPS 2105 +#define SCI_AUTOCSETSEPARATOR 2106 +#define SCI_AUTOCGETSEPARATOR 2107 +#define SCI_AUTOCSELECT 2108 +#define SCI_AUTOCSETCANCELATSTART 2110 +#define SCI_AUTOCGETCANCELATSTART 2111 +#define SCI_AUTOCSETFILLUPS 2112 +#define SCI_AUTOCSETCHOOSESINGLE 2113 +#define SCI_AUTOCGETCHOOSESINGLE 2114 +#define SCI_AUTOCSETIGNORECASE 2115 +#define SCI_AUTOCGETIGNORECASE 2116 +#define SCI_USERLISTSHOW 2117 +#define SCI_AUTOCSETAUTOHIDE 2118 +#define SCI_AUTOCGETAUTOHIDE 2119 +#define SCI_AUTOCSETDROPRESTOFWORD 2270 +#define SCI_AUTOCGETDROPRESTOFWORD 2271 +#define SCI_SETINDENT 2122 +#define SCI_GETINDENT 2123 +#define SCI_SETUSETABS 2124 +#define SCI_GETUSETABS 2125 +#define SCI_SETLINEINDENTATION 2126 +#define SCI_GETLINEINDENTATION 2127 +#define SCI_GETLINEINDENTPOSITION 2128 +#define SCI_GETCOLUMN 2129 +#define SCI_SETHSCROLLBAR 2130 +#define SCI_GETHSCROLLBAR 2131 +#define SCI_SETINDENTATIONGUIDES 2132 +#define SCI_GETINDENTATIONGUIDES 2133 +#define SCI_SETHIGHLIGHTGUIDE 2134 +#define SCI_GETHIGHLIGHTGUIDE 2135 +#define SCI_GETLINEENDPOSITION 2136 +#define SCI_GETCODEPAGE 2137 +#define SCI_GETCARETFORE 2138 +#define SCI_GETUSEPALETTE 2139 +#define SCI_GETREADONLY 2140 +#define SCI_SETCURRENTPOS 2141 +#define SCI_SETSELECTIONSTART 2142 +#define SCI_GETSELECTIONSTART 2143 +#define SCI_SETSELECTIONEND 2144 +#define SCI_GETSELECTIONEND 2145 +#define SCI_SETPRINTMAGNIFICATION 2146 +#define SCI_GETPRINTMAGNIFICATION 2147 +#define SC_PRINT_NORMAL 0 +#define SC_PRINT_INVERTLIGHT 1 +#define SC_PRINT_BLACKONWHITE 2 +#define SC_PRINT_COLOURONWHITE 3 +#define SC_PRINT_COLOURONWHITEDEFAULTBG 4 +#define SCI_SETPRINTCOLOURMODE 2148 +#define SCI_GETPRINTCOLOURMODE 2149 +#define SCFIND_WHOLEWORD 2 +#define SCFIND_MATCHCASE 4 +#define SCFIND_WORDSTART 0x00100000 +#define SCFIND_REGEXP 0x00200000 +#define SCI_FINDTEXT 2150 +#define SCI_FORMATRANGE 2151 +#define SCI_GETFIRSTVISIBLELINE 2152 +#define SCI_GETLINE 2153 +#define SCI_GETLINECOUNT 2154 +#define SCI_SETMARGINLEFT 2155 +#define SCI_GETMARGINLEFT 2156 +#define SCI_SETMARGINRIGHT 2157 +#define SCI_GETMARGINRIGHT 2158 +#define SCI_GETMODIFY 2159 +#define SCI_SETSEL 2160 +#define SCI_GETSELTEXT 2161 +#define SCI_GETTEXTRANGE 2162 +#define SCI_HIDESELECTION 2163 +#define SCI_POINTXFROMPOSITION 2164 +#define SCI_POINTYFROMPOSITION 2165 +#define SCI_LINEFROMPOSITION 2166 +#define SCI_POSITIONFROMLINE 2167 +#define SCI_LINESCROLL 2168 +#define SCI_SCROLLCARET 2169 +#define SCI_REPLACESEL 2170 +#define SCI_SETREADONLY 2171 +#define SCI_NULL 2172 +#define SCI_CANPASTE 2173 +#define SCI_CANUNDO 2174 +#define SCI_EMPTYUNDOBUFFER 2175 +#define SCI_UNDO 2176 +#define SCI_CUT 2177 +#define SCI_COPY 2178 +#define SCI_PASTE 2179 +#define SCI_CLEAR 2180 +#define SCI_SETTEXT 2181 +#define SCI_GETTEXT 2182 +#define SCI_GETTEXTLENGTH 2183 +#define SCI_GETDIRECTFUNCTION 2184 +#define SCI_GETDIRECTPOINTER 2185 +#define SCI_SETOVERTYPE 2186 +#define SCI_GETOVERTYPE 2187 +#define SCI_SETCARETWIDTH 2188 +#define SCI_GETCARETWIDTH 2189 +#define SCI_SETTARGETSTART 2190 +#define SCI_GETTARGETSTART 2191 +#define SCI_SETTARGETEND 2192 +#define SCI_GETTARGETEND 2193 +#define SCI_REPLACETARGET 2194 +#define SCI_REPLACETARGETRE 2195 +#define SCI_SEARCHINTARGET 2197 +#define SCI_SETSEARCHFLAGS 2198 +#define SCI_GETSEARCHFLAGS 2199 +#define SCI_CALLTIPSHOW 2200 +#define SCI_CALLTIPCANCEL 2201 +#define SCI_CALLTIPACTIVE 2202 +#define SCI_CALLTIPPOSSTART 2203 +#define SCI_CALLTIPSETHLT 2204 +#define SCI_CALLTIPSETBACK 2205 +#define SCI_VISIBLEFROMDOCLINE 2220 +#define SCI_DOCLINEFROMVISIBLE 2221 +#define SC_FOLDLEVELBASE 0x400 +#define SC_FOLDLEVELWHITEFLAG 0x1000 +#define SC_FOLDLEVELHEADERFLAG 0x2000 +#define SC_FOLDLEVELNUMBERMASK 0x0FFF +#define SCI_SETFOLDLEVEL 2222 +#define SCI_GETFOLDLEVEL 2223 +#define SCI_GETLASTCHILD 2224 +#define SCI_GETFOLDPARENT 2225 +#define SCI_SHOWLINES 2226 +#define SCI_HIDELINES 2227 +#define SCI_GETLINEVISIBLE 2228 +#define SCI_SETFOLDEXPANDED 2229 +#define SCI_GETFOLDEXPANDED 2230 +#define SCI_TOGGLEFOLD 2231 +#define SCI_ENSUREVISIBLE 2232 +#define SCI_SETFOLDFLAGS 2233 +#define SCI_ENSUREVISIBLEENFORCEPOLICY 2234 +#define SCI_SETTABINDENTS 2260 +#define SCI_GETTABINDENTS 2261 +#define SCI_SETBACKSPACEUNINDENTS 2262 +#define SCI_GETBACKSPACEUNINDENTS 2263 +#define SC_TIME_FOREVER 10000000 +#define SCI_SETMOUSEDWELLTIME 2264 +#define SCI_GETMOUSEDWELLTIME 2265 +#define SCI_WORDSTARTPOSITION 2266 +#define SCI_WORDENDPOSITION 2267 +#define SC_WRAP_NONE 0 +#define SC_WRAP_WORD 1 +#define SCI_SETWRAPMODE 2268 +#define SCI_GETWRAPMODE 2269 +#define SC_CACHE_NONE 0 +#define SC_CACHE_CARET 1 +#define SC_CACHE_PAGE 2 +#define SC_CACHE_DOCUMENT 3 +#define SCI_SETLAYOUTCACHE 2272 +#define SCI_GETLAYOUTCACHE 2273 +#define SCI_SETSCROLLWIDTH 2274 +#define SCI_GETSCROLLWIDTH 2275 +#define SCI_TEXTWIDTH 2276 +#define SCI_SETENDATLASTLINE 2277 +#define SCI_GETENDATLASTLINE 2278 +#define SCI_TEXTHEIGHT 2279 +#define SCI_SETVSCROLLBAR 2280 +#define SCI_GETVSCROLLBAR 2281 +#define SCI_APPENDTEXT 2282 +#define SCI_LINEDOWN 2300 +#define SCI_LINEDOWNEXTEND 2301 +#define SCI_LINEUP 2302 +#define SCI_LINEUPEXTEND 2303 +#define SCI_CHARLEFT 2304 +#define SCI_CHARLEFTEXTEND 2305 +#define SCI_CHARRIGHT 2306 +#define SCI_CHARRIGHTEXTEND 2307 +#define SCI_WORDLEFT 2308 +#define SCI_WORDLEFTEXTEND 2309 +#define SCI_WORDRIGHT 2310 +#define SCI_WORDRIGHTEXTEND 2311 +#define SCI_HOME 2312 +#define SCI_HOMEEXTEND 2313 +#define SCI_LINEEND 2314 +#define SCI_LINEENDEXTEND 2315 +#define SCI_DOCUMENTSTART 2316 +#define SCI_DOCUMENTSTARTEXTEND 2317 +#define SCI_DOCUMENTEND 2318 +#define SCI_DOCUMENTENDEXTEND 2319 +#define SCI_PAGEUP 2320 +#define SCI_PAGEUPEXTEND 2321 +#define SCI_PAGEDOWN 2322 +#define SCI_PAGEDOWNEXTEND 2323 +#define SCI_EDITTOGGLEOVERTYPE 2324 +#define SCI_CANCEL 2325 +#define SCI_DELETEBACK 2326 +#define SCI_TAB 2327 +#define SCI_BACKTAB 2328 +#define SCI_NEWLINE 2329 +#define SCI_FORMFEED 2330 +#define SCI_VCHOME 2331 +#define SCI_VCHOMEEXTEND 2332 +#define SCI_ZOOMIN 2333 +#define SCI_ZOOMOUT 2334 +#define SCI_DELWORDLEFT 2335 +#define SCI_DELWORDRIGHT 2336 +#define SCI_LINECUT 2337 +#define SCI_LINEDELETE 2338 +#define SCI_LINETRANSPOSE 2339 +#define SCI_LOWERCASE 2340 +#define SCI_UPPERCASE 2341 +#define SCI_LINESCROLLDOWN 2342 +#define SCI_LINESCROLLUP 2343 +#define SCI_DELETEBACKNOTLINE 2344 +#define SCI_HOMEDISPLAY 2345 +#define SCI_HOMEDISPLAYEXTEND 2346 +#define SCI_LINEENDDISPLAY 2347 +#define SCI_LINEENDDISPLAYEXTEND 2348 +#define SCI_MOVECARETINSIDEVIEW 2401 +#define SCI_LINELENGTH 2350 +#define SCI_BRACEHIGHLIGHT 2351 +#define SCI_BRACEBADLIGHT 2352 +#define SCI_BRACEMATCH 2353 +#define SCI_GETVIEWEOL 2355 +#define SCI_SETVIEWEOL 2356 +#define SCI_GETDOCPOINTER 2357 +#define SCI_SETDOCPOINTER 2358 +#define SCI_SETMODEVENTMASK 2359 +#define EDGE_NONE 0 +#define EDGE_LINE 1 +#define EDGE_BACKGROUND 2 +#define SCI_GETEDGECOLUMN 2360 +#define SCI_SETEDGECOLUMN 2361 +#define SCI_GETEDGEMODE 2362 +#define SCI_SETEDGEMODE 2363 +#define SCI_GETEDGECOLOUR 2364 +#define SCI_SETEDGECOLOUR 2365 +#define SCI_SEARCHANCHOR 2366 +#define SCI_SEARCHNEXT 2367 +#define SCI_SEARCHPREV 2368 +#define SCI_LINESONSCREEN 2370 +#define SCI_USEPOPUP 2371 +#define SCI_SELECTIONISRECTANGLE 2372 +#define SCI_SETZOOM 2373 +#define SCI_GETZOOM 2374 +#define SCI_CREATEDOCUMENT 2375 +#define SCI_ADDREFDOCUMENT 2376 +#define SCI_RELEASEDOCUMENT 2377 +#define SCI_GETMODEVENTMASK 2378 +#define SCI_SETFOCUS 2380 +#define SCI_GETFOCUS 2381 +#define SCI_SETSTATUS 2382 +#define SCI_GETSTATUS 2383 +#define SCI_SETMOUSEDOWNCAPTURES 2384 +#define SCI_GETMOUSEDOWNCAPTURES 2385 +#define SC_CURSORNORMAL -1 +#define SC_CURSORWAIT 4 +#define SCI_SETCURSOR 2386 +#define SCI_GETCURSOR 2387 +#define SCI_SETCONTROLCHARSYMBOL 2388 +#define SCI_GETCONTROLCHARSYMBOL 2389 +#define SCI_WORDPARTLEFT 2390 +#define SCI_WORDPARTLEFTEXTEND 2391 +#define SCI_WORDPARTRIGHT 2392 +#define SCI_WORDPARTRIGHTEXTEND 2393 +#define VISIBLE_SLOP 0x01 +#define VISIBLE_STRICT 0x04 +#define SCI_SETVISIBLEPOLICY 2394 +#define SCI_DELLINELEFT 2395 +#define SCI_DELLINERIGHT 2396 +#define SCI_SETXOFFSET 2397 +#define SCI_GETXOFFSET 2398 +#define SCI_CHOOSECARETX 2399 +#define SCI_GRABFOCUS 2400 +#define CARET_SLOP 0x01 +#define CARET_STRICT 0x04 +#define CARET_JUMPS 0x10 +#define CARET_EVEN 0x08 +#define SCI_SETXCARETPOLICY 2402 +#define SCI_SETYCARETPOLICY 2403 +#define SCI_STARTRECORD 3001 +#define SCI_STOPRECORD 3002 +#define SCI_SETLEXER 4001 +#define SCI_GETLEXER 4002 +#define SCI_COLOURISE 4003 +#define SCI_SETPROPERTY 4004 +#define SCI_SETKEYWORDS 4005 +#define SCI_SETLEXERLANGUAGE 4006 +#define SC_MOD_INSERTTEXT 0x1 +#define SC_MOD_DELETETEXT 0x2 +#define SC_MOD_CHANGESTYLE 0x4 +#define SC_MOD_CHANGEFOLD 0x8 +#define SC_PERFORMED_USER 0x10 +#define SC_PERFORMED_UNDO 0x20 +#define SC_PERFORMED_REDO 0x40 +#define SC_LASTSTEPINUNDOREDO 0x100 +#define SC_MOD_CHANGEMARKER 0x200 +#define SC_MOD_BEFOREINSERT 0x400 +#define SC_MOD_BEFOREDELETE 0x800 +#define SC_MODEVENTMASKALL 0xF77 +#define SCEN_CHANGE 768 +#define SCEN_SETFOCUS 512 +#define SCEN_KILLFOCUS 256 +#define SCK_DOWN 300 +#define SCK_UP 301 +#define SCK_LEFT 302 +#define SCK_RIGHT 303 +#define SCK_HOME 304 +#define SCK_END 305 +#define SCK_PRIOR 306 +#define SCK_NEXT 307 +#define SCK_DELETE 308 +#define SCK_INSERT 309 +#define SCK_ESCAPE 7 +#define SCK_BACK 8 +#define SCK_TAB 9 +#define SCK_RETURN 13 +#define SCK_ADD 310 +#define SCK_SUBTRACT 311 +#define SCK_DIVIDE 312 +#define SCMOD_SHIFT 1 +#define SCMOD_CTRL 2 +#define SCMOD_ALT 4 +#define SCN_STYLENEEDED 2000 +#define SCN_CHARADDED 2001 +#define SCN_SAVEPOINTREACHED 2002 +#define SCN_SAVEPOINTLEFT 2003 +#define SCN_MODIFYATTEMPTRO 2004 +#define SCN_KEY 2005 +#define SCN_DOUBLECLICK 2006 +#define SCN_UPDATEUI 2007 +#define SCN_MODIFIED 2008 +#define SCN_MACRORECORD 2009 +#define SCN_MARGINCLICK 2010 +#define SCN_NEEDSHOWN 2011 +#define SCN_PAINTED 2013 +#define SCN_USERLISTSELECTION 2014 +#define SCN_URIDROPPED 2015 +#define SCN_DWELLSTART 2016 +#define SCN_DWELLEND 2017 +#define SCN_ZOOM 2018 +//--Autogenerated -- end of section automatically generated from Scintilla.iface + +// These structures are defined to be exactly the same shape as the Win32 +// CHARRANGE, TEXTRANGE, FINDTEXTEX, FORMATRANGE, and NMHDR structs. +// So older code that treats Scintilla as a RichEdit will work. + +struct CharacterRange { + long cpMin; + long cpMax; +}; + +struct TextRange { + struct CharacterRange chrg; + char *lpstrText; +}; + +struct TextToFind { + struct CharacterRange chrg; + char *lpstrText; + struct CharacterRange chrgText; +}; + +#ifdef PLATFORM_H + +// This structure is used in printing and requires some of the graphics types +// from Platform.h. Not needed by most client code. + +struct RangeToFormat { + SurfaceID hdc; + SurfaceID hdcTarget; + PRectangle rc; + PRectangle rcPage; + CharacterRange chrg; +}; + +#endif + +struct NotifyHeader { + // hwndFrom is really an environment specifc window handle or pointer + // but most clients of Scintilla.h do not have this type visible. + //WindowID hwndFrom; + void *hwndFrom; + unsigned int idFrom; + unsigned int code; +}; + +struct SCNotification { + struct NotifyHeader nmhdr; + int position; // SCN_STYLENEEDED, SCN_MODIFIED, SCN_DWELLSTART, SCN_DWELLEND + int ch; // SCN_CHARADDED, SCN_KEY + int modifiers; // SCN_KEY + int modificationType; // SCN_MODIFIED + const char *text; // SCN_MODIFIED + int length; // SCN_MODIFIED + int linesAdded; // SCN_MODIFIED + int message; // SCN_MACRORECORD + uptr_t wParam; // SCN_MACRORECORD + sptr_t lParam; // SCN_MACRORECORD + int line; // SCN_MODIFIED + int foldLevelNow; // SCN_MODIFIED + int foldLevelPrev; // SCN_MODIFIED + int margin; // SCN_MARGINCLICK + int listType; // SCN_USERLISTSELECTION + int x; // SCN_DWELLSTART, SCN_DWELLEND + int y; // SCN_DWELLSTART, SCN_DWELLEND +}; + +// Deprecation section listing all API features that are deprecated and will +// will be removed completely in a future version. +// To enable these features define INCLUDE_DEPRECATED_FEATURES + +#ifdef INCLUDE_DEPRECATED_FEATURES + +#define SCI_SETCARETPOLICY 2369 +#define CARET_CENTER 0x02 +#define CARET_XEVEN 0x08 +#define CARET_XJUMPS 0x10 + +#define SCN_POSCHANGED 2012 +#define SCN_CHECKBRACE 2007 + +#endif + +#endif diff --git a/vscript/languages/gm/src/gmd/include/Scintilla.iface b/vscript/languages/gm/src/gmd/include/Scintilla.iface new file mode 100644 index 00000000..cd1bacb7 --- /dev/null +++ b/vscript/languages/gm/src/gmd/include/Scintilla.iface @@ -0,0 +1,1946 @@ +## First line may be used for shbang + +## This file defines the interface to Scintilla + +## Copyright 2000-2002 by Neil Hodgson +## The License.txt file describes the conditions under which this software may be distributed. + +## A line starting with ## is a pure comment and should be stripped by readers. +## A line starting with #! is for future shbang use +## A line starting with # followed by a space is a documentation comment and refers +## to the next feature definition. + +## Each feature is defined by a line starting with fun, get, set, val or evt. +## cat -> start a category +## fun -> a function +## get -> a property get function +## set -> a property set function +## val -> definition of a constant +## evt -> an event +## enu -> associate an enumeration with a set of vals with a prefix +## lex -> associate a lexer with the lexical classes it produces +## +## All other feature names should be ignored. They may be defined in the future. +## A property may have a set function, a get function or both. Each will have +## "Get" or "Set" in their names and the corresponding name will have the obvious switch. +## A property may be subscripted, in which case the first parameter is the subscript. +## fun, get, and set features have a strict syntax: +## [=,) +## param is [=] +## Additional white space is allowed between elements. +## The syntax for evt is [=[,]*]) +## Feature names that contain an underscore are defined by Windows, so in these +## cases, using the Windows definition is preferred where available. +## The feature numbers are stable so features will not be renumbered. +## Features may be removed but they will go through a period of deprecation +## before removal which is signalled by moving them into the Deprecated category. +## +## enu has the syntax enu=[]* where all the val +## features in this file starting with a given are considered part of the +## enumeration. +## +## lex has the syntax lex=[]* +## where name is a reasonably capitalised (Python, XML) identifier or UI name, +## lexerVal is the val used to specify the lexer, and the list of prefixes is similar +## to enu. The name may not be the same as that used within the lexer so the lexerVal +## should be used to tie these entities together. + +## Types: +## void +## int +## bool -> integer, 1=true, 0=false +## position -> integer position in a document +## colour -> colour integer containing red, green and blue bytes. +## string -> pointer to const character +## stringresult -> pointer to character +## cells -> pointer to array of cells, each cell containing a style byte and character byte +## textrange -> range of a min and a max position with an output string +## findtext -> searchrange, text -> foundposition +## keymod -> integer containing key in low half and modifiers in high half +## formatrange +## Types no longer used: +## findtextex -> searchrange +## charrange -> range of a min and a max position +## charrangeresult -> like charrange, but output param +## countedstring +## point -> x,y +## pointresult -> like point, but output param +## rectangle -> left,top,right,bottom +## Client code should ignore definitions containing types it does not understand, except +## for possibly #defining the constants + +## String arguments may contain NUL ('\0') characters where the calls provide a length +## argument and retrieve NUL characters. All retrieved strings except for those retrieved +## by GetLine also have a NUL appended but client code should calculate the size that +## will be returned rather than relying upon the NUL whenever possible. Allow for the +## extra NUL character when allocating buffers. + +cat Basics + +################################################ +## For Scintilla.h +val INVALID_POSITION=-1 +# Define start of Scintilla messages to be greater than all edit (EM_*) messages +# as many EM_ messages can be used although that use is deprecated. +val SCI_START=2000 +val SCI_OPTIONAL_START=3000 +val SCI_LEXER_START=4000 + +# Add text to the document. +fun void AddText=2001(int length, string text) + +# Add array of cells to document. +fun void AddStyledText=2002(int length, cells c) + +# Insert string at a position. +fun void InsertText=2003(position pos, string text) + +# Delete all text in the document. +fun void ClearAll=2004(,) + +# Set all style bytes to 0, remove all folding information. +fun void ClearDocumentStyle=2005(,) + +# The number of characters in the document. +get int GetLength=2006(,) + +# Returns the character byte at the position. +get int GetCharAt=2007(position pos,) + +# Returns the position of the caret. +get position GetCurrentPos=2008(,) + +# Returns the position of the opposite end of the selection to the caret. +get position GetAnchor=2009(,) + +# Returns the style byte at the position. +get int GetStyleAt=2010(position pos,) + +# Redoes the next action on the undo history. +fun void Redo=2011(,) + +# Choose between collecting actions into the undo +# history and discarding them. +set void SetUndoCollection=2012(bool collectUndo,) + +# Select all the text in the document. +fun void SelectAll=2013(,) + +# Remember the current position in the undo history as the position +# at which the document was saved. +fun void SetSavePoint=2014(,) + +# Retrieve a buffer of cells. +# Returns the number of bytes in the buffer not including terminating nulls. +fun int GetStyledText=2015(, textrange tr) + +# Are there any redoable actions in the undo history? +fun bool CanRedo=2016(,) + +# Retrieve the line number at which a particular marker is located. +fun int MarkerLineFromHandle=2017(int handle,) + +# Delete a marker. +fun void MarkerDeleteHandle=2018(int handle,) + +# Is undo history being collected? +get bool GetUndoCollection=2019(,) + +enu WhiteSpace=SCWS_ +val SCWS_INVISIBLE=0 +val SCWS_VISIBLEALWAYS=1 +val SCWS_VISIBLEAFTERINDENT=2 + +# Are white space characters currently visible? +# Returns one of SCWS_* constants. +get int GetViewWS=2020(,) + +# Make white space characters invisible, always visible or visible outside indentation. +set void SetViewWS=2021(int viewWS,) + +# Find the position from a point within the window. +fun int PositionFromPoint=2022(int x, int y) + +# Find the position from a point within the window but return +# INVALID_POSITION if not close to text. +fun int PositionFromPointClose=2023(int x, int y) + +# Set caret to start of a line and ensure it is visible. +fun void GotoLine=2024(int line,) + +# Set caret to a position and ensure it is visible. +fun void GotoPos=2025(position pos,) + +# Set the selection anchor to a position. The anchor is the opposite +# end of the selection from the caret. +set void SetAnchor=2026(position posAnchor,) + +# Retrieve the text of the line containing the caret. +# Returns the index of the caret on the line. +fun int GetCurLine=2027(int length, stringresult text) + +# Retrieve the position of the last correctly styled character. +get position GetEndStyled=2028(,) + +enu EndOfLine=SC_EOL_ +val SC_EOL_CRLF=0 +val SC_EOL_CR=1 +val SC_EOL_LF=2 + +# Convert all line endings in the document to one mode. +fun void ConvertEOLs=2029(int eolMode,) + +# Retrieve the current end of line mode - one of CRLF, CR, or LF. +get int GetEOLMode=2030(,) + +# Set the current end of line mode. +set void SetEOLMode=2031(int eolMode,) + +# Set the current styling position to pos and the styling mask to mask. +# The styling mask can be used to protect some bits in each styling byte from modification. +fun void StartStyling=2032(position pos, int mask) + +# Change style from current styling position for length characters to a style +# and move the current styling position to after this newly styled segment. +fun void SetStyling=2033(int length, int style) + +# Is drawing done first into a buffer or direct to the screen? +get bool GetBufferedDraw=2034(,) + +# If drawing is buffered then each line of text is drawn into a bitmap buffer +# before drawing it to the screen to avoid flicker. +set void SetBufferedDraw=2035(bool buffered,) + +# Change the visible size of a tab to be a multiple of the width of a space character. +set void SetTabWidth=2036(int tabWidth,) + +# Retrieve the visible size of a tab. +get int GetTabWidth=2121(,) + +# The SC_CP_UTF8 value can be used to enter Unicode mode. +# This is the same value as CP_UTF8 in Windows +val SC_CP_UTF8=65001 + +# Set the code page used to interpret the bytes of the document as characters. +# The SC_CP_UTF8 value can be used to enter Unicode mode. +set void SetCodePage=2037(int codePage,) + +# In palette mode, Scintilla uses the environment's palette calls to display +# more colours. This may lead to ugly displays. +set void SetUsePalette=2039(bool usePalette,) + +enu MarkerSymbol=SC_MARK_ +val MARKER_MAX=31 +val SC_MARK_CIRCLE=0 +val SC_MARK_ROUNDRECT=1 +val SC_MARK_ARROW=2 +val SC_MARK_SMALLRECT=3 +val SC_MARK_SHORTARROW=4 +val SC_MARK_EMPTY=5 +val SC_MARK_ARROWDOWN=6 +val SC_MARK_MINUS=7 +val SC_MARK_PLUS=8 + +# Shapes used for outlining column. +val SC_MARK_VLINE=9 +val SC_MARK_LCORNER=10 +val SC_MARK_TCORNER=11 +val SC_MARK_BOXPLUS=12 +val SC_MARK_BOXPLUSCONNECTED=13 +val SC_MARK_BOXMINUS=14 +val SC_MARK_BOXMINUSCONNECTED=15 +val SC_MARK_LCORNERCURVE=16 +val SC_MARK_TCORNERCURVE=17 +val SC_MARK_CIRCLEPLUS=18 +val SC_MARK_CIRCLEPLUSCONNECTED=19 +val SC_MARK_CIRCLEMINUS=20 +val SC_MARK_CIRCLEMINUSCONNECTED=21 + +# Invisible mark that only sets the line background color. +val SC_MARK_BACKGROUND=22 +val SC_MARK_DOTDOTDOT=23 +val SC_MARK_ARROWS=24 +val SC_MARK_PIXMAP=25 + +val SC_MARK_CHARACTER=10000 + +enu MarkerOutline=SC_MARKNUM_ +# Markers used for outlining column. +val SC_MARKNUM_FOLDEREND=25 +val SC_MARKNUM_FOLDEROPENMID=26 +val SC_MARKNUM_FOLDERMIDTAIL=27 +val SC_MARKNUM_FOLDERTAIL=28 +val SC_MARKNUM_FOLDERSUB=29 +val SC_MARKNUM_FOLDER=30 +val SC_MARKNUM_FOLDEROPEN=31 + +val SC_MASK_FOLDERS=0xFE000000 + +# Set the symbol used for a particular marker number. +fun void MarkerDefine=2040(int markerNumber, int markerSymbol) + +# Set the foreground colour used for a particular marker number. +fun void MarkerSetFore=2041(int markerNumber, colour fore) + +# Set the background colour used for a particular marker number. +fun void MarkerSetBack=2042(int markerNumber, colour back) + +# Add a marker to a line, returning an ID which can be used to find or delete the marker. +fun int MarkerAdd=2043(int line, int markerNumber) + +# Delete a marker from a line. +fun void MarkerDelete=2044(int line, int markerNumber) + +# Delete all markers with a particular number from all lines. +fun void MarkerDeleteAll=2045(int markerNumber,) + +# Get a bit mask of all the markers set on a line. +fun int MarkerGet=2046(int line,) + +# Find the next line after lineStart that includes a marker in mask. +fun int MarkerNext=2047(int lineStart, int markerMask) + +# Find the previous line before lineStart that includes a marker in mask. +fun int MarkerPrevious=2048(int lineStart, int markerMask) + +# Define a marker from a pixmap. +fun void MarkerDefinePixmap=2049(int markerNumber, string pixmap) + +enu MarginType=SC_MARGIN_ +val SC_MARGIN_SYMBOL=0 +val SC_MARGIN_NUMBER=1 + +# Set a margin to be either numeric or symbolic. +set void SetMarginTypeN=2240(int margin, int marginType) + +# Retrieve the type of a margin. +get int GetMarginTypeN=2241(int margin,) + +# Set the width of a margin to a width expressed in pixels. +set void SetMarginWidthN=2242(int margin, int pixelWidth) + +# Retrieve the width of a margin in pixels. +get int GetMarginWidthN=2243(int margin,) + +# Set a mask that determines which markers are displayed in a margin. +set void SetMarginMaskN=2244(int margin, int mask) + +# Retrieve the marker mask of a margin. +get int GetMarginMaskN=2245(int margin,) + +# Make a margin sensitive or insensitive to mouse clicks. +set void SetMarginSensitiveN=2246(int margin, bool sensitive) + +# Retrieve the mouse click sensitivity of a margin. +get bool GetMarginSensitiveN=2247(int margin,) + +# Styles in range 32..37 are predefined for parts of the UI and are not used as normal styles. +# Styles 38 and 39 are for future use. +enu StylesCommon=STYLE_ +val STYLE_DEFAULT=32 +val STYLE_LINENUMBER=33 +val STYLE_BRACELIGHT=34 +val STYLE_BRACEBAD=35 +val STYLE_CONTROLCHAR=36 +val STYLE_INDENTGUIDE=37 +val STYLE_LASTPREDEFINED=39 +val STYLE_MAX=127 + +# Character set identifiers are used in StyleSetCharacterSet. +# The values are the same as the Windows *_CHARSET values. +enu CharacterSet=SC_CHARSET_ +val SC_CHARSET_ANSI=0 +val SC_CHARSET_DEFAULT=1 +val SC_CHARSET_BALTIC=186 +val SC_CHARSET_CHINESEBIG5=136 +val SC_CHARSET_EASTEUROPE=238 +val SC_CHARSET_GB2312=134 +val SC_CHARSET_GREEK=161 +val SC_CHARSET_HANGUL=129 +val SC_CHARSET_MAC=77 +val SC_CHARSET_OEM=255 +val SC_CHARSET_RUSSIAN=204 +val SC_CHARSET_SHIFTJIS=128 +val SC_CHARSET_SYMBOL=2 +val SC_CHARSET_TURKISH=162 +val SC_CHARSET_JOHAB=130 +val SC_CHARSET_HEBREW=177 +val SC_CHARSET_ARABIC=178 +val SC_CHARSET_VIETNAMESE=163 +val SC_CHARSET_THAI=222 + +# Clear all the styles and make equivalent to the global default style. +set void StyleClearAll=2050(,) + +# Set the foreground colour of a style. +set void StyleSetFore=2051(int style, colour fore) + +# Set the background colour of a style. +set void StyleSetBack=2052(int style, colour back) + +# Set a style to be bold or not. +set void StyleSetBold=2053(int style, bool bold) + +# Set a style to be italic or not. +set void StyleSetItalic=2054(int style, bool italic) + +# Set the size of characters of a style. +set void StyleSetSize=2055(int style, int sizePoints) + +# Set the font of a style. +set void StyleSetFont=2056(int style, string fontName) + +# Set a style to have its end of line filled or not. +set void StyleSetEOLFilled=2057(int style, bool filled) + +# Reset the default style to its state at startup +fun void StyleResetDefault=2058(,) + +# Set a style to be underlined or not. +set void StyleSetUnderline=2059(int style, bool underline) + +enu CaseVisible=SC_CASE_ +val SC_CASE_MIXED=0 +val SC_CASE_UPPER=1 +val SC_CASE_LOWER=2 +# Set a style to be mixed case, or to force upper or lower case. +set void StyleSetCase=2060(int style, int caseForce) + +# Set the character set of the font in a style. +set void StyleSetCharacterSet=2066(int style, int characterSet) + +# Set the foreground colour of the selection and whether to use this setting. +fun void SetSelFore=2067(bool useSetting, colour fore) + +# Set the background colour of the selection and whether to use this setting. +fun void SetSelBack=2068(bool useSetting, colour back) + +# Set the foreground colour of the caret. +set void SetCaretFore=2069(colour fore,) + +# When key+modifier combination km is pressed perform msg. +fun void AssignCmdKey=2070(keymod km, int msg) + +# When key+modifier combination km do nothing. +fun void ClearCmdKey=2071(keymod km,) + +# Drop all key mappings. +fun void ClearAllCmdKeys=2072(,) + +# Set the styles for a segment of the document. +fun void SetStylingEx=2073(int length, string styles) + +# Set a style to be visible or not. +set void StyleSetVisible=2074(int style, bool visible) + +# Get the time in milliseconds that the caret is on and off. +get int GetCaretPeriod=2075(,) + +# Get the time in milliseconds that the caret is on and off. 0 = steady on. +set void SetCaretPeriod=2076(int periodMilliseconds,) + +# Set the set of characters making up words for when moving or selecting by word. +set void SetWordChars=2077(, string characters) + +# Start a sequence of actions that is undone and redone as a unit. +# May be nested. +fun void BeginUndoAction=2078(,) + +# End a sequence of actions that is undone and redone as a unit. +fun void EndUndoAction=2079(,) + +enu IndicatorStyle=INDIC_ +val INDIC_MAX=7 +val INDIC_PLAIN=0 +val INDIC_SQUIGGLE=1 +val INDIC_TT=2 +val INDIC_DIAGONAL=3 +val INDIC_STRIKE=4 +val INDIC0_MASK=0x20 +val INDIC1_MASK=0x40 +val INDIC2_MASK=0x80 +val INDICS_MASK=0xE0 + +# Set an indicator to plain, squiggle or TT. +set void IndicSetStyle=2080(int indic, int style) + +# Retrieve the style of an indicator. +get int IndicGetStyle=2081(int indic,) + +# Set the foreground colour of an indicator. +set void IndicSetFore=2082(int indic, colour fore) + +# Retrieve the foreground colour of an indicator. +get colour IndicGetFore=2083(int indic,) + +# Set the foreground colour of all whitespace and whether to use this setting. +fun void SetWhitespaceFore=2084(bool useSetting, colour fore) + +# Set the background colour of all whitespace and whether to use this setting. +fun void SetWhitespaceBack=2085(bool useSetting, colour back) + +# Divide each styling byte into lexical class bits (default: 5) and indicator +# bits (default: 3). If a lexer requires more than 32 lexical states, then this +# is used to expand the possible states. +set void SetStyleBits=2090(int bits,) + +# Retrieve number of bits in style bytes used to hold the lexical state. +get int GetStyleBits=2091(,) + +# Used to hold extra styling information for each line. +set void SetLineState=2092(int line, int state) + +# Retrieve the extra styling information for a line. +get int GetLineState=2093(int line,) + +# Retrieve the last line number that has line state. +get int GetMaxLineState=2094(,) + +# Is the background of the line containing the caret in a different colour? +get bool GetCaretLineVisible=2095(,) + +# Display the background of the line containing the caret in a different colour. +set void SetCaretLineVisible=2096(bool show,) + +# Get the colour of the background of the line containing the caret. +get colour GetCaretLineBack=2097(,) + +# Set the colour of the background of the line containing the caret. +set void SetCaretLineBack=2098(colour back,) + +# Set a style to be changeable or not (read only). +# Experimental feature, currently buggy. +set void StyleSetChangeable=2099(int style, bool changeable) + +# Display a auto-completion list. +# The lenEntered parameter indicates how many characters before +# the caret should be used to provide context. +fun void AutoCShow=2100(int lenEntered, string itemList) + +# Remove the auto-completion list from the screen. +fun void AutoCCancel=2101(,) + +# Is there an auto-completion list visible? +fun bool AutoCActive=2102(,) + +# Retrieve the position of the caret when the auto-completion list was displayed. +fun position AutoCPosStart=2103(,) + +# User has selected an item so remove the list and insert the selection. +fun void AutoCComplete=2104(,) + +# Define a set of character that when typed cancel the auto-completion list. +fun void AutoCStops=2105(, string characterSet) + +# Change the separator character in the string setting up an auto-completion list. +# Default is space but can be changed if items contain space. +set void AutoCSetSeparator=2106(int separatorCharacter,) + +# Retrieve the auto-completion list separator character. +get int AutoCGetSeparator=2107(,) + +# Select the item in the auto-completion list that starts with a string. +fun void AutoCSelect=2108(, string text) + +# Should the auto-completion list be cancelled if the user backspaces to a +# position before where the box was created. +set void AutoCSetCancelAtStart=2110(bool cancel,) + +# Retrieve whether auto-completion cancelled by backspacing before start. +get bool AutoCGetCancelAtStart=2111(,) + +# Define a set of characters that when typed will cause the autocompletion to +# choose the selected item. +set void AutoCSetFillUps=2112(, string characterSet) + +# Should a single item auto-completion list automatically choose the item. +set void AutoCSetChooseSingle=2113(bool chooseSingle,) + +# Retrieve whether a single item auto-completion list automatically choose the item. +get bool AutoCGetChooseSingle=2114(,) + +# Set whether case is significant when performing auto-completion searches. +set void AutoCSetIgnoreCase=2115(bool ignoreCase,) + +# Retrieve state of ignore case flag. +get bool AutoCGetIgnoreCase=2116(,) + +# Display a list of strings and send notification when user chooses one. +fun void UserListShow=2117(int listType, string itemList) + +# Set whether or not autocompletion is hidden automatically when nothing matches. +set void AutoCSetAutoHide=2118(bool autoHide,) + +# Retrieve whether or not autocompletion is hidden automatically when nothing matches. +get bool AutoCGetAutoHide=2119(,) + +# Set whether or not autocompletion deletes any word characters +# after the inserted text upon completion. +set void AutoCSetDropRestOfWord=2270(bool dropRestOfWord,) + +# Retrieve whether or not autocompletion deletes any word characters +# after the inserted text upon completion. +get bool AutoCGetDropRestOfWord=2271(,) + +# Set the number of spaces used for one level of indentation. +set void SetIndent=2122(int indentSize,) + +# Retrieve indentation size. +get int GetIndent=2123(,) + +# Indentation will only use space characters if useTabs is false, otherwise +# it will use a combination of tabs and spaces. +set void SetUseTabs=2124(bool useTabs,) + +# Retrieve whether tabs will be used in indentation. +get bool GetUseTabs=2125(,) + +# Change the indentation of a line to a number of columns. +set void SetLineIndentation=2126(int line, int indentSize) + +# Retrieve the number of columns that a line is indented. +get int GetLineIndentation=2127(int line,) + +# Retrieve the position before the first non indentation character on a line. +get position GetLineIndentPosition=2128(int line,) + +# Retrieve the column number of a position, taking tab width into account. +get int GetColumn=2129(position pos,) + +# Show or hide the horizontal scroll bar. +set void SetHScrollBar=2130(bool show,) + +# Is the horizontal scroll bar visible? +get bool GetHScrollBar=2131(,) + +# Show or hide indentation guides. +set void SetIndentationGuides=2132(bool show,) + +# Are the indentation guides visible? +get bool GetIndentationGuides=2133(,) + +# Set the highlighted indentation guide column. +# 0 = no highlighted guide. +set void SetHighlightGuide=2134(int column,) + +# Get the highlighted indentation guide column. +get int GetHighlightGuide=2135(,) + +# Get the position after the last visible characters on a line. +get int GetLineEndPosition=2136(int line,) + +# Get the code page used to interpret the bytes of the document as characters. +get int GetCodePage=2137(,) + +# Get the foreground colour of the caret. +get colour GetCaretFore=2138(,) + +# In palette mode? +get bool GetUsePalette=2139(,) + +# In read-only mode? +get bool GetReadOnly=2140(,) + +# Sets the position of the caret. +set void SetCurrentPos=2141(position pos,) + +# Sets the position that starts the selection - this becomes the anchor. +set void SetSelectionStart=2142(position pos,) + +# Returns the position at the start of the selection. +get position GetSelectionStart=2143(,) + +# Sets the position that ends the selection - this becomes the currentPosition. +set void SetSelectionEnd=2144(position pos,) + +# Returns the position at the end of the selection. +get position GetSelectionEnd=2145(,) + +# Sets the print magnification added to the point size of each style for printing. +set void SetPrintMagnification=2146(int magnification,) + +# Returns the print magnification. +get int GetPrintMagnification=2147(,) + +enu PrintOption=SC_PRINT_ +# PrintColourMode - use same colours as screen. +val SC_PRINT_NORMAL=0 +# PrintColourMode - invert the light value of each style for printing. +val SC_PRINT_INVERTLIGHT=1 +# PrintColourMode - force black text on white background for printing. +val SC_PRINT_BLACKONWHITE=2 +# PrintColourMode - text stays coloured, but all background is forced to be white for printing. +val SC_PRINT_COLOURONWHITE=3 +# PrintColourMode - only the default-background is forced to be white for printing. +val SC_PRINT_COLOURONWHITEDEFAULTBG=4 + +# Modify colours when printing for clearer printed text. +set void SetPrintColourMode=2148(int mode,) + +# Returns the print colour mode. +get int GetPrintColourMode=2149(,) + +enu FindOption=SCFIND_ +val SCFIND_WHOLEWORD=2 +val SCFIND_MATCHCASE=4 +val SCFIND_WORDSTART=0x00100000 +val SCFIND_REGEXP=0x00200000 + +# Find some text in the document. +fun position FindText=2150(int flags, findtext ft) + +# On Windows, will draw the document into a display context such as a printer. +fun void FormatRange=2151(bool draw, formatrange fr) + +# Retrieve the display line at the top of the display. +get int GetFirstVisibleLine=2152(,) + +# Retrieve the contents of a line. +# Returns the length of the line. +fun int GetLine=2153(int line, stringresult text) + +# Returns the number of lines in the document. There is always at least one. +get int GetLineCount=2154(,) + +# Sets the size in pixels of the left margin. +set void SetMarginLeft=2155(, int pixelWidth) + +# Returns the size in pixels of the left margin. +get int GetMarginLeft=2156(,) + +# Sets the size in pixels of the right margin. +set void SetMarginRight=2157(, int pixelWidth) + +# Returns the size in pixels of the right margin. +get int GetMarginRight=2158(,) + +# Is the document different from when it was last saved? +get bool GetModify=2159(,) + +# Select a range of text. +fun void SetSel=2160(position start, position end) + +# Retrieve the selected text. +# Return the length of the text. +fun int GetSelText=2161(,stringresult text) + +# Retrieve a range of text. +# Return the length of the text. +fun int GetTextRange=2162(, textrange tr) + +# Draw the selection in normal style or with selection highlighted. +fun void HideSelection=2163(bool normal,) + +# Retrieve the x value of the point in the window where a position is displayed. +fun int PointXFromPosition=2164(, position pos) + +# Retrieve the y value of the point in the window where a position is displayed. +fun int PointYFromPosition=2165(, position pos) + +# Retrieve the line containing a position. +fun int LineFromPosition=2166(position pos,) + +# Retrieve the position at the start of a line. +fun int PositionFromLine=2167(int line,) + +# Scroll horizontally and vertically. +fun void LineScroll=2168(int columns, int lines) + +# Ensure the caret is visible. +fun void ScrollCaret=2169(,) + +# Replace the selected text with the argument text. +fun void ReplaceSel=2170(, string text) + +# Set to read only or read write. +set void SetReadOnly=2171(bool readOnly,) + +# Null operation. +fun void Null=2172(,) + +# Will a paste succeed? +fun bool CanPaste=2173(,) + +# Are there any undoable actions in the undo history? +fun bool CanUndo=2174(,) + +# Delete the undo history. +fun void EmptyUndoBuffer=2175(,) + +# Undo one action in the undo history. +fun void Undo=2176(,) + +# Cut the selection to the clipboard. +fun void Cut=2177(,) + +# Copy the selection to the clipboard. +fun void Copy=2178(,) + +# Paste the contents of the clipboard into the document replacing the selection. +fun void Paste=2179(,) + +# Clear the selection. +fun void Clear=2180(,) + +# Replace the contents of the document with the argument text. +fun void SetText=2181(, string text) + +# Retrieve all the text in the document. +# Returns number of characters retrieved. +fun int GetText=2182(int length, stringresult text) + +# Retrieve the number of characters in the document. +get int GetTextLength=2183(,) + +# Retrieve a pointer to a function that processes messages for this Scintilla. +get int GetDirectFunction=2184(,) + +# Retrieve a pointer value to use as the first argument when calling +# the function returned by GetDirectFunction. +get int GetDirectPointer=2185(,) + +# Set to overtype (true) or insert mode. +set void SetOvertype=2186(bool overtype,) + +# Returns true if overtype mode is active otherwise false is returned. +get bool GetOvertype=2187(,) + +# Set the width of the insert mode caret. +set void SetCaretWidth=2188(int pixelWidth,) + +# Returns the width of the insert mode caret. +get int GetCaretWidth=2189(,) + +# Sets the position that starts the target which is used for updating the +# document without affecting the scroll position. +set void SetTargetStart=2190(position pos,) + +# Get the position that starts the target. +get position GetTargetStart=2191(,) + +# Sets the position that ends the target which is used for updating the +# document without affecting the scroll position. +set void SetTargetEnd=2192(position pos,) + +# Get the position that ends the target. +get position GetTargetEnd=2193(,) + +# Replace the target text with the argument text. +# Text is counted so it can contain nulls. +# Returns the length of the replacement text. +fun int ReplaceTarget=2194(int length, string text) + +# Replace the target text with the argument text after \d processing. +# Text is counted so it can contain nulls. +# Looks for \d where d is between 1 and 9 and replaces these with the strings +# matched in the last search operation which were surrounded by \( and \). +# Returns the length of the replacement text including any change +# caused by processing the \d patterns. +fun int ReplaceTargetRE=2195(int length, string text) + +# Search for a counted string in the target and set the target to the found +# range. Text is counted so it can contain nulls. +# Returns length of range or -1 for failure in which case target is not moved. +fun int SearchInTarget=2197(int length, string text) + +# Set the search flags used by SearchInTarget. +set void SetSearchFlags=2198(int flags,) + +# Get the search flags used by SearchInTarget. +get int GetSearchFlags=2199(,) + +# Show a call tip containing a definition near position pos. +fun void CallTipShow=2200(position pos, string definition) + +# Remove the call tip from the screen. +fun void CallTipCancel=2201(,) + +# Is there an active call tip? +fun bool CallTipActive=2202(,) + +# Retrieve the position where the caret was before displaying the call tip. +fun position CallTipPosStart=2203(,) + +# Highlight a segment of the definition. +fun void CallTipSetHlt=2204(int start, int end) + +# Set the background colour for the call tip. +set void CallTipSetBack=2205(colour back,) + +# Find the display line of a document line taking hidden lines into account. +fun int VisibleFromDocLine=2220(int line,) + +# Find the document line of a display line taking hidden lines into account. +fun int DocLineFromVisible=2221(int lineDisplay,) + +enu FoldLevel=SC_FOLDLEVEL +val SC_FOLDLEVELBASE=0x400 +val SC_FOLDLEVELWHITEFLAG=0x1000 +val SC_FOLDLEVELHEADERFLAG=0x2000 +val SC_FOLDLEVELNUMBERMASK=0x0FFF + +# Set the fold level of a line. +# This encodes an integer level along with flags indicating whether the +# line is a header and whether it is effectively white space. +set void SetFoldLevel=2222(int line, int level) + +# Retrieve the fold level of a line. +get int GetFoldLevel=2223(int line,) + +# Find the last child line of a header line. +get int GetLastChild=2224(int line, int level) + +# Find the parent line of a child line. +get int GetFoldParent=2225(int line,) + +# Make a range of lines visible. +fun void ShowLines=2226(int lineStart, int lineEnd) + +# Make a range of lines invisible. +fun void HideLines=2227(int lineStart, int lineEnd) + +# Is a line visible? +get bool GetLineVisible=2228(int line,) + +# Show the children of a header line. +set void SetFoldExpanded=2229(int line, bool expanded) + +# Is a header line expanded? +get bool GetFoldExpanded=2230(int line,) + +# Switch a header line between expanded and contracted. +fun void ToggleFold=2231(int line,) + +# Ensure a particular line is visible by expanding any header line hiding it. +fun void EnsureVisible=2232(int line,) + +# Set some debugging options for folding. +fun void SetFoldFlags=2233(int flags,) + +# Ensure a particular line is visible by expanding any header line hiding it. +# Use the currently set visibility policy to determine which range to display. +fun void EnsureVisibleEnforcePolicy=2234(int line,) + +# Sets whether a tab pressed when caret is within indentation indents. +set void SetTabIndents=2260(bool tabIndents,) + +# Does a tab pressed when caret is within indentation indent? +get bool GetTabIndents=2261(,) + +# Sets whether a backspace pressed when caret is within indentation unindents. +set void SetBackSpaceUnIndents=2262(bool bsUnIndents,) + +# Does a backspace pressed when caret is within indentation unindent? +get bool GetBackSpaceUnIndents=2263(,) + +val SC_TIME_FOREVER=10000000 + +# Sets the time the mouse must sit still to generate a mouse dwell event. +set void SetMouseDwellTime=2264(int periodMilliseconds,) + +# Retrieve the time the mouse must sit still to generate a mouse dwell event. +get int GetMouseDwellTime=2265(,) + +# Get position of start of word. +fun int WordStartPosition=2266(position pos, bool onlyWordCharacters) + +# Get position of end of word. +fun int WordEndPosition=2267(position pos, bool onlyWordCharacters) + +enu Wrap=SC_WRAP_ +val SC_WRAP_NONE=0 +val SC_WRAP_WORD=1 + +# Sets whether text is word wrapped. +set void SetWrapMode=2268(int mode,) + +# Retrieve whether text is word wrapped. +get int GetWrapMode=2269(,) + +enu LineCache=SC_CACHE_ +val SC_CACHE_NONE=0 +val SC_CACHE_CARET=1 +val SC_CACHE_PAGE=2 +val SC_CACHE_DOCUMENT=3 + +# Sets the degree of caching of layout information. +set void SetLayoutCache=2272(int mode,) + +# Retrieve the degree of caching of layout information. +get int GetLayoutCache=2273(,) + +# Sets the document width assumed for scrolling. +set void SetScrollWidth=2274(int pixelWidth,) + +# Retrieve the document width assumed for scrolling. +get int GetScrollWidth=2275(,) + +# Measure the pixel width of some text in a particular style. +# Nul terminated text argument. +# Does not handle tab or control characters. +fun int TextWidth=2276(int style, string text) + +# Sets the scroll range so that maximum scroll position has +# the last line at the bottom of the view (default). +# Setting this to false allows scrolling one page below the last line. +set void SetEndAtLastLine=2277(bool endAtLastLine,) + +# Retrieve whether the maximum scroll position has the last +# line at the bottom of the view. +get int GetEndAtLastLine=2278(,) + +# Retrieve the height of a particular line of text in pixels. +fun int TextHeight=2279(int line,) + +# Show or hide the vertical scroll bar. +set void SetVScrollBar=2280(bool show,) + +# Is the vertical scroll bar visible? +get bool GetVScrollBar=2281(,) + +# Append a string to the end of the document without changing the selection. +fun void AppendText=2282(int length, string text) + +## New messages go here + +## Start of key messages +# Move caret down one line. +fun void LineDown=2300(,) + +# Move caret down one line extending selection to new caret position. +fun void LineDownExtend=2301(,) + +# Move caret up one line. +fun void LineUp=2302(,) + +# Move caret up one line extending selection to new caret position. +fun void LineUpExtend=2303(,) + +# Move caret left one character. +fun void CharLeft=2304(,) + +# Move caret left one character extending selection to new caret position. +fun void CharLeftExtend=2305(,) + +# Move caret right one character. +fun void CharRight=2306(,) + +# Move caret right one character extending selection to new caret position. +fun void CharRightExtend=2307(,) + +# Move caret left one word. +fun void WordLeft=2308(,) + +# Move caret left one word extending selection to new caret position. +fun void WordLeftExtend=2309(,) + +# Move caret right one word. +fun void WordRight=2310(,) + +# Move caret right one word extending selection to new caret position. +fun void WordRightExtend=2311(,) + +# Move caret to first position on line. +fun void Home=2312(,) + +# Move caret to first position on line extending selection to new caret position. +fun void HomeExtend=2313(,) + +# Move caret to last position on line. +fun void LineEnd=2314(,) + +# Move caret to last position on line extending selection to new caret position. +fun void LineEndExtend=2315(,) + +# Move caret to first position in document. +fun void DocumentStart=2316(,) + +# Move caret to first position in document extending selection to new caret position. +fun void DocumentStartExtend=2317(,) + +# Move caret to last position in document. +fun void DocumentEnd=2318(,) + +# Move caret to last position in document extending selection to new caret position. +fun void DocumentEndExtend=2319(,) + +# Move caret one page up. +fun void PageUp=2320(,) + +# Move caret one page up extending selection to new caret position. +fun void PageUpExtend=2321(,) + +# Move caret one page down. +fun void PageDown=2322(,) + +# Move caret one page down extending selection to new caret position. +fun void PageDownExtend=2323(,) + +# Switch from insert to overtype mode or the reverse. +fun void EditToggleOvertype=2324(,) + +# Cancel any modes such as call tip or auto-completion list display. +fun void Cancel=2325(,) + +# Delete the selection or if no selection, the character before the caret. +fun void DeleteBack=2326(,) + +# If selection is empty or all on one line replace the selection with a tab character. +# If more than one line selected, indent the lines. +fun void Tab=2327(,) + +# Dedent the selected lines. +fun void BackTab=2328(,) + +# Insert a new line, may use a CRLF, CR or LF depending on EOL mode. +fun void NewLine=2329(,) + +# Insert a Form Feed character. +fun void FormFeed=2330(,) + +# Move caret to before first visible character on line. +# If already there move to first character on line. +fun void VCHome=2331(,) + +# Like VCHome but extending selection to new caret position. +fun void VCHomeExtend=2332(,) + +# Magnify the displayed text by increasing the sizes by 1 point. +fun void ZoomIn=2333(,) + +# Make the displayed text smaller by decreasing the sizes by 1 point. +fun void ZoomOut=2334(,) + +# Delete the word to the left of the caret. +fun void DelWordLeft=2335(,) + +# Delete the word to the right of the caret. +fun void DelWordRight=2336(,) + +# Cut the line containing the caret. +fun void LineCut=2337(,) + +# Delete the line containing the caret. +fun void LineDelete=2338(,) + +# Switch the current line with the previous. +fun void LineTranspose=2339(,) + +# Transform the selection to lower case. +fun void LowerCase=2340(,) + +# Transform the selection to upper case. +fun void UpperCase=2341(,) + +# Scroll the document down, keeping the caret visible. +fun void LineScrollDown=2342(,) + +# Scroll the document up, keeping the caret visible. +fun void LineScrollUp=2343(,) + +# Delete the selection or if no selection, the character before the caret. +# Will not delete the character before at the start of a line. +fun void DeleteBackNotLine=2344(,) + +# Move caret to first position on display line. +fun void HomeDisplay=2345(,) + +# Move caret to first position on display line extending selection to +# new caret position. +fun void HomeDisplayExtend=2346(,) + +# Move caret to last position on display line. +fun void LineEndDisplay=2347(,) + +# Move caret to last position on display line extending selection to new +# caret position. +fun void LineEndDisplayExtend=2348(,) + +# Move the caret inside current view if it's not there already. +fun void MoveCaretInsideView=2401(,) + +# How many characters are on a line, not including end of line characters? +fun int LineLength=2350(int line,) + +# Highlight the characters at two positions. +fun void BraceHighlight=2351(position pos1, position pos2) + +# Highlight the character at a position indicating there is no matching brace. +fun void BraceBadLight=2352(position pos,) + +# Find the position of a matching brace or INVALID_POSITION if no match. +fun position BraceMatch=2353(position pos,) + +# Are the end of line characters visible? +get bool GetViewEOL=2355(,) + +# Make the end of line characters visible or invisible. +set void SetViewEOL=2356(bool visible,) + +# Retrieve a pointer to the document object. +get int GetDocPointer=2357(,) + +# Change the document object used. +set void SetDocPointer=2358(,int pointer) + +# Set which document modification events are sent to the container. +set void SetModEventMask=2359(int mask,) + +enu EdgeVisualStyle=EDGE_ +val EDGE_NONE=0 +val EDGE_LINE=1 +val EDGE_BACKGROUND=2 + +# Retrieve the column number which text should be kept within. +get int GetEdgeColumn=2360(,) + +# Set the column number of the edge. +# If text goes past the edge then it is highlighted. +set void SetEdgeColumn=2361(int column,) + +# Retrieve the edge highlight mode. +get int GetEdgeMode=2362(,) + +# The edge may be displayed by a line (EDGE_LINE) or by highlighting text that +# goes beyond it (EDGE_BACKGROUND) or not displayed at all (EDGE_NONE). +set void SetEdgeMode=2363(int mode,) + +# Retrieve the colour used in edge indication. +get colour GetEdgeColour=2364(,) + +# Change the colour used in edge indication. +set void SetEdgeColour=2365(colour edgeColour,) + +# Sets the current caret position to be the search anchor. +fun void SearchAnchor=2366(,) + +# Find some text starting at the search anchor. +# Does not ensure the selection is visible. +fun int SearchNext=2367(int flags, string text) + +# Find some text starting at the search anchor and moving backwards. +# Does not ensure the selection is visible. +fun int SearchPrev=2368(int flags, string text) + +# Retrieves the number of lines completely visible. +get int LinesOnScreen=2370(,) + +# Set whether a pop up menu is displayed automatically when the user presses +# the wrong mouse button. +fun void UsePopUp=2371(bool allowPopUp,) + +# Is the selection rectangular? The alternative is the more common stream selection. +get bool SelectionIsRectangle=2372(,) + +# Set the zoom level. This number of points is added to the size of all fonts. +# It may be positive to magnify or negative to reduce. +set void SetZoom=2373(int zoom,) +# Retrieve the zoom level. +get int GetZoom=2374(,) + +# Create a new document object. +# Starts with reference count of 1 and not selected into editor. +fun int CreateDocument=2375(,) +# Extend life of document. +fun void AddRefDocument=2376(, int doc) +# Release a reference to the document, deleting document if it fades to black. +fun void ReleaseDocument=2377(, int doc) + +# Get which document modification events are sent to the container. +get int GetModEventMask=2378(,) + +# Change internal focus flag. +set void SetFocus=2380(bool focus,) +# Get internal focus flag. +get bool GetFocus=2381(,) + +# Change error status - 0 = OK. +set void SetStatus=2382(int statusCode,) +# Get error status. +get int GetStatus=2383(,) + +# Set whether the mouse is captured when its button is pressed. +set void SetMouseDownCaptures=2384(bool captures,) +# Get whether mouse gets captured. +get bool GetMouseDownCaptures=2385(,) + +enu CursorShape=SC_CURSOR +val SC_CURSORNORMAL=-1 +val SC_CURSORWAIT=4 +# Sets the cursor to one of the SC_CURSOR* values. +set void SetCursor=2386(int cursorType,) +# Get cursor type. +get int GetCursor=2387(,) + +# Change the way control characters are displayed: +# If symbol is < 32, keep the drawn way, else, use the given character. +set void SetControlCharSymbol=2388(int symbol,) +# Get the way control characters are displayed. +get int GetControlCharSymbol=2389(,) + +# Move to the previous change in capitalisation. +fun void WordPartLeft=2390(,) +# Move to the previous change in capitalisation extending selection +# to new caret position. +fun void WordPartLeftExtend=2391(,) +# Move to the change next in capitalisation. +fun void WordPartRight=2392(,) +# Move to the next change in capitalisation extending selection +# to new caret position. +fun void WordPartRightExtend=2393(,) + +# Constants for use with SetVisiblePolicy, similar to SetCaretPolicy. +val VISIBLE_SLOP=0x01 +val VISIBLE_STRICT=0x04 +# Set the way the display area is determined when a particular line +# is to be moved to by Find, FindNext, GotoLine, etc. +fun void SetVisiblePolicy=2394(int visiblePolicy, int visibleSlop) + +# Delete back from the current position to the start of the line. +fun void DelLineLeft=2395(,) + +# Delete forwards from the current position to the end of the line. +fun void DelLineRight=2396(,) + +# Get and Set the xOffset (ie, horizonal scroll position). +set void SetXOffset=2397(int newOffset,) +get int GetXOffset=2398(,) + +# Set the last x chosen value to be the caret x position +fun void ChooseCaretX=2399(,) + +# Set the focus to this Scintilla widget. +# GTK+ Specific. +fun void GrabFocus=2400(,) + +enu CaretPolicy = CARET_ +# Caret policy, used by SetXCaretPolicy and SetYCaretPolicy. +# If CARET_SLOP is set, we can define a slop value: caretSlop. +# This value defines an unwanted zone (UZ) where the caret is... unwanted. +# This zone is defined as a number of pixels near the vertical margins, +# and as a number of lines near the horizontal margins. +# By keeping the caret away from the edges, it is seen within its context, +# so it is likely that the identifier that the caret is on can be completely seen, +# and that the current line is seen with some of the lines following it which are +# often dependent on that line. +val CARET_SLOP=0x01 +# If CARET_STRICT is set, the policy is enforced... strictly. +# The caret is centred on the display if slop is not set, +# and cannot go in the UZ if slop is set. +val CARET_STRICT=0x04 +# If CARET_JUMPS is set, the display is moved more energetically +# so the caret can move in the same direction longer before the policy is applied again. +val CARET_JUMPS=0x10 +# If CARET_EVEN is not set, instead of having symmetrical UZs, +# the left and bottom UZs are extended up to right and top UZs respectively. +# This way, we favour the displaying of useful information: the begining of lines, +# where most code reside, and the lines after the caret, eg. the body of a function. +val CARET_EVEN=0x08 + +# Set the way the caret is kept visible when going sideway. +# The exclusion zone is given in pixels. +fun void SetXCaretPolicy=2402(int caretPolicy, int caretSlop) + +# Set the way the line the caret is on is kept visible. +# The exclusion zone is given in lines. +fun void SetYCaretPolicy=2403(int caretPolicy, int caretSlop) + +# Start notifying the container of all key presses and commands. +fun void StartRecord=3001(,) + +# Stop notifying the container of all key presses and commands. +fun void StopRecord=3002(,) + +# Set the lexing language of the document. +set void SetLexer=4001(int lexer,) + +# Retrieve the lexing language of the document. +get int GetLexer=4002(,) + +# Colourise a segment of the document using the current lexing language. +fun void Colourise=4003(position start, position end) + +# Set up a value that may be used by a lexer for some optional feature. +set void SetProperty=4004(string key, string value) + +# Set up the key words used by the lexer. +set void SetKeyWords=4005(int keywordSet, string keyWords) + +# Set the lexing language of the document based on string name. +set void SetLexerLanguage=4006(, string language) + +# Notifications +# Type of modification and the action which caused the modification. +# These are defined as a bit mask to make it easy to specify which notifications are wanted. +# One bit is set from each of SC_MOD_* and SC_PERFORMED_*. +enu ModificationFlags=SC_MOD_ SC_PERFORMED_ SC_LAST +val SC_MOD_INSERTTEXT=0x1 +val SC_MOD_DELETETEXT=0x2 +val SC_MOD_CHANGESTYLE=0x4 +val SC_MOD_CHANGEFOLD=0x8 +val SC_PERFORMED_USER=0x10 +val SC_PERFORMED_UNDO=0x20 +val SC_PERFORMED_REDO=0x40 +val SC_LASTSTEPINUNDOREDO=0x100 +val SC_MOD_CHANGEMARKER=0x200 +val SC_MOD_BEFOREINSERT=0x400 +val SC_MOD_BEFOREDELETE=0x800 +val SC_MODEVENTMASKALL=0xF77 + +# For compatibility, these go through the COMMAND notification rather than NOTIFY +# and should have had exactly the same values as the EN_* constants. +# Unfortunately the SETFOCUS and KILLFOCUS are flipped over from EN_* +# As clients depend on these constants, this will not be changed. +val SCEN_CHANGE=768 +val SCEN_SETFOCUS=512 +val SCEN_KILLFOCUS=256 + +# Symbolic key codes and modifier flags. +# ASCII and other printable characters below 256. +# Extended keys above 300. + +enu Keys=SCK_ +val SCK_DOWN=300 +val SCK_UP=301 +val SCK_LEFT=302 +val SCK_RIGHT=303 +val SCK_HOME=304 +val SCK_END=305 +val SCK_PRIOR=306 +val SCK_NEXT=307 +val SCK_DELETE=308 +val SCK_INSERT=309 +val SCK_ESCAPE=7 +val SCK_BACK=8 +val SCK_TAB=9 +val SCK_RETURN=13 +val SCK_ADD=310 +val SCK_SUBTRACT=311 +val SCK_DIVIDE=312 + +enu KeyMod=SCMOD_ +val SCMOD_SHIFT=1 +val SCMOD_CTRL=2 +val SCMOD_ALT=4 + +################################################ +# For SciLexer.h +enu Lexer=SCLEX_ +val SCLEX_CONTAINER=0 +val SCLEX_NULL=1 +val SCLEX_PYTHON=2 +val SCLEX_CPP=3 +val SCLEX_HTML=4 +val SCLEX_XML=5 +val SCLEX_PERL=6 +val SCLEX_SQL=7 +val SCLEX_VB=8 +val SCLEX_PROPERTIES=9 +val SCLEX_ERRORLIST=10 +val SCLEX_MAKEFILE=11 +val SCLEX_BATCH=12 +val SCLEX_XCODE=13 +val SCLEX_LATEX=14 +val SCLEX_LUA=15 +val SCLEX_DIFF=16 +val SCLEX_CONF=17 +val SCLEX_PASCAL=18 +val SCLEX_AVE=19 +val SCLEX_ADA=20 +val SCLEX_LISP=21 +val SCLEX_RUBY=22 +val SCLEX_EIFFEL=23 +val SCLEX_EIFFELKW=24 +val SCLEX_TCL=25 +val SCLEX_NNCRONTAB=26 +val SCLEX_BULLANT=27 +val SCLEX_VBSCRIPT=28 +val SCLEX_ASP=29 +val SCLEX_PHP=30 +val SCLEX_BAAN=31 +val SCLEX_MATLAB=32 +val SCLEX_SCRIPTOL=33 +val SCLEX_ASM=34 +val SCLEX_CPPNOCASE=35 +val SCLEX_FORTRAN=36 +val SCLEX_F77=37 + +# When a lexer specifies its language as SCLEX_AUTOMATIC it receives a +# value assigned in sequence from SCLEX_AUTOMATIC+1. +val SCLEX_AUTOMATIC=1000 +# Lexical states for SCLEX_PYTHON +lex Python=SCLEX_PYTHON SCE_P_ +lex Ruby=SCLEX_RUBY SCE_P_ +val SCE_P_DEFAULT=0 +val SCE_P_COMMENTLINE=1 +val SCE_P_NUMBER=2 +val SCE_P_STRING=3 +val SCE_P_CHARACTER=4 +val SCE_P_WORD=5 +val SCE_P_TRIPLE=6 +val SCE_P_TRIPLEDOUBLE=7 +val SCE_P_CLASSNAME=8 +val SCE_P_DEFNAME=9 +val SCE_P_OPERATOR=10 +val SCE_P_IDENTIFIER=11 +val SCE_P_COMMENTBLOCK=12 +val SCE_P_STRINGEOL=13 +# Lexical states for SCLEX_CPP +lex Cpp=SCLEX_CPP SCE_C_ +lex SQL=SCLEX_SQL SCE_C_ +lex Pascal=SCLEX_PASCAL SCE_C_ +lex TCL=SCLEX_TCL SCE_C_ +lex BullAnt=SCLEX_BULLANT SCE_C_ +val SCE_C_DEFAULT=0 +val SCE_C_COMMENT=1 +val SCE_C_COMMENTLINE=2 +val SCE_C_COMMENTDOC=3 +val SCE_C_NUMBER=4 +val SCE_C_WORD=5 +val SCE_C_STRING=6 +val SCE_C_CHARACTER=7 +val SCE_C_UUID=8 +val SCE_C_PREPROCESSOR=9 +val SCE_C_OPERATOR=10 +val SCE_C_IDENTIFIER=11 +val SCE_C_STRINGEOL=12 +val SCE_C_VERBATIM=13 +val SCE_C_REGEX=14 +val SCE_C_COMMENTLINEDOC=15 +val SCE_C_WORD2=16 +val SCE_C_COMMENTDOCKEYWORD=17 +val SCE_C_COMMENTDOCKEYWORDERROR=18 +# Lexical states for SCLEX_HTML, SCLEX_XML +lex HTML=SCLEX_HTML SCE_H +lex XML=SCLEX_XML SCE_H +lex ASP=SCLEX_ASP SCE_H +lex PHP=SCLEX_PHP SCE_H +val SCE_H_DEFAULT=0 +val SCE_H_TAG=1 +val SCE_H_TAGUNKNOWN=2 +val SCE_H_ATTRIBUTE=3 +val SCE_H_ATTRIBUTEUNKNOWN=4 +val SCE_H_NUMBER=5 +val SCE_H_DOUBLESTRING=6 +val SCE_H_SINGLESTRING=7 +val SCE_H_OTHER=8 +val SCE_H_COMMENT=9 +val SCE_H_ENTITY=10 +# XML and ASP +val SCE_H_TAGEND=11 +val SCE_H_XMLSTART=12 +val SCE_H_XMLEND=13 +val SCE_H_SCRIPT=14 +val SCE_H_ASP=15 +val SCE_H_ASPAT=16 +val SCE_H_CDATA=17 +val SCE_H_QUESTION=18 +# More HTML +val SCE_H_VALUE=19 +# X-Code +val SCE_H_XCCOMMENT=20 +# SGML +val SCE_H_SGML_DEFAULT=21 +val SCE_H_SGML_COMMAND=22 +val SCE_H_SGML_1ST_PARAM=23 +val SCE_H_SGML_DOUBLESTRING=24 +val SCE_H_SGML_SIMPLESTRING=25 +val SCE_H_SGML_ERROR=26 +val SCE_H_SGML_SPECIAL=27 +val SCE_H_SGML_ENTITY=28 +val SCE_H_SGML_COMMENT=29 +val SCE_H_SGML_1ST_PARAM_COMMENT=30 +val SCE_H_SGML_BLOCK_DEFAULT=31 +# Embedded Javascript +val SCE_HJ_START=40 +val SCE_HJ_DEFAULT=41 +val SCE_HJ_COMMENT=42 +val SCE_HJ_COMMENTLINE=43 +val SCE_HJ_COMMENTDOC=44 +val SCE_HJ_NUMBER=45 +val SCE_HJ_WORD=46 +val SCE_HJ_KEYWORD=47 +val SCE_HJ_DOUBLESTRING=48 +val SCE_HJ_SINGLESTRING=49 +val SCE_HJ_SYMBOLS=50 +val SCE_HJ_STRINGEOL=51 +val SCE_HJ_REGEX=52 +# ASP Javascript +val SCE_HJA_START=55 +val SCE_HJA_DEFAULT=56 +val SCE_HJA_COMMENT=57 +val SCE_HJA_COMMENTLINE=58 +val SCE_HJA_COMMENTDOC=59 +val SCE_HJA_NUMBER=60 +val SCE_HJA_WORD=61 +val SCE_HJA_KEYWORD=62 +val SCE_HJA_DOUBLESTRING=63 +val SCE_HJA_SINGLESTRING=64 +val SCE_HJA_SYMBOLS=65 +val SCE_HJA_STRINGEOL=66 +val SCE_HJA_REGEX=67 +# Embedded VBScript +val SCE_HB_START=70 +val SCE_HB_DEFAULT=71 +val SCE_HB_COMMENTLINE=72 +val SCE_HB_NUMBER=73 +val SCE_HB_WORD=74 +val SCE_HB_STRING=75 +val SCE_HB_IDENTIFIER=76 +val SCE_HB_STRINGEOL=77 +# ASP VBScript +val SCE_HBA_START=80 +val SCE_HBA_DEFAULT=81 +val SCE_HBA_COMMENTLINE=82 +val SCE_HBA_NUMBER=83 +val SCE_HBA_WORD=84 +val SCE_HBA_STRING=85 +val SCE_HBA_IDENTIFIER=86 +val SCE_HBA_STRINGEOL=87 +# Embedded Python +val SCE_HP_START=90 +val SCE_HP_DEFAULT=91 +val SCE_HP_COMMENTLINE=92 +val SCE_HP_NUMBER=93 +val SCE_HP_STRING=94 +val SCE_HP_CHARACTER=95 +val SCE_HP_WORD=96 +val SCE_HP_TRIPLE=97 +val SCE_HP_TRIPLEDOUBLE=98 +val SCE_HP_CLASSNAME=99 +val SCE_HP_DEFNAME=100 +val SCE_HP_OPERATOR=101 +val SCE_HP_IDENTIFIER=102 +# ASP Python +val SCE_HPA_START=105 +val SCE_HPA_DEFAULT=106 +val SCE_HPA_COMMENTLINE=107 +val SCE_HPA_NUMBER=108 +val SCE_HPA_STRING=109 +val SCE_HPA_CHARACTER=110 +val SCE_HPA_WORD=111 +val SCE_HPA_TRIPLE=112 +val SCE_HPA_TRIPLEDOUBLE=113 +val SCE_HPA_CLASSNAME=114 +val SCE_HPA_DEFNAME=115 +val SCE_HPA_OPERATOR=116 +val SCE_HPA_IDENTIFIER=117 +# PHP +val SCE_HPHP_DEFAULT=118 +val SCE_HPHP_HSTRING=119 +val SCE_HPHP_SIMPLESTRING=120 +val SCE_HPHP_WORD=121 +val SCE_HPHP_NUMBER=122 +val SCE_HPHP_VARIABLE=123 +val SCE_HPHP_COMMENT=124 +val SCE_HPHP_COMMENTLINE=125 +val SCE_HPHP_HSTRING_VARIABLE=126 +val SCE_HPHP_OPERATOR=127 +# Lexical states for SCLEX_PERL +lex Perl=SCLEX_PERL SCE_PL_ +val SCE_PL_DEFAULT=0 +val SCE_PL_ERROR=1 +val SCE_PL_COMMENTLINE=2 +val SCE_PL_POD=3 +val SCE_PL_NUMBER=4 +val SCE_PL_WORD=5 +val SCE_PL_STRING=6 +val SCE_PL_CHARACTER=7 +val SCE_PL_PUNCTUATION=8 +val SCE_PL_PREPROCESSOR=9 +val SCE_PL_OPERATOR=10 +val SCE_PL_IDENTIFIER=11 +val SCE_PL_SCALAR=12 +val SCE_PL_ARRAY=13 +val SCE_PL_HASH=14 +val SCE_PL_SYMBOLTABLE=15 +val SCE_PL_REGEX=17 +val SCE_PL_REGSUBST=18 +val SCE_PL_LONGQUOTE=19 +val SCE_PL_BACKTICKS=20 +val SCE_PL_DATASECTION=21 +val SCE_PL_HERE_DELIM=22 +val SCE_PL_HERE_Q=23 +val SCE_PL_HERE_QQ=24 +val SCE_PL_HERE_QX=25 +val SCE_PL_STRING_Q=26 +val SCE_PL_STRING_QQ=27 +val SCE_PL_STRING_QX=28 +val SCE_PL_STRING_QR=29 +val SCE_PL_STRING_QW=30 +# Lexical states for SCLEX_VB, SCLEX_VBSCRIPT +lex VB=SCLEX_VB SCE_B_ +lex VBScript=SCLEX_VBSCRIPT SCE_B_ +val SCE_B_DEFAULT=0 +val SCE_B_COMMENT=1 +val SCE_B_NUMBER=2 +val SCE_B_KEYWORD=3 +val SCE_B_STRING=4 +val SCE_B_PREPROCESSOR=5 +val SCE_B_OPERATOR=6 +val SCE_B_IDENTIFIER=7 +val SCE_B_DATE=8 +# Lexical states for SCLEX_PROPERTIES +lex Properties=SCLEX_PROPERTIES SCE_PROPS_ +val SCE_PROPS_DEFAULT=0 +val SCE_PROPS_COMMENT=1 +val SCE_PROPS_SECTION=2 +val SCE_PROPS_ASSIGNMENT=3 +val SCE_PROPS_DEFVAL=4 +# Lexical states for SCLEX_LATEX +lex LaTeX=SCLEX_LATEX SCE_L_ +val SCE_L_DEFAULT=0 +val SCE_L_COMMAND=1 +val SCE_L_TAG=2 +val SCE_L_MATH=3 +val SCE_L_COMMENT=4 +# Lexical states for SCLEX_LUA +lex Lua=SCLEX_LUA SCE_LUA_ +val SCE_LUA_DEFAULT=0 +val SCE_LUA_COMMENT=1 +val SCE_LUA_COMMENTLINE=2 +val SCE_LUA_COMMENTDOC=3 +val SCE_LUA_NUMBER=4 +val SCE_LUA_WORD=5 +val SCE_LUA_STRING=6 +val SCE_LUA_CHARACTER=7 +val SCE_LUA_LITERALSTRING=8 +val SCE_LUA_PREPROCESSOR=9 +val SCE_LUA_OPERATOR=10 +val SCE_LUA_IDENTIFIER=11 +val SCE_LUA_STRINGEOL=12 +val SCE_LUA_WORD2=13 +val SCE_LUA_WORD3=14 +val SCE_LUA_WORD4=15 +val SCE_LUA_WORD5=16 +val SCE_LUA_WORD6=17 +# Lexical states for SCLEX_ERRORLIST +lex ErrorList=SCLEX_ERRORLIST SCE_ERR_ +val SCE_ERR_DEFAULT=0 +val SCE_ERR_PYTHON=1 +val SCE_ERR_GCC=2 +val SCE_ERR_MS=3 +val SCE_ERR_CMD=4 +val SCE_ERR_BORLAND=5 +val SCE_ERR_PERL=6 +val SCE_ERR_NET=7 +val SCE_ERR_LUA=8 +val SCE_ERR_CTAG=9 +val SCE_ERR_DIFF_CHANGED=10 +val SCE_ERR_DIFF_ADDITION=11 +val SCE_ERR_DIFF_DELETION=12 +val SCE_ERR_DIFF_MESSAGE=13 +val SCE_ERR_PHP=14 +# Lexical states for SCLEX_BATCH +lex Batch=SCLEX_BATCH SCE_BAT_ +val SCE_BAT_DEFAULT=0 +val SCE_BAT_COMMENT=1 +val SCE_BAT_WORD=2 +val SCE_BAT_LABEL=3 +val SCE_BAT_HIDE=4 +val SCE_BAT_COMMAND=5 +val SCE_BAT_IDENTIFIER=6 +val SCE_BAT_OPERATOR=7 +# Lexical states for SCLEX_MAKEFILE +lex MakeFile=SCLEX_MAKEFILE SCE_MAKE_ +val SCE_MAKE_DEFAULT=0 +val SCE_MAKE_COMMENT=1 +val SCE_MAKE_PREPROCESSOR=2 +val SCE_MAKE_IDENTIFIER=3 +val SCE_MAKE_OPERATOR=4 +val SCE_MAKE_TARGET=5 +val SCE_MAKE_IDEOL=9 +# Lexical states for SCLEX_DIFF +lex Diff=SCLEX_DIFF SCE_DIFF_ +val SCE_DIFF_DEFAULT=0 +val SCE_DIFF_COMMENT=1 +val SCE_DIFF_COMMAND=2 +val SCE_DIFF_HEADER=3 +val SCE_DIFF_POSITION=4 +val SCE_DIFF_DELETED=5 +val SCE_DIFF_ADDED=6 +# Lexical states for SCLEX_CONF (Apache Configuration Files Lexer) +lex Conf=SCLEX_CONF SCE_CONF_ +val SCE_CONF_DEFAULT=0 +val SCE_CONF_COMMENT=1 +val SCE_CONF_NUMBER=2 +val SCE_CONF_IDENTIFIER=3 +val SCE_CONF_EXTENSION=4 +val SCE_CONF_PARAMETER=5 +val SCE_CONF_STRING=6 +val SCE_CONF_OPERATOR=7 +val SCE_CONF_IP=8 +val SCE_CONF_DIRECTIVE=9 +# Lexical states for SCLEX_AVE, Avenue +lex Avenue=SCLEX_AVE SCE_AVE_ +val SCE_AVE_DEFAULT=0 +val SCE_AVE_COMMENT=1 +val SCE_AVE_NUMBER=2 +val SCE_AVE_WORD=3 +val SCE_AVE_KEYWORD=4 +val SCE_AVE_STATEMENT=5 +val SCE_AVE_STRING=6 +val SCE_AVE_ENUM=7 +val SCE_AVE_STRINGEOL=8 +val SCE_AVE_IDENTIFIER=9 +val SCE_AVE_OPERATOR=10 +# Lexical states for SCLEX_ADA +lex Ada=SCLEX_ADA SCE_ADA_ +val SCE_ADA_DEFAULT=0 +val SCE_ADA_WORD=1 +val SCE_ADA_IDENTIFIER=2 +val SCE_ADA_NUMBER=3 +val SCE_ADA_DELIMITER=4 +val SCE_ADA_CHARACTER=5 +val SCE_ADA_CHARACTEREOL=6 +val SCE_ADA_STRING=7 +val SCE_ADA_STRINGEOL=8 +val SCE_ADA_LABEL=9 +val SCE_ADA_COMMENTLINE=10 +val SCE_ADA_ILLEGAL=11 +# Lexical states for SCLEX_BAAN +lex Baan=SCLEX_BAAN SCE_BAAN_ +val SCE_BAAN_DEFAULT=0 +val SCE_BAAN_COMMENT=1 +val SCE_BAAN_COMMENTDOC=2 +val SCE_BAAN_NUMBER=3 +val SCE_BAAN_WORD=4 +val SCE_BAAN_STRING=5 +val SCE_BAAN_PREPROCESSOR=6 +val SCE_BAAN_OPERATOR=7 +val SCE_BAAN_IDENTIFIER=8 +val SCE_BAAN_STRINGEOL=9 +val SCE_BAAN_WORD2=10 +# Lexical states for SCLEX_LISP +lex Lisp=SCLEX_LISP SCE_LISP_ +val SCE_LISP_DEFAULT=0 +val SCE_LISP_COMMENT=1 +val SCE_LISP_NUMBER=2 +val SCE_LISP_KEYWORD=3 +val SCE_LISP_STRING=6 +val SCE_LISP_STRINGEOL=8 +val SCE_LISP_IDENTIFIER=9 +val SCE_LISP_OPERATOR=10 +# Lexical states for SCLEX_EIFFEL and SCLEX_EIFFELKW +lex Eiffel=SCLEX_EIFFEL SCE_EIFFEL_ +lex EiffelKW=SCLEX_EIFFELKW SCE_EIFFEL_ +val SCE_EIFFEL_DEFAULT=0 +val SCE_EIFFEL_COMMENTLINE=1 +val SCE_EIFFEL_NUMBER=2 +val SCE_EIFFEL_WORD=3 +val SCE_EIFFEL_STRING=4 +val SCE_EIFFEL_CHARACTER=5 +val SCE_EIFFEL_OPERATOR=6 +val SCE_EIFFEL_IDENTIFIER=7 +val SCE_EIFFEL_STRINGEOL=8 +# Lexical states for SCLEX_NNCRONTAB (nnCron crontab Lexer) +lex NNCronTab=SCLEX_NNCRONTAB SCE_NNCRONTAB_ +val SCE_NNCRONTAB_DEFAULT=0 +val SCE_NNCRONTAB_COMMENT=1 +val SCE_NNCRONTAB_TASK=2 +val SCE_NNCRONTAB_SECTION=3 +val SCE_NNCRONTAB_KEYWORD=4 +val SCE_NNCRONTAB_MODIFIER=5 +val SCE_NNCRONTAB_ASTERISK=6 +val SCE_NNCRONTAB_NUMBER=7 +val SCE_NNCRONTAB_STRING=8 +val SCE_NNCRONTAB_ENVIRONMENT=9 +val SCE_NNCRONTAB_IDENTIFIER=10 +# Lexical states for SCLEX_MATLAB +lex MatLab=SCLEX_MATLAB SCE_MATLAB_ +val SCE_MATLAB_DEFAULT=0 +val SCE_MATLAB_COMMENT=1 +val SCE_MATLAB_COMMAND=2 +val SCE_MATLAB_NUMBER=3 +val SCE_MATLAB_KEYWORD=4 +val SCE_MATLAB_STRING=5 +val SCE_MATLAB_OPERATOR=6 +val SCE_MATLAB_IDENTIFIER=7 +# Lexical states for SCLEX_SCRIPTOL +lex Sol=SCLEX_SCRIPTOL SCE_SCRIPTOL_ +val SCE_SCRIPTOL_DEFAULT=0 +val SCE_SCRIPTOL_COMMENT=1 +val SCE_SCRIPTOL_COMMENTLINE=2 +val SCE_SCRIPTOL_COMMENTDOC=3 +val SCE_SCRIPTOL_NUMBER=4 +val SCE_SCRIPTOL_WORD=5 +val SCE_SCRIPTOL_STRING=6 +val SCE_SCRIPTOL_CHARACTER=7 +val SCE_SCRIPTOL_UUID=8 +val SCE_SCRIPTOL_PREPROCESSOR=9 +val SCE_SCRIPTOL_OPERATOR=10 +val SCE_SCRIPTOL_IDENTIFIER=11 +val SCE_SCRIPTOL_STRINGEOL=12 +val SCE_SCRIPTOL_VERBATIM=13 +val SCE_SCRIPTOL_REGEX=14 +val SCE_SCRIPTOL_COMMENTLINEDOC=15 +val SCE_SCRIPTOL_WORD2=16 +val SCE_SCRIPTOL_COMMENTDOCKEYWORD=17 +val SCE_SCRIPTOL_COMMENTDOCKEYWORDERROR=18 +val SCE_SCRIPTOL_COMMENTBASIC=19 +# Lexical states for SCLEX_ASM +lex Asm=SCLEX_ASM SCE_ASM_ +val SCE_ASM_DEFAULT=0 +val SCE_ASM_COMMENT=1 +val SCE_ASM_NUMBER=2 +val SCE_ASM_STRING=3 +val SCE_ASM_OPERATOR=4 +val SCE_ASM_IDENTIFIER=5 +val SCE_ASM_CPUINSTRUCTION=6 +val SCE_ASM_MATHINSTRUCTION=7 +val SCE_ASM_REGISTER=8 +val SCE_ASM_DIRECTIVE=9 +val SCE_ASM_DIRECTIVEOPERAND=10 +# Lexical states for SCLEX_FORTRAN +lex Fortran=SCLEX_FORTRAN SCE_F_ +lex F77=SCLEX_F77 SCE_F_ +val SCE_F_DEFAULT=0 +val SCE_F_COMMENT=1 +val SCE_F_NUMBER=2 +val SCE_F_STRING1=3 +val SCE_F_STRING2=4 +val SCE_F_STRINGEOL=5 +val SCE_F_OPERATOR=6 +val SCE_F_IDENTIFIER=7 +val SCE_F_WORD=8 +val SCE_F_WORD2=9 +val SCE_F_WORD3=10 +val SCE_F_PREPROCESSOR=11 +val SCE_F_OPERATOR2=12 +val SCE_F_LABEL=13 +val SCE_F_CONTINUATION=14 + +# Events + +evt void StyleNeeded=2000(int position) +evt void CharAdded=2001(int ch) +evt void SavePointReached=2002(void) +evt void SavePointLeft=2003(void) +evt void ModifyAttemptRO=2004(void) +# GTK+ Specific to work around focus and accelerator problems: +evt void Key=2005(int ch, int modifiers) +evt void DoubleClick=2006(void) +evt void UpdateUI=2007(void) +evt void Modified=2008(int position, int modificationType, string text, int length, int linesAdded, int line, int foldLevelNow, int foldLevelPrev) +evt void MacroRecord=2009(int message, int wParam, int lParam) +evt void MarginClick=2010(int modifiers, int position, int margin) +evt void NeedShown=2011(int position, int length) +evt void Painted=2013(void) +evt void UserListSelection=2014(int listType, string text) +evt void URIDropped=2015(string text) +evt void DwellStart=2016(int position) +evt void DwellEnd=2017(int position) +evt void Zoom=2018(void) + +cat Deprecated + +# CARET_POLICY changed in 1.47 +fun void SetCaretPolicy=2369(int caretPolicy, int caretSlop) +val CARET_CENTER=0x02 +val CARET_XEVEN=0x08 +val CARET_XJUMPS=0x10 + +# The old name for SCN_UPDATEUI +val SCN_CHECKBRACE=2007 +evt void PosChanged=2012(int position) + diff --git a/vscript/languages/gm/src/gmd/include/ScintillaWidget.h b/vscript/languages/gm/src/gmd/include/ScintillaWidget.h new file mode 100644 index 00000000..765fd859 --- /dev/null +++ b/vscript/languages/gm/src/gmd/include/ScintillaWidget.h @@ -0,0 +1,55 @@ +// Scintilla source code edit control +/** @file ScintillaWidget.h + ** Definition of Scintilla widget for GTK+. + ** Only needed by GTK+ code but is harmless on other platforms. + **/ +// Copyright 1998-2001 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef SCINTILLAWIDGET_H +#define SCINTILLAWIDGET_H + +#if PLAT_GTK + +#ifdef __cplusplus +extern "C" { +#endif + +#define SCINTILLA(obj) GTK_CHECK_CAST (obj, scintilla_get_type (), ScintillaObject) +#define SCINTILLA_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, scintilla_get_type (), ScintillaClass) +#define IS_SCINTILLA(obj) GTK_CHECK_TYPE (obj, scintilla_get_type ()) + +typedef struct _ScintillaObject ScintillaObject; +typedef struct _ScintillaClass ScintillaClass; + +struct _ScintillaObject { + GtkContainer cont; + void *pscin; +}; + +struct _ScintillaClass { + GtkContainerClass parent_class; + + void (* command) (ScintillaObject *ttt); + void (* notify) (ScintillaObject *ttt); +}; + +guint scintilla_get_type (void); +GtkWidget* scintilla_new (void); +void scintilla_set_id (ScintillaObject *sci,int id); +sptr_t scintilla_send_message (ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam); +void scintilla_release_resources(void); + +#if GTK_MAJOR_VERSION < 2 +#define SCINTILLA_NOTIFY "notify" +#else +#define SCINTILLA_NOTIFY "sci-notify" +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/vscript/languages/gm/src/gmd/include/WindowAccessor.h b/vscript/languages/gm/src/gmd/include/WindowAccessor.h new file mode 100644 index 00000000..6c16b150 --- /dev/null +++ b/vscript/languages/gm/src/gmd/include/WindowAccessor.h @@ -0,0 +1,57 @@ +// Scintilla source code edit control +/** @file WindowAccessor.h + ** Implementation of BufferAccess and StylingAccess on a Scintilla + ** rapid easy access to contents of a Scintilla. + **/ +// Copyright 1998-2001 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +/** + */ +class WindowAccessor : public Accessor { + // Private so WindowAccessor objects can not be copied + WindowAccessor(const WindowAccessor &source) : Accessor(), props(source.props) {} + WindowAccessor &operator=(const WindowAccessor &) { return *this; } +protected: + WindowID id; + PropSet &props; + int lenDoc; + + char styleBuf[bufferSize]; + int validLen; + char chFlags; + char chWhile; + unsigned int startSeg; + + bool InternalIsLeadByte(char ch); + void Fill(int position); +public: + WindowAccessor(WindowID id_, PropSet &props_) : + Accessor(), id(id_), props(props_), + lenDoc(-1), validLen(0), chFlags(0), chWhile(0) { + } + ~WindowAccessor(); + bool Match(int pos, const char *s); + char StyleAt(int position); + int GetLine(int position); + int LineStart(int line); + int LevelAt(int line); + int Length(); + void Flush(); + int GetLineState(int line); + int SetLineState(int line, int state); + int GetPropertyInt(const char *key, int defaultValue=0) { + return props.GetInt(key, defaultValue); + } + char *GetProperties() { + return props.ToString(); + } + + void StartAt(unsigned int start, char chMask=31); + void SetFlags(char chFlags_, char chWhile_) {chFlags = chFlags_; chWhile = chWhile_; }; + unsigned int GetStartSegment() { return startSeg; } + void StartSegment(unsigned int pos); + void ColourTo(unsigned int pos, int chAttr); + void SetLevel(int line, int level); + int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0); +}; diff --git a/vscript/languages/gm/src/gmd/res/Toolbar.bmp b/vscript/languages/gm/src/gmd/res/Toolbar.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0bff4fcf82f539a4c9da4298aade8ac29319f486 GIT binary patch literal 1198 zcmd6mJ8r`;42D&pgOU!tMvu_Bd#}@3qXG!9M+@kXIYZIii$@vIfo!0F`%zMCBaQpm z%7`MV$1nb*^Yr|7tCGAhKcF>wkKU-f@mTg*x)7rjLm86|GcIaW*L7@6X{c!u59KFI zO!nUh3F|*4vvC}P!pZ=aHFLz5u!8j9g4j{4waVA5e-U%nw(o2(07^Ew+ByjE)QkxD*tk9yNcw&$<@=$^F|a2Vky8#UOGrp_wj1A}E#GswO!t@TnP0(}jncEb NcE0<6h4sN-`Je7HPDua& literal 0 HcmV?d00001 diff --git a/vscript/languages/gm/src/gmd/res/bangbang.wav b/vscript/languages/gm/src/gmd/res/bangbang.wav new file mode 100644 index 0000000000000000000000000000000000000000..84cf9e1df0ef548bb6daccacbdf763494fc2c78c GIT binary patch literal 24120 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 PkaNE{wR~2C$NfnjhSXWT literal 0 HcmV?d00001 diff --git a/vscript/languages/gm/src/gmd/res/gmd.rc2 b/vscript/languages/gm/src/gmd/res/gmd.rc2 new file mode 100644 index 00000000..d412e990 --- /dev/null +++ b/vscript/languages/gm/src/gmd/res/gmd.rc2 @@ -0,0 +1,13 @@ +// +// GMD.RC2 - resources Microsoft Visual C++ does not edit directly +// + +#ifdef APSTUDIO_INVOKED + #error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// Add manually edited resources here... + +///////////////////////////////////////////////////////////////////////////// diff --git a/vscript/languages/gm/src/gme/NetClient.cpp b/vscript/languages/gm/src/gme/NetClient.cpp new file mode 100644 index 00000000..a75dbfb9 --- /dev/null +++ b/vscript/languages/gm/src/gme/NetClient.cpp @@ -0,0 +1,351 @@ +// See Copyright Notice in gmMachine.h + +#include "NetClient.h" +#include +#include +#include +#include +#include +#include +#include + +#undef SendMessage // stupid windows + +struct nPacket +{ + int id; // id == 0x4fe27d9a + int len; +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// QUEUE +// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +struct nQueueNode +{ + char * m_buffer; + int m_len; + nQueueNode * m_next; +}; + +class nQueue +{ +public: + nQueue() + { + m_queue = NULL; + m_lastDeQueue = NULL; + m_mutex = CreateMutex(NULL, FALSE, NULL); + } + + ~nQueue() + { + WaitForSingleObject(m_mutex, INFINITE); + + int a; + while(DeQueue(a)); + DeQueue(a); + + ReleaseMutex(m_mutex); + + // destroy mutex... todo + } + + bool EnQueue(const char * a_buffer, int a_len) + { + WaitForSingleObject(m_mutex, INFINITE); + + nQueueNode * node = new nQueueNode; + node->m_len = a_len; + node->m_buffer = new char[a_len]; + memcpy(node->m_buffer, a_buffer, a_len); + node->m_next = NULL; + + // add to end of list + nQueueNode ** n = &m_queue; + while(*n) n = &(*n)->m_next; + *n = node; + + ReleaseMutex(m_mutex); + + return true; + } + + const char * DeQueue(int &a_len) + { + const char * ret = NULL; + + WaitForSingleObject(m_mutex, INFINITE); + + if(m_lastDeQueue) + { + delete[] m_lastDeQueue->m_buffer; + delete m_lastDeQueue; + m_lastDeQueue = NULL; + } + + if(m_queue) + { + m_lastDeQueue = m_queue; + m_queue = m_queue->m_next; + a_len = m_lastDeQueue->m_len; + ret = m_lastDeQueue->m_buffer; + } + + ReleaseMutex(m_mutex); + + return ret; + } + + bool IsEmpty() { return (m_queue == NULL); } + +private: + + HANDLE m_mutex; + + nQueueNode * m_lastDeQueue; + nQueueNode * m_queue; +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// CLIENT +// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +struct nClientData +{ + SOCKET client; + nQueue messages; + CRITICAL_SECTION criticalSection; + bool threadAlive; +}; + + + +nClient::nClient() +{ + nClientData * cd = new nClientData; + cd->threadAlive = false; + cd->client = INVALID_SOCKET; + InitializeCriticalSection(&cd->criticalSection); + m_data = cd; +} + + + +nClient::~nClient() +{ + Close(); + nClientData * cd = (nClientData *) m_data; + DeleteCriticalSection(&cd->criticalSection); + delete cd; +} + + + +void nClient::Close() +{ + nClientData * cd = (nClientData *) m_data; + EnterCriticalSection(&cd->criticalSection); + + if(cd->client != INVALID_SOCKET) + { + closesocket(cd->client); + cd->client = INVALID_SOCKET; + } + + LeaveCriticalSection(&cd->criticalSection); + + // wait for the thread to die. + while(cd->threadAlive) + { + Sleep(0); + } + + WSACleanup(); +} + + + +bool nClient::IsConnected() +{ + bool result = false; + nClientData * cd = (nClientData *) m_data; + EnterCriticalSection(&cd->criticalSection); + if(cd->client != INVALID_SOCKET) + { + result = true; + } + LeaveCriticalSection(&cd->criticalSection); + return result; +} + + + +bool nClient::SendMessage(const char * a_buffer, int a_len) +{ + bool res = false; + nClientData * cd = (nClientData *) m_data; + nPacket packet; + packet.id = 0x4fe27d9a; + packet.len = a_len; + + EnterCriticalSection(&cd->criticalSection); + if(cd->client != INVALID_SOCKET) + { + send(cd->client, (const char *) &packet, sizeof(nPacket), 0); + send(cd->client, (const char *) a_buffer, a_len, 0); + res = true; + } + LeaveCriticalSection(&cd->criticalSection); + return res; +} + + + +const char * nClient::PumpMessage(int &a_len) +{ + nClientData * cd = (nClientData *) m_data; + const char * buffer = cd->messages.DeQueue(a_len); + return buffer; +} + + + +void nClientThread(void * param) +{ + nClientData * cd = (nClientData *) param; + EnterCriticalSection(&cd->criticalSection); + cd->threadAlive = true; + SOCKET client = cd->client; + LeaveCriticalSection(&cd->criticalSection); + + char * dbuffer = NULL; + char buffer[4096]; + char * sbp; + int state = 0; // 0 searching for packet, 1 getting message + int need = sizeof(nPacket); + + // packet header + nPacket packet; + char * dbp = (char *) &packet; + + // packet data + int dbufferSize = 0, n; + + // read loop + for(;;) + { + // read + n = recv(client, buffer, 4096, 0); + if(n == SOCKET_ERROR || n == 0) break; + sbp = buffer; + + // consume + while(n > 0) + { + int have = (n > need) ? need : n; + need -= have; + n -= have; + memcpy(dbp, sbp, have); + sbp += have; + dbp += have; + + // can we change state? + if(need == 0) + { + if(state == 0) + { + if(packet.id != 0x4fe27d9a) goto terror; + state = 1; + need = packet.len; + + // allocate the dbuffer + if(need > dbufferSize) + { + if(dbuffer) { delete[] dbuffer; } + dbufferSize = need + 512; + dbuffer = new char[dbufferSize]; + } + dbp = dbuffer; + } + else if(state == 1) + { + cd->messages.EnQueue(dbuffer, packet.len); + dbp = (char *) &packet; + need = sizeof(nPacket); + state = 0; + } + } + } + } + +terror: + + if(dbuffer) { delete[] dbuffer; } + + EnterCriticalSection(&cd->criticalSection); + cd->threadAlive = false; + LeaveCriticalSection(&cd->criticalSection); + + _endthread(); +} + + + +bool nClient::Connect(const char * a_server, short a_port) +{ + WSADATA wsaData; + struct hostent *hp; + unsigned int addr; + struct sockaddr_in server; + + int wsaret=WSAStartup(0x101,&wsaData); + if(wsaret) + return false; + + SOCKET conn; + + conn = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); + if(conn==INVALID_SOCKET) + return false; + + addr=inet_addr(a_server); + hp=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET); + + if(hp==NULL) + { + closesocket(conn); + return false; + } + + server.sin_addr.s_addr=*((unsigned long*)hp->h_addr); + server.sin_family=AF_INET; + server.sin_port=htons((u_short) a_port); + + if(connect(conn,(struct sockaddr*)&server,sizeof(server))) + { + closesocket(conn); + return false; + } + + nClientData * cd = (nClientData *) m_data; + EnterCriticalSection(&cd->criticalSection); + cd->client = conn; + LeaveCriticalSection(&cd->criticalSection); + + _beginthread(nClientThread, 0, cd); + Sleep(0); + + return true; +} + diff --git a/vscript/languages/gm/src/gme/NetClient.h b/vscript/languages/gm/src/gme/NetClient.h new file mode 100644 index 00000000..90a1bcee --- /dev/null +++ b/vscript/languages/gm/src/gme/NetClient.h @@ -0,0 +1,30 @@ +#ifndef _NETCLIENT_H_ +#define _NETCLIENT_H_ + +// See Copyright Notice in gmMachine.h + +#undef SendMessage // windows clash + +// +// nClient +// +class nClient +{ +public: + nClient(); + ~nClient(); + + bool Connect(const char * a_server, short a_port); + void Close(); + bool IsConnected(); + + bool SendMessage(const char * a_buffer, int a_len); + const char * PumpMessage(int &a_len); + +private: + + void * m_data; +}; + + +#endif //_NETCLIENT_H_ diff --git a/vscript/languages/gm/src/gme/gme.cpp b/vscript/languages/gm/src/gme/gme.cpp new file mode 100644 index 00000000..44b00eec --- /dev/null +++ b/vscript/languages/gm/src/gme/gme.cpp @@ -0,0 +1,493 @@ +// See Copyright Notice in gmMachine.h + +#include "gmmachine.h" +#include "gmthread.h" +#include "gmdebug.h" +#include "gmstreambuffer.h" + +// libs + +#include "gmmathlib.h" +#include "gmstringlib.h" +#include "gmarraylib.h" +#include "gmsystemlib.h" +#include "gmvector3lib.h" + +#include "timer.h" +#include "NetClient.h" +#include + +#define GM_DEBUGGER_PORT 49001 + +// +// globals +// + +#undef GetObject + +gmMachine * g_machine = NULL; +Timer g_timer, g_timer1; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// gmMachine exception handler +// + +bool GM_CDECL gmeMachineCallback(gmMachine * a_machine, gmMachineCommand a_command, const void * a_context) +{ + if(a_command == MC_THREAD_EXCEPTION) + { + bool first = true; + const char * entry; + while((entry = a_machine->GetLog().GetEntry(first))) + { + fprintf(stderr, "%s", entry); + } + a_machine->GetLog().Reset(); + } + return false; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// gmeLib +// + +static POINT s_screenSize; +static HANDLE s_hConsole; + +static void gmeInit(gmMachine * a_machine) +{ + CONSOLE_SCREEN_BUFFER_INFO csbi; + DWORD dwConSize; + + s_hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + GetConsoleScreenBufferInfo(s_hConsole, &csbi); + dwConSize = csbi.dwSize.X * csbi.dwSize.Y; + s_screenSize.x = csbi.dwSize.X; + s_screenSize.y = csbi.dwSize.Y; + + gmTableObject * table = a_machine->AllocTableObject(); + a_machine->GetGlobals()->Set(a_machine, "CA", gmVariable(GM_TABLE, table->GetRef())); + + table->Set(a_machine, "F_BLUE", gmVariable(GM_INT, FOREGROUND_BLUE)); + table->Set(a_machine, "F_GREEN", gmVariable(GM_INT, FOREGROUND_GREEN)); + table->Set(a_machine, "F_RED", gmVariable(GM_INT, FOREGROUND_RED)); + table->Set(a_machine, "F_INTENSITY", gmVariable(GM_INT, FOREGROUND_INTENSITY)); + table->Set(a_machine, "B_BLUE", gmVariable(GM_INT, BACKGROUND_BLUE)); + table->Set(a_machine, "B_GREEN", gmVariable(GM_INT, BACKGROUND_GREEN)); + table->Set(a_machine, "B_RED", gmVariable(GM_INT, BACKGROUND_RED)); + table->Set(a_machine, "B_INTENSITY", gmVariable(GM_INT, BACKGROUND_INTENSITY)); + + table->Set(a_machine, "LEADING_BYTE", gmVariable(GM_INT, COMMON_LVB_LEADING_BYTE)); + table->Set(a_machine, "TRAILING_BYTE", gmVariable(GM_INT, COMMON_LVB_TRAILING_BYTE)); + table->Set(a_machine, "GRID_HORIZONTAL", gmVariable(GM_INT, COMMON_LVB_GRID_HORIZONTAL)); + table->Set(a_machine, "GRID_LVERTICAL", gmVariable(GM_INT, COMMON_LVB_GRID_LVERTICAL)); + table->Set(a_machine, "GRID_RVERTICAL", gmVariable(GM_INT, COMMON_LVB_GRID_RVERTICAL)); + table->Set(a_machine, "REVERSE_VIDEO", gmVariable(GM_INT, COMMON_LVB_REVERSE_VIDEO)); + table->Set(a_machine, "UNDERSCORE", gmVariable(GM_INT, COMMON_LVB_UNDERSCORE)); +} + +static int GM_CDECL gmfCXY(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(2); + GM_CHECK_INT_PARAM(x, 0); + GM_CHECK_INT_PARAM(y, 1); + COORD point; + if(x < 0) x = 0; + if(y < 0) y = 0; + if(x > s_screenSize.x) x = s_screenSize.x; + if(y > s_screenSize.y) y = s_screenSize.y; + point.X = (short) x; point.Y = (short) y; + SetConsoleCursorPosition(s_hConsole, point); + return GM_OK; +} + +static int GM_CDECL gmfCXYTEXT(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(3); + GM_CHECK_INT_PARAM(x, 0); + GM_CHECK_INT_PARAM(y, 1); + GM_CHECK_STRING_PARAM(str, 2); + COORD point; + if(x < 0) x = 0; + if(y < 0) y = 0; + if(x > s_screenSize.x) x = s_screenSize.x; + if(y > s_screenSize.y) y = s_screenSize.y; + point.X = (short) x; point.Y = (short) y; + SetConsoleCursorPosition(s_hConsole, point); + printf("%s", str); + return GM_OK; +} + +static int GM_CDECL gmfCCLR(gmThread * a_thread) +{ + COORD coordScreen = { 0, 0 }; + DWORD cCharsWritten; + CONSOLE_SCREEN_BUFFER_INFO csbi; + DWORD dwConSize; + GetConsoleScreenBufferInfo(s_hConsole, &csbi); + dwConSize = csbi.dwSize.X * csbi.dwSize.Y; + FillConsoleOutputCharacter(s_hConsole, TEXT(' '), dwConSize, coordScreen, &cCharsWritten); + GetConsoleScreenBufferInfo(s_hConsole, &csbi); + FillConsoleOutputAttribute(s_hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten); + SetConsoleCursorPosition(s_hConsole, coordScreen); + return GM_OK; +} + +static int GM_CDECL gmfCURSOR(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(2); + GM_CHECK_INT_PARAM(state, 0); + GM_CHECK_INT_PARAM(size, 1); + CONSOLE_CURSOR_INFO info; + if(size < 1) size = 1; if(size > 100) size = 100; + info.bVisible = state; + info.dwSize = size; + SetConsoleCursorInfo(s_hConsole, &info); + return GM_OK; +} + +static int GM_CDECL gmfCATTRIB(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_INT_PARAM(param, 0); + SetConsoleTextAttribute(s_hConsole, (short) param); + return GM_OK; +} + +int GM_CDECL gmfTimer(gmThread * a_thread) +{ + a_thread->PushFloat(g_timer1.Tick()); + return GM_OK; +} + +int GM_CDECL gmfIsPressed(gmThread * a_thread) +{ + GM_CHECK_NUM_PARAMS(1); + GM_CHECK_INT_PARAM(key, 0); + a_thread->PushInt(GetAsyncKeyState(key)); + return GM_OK; +} + +static gmFunctionEntry s_gmeLib[] = +{ + {"TICK", gmfTimer}, + {"CLS", gmfCCLR}, + {"XY", gmfCXY}, + {"XYTEXT", gmfCXYTEXT}, + {"CURSOR", gmfCURSOR}, + {"CATTRIB", gmfCATTRIB}, + {"ISPRESSED", gmfIsPressed}, +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// debug callbacks +// + +#if GMDEBUG_SUPPORT + + +void SendDebuggerMessage(gmDebugSession * a_session, const void * a_command, int a_len) +{ + nClient * client = (nClient *) a_session->m_user; + client->SendMessage((const char *) a_command, a_len); +} + + +const void * PumpDebuggerMessage(gmDebugSession * a_session, int &a_len) +{ + nClient * client = (nClient *) a_session->m_user; + return client->PumpMessage(a_len); +} + + +#endif + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// gmeSetEnv +// +void GM_CDECL gmdSetEnv(gmMachine * a_machine, const char * a_env, gmTableObject * a_vars) +{ + char * t = (char *) alloca(strlen(a_env) + 1); + strcpy(t, a_env); + char * r = t; + while(*r != '\0' && *r != '=') ++r; + if(*r == '=') + { + *r = '\0'; + ++r; + } + else r = ""; + + a_vars->Set(a_machine, gmVariable(GM_STRING, a_machine->AllocStringObject(t)->GetRef()), + gmVariable(GM_STRING, a_machine->AllocStringObject(r)->GetRef())); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// main +// +void main(int argc, char * argv[], char * envp[]) +{ + bool debug = false, envvars = false, keypress = false, keypressOnError = false; + char * filename = ""; + char * ip = "127.0.0.1"; // localhost + int port = GM_DEBUGGER_PORT; + char * script = NULL; +#if GMDEBUG_SUPPORT + nClient client; + gmDebugSession session; + + session.m_sendMessage = SendDebuggerMessage; + session.m_pumpMessage = PumpDebuggerMessage; + session.m_user = &client; +#endif + + // + // process command line arguments + // + + if(argc <= 1) + { +#if GMDEBUG_SUPPORT + fprintf(stderr, "args: filename [-d for debug] [-e for env vars] [-ke for keypress on error] [-k for keypress on exit]"GM_NL); +#else //GMDEBUG_SUPPORT + fprintf(stderr, "args: filename [-e for env vars] [-ke for keypress on error] [-k for keypress on exit]"GM_NL); +#endif //GMDEBUG_SUPPORT + + return; + } + + filename = argv[1]; + int argstart = 2; + + int i; + for(i = 2; i < argc; ++i) + { + if(argv[i][0] == '-' && argv[i][1] == 'd') + { + debug = true; + // read the ip + if(argv[i][2]) + { + ip = argv[i] + 2; + } + argstart = i+1; + } + else if(argv[i][0] == '-' && argv[i][1] == 'e') + { + envvars = true; + argstart = i+1; + } + else if(argv[i][0] == '-' && argv[i][1] == 'k' && argv[i][2] == 'e') + { + keypressOnError = true; + argstart = i+1; + } + else if(argv[i][0] == '-' && argv[i][1] == 'k') + { + keypress = true; + argstart = i+1; + } + } + + // + // load the file + // + + FILE * fp = fopen(filename, "rb"); + if(fp) + { + fseek(fp, 0, SEEK_END); + int size = ftell(fp); + rewind(fp); + script = new char[size + 1]; + fread(script, 1, size, fp); + script[size] = 0; + fclose(fp); + } + if(script == NULL) + { + fprintf(stderr, "could not open file %s"GM_NL, filename); + if(keypress || keypressOnError) + { + getchar(); + } + return; + } + + // + // start the machine + // + + gmMachine::s_machineCallback = gmeMachineCallback; + + g_machine = new gmMachine; + g_machine->SetDesiredByteMemoryUsageHard(128*1024); + g_machine->SetDesiredByteMemoryUsageSoft(g_machine->GetDesiredByteMemoryUsageHard() * 9 / 10); + g_machine->SetAutoMemoryUsage(true); + g_machine->SetDebugMode(debug); + + // + // bind the process arguments to table "arg" + // + + gmTableObject * argTable = g_machine->AllocTableObject(); + g_machine->GetGlobals()->Set(g_machine, "arg", + gmVariable(GM_TABLE, argTable->GetRef())); + for(i = argstart; i < argc; ++i) + { + argTable->Set(g_machine, gmVariable(GM_INT, i - argstart), gmVariable(GM_STRING, g_machine->AllocStringObject(argv[i])->GetRef())); + } + + // + // bind the process arguments to table "env" + // + + if(envvars) + { + gmTableObject * envTable = g_machine->AllocTableObject(); + g_machine->GetGlobals()->Set(g_machine, "env", gmVariable(GM_TABLE, envTable->GetRef())); + for(i = argstart; envp[i]; ++i) + { + gmdSetEnv(g_machine, envp[i], envTable); + } + } + + // + // bind the default libs + // + + gmBindMathLib(g_machine); + gmBindStringLib(g_machine); + gmBindArrayLib(g_machine); + gmBindSystemLib(g_machine); + gmBindVector3Lib(g_machine); + gmeInit(g_machine); + + +#if GMDEBUG_SUPPORT + gmBindDebugLib(g_machine); +#endif + g_machine->RegisterLibrary(s_gmeLib, sizeof(s_gmeLib) / sizeof(s_gmeLib[0])); + + // + // compile the script + // + + + int errors = g_machine->ExecuteString(script, NULL, false, filename); + if(errors) + { + bool first = true; + const char * message; + while((message = g_machine->GetLog().GetEntry(first))) + { + fprintf(stderr, "%s"GM_NL, message); + } + g_machine->GetLog().Reset(); + + delete g_machine; + delete[] script; + + if(keypress || keypressOnError) + { + getchar(); + } + + return; + } + + // + // start the remote debug thread, which will connect to the debugger if it exists + // + if(debug && port) + { +#if GMDEBUG_SUPPORT + if(client.Connect(ip, ((short) port))) + { + session.Open(g_machine); + fprintf(stderr, "debug session opened"GM_NL); + } +#endif + } + + // + // execute loop + // + + g_timer.Init(); + g_timer1.Init(); + + float timeAcc = 0.0f; + gmuint32 idt = 0; + while(g_machine->Execute(idt)) + { + // + // update time + // + timeAcc += (g_timer.Tick() * 1000.0f); + if(timeAcc > 1.0f) + { + idt = (gmuint32) floorf(timeAcc); + timeAcc -= (float) idt; + } + else idt = 0; + + // + // update remote debug status + // + + if(debug && port) + { +#if GMDEBUG_SUPPORT + if(client.IsConnected()) + { + session.Update(); + } + else + { + session.Close(); + } +#endif + } +#ifdef WIN32 + // Just give the OS a chance to update and run more smoothly. + Sleep(0); +#endif //WIN32 + } + + // + // clean up the debug comms thread + // + + if(debug && port) + { +#if GMDEBUG_SUPPORT + session.Close(); +#endif + } + +#if GMDEBUG_SUPPORT + client.Close(); +#endif + delete[] script; + delete g_machine; + + _gmDumpLeaks(); + + if(keypress) + { + getchar(); + } +}; + diff --git a/vscript/languages/gm/src/gme/gme.dsp b/vscript/languages/gm/src/gme/gme.dsp new file mode 100644 index 00000000..bbd26774 --- /dev/null +++ b/vscript/languages/gm/src/gme/gme.dsp @@ -0,0 +1,438 @@ +# Microsoft Developer Studio Project File - Name="gme" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=gme - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gme.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gme.mak" CFG="gme - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gme - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "gme - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "Perforce Project" +# PROP Scc_LocalPath ".." +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gme - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\gm" /I "..\binds" /I "..\platform\win32msvc" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0xc09 /d "NDEBUG" +# ADD RSC /l 0xc09 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /out:"..\..\bin\gme.exe" + +!ELSEIF "$(CFG)" == "gme - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\gm" /I "..\binds" /I "..\platform\win32msvc" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0xc09 /d "_DEBUG" +# ADD RSC /l 0xc09 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /out:"..\..\bin\gme.debug.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "gme - Win32 Release" +# Name "gme - Win32 Debug" +# Begin Group "gm" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\gm\gmArraySimple.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmArraySimple.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmByteCode.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmByteCode.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmByteCodeGen.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmByteCodeGen.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmCodeGen.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmCodeGen.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmCodeGenHooks.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmCodeGenHooks.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmCodeTree.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmCodeTree.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmConfig.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmCrc.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmCrc.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmDebug.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmDebug.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmFunctionObject.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmFunctionObject.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmHash.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmHash.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmIncGC.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmIncGC.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmIterator.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmLibHooks.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmLibHooks.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmListDouble.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmListDouble.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmLog.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmLog.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmMachine.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmMachine.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmMachineLib.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmMachineLib.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmMem.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmMem.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmMemChain.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmMemChain.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmMemFixed.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmMemFixed.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmMemFixedSet.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmMemFixedSet.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmOperators.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmOperators.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmParser.cpp.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmScanner.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmScanner.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmStream.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmStreamBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmStreamBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmStringObject.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmStringObject.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmTableObject.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmTableObject.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmThread.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmThread.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmUserObject.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmUserObject.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmUtil.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmUtil.h +# End Source File +# Begin Source File + +SOURCE=..\gm\gmVariable.cpp +# End Source File +# Begin Source File + +SOURCE=..\gm\gmVariable.h +# End Source File +# End Group +# Begin Group "binds" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\binds\gmArrayLib.cpp +# End Source File +# Begin Source File + +SOURCE=..\binds\gmArrayLib.h +# End Source File +# Begin Source File + +SOURCE=..\binds\gmCall.cpp +# End Source File +# Begin Source File + +SOURCE=..\binds\gmCall.h +# End Source File +# Begin Source File + +SOURCE=..\binds\gmHelpers.cpp +# End Source File +# Begin Source File + +SOURCE=..\binds\gmHelpers.h +# End Source File +# Begin Source File + +SOURCE=..\binds\gmMathLib.cpp +# End Source File +# Begin Source File + +SOURCE=..\binds\gmMathLib.h +# End Source File +# Begin Source File + +SOURCE=..\binds\gmStringLib.cpp +# End Source File +# Begin Source File + +SOURCE=..\binds\gmStringLib.h +# End Source File +# Begin Source File + +SOURCE=..\binds\gmSystemLib.cpp +# End Source File +# Begin Source File + +SOURCE=..\binds\gmSystemLib.h +# End Source File +# Begin Source File + +SOURCE=..\binds\gmVector3Lib.cpp +# End Source File +# Begin Source File + +SOURCE=..\binds\gmVector3Lib.h +# End Source File +# End Group +# Begin Group "gme" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\gme.cpp +# End Source File +# Begin Source File + +SOURCE=.\NetClient.cpp +# End Source File +# Begin Source File + +SOURCE=.\NetClient.h +# End Source File +# Begin Source File + +SOURCE=.\timer.cpp +# End Source File +# Begin Source File + +SOURCE=.\timer.h +# End Source File +# End Group +# Begin Group "win32" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\platform\win32msvc\gmConfig_p.h +# End Source File +# End Group +# End Target +# End Project diff --git a/vscript/languages/gm/src/gme/gme.dsw b/vscript/languages/gm/src/gme/gme.dsw new file mode 100644 index 00000000..65f8b4f9 --- /dev/null +++ b/vscript/languages/gm/src/gme/gme.dsw @@ -0,0 +1,33 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "gme"=.\gme.dsp - Package Owner=<4> + +Package=<5> +{{{ + begin source code control + Perforce Project + .. + end source code control +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/vscript/languages/gm/src/gme/gme.vcproj b/vscript/languages/gm/src/gme/gme.vcproj new file mode 100644 index 00000000..9dda4fe6 --- /dev/null +++ b/vscript/languages/gm/src/gme/gme.vcproj @@ -0,0 +1,1314 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/gm/src/gme/timer.cpp b/vscript/languages/gm/src/gme/timer.cpp new file mode 100644 index 00000000..f36561e1 --- /dev/null +++ b/vscript/languages/gm/src/gme/timer.cpp @@ -0,0 +1,30 @@ +// See Copyright Notice in gmMachine.h +#include "timer.h" + +bool Timer::Init() +{ + resetTimer = true; + dTime = 0.0f; + bool result = QueryPerformanceFrequency(&timerFrequency) > 0; + oof = 1.0f / ((float)timerFrequency.QuadPart); + + return result; +} + +float Timer::Tick() +{ + QueryPerformanceCounter(&thisTime); + + if (resetTimer) + { + dTime = 0; + resetTimer = false; + } + else + { + dTime = ((float)(thisTime.QuadPart - lastTime.QuadPart)) * oof; + } + lastTime = thisTime; + + return dTime; +} diff --git a/vscript/languages/gm/src/gme/timer.h b/vscript/languages/gm/src/gme/timer.h new file mode 100644 index 00000000..dba6d938 --- /dev/null +++ b/vscript/languages/gm/src/gme/timer.h @@ -0,0 +1,27 @@ +// See Copyright Notice in gmMachine.h +#ifndef _timer_h +#define _timer_h + +#include + +class Timer +{ +public: + + Timer() : resetTimer(true), dTime(0.0f) {} + ~Timer() {} + + bool Init(); + void Reset() { resetTimer = true; } + + float Tick(); + float GetDelta() { return dTime; } + +private: + + LARGE_INTEGER timerFrequency, lastTime, thisTime; + float dTime, oof; + bool resetTimer; +}; + +#endif //_timer_h diff --git a/vscript/languages/gm/src/gml/gml.dsp b/vscript/languages/gm/src/gml/gml.dsp new file mode 100644 index 00000000..477d91a7 --- /dev/null +++ b/vscript/languages/gm/src/gml/gml.dsp @@ -0,0 +1,90 @@ +# Microsoft Developer Studio Project File - Name="gml" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=gml - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gml.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gml.mak" CFG="gml - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gml - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "gml - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "gml" +# PROP Scc_LocalPath "." +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gml - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "..\gm" /I "..\platform\win32msvc" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"..\..\bin\gml.exe" + +!ELSEIF "$(CFG)" == "gml - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\gm" /I "..\platform\win32msvc" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"..\..\bin\gml.debug.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "gml - Win32 Release" +# Name "gml - Win32 Debug" +# Begin Source File + +SOURCE=.\main.cpp +# End Source File +# End Target +# End Project diff --git a/vscript/languages/gm/src/gml/gml.dsw b/vscript/languages/gm/src/gml/gml.dsw new file mode 100644 index 00000000..dda6a3ff --- /dev/null +++ b/vscript/languages/gm/src/gml/gml.dsw @@ -0,0 +1,33 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "gml"=.\gml.dsp - Package Owner=<4> + +Package=<5> +{{{ + begin source code control + Perforce Project + . + end source code control +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/vscript/languages/gm/src/gml/gml.vcproj b/vscript/languages/gm/src/gml/gml.vcproj new file mode 100644 index 00000000..9f613f8b --- /dev/null +++ b/vscript/languages/gm/src/gml/gml.vcproj @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/gm/src/gml/main.cpp b/vscript/languages/gm/src/gml/main.cpp new file mode 100644 index 00000000..6a8c3961 --- /dev/null +++ b/vscript/languages/gm/src/gml/main.cpp @@ -0,0 +1,377 @@ +// See Copyright Notice in gmMachine.h + +#include +#include + +#pragma pack( push, 1 ) + +#include "gmConfig.h" +#include "gmByteCode.h" + +#define ID_func GM_MAKE_ID32('f','u','n','c') +#define ID_gml0 GM_MAKE_ID32('g','m','l','0') + + +struct gmlHeader +{ + gmuint32 id; + gmuint32 flags; + gmuint32 stOffset; + gmuint32 scOffset; + gmuint32 fnOffset; +}; + +struct gmlStrings +{ + gmuint32 size; +}; + +struct gmlLineInfo +{ + gmuint32 byteCodeAddress; + gmuint32 lineNumber; +}; + +struct gmlSource +{ + gmuint32 size; + gmuint32 flags; +}; + +struct gmlFunction +{ + gmuint32 func; + gmuint32 id; + gmuint32 flags; + gmuint32 numParams; + gmuint32 numLocals; + gmuint32 maxStackSize; + gmuint32 byteCodeLen; +}; + + +#pragma pack( pop ) + + +static void PrintByteCode(FILE * a_fp, const void * a_byteCode, int a_byteCodeLength, const char * symbols) +{ + union + { + const gmuint8 * instruction; + const gmuint32 * instruction32; + }; + + instruction = (const gmuint8 *) a_byteCode; + + const gmuint8 * end = instruction + a_byteCodeLength; + const gmuint8 * start = instruction; + const char * cp; + bool opiptr, opf32, opisymbol; + + while(instruction < end) + { + opiptr = false; + opf32 = false; + opisymbol = false; + + int addr = instruction - start; + + switch(*instruction32) + { + case BC_NOP : cp = "nop"; break; + case BC_LINE : cp = "line"; break; + + case BC_GETDOT : cp = "get dot"; opiptr = true; break; + case BC_SETDOT : cp = "set dot"; opiptr = true; break; + case BC_GETIND : cp = "get index"; break; + case BC_SETIND : cp = "set index"; break; + + case BC_BRA : cp = "bra"; opiptr = true; break; + case BC_BRZ : cp = "brz"; opiptr = true; break; + case BC_BRNZ : cp = "brnz"; opiptr = true; break; + case BC_BRZK : cp = "brzk"; opiptr = true; break; + case BC_BRNZK : cp = "brnzk"; opiptr = true; break; + case BC_CALL : cp = "call"; opiptr = true; break; + case BC_RET : cp = "ret"; break; + case BC_RETV : cp = "retv"; break; + case BC_FOREACH : cp = "foreach"; opiptr = true; break; + + case BC_POP : cp = "pop"; break; + case BC_POP2 : cp = "pop2"; break; + case BC_DUP : cp = "dup"; break; + case BC_DUP2 : cp = "dup2"; break; + case BC_SWAP : cp = "swap"; break; + case BC_PUSHNULL : cp = "push null"; break; + case BC_PUSHINT : cp = "push int"; opiptr = true; break; + case BC_PUSHINT0 : cp = "push int 0"; break; + case BC_PUSHINT1 : cp = "push int 1"; break; + case BC_PUSHFP : cp = "push fp"; opf32 = true; break; + case BC_PUSHSTR : cp = "push str"; opiptr = true; break; + case BC_PUSHTBL : cp = "push tbl"; break; + case BC_PUSHFN : cp = "push fn"; opiptr = true; break; + case BC_PUSHTHIS : cp = "push this"; break; + + case BC_GETLOCAL : cp = "get local"; opiptr = true; break; + case BC_SETLOCAL : cp = "set local"; opiptr = true; break; + case BC_GETGLOBAL : cp = "get global"; opiptr = true; break; + case BC_SETGLOBAL : cp = "set global"; opiptr = true; break; + case BC_GETTHIS : cp = "get this"; opiptr = true; break; + case BC_SETTHIS : cp = "set this"; opiptr = true; break; + + case BC_OP_ADD : cp = "add"; break; + case BC_OP_SUB : cp = "sub"; break; + case BC_OP_MUL : cp = "mul"; break; + case BC_OP_DIV : cp = "div"; break; + case BC_OP_REM : cp = "rem"; break; + //case BC_OP_INC : cp = "inc"; break; + //case BC_OP_DEC : cp = "dec"; break; + + case BC_BIT_OR : cp = "bor"; break; + case BC_BIT_XOR : cp = "bxor"; break; + case BC_BIT_AND : cp = "band"; break; + case BC_BIT_INV : cp = "binv"; break; + case BC_BIT_SHL : cp = "bshl"; break; + case BC_BIT_SHR : cp = "bshr"; break; + + case BC_OP_NEG : cp = "neg"; break; + case BC_OP_POS : cp = "pos"; break; + case BC_OP_NOT : cp = "not"; break; + + case BC_OP_LT : cp = "lt"; break; + case BC_OP_GT : cp = "gt"; break; + case BC_OP_LTE : cp = "lte"; break; + case BC_OP_GTE : cp = "gte"; break; + case BC_OP_EQ : cp = "eq"; break; + case BC_OP_NEQ : cp = "neq"; break; + + default : cp = "ERROR"; break; + } + + ++instruction32; + + if(opf32) + { + float fval = *((float *) instruction); + instruction += sizeof(gmint32); + fprintf(a_fp, " %04d %s %f"GM_NL, addr, cp, fval); + } + else if (opiptr) + { + gmptr ival = *((gmptr *) instruction); + instruction += sizeof(gmptr); + fprintf(a_fp, " %04d %s %d"GM_NL, addr, cp, ival); + } + else + { + fprintf(a_fp, " %04d %s"GM_NL, addr, cp); + } + } +} + + +void main(int argc, const char * argv[]) +{ + gmlHeader header; + gmlStrings strings; + gmlSource source; + gmlFunction function; + FILE * fp = NULL; + char * stringTable = NULL; + char * sourceCode = NULL; + bool error = true; + unsigned int i, j; + gmuint32 numFunctions = 0; + bool debug = false; + + // process command line arguments + if(argc < 2) + { + printf("Usage, %s where filename is a gmlib file you wish to view\n", argv[0]); + return; + } + + const char * libfile = argv[1]; + fp = fopen(libfile, "rb"); + if(fp == NULL) + { + printf("Could not open file %s\n", libfile); + return; + } + + // Load the gmlib header + if(fread(&header, sizeof(header), 1, fp) != 1) goto done; + if(header.id != ID_gml0) goto done; + debug = (header.flags & 1); + printf("GM LIBRARY %s, DEBUG=%d\n\n", libfile, debug); + + + // Load the string table + fseek(fp, header.stOffset, SEEK_SET); + if(fread(&strings, sizeof(strings), 1, fp) != 1) goto done; + printf("STRING TABLE, SIZE=%5d\n" + "===============================================================================\n", + strings.size); + stringTable = new char[strings.size]; + if(fread(stringTable, strings.size, 1, fp) != 1) goto done; + printf("%05d:%s\n", 0, stringTable); + for(i = 0; i < strings.size-1; ++i) + if(stringTable[i]==0) + printf("%05d:%s\n", i+1,&stringTable[i+1]); + + // Read the source code + if(header.scOffset) + { + printf("\n===============================================================================\n"); + printf("SOURCE CODE\n"); + printf("===============================================================================\n"); + + fseek(fp, header.scOffset, SEEK_SET); + if(fread(&source, sizeof(source), 1, fp) != 1) goto done; + sourceCode = new char[source.size]; + if(fread(sourceCode, source.size, 1, fp) != 1) goto done; + printf("%s", sourceCode); + printf("\n===============================================================================\n"); + } + else + { + printf("\nNO SOURCE CODE IN LIB\n"); + } + + // Read the functions + fseek(fp, header.fnOffset, SEEK_SET); + // read in the number of functions + if(fread(&numFunctions, sizeof(numFunctions), 1, fp) != 1) goto done; + printf("FUNCTIONS, COUNT=%d\n" + "===============================================================================\n\n", + numFunctions); + + for(i = 0; i < numFunctions; ++i) + { + printf("===============================================================================\n"); + + // Read in the function + if(fread(&function, sizeof(function), 1, fp) != 1) goto done; + if(function.func != ID_func) goto done; + + printf("FUNCTION ID %d\n", function.id); + printf("FLAGS %d\n", function.flags); + printf("NUM PARAMS %d\n", function.numParams); + printf("NUM LOCALS %d\n", function.numLocals); + printf("MAX STACK %d\n", function.maxStackSize); + printf("BYTE CODE SIZE %d\n", function.byteCodeLen); + + char * byteCode = new char[function.byteCodeLen]; + // Read in the byte code + if(fread(byteCode, function.byteCodeLen, 1, fp) != 1) + { + delete[] byteCode; + goto done; + } + + // Print the byte code + PrintByteCode(stdout, byteCode, function.byteCodeLen, stringTable); + delete[] byteCode; + + // Read in the function debug information + if(debug) + { + // debug name + gmuint32 ui32; + if(fread(&ui32, sizeof(ui32), 1, fp) != 1) goto done; + if(ui32 < strings.size) + { + printf("FUNCTION DEBUG NAME %s\n", stringTable + ui32); + } + else goto done; + + // line info + printf("\nLINE DEBUGGING INFO\n"); + if(fread(&ui32, sizeof(ui32), 1, fp) != 1) goto done; + for(j = 0; j < ui32; ++j) + { + gmlLineInfo lineInfo; + if(fread(&lineInfo, sizeof(lineInfo), 1, fp) != 1) goto done; + printf("BYTE CODE ADDR %5d SOURCE LINE NUMBER %5d\n", lineInfo.byteCodeAddress, lineInfo.lineNumber); + } + + // params and locals + printf("PARAMS AND LOCALS\n"); + for(j = 0; j < function.numLocals + function.numParams; ++j) + { + if(fread(&ui32, sizeof(ui32), 1, fp) != 1) goto done; + if(ui32 < strings.size) + { + if(j < function.numParams) + printf("PARAM %d %s\n", j, stringTable + ui32); + else + printf("LOCAL %d %s\n", j - function.numParams, stringTable + ui32); + } + else goto done; + } + } + printf("\n\n"); + } + + printf("END LIB\n"); + error = false; + +done: + + if(fp) { fclose(fp); } + if(stringTable) delete[] stringTable; + if(sourceCode) delete[] sourceCode; + if(error) printf("Error reading lib file\n"); +} + +/* + + flags [4 bytes] // 0x01 - debug lib, + + string_table_offset [4 bytes] // relative to start of lib + source_code_offset [4 bytes] // 0 for not there, otherwise relative to start of lib + functions_offset [4 bytes] // relative to start of lib + + string_table + { + string_table_size [4 bytes] + data [1 byte ] * string_table_size of 0 terminated strings + } + + source_code + { + source_code_size [4 bytes] + flags [4 bytes] // possibly encryption and compression flags + data [1 byte ] * source code size. + } + + functions + { + num_functions [4 bytes] // number of functions + + function[] + { + 'func' [4 bytes] + function_id [4 bytes] + num_params [4 bytes] + num_locals [4 bytes] + max_stack_size [4 bytes] + byte_code_length [4 bytes] + byte_code [1 byte ] * byte_code_length // contains offsets rel to string tab + // and function ids for certian op codes. + + if(debug lib) + { + debug_name_offset [4 bytes] + symbol_name_offsets[] [4 bytes] * (num_params + num_locals) (~0) on no offset + line_info_count [4 bytes] + + line_info[] + { + byte_code_address [4 bytes] + line_number [4 bytes] + } + } + } + } + +*/ diff --git a/vscript/languages/gm/src/platform/ps2cw/gmConfig_p.h b/vscript/languages/gm/src/platform/ps2cw/gmConfig_p.h new file mode 100644 index 00000000..b5f2eef6 --- /dev/null +++ b/vscript/languages/gm/src/platform/ps2cw/gmConfig_p.h @@ -0,0 +1,96 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMCONFIG_P_H_ +#define _GMCONFIG_P_H_ + +#include +#include +#include + +// pragmas + +// system defines + +#define GM_LITTLE_ENDIAN 1 +#define GM_COMPILER_CW +//#define GM_COMPILER_GCC +#define GM_PS2 + +#define GM_CDECL +#ifdef _DEBUG + #define GM_ASSERT(A) //TODO(A) +#else //_DEBUG + #define GM_ASSERT(A) +#endif //_DEBUG +#define GM_NL "\r\n" // "\n" +#define GM_FORCEINLINE inline +#define GM_INLINE inline +#define _gmstricmp strcasecmp +#define _gmsnprintf snprintf +#define _gmvsnprintf vsnprintf +#ifdef _DEBUG + #define GM_DEBUG_BUILD +#endif // _DEBUG +#define GM_PRINTF printf + +#define GM_NEW( alloc_params ) new alloc_params +#define GM_PLACEMENT_NEW( alloc_params, address ) new(address) alloc_params + +#define GM_DEFAULT_ALLOC_ALIGNMENT 4 + +#define GM_MAKE_ID32( a, b, c, d ) ( ((d)<<24) | ((c)<<16) | ((b)<<8) | (a)) + +#define GM_MIN_FLOAT32 -3.402823466e38f +#define GM_MAX_FLOAT32 3.402823466e38f + +#define GM_MIN_FLOAT64 -1.7976931348623158e308 +#define GM_MAX_FLOAT64 1.7976931348623158e308 + +#define GM_SMALLEST_FLOAT32 1.175494351e-38f +#define GM_SMALLEST_FLOAT64 2.2250738585072014e-308 + +#define GM_MIN_UINT8 0 +#define GM_MAX_UINT8 255 + +#define GM_MIN_INT8 -128 +#define GM_MAX_INT8 127 + +#define GM_MIN_UINT16 0 +#define GM_MAX_UINT16 65535 +#define GM_MIN_INT16 -32768 +#define GM_MAX_INT16 32767 + +#define GM_MIN_UINT32 0 +#define GM_MAX_UINT32 4294967295 +#define GM_MIN_INT32 -2147483648 +#define GM_MAX_INT32 2147483647 + +#define GM_MAX_INT 2147483647 +#define GM_MAX_SHORT 32767 + +#define GM_MAX_CHAR_STRING 256 +#define GM_MAX_PATH 256 + +// basic types +typedef const char * LPCTSTR; +typedef unsigned int gmuint; +typedef char gmint8; +typedef unsigned char gmuint8; +typedef short gmint16; +typedef unsigned short gmuint16; +typedef int gmint32; +typedef unsigned int gmuint32; +typedef float gmfloat; +typedef int gmptr; // machine pointer size as int +typedef unsigned int gmuptr; // machine pointer size as int + +#endif // _GMCONFIG_P_H_ \ No newline at end of file diff --git a/vscript/languages/gm/src/platform/win32gcc/gmConfig_p.h b/vscript/languages/gm/src/platform/win32gcc/gmConfig_p.h new file mode 100644 index 00000000..8d102141 --- /dev/null +++ b/vscript/languages/gm/src/platform/win32gcc/gmConfig_p.h @@ -0,0 +1,117 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMCONFIG_P_H_ +#define _GMCONFIG_P_H_ + +#include // alloca +#include +#include + +//#define _DEBUG // Manually enable for debug build if compiler doesn't + +// pragmas + + +// system defines + +#define GM_LITTLE_ENDIAN 1 +#define GM_COMPILER_GCC +#define GM_X86 + +#define GM_CDECL +#ifdef _DEBUG + #define GM_ASSERT(A) assert(A) +#else //_DEBUG + #define GM_ASSERT(A) +#endif //_DEBUG +#define GM_NL "\r\n" // "\n" +#define GM_FORCEINLINE inline // inline +#define GM_INLINE inline +#define _gmstricmp stricmp // strcasecmp +#define _gmsnprintf snprintf // snprintf +#define _gmvsnprintf vsnprintf // vsnprintf +#ifdef _DEBUG + #define GM_DEBUG_BUILD +#endif // _DEBUG +#define GM_PRINTF printf + +#define GM_NEW( alloc_params ) new alloc_params +#define GM_PLACEMENT_NEW( alloc_params, address ) new(address) alloc_params + +#define GM_DEFAULT_ALLOC_ALIGNMENT 4 + +#define GM_MAKE_ID32( a, b, c, d ) ( ((d)<<24) | ((c)<<16) | ((b)<<8) | (a)) + +#define GM_MIN_FLOAT32 -3.402823466e38f +#define GM_MAX_FLOAT32 3.402823466e38f + +#define GM_MIN_FLOAT64 -1.7976931348623158e308 +#define GM_MAX_FLOAT64 1.7976931348623158e308 + +#define GM_SMALLEST_FLOAT32 1.175494351e-38f +#define GM_SMALLEST_FLOAT64 2.2250738585072014e-308 + +#define GM_MIN_UINT8 0 +#define GM_MAX_UINT8 255 + +#define GM_MIN_INT8 -128 +#define GM_MAX_INT8 127 + +#define GM_MIN_UINT16 0 +#define GM_MAX_UINT16 65535 +#define GM_MIN_INT16 -32768 +#define GM_MAX_INT16 32767 + +#define GM_MIN_UINT32 0 +#define GM_MAX_UINT32 4294967295 +#define GM_MIN_INT32 -2147483648 +#define GM_MAX_INT32 2147483647 + +#define GM_MAX_INT 2147483647 +#define GM_MAX_SHORT 32767 + +#define GM_MAX_CHAR_STRING 256 +#define GM_MAX_PATH 256 + +// basic types +typedef const char * LPCTSTR; +typedef unsigned int gmuint; +typedef char gmint8; +typedef unsigned char gmuint8; +typedef short gmint16; +typedef unsigned short gmuint16; +typedef int gmint32; +typedef unsigned int gmuint32; +typedef float gmfloat; +typedef int gmptr; // machine pointer size as int +typedef unsigned int gmuptr; // machine pointer size as int + + +//#define GM_CRT_DEBUG +#undef GM_CRT_DEBUG + +#ifdef GM_CRT_DEBUG + #include + #ifdef _DEBUG + #define DEBUG_CLIENTBLOCK new (_CLIENT_BLOCK, __FILE__, __LINE__) + + #define SET_CRT_DEBUG_FIELD(a) _CrtSetDbgFlag( (a) | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) ) + #define CLEAR_CRT_DEBUG_FIELD(a) _CrtSetDbgFlag( ~(a) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) ) + #define _gmDumpLeaks() SET_CRT_DEBUG_FIELD( _CRTDBG_LEAK_CHECK_DF ) //Flag to dump memory leaks on exit + #else + #define DEBUG_CLIENTBLOCK new + + #define _gmDumpLeaks() //Do nothing + #endif +#endif //GM_CRT_DEBUG + +#endif // _GMCONFIG_P_H_ diff --git a/vscript/languages/gm/src/platform/win32msvc/gmConfig_p.h b/vscript/languages/gm/src/platform/win32msvc/gmConfig_p.h new file mode 100644 index 00000000..a11c1615 --- /dev/null +++ b/vscript/languages/gm/src/platform/win32msvc/gmConfig_p.h @@ -0,0 +1,136 @@ +/* + _____ __ ___ __ ____ _ __ + / ___/__ ___ _ ___ / |/ /__ ___ / /_____ __ __/ __/_______(_)__ / /_ + / (_ / _ `/ ' \/ -_) /|_/ / _ \/ _ \/ '_/ -_) // /\ \/ __/ __/ / _ \/ __/ + \___/\_,_/_/_/_/\__/_/ /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/ + /___/ /_/ + + See Copyright Notice in gmMachine.h + +*/ + +#ifndef _GMCONFIG_P_H_ +#define _GMCONFIG_P_H_ + +#include "platform.h" +#include "dbg.h" +#include "tier1/strtools.h" + +// pragmas + +#pragma inline_recursion( on ) +#pragma auto_inline( on ) +#pragma inline_depth( 255 ) +#pragma warning(disable : 4514) // removing unused inline function +#pragma warning(disable : 4100) // unreferenced formal parameter +#pragma warning(disable : 4706) // assignment within conditional expression +#pragma warning(disable : 4102) // unreferenced label +#pragma warning(disable : 4710) // not inlined + +// These two are for MSVS 2005 security consciousness until safe std lib funcs are available +#pragma warning(disable : 4996) // Deprecated functions +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE // Allow old unsecure standard library functions, Disable some 'warning C4996 - function was deprecated' +#endif +//#define _USE_32BIT_TIME_T // So system binds can use int for timestamps + +#include // alloca +#include +#include + +// system defines + +#define GM_LITTLE_ENDIAN 1 +#define GM_COMPILER_MSVC6 +#define GM_X86 + +#define GM_CDECL __cdecl +#ifdef _DEBUG + #define GM_ASSERT(A) Assert(A) +#else //_DEBUG + #define GM_ASSERT(A) +#endif //_DEBUG +#define GM_NL "\r\n" // "\n" +#define GM_FORCEINLINE __forceinline // inline +#define GM_INLINE inline +#define _gmstricmp stricmp // strcasecmp +#define _gmsnprintf V_snprintf // snprintf +#define _gmvsnprintf V_vsnprintf // vsnprintf +#ifdef _DEBUG + #define GM_DEBUG_BUILD +#endif // _DEBUG +#define GM_PRINTF printf + +//#define GM_CHECK_USER_BREAK_CALLBACK // Enable this only if a user break callback is set + +#define GM_NEW( alloc_params ) new alloc_params +#define GM_PLACEMENT_NEW( alloc_params, address ) new(address) alloc_params + +#define GM_DEFAULT_ALLOC_ALIGNMENT 4 + +#define GM_MAKE_ID32( a, b, c, d ) ( ((d)<<24) | ((c)<<16) | ((b)<<8) | (a)) + +#define GM_MIN_FLOAT32 -3.402823466e38f +#define GM_MAX_FLOAT32 3.402823466e38f + +#define GM_MIN_FLOAT64 -1.7976931348623158e308 +#define GM_MAX_FLOAT64 1.7976931348623158e308 + +#define GM_SMALLEST_FLOAT32 1.175494351e-38f +#define GM_SMALLEST_FLOAT64 2.2250738585072014e-308 + +#define GM_MIN_UINT8 0 +#define GM_MAX_UINT8 255 + +#define GM_MIN_INT8 -128 +#define GM_MAX_INT8 127 + +#define GM_MIN_UINT16 0 +#define GM_MAX_UINT16 65535 +#define GM_MIN_INT16 -32768 +#define GM_MAX_INT16 32767 + +#define GM_MIN_UINT32 0 +#define GM_MAX_UINT32 4294967295 +#define GM_MIN_INT32 -2147483648 +#define GM_MAX_INT32 2147483647 + +#define GM_MAX_INT 2147483647 +#define GM_MAX_SHORT 32767 + +#define GM_MAX_CHAR_STRING 256 +#define GM_MAX_PATH 256 + +// basic types +typedef const char * LPCTSTR; +typedef unsigned int gmuint; +typedef char gmint8; +typedef unsigned char gmuint8; +typedef short gmint16; +typedef unsigned short gmuint16; +typedef int gmint32; +typedef unsigned int gmuint32; +typedef float gmfloat; +typedef int gmptr; // machine pointer size as int +typedef unsigned int gmuptr; // machine pointer size as int + + +#define GM_CRT_DEBUG +//#undef GM_CRT_DEBUG + +#ifdef GM_CRT_DEBUG + #include + #ifdef _DEBUG + #define DEBUG_CLIENTBLOCK new (_CLIENT_BLOCK, __FILE__, __LINE__) + + #define SET_CRT_DEBUG_FIELD(a) _CrtSetDbgFlag( (a) | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) ) + #define CLEAR_CRT_DEBUG_FIELD(a) _CrtSetDbgFlag( ~(a) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) ) + #define _gmDumpLeaks() SET_CRT_DEBUG_FIELD( _CRTDBG_LEAK_CHECK_DF ) //Flag to dump memory leaks on exit + #else + #define DEBUG_CLIENTBLOCK new + + #define _gmDumpLeaks() //Do nothing + #endif +#endif //GM_CRT_DEBUG + +#endif // _GMCONFIG_P_H_ diff --git a/vscript/languages/gm/vgm/vgm.cpp b/vscript/languages/gm/vgm/vgm.cpp new file mode 100644 index 00000000..1726b570 --- /dev/null +++ b/vscript/languages/gm/vgm/vgm.cpp @@ -0,0 +1,715 @@ +//========== Copyright © 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: +// +//============================================================================= + +#define WIN32_LEAN_AND_MEAN 1 +#pragma warning( disable:4201) +#pragma comment(lib, "winmm.lib" ) +#include +#include // multimedia timer (may need winmm.lib) +#include +#include +#include + +#include "platform.h" + +#include "datamap.h" +#include "tier1/functors.h" +#include "tier1/utlvector.h" +#include "tier1/utlhash.h" +#include "tier1/fmtstr.h" +#include "vscript//ivscript.h" + +#include "gmThread.h" // game monkey script +#include "gmArrayLib.h" +#include "gmCall.h" +#include "gmGCRoot.h" +#include "gmGCRootUtil.h" +#include "gmHelpers.h" +#include "gmMathLib.h" +#include "gmStringLib.h" +#include "gmVector3Lib.h" + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +class CGCDisabler +{ +public: + CGCDisabler( gmMachine *pMachine ) + { + m_pMachine = pMachine; + m_bWasEnabled = m_pMachine->IsGCEnabled(); + m_pMachine->EnableGC( false ); + } + ~CGCDisabler() + { + m_pMachine->EnableGC( m_bWasEnabled ); + } + + gmMachine *m_pMachine; + bool m_bWasEnabled; +}; + +#define DISABLE_GC() CGCDisabler gcDisabler( this ) + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +class CGameMonkeyVM : public IScriptVM, + public gmMachine +{ +public: + CGameMonkeyVM() + { + } + + bool Init() + { + if ( !m_global ) + { + // Must be a re-init + gmMachine::Init(); + } + s_printCallback = ScriptPrintCallback; + SetDebugMode( true ); + AddCPPOwnedGMObject( GetGlobals() ); + + gmBindArrayLib( this ); + gmBindMathLib( this ); + gmBindStringLib( this ); + gmBindVector3Lib( this ); + + m_TypeMap.Init( 256 ); + return true; + } + + void Shutdown() + { + // Dump run time errors to output + if ( GetDebugMode() ) + { + FlushErrorLog(); + } + RemoveAllCPPOwnedGMObjects(); + ResetAndFreeMemory(); + m_TypeMap.Purge(); + } + + ScriptLanguage_t GetLanguage() + { + return SL_GAMEMONKEY; + } + + virtual const char *GetLanguageName() + { + return "GameMonkey"; + } + + virtual void AddSearchPath( const char *pszSearchPath ) + { + + } + + bool ConnectDebugger() { return true; } + void DisconnectDebugger() {} + + bool Frame( float simTime ) + { + return false; + } + + HSCRIPT CompileScript( const char *pszScript, const char *pszId ) + { + DISABLE_GC(); + gmFunctionObject *pFunction = CompileStringToFunction( pszScript ); + if ( !pFunction ) + { + FlushErrorLog(); + return NULL; + } + + ObjectHandle_t *pObjectHandle = new ObjectHandle_t; + pObjectHandle->pObject = pFunction; + AddCPPOwnedGMObject( pFunction ); + if ( pszId ) + { + pObjectHandle->pString = AllocStringObject( pszId ); + AddCPPOwnedGMObject( pObjectHandle->pString ); + gmTableObject *pGlobals = GetGlobals(); + pGlobals->Set( this, gmVariable(pObjectHandle->pString), gmVariable(pFunction) ); + } + else + { + pObjectHandle->pString = NULL; + } + return (HSCRIPT)pObjectHandle; + } + + void ReleaseScript( HSCRIPT hScript ) + { + ReleaseHandle( hScript ); + } + + ScriptStatus_t Run( HSCRIPT hScript, HSCRIPT hScope = NULL, bool bWait = true ) + { + return CGameMonkeyVM::ExecuteFunction( hScript, NULL, 0, NULL, hScope, bWait ); + } + + ScriptStatus_t Run( const char *pszScript, bool bWait = true ) + { + Assert( bWait ); + int errors = ExecuteString( pszScript, NULL, bWait ); + // Dump compile time errors to output + if(errors) + { + bool first = true; + const char * message; + + while((message = GetLog().GetEntry(first))) + { + Msg( "%s\n", message ); + } + GetLog().Reset(); + return SCRIPT_ERROR; + } + return SCRIPT_DONE; + } + + ScriptStatus_t Run( HSCRIPT hScript, bool bWait ) + { + Assert( bWait ); + return CGameMonkeyVM::Run( hScript, (HSCRIPT)NULL, bWait ); + } + + HSCRIPT CreateScope( const char *pszScope, HSCRIPT hParent = NULL ) + { + Assert( pszScope ); + Assert( !hParent ); + + DISABLE_GC(); + + gmTableObject *pGlobals = GetGlobals(); + gmTableObject *pNewTable = AllocTableObject(); + ObjectHandle_t *pObjectHandle = new ObjectHandle_t; + + AddCPPOwnedGMObject( pNewTable ); + pObjectHandle->pObject = pNewTable; + pObjectHandle->pString = AllocStringObject( pszScope ); + AddCPPOwnedGMObject( pObjectHandle->pString ); + + pGlobals->Set( this, gmVariable(pObjectHandle->pString), gmVariable(pNewTable) ); + + return (HSCRIPT)pObjectHandle; + } + + void ReleaseScope( HSCRIPT hScript ) + { + ReleaseHandle( hScript ); + } + + HSCRIPT LookupFunction( const char *pszFunction, HSCRIPT hScope = NULL ) + { + gmTableObject *pScope; + + if ( !hScope ) + { + pScope = GetGlobals(); + } + else + { + ObjectHandle_t *pScopeHandle = (ObjectHandle_t *)hScope; + pScope = assert_cast(pScopeHandle->pObject); + } + gmVariable varFunction = pScope->Get( this, pszFunction ); + gmFunctionObject *pFunction = varFunction.GetFunctionObjectSafe(); + if ( pFunction ) + { + ObjectHandle_t *pFunctionHandle = new ObjectHandle_t; + pFunctionHandle->pObject = pFunction; + pFunctionHandle->pString = NULL; + AddCPPOwnedGMObject( pFunction ); + return (HSCRIPT)pFunctionHandle; + } + return NULL; + } + + void ReleaseFunction( HSCRIPT hScript ) + { + ReleaseHandle( hScript ); + } + + ScriptStatus_t ExecuteFunction( HSCRIPT hFunction, ScriptVariant_t *pArgs, int nArgs, ScriptVariant_t *pReturn, HSCRIPT hScope, bool bWait ) + { + Assert( hFunction ); + Assert( bWait ); + ScriptStatus_t result = SCRIPT_ERROR; + if ( pReturn ) + { + pReturn->m_type = FIELD_VOID; + } + + if ( hFunction ) + { + ObjectHandle_t *pObjectHandle= (ObjectHandle_t *)hFunction; + gmTableObject *pGlobals = NULL; + gmTableObject *pScope; + if ( hScope ) + { + ObjectHandle_t *pScopeHandle= (ObjectHandle_t *)hScope; + pScope = assert_cast(pScopeHandle->pObject); + pGlobals = GetGlobals(); + SetGlobals( pScope ); + } + + gmCall functionCaller; + gmFunctionObject *pFunction = assert_cast(pObjectHandle->pObject); + if ( functionCaller.BeginFunction( this, pFunction, gmVariable::s_null, !bWait ) ) + { + for ( int i = 0; i < nArgs; i++ ) + { + switch ( pArgs[i].m_type ) + { + case FIELD_FLOAT: functionCaller.AddParamFloat( pArgs[i] ); break; + case FIELD_CSTRING: functionCaller.AddParamString( pArgs[i], strlen( pArgs[i].m_pszString ) ); break; + case FIELD_VECTOR: Assert( 0 ); functionCaller.AddParamNull(); break; + case FIELD_INTEGER: functionCaller.AddParamInt( pArgs[i] ); break; + case FIELD_BOOLEAN: functionCaller.AddParamInt( pArgs[i].m_bool ); break; + case FIELD_CHARACTER: { char sz[2]; sz[0] = pArgs[i].m_char; sz[1] = 0; functionCaller.AddParamString( sz, 1 ); break; } + } + } + + functionCaller.End(); + + if ( pReturn && ( bWait || !functionCaller.GetThread() ) && functionCaller.DidReturnVariable() ) + { + const gmVariable &ret = functionCaller.GetReturnedVariable(); + switch ( ret.m_type ) + { + case GM_NULL: break; + case GM_INT: *pReturn = ret.m_value.m_int; break; + case GM_FLOAT: *pReturn = ret.m_value.m_float; break; + case GM_STRING: + { + gmStringObject *pString = (gmStringObject *)ret.m_value.m_ref; + int size = pString->GetLength() + 1; + pReturn->m_type = FIELD_CSTRING; + pReturn->m_pszString = new char[size]; + memcpy( (void *)pReturn->m_pszString, pString->GetString(), size ); + } + break; + default: + DevMsg( "Script function returned unsupported type\n" ); + pReturn->m_type = FIELD_VOID; + } + } + } + + if ( !FlushErrorLog() ) + { + result = SCRIPT_DONE; + } + + if ( hScope ) + { + SetGlobals( pGlobals ); + } + } + return result; + } + + gmMachine *GetMachine() + { + return this; + } + + void RegisterFunction( ScriptFunctionBinding_t *pScriptFunction ) + { + RegisterLibraryFunction( pScriptFunction->m_desc.m_pszScriptName, &TranslateCall, NULL, pScriptFunction ); + } + + bool RegisterClass( ScriptClassDesc_t *pClassDesc ) + { + COMPILE_TIME_ASSERT( sizeof(pClassDesc) == sizeof(int) ); + if ( m_TypeMap.Find( (int)pClassDesc ) != m_TypeMap.InvalidHandle() ) + { + return true; + } + + gmType type = CreateUserType( pClassDesc->m_pszScriptName ); + m_TypeMap.Insert( (int)pClassDesc, type ); + + ScriptClassDesc_t *pCurDesc = pClassDesc; + CUtlVectorFixed functionEntries; + while ( pCurDesc ) + { + int nFunctions = pClassDesc->m_FunctionBindings.Count(); + functionEntries.SetSize( nFunctions ); + int i; + for ( i = 0; i < nFunctions; i++) + { + functionEntries[i].m_function = &TranslateCall; + functionEntries[i].m_name = pClassDesc->m_FunctionBindings[i].m_desc.m_pszFunction; + functionEntries[i].m_userData = &pClassDesc->m_FunctionBindings[i]; + } + RegisterTypeLibrary( type, functionEntries.Base(), nFunctions ); + pCurDesc = pCurDesc->m_pBaseDesc; + } + + if ( pClassDesc->m_pfnConstruct ) + { + RegisterLibraryFunction( pClassDesc->m_pszScriptName, &Construct, NULL, pClassDesc ); + RegisterUserCallbacks( type, NULL, &Destruct ); + } + + return true; + } + + bool RegisterInstance( ScriptClassDesc_t *pDesc, void *pInstance, const char *pszInstance, HSCRIPT hScope = NULL ) + { + if ( !RegisterClass( pDesc ) ) + { + return false; + } + + DISABLE_GC(); + + bool bResult = true; + + InstanceContext_t *pInstanceContext = new InstanceContext_t; + pInstanceContext->pInstance = pInstance; + pInstanceContext->pClassDesc = NULL; // i.e., no destruct + + // @TODO: This extra hash lookup could be eliminated (as it is also done in RegisterClass above) [2/13/2008 tom] + gmUserObject *pObject = AllocUserObject( pInstanceContext, m_TypeMap[m_TypeMap.Find((int)pDesc)] ); + AddCPPOwnedGMObject( pObject ); + + gmTableObject *pScope; + + if ( hScope ) + { + ObjectHandle_t *pScopeHandle= (ObjectHandle_t *)hScope; + pScope = (gmTableObject *)pScopeHandle->pObject; + } + else + { + pScope = GetGlobals(); + } + + if ( pScope ) + { + pScope->Set( this, pszInstance, gmVariable( pObject ) ); + } + else + { + DevMsg( "Undefined script scope!\n" ); + bResult = false; + } + + return bResult; + } + + void RemoveInstance( ScriptClassDesc_t *pDesc, void *pInstance, const char *pszInstance, HSCRIPT hScope = NULL ) + { + DISABLE_GC(); + gmTableObject *pScope; + + if ( hScope ) + { + ObjectHandle_t *pScopeHandle= (ObjectHandle_t *)hScope; + pScope = (gmTableObject *)pScopeHandle->pObject; + } + else + { + pScope = GetGlobals(); + } + + if ( pScope ) + { + gmVariable scriptVar = pScope->Get( this, pszInstance ); + gmUserObject *pObject = ( !scriptVar.IsNull() ) ? scriptVar.GetUserObjectSafe( m_TypeMap[m_TypeMap.Find((int)pDesc)] ) : NULL; + if ( pObject ) + { + delete pObject->m_user; + pObject->m_user = NULL; + pScope->Set( this, pszInstance, gmVariable::s_null ); + RemoveCPPOwnedGMObject( pObject ); + } + else + { + DevMsg( "Unknown instance\n" ); + } + } + else + { + DevMsg( "Undefined script scope!\n" ); + } + } + + +private: + struct InstanceContext_t + { + void *pInstance; + ScriptClassDesc_t *pClassDesc; + }; + + struct ObjectHandle_t + { + gmStringObject *pString; + gmObject *pObject; + }; + + void ReleaseHandle( HSCRIPT hScript ) + { + if ( hScript ) + { + ObjectHandle_t *pObjectHandle = (ObjectHandle_t *)hScript; + RemoveCPPOwnedGMObject( pObjectHandle->pObject ); + + if ( pObjectHandle->pString ) + { + gmTableObject *pGlobals = GetGlobals(); + pGlobals->Set( this, gmVariable(pObjectHandle->pString), gmVariable::s_null ); + RemoveCPPOwnedGMObject( pObjectHandle->pString ); + } + delete pObjectHandle; + } + } + + static void ScriptPrintCallback(gmMachine *pMachine, const char *pString) + { + Msg( "%s\n", pString ); + } + + static int GM_CDECL TranslateCall( gmThread *a_thread ) + { + const gmFunctionObject *fn = a_thread->GetFunctionObject(); + ScriptFunctionBinding_t *pVMScriptFunction = (ScriptFunctionBinding_t *)fn->m_cUserData; + + int nActualParams = a_thread->GetNumParams(); + int nFormalParams = pVMScriptFunction->m_desc.m_Parameters.Count(); + + GM_CHECK_NUM_PARAMS( nFormalParams ); + + CUtlVectorFixed params; + ScriptVariant_t returnValue; + + params.SetSize( nFormalParams ); + + int i = 0; + + if ( nActualParams ) + { + int iLimit = min( nActualParams, nFormalParams ); + ScriptDataType_t *pCurParamType = pVMScriptFunction->m_desc.m_Parameters.Base(); + for ( i = 0; i < iLimit; i++, pCurParamType++ ) + { + switch ( *pCurParamType ) + { + case FIELD_FLOAT: params[i] = a_thread->ParamFloatOrInt( i ); break; + case FIELD_CSTRING: params[i] = a_thread->ParamString( i ); break; + case FIELD_VECTOR: Assert( 0 ); params[i] = (Vector *)NULL; break; + case FIELD_INTEGER: params[i] = (int)a_thread->ParamFloatOrInt( i ); break; + case FIELD_BOOLEAN: + { + int type = a_thread->ParamType(i); + if ( type == GM_INT ) + params[i] = (bool)(a_thread->Param(i).m_value.m_int != 0 ); + else if ( type == GM_FLOAT ) + params[i] = (bool)(a_thread->Param(i).m_value.m_float != 0.0 ); + else + params[i] = true; + break; + } + case FIELD_CHARACTER: params[i] = a_thread->ParamString( i )[0]; break; + } + } + } + + for ( ; i < nFormalParams; i++ ) + { + COMPILE_TIME_ASSERT( sizeof(Vector *) >= sizeof(int) ); + params[i] = (Vector *)NULL; + } + + InstanceContext_t *pContext; + void *pObject; + + if ( pVMScriptFunction->m_flags & SF_MEMBER_FUNC ) + { + pContext = (InstanceContext_t *)a_thread->ThisUser(); + + if ( !pContext ) + { + return GM_EXCEPTION; + } + + pObject = pContext->pInstance; + + if ( !pObject ) + { + return GM_EXCEPTION; + } + } + else + { + pObject = NULL; + } + + (*pVMScriptFunction->m_pfnBinding)( pVMScriptFunction->m_pFunction, pObject, params.Base(), params.Count(), ( pVMScriptFunction->m_desc.m_ReturnType != FIELD_VOID ) ? &returnValue : NULL ); + + if ( pVMScriptFunction->m_desc.m_ReturnType != FIELD_VOID ) + { + switch ( pVMScriptFunction->m_desc.m_ReturnType ) + { + case FIELD_FLOAT: a_thread->PushFloat( returnValue ); break; + case FIELD_CSTRING: Assert( 0 ); a_thread->PushNull(); break; + case FIELD_VECTOR: Assert( 0 ); a_thread->PushNull(); break; + case FIELD_INTEGER: a_thread->PushInt( returnValue ); break; + case FIELD_BOOLEAN: a_thread->PushInt( (bool)returnValue ); break; + case FIELD_CHARACTER: Assert( 0 ); a_thread->PushNull(); break; + } + } + + return GM_OK; + } + + static int GM_CDECL Construct( gmThread *a_thread ) + { + CGameMonkeyVM *pThis = assert_cast(a_thread->GetMachine()); + const gmFunctionObject *fn = a_thread->GetFunctionObject(); + ScriptClassDesc_t *pClassDesc = (ScriptClassDesc_t *)fn->m_cUserData; + + GM_CHECK_NUM_PARAMS( 0 ); + + InstanceContext_t *pInstanceContext = new InstanceContext_t; + pInstanceContext->pInstance = pClassDesc->m_pfnConstruct(); + pInstanceContext->pClassDesc = pClassDesc; + + // @TODO: put the type in the userdata? [2/12/2008 tom] + a_thread->PushNewUser( pInstanceContext, pThis->m_TypeMap[pThis->m_TypeMap.Find((int)pClassDesc)] ); + + return GM_OK; + } + + static void Destruct( gmMachine *pMachine, gmUserObject* pObject ) + { + InstanceContext_t *pInstanceContext = ( InstanceContext_t *)pObject->m_user; + if ( pInstanceContext && pInstanceContext->pClassDesc ) + { + pInstanceContext->pClassDesc->m_pfnDestruct( pInstanceContext->pInstance ); + delete pInstanceContext; + } + } + + bool FlushErrorLog() + { + bool first = true; + bool errors = false; + const char * message; + + while((message = GetLog().GetEntry(first))) + { + Msg( "%s\n", message ); + errors = true; + } + GetLog().Reset(); + + return errors; + } + + CUtlHashFast m_TypeMap; +}; + +IScriptVM *ScriptCreateGameMonkeyVM() +{ + return new CGameMonkeyVM; +} + +void ScriptDestroyGameMonkeyVM( IScriptVM *pVM ) +{ + CGameMonkeyVM *pGameMonkeyVM = assert_cast(pVM); + delete pGameMonkeyVM; +} + + +#ifdef VGM_TEST +CGameMonkeyVM g_GMScriptVM; +IScriptVM *pScriptVM = &g_GMScriptVM; + +struct Test +{ + void Foo() { Msg( "Foo!\n");} +}; + +BEGIN_SCRIPTDESC_ROOT( Test ) + DEFINE_SCRIPTFUNC( Foo ) +END_SCRIPTDESC(); + +Test test; + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +int main( int argc, const char **argv) +{ + if ( argc < 2 ) + { + printf( "No script specified" ); + return 1; + } + + int key; + do + { + pScriptVM->Init(); + + const char *pszScript = argv[1]; + FILE *hFile = fopen( pszScript, "rb" ); + if ( !hFile ) + { + printf( "\"%s\" not found.\n", pszScript ); + return 1; + } + + int nFileLen = _filelength( _fileno( hFile ) ); + char *pBuf = new char[nFileLen + 1]; + fread( pBuf, 1, nFileLen, hFile ); + pBuf[nFileLen] = 0; + fclose( hFile ); + + printf( "Executing script \"%s\"\n----------------------------------------\n", pszScript ); + + HSCRIPT hScript = pScriptVM->CompileScript( pBuf, "test" ); + if ( hScript ) + { + HSCRIPT hScope = pScriptVM->CreateScope( "testScope" ); + pScriptVM->Run( hScript, hScope ); + HSCRIPT hFunction = pScriptVM->LookupFunction( "DoIt" ); + Assert( !hFunction ); + hFunction = pScriptVM->LookupFunction( "DoIt", hScope ); + Assert( hFunction ); + ScriptVariant_t ret; + pScriptVM->RegisterInstance( &test, "test" ); + pScriptVM->Call( hFunction, hScope, true, &ret, "Har", 6.0, 99 ); + + ret.Free(); + + pScriptVM->ReleaseFunction( hFunction ); + pScriptVM->ReleaseScript( hScript ); + pScriptVM->ReleaseScope( hScope ); + } + + printf("Script complete. Press q to exit, enter to run again.\n"); + key = _getch(); // Keypress before exit + pScriptVM->Shutdown(); + } while ( key != 'q' ); + + return 0; +} + +#endif \ No newline at end of file diff --git a/vscript/languages/gm/vgm/vgm.h b/vscript/languages/gm/vgm/vgm.h new file mode 100644 index 00000000..c06bdba0 --- /dev/null +++ b/vscript/languages/gm/vgm/vgm.h @@ -0,0 +1,17 @@ +//========== Copyright © 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: +// +//============================================================================= + +#ifndef VGM_H +#define VGM_H + +#if defined( _WIN32 ) +#pragma once +#endif + +IScriptVM *ScriptCreateGameMonkeyVM(); +void ScriptDestroyGameMonkeyVM( IScriptVM *pVM ); + +#endif // VGM_H diff --git a/vscript/languages/gm/vgm/vgm.vpc b/vscript/languages/gm/vgm/vgm.vpc new file mode 100644 index 00000000..4fc1efa7 --- /dev/null +++ b/vscript/languages/gm/vgm/vgm.vpc @@ -0,0 +1,135 @@ +//----------------------------------------------------------------------------- +// Project Script +//----------------------------------------------------------------------------- + +$Macro SRCDIR "..\..\..\.." +$Macro OUTBINDIR "." + +$Include "$SRCDIR\vpc_scripts\source_exe_con_win32_base.vpc" + +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE,..\src\gm;..\src\binds;..\src\platform\win32msvc" + $PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE;VGM_TEST" + } +} + +$Project "vgm" +{ + $Folder "Source Files" + { + $File "..\..\..\..\public\vscript\ivscript.h" + $File "..\..\..\..\public\vscript\vscript_templates.h" + $File "vgm.cpp" + } + + $Folder "GameMonkey" + { + $Folder "gm" + { + $Folder "Source Files" + { + $File "..\src\gm\gmArraySimple.cpp" \ + "..\src\gm\gmByteCode.cpp" \ + "..\src\gm\gmByteCodeGen.cpp" \ + "..\src\gm\gmCodeGen.cpp" \ + "..\src\gm\gmCodeGenHooks.cpp" \ + "..\src\gm\gmCodeTree.cpp" \ + "..\src\gm\gmCrc.cpp" \ + "..\src\gm\gmDebug.cpp" \ + "..\src\gm\gmFunctionObject.cpp" \ + "..\src\gm\gmHash.cpp" \ + "..\src\gm\gmIncGC.cpp" \ + "..\src\gm\gmLibHooks.cpp" \ + "..\src\gm\gmListDouble.cpp" \ + "..\src\gm\gmLog.cpp" \ + "..\src\gm\gmMachine.cpp" \ + "..\src\gm\gmMachineLib.cpp" \ + "..\src\gm\gmMem.cpp" \ + "..\src\gm\gmMemChain.cpp" \ + "..\src\gm\gmMemFixed.cpp" \ + "..\src\gm\gmMemFixedSet.cpp" \ + "..\src\gm\gmOperators.cpp" \ + "..\src\gm\gmParser.cpp" \ + "..\src\gm\gmScanner.cpp" \ + "..\src\gm\gmStream.cpp" \ + "..\src\gm\gmStreamBuffer.cpp" \ + "..\src\gm\gmStringObject.cpp" \ + "..\src\gm\gmTableObject.cpp" \ + "..\src\gm\gmThread.cpp" \ + "..\src\gm\gmUserObject.cpp" \ + "..\src\gm\gmUtil.cpp" \ + "..\src\gm\gmVariable.cpp" + } + + $Folder "Header Files" + { + $File "..\src\platform\win32msvc\gmConfig_p.h" \ + "..\src\gm\gmArraySimple.h" \ + "..\src\gm\gmByteCode.h" \ + "..\src\gm\gmByteCodeGen.h" \ + "..\src\gm\gmCodeGen.h" \ + "..\src\gm\gmCodeGenHooks.h" \ + "..\src\gm\gmCodeTree.h" \ + "..\src\gm\gmConfig.h" \ + "..\src\gm\gmCrc.h" \ + "..\src\gm\gmDebug.h" \ + "..\src\gm\gmFunctionObject.h" \ + "..\src\gm\gmHash.h" \ + "..\src\gm\gmIncGC.h" \ + "..\src\gm\gmIterator.h" \ + "..\src\gm\gmLibHooks.h" \ + "..\src\gm\gmListDouble.h" \ + "..\src\gm\gmLog.h" \ + "..\src\gm\gmMachine.h" \ + "..\src\gm\gmMachineLib.h" \ + "..\src\gm\gmMem.h" \ + "..\src\gm\gmMemChain.h" \ + "..\src\gm\gmMemFixed.h" \ + "..\src\gm\gmMemFixedSet.h" \ + "..\src\gm\gmOperators.h" \ + "..\src\gm\gmParser.cpp.h" \ + "..\src\gm\gmScanner.h" \ + "..\src\gm\gmStream.h" \ + "..\src\gm\gmStreamBuffer.h" \ + "..\src\gm\gmStringObject.h" \ + "..\src\gm\gmTableObject.h" \ + "..\src\gm\gmThread.h" \ + "..\src\gm\gmUserObject.h" \ + "..\src\gm\gmUtil.h" \ + "..\src\gm\gmVariable.h" + } + } + + $Folder "binds" + { + $Folder "Source Files" + { + $File "..\src\binds\gmArrayLib.cpp" \ + "..\src\binds\gmCall.cpp" \ + "..\src\binds\gmGCRoot.cpp" \ + "..\src\binds\gmGCRootUtil.cpp" \ + "..\src\binds\gmHelpers.cpp" \ + "..\src\binds\gmMathLib.cpp" \ + "..\src\binds\gmStringLib.cpp" \ + "..\src\binds\gmSystemLib.cpp" \ + "..\src\binds\gmVector3Lib.cpp" + } + $Folder "Header Files" + { + $File "..\src\binds\gmArrayLib.h" \ + "..\src\binds\gmCall.h" \ + "..\src\binds\gmGCRoot.h" \ + "..\src\binds\gmGCRootUtil.h" \ + "..\src\binds\gmHelpers.h" \ + "..\src\binds\gmMathLib.h" \ + "..\src\binds\gmStringLib.h" \ + "..\src\binds\gmSystemLib.h" \ + "..\src\binds\gmVector3Lib.h" + } + } + + } +} diff --git a/vscript/languages/gm/vgm/vscript_templates.h b/vscript/languages/gm/vgm/vscript_templates.h new file mode 100644 index 00000000..7dd11c5a --- /dev/null +++ b/vscript/languages/gm/vgm/vscript_templates.h @@ -0,0 +1,246 @@ +//========== Copyright © 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: +// +//============================================================================= + +#ifndef VSCRIPT_TEMPLATES_H +#define VSCRIPT_TEMPLATES_H + +#if defined( _WIN32 ) +#pragma once +#endif + +#define FUNC_APPEND_PARAMS_0 +#define FUNC_APPEND_PARAMS_1 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 1 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_1 *)(0) ) ); +#define FUNC_APPEND_PARAMS_2 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 2 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_1 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_2 *)(0) ) ); +#define FUNC_APPEND_PARAMS_3 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 3 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_1 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_2 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_3 *)(0) ) ); +#define FUNC_APPEND_PARAMS_4 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 4 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_1 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_2 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_3 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_4 *)(0) ) ); +#define FUNC_APPEND_PARAMS_5 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 5 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_1 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_2 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_3 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_4 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_5 *)(0) ) ); +#define FUNC_APPEND_PARAMS_6 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 6 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_1 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_2 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_3 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_4 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_5 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_6 *)(0) ) ); +#define FUNC_APPEND_PARAMS_7 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 7 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_1 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_2 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_3 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_4 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_5 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_6 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_7 *)(0) ) ); +#define FUNC_APPEND_PARAMS_8 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 8 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_1 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_2 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_3 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_4 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_5 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_6 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_7 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_8 *)(0) ) ); +#define FUNC_APPEND_PARAMS_9 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 9 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_1 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_2 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_3 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_4 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_5 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_6 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_7 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_8 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_9 *)(0) ) ); +#define FUNC_APPEND_PARAMS_10 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 10 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_1 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_2 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_3 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_4 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_5 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_6 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_7 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_8 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_9 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_10 *)(0) ) ); +#define FUNC_APPEND_PARAMS_11 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 11 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_1 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_2 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_3 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_4 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_5 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_6 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_7 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_8 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_9 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_10 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_11 *)(0) ) ); +#define FUNC_APPEND_PARAMS_12 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 12 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_1 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_2 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_3 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_4 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_5 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_6 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_7 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_8 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_9 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_10 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_11 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_12 *)(0) ) ); +#define FUNC_APPEND_PARAMS_13 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 13 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_1 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_2 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_3 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_4 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_5 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_6 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_7 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_8 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_9 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_10 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_11 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_12 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_13 *)(0) ) ); +#define FUNC_APPEND_PARAMS_14 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 14 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_1 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_2 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_3 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_4 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_5 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_6 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_7 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_8 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_9 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_10 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_11 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_12 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_13 *)(0) ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( (FUNC_ARG_TYPE_14 *)(0) ) ); + +#define DEFINE_NONMEMBER_FUNC_TYPE_DEDUCER(N) \ + template \ + inline void ScriptDeduceFunctionSignature(ScriptFuncDescriptor_t *pDesc, FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \ + { \ + pDesc->m_ReturnType = ScriptDeduceType((FUNCTION_RETTYPE *)(0)); \ + FUNC_APPEND_PARAMS_##N \ + } + +FUNC_GENERATE_ALL( DEFINE_NONMEMBER_FUNC_TYPE_DEDUCER ); + +#define DEFINE_MEMBER_FUNC_TYPE_DEDUCER(N) \ + template \ + inline void ScriptDeduceFunctionSignature(ScriptFuncDescriptor_t *pDesc, OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \ + { \ + pDesc->m_ReturnType = ScriptDeduceType((FUNCTION_RETTYPE *)(0)); \ + FUNC_APPEND_PARAMS_##N \ + } + +FUNC_GENERATE_ALL( DEFINE_MEMBER_FUNC_TYPE_DEDUCER ); + +//------------------------------------- + +#define DEFINE_CONST_MEMBER_FUNC_TYPE_DEDUCER(N) \ + template \ + inline void ScriptDeduceFunctionSignature(ScriptFuncDescriptor_t *pDesc, OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const ) \ + { \ + pDesc->m_ReturnType = ScriptDeduceType((FUNCTION_RETTYPE *)(0)); \ + FUNC_APPEND_PARAMS_##N \ + } + +FUNC_GENERATE_ALL( DEFINE_CONST_MEMBER_FUNC_TYPE_DEDUCER ); + +#define ScriptInitMemberFuncDescriptor_( pDesc, class, func, scriptName ) if ( 0 ) {} else { (pDesc)->m_pszScriptName = scriptName; (pDesc)->m_pszFunction = #func; ScriptDeduceFunctionSignature( pDesc, (class *)(0), &class::func ); } + +#define ScriptInitFuncDescriptorNamed( pDesc, func, scriptName ) if ( 0 ) {} else { (pDesc)->m_pszScriptName = scriptName; (pDesc)->m_pszFunction = #func; ScriptDeduceFunctionSignature( pDesc, &func ); } +#define ScriptInitFuncDescriptor( pDesc, func ) ScriptInitFuncDescriptorNamed( pDesc, func, #func ) +#define ScriptInitMemberFuncDescriptorNamed( pDesc, class, func, scriptName ) ScriptInitMemberFuncDescriptor_( pDesc, class, func, scriptName ) +#define ScriptInitMemberFuncDescriptor( pDesc, class, func ) ScriptInitMemberFuncDescriptorNamed( pDesc, class, func, #func ) + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +template +inline void *ScriptConvertFuncPtrToVoid( FUNCPTR_TYPE pFunc ) +{ + union FuncPtrConvert + { + void *p; + FUNCPTR_TYPE pFunc; + }; + + Assert( sizeof( pFunc ) == sizeof( void * ) ); + + FuncPtrConvert convert; + convert.pFunc = pFunc; + return convert.p; +} + +template +inline FUNCPTR_TYPE ScriptConvertFuncPtrFromVoid( void *p ) +{ + union FuncPtrConvert + { + void *p; + FUNCPTR_TYPE pFunc; + }; + + Assert( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) ); + + FuncPtrConvert convert; + convert.p = p; + return convert.pFunc; +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_0 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_1 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_1 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_2 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_2 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_3 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_3 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_4 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_4 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_5 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_5 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_6 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_6 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_7 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_7 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_8 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_8 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_9 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_9 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_10 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_10 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_11 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_11 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_12 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_12 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_13 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_13 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_14 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_14 + +#define SCRIPT_BINDING_ARGS_0 +#define SCRIPT_BINDING_ARGS_1 pArguments[0] +#define SCRIPT_BINDING_ARGS_2 pArguments[0], pArguments[1] +#define SCRIPT_BINDING_ARGS_3 pArguments[0], pArguments[1], pArguments[2] +#define SCRIPT_BINDING_ARGS_4 pArguments[0], pArguments[1], pArguments[2], pArguments[3] +#define SCRIPT_BINDING_ARGS_5 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4] +#define SCRIPT_BINDING_ARGS_6 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5] +#define SCRIPT_BINDING_ARGS_7 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6] +#define SCRIPT_BINDING_ARGS_8 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7] +#define SCRIPT_BINDING_ARGS_9 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8] +#define SCRIPT_BINDING_ARGS_10 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9] +#define SCRIPT_BINDING_ARGS_11 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9], pArguments[10] +#define SCRIPT_BINDING_ARGS_12 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9], pArguments[10], pArguments[11] +#define SCRIPT_BINDING_ARGS_13 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9], pArguments[10], pArguments[11], pArguments[12] +#define SCRIPT_BINDING_ARGS_14 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9], pArguments[10], pArguments[11], pArguments[12], pArguments[13] + + +#define DEFINE_SCRIPT_BINDINGS(N) \ + template \ + class CNonMemberScriptBinding##N \ + { \ + public: \ + static bool Call( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \ + { \ + Assert( nArguments == N ); \ + Assert( pReturn ); \ + Assert( !pContext ); \ + \ + if ( nArguments != N || !pReturn || pContext ) \ + { \ + return false; \ + } \ + *pReturn = ((FUNC_TYPE)pFunction)( SCRIPT_BINDING_ARGS_##N ); \ + return true; \ + } \ + }; \ + \ + template \ + class CNonMemberScriptBinding##N \ + { \ + public: \ + static bool Call( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \ + { \ + Assert( nArguments == N ); \ + Assert( !pReturn ); \ + Assert( !pContext ); \ + \ + if ( nArguments != N || pReturn || pContext ) \ + { \ + return false; \ + } \ + ((FUNC_TYPE)pFunction)( SCRIPT_BINDING_ARGS_##N ); \ + return true; \ + } \ + }; \ + \ + template \ + class CMemberScriptBinding##N \ + { \ + public: \ + static bool Call( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \ + { \ + Assert( nArguments == N ); \ + Assert( pReturn ); \ + Assert( pContext ); \ + \ + if ( nArguments != N || !pReturn || !pContext ) \ + { \ + return false; \ + } \ + *pReturn = (((OBJECT_TYPE_PTR)(pContext))->*ScriptConvertFuncPtrFromVoid(pFunction))( SCRIPT_BINDING_ARGS_##N ); \ + return true; \ + } \ + }; \ + \ + template \ + class CMemberScriptBinding##N \ + { \ + public: \ + static bool Call( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \ + { \ + Assert( nArguments == N ); \ + Assert( !pReturn ); \ + Assert( pContext ); \ + \ + if ( nArguments != N || pReturn || !pContext ) \ + { \ + return false; \ + } \ + (((OBJECT_TYPE_PTR)(pContext))->*ScriptConvertFuncPtrFromVoid(pFunction))( SCRIPT_BINDING_ARGS_##N ); \ + return true; \ + } \ + }; \ + \ + template \ + inline ScriptBindingFunc_t ScriptCreateBinding(FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \ + { \ + typedef FUNCTION_RETTYPE (*Func_t)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N); \ + return &CNonMemberScriptBinding##N::Call; \ + } \ + \ + template \ + inline ScriptBindingFunc_t ScriptCreateBinding(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE (FUNCTION_CLASS::*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \ + { \ + typedef FUNCTION_RETTYPE (FUNCTION_CLASS::*Func_t)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N); \ + return &CMemberScriptBinding##N::Call; \ + } \ + \ + template \ + inline ScriptBindingFunc_t ScriptCreateBinding(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE (FUNCTION_CLASS::*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const ) \ + { \ + typedef FUNCTION_RETTYPE (FUNCTION_CLASS::*Func_t)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N); \ + return &CMemberScriptBinding##N::Call; \ + } + +FUNC_GENERATE_ALL( DEFINE_SCRIPT_BINDINGS ); + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#endif // VSCRIPT_TEMPLATES_H diff --git a/vscript/languages/lua/lua-5.1.4/COPYRIGHT b/vscript/languages/lua/lua-5.1.4/COPYRIGHT new file mode 100644 index 00000000..3a53e741 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/COPYRIGHT @@ -0,0 +1,34 @@ +Lua License +----------- + +Lua is licensed under the terms of the MIT license reproduced below. +This means that Lua is free software and can be used for both academic +and commercial purposes at absolutely no cost. + +For details and rationale, see http://www.lua.org/license.html . + +=============================================================================== + +Copyright (C) 1994-2008 Lua.org, PUC-Rio. + +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. + +=============================================================================== + +(end of COPYRIGHT) diff --git a/vscript/languages/lua/lua-5.1.4/HISTORY b/vscript/languages/lua/lua-5.1.4/HISTORY new file mode 100644 index 00000000..ce0c95bc --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/HISTORY @@ -0,0 +1,183 @@ +HISTORY for Lua 5.1 + +* Changes from version 5.0 to 5.1 + ------------------------------- + Language: + + new module system. + + new semantics for control variables of fors. + + new semantics for setn/getn. + + new syntax/semantics for varargs. + + new long strings and comments. + + new `mod' operator (`%') + + new length operator #t + + metatables for all types + API: + + new functions: lua_createtable, lua_get(set)field, lua_push(to)integer. + + user supplies memory allocator (lua_open becomes lua_newstate). + + luaopen_* functions must be called through Lua. + Implementation: + + new configuration scheme via luaconf.h. + + incremental garbage collection. + + better handling of end-of-line in the lexer. + + fully reentrant parser (new Lua function `load') + + better support for 64-bit machines. + + native loadlib support for Mac OS X. + + standard distribution in only one library (lualib.a merged into lua.a) + +* Changes from version 4.0 to 5.0 + ------------------------------- + Language: + + lexical scoping. + + Lua coroutines. + + standard libraries now packaged in tables. + + tags replaced by metatables and tag methods replaced by metamethods, + stored in metatables. + + proper tail calls. + + each function can have its own global table, which can be shared. + + new __newindex metamethod, called when we insert a new key into a table. + + new block comments: --[[ ... ]]. + + new generic for. + + new weak tables. + + new boolean type. + + new syntax "local function". + + (f()) returns the first value returned by f. + + {f()} fills a table with all values returned by f. + + \n ignored in [[\n . + + fixed and-or priorities. + + more general syntax for function definition (e.g. function a.x.y:f()...end). + + more general syntax for function calls (e.g. (print or write)(9)). + + new functions (time/date, tmpfile, unpack, require, load*, etc.). + API: + + chunks are loaded by using lua_load; new luaL_loadfile and luaL_loadbuffer. + + introduced lightweight userdata, a simple "void*" without a metatable. + + new error handling protocol: the core no longer prints error messages; + all errors are reported to the caller on the stack. + + new lua_atpanic for host cleanup. + + new, signal-safe, hook scheme. + Implementation: + + new license: MIT. + + new, faster, register-based virtual machine. + + support for external multithreading and coroutines. + + new and consistent error message format. + + the core no longer needs "stdio.h" for anything (except for a single + use of sprintf to convert numbers to strings). + + lua.c now runs the environment variable LUA_INIT, if present. It can + be "@filename", to run a file, or the chunk itself. + + support for user extensions in lua.c. + sample implementation given for command line editing. + + new dynamic loading library, active by default on several platforms. + + safe garbage-collector metamethods. + + precompiled bytecodes checked for integrity (secure binary dostring). + + strings are fully aligned. + + position capture in string.find. + + read('*l') can read lines with embedded zeros. + +* Changes from version 3.2 to 4.0 + ------------------------------- + Language: + + new "break" and "for" statements (both numerical and for tables). + + uniform treatment of globals: globals are now stored in a Lua table. + + improved error messages. + + no more '$debug': full speed *and* full debug information. + + new read form: read(N) for next N bytes. + + general read patterns now deprecated. + (still available with -DCOMPAT_READPATTERNS.) + + all return values are passed as arguments for the last function + (old semantics still available with -DLUA_COMPAT_ARGRET) + + garbage collection tag methods for tables now deprecated. + + there is now only one tag method for order. + API: + + New API: fully re-entrant, simpler, and more efficient. + + New debug API. + Implementation: + + faster than ever: cleaner virtual machine and new hashing algorithm. + + non-recursive garbage-collector algorithm. + + reduced memory usage for programs with many strings. + + improved treatment for memory allocation errors. + + improved support for 16-bit machines (we hope). + + code now compiles unmodified as both ANSI C and C++. + + numbers in bases other than 10 are converted using strtoul. + + new -f option in Lua to support #! scripts. + + luac can now combine text and binaries. + +* Changes from version 3.1 to 3.2 + ------------------------------- + + redirected all output in Lua's core to _ERRORMESSAGE and _ALERT. + + increased limit on the number of constants and globals per function + (from 2^16 to 2^24). + + debugging info (lua_debug and hooks) moved into lua_state and new API + functions provided to get and set this info. + + new debug lib gives full debugging access within Lua. + + new table functions "foreachi", "sort", "tinsert", "tremove", "getn". + + new io functions "flush", "seek". + +* Changes from version 3.0 to 3.1 + ------------------------------- + + NEW FEATURE: anonymous functions with closures (via "upvalues"). + + new syntax: + - local variables in chunks. + - better scope control with DO block END. + - constructors can now be also written: { record-part; list-part }. + - more general syntax for function calls and lvalues, e.g.: + f(x).y=1 + o:f(x,y):g(z) + f"string" is sugar for f("string") + + strings may now contain arbitrary binary data (e.g., embedded zeros). + + major code re-organization and clean-up; reduced module interdependecies. + + no arbitrary limits on the total number of constants and globals. + + support for multiple global contexts. + + better syntax error messages. + + new traversal functions "foreach" and "foreachvar". + + the default for numbers is now double. + changing it to use floats or longs is easy. + + complete debug information stored in pre-compiled chunks. + + sample interpreter now prompts user when run interactively, and also + handles control-C interruptions gracefully. + +* Changes from version 2.5 to 3.0 + ------------------------------- + + NEW CONCEPT: "tag methods". + Tag methods replace fallbacks as the meta-mechanism for extending the + semantics of Lua. Whereas fallbacks had a global nature, tag methods + work on objects having the same tag (e.g., groups of tables). + Existing code that uses fallbacks should work without change. + + new, general syntax for constructors {[exp] = exp, ... }. + + support for handling variable number of arguments in functions (varargs). + + support for conditional compilation ($if ... $else ... $end). + + cleaner semantics in API simplifies host code. + + better support for writing libraries (auxlib.h). + + better type checking and error messages in the standard library. + + luac can now also undump. + +* Changes from version 2.4 to 2.5 + ------------------------------- + + io and string libraries are now based on pattern matching; + the old libraries are still available for compatibility + + dofile and dostring can now return values (via return statement) + + better support for 16- and 64-bit machines + + expanded documentation, with more examples + +* Changes from version 2.2 to 2.4 + ------------------------------- + + external compiler creates portable binary files that can be loaded faster + + interface for debugging and profiling + + new "getglobal" fallback + + new functions for handling references to Lua objects + + new functions in standard lib + + only one copy of each string is stored + + expanded documentation, with more examples + +* Changes from version 2.1 to 2.2 + ------------------------------- + + functions now may be declared with any "lvalue" as a name + + garbage collection of functions + + support for pipes + +* Changes from version 1.1 to 2.1 + ------------------------------- + + object-oriented support + + fallbacks + + simplified syntax for tables + + many internal improvements + +(end of HISTORY) diff --git a/vscript/languages/lua/lua-5.1.4/INSTALL b/vscript/languages/lua/lua-5.1.4/INSTALL new file mode 100644 index 00000000..17eb8aee --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/INSTALL @@ -0,0 +1,99 @@ +INSTALL for Lua 5.1 + +* Building Lua + ------------ + Lua is built in the src directory, but the build process can be + controlled from the top-level Makefile. + + Building Lua on Unix systems should be very easy. First do "make" and + see if your platform is listed. If so, just do "make xxx", where xxx + is your platform name. The platforms currently supported are: + aix ansi bsd freebsd generic linux macosx mingw posix solaris + + If your platform is not listed, try the closest one or posix, generic, + ansi, in this order. + + See below for customization instructions and for instructions on how + to build with other Windows compilers. + + If you want to check that Lua has been built correctly, do "make test" + after building Lua. Also, have a look at the example programs in test. + +* Installing Lua + -------------- + Once you have built Lua, you may want to install it in an official + place in your system. In this case, do "make install". The official + place and the way to install files are defined in Makefile. You must + have the right permissions to install files. + + If you want to build and install Lua in one step, do "make xxx install", + where xxx is your platform name. + + If you want to install Lua locally, then do "make local". This will + create directories bin, include, lib, man, and install Lua there as + follows: + + bin: lua luac + include: lua.h luaconf.h lualib.h lauxlib.h lua.hpp + lib: liblua.a + man/man1: lua.1 luac.1 + + These are the only directories you need for development. + + There are man pages for lua and luac, in both nroff and html, and a + reference manual in html in doc, some sample code in test, and some + useful stuff in etc. You don't need these directories for development. + + If you want to install Lua locally, but in some other directory, do + "make install INSTALL_TOP=xxx", where xxx is your chosen directory. + + See below for instructions for Windows and other systems. + +* Customization + ------------- + Three things can be customized by editing a file: + - Where and how to install Lua -- edit Makefile. + - How to build Lua -- edit src/Makefile. + - Lua features -- edit src/luaconf.h. + + You don't actually need to edit the Makefiles because you may set the + relevant variables when invoking make. + + On the other hand, if you need to select some Lua features, you'll need + to edit src/luaconf.h. The edited file will be the one installed, and + it will be used by any Lua clients that you build, to ensure consistency. + + We strongly recommend that you enable dynamic loading. This is done + automatically for all platforms listed above that have this feature + (and also Windows). See src/luaconf.h and also src/Makefile. + +* Building Lua on Windows and other systems + ----------------------------------------- + If you're not using the usual Unix tools, then the instructions for + building Lua depend on the compiler you use. You'll need to create + projects (or whatever your compiler uses) for building the library, + the interpreter, and the compiler, as follows: + + library: lapi.c lcode.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c + lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c + ltable.c ltm.c lundump.c lvm.c lzio.c + lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c loslib.c + ltablib.c lstrlib.c loadlib.c linit.c + + interpreter: library, lua.c + + compiler: library, luac.c print.c + + If you use Visual Studio .NET, you can use etc/luavs.bat in its + "Command Prompt". + + If all you want is to build the Lua interpreter, you may put all .c files + in a single project, except for luac.c and print.c. Or just use etc/all.c. + + To use Lua as a library in your own programs, you'll need to know how to + create and use libraries with your compiler. + + As mentioned above, you may edit luaconf.h to select some features before + building Lua. + +(end of INSTALL) diff --git a/vscript/languages/lua/lua-5.1.4/Makefile b/vscript/languages/lua/lua-5.1.4/Makefile new file mode 100644 index 00000000..6e78f66f --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/Makefile @@ -0,0 +1,128 @@ +# makefile for installing Lua +# see INSTALL for installation instructions +# see src/Makefile and src/luaconf.h for further customization + +# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= + +# Your platform. See PLATS for possible values. +PLAT= none + +# Where to install. The installation starts in the src and doc directories, +# so take care if INSTALL_TOP is not an absolute path. +INSTALL_TOP= /usr/local +INSTALL_BIN= $(INSTALL_TOP)/bin +INSTALL_INC= $(INSTALL_TOP)/include +INSTALL_LIB= $(INSTALL_TOP)/lib +INSTALL_MAN= $(INSTALL_TOP)/man/man1 +# +# You probably want to make INSTALL_LMOD and INSTALL_CMOD consistent with +# LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h (and also with etc/lua.pc). +INSTALL_LMOD= $(INSTALL_TOP)/share/lua/$V +INSTALL_CMOD= $(INSTALL_TOP)/lib/lua/$V + +# How to install. If your install program does not support "-p", then you +# may have to run ranlib on the installed liblua.a (do "make ranlib"). +INSTALL= install -p +INSTALL_EXEC= $(INSTALL) -m 0755 +INSTALL_DATA= $(INSTALL) -m 0644 +# +# If you don't have install you can use cp instead. +# INSTALL= cp -p +# INSTALL_EXEC= $(INSTALL) +# INSTALL_DATA= $(INSTALL) + +# Utilities. +MKDIR= mkdir -p +RANLIB= ranlib + +# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE ========= + +# Convenience platforms targets. +PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris + +# What to install. +TO_BIN= lua luac +TO_INC= lua.h luaconf.h lualib.h lauxlib.h ../etc/lua.hpp +TO_LIB= liblua.a +TO_MAN= lua.1 luac.1 + +# Lua version and release. +V= 5.1 +R= 5.1.4 + +all: $(PLAT) + +$(PLATS) clean: + cd src && $(MAKE) $@ + +test: dummy + src/lua test/hello.lua + +install: dummy + cd src && $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_MAN) $(INSTALL_LMOD) $(INSTALL_CMOD) + cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN) + cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC) + cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB) + cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN) + +ranlib: + cd src && cd $(INSTALL_LIB) && $(RANLIB) $(TO_LIB) + +local: + $(MAKE) install INSTALL_TOP=.. + +none: + @echo "Please do" + @echo " make PLATFORM" + @echo "where PLATFORM is one of these:" + @echo " $(PLATS)" + @echo "See INSTALL for complete instructions." + +# make may get confused with test/ and INSTALL in a case-insensitive OS +dummy: + +# echo config parameters +echo: + @echo "" + @echo "These are the parameters currently set in src/Makefile to build Lua $R:" + @echo "" + @cd src && $(MAKE) -s echo + @echo "" + @echo "These are the parameters currently set in Makefile to install Lua $R:" + @echo "" + @echo "PLAT = $(PLAT)" + @echo "INSTALL_TOP = $(INSTALL_TOP)" + @echo "INSTALL_BIN = $(INSTALL_BIN)" + @echo "INSTALL_INC = $(INSTALL_INC)" + @echo "INSTALL_LIB = $(INSTALL_LIB)" + @echo "INSTALL_MAN = $(INSTALL_MAN)" + @echo "INSTALL_LMOD = $(INSTALL_LMOD)" + @echo "INSTALL_CMOD = $(INSTALL_CMOD)" + @echo "INSTALL_EXEC = $(INSTALL_EXEC)" + @echo "INSTALL_DATA = $(INSTALL_DATA)" + @echo "" + @echo "See also src/luaconf.h ." + @echo "" + +# echo private config parameters +pecho: + @echo "V = $(V)" + @echo "R = $(R)" + @echo "TO_BIN = $(TO_BIN)" + @echo "TO_INC = $(TO_INC)" + @echo "TO_LIB = $(TO_LIB)" + @echo "TO_MAN = $(TO_MAN)" + +# echo config parameters as Lua code +# uncomment the last sed expression if you want nil instead of empty strings +lecho: + @echo "-- installation parameters for Lua $R" + @echo "VERSION = '$V'" + @echo "RELEASE = '$R'" + @$(MAKE) echo | grep = | sed -e 's/= /= "/' -e 's/$$/"/' #-e 's/""/nil/' + @echo "-- EOF" + +# list targets that do not create files (but not all makes understand .PHONY) +.PHONY: all $(PLATS) clean test install local none dummy echo pecho lecho + +# (end of Makefile) diff --git a/vscript/languages/lua/lua-5.1.4/README b/vscript/languages/lua/lua-5.1.4/README new file mode 100644 index 00000000..11b4dff7 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/README @@ -0,0 +1,37 @@ +README for Lua 5.1 + +See INSTALL for installation instructions. +See HISTORY for a summary of changes since the last released version. + +* What is Lua? + ------------ + Lua is a powerful, light-weight programming language designed for extending + applications. Lua is also frequently used as a general-purpose, stand-alone + language. Lua is free software. + + For complete information, visit Lua's web site at http://www.lua.org/ . + For an executive summary, see http://www.lua.org/about.html . + + Lua has been used in many different projects around the world. + For a short list, see http://www.lua.org/uses.html . + +* Availability + ------------ + Lua is freely available for both academic and commercial purposes. + See COPYRIGHT and http://www.lua.org/license.html for details. + Lua can be downloaded at http://www.lua.org/download.html . + +* Installation + ------------ + Lua is implemented in pure ANSI C, and compiles unmodified in all known + platforms that have an ANSI C compiler. In most Unix-like platforms, simply + do "make" with a suitable target. See INSTALL for detailed instructions. + +* Origin + ------ + Lua is developed at Lua.org, a laboratory of the Department of Computer + Science of PUC-Rio (the Pontifical Catholic University of Rio de Janeiro + in Brazil). + For more information about the authors, see http://www.lua.org/authors.html . + +(end of README) diff --git a/vscript/languages/lua/lua-5.1.4/doc/amazon.gif b/vscript/languages/lua/lua-5.1.4/doc/amazon.gif new file mode 100644 index 0000000000000000000000000000000000000000..f2586d5765361bb8a33a72401449f3abdefe4e16 GIT binary patch literal 797 zcmV+&1LFKgNk%w1VOjtj0K^&q@9)h50%r{k3;+NBK0Y<5t#HiDnQw1j_x9wkua=aQ zf8O4{J3ExYz@^dAvgzr__o-L@ehvGQF7LT?@$1I#;Ij3_g2%_+^3u}mmw|9dEECm0Kc!X!@|#@3&?4Fr)=|m57&HqxlCDW&_KZ+1;`8vSj33YC_e@b zLW(B90kQ_n9Ds8N3z4jU4HiAyWz9`JYknO6suY&Mn*c`+`V13=EEIuKH*uwDKrGlz zo{tDTNaHR5yf%>5cyj}g-^zXgiM@QV=g%Gh303A)7B84EpbPvE-6X=O$DmxJ`b(9|4E82-m%Ds!U< zI=HL8TMx@{~>s4%C(a0wK8Wjd@n+|5vxOvSr(vuAh- z5-e0mzlK5u3lKm6pnB`22G3HYpfaDDC`;MbMg*4 b)M@9Pc;4WH3w-wJ=bwNED(Iksh5!INDePJ9 literal 0 HcmV?d00001 diff --git a/vscript/languages/lua/lua-5.1.4/doc/contents.html b/vscript/languages/lua/lua-5.1.4/doc/contents.html new file mode 100644 index 00000000..8e58e18c --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/doc/contents.html @@ -0,0 +1,499 @@ + + + +Lua 5.1 Reference Manual - contents + + + + + + + +
+

+ +Lua 5.1 Reference Manual +

+ +This is an online version of +
+ + + +Lua 5.1 Reference Manual +
by R. Ierusalimschy, L. H. de Figueiredo, W. Celes +
Lua.org, August 2006 +
ISBN 85-903798-3-3 +
+[Buy from Amazon] +
+
+

+ +Buy a copy of this book and +help to support +the Lua project. +

+ +The reference manual is the official definition of the Lua language. +For a complete introduction to Lua programming, see the book +Programming in Lua. +

+ +start +· +contents +· +index +· +português +· +español +


+ +Copyright © 2006-2008 Lua.org, PUC-Rio. +Freely available under the terms of the +Lua license. + +

+ +

Contents

+ + +

Index

+ + + + + + + +
+

Lua functions

+_G
+_VERSION
+assert
+collectgarbage
+dofile
+error
+getfenv
+getmetatable
+ipairs
+load
+loadfile
+loadstring
+module
+next
+pairs
+pcall
+print
+rawequal
+rawget
+rawset
+require
+select
+setfenv
+setmetatable
+tonumber
+tostring
+type
+unpack
+xpcall
+

+ +coroutine.create
+coroutine.resume
+coroutine.running
+coroutine.status
+coroutine.wrap
+coroutine.yield
+

+ +debug.debug
+debug.getfenv
+debug.gethook
+debug.getinfo
+debug.getlocal
+debug.getmetatable
+debug.getregistry
+debug.getupvalue
+debug.setfenv
+debug.sethook
+debug.setlocal
+debug.setmetatable
+debug.setupvalue
+debug.traceback
+ +

+

 

+file:close
+file:flush
+file:lines
+file:read
+file:seek
+file:setvbuf
+file:write
+

+ +io.close
+io.flush
+io.input
+io.lines
+io.open
+io.output
+io.popen
+io.read
+io.stderr
+io.stdin
+io.stdout
+io.tmpfile
+io.type
+io.write
+

+ +math.abs
+math.acos
+math.asin
+math.atan
+math.atan2
+math.ceil
+math.cos
+math.cosh
+math.deg
+math.exp
+math.floor
+math.fmod
+math.frexp
+math.huge
+math.ldexp
+math.log
+math.log10
+math.max
+math.min
+math.modf
+math.pi
+math.pow
+math.rad
+math.random
+math.randomseed
+math.sin
+math.sinh
+math.sqrt
+math.tan
+math.tanh
+

+ +os.clock
+os.date
+os.difftime
+os.execute
+os.exit
+os.getenv
+os.remove
+os.rename
+os.setlocale
+os.time
+os.tmpname
+

+ +package.cpath
+package.loaded
+package.loaders
+package.loadlib
+package.path
+package.preload
+package.seeall
+

+ +string.byte
+string.char
+string.dump
+string.find
+string.format
+string.gmatch
+string.gsub
+string.len
+string.lower
+string.match
+string.rep
+string.reverse
+string.sub
+string.upper
+

+ +table.concat
+table.insert
+table.maxn
+table.remove
+table.sort
+ +

+

C API

+lua_Alloc
+lua_CFunction
+lua_Debug
+lua_Hook
+lua_Integer
+lua_Number
+lua_Reader
+lua_State
+lua_Writer
+

+ +lua_atpanic
+lua_call
+lua_checkstack
+lua_close
+lua_concat
+lua_cpcall
+lua_createtable
+lua_dump
+lua_equal
+lua_error
+lua_gc
+lua_getallocf
+lua_getfenv
+lua_getfield
+lua_getglobal
+lua_gethook
+lua_gethookcount
+lua_gethookmask
+lua_getinfo
+lua_getlocal
+lua_getmetatable
+lua_getstack
+lua_gettable
+lua_gettop
+lua_getupvalue
+lua_insert
+lua_isboolean
+lua_iscfunction
+lua_isfunction
+lua_islightuserdata
+lua_isnil
+lua_isnone
+lua_isnoneornil
+lua_isnumber
+lua_isstring
+lua_istable
+lua_isthread
+lua_isuserdata
+lua_lessthan
+lua_load
+lua_newstate
+lua_newtable
+lua_newthread
+lua_newuserdata
+lua_next
+lua_objlen
+lua_pcall
+lua_pop
+lua_pushboolean
+lua_pushcclosure
+lua_pushcfunction
+lua_pushfstring
+lua_pushinteger
+lua_pushlightuserdata
+lua_pushliteral
+lua_pushlstring
+lua_pushnil
+lua_pushnumber
+lua_pushstring
+lua_pushthread
+lua_pushvalue
+lua_pushvfstring
+lua_rawequal
+lua_rawget
+lua_rawgeti
+lua_rawset
+lua_rawseti
+lua_register
+lua_remove
+lua_replace
+lua_resume
+lua_setallocf
+lua_setfenv
+lua_setfield
+lua_setglobal
+lua_sethook
+lua_setlocal
+lua_setmetatable
+lua_settable
+lua_settop
+lua_setupvalue
+lua_status
+lua_toboolean
+lua_tocfunction
+lua_tointeger
+lua_tolstring
+lua_tonumber
+lua_topointer
+lua_tostring
+lua_tothread
+lua_touserdata
+lua_type
+lua_typename
+lua_upvalueindex
+lua_xmove
+lua_yield
+ +

+

auxiliary library

+luaL_Buffer
+luaL_Reg
+

+ +luaL_addchar
+luaL_addlstring
+luaL_addsize
+luaL_addstring
+luaL_addvalue
+luaL_argcheck
+luaL_argerror
+luaL_buffinit
+luaL_callmeta
+luaL_checkany
+luaL_checkint
+luaL_checkinteger
+luaL_checklong
+luaL_checklstring
+luaL_checknumber
+luaL_checkoption
+luaL_checkstack
+luaL_checkstring
+luaL_checktype
+luaL_checkudata
+luaL_dofile
+luaL_dostring
+luaL_error
+luaL_getmetafield
+luaL_getmetatable
+luaL_gsub
+luaL_loadbuffer
+luaL_loadfile
+luaL_loadstring
+luaL_newmetatable
+luaL_newstate
+luaL_openlibs
+luaL_optint
+luaL_optinteger
+luaL_optlong
+luaL_optlstring
+luaL_optnumber
+luaL_optstring
+luaL_prepbuffer
+luaL_pushresult
+luaL_ref
+luaL_register
+luaL_typename
+luaL_typerror
+luaL_unref
+luaL_where
+ +

+

+ +


+ +Last update: +Sat Jan 19 13:24:29 BRST 2008 + + + + + diff --git a/vscript/languages/lua/lua-5.1.4/doc/cover.png b/vscript/languages/lua/lua-5.1.4/doc/cover.png new file mode 100644 index 0000000000000000000000000000000000000000..2dbb198123f03a7250bfa57c8253739962d69afb GIT binary patch literal 3305 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 literal 0 HcmV?d00001 diff --git a/vscript/languages/lua/lua-5.1.4/doc/logo.gif b/vscript/languages/lua/lua-5.1.4/doc/logo.gif new file mode 100644 index 0000000000000000000000000000000000000000..2f5e4ac2e742fbb7675e739879211553758aea9c GIT binary patch literal 4232 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 PWz_J}_#7St0k8iB@FZjZ literal 0 HcmV?d00001 diff --git a/vscript/languages/lua/lua-5.1.4/doc/lua.1 b/vscript/languages/lua/lua-5.1.4/doc/lua.1 new file mode 100644 index 00000000..24809cc6 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/doc/lua.1 @@ -0,0 +1,163 @@ +.\" $Id: lua.man,v 1.11 2006/01/06 16:03:34 lhf Exp $ +.TH LUA 1 "$Date: 2006/01/06 16:03:34 $" +.SH NAME +lua \- Lua interpreter +.SH SYNOPSIS +.B lua +[ +.I options +] +[ +.I script +[ +.I args +] +] +.SH DESCRIPTION +.B lua +is the stand-alone Lua interpreter. +It loads and executes Lua programs, +either in textual source form or +in precompiled binary form. +(Precompiled binaries are output by +.BR luac , +the Lua compiler.) +.B lua +can be used as a batch interpreter and also interactively. +.LP +The given +.I options +(see below) +are executed and then +the Lua program in file +.I script +is loaded and executed. +The given +.I args +are available to +.I script +as strings in a global table named +.BR arg . +If these arguments contain spaces or other characters special to the shell, +then they should be quoted +(but note that the quotes will be removed by the shell). +The arguments in +.B arg +start at 0, +which contains the string +.RI ' script '. +The index of the last argument is stored in +.BR arg.n . +The arguments given in the command line before +.IR script , +including the name of the interpreter, +are available in negative indices in +.BR arg . +.LP +At the very start, +before even handling the command line, +.B lua +executes the contents of the environment variable +.BR LUA_INIT , +if it is defined. +If the value of +.B LUA_INIT +is of the form +.RI '@ filename ', +then +.I filename +is executed. +Otherwise, the string is assumed to be a Lua statement and is executed. +.LP +Options start with +.B '\-' +and are described below. +You can use +.B "'\--'" +to signal the end of options. +.LP +If no arguments are given, +then +.B "\-v \-i" +is assumed when the standard input is a terminal; +otherwise, +.B "\-" +is assumed. +.LP +In interactive mode, +.B lua +prompts the user, +reads lines from the standard input, +and executes them as they are read. +If a line does not contain a complete statement, +then a secondary prompt is displayed and +lines are read until a complete statement is formed or +a syntax error is found. +So, one way to interrupt the reading of an incomplete statement is +to force a syntax error: +adding a +.B ';' +in the middle of a statement is a sure way of forcing a syntax error +(except inside multiline strings and comments; these must be closed explicitly). +If a line starts with +.BR '=' , +then +.B lua +displays the values of all the expressions in the remainder of the +line. The expressions must be separated by commas. +The primary prompt is the value of the global variable +.BR _PROMPT , +if this value is a string; +otherwise, the default prompt is used. +Similarly, the secondary prompt is the value of the global variable +.BR _PROMPT2 . +So, +to change the prompts, +set the corresponding variable to a string of your choice. +You can do that after calling the interpreter +or on the command line +(but in this case you have to be careful with quotes +if the prompt string contains a space; otherwise you may confuse the shell.) +The default prompts are "> " and ">> ". +.SH OPTIONS +.TP +.B \- +load and execute the standard input as a file, +that is, +not interactively, +even when the standard input is a terminal. +.TP +.BI \-e " stat" +execute statement +.IR stat . +You need to quote +.I stat +if it contains spaces, quotes, +or other characters special to the shell. +.TP +.B \-i +enter interactive mode after +.I script +is executed. +.TP +.BI \-l " name" +call +.BI require(' name ') +before executing +.IR script . +Typically used to load libraries. +.TP +.B \-v +show version information. +.SH "SEE ALSO" +.BR luac (1) +.br +http://www.lua.org/ +.SH DIAGNOSTICS +Error messages should be self explanatory. +.SH AUTHORS +R. Ierusalimschy, +L. H. de Figueiredo, +and +W. Celes +.\" EOF diff --git a/vscript/languages/lua/lua-5.1.4/doc/lua.css b/vscript/languages/lua/lua-5.1.4/doc/lua.css new file mode 100644 index 00000000..039cf116 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/doc/lua.css @@ -0,0 +1,41 @@ +body { + color: #000000 ; + background-color: #FFFFFF ; + font-family: sans-serif ; + text-align: justify ; + margin-right: 20px ; + margin-left: 20px ; +} + +h1, h2, h3, h4 { + font-weight: normal ; + font-style: italic ; +} + +a:link { + color: #000080 ; + background-color: inherit ; + text-decoration: none ; +} + +a:visited { + background-color: inherit ; + text-decoration: none ; +} + +a:link:hover, a:visited:hover { + color: #000080 ; + background-color: #E0E0FF ; +} + +a:link:active, a:visited:active { + color: #FF0000 ; +} + +hr { + border: 0 ; + height: 1px ; + color: #a0a0a0 ; + background-color: #a0a0a0 ; +} + diff --git a/vscript/languages/lua/lua-5.1.4/doc/lua.html b/vscript/languages/lua/lua-5.1.4/doc/lua.html new file mode 100644 index 00000000..1d435ab0 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/doc/lua.html @@ -0,0 +1,172 @@ + + + +LUA man page + + + + + +

NAME

+lua - Lua interpreter +

SYNOPSIS

+lua +[ +options +] +[ +script +[ +args +] +] +

DESCRIPTION

+lua +is the stand-alone Lua interpreter. +It loads and executes Lua programs, +either in textual source form or +in precompiled binary form. +(Precompiled binaries are output by +luac, +the Lua compiler.) +lua +can be used as a batch interpreter and also interactively. +

+The given +options +(see below) +are executed and then +the Lua program in file +script +is loaded and executed. +The given +args +are available to +script +as strings in a global table named +arg. +If these arguments contain spaces or other characters special to the shell, +then they should be quoted +(but note that the quotes will be removed by the shell). +The arguments in +arg +start at 0, +which contains the string +'script'. +The index of the last argument is stored in +arg.n. +The arguments given in the command line before +script, +including the name of the interpreter, +are available in negative indices in +arg. +

+At the very start, +before even handling the command line, +lua +executes the contents of the environment variable +LUA_INIT, +if it is defined. +If the value of +LUA_INIT +is of the form +'@filename', +then +filename +is executed. +Otherwise, the string is assumed to be a Lua statement and is executed. +

+Options start with +'-' +and are described below. +You can use +'--' +to signal the end of options. +

+If no arguments are given, +then +"-v -i" +is assumed when the standard input is a terminal; +otherwise, +"-" +is assumed. +

+In interactive mode, +lua +prompts the user, +reads lines from the standard input, +and executes them as they are read. +If a line does not contain a complete statement, +then a secondary prompt is displayed and +lines are read until a complete statement is formed or +a syntax error is found. +So, one way to interrupt the reading of an incomplete statement is +to force a syntax error: +adding a +';' +in the middle of a statement is a sure way of forcing a syntax error +(except inside multiline strings and comments; these must be closed explicitly). +If a line starts with +'=', +then +lua +displays the values of all the expressions in the remainder of the +line. The expressions must be separated by commas. +The primary prompt is the value of the global variable +_PROMPT, +if this value is a string; +otherwise, the default prompt is used. +Similarly, the secondary prompt is the value of the global variable +_PROMPT2. +So, +to change the prompts, +set the corresponding variable to a string of your choice. +You can do that after calling the interpreter +or on the command line +(but in this case you have to be careful with quotes +if the prompt string contains a space; otherwise you may confuse the shell.) +The default prompts are "> " and ">> ". +

OPTIONS

+

+- +load and execute the standard input as a file, +that is, +not interactively, +even when the standard input is a terminal. +

+-e stat +execute statement +stat. +You need to quote +stat +if it contains spaces, quotes, +or other characters special to the shell. +

+-i +enter interactive mode after +script +is executed. +

+-l name +call +require('name') +before executing +script. +Typically used to load libraries. +

+-v +show version information. +

SEE ALSO

+luac(1) +
+http://www.lua.org/ +

DIAGNOSTICS

+Error messages should be self explanatory. +

AUTHORS

+R. Ierusalimschy, +L. H. de Figueiredo, +and +W. Celes + + + diff --git a/vscript/languages/lua/lua-5.1.4/doc/luac.1 b/vscript/languages/lua/lua-5.1.4/doc/luac.1 new file mode 100644 index 00000000..d8146782 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/doc/luac.1 @@ -0,0 +1,136 @@ +.\" $Id: luac.man,v 1.28 2006/01/06 16:03:34 lhf Exp $ +.TH LUAC 1 "$Date: 2006/01/06 16:03:34 $" +.SH NAME +luac \- Lua compiler +.SH SYNOPSIS +.B luac +[ +.I options +] [ +.I filenames +] +.SH DESCRIPTION +.B luac +is the Lua compiler. +It translates programs written in the Lua programming language +into binary files that can be later loaded and executed. +.LP +The main advantages of precompiling chunks are: +faster loading, +protecting source code from accidental user changes, +and +off-line syntax checking. +.LP +Pre-compiling does not imply faster execution +because in Lua chunks are always compiled into bytecodes before being executed. +.B luac +simply allows those bytecodes to be saved in a file for later execution. +.LP +Pre-compiled chunks are not necessarily smaller than the corresponding source. +The main goal in pre-compiling is faster loading. +.LP +The binary files created by +.B luac +are portable only among architectures with the same word size and byte order. +.LP +.B luac +produces a single output file containing the bytecodes +for all source files given. +By default, +the output file is named +.BR luac.out , +but you can change this with the +.B \-o +option. +.LP +In the command line, +you can mix +text files containing Lua source and +binary files containing precompiled chunks. +This is useful to combine several precompiled chunks, +even from different (but compatible) platforms, +into a single precompiled chunk. +.LP +You can use +.B "'\-'" +to indicate the standard input as a source file +and +.B "'\--'" +to signal the end of options +(that is, +all remaining arguments will be treated as files even if they start with +.BR "'\-'" ). +.LP +The internal format of the binary files produced by +.B luac +is likely to change when a new version of Lua is released. +So, +save the source files of all Lua programs that you precompile. +.LP +.SH OPTIONS +Options must be separate. +.TP +.B \-l +produce a listing of the compiled bytecode for Lua's virtual machine. +Listing bytecodes is useful to learn about Lua's virtual machine. +If no files are given, then +.B luac +loads +.B luac.out +and lists its contents. +.TP +.BI \-o " file" +output to +.IR file , +instead of the default +.BR luac.out . +(You can use +.B "'\-'" +for standard output, +but not on platforms that open standard output in text mode.) +The output file may be a source file because +all files are loaded before the output file is written. +Be careful not to overwrite precious files. +.TP +.B \-p +load files but do not generate any output file. +Used mainly for syntax checking and for testing precompiled chunks: +corrupted files will probably generate errors when loaded. +Lua always performs a thorough integrity test on precompiled chunks. +Bytecode that passes this test is completely safe, +in the sense that it will not break the interpreter. +However, +there is no guarantee that such code does anything sensible. +(None can be given, because the halting problem is unsolvable.) +If no files are given, then +.B luac +loads +.B luac.out +and tests its contents. +No messages are displayed if the file passes the integrity test. +.TP +.B \-s +strip debug information before writing the output file. +This saves some space in very large chunks, +but if errors occur when running a stripped chunk, +then the error messages may not contain the full information they usually do. +For instance, +line numbers and names of local variables are lost. +.TP +.B \-v +show version information. +.SH FILES +.TP 15 +.B luac.out +default output file +.SH "SEE ALSO" +.BR lua (1) +.br +http://www.lua.org/ +.SH DIAGNOSTICS +Error messages should be self explanatory. +.SH AUTHORS +L. H. de Figueiredo, +R. Ierusalimschy and +W. Celes +.\" EOF diff --git a/vscript/languages/lua/lua-5.1.4/doc/luac.html b/vscript/languages/lua/lua-5.1.4/doc/luac.html new file mode 100644 index 00000000..179ffe82 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/doc/luac.html @@ -0,0 +1,145 @@ + + + +LUAC man page + + + + + +

NAME

+luac - Lua compiler +

SYNOPSIS

+luac +[ +options +] [ +filenames +] +

DESCRIPTION

+luac +is the Lua compiler. +It translates programs written in the Lua programming language +into binary files that can be later loaded and executed. +

+The main advantages of precompiling chunks are: +faster loading, +protecting source code from accidental user changes, +and +off-line syntax checking. +

+Precompiling does not imply faster execution +because in Lua chunks are always compiled into bytecodes before being executed. +luac +simply allows those bytecodes to be saved in a file for later execution. +

+Precompiled chunks are not necessarily smaller than the corresponding source. +The main goal in precompiling is faster loading. +

+The binary files created by +luac +are portable only among architectures with the same word size and byte order. +

+luac +produces a single output file containing the bytecodes +for all source files given. +By default, +the output file is named +luac.out, +but you can change this with the +-o +option. +

+In the command line, +you can mix +text files containing Lua source and +binary files containing precompiled chunks. +This is useful because several precompiled chunks, +even from different (but compatible) platforms, +can be combined into a single precompiled chunk. +

+You can use +'-' +to indicate the standard input as a source file +and +'--' +to signal the end of options +(that is, +all remaining arguments will be treated as files even if they start with +'-'). +

+The internal format of the binary files produced by +luac +is likely to change when a new version of Lua is released. +So, +save the source files of all Lua programs that you precompile. +

+

OPTIONS

+Options must be separate. +

+-l +produce a listing of the compiled bytecode for Lua's virtual machine. +Listing bytecodes is useful to learn about Lua's virtual machine. +If no files are given, then +luac +loads +luac.out +and lists its contents. +

+-o file +output to +file, +instead of the default +luac.out. +(You can use +'-' +for standard output, +but not on platforms that open standard output in text mode.) +The output file may be a source file because +all files are loaded before the output file is written. +Be careful not to overwrite precious files. +

+-p +load files but do not generate any output file. +Used mainly for syntax checking and for testing precompiled chunks: +corrupted files will probably generate errors when loaded. +Lua always performs a thorough integrity test on precompiled chunks. +Bytecode that passes this test is completely safe, +in the sense that it will not break the interpreter. +However, +there is no guarantee that such code does anything sensible. +(None can be given, because the halting problem is unsolvable.) +If no files are given, then +luac +loads +luac.out +and tests its contents. +No messages are displayed if the file passes the integrity test. +

+-s +strip debug information before writing the output file. +This saves some space in very large chunks, +but if errors occur when running a stripped chunk, +then the error messages may not contain the full information they usually do. +For instance, +line numbers and names of local variables are lost. +

+-v +show version information. +

FILES

+

+luac.out +default output file +

SEE ALSO

+lua(1) +
+http://www.lua.org/ +

DIAGNOSTICS

+Error messages should be self explanatory. +

AUTHORS

+L. H. de Figueiredo, +R. Ierusalimschy and +W. Celes + + + diff --git a/vscript/languages/lua/lua-5.1.4/doc/manual.css b/vscript/languages/lua/lua-5.1.4/doc/manual.css new file mode 100644 index 00000000..eed5afd9 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/doc/manual.css @@ -0,0 +1,13 @@ +h3 code { + font-family: inherit ; +} + +pre { + font-size: 105% ; +} + +span.apii { + float: right ; + font-family: inherit ; +} + diff --git a/vscript/languages/lua/lua-5.1.4/doc/manual.html b/vscript/languages/lua/lua-5.1.4/doc/manual.html new file mode 100644 index 00000000..f46f17c8 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/doc/manual.html @@ -0,0 +1,8801 @@ + + + + +Lua 5.1 Reference Manual + + + + + + + +
+

+ +Lua 5.1 Reference Manual +

+ +by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes +

+ +Copyright © 2006-2008 Lua.org, PUC-Rio. +Freely available under the terms of the +Lua license. + +


+

+ +contents +· +index + + +

+ + + + + + +

1 - Introduction

+ +

+Lua is an extension programming language designed to support +general procedural programming with data description +facilities. +It also offers good support for object-oriented programming, +functional programming, and data-driven programming. +Lua is intended to be used as a powerful, light-weight +scripting language for any program that needs one. +Lua is implemented as a library, written in clean C +(that is, in the common subset of ANSI C and C++). + + +

+Being an extension language, Lua has no notion of a "main" program: +it only works embedded in a host client, +called the embedding program or simply the host. +This host program can invoke functions to execute a piece of Lua code, +can write and read Lua variables, +and can register C functions to be called by Lua code. +Through the use of C functions, Lua can be augmented to cope with +a wide range of different domains, +thus creating customized programming languages sharing a syntactical framework. +The Lua distribution includes a sample host program called lua, +which uses the Lua library to offer a complete, stand-alone Lua interpreter. + + +

+Lua is free software, +and is provided as usual with no guarantees, +as stated in its license. +The implementation described in this manual is available +at Lua's official web site, www.lua.org. + + +

+Like any other reference manual, +this document is dry in places. +For a discussion of the decisions behind the design of Lua, +see the technical papers available at Lua's web site. +For a detailed introduction to programming in Lua, +see Roberto's book, Programming in Lua (Second Edition). + + + +

2 - The Language

+ +

+This section describes the lexis, the syntax, and the semantics of Lua. +In other words, +this section describes +which tokens are valid, +how they can be combined, +and what their combinations mean. + + +

+The language constructs will be explained using the usual extended BNF notation, +in which +{a} means 0 or more a's, and +[a] means an optional a. +Non-terminals are shown like non-terminal, +keywords are shown like kword, +and other terminal symbols are shown like `=´. +The complete syntax of Lua can be found in §8 +at the end of this manual. + + + +

2.1 - Lexical Conventions

+ +

+Names +(also called identifiers) +in Lua can be any string of letters, +digits, and underscores, +not beginning with a digit. +This coincides with the definition of names in most languages. +(The definition of letter depends on the current locale: +any character considered alphabetic by the current locale +can be used in an identifier.) +Identifiers are used to name variables and table fields. + + +

+The following keywords are reserved +and cannot be used as names: + + +

+     and       break     do        else      elseif
+     end       false     for       function  if
+     in        local     nil       not       or
+     repeat    return    then      true      until     while
+
+ +

+Lua is a case-sensitive language: +and is a reserved word, but And and AND +are two different, valid names. +As a convention, names starting with an underscore followed by +uppercase letters (such as _VERSION) +are reserved for internal global variables used by Lua. + + +

+The following strings denote other tokens: + +

+     +     -     *     /     %     ^     #
+     ==    ~=    <=    >=    <     >     =
+     (     )     {     }     [     ]
+     ;     :     ,     .     ..    ...
+
+ +

+Literal strings +can be delimited by matching single or double quotes, +and can contain the following C-like escape sequences: +'\a' (bell), +'\b' (backspace), +'\f' (form feed), +'\n' (newline), +'\r' (carriage return), +'\t' (horizontal tab), +'\v' (vertical tab), +'\\' (backslash), +'\"' (quotation mark [double quote]), +and '\'' (apostrophe [single quote]). +Moreover, a backslash followed by a real newline +results in a newline in the string. +A character in a string can also be specified by its numerical value +using the escape sequence \ddd, +where ddd is a sequence of up to three decimal digits. +(Note that if a numerical escape is to be followed by a digit, +it must be expressed using exactly three digits.) +Strings in Lua can contain any 8-bit value, including embedded zeros, +which can be specified as '\0'. + + +

+Literal strings can also be defined using a long format +enclosed by long brackets. +We define an opening long bracket of level n as an opening +square bracket followed by n equal signs followed by another +opening square bracket. +So, an opening long bracket of level 0 is written as [[, +an opening long bracket of level 1 is written as [=[, +and so on. +A closing long bracket is defined similarly; +for instance, a closing long bracket of level 4 is written as ]====]. +A long string starts with an opening long bracket of any level and +ends at the first closing long bracket of the same level. +Literals in this bracketed form can run for several lines, +do not interpret any escape sequences, +and ignore long brackets of any other level. +They can contain anything except a closing bracket of the proper level. + + +

+For convenience, +when the opening long bracket is immediately followed by a newline, +the newline is not included in the string. +As an example, in a system using ASCII +(in which 'a' is coded as 97, +newline is coded as 10, and '1' is coded as 49), +the five literal strings below denote the same string: + +

+     a = 'alo\n123"'
+     a = "alo\n123\""
+     a = '\97lo\10\04923"'
+     a = [[alo
+     123"]]
+     a = [==[
+     alo
+     123"]==]
+
+ +

+A numerical constant can be written with an optional decimal part +and an optional decimal exponent. +Lua also accepts integer hexadecimal constants, +by prefixing them with 0x. +Examples of valid numerical constants are + +

+     3   3.0   3.1416   314.16e-2   0.31416E1   0xff   0x56
+
+ +

+A comment starts with a double hyphen (--) +anywhere outside a string. +If the text immediately after -- is not an opening long bracket, +the comment is a short comment, +which runs until the end of the line. +Otherwise, it is a long comment, +which runs until the corresponding closing long bracket. +Long comments are frequently used to disable code temporarily. + + + + + +

2.2 - Values and Types

+ +

+Lua is a dynamically typed language. +This means that +variables do not have types; only values do. +There are no type definitions in the language. +All values carry their own type. + + +

+All values in Lua are first-class values. +This means that all values can be stored in variables, +passed as arguments to other functions, and returned as results. + + +

+There are eight basic types in Lua: +nil, boolean, number, +string, function, userdata, +thread, and table. +Nil is the type of the value nil, +whose main property is to be different from any other value; +it usually represents the absence of a useful value. +Boolean is the type of the values false and true. +Both nil and false make a condition false; +any other value makes it true. +Number represents real (double-precision floating-point) numbers. +(It is easy to build Lua interpreters that use other +internal representations for numbers, +such as single-precision float or long integers; +see file luaconf.h.) +String represents arrays of characters. + +Lua is 8-bit clean: +strings can contain any 8-bit character, +including embedded zeros ('\0') (see §2.1). + + +

+Lua can call (and manipulate) functions written in Lua and +functions written in C +(see §2.5.8). + + +

+The type userdata is provided to allow arbitrary C data to +be stored in Lua variables. +This type corresponds to a block of raw memory +and has no pre-defined operations in Lua, +except assignment and identity test. +However, by using metatables, +the programmer can define operations for userdata values +(see §2.8). +Userdata values cannot be created or modified in Lua, +only through the C API. +This guarantees the integrity of data owned by the host program. + + +

+The type thread represents independent threads of execution +and it is used to implement coroutines (see §2.11). +Do not confuse Lua threads with operating-system threads. +Lua supports coroutines on all systems, +even those that do not support threads. + + +

+The type table implements associative arrays, +that is, arrays that can be indexed not only with numbers, +but with any value (except nil). +Tables can be heterogeneous; +that is, they can contain values of all types (except nil). +Tables are the sole data structuring mechanism in Lua; +they can be used to represent ordinary arrays, +symbol tables, sets, records, graphs, trees, etc. +To represent records, Lua uses the field name as an index. +The language supports this representation by +providing a.name as syntactic sugar for a["name"]. +There are several convenient ways to create tables in Lua +(see §2.5.7). + + +

+Like indices, +the value of a table field can be of any type (except nil). +In particular, +because functions are first-class values, +table fields can contain functions. +Thus tables can also carry methods (see §2.5.9). + + +

+Tables, functions, threads, and (full) userdata values are objects: +variables do not actually contain these values, +only references to them. +Assignment, parameter passing, and function returns +always manipulate references to such values; +these operations do not imply any kind of copy. + + +

+The library function type returns a string describing the type +of a given value. + + + +

2.2.1 - Coercion

+ +

+Lua provides automatic conversion between +string and number values at run time. +Any arithmetic operation applied to a string tries to convert +this string to a number, following the usual conversion rules. +Conversely, whenever a number is used where a string is expected, +the number is converted to a string, in a reasonable format. +For complete control over how numbers are converted to strings, +use the format function from the string library +(see string.format). + + + + + + + +

2.3 - Variables

+ +

+Variables are places that store values. + +There are three kinds of variables in Lua: +global variables, local variables, and table fields. + + +

+A single name can denote a global variable or a local variable +(or a function's formal parameter, +which is a particular kind of local variable): + +

+	var ::= Name
+

+Name denotes identifiers, as defined in §2.1. + + +

+Any variable is assumed to be global unless explicitly declared +as a local (see §2.4.7). +Local variables are lexically scoped: +local variables can be freely accessed by functions +defined inside their scope (see §2.6). + + +

+Before the first assignment to a variable, its value is nil. + + +

+Square brackets are used to index a table: + +

+	var ::= prefixexp `[´ exp `]´
+

+The meaning of accesses to global variables +and table fields can be changed via metatables. +An access to an indexed variable t[i] is equivalent to +a call gettable_event(t,i). +(See §2.8 for a complete description of the +gettable_event function. +This function is not defined or callable in Lua. +We use it here only for explanatory purposes.) + + +

+The syntax var.Name is just syntactic sugar for +var["Name"]: + +

+	var ::= prefixexp `.´ Name
+
+ +

+All global variables live as fields in ordinary Lua tables, +called environment tables or simply +environments (see §2.9). +Each function has its own reference to an environment, +so that all global variables in this function +will refer to this environment table. +When a function is created, +it inherits the environment from the function that created it. +To get the environment table of a Lua function, +you call getfenv. +To replace it, +you call setfenv. +(You can only manipulate the environment of C functions +through the debug library; (see §5.9).) + + +

+An access to a global variable x +is equivalent to _env.x, +which in turn is equivalent to + +

+     gettable_event(_env, "x")
+

+where _env is the environment of the running function. +(See §2.8 for a complete description of the +gettable_event function. +This function is not defined or callable in Lua. +Similarly, the _env variable is not defined in Lua. +We use them here only for explanatory purposes.) + + + + + +

2.4 - Statements

+ +

+Lua supports an almost conventional set of statements, +similar to those in Pascal or C. +This set includes +assignments, control structures, function calls, +and variable declarations. + + + +

2.4.1 - Chunks

+ +

+The unit of execution of Lua is called a chunk. +A chunk is simply a sequence of statements, +which are executed sequentially. +Each statement can be optionally followed by a semicolon: + +

+	chunk ::= {stat [`;´]}
+

+There are no empty statements and thus ';;' is not legal. + + +

+Lua handles a chunk as the body of an anonymous function +with a variable number of arguments +(see §2.5.9). +As such, chunks can define local variables, +receive arguments, and return values. + + +

+A chunk can be stored in a file or in a string inside the host program. +To execute a chunk, +Lua first pre-compiles the chunk into instructions for a virtual machine, +and then it executes the compiled code +with an interpreter for the virtual machine. + + +

+Chunks can also be pre-compiled into binary form; +see program luac for details. +Programs in source and compiled forms are interchangeable; +Lua automatically detects the file type and acts accordingly. + + + + + + +

2.4.2 - Blocks

+A block is a list of statements; +syntactically, a block is the same as a chunk: + +

+	block ::= chunk
+
+ +

+A block can be explicitly delimited to produce a single statement: + +

+	stat ::= do block end
+

+Explicit blocks are useful +to control the scope of variable declarations. +Explicit blocks are also sometimes used to +add a return or break statement in the middle +of another block (see §2.4.4). + + + + + +

2.4.3 - Assignment

+ +

+Lua allows multiple assignments. +Therefore, the syntax for assignment +defines a list of variables on the left side +and a list of expressions on the right side. +The elements in both lists are separated by commas: + +

+	stat ::= varlist `=´ explist
+	varlist ::= var {`,´ var}
+	explist ::= exp {`,´ exp}
+

+Expressions are discussed in §2.5. + + +

+Before the assignment, +the list of values is adjusted to the length of +the list of variables. +If there are more values than needed, +the excess values are thrown away. +If there are fewer values than needed, +the list is extended with as many nil's as needed. +If the list of expressions ends with a function call, +then all values returned by that call enter the list of values, +before the adjustment +(except when the call is enclosed in parentheses; see §2.5). + + +

+The assignment statement first evaluates all its expressions +and only then are the assignments performed. +Thus the code + +

+     i = 3
+     i, a[i] = i+1, 20
+

+sets a[3] to 20, without affecting a[4] +because the i in a[i] is evaluated (to 3) +before it is assigned 4. +Similarly, the line + +

+     x, y = y, x
+

+exchanges the values of x and y, +and + +

+     x, y, z = y, z, x
+

+cyclically permutes the values of x, y, and z. + + +

+The meaning of assignments to global variables +and table fields can be changed via metatables. +An assignment to an indexed variable t[i] = val is equivalent to +settable_event(t,i,val). +(See §2.8 for a complete description of the +settable_event function. +This function is not defined or callable in Lua. +We use it here only for explanatory purposes.) + + +

+An assignment to a global variable x = val +is equivalent to the assignment +_env.x = val, +which in turn is equivalent to + +

+     settable_event(_env, "x", val)
+

+where _env is the environment of the running function. +(The _env variable is not defined in Lua. +We use it here only for explanatory purposes.) + + + + + +

2.4.4 - Control Structures

+The control structures +if, while, and repeat have the usual meaning and +familiar syntax: + + + + +

+	stat ::= while exp do block end
+	stat ::= repeat block until exp
+	stat ::= if exp then block {elseif exp then block} [else block] end
+

+Lua also has a for statement, in two flavors (see §2.4.5). + + +

+The condition expression of a +control structure can return any value. +Both false and nil are considered false. +All values different from nil and false are considered true +(in particular, the number 0 and the empty string are also true). + + +

+In the repeatuntil loop, +the inner block does not end at the until keyword, +but only after the condition. +So, the condition can refer to local variables +declared inside the loop block. + + +

+The return statement is used to return values +from a function or a chunk (which is just a function). + +Functions and chunks can return more than one value, +and so the syntax for the return statement is + +

+	stat ::= return [explist]
+
+ +

+The break statement is used to terminate the execution of a +while, repeat, or for loop, +skipping to the next statement after the loop: + + +

+	stat ::= break
+

+A break ends the innermost enclosing loop. + + +

+The return and break +statements can only be written as the last statement of a block. +If it is really necessary to return or break in the +middle of a block, +then an explicit inner block can be used, +as in the idioms +do return end and do break end, +because now return and break are the last statements in +their (inner) blocks. + + + + + +

2.4.5 - For Statement

+ +

+ +The for statement has two forms: +one numeric and one generic. + + +

+The numeric for loop repeats a block of code while a +control variable runs through an arithmetic progression. +It has the following syntax: + +

+	stat ::= for Name `=´ exp `,´ exp [`,´ exp] do block end
+

+The block is repeated for name starting at the value of +the first exp, until it passes the second exp by steps of the +third exp. +More precisely, a for statement like + +

+     for v = e1, e2, e3 do block end
+

+is equivalent to the code: + +

+     do
+       local var, limit, step = tonumber(e1), tonumber(e2), tonumber(e3)
+       if not (var and limit and step) then error() end
+       while (step > 0 and var <= limit) or (step <= 0 and var >= limit) do
+         local v = var
+         block
+         var = var + step
+       end
+     end
+

+Note the following: + +

    + +
  • +All three control expressions are evaluated only once, +before the loop starts. +They must all result in numbers. +
  • + +
  • +var, limit, and step are invisible variables. +The names shown here are for explanatory purposes only. +
  • + +
  • +If the third expression (the step) is absent, +then a step of 1 is used. +
  • + +
  • +You can use break to exit a for loop. +
  • + +
  • +The loop variable v is local to the loop; +you cannot use its value after the for ends or is broken. +If you need this value, +assign it to another variable before breaking or exiting the loop. +
  • + +
+ +

+The generic for statement works over functions, +called iterators. +On each iteration, the iterator function is called to produce a new value, +stopping when this new value is nil. +The generic for loop has the following syntax: + +

+	stat ::= for namelist in explist do block end
+	namelist ::= Name {`,´ Name}
+

+A for statement like + +

+     for var_1, ···, var_n in explist do block end
+

+is equivalent to the code: + +

+     do
+       local f, s, var = explist
+       while true do
+         local var_1, ···, var_n = f(s, var)
+         var = var_1
+         if var == nil then break end
+         block
+       end
+     end
+

+Note the following: + +

    + +
  • +explist is evaluated only once. +Its results are an iterator function, +a state, +and an initial value for the first iterator variable. +
  • + +
  • +f, s, and var are invisible variables. +The names are here for explanatory purposes only. +
  • + +
  • +You can use break to exit a for loop. +
  • + +
  • +The loop variables var_i are local to the loop; +you cannot use their values after the for ends. +If you need these values, +then assign them to other variables before breaking or exiting the loop. +
  • + +
+ + + + +

2.4.6 - Function Calls as Statements

+To allow possible side-effects, +function calls can be executed as statements: + +

+	stat ::= functioncall
+

+In this case, all returned values are thrown away. +Function calls are explained in §2.5.8. + + + + + +

2.4.7 - Local Declarations

+Local variables can be declared anywhere inside a block. +The declaration can include an initial assignment: + +

+	stat ::= local namelist [`=´ explist]
+

+If present, an initial assignment has the same semantics +of a multiple assignment (see §2.4.3). +Otherwise, all variables are initialized with nil. + + +

+A chunk is also a block (see §2.4.1), +and so local variables can be declared in a chunk outside any explicit block. +The scope of such local variables extends until the end of the chunk. + + +

+The visibility rules for local variables are explained in §2.6. + + + + + + + +

2.5 - Expressions

+ +

+The basic expressions in Lua are the following: + +

+	exp ::= prefixexp
+	exp ::= nil | false | true
+	exp ::= Number
+	exp ::= String
+	exp ::= function
+	exp ::= tableconstructor
+	exp ::= `...´
+	exp ::= exp binop exp
+	exp ::= unop exp
+	prefixexp ::= var | functioncall | `(´ exp `)´
+
+ +

+Numbers and literal strings are explained in §2.1; +variables are explained in §2.3; +function definitions are explained in §2.5.9; +function calls are explained in §2.5.8; +table constructors are explained in §2.5.7. +Vararg expressions, +denoted by three dots ('...'), can only be used when +directly inside a vararg function; +they are explained in §2.5.9. + + +

+Binary operators comprise arithmetic operators (see §2.5.1), +relational operators (see §2.5.2), logical operators (see §2.5.3), +and the concatenation operator (see §2.5.4). +Unary operators comprise the unary minus (see §2.5.1), +the unary not (see §2.5.3), +and the unary length operator (see §2.5.5). + + +

+Both function calls and vararg expressions can result in multiple values. +If an expression is used as a statement +(only possible for function calls (see §2.4.6)), +then its return list is adjusted to zero elements, +thus discarding all returned values. +If an expression is used as the last (or the only) element +of a list of expressions, +then no adjustment is made +(unless the call is enclosed in parentheses). +In all other contexts, +Lua adjusts the result list to one element, +discarding all values except the first one. + + +

+Here are some examples: + +

+     f()                -- adjusted to 0 results
+     g(f(), x)          -- f() is adjusted to 1 result
+     g(x, f())          -- g gets x plus all results from f()
+     a,b,c = f(), x     -- f() is adjusted to 1 result (c gets nil)
+     a,b = ...          -- a gets the first vararg parameter, b gets
+                        -- the second (both a and b can get nil if there
+                        -- is no corresponding vararg parameter)
+     
+     a,b,c = x, f()     -- f() is adjusted to 2 results
+     a,b,c = f()        -- f() is adjusted to 3 results
+     return f()         -- returns all results from f()
+     return ...         -- returns all received vararg parameters
+     return x,y,f()     -- returns x, y, and all results from f()
+     {f()}              -- creates a list with all results from f()
+     {...}              -- creates a list with all vararg parameters
+     {f(), nil}         -- f() is adjusted to 1 result
+
+ +

+Any expression enclosed in parentheses always results in only one value. +Thus, +(f(x,y,z)) is always a single value, +even if f returns several values. +(The value of (f(x,y,z)) is the first value returned by f +or nil if f does not return any values.) + + + +

2.5.1 - Arithmetic Operators

+Lua supports the usual arithmetic operators: +the binary + (addition), +- (subtraction), * (multiplication), +/ (division), % (modulo), and ^ (exponentiation); +and unary - (negation). +If the operands are numbers, or strings that can be converted to +numbers (see §2.2.1), +then all operations have the usual meaning. +Exponentiation works for any exponent. +For instance, x^(-0.5) computes the inverse of the square root of x. +Modulo is defined as + +

+     a % b == a - math.floor(a/b)*b
+

+That is, it is the remainder of a division that rounds +the quotient towards minus infinity. + + + + + +

2.5.2 - Relational Operators

+The relational operators in Lua are + +

+     ==    ~=    <     >     <=    >=
+

+These operators always result in false or true. + + +

+Equality (==) first compares the type of its operands. +If the types are different, then the result is false. +Otherwise, the values of the operands are compared. +Numbers and strings are compared in the usual way. +Objects (tables, userdata, threads, and functions) +are compared by reference: +two objects are considered equal only if they are the same object. +Every time you create a new object +(a table, userdata, thread, or function), +this new object is different from any previously existing object. + + +

+You can change the way that Lua compares tables and userdata +by using the "eq" metamethod (see §2.8). + + +

+The conversion rules of §2.2.1 +do not apply to equality comparisons. +Thus, "0"==0 evaluates to false, +and t[0] and t["0"] denote different +entries in a table. + + +

+The operator ~= is exactly the negation of equality (==). + + +

+The order operators work as follows. +If both arguments are numbers, then they are compared as such. +Otherwise, if both arguments are strings, +then their values are compared according to the current locale. +Otherwise, Lua tries to call the "lt" or the "le" +metamethod (see §2.8). +A comparison a > b is translated to b < a +and a >= b is translated to b <= a. + + + + + +

2.5.3 - Logical Operators

+The logical operators in Lua are +and, or, and not. +Like the control structures (see §2.4.4), +all logical operators consider both false and nil as false +and anything else as true. + + +

+The negation operator not always returns false or true. +The conjunction operator and returns its first argument +if this value is false or nil; +otherwise, and returns its second argument. +The disjunction operator or returns its first argument +if this value is different from nil and false; +otherwise, or returns its second argument. +Both and and or use short-cut evaluation; +that is, +the second operand is evaluated only if necessary. +Here are some examples: + +

+     10 or 20            --> 10
+     10 or error()       --> 10
+     nil or "a"          --> "a"
+     nil and 10          --> nil
+     false and error()   --> false
+     false and nil       --> false
+     false or nil        --> nil
+     10 and 20           --> 20
+

+(In this manual, +--> indicates the result of the preceding expression.) + + + + + +

2.5.4 - Concatenation

+The string concatenation operator in Lua is +denoted by two dots ('..'). +If both operands are strings or numbers, then they are converted to +strings according to the rules mentioned in §2.2.1. +Otherwise, the "concat" metamethod is called (see §2.8). + + + + + +

2.5.5 - The Length Operator

+ +

+The length operator is denoted by the unary operator #. +The length of a string is its number of bytes +(that is, the usual meaning of string length when each +character is one byte). + + +

+The length of a table t is defined to be any +integer index n +such that t[n] is not nil and t[n+1] is nil; +moreover, if t[1] is nil, n can be zero. +For a regular array, with non-nil values from 1 to a given n, +its length is exactly that n, +the index of its last value. +If the array has "holes" +(that is, nil values between other non-nil values), +then #t can be any of the indices that +directly precedes a nil value +(that is, it may consider any such nil value as the end of +the array). + + + + + +

2.5.6 - Precedence

+Operator precedence in Lua follows the table below, +from lower to higher priority: + +

+     or
+     and
+     <     >     <=    >=    ~=    ==
+     ..
+     +     -
+     *     /     %
+     not   #     - (unary)
+     ^
+

+As usual, +you can use parentheses to change the precedences of an expression. +The concatenation ('..') and exponentiation ('^') +operators are right associative. +All other binary operators are left associative. + + + + + +

2.5.7 - Table Constructors

+Table constructors are expressions that create tables. +Every time a constructor is evaluated, a new table is created. +A constructor can be used to create an empty table +or to create a table and initialize some of its fields. +The general syntax for constructors is + +

+	tableconstructor ::= `{´ [fieldlist] `}´
+	fieldlist ::= field {fieldsep field} [fieldsep]
+	field ::= `[´ exp `]´ `=´ exp | Name `=´ exp | exp
+	fieldsep ::= `,´ | `;´
+
+ +

+Each field of the form [exp1] = exp2 adds to the new table an entry +with key exp1 and value exp2. +A field of the form name = exp is equivalent to +["name"] = exp. +Finally, fields of the form exp are equivalent to +[i] = exp, where i are consecutive numerical integers, +starting with 1. +Fields in the other formats do not affect this counting. +For example, + +

+     a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 }
+

+is equivalent to + +

+     do
+       local t = {}
+       t[f(1)] = g
+       t[1] = "x"         -- 1st exp
+       t[2] = "y"         -- 2nd exp
+       t.x = 1            -- t["x"] = 1
+       t[3] = f(x)        -- 3rd exp
+       t[30] = 23
+       t[4] = 45          -- 4th exp
+       a = t
+     end
+
+ +

+If the last field in the list has the form exp +and the expression is a function call or a vararg expression, +then all values returned by this expression enter the list consecutively +(see §2.5.8). +To avoid this, +enclose the function call or the vararg expression +in parentheses (see §2.5). + + +

+The field list can have an optional trailing separator, +as a convenience for machine-generated code. + + + + + +

2.5.8 - Function Calls

+A function call in Lua has the following syntax: + +

+	functioncall ::= prefixexp args
+

+In a function call, +first prefixexp and args are evaluated. +If the value of prefixexp has type function, +then this function is called +with the given arguments. +Otherwise, the prefixexp "call" metamethod is called, +having as first parameter the value of prefixexp, +followed by the original call arguments +(see §2.8). + + +

+The form + +

+	functioncall ::= prefixexp `:´ Name args
+

+can be used to call "methods". +A call v:name(args) +is syntactic sugar for v.name(v,args), +except that v is evaluated only once. + + +

+Arguments have the following syntax: + +

+	args ::= `(´ [explist] `)´
+	args ::= tableconstructor
+	args ::= String
+

+All argument expressions are evaluated before the call. +A call of the form f{fields} is +syntactic sugar for f({fields}); +that is, the argument list is a single new table. +A call of the form f'string' +(or f"string" or f[[string]]) +is syntactic sugar for f('string'); +that is, the argument list is a single literal string. + + +

+As an exception to the free-format syntax of Lua, +you cannot put a line break before the '(' in a function call. +This restriction avoids some ambiguities in the language. +If you write + +

+     a = f
+     (g).x(a)
+

+Lua would see that as a single statement, a = f(g).x(a). +So, if you want two statements, you must add a semi-colon between them. +If you actually want to call f, +you must remove the line break before (g). + + +

+A call of the form return functioncall is called +a tail call. +Lua implements proper tail calls +(or proper tail recursion): +in a tail call, +the called function reuses the stack entry of the calling function. +Therefore, there is no limit on the number of nested tail calls that +a program can execute. +However, a tail call erases any debug information about the +calling function. +Note that a tail call only happens with a particular syntax, +where the return has one single function call as argument; +this syntax makes the calling function return exactly +the returns of the called function. +So, none of the following examples are tail calls: + +

+     return (f(x))        -- results adjusted to 1
+     return 2 * f(x)
+     return x, f(x)       -- additional results
+     f(x); return         -- results discarded
+     return x or f(x)     -- results adjusted to 1
+
+ + + + +

2.5.9 - Function Definitions

+ +

+The syntax for function definition is + +

+	function ::= function funcbody
+	funcbody ::= `(´ [parlist] `)´ block end
+
+ +

+The following syntactic sugar simplifies function definitions: + +

+	stat ::= function funcname funcbody
+	stat ::= local function Name funcbody
+	funcname ::= Name {`.´ Name} [`:´ Name]
+

+The statement + +

+     function f () body end
+

+translates to + +

+     f = function () body end
+

+The statement + +

+     function t.a.b.c.f () body end
+

+translates to + +

+     t.a.b.c.f = function () body end
+

+The statement + +

+     local function f () body end
+

+translates to + +

+     local f; f = function () body end
+

+not to + +

+     local f = function () body end
+

+(This only makes a difference when the body of the function +contains references to f.) + + +

+A function definition is an executable expression, +whose value has type function. +When Lua pre-compiles a chunk, +all its function bodies are pre-compiled too. +Then, whenever Lua executes the function definition, +the function is instantiated (or closed). +This function instance (or closure) +is the final value of the expression. +Different instances of the same function +can refer to different external local variables +and can have different environment tables. + + +

+Parameters act as local variables that are +initialized with the argument values: + +

+	parlist ::= namelist [`,´ `...´] | `...´
+

+When a function is called, +the list of arguments is adjusted to +the length of the list of parameters, +unless the function is a variadic or vararg function, +which is +indicated by three dots ('...') at the end of its parameter list. +A vararg function does not adjust its argument list; +instead, it collects all extra arguments and supplies them +to the function through a vararg expression, +which is also written as three dots. +The value of this expression is a list of all actual extra arguments, +similar to a function with multiple results. +If a vararg expression is used inside another expression +or in the middle of a list of expressions, +then its return list is adjusted to one element. +If the expression is used as the last element of a list of expressions, +then no adjustment is made +(unless that last expression is enclosed in parentheses). + + +

+As an example, consider the following definitions: + +

+     function f(a, b) end
+     function g(a, b, ...) end
+     function r() return 1,2,3 end
+

+Then, we have the following mapping from arguments to parameters and +to the vararg expression: + +

+     CALL            PARAMETERS
+     
+     f(3)             a=3, b=nil
+     f(3, 4)          a=3, b=4
+     f(3, 4, 5)       a=3, b=4
+     f(r(), 10)       a=1, b=10
+     f(r())           a=1, b=2
+     
+     g(3)             a=3, b=nil, ... -->  (nothing)
+     g(3, 4)          a=3, b=4,   ... -->  (nothing)
+     g(3, 4, 5, 8)    a=3, b=4,   ... -->  5  8
+     g(5, r())        a=5, b=1,   ... -->  2  3
+
+ +

+Results are returned using the return statement (see §2.4.4). +If control reaches the end of a function +without encountering a return statement, +then the function returns with no results. + + +

+The colon syntax +is used for defining methods, +that is, functions that have an implicit extra parameter self. +Thus, the statement + +

+     function t.a.b.c:f (params) body end
+

+is syntactic sugar for + +

+     t.a.b.c.f = function (self, params) body end
+
+ + + + + + +

2.6 - Visibility Rules

+ +

+ +Lua is a lexically scoped language. +The scope of variables begins at the first statement after +their declaration and lasts until the end of the innermost block that +includes the declaration. +Consider the following example: + +

+     x = 10                -- global variable
+     do                    -- new block
+       local x = x         -- new 'x', with value 10
+       print(x)            --> 10
+       x = x+1
+       do                  -- another block
+         local x = x+1     -- another 'x'
+         print(x)          --> 12
+       end
+       print(x)            --> 11
+     end
+     print(x)              --> 10  (the global one)
+
+ +

+Notice that, in a declaration like local x = x, +the new x being declared is not in scope yet, +and so the second x refers to the outside variable. + + +

+Because of the lexical scoping rules, +local variables can be freely accessed by functions +defined inside their scope. +A local variable used by an inner function is called +an upvalue, or external local variable, +inside the inner function. + + +

+Notice that each execution of a local statement +defines new local variables. +Consider the following example: + +

+     a = {}
+     local x = 20
+     for i=1,10 do
+       local y = 0
+       a[i] = function () y=y+1; return x+y end
+     end
+

+The loop creates ten closures +(that is, ten instances of the anonymous function). +Each of these closures uses a different y variable, +while all of them share the same x. + + + + + +

2.7 - Error Handling

+ +

+Because Lua is an embedded extension language, +all Lua actions start from C code in the host program +calling a function from the Lua library (see lua_pcall). +Whenever an error occurs during Lua compilation or execution, +control returns to C, +which can take appropriate measures +(such as printing an error message). + + +

+Lua code can explicitly generate an error by calling the +error function. +If you need to catch errors in Lua, +you can use the pcall function. + + + + + +

2.8 - Metatables

+ +

+Every value in Lua can have a metatable. +This metatable is an ordinary Lua table +that defines the behavior of the original value +under certain special operations. +You can change several aspects of the behavior +of operations over a value by setting specific fields in its metatable. +For instance, when a non-numeric value is the operand of an addition, +Lua checks for a function in the field "__add" in its metatable. +If it finds one, +Lua calls this function to perform the addition. + + +

+We call the keys in a metatable events +and the values metamethods. +In the previous example, the event is "add" +and the metamethod is the function that performs the addition. + + +

+You can query the metatable of any value +through the getmetatable function. + + +

+You can replace the metatable of tables +through the setmetatable +function. +You cannot change the metatable of other types from Lua +(except by using the debug library); +you must use the C API for that. + + +

+Tables and full userdata have individual metatables +(although multiple tables and userdata can share their metatables). +Values of all other types share one single metatable per type; +that is, there is one single metatable for all numbers, +one for all strings, etc. + + +

+A metatable controls how an object behaves in arithmetic operations, +order comparisons, concatenation, length operation, and indexing. +A metatable also can define a function to be called when a userdata +is garbage collected. +For each of these operations Lua associates a specific key +called an event. +When Lua performs one of these operations over a value, +it checks whether this value has a metatable with the corresponding event. +If so, the value associated with that key (the metamethod) +controls how Lua will perform the operation. + + +

+Metatables control the operations listed next. +Each operation is identified by its corresponding name. +The key for each operation is a string with its name prefixed by +two underscores, '__'; +for instance, the key for operation "add" is the +string "__add". +The semantics of these operations is better explained by a Lua function +describing how the interpreter executes the operation. + + +

+The code shown here in Lua is only illustrative; +the real behavior is hard coded in the interpreter +and it is much more efficient than this simulation. +All functions used in these descriptions +(rawget, tonumber, etc.) +are described in §5.1. +In particular, to retrieve the metamethod of a given object, +we use the expression + +

+     metatable(obj)[event]
+

+This should be read as + +

+     rawget(getmetatable(obj) or {}, event)
+

+ +That is, the access to a metamethod does not invoke other metamethods, +and the access to objects with no metatables does not fail +(it simply results in nil). + + + +

    + +
  • "add": +the + operation. + + + +

    +The function getbinhandler below defines how Lua chooses a handler +for a binary operation. +First, Lua tries the first operand. +If its type does not define a handler for the operation, +then Lua tries the second operand. + +

    +     function getbinhandler (op1, op2, event)
    +       return metatable(op1)[event] or metatable(op2)[event]
    +     end
    +

    +By using this function, +the behavior of the op1 + op2 is + +

    +     function add_event (op1, op2)
    +       local o1, o2 = tonumber(op1), tonumber(op2)
    +       if o1 and o2 then  -- both operands are numeric?
    +         return o1 + o2   -- '+' here is the primitive 'add'
    +       else  -- at least one of the operands is not numeric
    +         local h = getbinhandler(op1, op2, "__add")
    +         if h then
    +           -- call the handler with both operands
    +           return (h(op1, op2))
    +         else  -- no handler available: default behavior
    +           error(···)
    +         end
    +       end
    +     end
    +

    +

  • + +
  • "sub": +the - operation. + +Behavior similar to the "add" operation. +
  • + +
  • "mul": +the * operation. + +Behavior similar to the "add" operation. +
  • + +
  • "div": +the / operation. + +Behavior similar to the "add" operation. +
  • + +
  • "mod": +the % operation. + +Behavior similar to the "add" operation, +with the operation +o1 - floor(o1/o2)*o2 as the primitive operation. +
  • + +
  • "pow": +the ^ (exponentiation) operation. + +Behavior similar to the "add" operation, +with the function pow (from the C math library) +as the primitive operation. +
  • + +
  • "unm": +the unary - operation. + + +
    +     function unm_event (op)
    +       local o = tonumber(op)
    +       if o then  -- operand is numeric?
    +         return -o  -- '-' here is the primitive 'unm'
    +       else  -- the operand is not numeric.
    +         -- Try to get a handler from the operand
    +         local h = metatable(op).__unm
    +         if h then
    +           -- call the handler with the operand
    +           return (h(op))
    +         else  -- no handler available: default behavior
    +           error(···)
    +         end
    +       end
    +     end
    +

    +

  • + +
  • "concat": +the .. (concatenation) operation. + + +
    +     function concat_event (op1, op2)
    +       if (type(op1) == "string" or type(op1) == "number") and
    +          (type(op2) == "string" or type(op2) == "number") then
    +         return op1 .. op2  -- primitive string concatenation
    +       else
    +         local h = getbinhandler(op1, op2, "__concat")
    +         if h then
    +           return (h(op1, op2))
    +         else
    +           error(···)
    +         end
    +       end
    +     end
    +

    +

  • + +
  • "len": +the # operation. + + +
    +     function len_event (op)
    +       if type(op) == "string" then
    +         return strlen(op)         -- primitive string length
    +       elseif type(op) == "table" then
    +         return #op                -- primitive table length
    +       else
    +         local h = metatable(op).__len
    +         if h then
    +           -- call the handler with the operand
    +           return (h(op))
    +         else  -- no handler available: default behavior
    +           error(···)
    +         end
    +       end
    +     end
    +

    +See §2.5.5 for a description of the length of a table. +

  • + +
  • "eq": +the == operation. + +The function getcomphandler defines how Lua chooses a metamethod +for comparison operators. +A metamethod only is selected when both objects +being compared have the same type +and the same metamethod for the selected operation. + +
    +     function getcomphandler (op1, op2, event)
    +       if type(op1) ~= type(op2) then return nil end
    +       local mm1 = metatable(op1)[event]
    +       local mm2 = metatable(op2)[event]
    +       if mm1 == mm2 then return mm1 else return nil end
    +     end
    +

    +The "eq" event is defined as follows: + +

    +     function eq_event (op1, op2)
    +       if type(op1) ~= type(op2) then  -- different types?
    +         return false   -- different objects
    +       end
    +       if op1 == op2 then   -- primitive equal?
    +         return true   -- objects are equal
    +       end
    +       -- try metamethod
    +       local h = getcomphandler(op1, op2, "__eq")
    +       if h then
    +         return (h(op1, op2))
    +       else
    +         return false
    +       end
    +     end
    +

    +a ~= b is equivalent to not (a == b). +

  • + +
  • "lt": +the < operation. + + +
    +     function lt_event (op1, op2)
    +       if type(op1) == "number" and type(op2) == "number" then
    +         return op1 < op2   -- numeric comparison
    +       elseif type(op1) == "string" and type(op2) == "string" then
    +         return op1 < op2   -- lexicographic comparison
    +       else
    +         local h = getcomphandler(op1, op2, "__lt")
    +         if h then
    +           return (h(op1, op2))
    +         else
    +           error(···)
    +         end
    +       end
    +     end
    +

    +a > b is equivalent to b < a. +

  • + +
  • "le": +the <= operation. + + +
    +     function le_event (op1, op2)
    +       if type(op1) == "number" and type(op2) == "number" then
    +         return op1 <= op2   -- numeric comparison
    +       elseif type(op1) == "string" and type(op2) == "string" then
    +         return op1 <= op2   -- lexicographic comparison
    +       else
    +         local h = getcomphandler(op1, op2, "__le")
    +         if h then
    +           return (h(op1, op2))
    +         else
    +           h = getcomphandler(op1, op2, "__lt")
    +           if h then
    +             return not h(op2, op1)
    +           else
    +             error(···)
    +           end
    +         end
    +       end
    +     end
    +

    +a >= b is equivalent to b <= a. +Note that, in the absence of a "le" metamethod, +Lua tries the "lt", assuming that a <= b is +equivalent to not (b < a). +

  • + +
  • "index": +The indexing access table[key]. + + +
    +     function gettable_event (table, key)
    +       local h
    +       if type(table) == "table" then
    +         local v = rawget(table, key)
    +         if v ~= nil then return v end
    +         h = metatable(table).__index
    +         if h == nil then return nil end
    +       else
    +         h = metatable(table).__index
    +         if h == nil then
    +           error(···)
    +         end
    +       end
    +       if type(h) == "function" then
    +         return (h(table, key))     -- call the handler
    +       else return h[key]           -- or repeat operation on it
    +       end
    +     end
    +

    +

  • + +
  • "newindex": +The indexing assignment table[key] = value. + + +
    +     function settable_event (table, key, value)
    +       local h
    +       if type(table) == "table" then
    +         local v = rawget(table, key)
    +         if v ~= nil then rawset(table, key, value); return end
    +         h = metatable(table).__newindex
    +         if h == nil then rawset(table, key, value); return end
    +       else
    +         h = metatable(table).__newindex
    +         if h == nil then
    +           error(···)
    +         end
    +       end
    +       if type(h) == "function" then
    +         h(table, key,value)           -- call the handler
    +       else h[key] = value             -- or repeat operation on it
    +       end
    +     end
    +

    +

  • + +
  • "call": +called when Lua calls a value. + + +
    +     function function_event (func, ...)
    +       if type(func) == "function" then
    +         return func(...)   -- primitive call
    +       else
    +         local h = metatable(func).__call
    +         if h then
    +           return h(func, ...)
    +         else
    +           error(···)
    +         end
    +       end
    +     end
    +

    +

  • + +
+ + + + +

2.9 - Environments

+ +

+Besides metatables, +objects of types thread, function, and userdata +have another table associated with them, +called their environment. +Like metatables, environments are regular tables and +multiple objects can share the same environment. + + +

+Threads are created sharing the environment of the creating thread. +Userdata and C functions are created sharing the environment +of the creating C function. +Non-nested Lua functions +(created by loadfile, loadstring or load) +are created sharing the environment of the creating thread. +Nested Lua functions are created sharing the environment of +the creating Lua function. + + +

+Environments associated with userdata have no meaning for Lua. +It is only a convenience feature for programmers to associate a table to +a userdata. + + +

+Environments associated with threads are called +global environments. +They are used as the default environment for threads and +non-nested Lua functions created by the thread +and can be directly accessed by C code (see §3.3). + + +

+The environment associated with a C function can be directly +accessed by C code (see §3.3). +It is used as the default environment for other C functions +and userdata created by the function. + + +

+Environments associated with Lua functions are used to resolve +all accesses to global variables within the function (see §2.3). +They are used as the default environment for nested Lua functions +created by the function. + + +

+You can change the environment of a Lua function or the +running thread by calling setfenv. +You can get the environment of a Lua function or the running thread +by calling getfenv. +To manipulate the environment of other objects +(userdata, C functions, other threads) you must +use the C API. + + + + + +

2.10 - Garbage Collection

+ +

+Lua performs automatic memory management. +This means that +you have to worry neither about allocating memory for new objects +nor about freeing it when the objects are no longer needed. +Lua manages memory automatically by running +a garbage collector from time to time +to collect all dead objects +(that is, objects that are no longer accessible from Lua). +All memory used by Lua is subject to automatic management: +tables, userdata, functions, threads, strings, etc. + + +

+Lua implements an incremental mark-and-sweep collector. +It uses two numbers to control its garbage-collection cycles: +the garbage-collector pause and +the garbage-collector step multiplier. +Both use percentage points as units +(so that a value of 100 means an internal value of 1). + + +

+The garbage-collector pause +controls how long the collector waits before starting a new cycle. +Larger values make the collector less aggressive. +Values smaller than 100 mean the collector will not wait to +start a new cycle. +A value of 200 means that the collector waits for the total memory in use +to double before starting a new cycle. + + +

+The step multiplier +controls the relative speed of the collector relative to +memory allocation. +Larger values make the collector more aggressive but also increase +the size of each incremental step. +Values smaller than 100 make the collector too slow and +can result in the collector never finishing a cycle. +The default, 200, means that the collector runs at "twice" +the speed of memory allocation. + + +

+You can change these numbers by calling lua_gc in C +or collectgarbage in Lua. +With these functions you can also control +the collector directly (e.g., stop and restart it). + + + +

2.10.1 - Garbage-Collection Metamethods

+ +

+Using the C API, +you can set garbage-collector metamethods for userdata (see §2.8). +These metamethods are also called finalizers. +Finalizers allow you to coordinate Lua's garbage collection +with external resource management +(such as closing files, network or database connections, +or freeing your own memory). + + +

+Garbage userdata with a field __gc in their metatables are not +collected immediately by the garbage collector. +Instead, Lua puts them in a list. +After the collection, +Lua does the equivalent of the following function +for each userdata in that list: + +

+     function gc_event (udata)
+       local h = metatable(udata).__gc
+       if h then
+         h(udata)
+       end
+     end
+
+ +

+At the end of each garbage-collection cycle, +the finalizers for userdata are called in reverse +order of their creation, +among those collected in that cycle. +That is, the first finalizer to be called is the one associated +with the userdata created last in the program. +The userdata itself is freed only in the next garbage-collection cycle. + + + + + +

2.10.2 - Weak Tables

+ +

+A weak table is a table whose elements are +weak references. +A weak reference is ignored by the garbage collector. +In other words, +if the only references to an object are weak references, +then the garbage collector will collect this object. + + +

+A weak table can have weak keys, weak values, or both. +A table with weak keys allows the collection of its keys, +but prevents the collection of its values. +A table with both weak keys and weak values allows the collection of +both keys and values. +In any case, if either the key or the value is collected, +the whole pair is removed from the table. +The weakness of a table is controlled by the +__mode field of its metatable. +If the __mode field is a string containing the character 'k', +the keys in the table are weak. +If __mode contains 'v', +the values in the table are weak. + + +

+After you use a table as a metatable, +you should not change the value of its __mode field. +Otherwise, the weak behavior of the tables controlled by this +metatable is undefined. + + + + + + + +

2.11 - Coroutines

+ +

+Lua supports coroutines, +also called collaborative multithreading. +A coroutine in Lua represents an independent thread of execution. +Unlike threads in multithread systems, however, +a coroutine only suspends its execution by explicitly calling +a yield function. + + +

+You create a coroutine with a call to coroutine.create. +Its sole argument is a function +that is the main function of the coroutine. +The create function only creates a new coroutine and +returns a handle to it (an object of type thread); +it does not start the coroutine execution. + + +

+When you first call coroutine.resume, +passing as its first argument +a thread returned by coroutine.create, +the coroutine starts its execution, +at the first line of its main function. +Extra arguments passed to coroutine.resume are passed on +to the coroutine main function. +After the coroutine starts running, +it runs until it terminates or yields. + + +

+A coroutine can terminate its execution in two ways: +normally, when its main function returns +(explicitly or implicitly, after the last instruction); +and abnormally, if there is an unprotected error. +In the first case, coroutine.resume returns true, +plus any values returned by the coroutine main function. +In case of errors, coroutine.resume returns false +plus an error message. + + +

+A coroutine yields by calling coroutine.yield. +When a coroutine yields, +the corresponding coroutine.resume returns immediately, +even if the yield happens inside nested function calls +(that is, not in the main function, +but in a function directly or indirectly called by the main function). +In the case of a yield, coroutine.resume also returns true, +plus any values passed to coroutine.yield. +The next time you resume the same coroutine, +it continues its execution from the point where it yielded, +with the call to coroutine.yield returning any extra +arguments passed to coroutine.resume. + + +

+Like coroutine.create, +the coroutine.wrap function also creates a coroutine, +but instead of returning the coroutine itself, +it returns a function that, when called, resumes the coroutine. +Any arguments passed to this function +go as extra arguments to coroutine.resume. +coroutine.wrap returns all the values returned by coroutine.resume, +except the first one (the boolean error code). +Unlike coroutine.resume, +coroutine.wrap does not catch errors; +any error is propagated to the caller. + + +

+As an example, +consider the following code: + +

+     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)
+           return b, "end"
+     end)
+            
+     print("main", coroutine.resume(co, 1, 10))
+     print("main", coroutine.resume(co, "r"))
+     print("main", coroutine.resume(co, "x", "y"))
+     print("main", coroutine.resume(co, "x", "y"))
+

+When you run it, it produces the following output: + +

+     co-body 1       10
+     foo     2
+     
+     main    true    4
+     co-body r
+     main    true    11      -9
+     co-body x       y
+     main    true    10      end
+     main    false   cannot resume dead coroutine
+
+ + + + +

3 - The Application Program Interface

+ +

+ +This section describes the C API for Lua, that is, +the set of C functions available to the host program to communicate +with Lua. +All API functions and related types and constants +are declared in the header file lua.h. + + +

+Even when we use the term "function", +any facility in the API may be provided as a macro instead. +All such macros use each of their arguments exactly once +(except for the first argument, which is always a Lua state), +and so do not generate any hidden side-effects. + + +

+As in most C libraries, +the Lua API functions do not check their arguments for validity or consistency. +However, you can change this behavior by compiling Lua +with a proper definition for the macro luai_apicheck, +in file luaconf.h. + + + +

3.1 - The Stack

+ +

+Lua uses a virtual stack to pass values to and from C. +Each element in this stack represents a Lua value +(nil, number, string, etc.). + + +

+Whenever Lua calls C, the called function gets a new stack, +which is independent of previous stacks and of stacks of +C functions that are still active. +This stack initially contains any arguments to the C function +and it is where the C function pushes its results +to be returned to the caller (see lua_CFunction). + + +

+For convenience, +most query operations in the API do not follow a strict stack discipline. +Instead, they can refer to any element in the stack +by using an index: +A positive index represents an absolute stack position +(starting at 1); +a negative index represents an offset relative to the top of the stack. +More specifically, if the stack has n elements, +then index 1 represents the first element +(that is, the element that was pushed onto the stack first) +and +index n represents the last element; +index -1 also represents the last element +(that is, the element at the top) +and index -n represents the first element. +We say that an index is valid +if it lies between 1 and the stack top +(that is, if 1 ≤ abs(index) ≤ top). + + + + + + +

3.2 - Stack Size

+ +

+When you interact with Lua API, +you are responsible for ensuring consistency. +In particular, +you are responsible for controlling stack overflow. +You can use the function lua_checkstack +to grow the stack size. + + +

+Whenever Lua calls C, +it ensures that at least LUA_MINSTACK stack positions are available. +LUA_MINSTACK is defined as 20, +so that usually you do not have to worry about stack space +unless your code has loops pushing elements onto the stack. + + +

+Most query functions accept as indices any value inside the +available stack space, that is, indices up to the maximum stack size +you have set through lua_checkstack. +Such indices are called acceptable indices. +More formally, we define an acceptable index +as follows: + +

+     (index < 0 && abs(index) <= top) ||
+     (index > 0 && index <= stackspace)
+

+Note that 0 is never an acceptable index. + + + + + +

3.3 - Pseudo-Indices

+ +

+Unless otherwise noted, +any function that accepts valid indices can also be called with +pseudo-indices, +which represent some Lua values that are accessible to C code +but which are not in the stack. +Pseudo-indices are used to access the thread environment, +the function environment, +the registry, +and the upvalues of a C function (see §3.4). + + +

+The thread environment (where global variables live) is +always at pseudo-index LUA_GLOBALSINDEX. +The environment of the running C function is always +at pseudo-index LUA_ENVIRONINDEX. + + +

+To access and change the value of global variables, +you can use regular table operations over an environment table. +For instance, to access the value of a global variable, do + +

+     lua_getfield(L, LUA_GLOBALSINDEX, varname);
+
+ + + + +

3.4 - C Closures

+ +

+When a C function is created, +it is possible to associate some values with it, +thus creating a C closure; +these values are called upvalues and are +accessible to the function whenever it is called +(see lua_pushcclosure). + + +

+Whenever a C function is called, +its upvalues are located at specific pseudo-indices. +These pseudo-indices are produced by the macro +lua_upvalueindex. +The first value associated with a function is at position +lua_upvalueindex(1), and so on. +Any access to lua_upvalueindex(n), +where n is greater than the number of upvalues of the +current function (but not greater than 256), +produces an acceptable (but invalid) index. + + + + + +

3.5 - Registry

+ +

+Lua provides a registry, +a pre-defined table that can be used by any C code to +store whatever Lua value it needs to store. +This table is always located at pseudo-index +LUA_REGISTRYINDEX. +Any C library can store data into this table, +but it should take care to choose keys different from those used +by other libraries, to avoid collisions. +Typically, you should use as key a string containing your library name +or a light userdata with the address of a C object in your code. + + +

+The integer keys in the registry are used by the reference mechanism, +implemented by the auxiliary library, +and therefore should not be used for other purposes. + + + + + +

3.6 - Error Handling in C

+ +

+Internally, Lua uses the C longjmp facility to handle errors. +(You can also choose to use exceptions if you use C++; +see file luaconf.h.) +When Lua faces any error +(such as memory allocation errors, type errors, syntax errors, +and runtime errors) +it raises an error; +that is, it does a long jump. +A protected environment uses setjmp +to set a recover point; +any error jumps to the most recent active recover point. + + +

+Most functions in the API can throw an error, +for instance due to a memory allocation error. +The documentation for each function indicates whether +it can throw errors. + + +

+Inside a C function you can throw an error by calling lua_error. + + + + + +

3.7 - Functions and Types

+ +

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


lua_Alloc

+
typedef void * (*lua_Alloc) (void *ud,
+                             void *ptr,
+                             size_t osize,
+                             size_t nsize);
+ +

+The type of the memory-allocation function used by Lua states. +The allocator function must provide a +functionality similar to realloc, +but not exactly the same. +Its arguments are +ud, an opaque pointer passed to lua_newstate; +ptr, a pointer to the block being allocated/reallocated/freed; +osize, the original size of the block; +nsize, the new size of the block. +ptr is NULL if and only if osize is zero. +When nsize is zero, the allocator must return NULL; +if osize is not zero, +it should free the block pointed to by ptr. +When nsize is not zero, the allocator returns NULL +if and only if it cannot fill the request. +When nsize is not zero and osize is zero, +the allocator should behave like malloc. +When nsize and osize are not zero, +the allocator behaves like realloc. +Lua assumes that the allocator never fails when +osize >= nsize. + + +

+Here is a simple implementation for the allocator function. +It is used in the auxiliary library by luaL_newstate. + +

+     static void *l_alloc (void *ud, void *ptr, size_t osize,
+                                                size_t nsize) {
+       (void)ud;  (void)osize;  /* not used */
+       if (nsize == 0) {
+         free(ptr);
+         return NULL;
+       }
+       else
+         return realloc(ptr, nsize);
+     }
+

+This code assumes +that free(NULL) has no effect and that +realloc(NULL, size) is equivalent to malloc(size). +ANSI C ensures both behaviors. + + + + + +


lua_atpanic

+[-0, +0, -] +

lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);
+ +

+Sets a new panic function and returns the old one. + + +

+If an error happens outside any protected environment, +Lua calls a panic function +and then calls exit(EXIT_FAILURE), +thus exiting the host application. +Your panic function can avoid this exit by +never returning (e.g., doing a long jump). + + +

+The panic function can access the error message at the top of the stack. + + + + + +


lua_call

+[-(nargs + 1), +nresults, e] +

void lua_call (lua_State *L, int nargs, int nresults);
+ +

+Calls a function. + + +

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


lua_CFunction

+
typedef int (*lua_CFunction) (lua_State *L);
+ +

+Type for C functions. + + +

+In order to communicate properly with Lua, +a C function must use the following protocol, +which defines the way parameters and results are passed: +a C function receives its arguments from Lua in its stack +in direct order (the first argument is pushed first). +So, when the function starts, +lua_gettop(L) returns the number of arguments received by the function. +The first argument (if any) is at index 1 +and its last argument is at index lua_gettop(L). +To return values to Lua, a C function just pushes them onto the stack, +in direct order (the first result is pushed first), +and returns the number of results. +Any other value in the stack below the results will be properly +discarded by Lua. +Like a Lua function, a C function called by Lua can also return +many results. + + +

+As an example, the following function receives a variable number +of numerical arguments and returns their average and sum: + +

+     static int foo (lua_State *L) {
+       int n = lua_gettop(L);    /* number of arguments */
+       lua_Number sum = 0;
+       int i;
+       for (i = 1; i <= n; i++) {
+         if (!lua_isnumber(L, i)) {
+           lua_pushstring(L, "incorrect argument");
+           lua_error(L);
+         }
+         sum += lua_tonumber(L, i);
+       }
+       lua_pushnumber(L, sum/n);        /* first result */
+       lua_pushnumber(L, sum);         /* second result */
+       return 2;                   /* number of results */
+     }
+
+ + + + +

lua_checkstack

+[-0, +0, m] +

int lua_checkstack (lua_State *L, int extra);
+ +

+Ensures that there are at least extra free stack slots in the stack. +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. + + + + + +


lua_close

+[-0, +0, -] +

void lua_close (lua_State *L);
+ +

+Destroys all objects in the given Lua state +(calling the corresponding garbage-collection metamethods, if any) +and frees all dynamic memory used by this state. +On several platforms, you may not need to call this function, +because all resources are naturally released when the host program ends. +On the other hand, long-running programs, +such as a daemon or a web server, +might need to release states as soon as they are not needed, +to avoid growing too large. + + + + + +


lua_concat

+[-n, +1, e] +

void lua_concat (lua_State *L, int n);
+ +

+Concatenates the n values at the top of the stack, +pops them, and leaves the result at the top. +If n is 1, the result is the single value on the stack +(that is, the function does nothing); +if n is 0, the result is the empty string. +Concatenation is performed following the usual semantics of Lua +(see §2.5.4). + + + + + +


lua_cpcall

+[-0, +(0|1), -] +

int lua_cpcall (lua_State *L, lua_CFunction func, void *ud);
+ +

+Calls the C function func in protected mode. +func starts with only one element in its stack, +a light userdata containing ud. +In case of errors, +lua_cpcall returns the same error codes as lua_pcall, +plus the error object on the top of the stack; +otherwise, it returns zero, and does not change the stack. +All values returned by func are discarded. + + + + + +


lua_createtable

+[-0, +1, m] +

void lua_createtable (lua_State *L, int narr, int nrec);
+ +

+Creates a new empty table and pushes it onto the stack. +The new table has space pre-allocated +for narr array elements and nrec non-array elements. +This pre-allocation is useful when you know exactly how many elements +the table will have. +Otherwise you can use the function lua_newtable. + + + + + +


lua_dump

+[-0, +0, m] +

int lua_dump (lua_State *L, lua_Writer writer, void *data);
+ +

+Dumps a function as a binary chunk. +Receives a Lua function on the top of the stack +and produces a binary chunk that, +if loaded again, +results in a function equivalent to the one dumped. +As it produces parts of the chunk, +lua_dump calls function writer (see lua_Writer) +with the given data +to write them. + + +

+The value returned is the error code returned by the last +call to the writer; +0 means no errors. + + +

+This function does not pop the Lua function from the stack. + + + + + +


lua_equal

+[-0, +0, e] +

int lua_equal (lua_State *L, int index1, int index2);
+ +

+Returns 1 if the two values in acceptable indices index1 and +index2 are equal, +following the semantics of the Lua == operator +(that is, may call metamethods). +Otherwise returns 0. +Also returns 0 if any of the indices is non valid. + + + + + +


lua_error

+[-1, +0, v] +

int lua_error (lua_State *L);
+ +

+Generates a Lua error. +The error message (which can actually be a Lua value of any type) +must be on the stack top. +This function does a long jump, +and therefore never returns. +(see luaL_error). + + + + + +


lua_gc

+[-0, +0, e] +

int lua_gc (lua_State *L, int what, int data);
+ +

+Controls the garbage collector. + + +

+This function performs several tasks, +according to the value of the parameter what: + +

    + +
  • LUA_GCSTOP: +stops the garbage collector. +
  • + +
  • LUA_GCRESTART: +restarts the garbage collector. +
  • + +
  • LUA_GCCOLLECT: +performs a full garbage-collection cycle. +
  • + +
  • LUA_GCCOUNT: +returns the current amount of memory (in Kbytes) in use by Lua. +
  • + +
  • LUA_GCCOUNTB: +returns the remainder of dividing the current amount of bytes of +memory in use by Lua by 1024. +
  • + +
  • LUA_GCSTEP: +performs an incremental step of garbage collection. +The step "size" is controlled by data +(larger values mean more steps) in a non-specified way. +If you want to control the step size +you must experimentally tune the value of data. +The function returns 1 if the step finished a +garbage-collection cycle. +
  • + +
  • LUA_GCSETPAUSE: +sets data as the new value +for the pause of the collector (see §2.10). +The function returns the previous value of the pause. +
  • + +
  • LUA_GCSETSTEPMUL: +sets data as the new value for the step multiplier of +the collector (see §2.10). +The function returns the previous value of the step multiplier. +
  • + +
+ + + + +

lua_getallocf

+[-0, +0, -] +

lua_Alloc lua_getallocf (lua_State *L, void **ud);
+ +

+Returns the memory-allocation function of a given state. +If ud is not NULL, Lua stores in *ud the +opaque pointer passed to lua_newstate. + + + + + +


lua_getfenv

+[-0, +1, -] +

void lua_getfenv (lua_State *L, int index);
+ +

+Pushes onto the stack the environment table of +the value at the given index. + + + + + +


lua_getfield

+[-0, +1, e] +

void lua_getfield (lua_State *L, int index, const char *k);
+ +

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


lua_getglobal

+[-0, +1, e] +

void lua_getglobal (lua_State *L, const char *name);
+ +

+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)
+
+ + + + +

lua_getmetatable

+[-0, +(0|1), -] +

int lua_getmetatable (lua_State *L, int index);
+ +

+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 0 and pushes nothing on the stack. + + + + + +


lua_gettable

+[-1, +1, e] +

void lua_gettable (lua_State *L, int index);
+ +

+Pushes onto the stack the value t[k], +where t is the value at the given valid index +and k is the value at the top of the stack. + + +

+This function pops the key from the stack +(putting the resulting value in its place). +As in Lua, this function may trigger a metamethod +for the "index" event (see §2.8). + + + + + +


lua_gettop

+[-0, +0, -] +

int lua_gettop (lua_State *L);
+ +

+Returns the index of the top element in the stack. +Because indices start at 1, +this result is equal to the number of elements in the stack +(and so 0 means an empty stack). + + + + + +


lua_insert

+[-1, +1, -] +

void lua_insert (lua_State *L, int index);
+ +

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


lua_Integer

+
typedef ptrdiff_t lua_Integer;
+ +

+The type used by the Lua API to represent integral values. + + +

+By default it is a ptrdiff_t, +which is usually the largest signed integral type the machine handles +"comfortably". + + + + + +


lua_isboolean

+[-0, +0, -] +

int lua_isboolean (lua_State *L, int index);
+ +

+Returns 1 if the value at the given acceptable index has type boolean, +and 0 otherwise. + + + + + +


lua_iscfunction

+[-0, +0, -] +

int lua_iscfunction (lua_State *L, int index);
+ +

+Returns 1 if the value at the given acceptable index is a C function, +and 0 otherwise. + + + + + +


lua_isfunction

+[-0, +0, -] +

int lua_isfunction (lua_State *L, int index);
+ +

+Returns 1 if the value at the given acceptable index is a function +(either C or Lua), and 0 otherwise. + + + + + +


lua_islightuserdata

+[-0, +0, -] +

int lua_islightuserdata (lua_State *L, int index);
+ +

+Returns 1 if the value at the given acceptable index is a light userdata, +and 0 otherwise. + + + + + +


lua_isnil

+[-0, +0, -] +

int lua_isnil (lua_State *L, int index);
+ +

+Returns 1 if the value at the given acceptable index is nil, +and 0 otherwise. + + + + + +


lua_isnone

+[-0, +0, -] +

int lua_isnone (lua_State *L, int index);
+ +

+Returns 1 if the given acceptable index is not valid +(that is, it refers to an element outside the current stack), +and 0 otherwise. + + + + + +


lua_isnoneornil

+[-0, +0, -] +

int lua_isnoneornil (lua_State *L, int index);
+ +

+Returns 1 if 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. + + + + + +


lua_isnumber

+[-0, +0, -] +

int lua_isnumber (lua_State *L, int index);
+ +

+Returns 1 if the value at the given acceptable index is a number +or a string convertible to a number, +and 0 otherwise. + + + + + +


lua_isstring

+[-0, +0, -] +

int lua_isstring (lua_State *L, int index);
+ +

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


lua_istable

+[-0, +0, -] +

int lua_istable (lua_State *L, int index);
+ +

+Returns 1 if the value at the given acceptable index is a table, +and 0 otherwise. + + + + + +


lua_isthread

+[-0, +0, -] +

int lua_isthread (lua_State *L, int index);
+ +

+Returns 1 if the value at the given acceptable index is a thread, +and 0 otherwise. + + + + + +


lua_isuserdata

+[-0, +0, -] +

int lua_isuserdata (lua_State *L, int index);
+ +

+Returns 1 if the value at the given acceptable index is a userdata +(either full or light), and 0 otherwise. + + + + + +


lua_lessthan

+[-0, +0, e] +

int lua_lessthan (lua_State *L, int index1, int index2);
+ +

+Returns 1 if the value at acceptable index index1 is smaller +than the value at acceptable index index2, +following the semantics of the Lua < operator +(that is, may call metamethods). +Otherwise returns 0. +Also returns 0 if any of the indices is non valid. + + + + + +


lua_load

+[-0, +1, -] +

int lua_load (lua_State *L,
+              lua_Reader reader,
+              void *data,
+              const char *chunkname);
+ +

+Loads a Lua chunk. +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). + + + + + +


lua_newstate

+[-0, +0, -] +

lua_State *lua_newstate (lua_Alloc f, void *ud);
+ +

+Creates a new, independent state. +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. + + + + + +


lua_newtable

+[-0, +1, m] +

void lua_newtable (lua_State *L);
+ +

+Creates a new empty table and pushes it onto the stack. +It is equivalent to lua_createtable(L, 0, 0). + + + + + +


lua_newthread

+[-0, +1, m] +

lua_State *lua_newthread (lua_State *L);
+ +

+Creates a new thread, pushes it on the stack, +and returns a pointer to a lua_State that represents this new thread. +The new state returned by this function shares with the original state +all global objects (such as tables), +but has an independent execution stack. + + +

+There is no explicit function to close or to destroy a thread. +Threads are subject to garbage collection, +like any Lua object. + + + + + +


lua_newuserdata

+[-0, +1, m] +

void *lua_newuserdata (lua_State *L, size_t size);
+ +

+This function allocates a new block of memory with the given size, +pushes onto the stack a new full userdata with the block address, +and returns this address. + + +

+Userdata represent C values in Lua. +A full userdata represents a block of memory. +It is an object (like a table): +you must create it, it can have its own metatable, +and you can detect when it is being collected. +A full userdata is only equal to itself (under raw equality). + + +

+When Lua collects a full userdata with a gc metamethod, +Lua calls the metamethod and marks the userdata as finalized. +When this userdata is collected again then +Lua frees its corresponding memory. + + + + + +


lua_next

+[-1, +(2|0), e] +

int lua_next (lua_State *L, int index);
+ +

+Pops a key from the stack, +and pushes a key-value pair from the table at the given index +(the "next" pair after the given key). +If there are no more elements in the table, +then lua_next returns 0 (and pushes nothing). + + +

+A typical traversal looks like this: + +

+     /* table is in the stack at index 't' */
+     lua_pushnil(L);  /* first key */
+     while (lua_next(L, t) != 0) {
+       /* uses 'key' (at index -2) and 'value' (at index -1) */
+       printf("%s - %s\n",
+              lua_typename(L, lua_type(L, -2)),
+              lua_typename(L, lua_type(L, -1)));
+       /* removes 'value'; keeps 'key' for next iteration */
+       lua_pop(L, 1);
+     }
+
+ +

+While traversing a table, +do not call lua_tolstring directly on a key, +unless you know that the key is actually a string. +Recall that lua_tolstring changes +the value at the given index; +this confuses the next call to lua_next. + + + + + +


lua_Number

+
typedef double lua_Number;
+ +

+The type of numbers in Lua. +By default, it is double, but that can be changed in luaconf.h. + + +

+Through the configuration file you can change +Lua to operate with another type for numbers (e.g., float or long). + + + + + +


lua_objlen

+[-0, +0, -] +

size_t lua_objlen (lua_State *L, int index);
+ +

+Returns the "length" of the value at the given acceptable index: +for strings, this is the string length; +for tables, this is the result of the length operator ('#'); +for userdata, this is the size of the block of memory allocated +for the userdata; +for other values, it is 0. + + + + + +


lua_pcall

+[-(nargs + 1), +(nresults|1), -] +

int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);
+ +

+Calls a function in protected mode. + + +

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

+If errfunc is 0, +then the error message returned on the stack +is exactly the original error message. +Otherwise, errfunc is the stack index of an +error handler function. +(In the current implementation, this index cannot be a pseudo-index.) +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 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. +
  • + +
+ + + + +

lua_pop

+[-n, +0, -] +

void lua_pop (lua_State *L, int n);
+ +

+Pops n elements from the stack. + + + + + +


lua_pushboolean

+[-0, +1, -] +

void lua_pushboolean (lua_State *L, int b);
+ +

+Pushes a boolean value with value b onto the stack. + + + + + +


lua_pushcclosure

+[-n, +1, m] +

void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
+ +

+Pushes a new C closure onto the stack. + + +

+When a C function is created, +it is possible to associate some values with it, +thus creating a C closure (see §3.4); +these values are then accessible to the function whenever it is called. +To associate values with a C function, +first these values should be pushed onto the stack +(when there are multiple values, the first value is pushed first). +Then lua_pushcclosure +is called to create and push the C function onto the stack, +with the argument n telling how many values should be +associated with the function. +lua_pushcclosure also pops these values from the stack. + + +

+The maximum value for n is 255. + + + + + +


lua_pushcfunction

+[-0, +1, m] +

void lua_pushcfunction (lua_State *L, lua_CFunction f);
+ +

+Pushes a C function onto the stack. +This function receives a pointer to a C function +and pushes onto the stack a Lua value of type function that, +when called, invokes the corresponding C function. + + +

+Any function to be registered in Lua must +follow the correct protocol to receive its parameters +and return its results (see lua_CFunction). + + +

+lua_pushcfunction is defined as a macro: + +

+     #define lua_pushcfunction(L,f)  lua_pushcclosure(L,f,0)
+
+ + + + +

lua_pushfstring

+[-0, +1, m] +

const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
+ +

+Pushes onto the stack a formatted string +and returns a pointer to this string. +It is similar to the C function sprintf, +but has some important differences: + +

    + +
  • +You do not have to allocate space for the result: +the result is a Lua string and Lua takes care of memory allocation +(and deallocation, through garbage collection). +
  • + +
  • +The conversion specifiers are quite restricted. +There are no flags, widths, or precisions. +The conversion specifiers can only be +'%%' (inserts a '%' in the string), +'%s' (inserts a zero-terminated string, with no size restrictions), +'%f' (inserts a lua_Number), +'%p' (inserts a pointer as a hexadecimal numeral), +'%d' (inserts an int), and +'%c' (inserts an int as a character). +
  • + +
+ + + + +

lua_pushinteger

+[-0, +1, -] +

void lua_pushinteger (lua_State *L, lua_Integer n);
+ +

+Pushes a number with value n onto the stack. + + + + + +


lua_pushlightuserdata

+[-0, +1, -] +

void lua_pushlightuserdata (lua_State *L, void *p);
+ +

+Pushes a light userdata onto the stack. + + +

+Userdata represent C values in Lua. +A light userdata represents a pointer. +It is a value (like a number): +you do not create it, it has no individual metatable, +and it is not collected (as it was never created). +A light userdata is equal to "any" +light userdata with the same C address. + + + + + +


lua_pushliteral

+[-0, +1, m] +

void lua_pushliteral (lua_State *L, const char *s);
+ +

+This macro is equivalent to lua_pushlstring, +but can be used only when s is a literal string. +In these cases, it automatically provides the string length. + + + + + +


lua_pushlstring

+[-0, +1, m] +

void lua_pushlstring (lua_State *L, const char *s, size_t len);
+ +

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


lua_pushnil

+[-0, +1, -] +

void lua_pushnil (lua_State *L);
+ +

+Pushes a nil value onto the stack. + + + + + +


lua_pushnumber

+[-0, +1, -] +

void lua_pushnumber (lua_State *L, lua_Number n);
+ +

+Pushes a number with value n onto the stack. + + + + + +


lua_pushstring

+[-0, +1, m] +

void lua_pushstring (lua_State *L, const char *s);
+ +

+Pushes the zero-terminated string pointed to by 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. + + + + + +


lua_pushthread

+[-0, +1, -] +

int lua_pushthread (lua_State *L);
+ +

+Pushes the thread represented by L onto the stack. +Returns 1 if this thread is the main thread of its state. + + + + + +


lua_pushvalue

+[-0, +1, -] +

void lua_pushvalue (lua_State *L, int index);
+ +

+Pushes a copy of the element at the given valid index +onto the stack. + + + + + +


lua_pushvfstring

+[-0, +1, m] +

const char *lua_pushvfstring (lua_State *L,
+                              const char *fmt,
+                              va_list argp);
+ +

+Equivalent to lua_pushfstring, except that it receives a va_list +instead of a variable number of arguments. + + + + + +


lua_rawequal

+[-0, +0, -] +

int lua_rawequal (lua_State *L, int index1, int index2);
+ +

+Returns 1 if the two values in acceptable indices index1 and +index2 are primitively equal +(that is, without calling metamethods). +Otherwise returns 0. +Also returns 0 if any of the indices are non valid. + + + + + +


lua_rawget

+[-1, +1, -] +

void lua_rawget (lua_State *L, int index);
+ +

+Similar to lua_gettable, but does a raw access +(i.e., without metamethods). + + + + + +


lua_rawgeti

+[-0, +1, -] +

void lua_rawgeti (lua_State *L, int index, int n);
+ +

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


lua_rawset

+[-2, +0, m] +

void lua_rawset (lua_State *L, int index);
+ +

+Similar to lua_settable, but does a raw assignment +(i.e., without metamethods). + + + + + +


lua_rawseti

+[-1, +0, m] +

void lua_rawseti (lua_State *L, int index, int n);
+ +

+Does the equivalent of t[n] = 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. +The assignment is raw; +that is, it does not invoke metamethods. + + + + + +


lua_Reader

+
typedef const char * (*lua_Reader) (lua_State *L,
+                                    void *data,
+                                    size_t *size);
+ +

+The reader function used by lua_load. +Every time it needs another piece of the chunk, +lua_load calls the reader, +passing along its data parameter. +The reader must return a pointer to a block of memory +with a new piece of the chunk +and set size to the block size. +The block must exist until the reader function is called again. +To signal the end of the chunk, +the reader must return NULL or set size to zero. +The reader function may return pieces of any size greater than zero. + + + + + +


lua_register

+[-0, +0, e] +

void lua_register (lua_State *L,
+                   const char *name,
+                   lua_CFunction f);
+ +

+Sets the C function f as the new value of global name. +It is defined as a macro: + +

+     #define lua_register(L,n,f) \
+            (lua_pushcfunction(L, f), lua_setglobal(L, n))
+
+ + + + +

lua_remove

+[-1, +0, -] +

void lua_remove (lua_State *L, int index);
+ +

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


lua_replace

+[-1, +0, -] +

void lua_replace (lua_State *L, int index);
+ +

+Moves the top element into the given position (and pops it), +without shifting any element +(therefore replacing the value at the given position). + + + + + +


lua_resume

+[-?, +?, -] +

int lua_resume (lua_State *L, int narg);
+ +

+Starts and resumes a coroutine in a given thread. + + +

+To start a coroutine, you first create a new thread +(see lua_newthread); +then you push onto its stack the main function plus any arguments; +then you call lua_resume, +with narg being the number of arguments. +This call returns when the coroutine suspends or finishes its execution. +When it returns, the stack contains all values passed to lua_yield, +or all values returned by the body function. +lua_resume returns +LUA_YIELD if the coroutine yields, +0 if the coroutine finishes its execution +without errors, +or an error code in case of errors (see lua_pcall). +In case of errors, +the stack is not unwound, +so you can use the debug API over it. +The error message is on the top of the stack. +To restart a coroutine, you put on its stack only the values to +be passed as results from yield, +and then call lua_resume. + + + + + +


lua_setallocf

+[-0, +0, -] +

void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
+ +

+Changes the allocator function of a given state to f +with user data ud. + + + + + +


lua_setfenv

+[-1, +0, -] +

int lua_setfenv (lua_State *L, int index);
+ +

+Pops a table from the stack and sets it as +the new environment for the value at the given index. +If the value at the given index is +neither a function nor a thread nor a userdata, +lua_setfenv returns 0. +Otherwise it returns 1. + + + + + +


lua_setfield

+[-1, +0, e] +

void lua_setfield (lua_State *L, int index, const char *k);
+ +

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


lua_setglobal

+[-1, +0, e] +

void lua_setglobal (lua_State *L, const char *name);
+ +

+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)
+
+ + + + +

lua_setmetatable

+[-1, +0, -] +

int lua_setmetatable (lua_State *L, int index);
+ +

+Pops a table from the stack and +sets it as the new metatable for the value at the given +acceptable index. + + + + + +


lua_settable

+[-2, +0, e] +

void lua_settable (lua_State *L, int index);
+ +

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

+This function pops both the key and the value from the stack. +As in Lua, this function may trigger a metamethod +for the "newindex" event (see §2.8). + + + + + +


lua_settop

+[-?, +?, -] +

void lua_settop (lua_State *L, int index);
+ +

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


lua_State

+
typedef struct lua_State lua_State;
+ +

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

+A pointer to this state must be passed as the first argument to +every function in the library, except to lua_newstate, +which creates a Lua state from scratch. + + + + + +


lua_status

+[-0, +0, -] +

int lua_status (lua_State *L);
+ +

+Returns the status of the thread L. + + +

+The status can be 0 for a normal thread, +an error code if the thread finished its execution with an error, +or LUA_YIELD if the thread is suspended. + + + + + +


lua_toboolean

+[-0, +0, -] +

int lua_toboolean (lua_State *L, int index);
+ +

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


lua_tocfunction

+[-0, +0, -] +

lua_CFunction lua_tocfunction (lua_State *L, int index);
+ +

+Converts a value at the given acceptable index to a C function. +That value must be a C function; +otherwise, returns NULL. + + + + + +


lua_tointeger

+[-0, +0, -] +

lua_Integer lua_tointeger (lua_State *L, int index);
+ +

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


lua_tolstring

+[-0, +0, m] +

const char *lua_tolstring (lua_State *L, int index, size_t *len);
+ +

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


lua_tonumber

+[-0, +0, -] +

lua_Number lua_tonumber (lua_State *L, int index);
+ +

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


lua_topointer

+[-0, +0, -] +

const void *lua_topointer (lua_State *L, int index);
+ +

+Converts the value at the given acceptable index to a generic +C pointer (void*). +The value can 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. + + + + + +


lua_tostring

+[-0, +0, m] +

const char *lua_tostring (lua_State *L, int index);
+ +

+Equivalent to lua_tolstring with len equal to NULL. + + + + + +


lua_tothread

+[-0, +0, -] +

lua_State *lua_tothread (lua_State *L, int index);
+ +

+Converts the value at the given acceptable index to a Lua thread +(represented as lua_State*). +This value must be a thread; +otherwise, the function returns NULL. + + + + + +


lua_touserdata

+[-0, +0, -] +

void *lua_touserdata (lua_State *L, int index);
+ +

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


lua_type

+[-0, +0, -] +

int lua_type (lua_State *L, int index);
+ +

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


lua_typename

+[-0, +0, -] +

const char *lua_typename  (lua_State *L, int tp);
+ +

+Returns the name of the type encoded by the value tp, +which must be one the values returned by lua_type. + + + + + +


lua_Writer

+
typedef int (*lua_Writer) (lua_State *L,
+                           const void* p,
+                           size_t sz,
+                           void* ud);
+ +

+The type of the writer function used by lua_dump. +Every time it produces another piece of chunk, +lua_dump calls the writer, +passing along the buffer to be written (p), +its size (sz), +and the data parameter supplied to lua_dump. + + +

+The writer returns an error code: +0 means no errors; +any other value means an error and stops lua_dump from +calling the writer again. + + + + + +


lua_xmove

+[-?, +?, -] +

void lua_xmove (lua_State *from, lua_State *to, int n);
+ +

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


lua_yield

+[-?, +?, -] +

int lua_yield  (lua_State *L, int nresults);
+ +

+Yields a coroutine. + + +

+This function should only be called as the +return expression of a C function, as follows: + +

+     return lua_yield (L, nresults);
+

+When a C function calls lua_yield in that way, +the running coroutine suspends its execution, +and the call to lua_resume that started this coroutine returns. +The parameter nresults is the number of values from the stack +that are passed as results to lua_resume. + + + + + + + +

3.8 - The Debug Interface

+ +

+Lua has no built-in debugging facilities. +Instead, it offers a special interface +by means of functions and hooks. +This interface allows the construction of different +kinds of debuggers, profilers, and other tools +that need "inside information" from the interpreter. + + + +


lua_Debug

+
typedef struct lua_Debug {
+  int event;
+  const char *name;           /* (n) */
+  const char *namewhat;       /* (n) */
+  const char *what;           /* (S) */
+  const char *source;         /* (S) */
+  int currentline;            /* (l) */
+  int nups;                   /* (u) number of upvalues */
+  int linedefined;            /* (S) */
+  int lastlinedefined;        /* (S) */
+  char short_src[LUA_IDSIZE]; /* (S) */
+  /* private part */
+  other fields
+} lua_Debug;
+ +

+A structure used to carry different pieces of +information about an active function. +lua_getstack fills only the private part +of this structure, for later use. +To fill the other fields of lua_Debug with useful information, +call lua_getinfo. + + +

+The fields of lua_Debug have the following meaning: + +

    + +
  • source: +If the function was defined in a string, +then source is that string. +If the function was defined in a file, +then source starts with a '@' followed by the file name. +
  • + +
  • short_src: +a "printable" version of source, to be used in error messages. +
  • + +
  • linedefined: +the line number where the definition of the function starts. +
  • + +
  • lastlinedefined: +the line number where the definition of the function ends. +
  • + +
  • what: +the string "Lua" if the function is a Lua function, +"C" if it is a C function, +"main" if it is the main part of a chunk, +and "tail" if it was a function that did a tail call. +In the latter case, +Lua has no other information about the function. +
  • + +
  • currentline: +the current line where the given function is executing. +When no line information is available, +currentline is set to -1. +
  • + +
  • name: +a reasonable name for the given function. +Because functions in Lua are first-class values, +they do not have a fixed name: +some functions can be the value of multiple global variables, +while others can be stored only in a table field. +The lua_getinfo function checks how the function was +called to find a suitable name. +If it cannot find a name, +then name is set to NULL. +
  • + +
  • namewhat: +explains the name field. +The value of namewhat can be +"global", "local", "method", +"field", "upvalue", or "" (the empty string), +according to how the function was called. +(Lua uses the empty string when no other option seems to apply.) +
  • + +
  • nups: +the number of upvalues of the function. +
  • + +
+ + + + +

lua_gethook

+[-0, +0, -] +

lua_Hook lua_gethook (lua_State *L);
+ +

+Returns the current hook function. + + + + + +


lua_gethookcount

+[-0, +0, -] +

int lua_gethookcount (lua_State *L);
+ +

+Returns the current hook count. + + + + + +


lua_gethookmask

+[-0, +0, -] +

int lua_gethookmask (lua_State *L);
+ +

+Returns the current hook mask. + + + + + +


lua_getinfo

+[-(0|1), +(0|1|2), m] +

int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
+ +

+Returns information about a specific function or function invocation. + + +

+To get information about a function invocation, +the parameter ar must be a valid activation record that was +filled by a previous call to lua_getstack or +given as argument to a hook (see lua_Hook). + + +

+To get information about a function you push it onto the stack +and start the what string with the character '>'. +(In that case, +lua_getinfo pops the function in the top of the stack.) +For instance, to know in which line a function f was defined, +you can write the following code: + +

+     lua_Debug ar;
+     lua_getfield(L, LUA_GLOBALSINDEX, "f");  /* get global 'f' */
+     lua_getinfo(L, ">S", &ar);
+     printf("%d\n", ar.linedefined);
+
+ +

+Each character in the string what +selects some fields of the structure ar to be filled or +a value to be pushed on the stack: + +

    + +
  • 'n': fills in the field name and namewhat; +
  • + +
  • 'S': +fills in the fields source, short_src, +linedefined, lastlinedefined, and what; +
  • + +
  • 'l': fills in the field currentline; +
  • + +
  • 'u': fills in the field nups; +
  • + +
  • 'f': +pushes onto the stack the function that is +running at the given level; +
  • + +
  • 'L': +pushes onto the stack a table whose indices are the +numbers of the lines that are valid on the function. +(A valid line is a line with some associated code, +that is, a line where you can put a break point. +Non-valid lines include empty lines and comments.) +
  • + +
+ +

+This function returns 0 on error +(for instance, an invalid option in what). + + + + + +


lua_getlocal

+[-0, +(0|1), -] +

const char *lua_getlocal (lua_State *L, lua_Debug *ar, int n);
+ +

+Gets information about a local variable of a given activation record. +The parameter ar must be a valid activation record that was +filled by a previous call to lua_getstack or +given as argument to a hook (see lua_Hook). +The index n selects which local variable to inspect +(1 is the first parameter or active local variable, and so on, +until the last active local variable). +lua_getlocal pushes the variable's value onto the stack +and returns its name. + + +

+Variable names starting with '(' (open parentheses) +represent internal variables +(loop control variables, temporaries, and C function locals). + + +

+Returns NULL (and pushes nothing) +when the index is greater than +the number of active local variables. + + + + + +


lua_getstack

+[-0, +0, -] +

int lua_getstack (lua_State *L, int level, lua_Debug *ar);
+ +

+Get information about the interpreter runtime stack. + + +

+This function fills parts of a lua_Debug structure with +an identification of the activation record +of the function executing at a given level. +Level 0 is the current running function, +whereas level n+1 is the function that has called level n. +When there are no errors, lua_getstack returns 1; +when called with a level greater than the stack depth, +it returns 0. + + + + + +


lua_getupvalue

+[-0, +(0|1), -] +

const char *lua_getupvalue (lua_State *L, int funcindex, int n);
+ +

+Gets information about a closure's upvalue. +(For Lua functions, +upvalues are the external local variables that the function uses, +and that are consequently included in its closure.) +lua_getupvalue gets the index n of an upvalue, +pushes the upvalue's value onto the stack, +and returns its name. +funcindex points to the closure in the stack. +(Upvalues have no particular order, +as they are active through the whole function. +So, they are numbered in an arbitrary order.) + + +

+Returns NULL (and pushes nothing) +when the index is greater than the number of upvalues. +For C functions, this function uses the empty string "" +as a name for all upvalues. + + + + + +


lua_Hook

+
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
+ +

+Type for debugging hook functions. + + +

+Whenever a hook is called, its ar argument has its field +event set to the specific event that triggered the hook. +Lua identifies these events with the following constants: +LUA_HOOKCALL, LUA_HOOKRET, +LUA_HOOKTAILRET, LUA_HOOKLINE, +and LUA_HOOKCOUNT. +Moreover, for line events, the field currentline is also set. +To get the value of any other field in ar, +the hook must call lua_getinfo. +For return events, event can be LUA_HOOKRET, +the normal value, or LUA_HOOKTAILRET. +In the latter case, Lua is simulating a return from +a function that did a tail call; +in this case, it is useless to call lua_getinfo. + + +

+While Lua is running a hook, it disables other calls to hooks. +Therefore, if a hook calls back Lua to execute a function or a chunk, +this execution occurs without any calls to hooks. + + + + + +


lua_sethook

+[-0, +0, -] +

int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);
+ +

+Sets the debugging hook function. + + +

+Argument f is the hook function. +mask specifies on which events the hook will be called: +it is formed by a bitwise or of the constants +LUA_MASKCALL, +LUA_MASKRET, +LUA_MASKLINE, +and LUA_MASKCOUNT. +The count argument is only meaningful when the mask +includes LUA_MASKCOUNT. +For each event, the hook is called as explained below: + +

    + +
  • The call hook: is called when the interpreter calls a function. +The hook is called just after Lua enters the new function, +before the function gets its arguments. +
  • + +
  • The return hook: is called when the interpreter returns from a function. +The hook is called just before Lua leaves the function. +You have no access to the values to be returned by the function. +
  • + +
  • The line hook: is called when the interpreter is about to +start the execution of a new line of code, +or when it jumps back in the code (even to the same line). +(This event only happens while Lua is executing a Lua function.) +
  • + +
  • The count hook: is called after the interpreter executes every +count instructions. +(This event only happens while Lua is executing a Lua function.) +
  • + +
+ +

+A hook is disabled by setting mask to zero. + + + + + +


lua_setlocal

+[-(0|1), +0, -] +

const char *lua_setlocal (lua_State *L, lua_Debug *ar, int n);
+ +

+Sets the value of a local variable of a given activation record. +Parameters ar and n are as in lua_getlocal +(see lua_getlocal). +lua_setlocal assigns the value at the top of the stack +to the variable and returns its name. +It also pops the value from the stack. + + +

+Returns NULL (and pops nothing) +when the index is greater than +the number of active local variables. + + + + + +


lua_setupvalue

+[-(0|1), +0, -] +

const char *lua_setupvalue (lua_State *L, int funcindex, int n);
+ +

+Sets the value of a closure's upvalue. +It assigns the value at the top of the stack +to the upvalue and returns its name. +It also pops the value from the stack. +Parameters funcindex and n are as in the lua_getupvalue +(see lua_getupvalue). + + +

+Returns NULL (and pops nothing) +when the index is greater than the number of upvalues. + + + + + + + +

4 - The Auxiliary Library

+ +

+ +The auxiliary library provides several convenient functions +to interface C with Lua. +While the basic API provides the primitive functions for all +interactions between C and Lua, +the auxiliary library provides higher-level functions for some +common tasks. + + +

+All functions from the auxiliary library +are defined in header file lauxlib.h and +have a prefix luaL_. + + +

+All functions in the auxiliary library are built on +top of the basic API, +and so they provide nothing that cannot be done with this API. + + +

+Several functions in the auxiliary library are used to +check C function arguments. +Their names are always luaL_check* or luaL_opt*. +All of these functions throw an error if the check is not satisfied. +Because the error message is formatted for arguments +(e.g., "bad argument #1"), +you should not use these functions for other stack values. + + + +

4.1 - Functions and Types

+ +

+Here we list all functions and types from the auxiliary library +in alphabetical order. + + + +


luaL_addchar

+[-0, +0, m] +

void luaL_addchar (luaL_Buffer *B, char c);
+ +

+Adds the character c to the buffer B +(see luaL_Buffer). + + + + + +


luaL_addlstring

+[-0, +0, m] +

void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);
+ +

+Adds the string pointed to by s with length l to +the buffer B +(see luaL_Buffer). +The string may contain embedded zeros. + + + + + +


luaL_addsize

+[-0, +0, m] +

void luaL_addsize (luaL_Buffer *B, size_t n);
+ +

+Adds to the buffer B (see luaL_Buffer) +a string of length n previously copied to the +buffer area (see luaL_prepbuffer). + + + + + +


luaL_addstring

+[-0, +0, m] +

void luaL_addstring (luaL_Buffer *B, const char *s);
+ +

+Adds the zero-terminated string pointed to by s +to the buffer B +(see luaL_Buffer). +The string may not contain embedded zeros. + + + + + +


luaL_addvalue

+[-1, +0, m] +

void luaL_addvalue (luaL_Buffer *B);
+ +

+Adds the value at the top of the stack +to the buffer B +(see luaL_Buffer). +Pops the value. + + +

+This is the only function on string buffers that can (and must) +be called with an extra element on the stack, +which is the value to be added to the buffer. + + + + + +


luaL_argcheck

+[-0, +0, v] +

void luaL_argcheck (lua_State *L,
+                    int cond,
+                    int narg,
+                    const char *extramsg);
+ +

+Checks whether cond is true. +If not, raises an error with the following message, +where func is retrieved from the call stack: + +

+     bad argument #<narg> to <func> (<extramsg>)
+
+ + + + +

luaL_argerror

+[-0, +0, v] +

int luaL_argerror (lua_State *L, int narg, const char *extramsg);
+ +

+Raises an error with the following message, +where func is retrieved from the call stack: + +

+     bad argument #<narg> to <func> (<extramsg>)
+
+ +

+This function never returns, +but it is an idiom to use it in C functions +as return luaL_argerror(args). + + + + + +


luaL_Buffer

+
typedef struct luaL_Buffer luaL_Buffer;
+ +

+Type for a string buffer. + + +

+A string buffer allows C code to build Lua strings piecemeal. +Its pattern of use is as follows: + +

    + +
  • First you declare a variable b of type luaL_Buffer.
  • + +
  • Then you initialize it with a call luaL_buffinit(L, &b).
  • + +
  • +Then you add string pieces to the buffer calling any of +the luaL_add* functions. +
  • + +
  • +You finish by calling luaL_pushresult(&b). +This call leaves the final string on the top of the stack. +
  • + +
+ +

+During its normal operation, +a string buffer uses a variable number of stack slots. +So, while using a buffer, you cannot assume that you know where +the top of the stack is. +You can use the stack between successive calls to buffer operations +as long as that use is balanced; +that is, +when you call a buffer operation, +the stack is at the same level +it was immediately after the previous buffer operation. +(The only exception to this rule is luaL_addvalue.) +After calling luaL_pushresult the stack is back to its +level when the buffer was initialized, +plus the final string on its top. + + + + + +


luaL_buffinit

+[-0, +0, -] +

void luaL_buffinit (lua_State *L, luaL_Buffer *B);
+ +

+Initializes a buffer B. +This function does not allocate any space; +the buffer must be declared as a variable +(see luaL_Buffer). + + + + + +


luaL_callmeta

+[-0, +(0|1), e] +

int luaL_callmeta (lua_State *L, int obj, const char *e);
+ +

+Calls a metamethod. + + +

+If the object at index obj has a metatable and this +metatable has a field e, +this function calls this field and passes the object as its only argument. +In this case this function returns 1 and pushes onto the +stack the value returned by the call. +If there is no metatable or no metamethod, +this function returns 0 (without pushing any value on the stack). + + + + + +


luaL_checkany

+[-0, +0, v] +

void luaL_checkany (lua_State *L, int narg);
+ +

+Checks whether the function has an argument +of any type (including nil) at position narg. + + + + + +


luaL_checkint

+[-0, +0, v] +

int luaL_checkint (lua_State *L, int narg);
+ +

+Checks whether the function argument narg is a number +and returns this number cast to an int. + + + + + +


luaL_checkinteger

+[-0, +0, v] +

lua_Integer luaL_checkinteger (lua_State *L, int narg);
+ +

+Checks whether the function argument narg is a number +and returns this number cast to a lua_Integer. + + + + + +


luaL_checklong

+[-0, +0, v] +

long luaL_checklong (lua_State *L, int narg);
+ +

+Checks whether the function argument narg is a number +and returns this number cast to a long. + + + + + +


luaL_checklstring

+[-0, +0, v] +

const char *luaL_checklstring (lua_State *L, int narg, size_t *l);
+ +

+Checks whether the function argument narg is a string +and returns this string; +if l is not NULL fills *l +with the string's length. + + +

+This function uses lua_tolstring to get its result, +so all conversions and caveats of that function apply here. + + + + + +


luaL_checknumber

+[-0, +0, v] +

lua_Number luaL_checknumber (lua_State *L, int narg);
+ +

+Checks whether the function argument narg is a number +and returns this number. + + + + + +


luaL_checkoption

+[-0, +0, v] +

int luaL_checkoption (lua_State *L,
+                      int narg,
+                      const char *def,
+                      const char *const lst[]);
+ +

+Checks whether the function argument narg is a string and +searches for this string in the array lst +(which must be NULL-terminated). +Returns the index in the array where the string was found. +Raises an error if the argument is not a string or +if the string cannot be found. + + +

+If def is not NULL, +the function uses def as a default value when +there is no argument narg or if this argument is nil. + + +

+This is a useful function for mapping strings to C enums. +(The usual convention in Lua libraries is +to use strings instead of numbers to select options.) + + + + + +


luaL_checkstack

+[-0, +0, v] +

void luaL_checkstack (lua_State *L, int sz, const char *msg);
+ +

+Grows the stack size to top + sz elements, +raising an error if the stack cannot grow to that size. +msg is an additional text to go into the error message. + + + + + +


luaL_checkstring

+[-0, +0, v] +

const char *luaL_checkstring (lua_State *L, int narg);
+ +

+Checks whether the function argument narg is a string +and returns this string. + + +

+This function uses lua_tolstring to get its result, +so all conversions and caveats of that function apply here. + + + + + +


luaL_checktype

+[-0, +0, v] +

void luaL_checktype (lua_State *L, int narg, int t);
+ +

+Checks whether the function argument narg has type t. +See lua_type for the encoding of types for t. + + + + + +


luaL_checkudata

+[-0, +0, v] +

void *luaL_checkudata (lua_State *L, int narg, const char *tname);
+ +

+Checks whether the function argument narg is a userdata +of the type tname (see luaL_newmetatable). + + + + + +


luaL_dofile

+[-0, +?, m] +

int luaL_dofile (lua_State *L, const char *filename);
+ +

+Loads and runs the given file. +It is defined as the following macro: + +

+     (luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0))
+

+It returns 0 if there are no errors +or 1 in case of errors. + + + + + +


luaL_dostring

+[-0, +?, m] +

int luaL_dostring (lua_State *L, const char *str);
+ +

+Loads and runs the given string. +It is defined as the following macro: + +

+     (luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0))
+

+It returns 0 if there are no errors +or 1 in case of errors. + + + + + +


luaL_error

+[-0, +0, v] +

int luaL_error (lua_State *L, const char *fmt, ...);
+ +

+Raises an error. +The error message format is given by fmt +plus any extra arguments, +following the same rules of lua_pushfstring. +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. + + +

+This function never returns, +but it is an idiom to use it in C functions +as return luaL_error(args). + + + + + +


luaL_getmetafield

+[-0, +(0|1), m] +

int luaL_getmetafield (lua_State *L, int obj, const char *e);
+ +

+Pushes onto the stack the field e from the metatable +of the object at index obj. +If the object does not have a metatable, +or if the metatable does not have this field, +returns 0 and pushes nothing. + + + + + +


luaL_getmetatable

+[-0, +1, -] +

void luaL_getmetatable (lua_State *L, const char *tname);
+ +

+Pushes onto the stack the metatable associated with name tname +in the registry (see luaL_newmetatable). + + + + + +


luaL_gsub

+[-0, +1, m] +

const char *luaL_gsub (lua_State *L,
+                       const char *s,
+                       const char *p,
+                       const char *r);
+ +

+Creates a copy of string s by replacing +any occurrence of the string p +with the string r. +Pushes the resulting string on the stack and returns it. + + + + + +


luaL_loadbuffer

+[-0, +1, m] +

int luaL_loadbuffer (lua_State *L,
+                     const char *buff,
+                     size_t sz,
+                     const char *name);
+ +

+Loads a buffer as a Lua chunk. +This function uses lua_load to load the chunk in the +buffer pointed to by buff with size sz. + + +

+This function returns the same results as lua_load. +name is the chunk name, +used for debug information and error messages. + + + + + +


luaL_loadfile

+[-0, +1, m] +

int luaL_loadfile (lua_State *L, const char *filename);
+ +

+Loads a file as a Lua chunk. +This function uses lua_load to load the chunk in the file +named filename. +If filename is NULL, +then it loads from the standard input. +The first line in the file is ignored if it starts with a #. + + +

+This function returns the same results as lua_load, +but it has an extra error code LUA_ERRFILE +if it cannot open/read the file. + + +

+As lua_load, this function only loads the chunk; +it does not run it. + + + + + +


luaL_loadstring

+[-0, +1, m] +

int luaL_loadstring (lua_State *L, const char *s);
+ +

+Loads a string as a Lua chunk. +This function uses lua_load to load the chunk in +the zero-terminated string s. + + +

+This function returns the same results as lua_load. + + +

+Also as lua_load, this function only loads the chunk; +it does not run it. + + + + + +


luaL_newmetatable

+[-0, +1, m] +

int luaL_newmetatable (lua_State *L, const char *tname);
+ +

+If the registry already has the key tname, +returns 0. +Otherwise, +creates a new table to be used as a metatable for userdata, +adds it to the registry with key tname, +and returns 1. + + +

+In both cases pushes onto the stack the final value associated +with tname in the registry. + + + + + +


luaL_newstate

+[-0, +0, -] +

lua_State *luaL_newstate (void);
+ +

+Creates a new Lua state. +It calls lua_newstate with an +allocator based on the standard C realloc function +and then sets a panic function (see lua_atpanic) that prints +an error message to the standard error output in case of fatal +errors. + + +

+Returns the new state, +or NULL if there is a memory allocation error. + + + + + +


luaL_openlibs

+[-0, +0, m] +

void luaL_openlibs (lua_State *L);
+ +

+Opens all standard Lua libraries into the given state. + + + + + +


luaL_optint

+[-0, +0, v] +

int luaL_optint (lua_State *L, int narg, int d);
+ +

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


luaL_optinteger

+[-0, +0, v] +

lua_Integer luaL_optinteger (lua_State *L,
+                             int narg,
+                             lua_Integer d);
+ +

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


luaL_optlong

+[-0, +0, v] +

long luaL_optlong (lua_State *L, int narg, long 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. + + + + + +


luaL_optlstring

+[-0, +0, v] +

const char *luaL_optlstring (lua_State *L,
+                             int narg,
+                             const char *d,
+                             size_t *l);
+ +

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

+If l is not NULL, +fills the position *l with the results's length. + + + + + +


luaL_optnumber

+[-0, +0, v] +

lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number d);
+ +

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


luaL_optstring

+[-0, +0, v] +

const char *luaL_optstring (lua_State *L,
+                            int narg,
+                            const char *d);
+ +

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


luaL_prepbuffer

+[-0, +0, -] +

char *luaL_prepbuffer (luaL_Buffer *B);
+ +

+Returns an address to a space of size LUAL_BUFFERSIZE +where you can copy a string to be added to buffer B +(see luaL_Buffer). +After copying the string into this space you must call +luaL_addsize with the size of the string to actually add +it to the buffer. + + + + + +


luaL_pushresult

+[-?, +1, m] +

void luaL_pushresult (luaL_Buffer *B);
+ +

+Finishes the use of buffer B leaving the final string on +the top of the stack. + + + + + +


luaL_ref

+[-1, +0, m] +

int luaL_ref (lua_State *L, int t);
+ +

+Creates and returns a reference, +in the table at index t, +for the object at the top of the stack (and pops the object). + + +

+A reference is a unique integer key. +As long as you do not manually add integer keys into table t, +luaL_ref ensures the uniqueness of the key it returns. +You can retrieve an object referred by reference r +by calling lua_rawgeti(L, t, r). +Function luaL_unref frees a reference and its associated object. + + +

+If the object at the top of the stack is nil, +luaL_ref returns the constant LUA_REFNIL. +The constant LUA_NOREF is guaranteed to be different +from any reference returned by luaL_ref. + + + + + +


luaL_Reg

+
typedef struct luaL_Reg {
+  const char *name;
+  lua_CFunction func;
+} luaL_Reg;
+ +

+Type for arrays of functions to be registered by +luaL_register. +name is the function name and func is a pointer to +the function. +Any array of luaL_Reg must end with an sentinel entry +in which both name and func are NULL. + + + + + +


luaL_register

+[-(0|1), +1, m] +

void luaL_register (lua_State *L,
+                    const char *libname,
+                    const luaL_Reg *l);
+ +

+Opens a library. + + +

+When called with libname equal to NULL, +it simply registers all functions in the list l +(see luaL_Reg) into the table on the top of the stack. + + +

+When called with a non-null libname, +luaL_register creates a new table t, +sets it as the value of the global variable libname, +sets it as the value of package.loaded[libname], +and registers on it all functions in the list l. +If there is a table in package.loaded[libname] or in +variable libname, +reuses this table instead of creating a new one. + + +

+In any case the function leaves the table +on the top of the stack. + + + + + +


luaL_typename

+[-0, +0, -] +

const char *luaL_typename (lua_State *L, int index);
+ +

+Returns the name of the type of the value at the given index. + + + + + +


luaL_typerror

+[-0, +0, v] +

int luaL_typerror (lua_State *L, int narg, const char *tname);
+ +

+Generates an error with a message like the following: + +

+     location: bad argument narg to 'func' (tname expected, got rt)
+

+where location is produced by luaL_where, +func is the name of the current function, +and rt is the type name of the actual argument. + + + + + +


luaL_unref

+[-0, +0, -] +

void luaL_unref (lua_State *L, int t, int ref);
+ +

+Releases reference ref from the table at index t +(see luaL_ref). +The entry is removed from the table, +so that the referred object can be collected. +The reference ref is also freed to be used again. + + +

+If ref is LUA_NOREF or LUA_REFNIL, +luaL_unref does nothing. + + + + + +


luaL_where

+[-0, +1, m] +

void luaL_where (lua_State *L, int lvl);
+ +

+Pushes onto the stack a string identifying the current position +of the control at level lvl in the call stack. +Typically this string has the following format: + +

+     chunkname:currentline:
+

+Level 0 is the running function, +level 1 is the function that called the running function, +etc. + + +

+This function is used to build a prefix for error messages. + + + + + + + +

5 - Standard Libraries

+ +

+The standard Lua libraries provide useful functions +that are implemented directly through the C API. +Some of these functions provide essential services to the language +(e.g., type and getmetatable); +others provide access to "outside" services (e.g., I/O); +and others could be implemented in Lua itself, +but are quite useful or have critical performance requirements that +deserve an implementation in C (e.g., table.sort). + + +

+All libraries are implemented through the official C API +and are provided as separate C modules. +Currently, Lua has the following standard libraries: + +

    + +
  • basic library,
  • which includes the coroutine sub-library; + +
  • package library;
  • + +
  • string manipulation;
  • + +
  • table manipulation;
  • + +
  • mathematical functions (sin, log, etc.);
  • + +
  • input and output;
  • + +
  • operating system facilities;
  • + +
  • debug facilities.
  • + +

+Except for the basic and package libraries, +each library provides all its functions as fields of a global table +or as methods of its objects. + + +

+To have access to these libraries, +the C host program should call the luaL_openlibs function, +which opens all standard libraries. +Alternatively, +it can open them individually by calling +luaopen_base (for the basic library), +luaopen_package (for the package library), +luaopen_string (for the string library), +luaopen_table (for the table library), +luaopen_math (for the mathematical library), +luaopen_io (for the I/O library), +luaopen_os (for the Operating System library), +and luaopen_debug (for the debug library). +These functions are declared in lualib.h +and should not be called directly: +you must call them like any other Lua C function, +e.g., by using lua_call. + + + +

5.1 - Basic Functions

+ +

+The basic library provides some core functions to Lua. +If you do not include this library in your application, +you should check carefully whether you need to provide +implementations for some of its facilities. + + +

+


assert (v [, message])

+Issues an error when +the value of its argument v is false (i.e., nil or false); +otherwise, returns all its arguments. +message is an error message; +when absent, it defaults to "assertion failed!" + + + + +

+


collectgarbage (opt [, arg])

+ + +

+This function is a generic interface to the garbage collector. +It performs different functions according to its first argument, opt: + +

    + +
  • "stop": +stops the garbage collector. +
  • + +
  • "restart": +restarts the garbage collector. +
  • + +
  • "collect": +performs a full garbage-collection cycle. +
  • + +
  • "count": +returns the total memory in use by Lua (in Kbytes). +
  • + +
  • "step": +performs a garbage-collection step. +The step "size" is controlled by arg +(larger values mean more steps) in a non-specified way. +If you want to control the step size +you must experimentally tune the value of arg. +Returns true if the step finished a collection cycle. +
  • + +
  • "setpause": +sets arg as the new value for the pause of +the collector (see §2.10). +Returns the previous value for pause. +
  • + +
  • "setstepmul": +sets arg as the new value for the step multiplier of +the collector (see §2.10). +Returns the previous value for step. +
  • + +
+ + + +

+


dofile (filename)

+Opens the named file and executes its contents as a Lua chunk. +When called without arguments, +dofile executes the contents of the standard input (stdin). +Returns all values returned by the chunk. +In case of errors, dofile propagates the error +to its caller (that is, dofile does not run in protected mode). + + + + +

+


error (message [, level])

+Terminates the last protected function called +and returns message as the error message. +Function error never returns. + + +

+Usually, error adds some information about the error position +at the beginning of the message. +The level argument specifies how to get the error position. +With level 1 (the default), the error position is where the +error function was called. +Level 2 points the error to where the function +that called error was called; and so on. +Passing a level 0 avoids the addition of error position information +to the message. + + + + +

+


_G

+A global variable (not a function) that +holds the global environment (that is, _G._G = _G). +Lua itself does not use this variable; +changing its value does not affect any environment, +nor vice-versa. +(Use setfenv to change environments.) + + + + +

+


getfenv ([f])

+Returns the current environment in use by the function. +f can be a Lua function or a number +that specifies the function at that stack level: +Level 1 is the function calling getfenv. +If the given function is not a Lua function, +or if f is 0, +getfenv returns the global environment. +The default for f is 1. + + + + +

+


getmetatable (object)

+ + +

+If object does not have a metatable, returns nil. +Otherwise, +if the object's metatable has a "__metatable" field, +returns the associated value. +Otherwise, returns the metatable of the given object. + + + + +

+


ipairs (t)

+ + +

+Returns three values: an iterator function, the table t, and 0, +so that the construction + +

+     for i,v in ipairs(t) do body end
+

+will iterate over the pairs (1,t[1]), (2,t[2]), ···, +up to the first integer key absent from the table. + + + + +

+


load (func [, chunkname])

+ + +

+Loads a chunk using function func to get its pieces. +Each call to func must return a string that concatenates +with previous results. +A return of an empty string, nil, or no value signals the end of the chunk. + + +

+If there are no errors, +returns the compiled chunk as a function; +otherwise, returns nil plus the error message. +The environment of the returned function is the global environment. + + +

+chunkname is used as the chunk name for error messages +and debug information. +When absent, +it defaults to "=(load)". + + + + +

+


loadfile ([filename])

+ + +

+Similar to load, +but gets the chunk from file filename +or from the standard input, +if no file name is given. + + + + +

+


loadstring (string [, chunkname])

+ + +

+Similar to load, +but gets the chunk from the given string. + + +

+To load and run a given string, use the idiom + +

+     assert(loadstring(s))()
+
+ +

+When absent, +chunkname defaults to the given string. + + + + +

+


next (table [, index])

+ + +

+Allows a program to traverse all fields of a table. +Its first argument is a table and its second argument +is an index in this table. +next returns the next index of the table +and its associated value. +When called with nil as its second argument, +next returns an initial index +and its associated value. +When called with the last index, +or with nil in an empty table, +next returns nil. +If the second argument is absent, then it is interpreted as nil. +In particular, +you can use next(t) to check whether a table is empty. + + +

+The order in which the indices are enumerated is not specified, +even for numeric indices. +(To traverse a table in numeric order, +use a numerical for or the ipairs function.) + + +

+The behavior of next is undefined if, +during the traversal, +you assign any value to a non-existent field in the table. +You may however modify existing fields. +In particular, you may clear existing fields. + + + + +

+


pairs (t)

+ + +

+Returns three values: the next function, the table t, and nil, +so that the construction + +

+     for k,v in pairs(t) do body end
+

+will iterate over all key–value pairs of table t. + + +

+See function next for the caveats of modifying +the table during its traversal. + + + + +

+


pcall (f, arg1, ···)

+ + +

+Calls function f with +the given arguments in protected mode. +This means that any error inside f is not propagated; +instead, pcall catches the error +and returns a status code. +Its first result is the status code (a boolean), +which is true if the call succeeds without errors. +In such case, pcall also returns all results from the call, +after this first result. +In case of any error, pcall returns false plus the error message. + + + + +

+


print (···)

+Receives any number of arguments, +and prints their values to stdout, +using the tostring function to convert them to strings. +print is not intended for formatted output, +but only as a quick way to show a value, +typically for debugging. +For formatted output, use string.format. + + + + +

+


rawequal (v1, v2)

+Checks whether v1 is equal to v2, +without invoking any metamethod. +Returns a boolean. + + + + +

+


rawget (table, index)

+Gets the real value of table[index], +without invoking any metamethod. +table must be a table; +index may be any value. + + + + +

+


rawset (table, index, value)

+Sets the real value of table[index] to value, +without invoking any metamethod. +table must be a table, +index any value different from nil, +and value any Lua value. + + +

+This function returns table. + + + + +

+


select (index, ···)

+ + +

+If index is a number, +returns all arguments after argument number index. +Otherwise, index must be the string "#", +and select returns the total number of extra arguments it received. + + + + +

+


setfenv (f, table)

+ + +

+Sets the environment to be used by the given function. +f can be a Lua function or a number +that specifies the function at that stack level: +Level 1 is the function calling setfenv. +setfenv returns the given function. + + +

+As a special case, when f is 0 setfenv changes +the environment of the running thread. +In this case, setfenv returns no values. + + + + +

+


setmetatable (table, metatable)

+ + +

+Sets the metatable for the given table. +(You cannot change the metatable of other types from Lua, only from C.) +If metatable is nil, +removes the metatable of the given table. +If the original metatable has a "__metatable" field, +raises an error. + + +

+This function returns table. + + + + +

+


tonumber (e [, base])

+Tries to convert its argument to a number. +If the argument is already a number or a string convertible +to a number, then tonumber returns this number; +otherwise, it returns nil. + + +

+An optional argument specifies the base to interpret the numeral. +The base may be any integer between 2 and 36, inclusive. +In bases above 10, the letter 'A' (in either upper or lower case) +represents 10, 'B' represents 11, and so forth, +with 'Z' representing 35. +In base 10 (the default), the number can have a decimal part, +as well as an optional exponent part (see §2.1). +In other bases, only unsigned integers are accepted. + + + + +

+


tostring (e)

+Receives an argument of any type and +converts it to a string in a reasonable format. +For complete control of how numbers are converted, +use string.format. + + +

+If the metatable of e has a "__tostring" field, +then tostring calls the corresponding value +with e as argument, +and uses the result of the call as its result. + + + + +

+


type (v)

+Returns the type of its only argument, coded as a string. +The possible results of this function are +"nil" (a string, not the value nil), +"number", +"string", +"boolean", +"table", +"function", +"thread", +and "userdata". + + + + +

+


unpack (list [, i [, j]])

+Returns the elements from the given table. +This function is equivalent to + +
+     return list[i], list[i+1], ···, list[j]
+

+except that the above code can be written only for a fixed number +of elements. +By default, i is 1 and j is the length of the list, +as defined by the length operator (see §2.5.5). + + + + +

+


_VERSION

+A global variable (not a function) that +holds a string containing the current interpreter version. +The current contents of this variable is "Lua 5.1". + + + + +

+


xpcall (f, err)

+ + +

+This function is similar to pcall, +except that you can set a new error handler. + + +

+xpcall calls function f in protected mode, +using err as the error handler. +Any error inside f is not propagated; +instead, xpcall catches the error, +calls the err function with the original error object, +and returns a status code. +Its first result is the status code (a boolean), +which is true if the call succeeds without errors. +In this case, xpcall also returns all results from the call, +after this first result. +In case of any error, +xpcall returns false plus the result from err. + + + + + + + +

5.2 - Coroutine Manipulation

+ +

+The operations related to coroutines comprise a sub-library of +the basic library and come inside the table coroutine. +See §2.11 for a general description of coroutines. + + +

+


coroutine.create (f)

+ + +

+Creates a new coroutine, with body f. +f must be a Lua function. +Returns this new coroutine, +an object with type "thread". + + + + +

+


coroutine.resume (co [, val1, ···])

+ + +

+Starts or continues the execution of coroutine co. +The first time you resume a coroutine, +it starts running its body. +The values val1, ··· are passed +as the arguments to the body function. +If the coroutine has yielded, +resume restarts it; +the values val1, ··· are passed +as the results from the yield. + + +

+If the coroutine runs without any errors, +resume returns true plus any values passed to yield +(if the coroutine yields) or any values returned by the body function +(if the coroutine terminates). +If there is any error, +resume returns false plus the error message. + + + + +

+


coroutine.running ()

+ + +

+Returns the running coroutine, +or nil when called by the main thread. + + + + +

+


coroutine.status (co)

+ + +

+Returns the status of coroutine co, as a string: +"running", +if the coroutine is running (that is, it called status); +"suspended", if the coroutine is suspended in a call to yield, +or if it has not started running yet; +"normal" if the coroutine is active but not running +(that is, it has resumed another coroutine); +and "dead" if the coroutine has finished its body function, +or if it has stopped with an error. + + + + +

+


coroutine.wrap (f)

+ + +

+Creates a new coroutine, with body f. +f must be a Lua function. +Returns a function that resumes the coroutine each time it is called. +Any arguments passed to the function behave as the +extra arguments to resume. +Returns the same values returned by resume, +except the first boolean. +In case of error, propagates the error. + + + + +

+


coroutine.yield (···)

+ + +

+Suspends the execution of the calling coroutine. +The coroutine cannot be running a C function, +a metamethod, or an iterator. +Any arguments to yield are passed as extra results to resume. + + + + + + + +

5.3 - Modules

+ +

+The package library provides basic +facilities for loading and building modules in Lua. +It exports two of its functions directly in the global environment: +require and module. +Everything else is exported in a table package. + + +

+


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 can receive optional options after +the module name, +where each option is a function to be applied over the module. + + + + +

+


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

+


package.cpath

+ + +

+The path used by require to search for a C loader. + + +

+Lua initializes the C path package.cpath in the same way +it initializes the Lua path package.path, +using the environment variable LUA_CPATH +or a default path defined in luaconf.h. + + + + +

+ +


package.loaded

+ + +

+A table used by require to control which +modules are already loaded. +When you require a module modname and +package.loaded[modname] is not false, +require simply returns the value stored there. + + + + +

+


package.loaders

+ + +

+A table used by require to control how to load modules. + + +

+Each entry in this table is a searcher function. +When looking for a module, +require calls each of these searchers in ascending order, +with the module name (the argument given to require) as its +sole parameter. +The function can return another function (the module loader) +or a string explaining why it did not find that module +(or nil if it has nothing to say). +Lua initializes this table with four functions. + + +

+The first searcher simply looks for a loader in the +package.preload table. + + +

+The second searcher looks for a loader as a Lua library, +using the path stored at package.path. +A path is a sequence of templates separated by semicolons. +For each template, +the searcher will change each interrogation +mark in the template by filename, +which is the module name with each dot replaced by a +"directory separator" (such as "/" in Unix); +then it will try to open the resulting file name. +So, for instance, if the Lua path is the string + +

+     "./?.lua;./?.lc;/usr/local/?/init.lua"
+

+the search for a Lua file for module foo +will try to open the files +./foo.lua, ./foo.lc, and +/usr/local/foo/init.lua, in that order. + + +

+The third searcher looks for a loader as a C library, +using the path given by the variable package.cpath. +For instance, +if the C path is the string + +

+     "./?.so;./?.dll;/usr/local/?/init.so"
+

+the searcher for module foo +will try to open the files ./foo.so, ./foo.dll, +and /usr/local/foo/init.so, in that order. +Once it finds a C library, +this searcher first uses a dynamic link facility to link the +application with the library. +Then it tries to find a C function inside the library to +be used as the loader. +The name of this C function is the string "luaopen_" +concatenated with a copy of the module name where each dot +is replaced by an underscore. +Moreover, if the module name has a hyphen, +its prefix up to (and including) the first hyphen is removed. +For instance, if the module name is a.v1-b.c, +the function name will be luaopen_b_c. + + +

+The fourth searcher tries an all-in-one loader. +It searches the C path for a library for +the root name of the given module. +For instance, when requiring a.b.c, +it will search for a C library for a. +If found, it looks into it for an open function for +the submodule; +in our example, that would be luaopen_a_b_c. +With this facility, a package can pack several C submodules +into one single library, +with each submodule keeping its original open function. + + + + +

+


package.loadlib (libname, funcname)

+ + +

+Dynamically links the host program with the C library libname. +Inside this library, looks for a function funcname +and returns this function as a C function. +(So, funcname must follow the protocol (see lua_CFunction)). + + +

+This is a low-level function. +It completely bypasses the package and module system. +Unlike require, +it does not perform any path searching and +does not automatically adds extensions. +libname must be the complete file name of the C library, +including if necessary a path and extension. +funcname must be the exact name exported by the C library +(which may depend on the C compiler and linker used). + + +

+This function is not supported by ANSI C. +As such, it is only available on some platforms +(Windows, Linux, Mac OS X, Solaris, BSD, +plus other Unix systems that support the dlfcn standard). + + + + +

+


package.path

+ + +

+The path used by require to search for a Lua loader. + + +

+At start-up, Lua initializes this variable with +the value of the environment variable LUA_PATH or +with a default path defined in luaconf.h, +if the environment variable is not defined. +Any ";;" in the value of the environment variable +is replaced by the default path. + + + + +

+


package.preload

+ + +

+A table to store loaders for specific modules +(see require). + + + + +

+


package.seeall (module)

+ + +

+Sets a metatable for module with +its __index field referring to the global environment, +so that this module inherits values +from the global environment. +To be used as an option to function module. + + + + + + + +

5.4 - String Manipulation

+ +

+This library provides generic functions for string manipulation, +such as finding and extracting substrings, and pattern matching. +When indexing a string in Lua, the first character is at position 1 +(not at 0, as in C). +Indices are allowed to be negative and are interpreted as indexing backwards, +from the end of the string. +Thus, the last character is at position -1, and so on. + + +

+The string library provides all its functions inside the table +string. +It also sets a metatable for strings +where the __index field points to the string table. +Therefore, you can use the string functions in object-oriented style. +For instance, string.byte(s, i) +can be written as s:byte(i). + + +

+The string library assumes one-byte character encodings. + + +

+


string.byte (s [, i [, j]])

+Returns the internal numerical codes of the characters s[i], +s[i+1], ···, s[j]. +The default value for i is 1; +the default value for j is i. + + +

+Note that numerical codes are not necessarily portable across platforms. + + + + +

+


string.char (···)

+Receives zero or more integers. +Returns a string with length equal to the number of arguments, +in which each character has the internal numerical code equal +to its corresponding argument. + + +

+Note that numerical codes are not necessarily portable across platforms. + + + + +

+


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

+


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

+


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

+


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

+


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 can 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"
+
+ + + +

+


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

+


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

+


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 can be negative. + + + + +

+


string.rep (s, n)

+Returns a string that is the concatenation of n copies of +the string s. + + + + +

+


string.reverse (s)

+Returns a string that is the string s reversed. + + + + +

+


string.sub (s, i [, j])

+Returns the substring of s that +starts at i and continues until j; +i and j can be negative. +If j is absent, then it is assumed to be equal to -1 +(which is the same as the string length). +In particular, +the call string.sub(s,1,j) returns a prefix of s +with length j, +and string.sub(s, -i) returns a suffix of s +with length i. + + + + +

+


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

5.4.1 - Patterns

+ + +

Character Class:

+A character class is used to represent a set of characters. +The following combinations are allowed in describing a character class: + +

    + +
  • x: +(where x is not one of the magic characters +^$()%.[]*+-?) +represents the character x itself. +
  • + +
  • .: (a dot) represents all characters.
  • + +
  • %a: represents all letters.
  • + +
  • %c: represents all control characters.
  • + +
  • %d: represents all digits.
  • + +
  • %l: represents all lowercase letters.
  • + +
  • %p: represents all punctuation characters.
  • + +
  • %s: represents all space characters.
  • + +
  • %u: represents all uppercase letters.
  • + +
  • %w: represents all alphanumeric characters.
  • + +
  • %x: represents all hexadecimal digits.
  • + +
  • %z: represents the character with representation 0.
  • + +
  • %x: (where x is any non-alphanumeric character) +represents the character x. +This is the standard way to escape the magic characters. +Any punctuation character (even the non magic) +can be preceded by a '%' +when used to represent itself in a pattern. +
  • + +
  • [set]: +represents the class which is the union of all +characters in set. +A range of characters can be specified by +separating the end characters of the range with a '-'. +All classes %x described above can also be used as +components in set. +All other characters in set represent themselves. +For example, [%w_] (or [_%w]) +represents all alphanumeric characters plus the underscore, +[0-7] represents the octal digits, +and [0-7%l%-] represents the octal digits plus +the lowercase letters plus the '-' character. + + +

    +The interaction between ranges and classes is not defined. +Therefore, patterns like [%a-z] or [a-%%] +have no meaning. +

  • + +
  • [^set]: +represents the complement of set, +where set is interpreted as above. +
  • + +

+For all classes represented by single letters (%a, %c, etc.), +the corresponding uppercase letter represents the complement of the class. +For instance, %S represents all non-space characters. + + +

+The definitions of letter, space, and other character groups +depend on the current locale. +In particular, the class [a-z] may not be equivalent to %l. + + + + + +

Pattern Item:

+A pattern item can be + +

    + +
  • +a single character class, +which matches any single character in the class; +
  • + +
  • +a single character class followed by '*', +which matches 0 or more repetitions of characters in the class. +These repetition items will always match the longest possible sequence; +
  • + +
  • +a single character class followed by '+', +which matches 1 or more repetitions of characters in the class. +These repetition items will always match the longest possible sequence; +
  • + +
  • +a single character class followed by '-', +which also matches 0 or more repetitions of characters in the class. +Unlike '*', +these repetition items will always match the shortest possible sequence; +
  • + +
  • +a single character class followed by '?', +which matches 0 or 1 occurrence of a character in the class; +
  • + +
  • +%n, for n between 1 and 9; +such item matches a substring equal to the n-th captured string +(see below); +
  • + +
  • +%bxy, where x and y are two distinct characters; +such item matches strings that start with x, end with y, +and where the x and y are balanced. +This means that, if one reads the string from left to right, +counting +1 for an x and -1 for a y, +the ending y is the first y where the count reaches 0. +For instance, the item %b() matches expressions with +balanced parentheses. +
  • + +
+ + + + +

Pattern:

+A pattern is a sequence of pattern items. +A '^' at the beginning of a pattern anchors the match at the +beginning of the subject string. +A '$' at the end of a pattern anchors the match at the +end of the subject string. +At other positions, +'^' and '$' have no special meaning and represent themselves. + + + + + +

Captures:

+A pattern can contain sub-patterns enclosed in parentheses; +they describe captures. +When a match succeeds, the substrings of the subject string +that match captures are stored (captured) for future use. +Captures are numbered according to their left parentheses. +For instance, in the pattern "(a*(.)%w(%s*))", +the part of the string matching "a*(.)%w(%s*)" is +stored as the first capture (and therefore has number 1); +the character matching "." is captured with number 2, +and the part matching "%s*" has number 3. + + +

+As a special case, the empty capture () captures +the current string position (a number). +For instance, if we apply the pattern "()aa()" on the +string "flaaap", there will be two captures: 3 and 5. + + +

+A pattern cannot contain embedded zeros. Use %z instead. + + + + + + + + + + + +

5.5 - Table Manipulation

+This library provides generic functions for table manipulation. +It provides all its functions inside the table table. + + +

+Most functions in the table library assume that the table +represents an array or a list. +For these functions, when we talk about the "length" of a table +we mean the result of the length operator. + + +

+


table.concat (table [, sep [, i [, j]]])

+Given an array where all elements are strings or numbers, +returns table[i]..sep..table[i+1] ··· sep..table[j]. +The default value for sep is the empty string, +the default for i is 1, +and the default for j is the length of the table. +If i is greater than j, returns the empty string. + + + + +

+


table.insert (table, [pos,] value)

+ + +

+Inserts element value at position pos in table, +shifting up other elements to open space, if necessary. +The default value for pos is n+1, +where n is the length of the table (see §2.5.5), +so that a call table.insert(t,x) inserts x at the end +of table t. + + + + +

+


table.maxn (table)

+ + +

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

+


table.remove (table [, pos])

+ + +

+Removes from table the element at position pos, +shifting down other elements to close the space, if necessary. +Returns the value of the removed element. +The default value for pos is n, +where n is the length of the table, +so that a call table.remove(t) removes the last element +of table t. + + + + +

+


table.sort (table [, comp])

+Sorts table elements in a given order, in-place, +from table[1] to table[n], +where n is the length of the table. +If comp is given, +then it must be a function that receives two table elements, +and returns true +when the first is less than the second +(so that not comp(a[i+1],a[i]) will be true after the sort). +If comp is not given, +then the standard Lua operator < is used instead. + + +

+The sort algorithm is not stable; +that is, elements considered equal by the given order +may have their relative positions changed by the sort. + + + + + + + +

5.6 - Mathematical Functions

+ +

+This library is an interface to the standard C math library. +It provides all its functions inside the table math. + + +

+


math.abs (x)

+ + +

+Returns the absolute value of x. + + + + +

+


math.acos (x)

+ + +

+Returns the arc cosine of x (in radians). + + + + +

+


math.asin (x)

+ + +

+Returns the arc sine of x (in radians). + + + + +

+


math.atan (x)

+ + +

+Returns the arc tangent of x (in radians). + + + + +

+


math.atan2 (y, x)

+ + +

+Returns the arc tangent of y/x (in radians), +but uses the signs of both parameters to find the +quadrant of the result. +(It also handles correctly the case of x being zero.) + + + + +

+


math.ceil (x)

+ + +

+Returns the smallest integer larger than or equal to x. + + + + +

+


math.cos (x)

+ + +

+Returns the cosine of x (assumed to be in radians). + + + + +

+


math.cosh (x)

+ + +

+Returns the hyperbolic cosine of x. + + + + +

+


math.deg (x)

+ + +

+Returns the angle x (given in radians) in degrees. + + + + +

+


math.exp (x)

+ + +

+Returns the value ex. + + + + +

+


math.floor (x)

+ + +

+Returns the largest integer smaller than or equal to x. + + + + +

+


math.fmod (x, y)

+ + +

+Returns the remainder of the division of x by y +that rounds the quotient towards zero. + + + + +

+


math.frexp (x)

+ + +

+Returns m and e such that x = m2e, +e is an integer and the absolute value of m is +in the range [0.5, 1) +(or zero when x is zero). + + + + +

+


math.huge

+ + +

+The value HUGE_VAL, +a value larger than or equal to any other numerical value. + + + + +

+


math.ldexp (m, e)

+ + +

+Returns m2e (e should be an integer). + + + + +

+


math.log (x)

+ + +

+Returns the natural logarithm of x. + + + + +

+


math.log10 (x)

+ + +

+Returns the base-10 logarithm of x. + + + + +

+


math.max (x, ···)

+ + +

+Returns the maximum value among its arguments. + + + + +

+


math.min (x, ···)

+ + +

+Returns the minimum value among its arguments. + + + + +

+


math.modf (x)

+ + +

+Returns two numbers, +the integral part of x and the fractional part of x. + + + + +

+


math.pi

+ + +

+The value of pi. + + + + +

+


math.pow (x, y)

+ + +

+Returns xy. +(You can also use the expression x^y to compute this value.) + + + + +

+


math.rad (x)

+ + +

+Returns the angle x (given in degrees) in radians. + + + + +

+


math.random ([m [, n]])

+ + +

+This function is an interface to the simple +pseudo-random generator function rand provided by ANSI C. +(No guarantees can be given for its statistical properties.) + + +

+When called without arguments, +returns a uniform pseudo-random real number +in the range [0,1). +When called with an integer number m, +math.random returns +a uniform pseudo-random integer in the range [1, m]. +When called with two integer numbers m and n, +math.random returns a uniform pseudo-random +integer in the range [m, n]. + + + + +

+


math.randomseed (x)

+ + +

+Sets x as the "seed" +for the pseudo-random generator: +equal seeds produce equal sequences of numbers. + + + + +

+


math.sin (x)

+ + +

+Returns the sine of x (assumed to be in radians). + + + + +

+


math.sinh (x)

+ + +

+Returns the hyperbolic sine of x. + + + + +

+


math.sqrt (x)

+ + +

+Returns the square root of x. +(You can also use the expression x^0.5 to compute this value.) + + + + +

+


math.tan (x)

+ + +

+Returns the tangent of x (assumed to be in radians). + + + + +

+


math.tanh (x)

+ + +

+Returns the hyperbolic tangent of x. + + + + + + + +

5.7 - Input and Output Facilities

+ +

+The I/O library provides two different styles for file manipulation. +The first one uses implicit file descriptors; +that is, there are operations to set a default input file and a +default output file, +and all input/output operations are over these default files. +The second style uses explicit file descriptors. + + +

+When using implicit file descriptors, +all operations are supplied by table io. +When using explicit file descriptors, +the operation io.open returns a file descriptor +and then all operations are supplied as methods of the file descriptor. + + +

+The table io also provides +three predefined file descriptors with their usual meanings from C: +io.stdin, io.stdout, and io.stderr. +The I/O library never closes these files. + + +

+Unless otherwise stated, +all I/O functions return nil on failure +(plus an error message as a second result and +a system-dependent error code as a third result) +and some value different from nil on success. + + +

+


io.close ([file])

+ + +

+Equivalent to file:close(). +Without a file, closes the default output file. + + + + +

+


io.flush ()

+ + +

+Equivalent to file:flush over the default output file. + + + + +

+


io.input ([file])

+ + +

+When called with a file name, it opens the named file (in text mode), +and sets its handle as the default input file. +When called with a file handle, +it simply sets this file handle as the default input file. +When called without parameters, +it returns the current default input file. + + +

+In case of errors this function raises the error, +instead of returning an error code. + + + + +

+


io.lines ([filename])

+ + +

+Opens the given file name in read mode +and returns an iterator function that, +each time it is called, +returns a new line from the file. +Therefore, the construction + +

+     for line in io.lines(filename) do body end
+

+will iterate over all lines of the file. +When the iterator function detects the end of file, +it returns nil (to finish the loop) and automatically closes the file. + + +

+The call io.lines() (with no file name) is equivalent +to io.input():lines(); +that is, it iterates over the lines of the default input file. +In this case it does not close the file when the loop ends. + + + + +

+


io.open (filename [, mode])

+ + +

+This function opens a file, +in the mode specified in the string mode. +It returns a new file handle, +or, in case of errors, nil plus an error message. + + +

+The mode string can be any of the following: + +

    +
  • "r": read mode (the default);
  • +
  • "w": write mode;
  • +
  • "a": append mode;
  • +
  • "r+": update mode, all previous data is preserved;
  • +
  • "w+": update mode, all previous data is erased;
  • +
  • "a+": append update mode, previous data is preserved, + writing is only allowed at the end of file.
  • +

+The mode string can also have a 'b' at the end, +which is needed in some systems to open the file in binary mode. +This string is exactly what is used in the +standard C function fopen. + + + + +

+


io.output ([file])

+ + +

+Similar to io.input, but operates over the default output file. + + + + +

+


io.popen (prog [, mode])

+ + +

+Starts program prog in a separated process and returns +a file handle that you can use to read data from this program +(if mode is "r", the default) +or to write data to this program +(if mode is "w"). + + +

+This function is system dependent and is not available +on all platforms. + + + + +

+


io.read (···)

+ + +

+Equivalent to io.input():read. + + + + +

+


io.tmpfile ()

+ + +

+Returns a handle for a temporary file. +This file is opened in update mode +and it is automatically removed when the program ends. + + + + +

+


io.type (obj)

+ + +

+Checks whether obj is a valid file handle. +Returns the string "file" if obj is an open file handle, +"closed file" if obj is a closed file handle, +or nil if obj is not a file handle. + + + + +

+


io.write (···)

+ + +

+Equivalent to io.output():write. + + + + +

+


file:close ()

+ + +

+Closes file. +Note that files are automatically closed when +their handles are garbage collected, +but that takes an unpredictable amount of time to happen. + + + + +

+


file:flush ()

+ + +

+Saves any written data to file. + + + + +

+


file:lines ()

+ + +

+Returns an iterator function that, +each time it is called, +returns a new line from the file. +Therefore, the construction + +

+     for line in file:lines() do body end
+

+will iterate over all lines of the file. +(Unlike io.lines, this function does not close the file +when the loop ends.) + + + + +

+


file:read (···)

+ + +

+Reads the file file, +according to the given formats, which specify what to read. +For each format, +the function returns a string (or a number) with the characters read, +or nil if it cannot read data with the specified format. +When called without formats, +it uses a default format that reads the entire next line +(see below). + + +

+The available formats are + +

    + +
  • "*n": +reads a number; +this is the only format that returns a number instead of a string. +
  • + +
  • "*a": +reads the whole file, starting at the current position. +On end of file, it returns the empty string. +
  • + +
  • "*l": +reads the next line (skipping the end of line), +returning nil on end of file. +This is the default format. +
  • + +
  • number: +reads a string with up to this number of characters, +returning nil on end of file. +If number is zero, +it reads nothing and returns an empty string, +or nil on end of file. +
  • + +
+ + + +

+


file:seek ([whence] [, offset])

+ + +

+Sets and gets the file position, +measured from the beginning of the file, +to the position given by offset plus a base +specified by the string whence, as follows: + +

    +
  • "set": base is position 0 (beginning of the file);
  • +
  • "cur": base is current position;
  • +
  • "end": base is end of file;
  • +

+In case of success, function seek returns the final file position, +measured in bytes from the beginning of the file. +If this function fails, it returns nil, +plus a string describing the error. + + +

+The default value for whence is "cur", +and for offset is 0. +Therefore, the call file:seek() returns the current +file position, without changing it; +the call file:seek("set") sets the position to the +beginning of the file (and returns 0); +and the call file:seek("end") sets the position to the +end of the file, and returns its size. + + + + +

+


file:setvbuf (mode [, size])

+ + +

+Sets the buffering mode for an output file. +There are three available modes: + +

    + +
  • "no": +no buffering; the result of any output operation appears immediately. +
  • + +
  • "full": +full buffering; output operation is performed only +when the buffer is full (or when you explicitly flush the file +(see io.flush)). +
  • + +
  • "line": +line buffering; output is buffered until a newline is output +or there is any input from some special files +(such as a terminal device). +
  • + +

+For the last two cases, size +specifies the size of the buffer, in bytes. +The default is an appropriate size. + + + + +

+


file:write (···)

+ + +

+Writes the value of each of its arguments to +the file. +The arguments must be strings or numbers. +To write other values, +use tostring or string.format before write. + + + + + + + +

5.8 - Operating System Facilities

+ +

+This library is implemented through table os. + + +

+


os.clock ()

+ + +

+Returns an approximation of the amount in seconds of CPU time +used by the program. + + + + +

+


os.date ([format [, time]])

+ + +

+Returns a string or a table containing date and time, +formatted according to the given string format. + + +

+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")). + + + + +

+


os.difftime (t2, t1)

+ + +

+Returns the number of seconds from time t1 to time t2. +In POSIX, Windows, and some other systems, +this value is exactly t2-t1. + + + + +

+


os.execute ([command])

+ + +

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

+


os.exit ([code])

+ + +

+Calls the C function exit, +with an optional code, +to terminate the host program. +The default value for code is the success code. + + + + +

+


os.getenv (varname)

+ + +

+Returns the value of the process environment variable varname, +or nil if the variable is not defined. + + + + +

+


os.remove (filename)

+ + +

+Deletes the file or directory with the given name. +Directories must be empty to be removed. +If this function fails, it returns nil, +plus a string describing the error. + + + + +

+


os.rename (oldname, newname)

+ + +

+Renames file or directory named oldname to newname. +If this function fails, it returns nil, +plus a string describing the error. + + + + +

+


os.setlocale (locale [, category])

+ + +

+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". +The function returns the name of the new locale, +or nil if the request cannot be honored. + + +

+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 nil as the first argument, +this function only returns the name of the current locale +for the given category. + + + + +

+


os.time ([table])

+ + +

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

+The returned value is a number, whose meaning depends on your system. +In POSIX, Windows, and some other systems, this number counts the number +of seconds since some given start time (the "epoch"). +In other systems, the meaning is not specified, +and the number returned by time can be used only as an argument to +date and difftime. + + + + +

+


os.tmpname ()

+ + +

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

+When possible, +you may prefer to use io.tmpfile, +which automatically removes the file when the program ends. + + + + + + + +

5.9 - The Debug Library

+ +

+This library provides +the functionality of the debug interface to Lua programs. +You should exert care when using this library. +The functions provided here should be used exclusively for debugging +and similar tasks, such as profiling. +Please resist the temptation to use them as a +usual programming tool: +they can be very slow. +Moreover, several of these functions +violate some assumptions about Lua code +(e.g., that variables local to a function +cannot be accessed from outside or +that userdata metatables cannot be changed by Lua code) +and therefore can compromise otherwise secure code. + + +

+All functions in this library are provided +inside the debug table. +All functions that operate over a thread +have an optional first argument which is the +thread to operate over. +The default is always the current thread. + + +

+


debug.debug ()

+ + +

+Enters an interactive mode with the user, +running each string that the user enters. +Using simple commands and other debug facilities, +the user can inspect global and local variables, +change their values, evaluate expressions, and so on. +A line containing only the word cont finishes this function, +so that the caller continues its execution. + + +

+Note that commands for debug.debug are not lexically nested +within any function, and so have no direct access to local variables. + + + + +

+


debug.getfenv (o)

+Returns the environment of object o. + + + + +

+


debug.gethook ([thread])

+ + +

+Returns the current hook settings of the thread, as three values: +the current hook function, the current hook mask, +and the current hook count +(as set by the debug.sethook function). + + + + +

+


debug.getinfo ([thread,] function [, what])

+ + +

+Returns a table with information about a function. +You can give the function directly, +or you can give a number as the value of function, +which means the function running at level function of the call stack +of the given thread: +level 0 is the current function (getinfo itself); +level 1 is the function that called getinfo; +and so on. +If function is a number larger than the number of active functions, +then getinfo returns nil. + + +

+The returned table can contain all the fields returned by lua_getinfo, +with the string what describing which fields to fill in. +The default for what is to get all information available, +except the table of valid lines. +If present, +the option 'f' +adds a field named func with the function itself. +If present, +the option 'L' +adds a field named activelines with the table of +valid lines. + + +

+For instance, the expression debug.getinfo(1,"n").name returns +a table with a name for the current function, +if a reasonable name can be found, +and the expression debug.getinfo(print) +returns a table with all available information +about the print function. + + + + +

+


debug.getlocal ([thread,] level, local)

+ + +

+This function returns the name and the value of the local variable +with index local of the function at level level of the stack. +(The first parameter or local variable has index 1, and so on, +until the last active local variable.) +The function returns nil if there is no local +variable with the given index, +and raises an error when called with a level out of range. +(You can call debug.getinfo to check whether the level is valid.) + + +

+Variable names starting with '(' (open parentheses) +represent internal variables +(loop control variables, temporaries, and C function locals). + + + + +

+


debug.getmetatable (object)

+ + +

+Returns the metatable of the given object +or nil if it does not have a metatable. + + + + +

+


debug.getregistry ()

+ + +

+Returns the registry table (see §3.5). + + + + +

+


debug.getupvalue (func, up)

+ + +

+This function returns the name and the value of the upvalue +with index up of the function func. +The function returns nil if there is no upvalue with the given index. + + + + +

+


debug.setfenv (object, table)

+ + +

+Sets the environment of the given object to the given table. +Returns object. + + + + +

+


debug.sethook ([thread,] hook, mask [, count])

+ + +

+Sets the given function as a hook. +The string mask and the number count describe +when the hook will be called. +The string mask may have the following characters, +with the given meaning: + +

    +
  • "c": the hook is called every time Lua calls a function;
  • +
  • "r": the hook is called every time Lua returns from a function;
  • +
  • "l": the hook is called every time Lua enters a new line of code.
  • +

+With a count different from zero, +the hook is called after every count instructions. + + +

+When called without arguments, +debug.sethook turns off the hook. + + +

+When the hook is called, its first parameter is a string +describing the event that has triggered its call: +"call", "return" (or "tail return", +when simulating a return from a tail call), +"line", and "count". +For line events, +the hook also gets the new line number as its second parameter. +Inside a hook, +you can call getinfo with level 2 to get more information about +the running function +(level 0 is the getinfo function, +and level 1 is the hook function), +unless the event is "tail return". +In this case, Lua is only simulating the return, +and a call to getinfo will return invalid data. + + + + +

+


debug.setlocal ([thread,] level, local, value)

+ + +

+This function assigns the value value to the local variable +with index local of the function at level level of the stack. +The function returns nil if there is no local +variable with the given index, +and raises an error when called with a level out of range. +(You can call getinfo to check whether the level is valid.) +Otherwise, it returns the name of the local variable. + + + + +

+


debug.setmetatable (object, table)

+ + +

+Sets the metatable for the given object to the given table +(which can be nil). + + + + +

+


debug.setupvalue (func, up, value)

+ + +

+This function assigns the value value to the upvalue +with index up of the function func. +The function returns nil if there is no upvalue +with the given index. +Otherwise, it returns the name of the upvalue. + + + + +

+


debug.traceback ([thread,] [message] [, level])

+ + +

+Returns a string with a traceback of the call stack. +An optional message string is appended +at the beginning of the traceback. +An optional level number tells at which level +to start the traceback +(default is 1, the function calling traceback). + + + + + + + +

6 - Lua Stand-alone

+ +

+Although Lua has been designed as an extension language, +to be embedded in a host C program, +it is also frequently used as a stand-alone language. +An interpreter for Lua as a stand-alone language, +called simply lua, +is provided with the standard distribution. +The stand-alone interpreter includes +all standard libraries, including the debug library. +Its usage is: + +

+     lua [options] [script [args]]
+

+The options are: + +

    +
  • -e stat: executes string stat;
  • +
  • -l mod: "requires" mod;
  • +
  • -i: enters interactive mode after running script;
  • +
  • -v: prints version information;
  • +
  • --: stops handling options;
  • +
  • -: executes stdin as a file and stops handling options.
  • +

+After handling its options, lua runs the given script, +passing to it the given args as string arguments. +When called without arguments, +lua behaves as lua -v -i +when the standard input (stdin) is a terminal, +and as lua - otherwise. + + +

+Before running any argument, +the interpreter checks for an environment variable LUA_INIT. +If its format is @filename, +then lua executes the file. +Otherwise, lua executes the string itself. + + +

+All options are handled in order, except -i. +For instance, an invocation like + +

+     $ lua -e'a=1' -e 'print(a)' script.lua
+

+will first set a to 1, then print the value of a (which is '1'), +and finally run the file script.lua with no arguments. +(Here $ is the shell prompt. Your prompt may be different.) + + +

+Before starting to run the script, +lua collects all arguments in the command line +in a global table called arg. +The script name is stored at index 0, +the first argument after the script name goes to index 1, +and so on. +Any arguments before the script name +(that is, the interpreter name plus the options) +go to negative indices. +For instance, in the call + +

+     $ lua -la b.lua t1 t2
+

+the interpreter first runs the file a.lua, +then creates a table + +

+     arg = { [-2] = "lua", [-1] = "-la",
+             [0] = "b.lua",
+             [1] = "t1", [2] = "t2" }
+

+and finally runs the file b.lua. +The script is called with arg[1], arg[2], ··· +as arguments; +it can also access these arguments with the vararg expression '...'. + + +

+In interactive mode, +if you write an incomplete statement, +the interpreter waits for its completion +by issuing a different prompt. + + +

+If the global variable _PROMPT contains a string, +then its value is used as the prompt. +Similarly, if the global variable _PROMPT2 contains a string, +its value is used as the secondary prompt +(issued during incomplete statements). +Therefore, both prompts can be changed directly on the command line +or in any Lua programs by assigning to _PROMPT. +See the next example: + +

+     $ lua -e"_PROMPT='myprompt> '" -i
+

+(The outer pair of quotes is for the shell, +the inner pair is for Lua.) +Note the use of -i to enter interactive mode; +otherwise, +the program would just end silently +right after the assignment to _PROMPT. + + +

+To allow the use of Lua as a +script interpreter in Unix systems, +the stand-alone interpreter skips +the first line of a chunk if it starts with #. +Therefore, Lua scripts can be made into executable programs +by using chmod +x and the #! form, +as in + +

+     #!/usr/local/bin/lua
+

+(Of course, +the location of the Lua interpreter may be different in your machine. +If lua is in your PATH, +then + +

+     #!/usr/bin/env lua
+

+is a more portable solution.) + + + +

7 - Incompatibilities with the Previous Version

+ +

+Here we list the incompatibilities that you may find when moving a program +from Lua 5.0 to Lua 5.1. +You can avoid most of the incompatibilities compiling Lua with +appropriate options (see file luaconf.h). +However, +all these compatibility options will be removed in the next version of Lua. + + + +

7.1 - Changes in the Language

+
    + +
  • +The vararg system changed from the pseudo-argument arg with a +table with the extra arguments to the vararg expression. +(See compile-time option LUA_COMPAT_VARARG in luaconf.h.) +
  • + +
  • +There was a subtle change in the scope of the implicit +variables of the for statement and for the repeat statement. +
  • + +
  • +The long string/long comment syntax ([[string]]) +does not allow nesting. +You can use the new syntax ([=[string]=]) in these cases. +(See compile-time option LUA_COMPAT_LSTR in luaconf.h.) +
  • + +
+ + + + +

7.2 - Changes in the Libraries

+
    + +
  • +Function string.gfind was renamed string.gmatch. +(See compile-time option LUA_COMPAT_GFIND in luaconf.h.) +
  • + +
  • +When string.gsub is called with a function as its +third argument, +whenever this function returns nil or false the +replacement string is the whole match, +instead of the empty string. +
  • + +
  • +Function table.setn was deprecated. +Function table.getn corresponds +to the new length operator (#); +use the operator instead of the function. +(See compile-time option LUA_COMPAT_GETN in luaconf.h.) +
  • + +
  • +Function loadlib was renamed package.loadlib. +(See compile-time option LUA_COMPAT_LOADLIB in luaconf.h.) +
  • + +
  • +Function math.mod was renamed math.fmod. +(See compile-time option LUA_COMPAT_MOD in luaconf.h.) +
  • + +
  • +Functions table.foreach and table.foreachi are deprecated. +You can use a for loop with pairs or ipairs instead. +
  • + +
  • +There were substantial changes in function require due to +the new module system. +However, the new behavior is mostly compatible with the old, +but require gets the path from package.path instead +of from LUA_PATH. +
  • + +
  • +Function collectgarbage has different arguments. +Function gcinfo is deprecated; +use collectgarbage("count") instead. +
  • + +
+ + + + +

7.3 - Changes in the API

+
    + +
  • +The luaopen_* functions (to open libraries) +cannot be called directly, +like a regular C function. +They must be called through Lua, +like a Lua function. +
  • + +
  • +Function lua_open was replaced by lua_newstate to +allow the user to set a memory-allocation function. +You can use luaL_newstate from the standard library to +create a state with a standard allocation function +(based on realloc). +
  • + +
  • +Functions luaL_getn and luaL_setn +(from the auxiliary library) are deprecated. +Use lua_objlen instead of luaL_getn +and nothing instead of luaL_setn. +
  • + +
  • +Function luaL_openlib was replaced by luaL_register. +
  • + +
  • +Function luaL_checkudata now throws an error when the given value +is not a userdata of the expected type. +(In Lua 5.0 it returned NULL.) +
  • + +
+ + + + +

8 - The Complete Syntax of Lua

+ +

+Here is the complete syntax of Lua in extended BNF. +(It does not describe operator precedences.) + + + + +

+
+	chunk ::= {stat [`;´]} [laststat [`;´]]
+
+	block ::= chunk
+
+	stat ::=  varlist `=´ explist | 
+		 functioncall | 
+		 do block end | 
+		 while exp do block end | 
+		 repeat block until exp | 
+		 if exp then block {elseif exp then block} [else block] end | 
+		 for Name `=´ exp `,´ exp [`,´ exp] do block end | 
+		 for namelist in explist do block end | 
+		 function funcname funcbody | 
+		 local function Name funcbody | 
+		 local namelist [`=´ explist] 
+
+	laststat ::= return [explist] | break
+
+	funcname ::= Name {`.´ Name} [`:´ Name]
+
+	varlist ::= var {`,´ var}
+
+	var ::=  Name | prefixexp `[´ exp `]´ | prefixexp `.´ Name 
+
+	namelist ::= Name {`,´ Name}
+
+	explist ::= {exp `,´} exp
+
+	exp ::=  nil | false | true | Number | String | `...´ | function | 
+		 prefixexp | tableconstructor | exp binop exp | unop exp 
+
+	prefixexp ::= var | functioncall | `(´ exp `)´
+
+	functioncall ::=  prefixexp args | prefixexp `:´ Name args 
+
+	args ::=  `(´ [explist] `)´ | tableconstructor | String 
+
+	function ::= function funcbody
+
+	funcbody ::= `(´ [parlist] `)´ block end
+
+	parlist ::= namelist [`,´ `...´] | `...´
+
+	tableconstructor ::= `{´ [fieldlist] `}´
+
+	fieldlist ::= field {fieldsep field} [fieldsep]
+
+	field ::= `[´ exp `]´ `=´ exp | Name `=´ exp | exp
+
+	fieldsep ::= `,´ | `;´
+
+	binop ::= `+´ | `-´ | `*´ | `/´ | `^´ | `%´ | `..´ | 
+		 `<´ | `<=´ | `>´ | `>=´ | `==´ | `~=´ | 
+		 and | or
+
+	unop ::= `-´ | not | `#´
+
+
+ +

+ + + + + + + +


+ +Last update: +Mon Aug 18 13:25:46 BRT 2008 + + + + + diff --git a/vscript/languages/lua/lua-5.1.4/doc/readme.html b/vscript/languages/lua/lua-5.1.4/doc/readme.html new file mode 100644 index 00000000..38be6dbb --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/doc/readme.html @@ -0,0 +1,40 @@ + + +Lua documentation + + + + + +
+

+Lua +Documentation +

+ +This is the documentation included in the source distribution of Lua 5.1.4. + + + +Lua's +official web site +contains updated documentation, +especially the +reference manual. +

+ +


+ +Last update: +Tue Aug 12 14:46:07 BRT 2008 + + + + diff --git a/vscript/languages/lua/lua-5.1.4/etc/Makefile b/vscript/languages/lua/lua-5.1.4/etc/Makefile new file mode 100644 index 00000000..6d00008d --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/etc/Makefile @@ -0,0 +1,44 @@ +# makefile for Lua etc + +TOP= .. +LIB= $(TOP)/src +INC= $(TOP)/src +BIN= $(TOP)/src +SRC= $(TOP)/src +TST= $(TOP)/test + +CC= gcc +CFLAGS= -O2 -Wall -I$(INC) $(MYCFLAGS) +MYCFLAGS= +MYLDFLAGS= -Wl,-E +MYLIBS= -lm +#MYLIBS= -lm -Wl,-E -ldl -lreadline -lhistory -lncurses +RM= rm -f + +default: + @echo 'Please choose a target: min noparser one strict clean' + +min: min.c + $(CC) $(CFLAGS) $@.c -L$(LIB) -llua $(MYLIBS) + echo 'print"Hello there!"' | ./a.out + +noparser: noparser.o + $(CC) noparser.o $(SRC)/lua.o -L$(LIB) -llua $(MYLIBS) + $(BIN)/luac $(TST)/hello.lua + -./a.out luac.out + -./a.out -e'a=1' + +one: + $(CC) $(CFLAGS) all.c $(MYLIBS) + ./a.out $(TST)/hello.lua + +strict: + -$(BIN)/lua -e 'print(a);b=2' + -$(BIN)/lua -lstrict -e 'print(a)' + -$(BIN)/lua -e 'function f() b=2 end f()' + -$(BIN)/lua -lstrict -e 'function f() b=2 end f()' + +clean: + $(RM) a.out core core.* *.o luac.out + +.PHONY: default min noparser one strict clean diff --git a/vscript/languages/lua/lua-5.1.4/etc/README b/vscript/languages/lua/lua-5.1.4/etc/README new file mode 100644 index 00000000..5149fc91 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/etc/README @@ -0,0 +1,37 @@ +This directory contains some useful files and code. +Unlike the code in ../src, everything here is in the public domain. + +If any of the makes fail, you're probably not using the same libraries +used to build Lua. Set MYLIBS in Makefile accordingly. + +all.c + Full Lua interpreter in a single file. + Do "make one" for a demo. + +lua.hpp + Lua header files for C++ using 'extern "C"'. + +lua.ico + A Lua icon for Windows (and web sites: save as favicon.ico). + Drawn by hand by Markus Gritsch . + +lua.pc + pkg-config data for Lua + +luavs.bat + Script to build Lua under "Visual Studio .NET Command Prompt". + Run it from the toplevel as etc\luavs.bat. + +min.c + A minimal Lua interpreter. + Good for learning and for starting your own. + Do "make min" for a demo. + +noparser.c + Linking with noparser.o avoids loading the parsing modules in lualib.a. + Do "make noparser" for a demo. + +strict.lua + Traps uses of undeclared global variables. + Do "make strict" for a demo. + diff --git a/vscript/languages/lua/lua-5.1.4/etc/all.c b/vscript/languages/lua/lua-5.1.4/etc/all.c new file mode 100644 index 00000000..dab68fac --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/etc/all.c @@ -0,0 +1,38 @@ +/* +* all.c -- Lua core, libraries and interpreter in a single file +*/ + +#define luaall_c + +#include "lapi.c" +#include "lcode.c" +#include "ldebug.c" +#include "ldo.c" +#include "ldump.c" +#include "lfunc.c" +#include "lgc.c" +#include "llex.c" +#include "lmem.c" +#include "lobject.c" +#include "lopcodes.c" +#include "lparser.c" +#include "lstate.c" +#include "lstring.c" +#include "ltable.c" +#include "ltm.c" +#include "lundump.c" +#include "lvm.c" +#include "lzio.c" + +#include "lauxlib.c" +#include "lbaselib.c" +#include "ldblib.c" +#include "liolib.c" +#include "linit.c" +#include "lmathlib.c" +#include "loadlib.c" +#include "loslib.c" +#include "lstrlib.c" +#include "ltablib.c" + +#include "lua.c" diff --git a/vscript/languages/lua/lua-5.1.4/etc/lua.hpp b/vscript/languages/lua/lua-5.1.4/etc/lua.hpp new file mode 100644 index 00000000..ec417f59 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/etc/lua.hpp @@ -0,0 +1,9 @@ +// lua.hpp +// Lua header files for C++ +// <> not supplied automatically because Lua also compiles as C++ + +extern "C" { +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" +} diff --git a/vscript/languages/lua/lua-5.1.4/etc/lua.ico b/vscript/languages/lua/lua-5.1.4/etc/lua.ico new file mode 100644 index 0000000000000000000000000000000000000000..ccbabc4e2004683f29598a991006d7caff6d837d GIT binary patch literal 1078 zcma)5y>7xl4E|D3VJbX9VX7GW1~6FSw!BIQq_T0tNo32b^bxZ4H5fZGR7xh?&v!Y3 zDh3=J`#b+#Yy%W{!g4u>(a#g`Mme7+yefc~5wPOflDr`o81qe{?|t$BfABsDzNw;V z8cH*0{6W<;G9Np#7ik(qoR4aR5-A@{5)}DJ9&}FRBA#X_5+im4-kQSzMF^)-t2(Vi ztw-^|Sn8@O_lM9`oos+0wMZGt&`Bq(aK&XCv1Gfr&Jtd6%lKPdD{s=unqGWyb3%y{X9SS{jB~HMh0oKMISQrDC zJ;K?)>ElnpmN^UNE-rXxtyk{c#rCe~`P=qnFT7 bCxwx*w%~s~=?o*z_6Fk4@7l(poWF`cPpA(! literal 0 HcmV?d00001 diff --git a/vscript/languages/lua/lua-5.1.4/etc/lua.pc b/vscript/languages/lua/lua-5.1.4/etc/lua.pc new file mode 100644 index 00000000..f52f55b0 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/etc/lua.pc @@ -0,0 +1,31 @@ +# lua.pc -- pkg-config data for Lua + +# vars from install Makefile + +# grep '^V=' ../Makefile +V= 5.1 +# grep '^R=' ../Makefile +R= 5.1.4 + +# grep '^INSTALL_.*=' ../Makefile | sed 's/INSTALL_TOP/prefix/' +prefix= /usr/local +INSTALL_BIN= ${prefix}/bin +INSTALL_INC= ${prefix}/include +INSTALL_LIB= ${prefix}/lib +INSTALL_MAN= ${prefix}/man/man1 +INSTALL_LMOD= ${prefix}/share/lua/${V} +INSTALL_CMOD= ${prefix}/lib/lua/${V} + +# canonical vars +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: Lua +Description: An Extensible Extension Language +Version: ${R} +Requires: +Libs: -L${libdir} -llua -lm +Cflags: -I${includedir} + +# (end of lua.pc) diff --git a/vscript/languages/lua/lua-5.1.4/etc/luavs.bat b/vscript/languages/lua/lua-5.1.4/etc/luavs.bat new file mode 100644 index 00000000..054b4625 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/etc/luavs.bat @@ -0,0 +1,28 @@ +@rem Script to build Lua under "Visual Studio .NET Command Prompt". +@rem Do not run from this directory; run it from the toplevel: etc\luavs.bat . +@rem It creates lua51.dll, lua51.lib, lua.exe, and luac.exe in src. +@rem (contributed by David Manura and Mike Pall) + +@setlocal +@set MYCOMPILE=cl /nologo /MD /O2 /W3 /c /D_CRT_SECURE_NO_DEPRECATE +@set MYLINK=link /nologo +@set MYMT=mt /nologo + +cd src +%MYCOMPILE% /DLUA_BUILD_AS_DLL l*.c +del lua.obj luac.obj +%MYLINK% /DLL /out:lua51.dll l*.obj +if exist lua51.dll.manifest^ + %MYMT% -manifest lua51.dll.manifest -outputresource:lua51.dll;2 +%MYCOMPILE% /DLUA_BUILD_AS_DLL lua.c +%MYLINK% /out:lua.exe lua.obj lua51.lib +if exist lua.exe.manifest^ + %MYMT% -manifest lua.exe.manifest -outputresource:lua.exe +%MYCOMPILE% l*.c print.c +del lua.obj linit.obj lbaselib.obj ldblib.obj liolib.obj lmathlib.obj^ + loslib.obj ltablib.obj lstrlib.obj loadlib.obj +%MYLINK% /out:luac.exe *.obj +if exist luac.exe.manifest^ + %MYMT% -manifest luac.exe.manifest -outputresource:luac.exe +del *.obj *.manifest +cd .. diff --git a/vscript/languages/lua/lua-5.1.4/etc/min.c b/vscript/languages/lua/lua-5.1.4/etc/min.c new file mode 100644 index 00000000..6a85a4d1 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/etc/min.c @@ -0,0 +1,39 @@ +/* +* min.c -- a minimal Lua interpreter +* loads stdin only with minimal error handling. +* no interaction, and no standard library, only a "print" function. +*/ + +#include + +#include "lua.h" +#include "lauxlib.h" + +static int print(lua_State *L) +{ + int n=lua_gettop(L); + int i; + for (i=1; i<=n; i++) + { + if (i>1) printf("\t"); + if (lua_isstring(L,i)) + printf("%s",lua_tostring(L,i)); + else if (lua_isnil(L,i)) + printf("%s","nil"); + else if (lua_isboolean(L,i)) + printf("%s",lua_toboolean(L,i) ? "true" : "false"); + else + printf("%s:%p",luaL_typename(L,i),lua_topointer(L,i)); + } + printf("\n"); + return 0; +} + +int main(void) +{ + lua_State *L=lua_open(); + lua_register(L,"print",print); + if (luaL_dofile(L,NULL)!=0) fprintf(stderr,"%s\n",lua_tostring(L,-1)); + lua_close(L); + return 0; +} diff --git a/vscript/languages/lua/lua-5.1.4/etc/noparser.c b/vscript/languages/lua/lua-5.1.4/etc/noparser.c new file mode 100644 index 00000000..13ba5462 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/etc/noparser.c @@ -0,0 +1,50 @@ +/* +* The code below can be used to make a Lua core that does not contain the +* parsing modules (lcode, llex, lparser), which represent 35% of the total core. +* You'll only be able to load binary files and strings, precompiled with luac. +* (Of course, you'll have to build luac with the original parsing modules!) +* +* To use this module, simply compile it ("make noparser" does that) and list +* its object file before the Lua libraries. The linker should then not load +* the parsing modules. To try it, do "make luab". +* +* If you also want to avoid the dump module (ldump.o), define NODUMP. +* #define NODUMP +*/ + +#define LUA_CORE + +#include "llex.h" +#include "lparser.h" +#include "lzio.h" + +LUAI_FUNC void luaX_init (lua_State *L) { + UNUSED(L); +} + +LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { + UNUSED(z); + UNUSED(buff); + UNUSED(name); + lua_pushliteral(L,"parser not loaded"); + lua_error(L); + return NULL; +} + +#ifdef NODUMP +#include "lundump.h" + +LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) { + UNUSED(f); + UNUSED(w); + UNUSED(data); + UNUSED(strip); +#if 1 + UNUSED(L); + return 0; +#else + lua_pushliteral(L,"dumper not loaded"); + lua_error(L); +#endif +} +#endif diff --git a/vscript/languages/lua/lua-5.1.4/etc/strict.lua b/vscript/languages/lua/lua-5.1.4/etc/strict.lua new file mode 100644 index 00000000..604619dd --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/etc/strict.lua @@ -0,0 +1,41 @@ +-- +-- strict.lua +-- checks uses of undeclared global variables +-- All global variables must be 'declared' through a regular assignment +-- (even assigning nil will do) in a main chunk before being used +-- anywhere or assigned to inside a function. +-- + +local getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget + +local mt = getmetatable(_G) +if mt == nil then + mt = {} + setmetatable(_G, mt) +end + +mt.__declared = {} + +local function what () + local d = getinfo(3, "S") + return d and d.what or "C" +end + +mt.__newindex = function (t, n, v) + if not mt.__declared[n] then + local w = what() + if w ~= "main" and w ~= "C" then + error("assign to undeclared variable '"..n.."'", 2) + end + mt.__declared[n] = true + end + rawset(t, n, v) +end + +mt.__index = function (t, n) + if not mt.__declared[n] and what() ~= "C" then + error("variable '"..n.."' is not declared", 2) + end + return rawget(t, n) +end + diff --git a/vscript/languages/lua/lua-5.1.4/src/Makefile b/vscript/languages/lua/lua-5.1.4/src/Makefile new file mode 100644 index 00000000..e4a3cd61 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/Makefile @@ -0,0 +1,182 @@ +# makefile for building Lua +# see ../INSTALL for installation instructions +# see ../Makefile and luaconf.h for further customization + +# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= + +# Your platform. See PLATS for possible values. +PLAT= none + +CC= gcc +CFLAGS= -O2 -Wall $(MYCFLAGS) +AR= ar rcu +RANLIB= ranlib +RM= rm -f +LIBS= -lm $(MYLIBS) + +MYCFLAGS= +MYLDFLAGS= +MYLIBS= + +# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE ========= + +PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris + +LUA_A= liblua.a +CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \ + lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \ + lundump.o lvm.o lzio.o +LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \ + lstrlib.o loadlib.o linit.o + +LUA_T= lua +LUA_O= lua.o + +LUAC_T= luac +LUAC_O= luac.o print.o + +ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O) +ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) +ALL_A= $(LUA_A) + +default: $(PLAT) + +all: $(ALL_T) + +o: $(ALL_O) + +a: $(ALL_A) + +$(LUA_A): $(CORE_O) $(LIB_O) + $(AR) $@ $? + $(RANLIB) $@ + +$(LUA_T): $(LUA_O) $(LUA_A) + $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) + +$(LUAC_T): $(LUAC_O) $(LUA_A) + $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) + +clean: + $(RM) $(ALL_T) $(ALL_O) + +depend: + @$(CC) $(CFLAGS) -MM l*.c print.c + +echo: + @echo "PLAT = $(PLAT)" + @echo "CC = $(CC)" + @echo "CFLAGS = $(CFLAGS)" + @echo "AR = $(AR)" + @echo "RANLIB = $(RANLIB)" + @echo "RM = $(RM)" + @echo "MYCFLAGS = $(MYCFLAGS)" + @echo "MYLDFLAGS = $(MYLDFLAGS)" + @echo "MYLIBS = $(MYLIBS)" + +# convenience targets for popular platforms + +none: + @echo "Please choose a platform:" + @echo " $(PLATS)" + +aix: + $(MAKE) all CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" MYLDFLAGS="-brtl -bexpall" + +ansi: + $(MAKE) all MYCFLAGS=-DLUA_ANSI + +bsd: + $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E" + +freebsd: + $(MAKE) all MYCFLAGS="-DLUA_USE_LINUX" MYLIBS="-Wl,-E -lreadline" + +generic: + $(MAKE) all MYCFLAGS= + +linux: + $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses" + +macosx: + $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-lreadline" +# use this on Mac OS X 10.3- +# $(MAKE) all MYCFLAGS=-DLUA_USE_MACOSX + +mingw: + $(MAKE) "LUA_A=lua51.dll" "LUA_T=lua.exe" \ + "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ + "MYCFLAGS=-DLUA_BUILD_AS_DLL" "MYLIBS=" "MYLDFLAGS=-s" lua.exe + $(MAKE) "LUAC_T=luac.exe" luac.exe + +posix: + $(MAKE) all MYCFLAGS=-DLUA_USE_POSIX + +solaris: + $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" + +# list targets that do not create files (but not all makes understand .PHONY) +.PHONY: all $(PLATS) default o a clean depend echo none + +# DO NOT DELETE + +lapi.o: lapi.c lua.h luaconf.h lapi.h lobject.h llimits.h ldebug.h \ + lstate.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h \ + lundump.h lvm.h +lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h +lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h +lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ + lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \ + ltable.h +ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h +ldebug.o: ldebug.c lua.h luaconf.h lapi.h lobject.h llimits.h lcode.h \ + llex.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h \ + lfunc.h lstring.h lgc.h ltable.h lvm.h +ldo.o: ldo.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ + lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h lstring.h \ + ltable.h lundump.h lvm.h +ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ + lzio.h lmem.h lundump.h +lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h lmem.h \ + lstate.h ltm.h lzio.h +lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ + lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h +linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h +liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h +llex.o: llex.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h ltm.h \ + lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h +lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h +lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ + ltm.h lzio.h lmem.h ldo.h +loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h +lobject.o: lobject.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h \ + ltm.h lzio.h lmem.h lstring.h lgc.h lvm.h +lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h +loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h +lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ + lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h \ + lfunc.h lstring.h lgc.h ltable.h +lstate.o: lstate.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ + ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h llex.h lstring.h ltable.h +lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \ + ltm.h lzio.h lstring.h lgc.h +lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h +ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ + ltm.h lzio.h lmem.h ldo.h lgc.h ltable.h +ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h +ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ + lmem.h lstring.h lgc.h ltable.h +lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h +luac.o: luac.c lua.h luaconf.h lauxlib.h ldo.h lobject.h llimits.h \ + lstate.h ltm.h lzio.h lmem.h lfunc.h lopcodes.h lstring.h lgc.h \ + lundump.h +lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \ + llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h +lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ + lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h +lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \ + lzio.h +print.o: print.c ldebug.h lstate.h lua.h luaconf.h lobject.h llimits.h \ + ltm.h lzio.h lmem.h lopcodes.h lundump.h + +# (end of Makefile) diff --git a/vscript/languages/lua/lua-5.1.4/src/lapi.c b/vscript/languages/lua/lua-5.1.4/src/lapi.c new file mode 100644 index 00000000..5d5145d2 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lapi.c @@ -0,0 +1,1087 @@ +/* +** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $ +** Lua API +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include + +#define lapi_c +#define LUA_CORE + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" + + + +const char lua_ident[] = + "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n" + "$Authors: " LUA_AUTHORS " $\n" + "$URL: www.lua.org $\n"; + + + +#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) + +#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject) + +#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;} + + + +static TValue *index2adr (lua_State *L, int idx) { + if (idx > 0) { + TValue *o = L->base + (idx - 1); + api_check(L, idx <= L->ci->top - L->base); + if (o >= L->top) return cast(TValue *, luaO_nilobject); + else return o; + } + else if (idx > LUA_REGISTRYINDEX) { + api_check(L, idx != 0 && -idx <= L->top - L->base); + return L->top + idx; + } + else switch (idx) { /* pseudo-indices */ + case LUA_REGISTRYINDEX: return registry(L); + case LUA_ENVIRONINDEX: { + Closure *func = curr_func(L); + sethvalue(L, &L->env, func->c.env); + return &L->env; + } + case LUA_GLOBALSINDEX: return gt(L); + default: { + Closure *func = curr_func(L); + idx = LUA_GLOBALSINDEX - idx; + return (idx <= func->c.nupvalues) + ? &func->c.upvalue[idx-1] + : cast(TValue *, luaO_nilobject); + } + } +} + + +static Table *getcurrenv (lua_State *L) { + if (L->ci == L->base_ci) /* no enclosing function? */ + return hvalue(gt(L)); /* use global table as environment */ + else { + Closure *func = curr_func(L); + return func->c.env; + } +} + + +void luaA_pushobject (lua_State *L, const TValue *o) { + setobj2s(L, L->top, o); + api_incr_top(L); +} + + +LUA_API int lua_checkstack (lua_State *L, int size) { + int res = 1; + lua_lock(L); + if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) + res = 0; /* stack overflow */ + else if (size > 0) { + luaD_checkstack(L, size); + if (L->ci->top < L->top + size) + L->ci->top = L->top + size; + } + lua_unlock(L); + return res; +} + + +LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { + int i; + if (from == to) return; + lua_lock(to); + api_checknelems(from, n); + api_check(from, G(from) == G(to)); + api_check(from, to->ci->top - to->top >= n); + from->top -= n; + for (i = 0; i < n; i++) { + setobj2s(to, to->top++, from->top + i); + } + lua_unlock(to); +} + + +LUA_API void lua_setlevel (lua_State *from, lua_State *to) { + to->nCcalls = from->nCcalls; +} + + +LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { + lua_CFunction old; + lua_lock(L); + old = G(L)->panic; + G(L)->panic = panicf; + lua_unlock(L); + return old; +} + + +LUA_API lua_State *lua_newthread (lua_State *L) { + lua_State *L1; + lua_lock(L); + luaC_checkGC(L); + L1 = luaE_newthread(L); + setthvalue(L, L->top, L1); + api_incr_top(L); + lua_unlock(L); + luai_userstatethread(L, L1); + return L1; +} + + + +/* +** basic stack manipulation +*/ + + +LUA_API int lua_gettop (lua_State *L) { + return cast_int(L->top - L->base); +} + + +LUA_API void lua_settop (lua_State *L, int idx) { + lua_lock(L); + if (idx >= 0) { + api_check(L, idx <= L->stack_last - L->base); + while (L->top < L->base + idx) + setnilvalue(L->top++); + L->top = L->base + idx; + } + else { + api_check(L, -(idx+1) <= (L->top - L->base)); + L->top += idx+1; /* `subtract' index (index is negative) */ + } + lua_unlock(L); +} + + +LUA_API void lua_remove (lua_State *L, int idx) { + StkId p; + lua_lock(L); + p = index2adr(L, idx); + api_checkvalidindex(L, p); + while (++p < L->top) setobjs2s(L, p-1, p); + L->top--; + lua_unlock(L); +} + + +LUA_API void lua_insert (lua_State *L, int idx) { + StkId p; + StkId q; + lua_lock(L); + p = index2adr(L, idx); + api_checkvalidindex(L, p); + for (q = L->top; q>p; q--) setobjs2s(L, q, q-1); + setobjs2s(L, p, L->top); + lua_unlock(L); +} + + +LUA_API void lua_replace (lua_State *L, int idx) { + StkId o; + lua_lock(L); + /* explicit test for incompatible code */ + if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci) + luaG_runerror(L, "no calling environment"); + api_checknelems(L, 1); + o = index2adr(L, idx); + api_checkvalidindex(L, o); + if (idx == LUA_ENVIRONINDEX) { + Closure *func = curr_func(L); + api_check(L, ttistable(L->top - 1)); + func->c.env = hvalue(L->top - 1); + luaC_barrier(L, func, L->top - 1); + } + else { + setobj(L, o, L->top - 1); + if (idx < LUA_GLOBALSINDEX) /* function upvalue? */ + luaC_barrier(L, curr_func(L), L->top - 1); + } + L->top--; + lua_unlock(L); +} + + +LUA_API void lua_pushvalue (lua_State *L, int idx) { + lua_lock(L); + setobj2s(L, L->top, index2adr(L, idx)); + api_incr_top(L); + lua_unlock(L); +} + + + +/* +** access functions (stack -> C) +*/ + + +LUA_API int lua_type (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + return (o == luaO_nilobject) ? LUA_TNONE : ttype(o); +} + + +LUA_API const char *lua_typename (lua_State *L, int t) { + UNUSED(L); + return (t == LUA_TNONE) ? "no value" : luaT_typenames[t]; +} + + +LUA_API int lua_iscfunction (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + return iscfunction(o); +} + + +LUA_API int lua_isnumber (lua_State *L, int idx) { + TValue n; + const TValue *o = index2adr(L, idx); + return tonumber(o, &n); +} + + +LUA_API int lua_isstring (lua_State *L, int idx) { + int t = lua_type(L, idx); + return (t == LUA_TSTRING || t == LUA_TNUMBER); +} + + +LUA_API int lua_isuserdata (lua_State *L, int idx) { + const TValue *o = index2adr(L, idx); + return (ttisuserdata(o) || ttislightuserdata(o)); +} + + +LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { + StkId o1 = index2adr(L, index1); + StkId o2 = index2adr(L, index2); + return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 + : luaO_rawequalObj(o1, o2); +} + + +LUA_API int lua_equal (lua_State *L, int index1, int index2) { + StkId o1, o2; + int i; + lua_lock(L); /* may call tag method */ + o1 = index2adr(L, index1); + o2 = index2adr(L, index2); + i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2); + lua_unlock(L); + return i; +} + + +LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { + StkId o1, o2; + int i; + lua_lock(L); /* may call tag method */ + o1 = index2adr(L, index1); + o2 = index2adr(L, index2); + i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 + : luaV_lessthan(L, o1, o2); + lua_unlock(L); + return i; +} + + + +LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { + TValue n; + const TValue *o = index2adr(L, idx); + if (tonumber(o, &n)) + return nvalue(o); + else + return 0; +} + + +LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) { + TValue n; + const TValue *o = index2adr(L, idx); + if (tonumber(o, &n)) { + lua_Integer res; + lua_Number num = nvalue(o); + lua_number2integer(res, num); + return res; + } + else + return 0; +} + + +LUA_API int lua_toboolean (lua_State *L, int idx) { + const TValue *o = index2adr(L, idx); + return !l_isfalse(o); +} + + +LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { + StkId o = index2adr(L, idx); + if (!ttisstring(o)) { + lua_lock(L); /* `luaV_tostring' may create a new string */ + if (!luaV_tostring(L, o)) { /* conversion failed? */ + if (len != NULL) *len = 0; + lua_unlock(L); + return NULL; + } + luaC_checkGC(L); + o = index2adr(L, idx); /* previous call may reallocate the stack */ + lua_unlock(L); + } + if (len != NULL) *len = tsvalue(o)->len; + return svalue(o); +} + + +LUA_API size_t lua_objlen (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + switch (ttype(o)) { + case LUA_TSTRING: return tsvalue(o)->len; + case LUA_TUSERDATA: return uvalue(o)->len; + case LUA_TTABLE: return luaH_getn(hvalue(o)); + case LUA_TNUMBER: { + size_t l; + lua_lock(L); /* `luaV_tostring' may create a new string */ + l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0); + lua_unlock(L); + return l; + } + default: return 0; + } +} + + +LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + return (!iscfunction(o)) ? NULL : clvalue(o)->c.f; +} + + +LUA_API void *lua_touserdata (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + switch (ttype(o)) { + case LUA_TUSERDATA: return (rawuvalue(o) + 1); + case LUA_TLIGHTUSERDATA: return pvalue(o); + default: return NULL; + } +} + + +LUA_API lua_State *lua_tothread (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + return (!ttisthread(o)) ? NULL : thvalue(o); +} + + +LUA_API const void *lua_topointer (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + switch (ttype(o)) { + case LUA_TTABLE: return hvalue(o); + case LUA_TFUNCTION: return clvalue(o); + case LUA_TTHREAD: return thvalue(o); + case LUA_TUSERDATA: + case LUA_TLIGHTUSERDATA: + return lua_touserdata(L, idx); + default: return NULL; + } +} + + + +/* +** push functions (C -> stack) +*/ + + +LUA_API void lua_pushnil (lua_State *L) { + lua_lock(L); + setnilvalue(L->top); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { + lua_lock(L); + setnvalue(L->top, n); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { + lua_lock(L); + setnvalue(L->top, cast_num(n)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { + lua_lock(L); + luaC_checkGC(L); + setsvalue2s(L, L->top, luaS_newlstr(L, s, len)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushstring (lua_State *L, const char *s) { + if (s == NULL) + lua_pushnil(L); + else + lua_pushlstring(L, s, strlen(s)); +} + + +LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, + va_list argp) { + const char *ret; + lua_lock(L); + luaC_checkGC(L); + ret = luaO_pushvfstring(L, fmt, argp); + lua_unlock(L); + return ret; +} + + +LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { + const char *ret; + va_list argp; + lua_lock(L); + luaC_checkGC(L); + va_start(argp, fmt); + ret = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + lua_unlock(L); + return ret; +} + + +LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { + Closure *cl; + lua_lock(L); + luaC_checkGC(L); + api_checknelems(L, n); + cl = luaF_newCclosure(L, n, getcurrenv(L)); + cl->c.f = fn; + L->top -= n; + while (n--) + setobj2n(L, &cl->c.upvalue[n], L->top+n); + setclvalue(L, L->top, cl); + lua_assert(iswhite(obj2gco(cl))); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushboolean (lua_State *L, int b) { + lua_lock(L); + setbvalue(L->top, (b != 0)); /* ensure that true is 1 */ + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { + lua_lock(L); + setpvalue(L->top, p); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API int lua_pushthread (lua_State *L) { + lua_lock(L); + setthvalue(L, L->top, L); + api_incr_top(L); + lua_unlock(L); + return (G(L)->mainthread == L); +} + + + +/* +** get functions (Lua -> stack) +*/ + + +LUA_API void lua_gettable (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + luaV_gettable(L, t, L->top - 1, L->top - 1); + lua_unlock(L); +} + + +LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { + StkId t; + TValue key; + lua_lock(L); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + setsvalue(L, &key, luaS_new(L, k)); + luaV_gettable(L, t, &key, L->top); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_rawget (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = index2adr(L, idx); + api_check(L, ttistable(t)); + setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); + lua_unlock(L); +} + + +LUA_API void lua_rawgeti (lua_State *L, int idx, int n) { + StkId o; + lua_lock(L); + o = index2adr(L, idx); + api_check(L, ttistable(o)); + setobj2s(L, L->top, luaH_getnum(hvalue(o), n)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { + lua_lock(L); + luaC_checkGC(L); + sethvalue(L, L->top, luaH_new(L, narray, nrec)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API int lua_getmetatable (lua_State *L, int objindex) { + const TValue *obj; + Table *mt = NULL; + int res; + lua_lock(L); + obj = index2adr(L, objindex); + switch (ttype(obj)) { + case LUA_TTABLE: + mt = hvalue(obj)->metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(obj)->metatable; + break; + default: + mt = G(L)->mt[ttype(obj)]; + break; + } + if (mt == NULL) + res = 0; + else { + sethvalue(L, L->top, mt); + api_incr_top(L); + res = 1; + } + lua_unlock(L); + return res; +} + + +LUA_API void lua_getfenv (lua_State *L, int idx) { + StkId o; + lua_lock(L); + o = index2adr(L, idx); + api_checkvalidindex(L, o); + switch (ttype(o)) { + case LUA_TFUNCTION: + sethvalue(L, L->top, clvalue(o)->c.env); + break; + case LUA_TUSERDATA: + sethvalue(L, L->top, uvalue(o)->env); + break; + case LUA_TTHREAD: + setobj2s(L, L->top, gt(thvalue(o))); + break; + default: + setnilvalue(L->top); + break; + } + api_incr_top(L); + lua_unlock(L); +} + + +/* +** set functions (stack -> Lua) +*/ + + +LUA_API void lua_settable (lua_State *L, int idx) { + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + luaV_settable(L, t, L->top - 2, L->top - 1); + L->top -= 2; /* pop index and value */ + lua_unlock(L); +} + + +LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { + StkId t; + TValue key; + lua_lock(L); + api_checknelems(L, 1); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + setsvalue(L, &key, luaS_new(L, k)); + luaV_settable(L, t, &key, L->top - 1); + L->top--; /* pop value */ + lua_unlock(L); +} + + +LUA_API void lua_rawset (lua_State *L, int idx) { + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = index2adr(L, idx); + api_check(L, ttistable(t)); + setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); + luaC_barriert(L, hvalue(t), L->top-1); + L->top -= 2; + lua_unlock(L); +} + + +LUA_API void lua_rawseti (lua_State *L, int idx, int n) { + StkId o; + lua_lock(L); + api_checknelems(L, 1); + o = index2adr(L, idx); + api_check(L, ttistable(o)); + setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1); + luaC_barriert(L, hvalue(o), L->top-1); + L->top--; + lua_unlock(L); +} + + +LUA_API int lua_setmetatable (lua_State *L, int objindex) { + TValue *obj; + Table *mt; + lua_lock(L); + api_checknelems(L, 1); + obj = index2adr(L, objindex); + api_checkvalidindex(L, obj); + if (ttisnil(L->top - 1)) + mt = NULL; + else { + api_check(L, ttistable(L->top - 1)); + mt = hvalue(L->top - 1); + } + switch (ttype(obj)) { + case LUA_TTABLE: { + hvalue(obj)->metatable = mt; + if (mt) + luaC_objbarriert(L, hvalue(obj), mt); + break; + } + case LUA_TUSERDATA: { + uvalue(obj)->metatable = mt; + if (mt) + luaC_objbarrier(L, rawuvalue(obj), mt); + break; + } + default: { + G(L)->mt[ttype(obj)] = mt; + break; + } + } + L->top--; + lua_unlock(L); + return 1; +} + + +LUA_API int lua_setfenv (lua_State *L, int idx) { + StkId o; + int res = 1; + lua_lock(L); + api_checknelems(L, 1); + o = index2adr(L, idx); + api_checkvalidindex(L, o); + api_check(L, ttistable(L->top - 1)); + switch (ttype(o)) { + case LUA_TFUNCTION: + clvalue(o)->c.env = hvalue(L->top - 1); + break; + case LUA_TUSERDATA: + uvalue(o)->env = hvalue(L->top - 1); + break; + case LUA_TTHREAD: + sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1)); + break; + default: + res = 0; + break; + } + if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); + L->top--; + lua_unlock(L); + return res; +} + + +/* +** `load' and `call' functions (run Lua code) +*/ + + +#define adjustresults(L,nres) \ + { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; } + + +#define checkresults(L,na,nr) \ + api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na))) + + +LUA_API void lua_call (lua_State *L, int nargs, int nresults) { + StkId func; + lua_lock(L); + api_checknelems(L, nargs+1); + checkresults(L, nargs, nresults); + func = L->top - (nargs+1); + luaD_call(L, func, nresults); + adjustresults(L, nresults); + lua_unlock(L); +} + + + +/* +** Execute a protected call. +*/ +struct CallS { /* data to `f_call' */ + StkId func; + int nresults; +}; + + +static void f_call (lua_State *L, void *ud) { + struct CallS *c = cast(struct CallS *, ud); + luaD_call(L, c->func, c->nresults); +} + + + +LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) { + struct CallS c; + int status; + ptrdiff_t func; + lua_lock(L); + api_checknelems(L, nargs+1); + checkresults(L, nargs, nresults); + if (errfunc == 0) + func = 0; + else { + StkId o = index2adr(L, errfunc); + api_checkvalidindex(L, o); + func = savestack(L, o); + } + c.func = L->top - (nargs+1); /* function to be called */ + c.nresults = nresults; + status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); + adjustresults(L, nresults); + lua_unlock(L); + return status; +} + + +/* +** Execute a protected C call. +*/ +struct CCallS { /* data to `f_Ccall' */ + lua_CFunction func; + void *ud; +}; + + +static void f_Ccall (lua_State *L, void *ud) { + struct CCallS *c = cast(struct CCallS *, ud); + Closure *cl; + cl = luaF_newCclosure(L, 0, getcurrenv(L)); + cl->c.f = c->func; + setclvalue(L, L->top, cl); /* push function */ + api_incr_top(L); + setpvalue(L->top, c->ud); /* push only argument */ + api_incr_top(L); + luaD_call(L, L->top - 2, 0); +} + + +LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) { + struct CCallS c; + int status; + lua_lock(L); + c.func = func; + c.ud = ud; + status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0); + lua_unlock(L); + return status; +} + + +LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, + const char *chunkname) { + ZIO z; + int status; + lua_lock(L); + if (!chunkname) chunkname = "?"; + luaZ_init(L, &z, reader, data); + status = luaD_protectedparser(L, &z, chunkname); + lua_unlock(L); + return status; +} + + +LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { + int status; + TValue *o; + lua_lock(L); + api_checknelems(L, 1); + o = L->top - 1; + if (isLfunction(o)) + status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0); + else + status = 1; + lua_unlock(L); + return status; +} + + +LUA_API int lua_status (lua_State *L) { + return L->status; +} + + +/* +** Garbage-collection function +*/ + +LUA_API int lua_gc (lua_State *L, int what, int data) { + int res = 0; + global_State *g; + lua_lock(L); + g = G(L); + switch (what) { + case LUA_GCSTOP: { + g->GCthreshold = MAX_LUMEM; + break; + } + case LUA_GCRESTART: { + g->GCthreshold = g->totalbytes; + break; + } + case LUA_GCCOLLECT: { + luaC_fullgc(L); + break; + } + case LUA_GCCOUNT: { + /* GC values are expressed in Kbytes: #bytes/2^10 */ + res = cast_int(g->totalbytes >> 10); + break; + } + case LUA_GCCOUNTB: { + res = cast_int(g->totalbytes & 0x3ff); + break; + } + case LUA_GCSTEP: { + lu_mem a = (cast(lu_mem, data) << 10); + if (a <= g->totalbytes) + g->GCthreshold = g->totalbytes - a; + else + g->GCthreshold = 0; + while (g->GCthreshold <= g->totalbytes) { + luaC_step(L); + if (g->gcstate == GCSpause) { /* end of cycle? */ + res = 1; /* signal it */ + break; + } + } + break; + } + case LUA_GCSETPAUSE: { + res = g->gcpause; + g->gcpause = data; + break; + } + case LUA_GCSETSTEPMUL: { + res = g->gcstepmul; + g->gcstepmul = data; + break; + } + default: res = -1; /* invalid option */ + } + lua_unlock(L); + return res; +} + + + +/* +** miscellaneous functions +*/ + + +LUA_API int lua_error (lua_State *L) { + lua_lock(L); + api_checknelems(L, 1); + luaG_errormsg(L); + lua_unlock(L); + return 0; /* to avoid warnings */ +} + + +LUA_API int lua_next (lua_State *L, int idx) { + StkId t; + int more; + lua_lock(L); + t = index2adr(L, idx); + api_check(L, ttistable(t)); + more = luaH_next(L, hvalue(t), L->top - 1); + if (more) { + api_incr_top(L); + } + else /* no more elements */ + L->top -= 1; /* remove key */ + lua_unlock(L); + return more; +} + + +LUA_API void lua_concat (lua_State *L, int n) { + lua_lock(L); + api_checknelems(L, n); + if (n >= 2) { + luaC_checkGC(L); + luaV_concat(L, n, cast_int(L->top - L->base) - 1); + L->top -= (n-1); + } + else if (n == 0) { /* push empty string */ + setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); + api_incr_top(L); + } + /* else n == 1; nothing to do */ + lua_unlock(L); +} + + +LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { + lua_Alloc f; + lua_lock(L); + if (ud) *ud = G(L)->ud; + f = G(L)->frealloc; + lua_unlock(L); + return f; +} + + +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { + lua_lock(L); + G(L)->ud = ud; + G(L)->frealloc = f; + lua_unlock(L); +} + + +LUA_API void *lua_newuserdata (lua_State *L, size_t size) { + Udata *u; + lua_lock(L); + luaC_checkGC(L); + u = luaS_newudata(L, size, getcurrenv(L)); + setuvalue(L, L->top, u); + api_incr_top(L); + lua_unlock(L); + return u + 1; +} + + + + +static const char *aux_upvalue (StkId fi, int n, TValue **val) { + Closure *f; + if (!ttisfunction(fi)) return NULL; + f = clvalue(fi); + if (f->c.isC) { + if (!(1 <= n && n <= f->c.nupvalues)) return NULL; + *val = &f->c.upvalue[n-1]; + return ""; + } + else { + Proto *p = f->l.p; + if (!(1 <= n && n <= p->sizeupvalues)) return NULL; + *val = f->l.upvals[n-1]->v; + return getstr(p->upvalues[n-1]); + } +} + + +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TValue *val; + lua_lock(L); + name = aux_upvalue(index2adr(L, funcindex), n, &val); + if (name) { + setobj2s(L, L->top, val); + api_incr_top(L); + } + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TValue *val; + StkId fi; + lua_lock(L); + fi = index2adr(L, funcindex); + api_checknelems(L, 1); + name = aux_upvalue(fi, n, &val); + if (name) { + L->top--; + setobj(L, val, L->top); + luaC_barrier(L, clvalue(fi), L->top); + } + lua_unlock(L); + return name; +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/lapi.h b/vscript/languages/lua/lua-5.1.4/src/lapi.h new file mode 100644 index 00000000..2c3fab24 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lapi.h @@ -0,0 +1,16 @@ +/* +** $Id: lapi.h,v 2.2.1.1 2007/12/27 13:02:25 roberto Exp $ +** Auxiliary functions from Lua API +** See Copyright Notice in lua.h +*/ + +#ifndef lapi_h +#define lapi_h + + +#include "lobject.h" + + +LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o); + +#endif diff --git a/vscript/languages/lua/lua-5.1.4/src/lauxlib.c b/vscript/languages/lua/lua-5.1.4/src/lauxlib.c new file mode 100644 index 00000000..10f14e2c --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lauxlib.c @@ -0,0 +1,652 @@ +/* +** $Id: lauxlib.c,v 1.159.1.3 2008/01/21 13:20:51 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include +#include + + +/* This file uses only the official API of Lua. +** Any function declared here could be written as an application function. +*/ + +#define lauxlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" + + +#define FREELIST_REF 0 /* free list of references */ + + +/* convert a stack index to positive */ +#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \ + lua_gettop(L) + (i) + 1) + + +/* +** {====================================================== +** Error-report functions +** ======================================================= +*/ + + +LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { + lua_Debug ar; + if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ + return luaL_error(L, "bad argument #%d (%s)", narg, extramsg); + lua_getinfo(L, "n", &ar); + if (strcmp(ar.namewhat, "method") == 0) { + narg--; /* do not count `self' */ + if (narg == 0) /* error is in the self argument itself? */ + return luaL_error(L, "calling " LUA_QS " on bad self (%s)", + ar.name, extramsg); + } + if (ar.name == NULL) + ar.name = "?"; + return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", + narg, ar.name, extramsg); +} + + +LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) { + const char *msg = lua_pushfstring(L, "%s expected, got %s", + tname, luaL_typename(L, narg)); + return luaL_argerror(L, narg, msg); +} + + +static void tag_error (lua_State *L, int narg, int tag) { + luaL_typerror(L, narg, lua_typename(L, tag)); +} + + +LUALIB_API void luaL_where (lua_State *L, int level) { + lua_Debug ar; + if (lua_getstack(L, level, &ar)) { /* check function at level */ + lua_getinfo(L, "Sl", &ar); /* get info about it */ + if (ar.currentline > 0) { /* is there info? */ + lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); + return; + } + } + lua_pushliteral(L, ""); /* else, no information available... */ +} + + +LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + luaL_where(L, 1); + lua_pushvfstring(L, fmt, argp); + va_end(argp); + lua_concat(L, 2); + return lua_error(L); +} + +/* }====================================================== */ + + +LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def, + const char *const lst[]) { + const char *name = (def) ? luaL_optstring(L, narg, def) : + luaL_checkstring(L, narg); + int i; + for (i=0; lst[i]; i++) + if (strcmp(lst[i], name) == 0) + return i; + return luaL_argerror(L, narg, + lua_pushfstring(L, "invalid option " LUA_QS, name)); +} + + +LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { + lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */ + if (!lua_isnil(L, -1)) /* name already in use? */ + return 0; /* leave previous value on top, but return 0 */ + lua_pop(L, 1); + lua_newtable(L); /* create metatable */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ + return 1; +} + + +LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { + void *p = lua_touserdata(L, ud); + if (p != NULL) { /* value is a userdata? */ + if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ + lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ + if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */ + lua_pop(L, 2); /* remove both metatables */ + return p; + } + } + } + luaL_typerror(L, ud, tname); /* else error */ + return NULL; /* to avoid warnings */ +} + + +LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) { + if (!lua_checkstack(L, space)) + luaL_error(L, "stack overflow (%s)", mes); +} + + +LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) { + if (lua_type(L, narg) != t) + tag_error(L, narg, t); +} + + +LUALIB_API void luaL_checkany (lua_State *L, int narg) { + if (lua_type(L, narg) == LUA_TNONE) + luaL_argerror(L, narg, "value expected"); +} + + +LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) { + const char *s = lua_tolstring(L, narg, len); + if (!s) tag_error(L, narg, LUA_TSTRING); + return s; +} + + +LUALIB_API const char *luaL_optlstring (lua_State *L, int narg, + const char *def, size_t *len) { + if (lua_isnoneornil(L, narg)) { + if (len) + *len = (def ? strlen(def) : 0); + return def; + } + else return luaL_checklstring(L, narg, len); +} + + +LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) { + lua_Number d = lua_tonumber(L, narg); + if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ + tag_error(L, narg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { + return luaL_opt(L, luaL_checknumber, narg, def); +} + + +LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { + lua_Integer d = lua_tointeger(L, narg); + if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ + tag_error(L, narg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg, + lua_Integer def) { + return luaL_opt(L, luaL_checkinteger, narg, def); +} + + +LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { + if (!lua_getmetatable(L, obj)) /* no metatable? */ + return 0; + lua_pushstring(L, event); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) { + lua_pop(L, 2); /* remove metatable and metafield */ + return 0; + } + else { + lua_remove(L, -2); /* remove only metatable */ + return 1; + } +} + + +LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { + obj = abs_index(L, obj); + if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ + return 0; + lua_pushvalue(L, obj); + lua_call(L, 1, 1); + return 1; +} + + +LUALIB_API void (luaL_register) (lua_State *L, const char *libname, + const luaL_Reg *l) { + luaI_openlib(L, libname, l, 0); +} + + +static int libsize (const luaL_Reg *l) { + int size = 0; + for (; l->name; l++) size++; + return size; +} + + +LUALIB_API void luaI_openlib (lua_State *L, const char *libname, + const luaL_Reg *l, int nup) { + if (libname) { + int size = libsize(l); + /* check whether lib already exists */ + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); + lua_getfield(L, -1, libname); /* get _LOADED[libname] */ + if (!lua_istable(L, -1)) { /* not found? */ + lua_pop(L, 1); /* remove previous result */ + /* try global variable (and create one if it does not exist) */ + if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL) + luaL_error(L, "name conflict for module " LUA_QS, libname); + lua_pushvalue(L, -1); + lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ + } + lua_remove(L, -2); /* remove _LOADED table */ + lua_insert(L, -(nup+1)); /* move library table to below upvalues */ + } + for (; l->name; l++) { + int i; + for (i=0; ifunc, nup); + lua_setfield(L, -(nup+2), l->name); + } + lua_pop(L, nup); /* remove upvalues */ +} + + + +/* +** {====================================================== +** getn-setn: size for arrays +** ======================================================= +*/ + +#if defined(LUA_COMPAT_GETN) + +static int checkint (lua_State *L, int topop) { + int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1; + lua_pop(L, topop); + return n; +} + + +static void getsizes (lua_State *L) { + lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); + if (lua_isnil(L, -1)) { /* no `size' table? */ + lua_pop(L, 1); /* remove nil */ + lua_newtable(L); /* create it */ + lua_pushvalue(L, -1); /* `size' will be its own metatable */ + lua_setmetatable(L, -2); + lua_pushliteral(L, "kv"); + lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */ + } +} + + +LUALIB_API void luaL_setn (lua_State *L, int t, int n) { + t = abs_index(L, t); + lua_pushliteral(L, "n"); + lua_rawget(L, t); + if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */ + lua_pushliteral(L, "n"); /* use it */ + lua_pushinteger(L, n); + lua_rawset(L, t); + } + else { /* use `sizes' */ + getsizes(L); + lua_pushvalue(L, t); + lua_pushinteger(L, n); + lua_rawset(L, -3); /* sizes[t] = n */ + lua_pop(L, 1); /* remove `sizes' */ + } +} + + +LUALIB_API int luaL_getn (lua_State *L, int t) { + int n; + t = abs_index(L, t); + lua_pushliteral(L, "n"); /* try t.n */ + lua_rawget(L, t); + if ((n = checkint(L, 1)) >= 0) return n; + getsizes(L); /* else try sizes[t] */ + lua_pushvalue(L, t); + lua_rawget(L, -2); + if ((n = checkint(L, 2)) >= 0) return n; + return (int)lua_objlen(L, t); +} + +#endif + +/* }====================================================== */ + + + +LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, + const char *r) { + const char *wild; + size_t l = strlen(p); + luaL_Buffer b; + luaL_buffinit(L, &b); + while ((wild = strstr(s, p)) != NULL) { + luaL_addlstring(&b, s, wild - s); /* push prefix */ + luaL_addstring(&b, r); /* push replacement in place of pattern */ + s = wild + l; /* continue after `p' */ + } + luaL_addstring(&b, s); /* push last suffix */ + luaL_pushresult(&b); + return lua_tostring(L, -1); +} + + +LUALIB_API const char *luaL_findtable (lua_State *L, int idx, + const char *fname, int szhint) { + const char *e; + lua_pushvalue(L, idx); + do { + e = strchr(fname, '.'); + if (e == NULL) e = fname + strlen(fname); + lua_pushlstring(L, fname, e - fname); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) { /* no such field? */ + lua_pop(L, 1); /* remove this nil */ + lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */ + lua_pushlstring(L, fname, e - fname); + lua_pushvalue(L, -2); + lua_settable(L, -4); /* set new table into field */ + } + else if (!lua_istable(L, -1)) { /* field has a non-table value? */ + lua_pop(L, 2); /* remove table and value */ + return fname; /* return problematic part of the name */ + } + lua_remove(L, -2); /* remove previous table */ + fname = e + 1; + } while (*e == '.'); + return NULL; +} + + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + + +#define bufflen(B) ((B)->p - (B)->buffer) +#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) + +#define LIMIT (LUA_MINSTACK/2) + + +static int emptybuffer (luaL_Buffer *B) { + size_t l = bufflen(B); + if (l == 0) return 0; /* put nothing on stack */ + else { + lua_pushlstring(B->L, B->buffer, l); + B->p = B->buffer; + B->lvl++; + return 1; + } +} + + +static void adjuststack (luaL_Buffer *B) { + if (B->lvl > 1) { + lua_State *L = B->L; + int toget = 1; /* number of levels to concat */ + size_t toplen = lua_strlen(L, -1); + do { + size_t l = lua_strlen(L, -(toget+1)); + if (B->lvl - toget + 1 >= LIMIT || toplen > l) { + toplen += l; + toget++; + } + else break; + } while (toget < B->lvl); + lua_concat(L, toget); + B->lvl = B->lvl - toget + 1; + } +} + + +LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) { + if (emptybuffer(B)) + adjuststack(B); + return B->buffer; +} + + +LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { + while (l--) + luaL_addchar(B, *s++); +} + + +LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { + luaL_addlstring(B, s, strlen(s)); +} + + +LUALIB_API void luaL_pushresult (luaL_Buffer *B) { + emptybuffer(B); + lua_concat(B->L, B->lvl); + B->lvl = 1; +} + + +LUALIB_API void luaL_addvalue (luaL_Buffer *B) { + lua_State *L = B->L; + size_t vl; + const char *s = lua_tolstring(L, -1, &vl); + if (vl <= bufffree(B)) { /* fit into buffer? */ + memcpy(B->p, s, vl); /* put it there */ + B->p += vl; + lua_pop(L, 1); /* remove from stack */ + } + else { + if (emptybuffer(B)) + lua_insert(L, -2); /* put buffer before new value */ + B->lvl++; /* add new value into B stack */ + adjuststack(B); + } +} + + +LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { + B->L = L; + B->p = B->buffer; + B->lvl = 0; +} + +/* }====================================================== */ + + +LUALIB_API int luaL_ref (lua_State *L, int t) { + int ref; + t = abs_index(L, t); + if (lua_isnil(L, -1)) { + lua_pop(L, 1); /* remove from stack */ + return LUA_REFNIL; /* `nil' has a unique fixed reference */ + } + lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ + ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ + lua_pop(L, 1); /* remove it from stack */ + if (ref != 0) { /* any free element? */ + lua_rawgeti(L, t, ref); /* remove it from list */ + lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ + } + else { /* no free elements */ + ref = (int)lua_objlen(L, t); + ref++; /* create new reference */ + } + lua_rawseti(L, t, ref); + return ref; +} + + +LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { + if (ref >= 0) { + t = abs_index(L, t); + lua_rawgeti(L, t, FREELIST_REF); + lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */ + lua_pushinteger(L, ref); + lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */ + } +} + + + +/* +** {====================================================== +** Load functions +** ======================================================= +*/ + +typedef struct LoadF { + int extraline; + FILE *f; + char buff[LUAL_BUFFERSIZE]; +} LoadF; + + +static const char *getF (lua_State *L, void *ud, size_t *size) { + LoadF *lf = (LoadF *)ud; + (void)L; + if (lf->extraline) { + lf->extraline = 0; + *size = 1; + return "\n"; + } + if (feof(lf->f)) return NULL; + *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); + return (*size > 0) ? lf->buff : NULL; +} + + +static int errfile (lua_State *L, const char *what, int fnameindex) { + const char *serr = strerror(errno); + const char *filename = lua_tostring(L, fnameindex) + 1; + lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); + lua_remove(L, fnameindex); + return LUA_ERRFILE; +} + + +LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { + LoadF lf; + int status, readstatus; + int c; + int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ + lf.extraline = 0; + if (filename == NULL) { + lua_pushliteral(L, "=stdin"); + lf.f = stdin; + } + else { + lua_pushfstring(L, "@%s", filename); + lf.f = fopen(filename, "r"); + if (lf.f == NULL) return errfile(L, "open", fnameindex); + } + c = getc(lf.f); + if (c == '#') { /* Unix exec. file? */ + lf.extraline = 1; + while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */ + if (c == '\n') c = getc(lf.f); + } + if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ + lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ + if (lf.f == NULL) return errfile(L, "reopen", fnameindex); + /* skip eventual `#!...' */ + while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ; + lf.extraline = 0; + } + ungetc(c, lf.f); + status = lua_load(L, getF, &lf, lua_tostring(L, -1)); + readstatus = ferror(lf.f); + if (filename) fclose(lf.f); /* close file (even in case of errors) */ + if (readstatus) { + lua_settop(L, fnameindex); /* ignore results from `lua_load' */ + return errfile(L, "read", fnameindex); + } + lua_remove(L, fnameindex); + return status; +} + + +typedef struct LoadS { + const char *s; + size_t size; +} LoadS; + + +static const char *getS (lua_State *L, void *ud, size_t *size) { + LoadS *ls = (LoadS *)ud; + (void)L; + if (ls->size == 0) return NULL; + *size = ls->size; + ls->size = 0; + return ls->s; +} + + +LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size, + const char *name) { + LoadS ls; + ls.s = buff; + ls.size = size; + return lua_load(L, getS, &ls, name); +} + + +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) { + return luaL_loadbuffer(L, s, strlen(s), s); +} + + + +/* }====================================================== */ + + +static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { + (void)ud; + (void)osize; + if (nsize == 0) { + free(ptr); + return NULL; + } + else + return realloc(ptr, nsize); +} + + +static int panic (lua_State *L) { + (void)L; /* to avoid warnings */ + fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n", + lua_tostring(L, -1)); + return 0; +} + + +LUALIB_API lua_State *luaL_newstate (void) { + lua_State *L = lua_newstate(l_alloc, NULL); + if (L) lua_atpanic(L, &panic); + return L; +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/lauxlib.h b/vscript/languages/lua/lua-5.1.4/src/lauxlib.h new file mode 100644 index 00000000..34258235 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lauxlib.h @@ -0,0 +1,174 @@ +/* +** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lauxlib_h +#define lauxlib_h + + +#include +#include + +#include "lua.h" + + +#if defined(LUA_COMPAT_GETN) +LUALIB_API int (luaL_getn) (lua_State *L, int t); +LUALIB_API void (luaL_setn) (lua_State *L, int t, int n); +#else +#define luaL_getn(L,i) ((int)lua_objlen(L, i)) +#define luaL_setn(L,i,j) ((void)0) /* no op! */ +#endif + +#if defined(LUA_COMPAT_OPENLIB) +#define luaI_openlib luaL_openlib +#endif + + +/* extra error code for `luaL_load' */ +#define LUA_ERRFILE (LUA_ERRERR+1) + + +typedef struct luaL_Reg { + const char *name; + lua_CFunction func; +} luaL_Reg; + + + +LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname, + const luaL_Reg *l, int nup); +LUALIB_API void (luaL_register) (lua_State *L, const char *libname, + const luaL_Reg *l); +LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); +LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); +LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, + size_t *l); +LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, + const char *def, size_t *l); +LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); +LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); + +LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); +LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, + lua_Integer def); + +LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); +LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); +LUALIB_API void (luaL_checkany) (lua_State *L, int narg); + +LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); +LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); + +LUALIB_API void (luaL_where) (lua_State *L, int lvl); +LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); + +LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, + const char *const lst[]); + +LUALIB_API int (luaL_ref) (lua_State *L, int t); +LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); + +LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); +LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, + const char *name); +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); + +LUALIB_API lua_State *(luaL_newstate) (void); + + +LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, + const char *r); + +LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, + const char *fname, int szhint); + + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define luaL_argcheck(L, cond,numarg,extramsg) \ + ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) +#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) + +#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) + +#define luaL_dofile(L, fn) \ + (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_dostring(L, s) \ + (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) + +#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + + + +typedef struct luaL_Buffer { + char *p; /* current position in buffer */ + int lvl; /* number of strings in the stack (level) */ + lua_State *L; + char buffer[LUAL_BUFFERSIZE]; +} luaL_Buffer; + +#define luaL_addchar(B,c) \ + ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ + (*(B)->p++ = (char)(c))) + +/* compatibility only */ +#define luaL_putchar(B,c) luaL_addchar(B,c) + +#define luaL_addsize(B,n) ((B)->p += (n)) + +LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); +LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); +LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); +LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); +LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); + + +/* }====================================================== */ + + +/* compatibility with ref system */ + +/* pre-defined references */ +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) + +#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ + (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) + +#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) + +#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) + + +#define luaL_reg luaL_Reg + +#endif + + diff --git a/vscript/languages/lua/lua-5.1.4/src/lbaselib.c b/vscript/languages/lua/lua-5.1.4/src/lbaselib.c new file mode 100644 index 00000000..2a4c079d --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lbaselib.c @@ -0,0 +1,653 @@ +/* +** $Id: lbaselib.c,v 1.191.1.6 2008/02/14 16:46:22 roberto Exp $ +** Basic library +** See Copyright Notice in lua.h +*/ + + + +#include +#include +#include +#include + +#define lbaselib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + + +/* +** If your system does not support `stdout', you can just remove this function. +** If you need, you can define your own `print' function, following this +** model but changing `fputs' to put the strings at a proper place +** (a console window or a log file, for instance). +*/ +static int luaB_print (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int i; + lua_getglobal(L, "tostring"); + for (i=1; i<=n; i++) { + const char *s; + lua_pushvalue(L, -1); /* function to be called */ + lua_pushvalue(L, i); /* value to print */ + lua_call(L, 1, 1); + s = lua_tostring(L, -1); /* get result */ + if (s == NULL) + return luaL_error(L, LUA_QL("tostring") " must return a string to " + LUA_QL("print")); + if (i>1) fputs("\t", stdout); + fputs(s, stdout); + lua_pop(L, 1); /* pop result */ + } + fputs("\n", stdout); + return 0; +} + + +static int luaB_tonumber (lua_State *L) { + int base = luaL_optint(L, 2, 10); + if (base == 10) { /* standard conversion */ + luaL_checkany(L, 1); + if (lua_isnumber(L, 1)) { + lua_pushnumber(L, lua_tonumber(L, 1)); + return 1; + } + } + else { + const char *s1 = luaL_checkstring(L, 1); + char *s2; + unsigned long n; + luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); + n = strtoul(s1, &s2, base); + if (s1 != s2) { /* at least one valid digit? */ + while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */ + if (*s2 == '\0') { /* no invalid trailing characters? */ + lua_pushnumber(L, (lua_Number)n); + return 1; + } + } + } + lua_pushnil(L); /* else not a number */ + return 1; +} + + +static int luaB_error (lua_State *L) { + int level = luaL_optint(L, 2, 1); + lua_settop(L, 1); + if (lua_isstring(L, 1) && level > 0) { /* add extra information? */ + luaL_where(L, level); + lua_pushvalue(L, 1); + lua_concat(L, 2); + } + return lua_error(L); +} + + +static int luaB_getmetatable (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); + return 1; /* no metatable */ + } + luaL_getmetafield(L, 1, "__metatable"); + return 1; /* returns either __metatable field (if present) or metatable */ +} + + +static int luaB_setmetatable (lua_State *L) { + int t = lua_type(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, + "nil or table expected"); + if (luaL_getmetafield(L, 1, "__metatable")) + luaL_error(L, "cannot change a protected metatable"); + lua_settop(L, 2); + lua_setmetatable(L, 1); + return 1; +} + + +static void getfunc (lua_State *L, int opt) { + if (lua_isfunction(L, 1)) lua_pushvalue(L, 1); + else { + lua_Debug ar; + int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1); + luaL_argcheck(L, level >= 0, 1, "level must be non-negative"); + if (lua_getstack(L, level, &ar) == 0) + luaL_argerror(L, 1, "invalid level"); + lua_getinfo(L, "f", &ar); + if (lua_isnil(L, -1)) + luaL_error(L, "no function environment for tail call at level %d", + level); + } +} + + +static int luaB_getfenv (lua_State *L) { + getfunc(L, 1); + if (lua_iscfunction(L, -1)) /* is a C function? */ + lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */ + else + lua_getfenv(L, -1); + return 1; +} + + +static int luaB_setfenv (lua_State *L) { + luaL_checktype(L, 2, LUA_TTABLE); + getfunc(L, 0); + lua_pushvalue(L, 2); + if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) { + /* change environment of current thread */ + lua_pushthread(L); + lua_insert(L, -2); + lua_setfenv(L, -2); + return 0; + } + else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0) + luaL_error(L, + LUA_QL("setfenv") " cannot change environment of given object"); + return 1; +} + + +static int luaB_rawequal (lua_State *L) { + luaL_checkany(L, 1); + luaL_checkany(L, 2); + lua_pushboolean(L, lua_rawequal(L, 1, 2)); + return 1; +} + + +static int luaB_rawget (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_rawget(L, 1); + return 1; +} + +static int luaB_rawset (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + luaL_checkany(L, 3); + lua_settop(L, 3); + lua_rawset(L, 1); + return 1; +} + + +static int luaB_gcinfo (lua_State *L) { + lua_pushinteger(L, lua_getgccount(L)); + return 1; +} + + +static int luaB_collectgarbage (lua_State *L) { + static const char *const opts[] = {"stop", "restart", "collect", + "count", "step", "setpause", "setstepmul", NULL}; + static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, + LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL}; + int o = luaL_checkoption(L, 1, "collect", opts); + int ex = luaL_optint(L, 2, 0); + int res = lua_gc(L, optsnum[o], ex); + switch (optsnum[o]) { + case LUA_GCCOUNT: { + int b = lua_gc(L, LUA_GCCOUNTB, 0); + lua_pushnumber(L, res + ((lua_Number)b/1024)); + return 1; + } + case LUA_GCSTEP: { + lua_pushboolean(L, res); + return 1; + } + default: { + lua_pushnumber(L, res); + return 1; + } + } +} + + +static int luaB_type (lua_State *L) { + luaL_checkany(L, 1); + lua_pushstring(L, luaL_typename(L, 1)); + return 1; +} + + +static int luaB_next (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 2); /* create a 2nd argument if there isn't one */ + if (lua_next(L, 1)) + return 2; + else { + lua_pushnil(L); + return 1; + } +} + + +static int luaB_pairs (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ + lua_pushvalue(L, 1); /* state, */ + lua_pushnil(L); /* and initial value */ + return 3; +} + + +static int ipairsaux (lua_State *L) { + int i = luaL_checkint(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + i++; /* next value */ + lua_pushinteger(L, i); + lua_rawgeti(L, 1, i); + return (lua_isnil(L, -1)) ? 0 : 2; +} + + +static int luaB_ipairs (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ + lua_pushvalue(L, 1); /* state, */ + lua_pushinteger(L, 0); /* and initial value */ + return 3; +} + + +static int load_aux (lua_State *L, int status) { + if (status == 0) /* OK? */ + return 1; + else { + lua_pushnil(L); + lua_insert(L, -2); /* put before error message */ + return 2; /* return nil plus error message */ + } +} + + +static int luaB_loadstring (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + const char *chunkname = luaL_optstring(L, 2, s); + return load_aux(L, luaL_loadbuffer(L, s, l, chunkname)); +} + + +static int luaB_loadfile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + return load_aux(L, luaL_loadfile(L, fname)); +} + + +/* +** Reader for generic `load' function: `lua_load' uses the +** stack for internal stuff, so the reader cannot change the +** stack top. Instead, it keeps its resulting string in a +** reserved slot inside the stack. +*/ +static const char *generic_reader (lua_State *L, void *ud, size_t *size) { + (void)ud; /* to avoid warnings */ + luaL_checkstack(L, 2, "too many nested functions"); + lua_pushvalue(L, 1); /* get function */ + lua_call(L, 0, 1); /* call it */ + if (lua_isnil(L, -1)) { + *size = 0; + return NULL; + } + else if (lua_isstring(L, -1)) { + lua_replace(L, 3); /* save string in a reserved stack slot */ + return lua_tolstring(L, 3, size); + } + else luaL_error(L, "reader function must return a string"); + return NULL; /* to avoid warnings */ +} + + +static int luaB_load (lua_State *L) { + int status; + const char *cname = luaL_optstring(L, 2, "=(load)"); + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_settop(L, 3); /* function, eventual name, plus one reserved slot */ + status = lua_load(L, generic_reader, NULL, cname); + return load_aux(L, status); +} + + +static int luaB_dofile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + int n = lua_gettop(L); + if (luaL_loadfile(L, fname) != 0) lua_error(L); + lua_call(L, 0, LUA_MULTRET); + return lua_gettop(L) - n; +} + + +static int luaB_assert (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_toboolean(L, 1)) + return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); + return lua_gettop(L); +} + + +static int luaB_unpack (lua_State *L) { + int i, e, n; + luaL_checktype(L, 1, LUA_TTABLE); + i = luaL_optint(L, 2, 1); + e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1)); + if (i > e) return 0; /* empty range */ + n = e - i + 1; /* number of elements */ + if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ + return luaL_error(L, "too many results to unpack"); + lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ + while (i++ < e) /* push arg[i + 1...e] */ + lua_rawgeti(L, 1, i); + return n; +} + + +static int luaB_select (lua_State *L) { + int n = lua_gettop(L); + if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') { + lua_pushinteger(L, n-1); + return 1; + } + else { + int i = luaL_checkint(L, 1); + if (i < 0) i = n + i; + else if (i > n) i = n; + luaL_argcheck(L, 1 <= i, 1, "index out of range"); + return n - i; + } +} + + +static int luaB_pcall (lua_State *L) { + int status; + luaL_checkany(L, 1); + status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0); + lua_pushboolean(L, (status == 0)); + lua_insert(L, 1); + return lua_gettop(L); /* return status + all results */ +} + + +static int luaB_xpcall (lua_State *L) { + int status; + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_insert(L, 1); /* put error function under function to be called */ + status = lua_pcall(L, 0, LUA_MULTRET, 1); + lua_pushboolean(L, (status == 0)); + lua_replace(L, 1); + return lua_gettop(L); /* return status + all results */ +} + + +static int luaB_tostring (lua_State *L) { + luaL_checkany(L, 1); + if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */ + return 1; /* use its value */ + switch (lua_type(L, 1)) { + case LUA_TNUMBER: + lua_pushstring(L, lua_tostring(L, 1)); + break; + case LUA_TSTRING: + lua_pushvalue(L, 1); + break; + case LUA_TBOOLEAN: + lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false")); + break; + case LUA_TNIL: + lua_pushliteral(L, "nil"); + break; + default: + lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1)); + break; + } + return 1; +} + + +static int luaB_newproxy (lua_State *L) { + lua_settop(L, 1); + lua_newuserdata(L, 0); /* create proxy */ + if (lua_toboolean(L, 1) == 0) + return 1; /* no metatable */ + else if (lua_isboolean(L, 1)) { + lua_newtable(L); /* create a new metatable `m' ... */ + lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */ + lua_pushboolean(L, 1); + lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */ + } + else { + int validproxy = 0; /* to check if weaktable[metatable(u)] == true */ + if (lua_getmetatable(L, 1)) { + lua_rawget(L, lua_upvalueindex(1)); + validproxy = lua_toboolean(L, -1); + lua_pop(L, 1); /* remove value */ + } + luaL_argcheck(L, validproxy, 1, "boolean or proxy expected"); + lua_getmetatable(L, 1); /* metatable is valid; get it */ + } + lua_setmetatable(L, 2); + return 1; +} + + +static const luaL_Reg base_funcs[] = { + {"assert", luaB_assert}, + {"collectgarbage", luaB_collectgarbage}, + {"dofile", luaB_dofile}, + {"error", luaB_error}, + {"gcinfo", luaB_gcinfo}, + {"getfenv", luaB_getfenv}, + {"getmetatable", luaB_getmetatable}, + {"loadfile", luaB_loadfile}, + {"load", luaB_load}, + {"loadstring", luaB_loadstring}, + {"next", luaB_next}, + {"pcall", luaB_pcall}, + {"print", luaB_print}, + {"rawequal", luaB_rawequal}, + {"rawget", luaB_rawget}, + {"rawset", luaB_rawset}, + {"select", luaB_select}, + {"setfenv", luaB_setfenv}, + {"setmetatable", luaB_setmetatable}, + {"tonumber", luaB_tonumber}, + {"tostring", luaB_tostring}, + {"type", luaB_type}, + {"unpack", luaB_unpack}, + {"xpcall", luaB_xpcall}, + {NULL, NULL} +}; + + +/* +** {====================================================== +** Coroutine library +** ======================================================= +*/ + +#define CO_RUN 0 /* running */ +#define CO_SUS 1 /* suspended */ +#define CO_NOR 2 /* 'normal' (it resumed another coroutine) */ +#define CO_DEAD 3 + +static const char *const statnames[] = + {"running", "suspended", "normal", "dead"}; + +static int costatus (lua_State *L, lua_State *co) { + if (L == co) return CO_RUN; + switch (lua_status(co)) { + case LUA_YIELD: + return CO_SUS; + case 0: { + lua_Debug ar; + if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ + return CO_NOR; /* it is running */ + else if (lua_gettop(co) == 0) + return CO_DEAD; + else + return CO_SUS; /* initial state */ + } + default: /* some error occured */ + return CO_DEAD; + } +} + + +static int luaB_costatus (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + luaL_argcheck(L, co, 1, "coroutine expected"); + lua_pushstring(L, statnames[costatus(L, co)]); + return 1; +} + + +static int auxresume (lua_State *L, lua_State *co, int narg) { + int status = costatus(L, co); + if (!lua_checkstack(co, narg)) + luaL_error(L, "too many arguments to resume"); + if (status != CO_SUS) { + lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]); + return -1; /* error flag */ + } + lua_xmove(L, co, narg); + lua_setlevel(L, co); + status = lua_resume(co, narg); + if (status == 0 || status == LUA_YIELD) { + int nres = lua_gettop(co); + if (!lua_checkstack(L, nres + 1)) + luaL_error(L, "too many results to resume"); + lua_xmove(co, L, nres); /* move yielded values */ + return nres; + } + else { + lua_xmove(co, L, 1); /* move error message */ + return -1; /* error flag */ + } +} + + +static int luaB_coresume (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + int r; + luaL_argcheck(L, co, 1, "coroutine expected"); + r = auxresume(L, co, lua_gettop(L) - 1); + if (r < 0) { + lua_pushboolean(L, 0); + lua_insert(L, -2); + return 2; /* return false + error message */ + } + else { + lua_pushboolean(L, 1); + lua_insert(L, -(r + 1)); + return r + 1; /* return true + `resume' returns */ + } +} + + +static int luaB_auxwrap (lua_State *L) { + lua_State *co = lua_tothread(L, lua_upvalueindex(1)); + int r = auxresume(L, co, lua_gettop(L)); + if (r < 0) { + if (lua_isstring(L, -1)) { /* error object is a string? */ + luaL_where(L, 1); /* add extra info */ + lua_insert(L, -2); + lua_concat(L, 2); + } + lua_error(L); /* propagate error */ + } + return r; +} + + +static int luaB_cocreate (lua_State *L) { + lua_State *NL = lua_newthread(L); + luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, + "Lua function expected"); + lua_pushvalue(L, 1); /* move function to top */ + lua_xmove(L, NL, 1); /* move function from L to NL */ + return 1; +} + + +static int luaB_cowrap (lua_State *L) { + luaB_cocreate(L); + lua_pushcclosure(L, luaB_auxwrap, 1); + return 1; +} + + +static int luaB_yield (lua_State *L) { + return lua_yield(L, lua_gettop(L)); +} + + +static int luaB_corunning (lua_State *L) { + if (lua_pushthread(L)) + lua_pushnil(L); /* main thread is not a coroutine */ + return 1; +} + + +static const luaL_Reg co_funcs[] = { + {"create", luaB_cocreate}, + {"resume", luaB_coresume}, + {"running", luaB_corunning}, + {"status", luaB_costatus}, + {"wrap", luaB_cowrap}, + {"yield", luaB_yield}, + {NULL, NULL} +}; + +/* }====================================================== */ + + +static void auxopen (lua_State *L, const char *name, + lua_CFunction f, lua_CFunction u) { + lua_pushcfunction(L, u); + lua_pushcclosure(L, f, 1); + lua_setfield(L, -2, name); +} + + +static void base_open (lua_State *L) { + /* set global _G */ + lua_pushvalue(L, LUA_GLOBALSINDEX); + lua_setglobal(L, "_G"); + /* open lib into global table */ + luaL_register(L, "_G", base_funcs); + lua_pushliteral(L, LUA_VERSION); + lua_setglobal(L, "_VERSION"); /* set global _VERSION */ + /* `ipairs' and `pairs' need auxliliary functions as upvalues */ + auxopen(L, "ipairs", luaB_ipairs, ipairsaux); + auxopen(L, "pairs", luaB_pairs, luaB_next); + /* `newproxy' needs a weaktable as upvalue */ + lua_createtable(L, 0, 1); /* new table `w' */ + lua_pushvalue(L, -1); /* `w' will be its own metatable */ + lua_setmetatable(L, -2); + lua_pushliteral(L, "kv"); + lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ + lua_pushcclosure(L, luaB_newproxy, 1); + lua_setglobal(L, "newproxy"); /* set global `newproxy' */ +} + + +LUALIB_API int luaopen_base (lua_State *L) { + base_open(L); + luaL_register(L, LUA_COLIBNAME, co_funcs); + return 2; +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/lcode.c b/vscript/languages/lua/lua-5.1.4/src/lcode.c new file mode 100644 index 00000000..cff626b7 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lcode.c @@ -0,0 +1,839 @@ +/* +** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + + +#include + +#define lcode_c +#define LUA_CORE + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "ltable.h" + + +#define hasjumps(e) ((e)->t != (e)->f) + + +static int isnumeral(expdesc *e) { + return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP); +} + + +void luaK_nil (FuncState *fs, int from, int n) { + Instruction *previous; + if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ + if (fs->pc == 0) { /* function start? */ + if (from >= fs->nactvar) + return; /* positions are already clean */ + } + else { + previous = &fs->f->code[fs->pc-1]; + if (GET_OPCODE(*previous) == OP_LOADNIL) { + int pfrom = GETARG_A(*previous); + int pto = GETARG_B(*previous); + if (pfrom <= from && from <= pto+1) { /* can connect both? */ + if (from+n-1 > pto) + SETARG_B(*previous, from+n-1); + return; + } + } + } + } + luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */ +} + + +int luaK_jump (FuncState *fs) { + int jpc = fs->jpc; /* save list of jumps to here */ + int j; + fs->jpc = NO_JUMP; + j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); + luaK_concat(fs, &j, jpc); /* keep them on hold */ + return j; +} + + +void luaK_ret (FuncState *fs, int first, int nret) { + luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); +} + + +static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { + luaK_codeABC(fs, op, A, B, C); + return luaK_jump(fs); +} + + +static void fixjump (FuncState *fs, int pc, int dest) { + Instruction *jmp = &fs->f->code[pc]; + int offset = dest-(pc+1); + lua_assert(dest != NO_JUMP); + if (abs(offset) > MAXARG_sBx) + luaX_syntaxerror(fs->ls, "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 luaK_getlabel (FuncState *fs) { + fs->lasttarget = fs->pc; + return fs->pc; +} + + +static int getjump (FuncState *fs, int pc) { + int offset = GETARG_sBx(fs->f->code[pc]); + if (offset == NO_JUMP) /* point to itself represents end of list */ + return NO_JUMP; /* end of list */ + else + return (pc+1)+offset; /* turn offset into absolute position */ +} + + +static Instruction *getjumpcontrol (FuncState *fs, int pc) { + Instruction *pi = &fs->f->code[pc]; + if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) + return pi-1; + else + return pi; +} + + +/* +** check whether list has any jump that do not produce a value +** (or produce an inverted value) +*/ +static int need_value (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) { + Instruction i = *getjumpcontrol(fs, list); + if (GET_OPCODE(i) != OP_TESTSET) return 1; + } + return 0; /* not found */ +} + + +static int patchtestreg (FuncState *fs, int node, int reg) { + Instruction *i = getjumpcontrol(fs, node); + if (GET_OPCODE(*i) != OP_TESTSET) + return 0; /* cannot patch other instructions */ + if (reg != NO_REG && reg != GETARG_B(*i)) + SETARG_A(*i, reg); + else /* no register to put value or register already has the value */ + *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); + + return 1; +} + + +static void removevalues (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) + patchtestreg(fs, list, NO_REG); +} + + +static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, + int dtarget) { + while (list != NO_JUMP) { + int next = getjump(fs, list); + if (patchtestreg(fs, list, reg)) + fixjump(fs, list, vtarget); + else + fixjump(fs, list, dtarget); /* jump to default target */ + list = next; + } +} + + +static void dischargejpc (FuncState *fs) { + patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); + fs->jpc = NO_JUMP; +} + + +void luaK_patchlist (FuncState *fs, int list, int target) { + if (target == fs->pc) + luaK_patchtohere(fs, list); + else { + lua_assert(target < fs->pc); + patchlistaux(fs, list, target, NO_REG, target); + } +} + + +void luaK_patchtohere (FuncState *fs, int list) { + luaK_getlabel(fs); + luaK_concat(fs, &fs->jpc, list); +} + + +void luaK_concat (FuncState *fs, int *l1, int l2) { + if (l2 == NO_JUMP) return; + else if (*l1 == NO_JUMP) + *l1 = l2; + else { + int list = *l1; + int next; + while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ + list = next; + fixjump(fs, list, l2); + } +} + + +void luaK_checkstack (FuncState *fs, int n) { + int newstack = fs->freereg + n; + if (newstack > fs->f->maxstacksize) { + if (newstack >= MAXSTACK) + luaX_syntaxerror(fs->ls, "function or expression too complex"); + fs->f->maxstacksize = cast_byte(newstack); + } +} + + +void luaK_reserveregs (FuncState *fs, int n) { + luaK_checkstack(fs, n); + fs->freereg += n; +} + + +static void freereg (FuncState *fs, int reg) { + if (!ISK(reg) && reg >= fs->nactvar) { + fs->freereg--; + lua_assert(reg == fs->freereg); + } +} + + +static void freeexp (FuncState *fs, expdesc *e) { + if (e->k == VNONRELOC) + freereg(fs, e->u.s.info); +} + + +static int addk (FuncState *fs, TValue *k, TValue *v) { + lua_State *L = fs->L; + TValue *idx = luaH_set(L, fs->h, k); + Proto *f = fs->f; + int oldsize = f->sizek; + if (ttisnumber(idx)) { + lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); + return cast_int(nvalue(idx)); + } + else { /* constant not found; create a new entry */ + setnvalue(idx, cast_num(fs->nk)); + luaM_growvector(L, f->k, fs->nk, f->sizek, TValue, + MAXARG_Bx, "constant table overflow"); + while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); + setobj(L, &f->k[fs->nk], v); + luaC_barrier(L, f, v); + return fs->nk++; + } +} + + +int luaK_stringK (FuncState *fs, TString *s) { + TValue o; + setsvalue(fs->L, &o, s); + return addk(fs, &o, &o); +} + + +int luaK_numberK (FuncState *fs, lua_Number r) { + TValue o; + setnvalue(&o, r); + return addk(fs, &o, &o); +} + + +static int boolK (FuncState *fs, int b) { + TValue o; + setbvalue(&o, b); + return addk(fs, &o, &o); +} + + +static int nilK (FuncState *fs) { + TValue k, v; + setnilvalue(&v); + /* cannot use nil as key; instead use table itself to represent nil */ + sethvalue(fs->L, &k, fs->h); + return addk(fs, &k, &v); +} + + +void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { + if (e->k == VCALL) { /* expression is an open function call? */ + SETARG_C(getcode(fs, e), nresults+1); + } + else if (e->k == VVARARG) { + SETARG_B(getcode(fs, e), nresults+1); + SETARG_A(getcode(fs, e), fs->freereg); + luaK_reserveregs(fs, 1); + } +} + + +void luaK_setoneret (FuncState *fs, expdesc *e) { + if (e->k == VCALL) { /* expression is an open function call? */ + e->k = VNONRELOC; + e->u.s.info = GETARG_A(getcode(fs, e)); + } + else if (e->k == VVARARG) { + SETARG_B(getcode(fs, e), 2); + e->k = VRELOCABLE; /* can relocate its simple result */ + } +} + + +void luaK_dischargevars (FuncState *fs, expdesc *e) { + switch (e->k) { + case VLOCAL: { + e->k = VNONRELOC; + break; + } + case VUPVAL: { + e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0); + e->k = VRELOCABLE; + break; + } + case VGLOBAL: { + e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info); + e->k = VRELOCABLE; + break; + } + case VINDEXED: { + freereg(fs, e->u.s.aux); + freereg(fs, e->u.s.info); + e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux); + e->k = VRELOCABLE; + break; + } + case VVARARG: + case VCALL: { + luaK_setoneret(fs, e); + break; + } + default: break; /* there is one value available (somewhere) */ + } +} + + +static int code_label (FuncState *fs, int A, int b, int jump) { + luaK_getlabel(fs); /* those instructions may be jump targets */ + return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); +} + + +static void discharge2reg (FuncState *fs, expdesc *e, int reg) { + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: { + luaK_nil(fs, reg, 1); + break; + } + case VFALSE: case VTRUE: { + luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); + break; + } + case VK: { + luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info); + break; + } + case VKNUM: { + luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval)); + break; + } + case VRELOCABLE: { + Instruction *pc = &getcode(fs, e); + SETARG_A(*pc, reg); + break; + } + case VNONRELOC: { + if (reg != e->u.s.info) + luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0); + break; + } + default: { + lua_assert(e->k == VVOID || e->k == VJMP); + return; /* nothing to do... */ + } + } + e->u.s.info = reg; + e->k = VNONRELOC; +} + + +static void discharge2anyreg (FuncState *fs, expdesc *e) { + if (e->k != VNONRELOC) { + luaK_reserveregs(fs, 1); + discharge2reg(fs, e, fs->freereg-1); + } +} + + +static void exp2reg (FuncState *fs, expdesc *e, int reg) { + discharge2reg(fs, e, reg); + if (e->k == VJMP) + luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */ + if (hasjumps(e)) { + int final; /* position after whole expression */ + int p_f = NO_JUMP; /* position of an eventual LOAD false */ + int p_t = NO_JUMP; /* position of an eventual LOAD true */ + if (need_value(fs, e->t) || need_value(fs, e->f)) { + int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); + p_f = code_label(fs, reg, 0, 1); + p_t = code_label(fs, reg, 1, 0); + luaK_patchtohere(fs, fj); + } + final = luaK_getlabel(fs); + patchlistaux(fs, e->f, final, reg, p_f); + patchlistaux(fs, e->t, final, reg, p_t); + } + e->f = e->t = NO_JUMP; + e->u.s.info = reg; + e->k = VNONRELOC; +} + + +void luaK_exp2nextreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + freeexp(fs, e); + luaK_reserveregs(fs, 1); + exp2reg(fs, e, fs->freereg - 1); +} + + +int luaK_exp2anyreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + if (e->k == VNONRELOC) { + if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */ + if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */ + exp2reg(fs, e, e->u.s.info); /* put value on it */ + return e->u.s.info; + } + } + luaK_exp2nextreg(fs, e); /* default */ + return e->u.s.info; +} + + +void luaK_exp2val (FuncState *fs, expdesc *e) { + if (hasjumps(e)) + luaK_exp2anyreg(fs, e); + else + luaK_dischargevars(fs, e); +} + + +int luaK_exp2RK (FuncState *fs, expdesc *e) { + luaK_exp2val(fs, e); + switch (e->k) { + case VKNUM: + case VTRUE: + case VFALSE: + case VNIL: { + if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */ + e->u.s.info = (e->k == VNIL) ? nilK(fs) : + (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) : + boolK(fs, (e->k == VTRUE)); + e->k = VK; + return RKASK(e->u.s.info); + } + else break; + } + case 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 luaK_exp2anyreg(fs, e); +} + + +void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { + switch (var->k) { + case VLOCAL: { + freeexp(fs, ex); + exp2reg(fs, ex, var->u.s.info); + return; + } + case VUPVAL: { + int e = luaK_exp2anyreg(fs, ex); + luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0); + break; + } + case VGLOBAL: { + int e = luaK_exp2anyreg(fs, ex); + luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info); + break; + } + case VINDEXED: { + int e = luaK_exp2RK(fs, ex); + luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e); + break; + } + default: { + lua_assert(0); /* invalid var kind to store */ + break; + } + } + freeexp(fs, ex); +} + + +void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { + int func; + luaK_exp2anyreg(fs, e); + freeexp(fs, e); + func = fs->freereg; + luaK_reserveregs(fs, 2); + luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key)); + freeexp(fs, key); + e->u.s.info = func; + e->k = VNONRELOC; +} + + +static void invertjump (FuncState *fs, expdesc *e) { + Instruction *pc = getjumpcontrol(fs, e->u.s.info); + lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && + GET_OPCODE(*pc) != OP_TEST); + SETARG_A(*pc, !(GETARG_A(*pc))); +} + + +static int jumponcond (FuncState *fs, expdesc *e, int cond) { + if (e->k == VRELOCABLE) { + Instruction ie = getcode(fs, e); + if (GET_OPCODE(ie) == OP_NOT) { + fs->pc--; /* remove previous OP_NOT */ + return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); + } + /* else go through */ + } + discharge2anyreg(fs, e); + freeexp(fs, e); + return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond); +} + + +void luaK_goiftrue (FuncState *fs, expdesc *e) { + int pc; /* pc of last jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VK: case VKNUM: case VTRUE: { + pc = NO_JUMP; /* always true; do nothing */ + break; + } + case VFALSE: { + pc = luaK_jump(fs); /* always jump */ + break; + } + case VJMP: { + invertjump(fs, e); + pc = e->u.s.info; + break; + } + default: { + pc = jumponcond(fs, e, 0); + break; + } + } + luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ + luaK_patchtohere(fs, e->t); + e->t = NO_JUMP; +} + + +static void luaK_goiffalse (FuncState *fs, expdesc *e) { + int pc; /* pc of last jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: case VFALSE: { + pc = NO_JUMP; /* always false; do nothing */ + break; + } + case VTRUE: { + pc = luaK_jump(fs); /* always jump */ + break; + } + case VJMP: { + pc = e->u.s.info; + break; + } + default: { + pc = jumponcond(fs, e, 1); + break; + } + } + luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ + luaK_patchtohere(fs, e->f); + e->f = NO_JUMP; +} + + +static void codenot (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: case VFALSE: { + e->k = VTRUE; + break; + } + case VK: case VKNUM: case VTRUE: { + e->k = VFALSE; + break; + } + case VJMP: { + invertjump(fs, e); + break; + } + case VRELOCABLE: + case VNONRELOC: { + discharge2anyreg(fs, e); + freeexp(fs, e); + e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0); + e->k = VRELOCABLE; + break; + } + default: { + lua_assert(0); /* cannot happen */ + break; + } + } + /* interchange true and false lists */ + { int temp = e->f; e->f = e->t; e->t = temp; } + removevalues(fs, e->f); + removevalues(fs, e->t); +} + + +void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { + t->u.s.aux = luaK_exp2RK(fs, k); + t->k = VINDEXED; +} + + +static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { + lua_Number v1, v2, r; + if (!isnumeral(e1) || !isnumeral(e2)) return 0; + v1 = e1->u.nval; + v2 = e2->u.nval; + switch (op) { + case OP_ADD: r = luai_numadd(v1, v2); break; + case OP_SUB: r = luai_numsub(v1, v2); break; + case OP_MUL: r = luai_nummul(v1, v2); break; + case OP_DIV: + if (v2 == 0) return 0; /* do not attempt to divide by 0 */ + r = luai_numdiv(v1, v2); break; + case OP_MOD: + if (v2 == 0) return 0; /* do not attempt to divide by 0 */ + r = luai_nummod(v1, v2); break; + case OP_POW: r = luai_numpow(v1, v2); break; + case OP_UNM: r = luai_numunm(v1); break; + case OP_LEN: return 0; /* no constant folding for 'len' */ + default: lua_assert(0); r = 0; break; + } + if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */ + e1->u.nval = r; + return 1; +} + + +static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { + if (constfolding(op, e1, e2)) + return; + else { + int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0; + int o1 = luaK_exp2RK(fs, e1); + if (o1 > o2) { + freeexp(fs, e1); + freeexp(fs, e2); + } + else { + freeexp(fs, e2); + freeexp(fs, e1); + } + e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2); + e1->k = VRELOCABLE; + } +} + + +static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, + expdesc *e2) { + int o1 = luaK_exp2RK(fs, e1); + int o2 = luaK_exp2RK(fs, e2); + freeexp(fs, e2); + freeexp(fs, 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 = condjump(fs, op, cond, o1, o2); + e1->k = VJMP; +} + + +void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { + expdesc e2; + e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; + switch (op) { + case OPR_MINUS: { + if (!isnumeral(e)) + luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */ + codearith(fs, OP_UNM, e, &e2); + break; + } + case OPR_NOT: codenot(fs, e); break; + case OPR_LEN: { + luaK_exp2anyreg(fs, e); /* cannot operate on constants */ + codearith(fs, OP_LEN, e, &e2); + break; + } + default: lua_assert(0); + } +} + + +void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { + switch (op) { + case OPR_AND: { + luaK_goiftrue(fs, v); + break; + } + case OPR_OR: { + luaK_goiffalse(fs, v); + break; + } + case OPR_CONCAT: { + luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ + break; + } + case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: + case OPR_MOD: case OPR_POW: { + if (!isnumeral(v)) luaK_exp2RK(fs, v); + break; + } + default: { + luaK_exp2RK(fs, v); + break; + } + } +} + + +void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { + switch (op) { + case OPR_AND: { + lua_assert(e1->t == NO_JUMP); /* list must be closed */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e2->f, e1->f); + *e1 = *e2; + break; + } + case OPR_OR: { + lua_assert(e1->f == NO_JUMP); /* list must be closed */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e2->t, e1->t); + *e1 = *e2; + break; + } + case OPR_CONCAT: { + luaK_exp2val(fs, e2); + if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { + lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1); + freeexp(fs, e1); + SETARG_B(getcode(fs, e2), e1->u.s.info); + e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info; + } + else { + luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ + codearith(fs, OP_CONCAT, e1, e2); + } + break; + } + case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break; + case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break; + case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break; + case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break; + case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break; + case OPR_POW: codearith(fs, OP_POW, e1, e2); break; + case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break; + case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break; + case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break; + case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break; + case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break; + case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break; + default: lua_assert(0); + } +} + + +void luaK_fixline (FuncState *fs, int line) { + fs->f->lineinfo[fs->pc - 1] = line; +} + + +static int luaK_code (FuncState *fs, Instruction i, int line) { + Proto *f = fs->f; + dischargejpc(fs); /* `pc' will change */ + /* put new instruction in code array */ + luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction, + MAX_INT, "code size overflow"); + f->code[fs->pc] = i; + /* save corresponding line information */ + luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int, + MAX_INT, "code size overflow"); + f->lineinfo[fs->pc] = line; + return fs->pc++; +} + + +int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { + lua_assert(getOpMode(o) == iABC); + lua_assert(getBMode(o) != OpArgN || b == 0); + lua_assert(getCMode(o) != OpArgN || c == 0); + return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline); +} + + +int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { + lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); + lua_assert(getCMode(o) == OpArgN); + return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline); +} + + +void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { + int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; + int b = (tostore == LUA_MULTRET) ? 0 : tostore; + lua_assert(tostore != 0); + if (c <= MAXARG_C) + luaK_codeABC(fs, OP_SETLIST, base, b, c); + else { + luaK_codeABC(fs, OP_SETLIST, base, b, 0); + luaK_code(fs, cast(Instruction, c), fs->ls->lastline); + } + fs->freereg = base + 1; /* free registers with list values */ +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/lcode.h b/vscript/languages/lua/lua-5.1.4/src/lcode.h new file mode 100644 index 00000000..b941c607 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lcode.h @@ -0,0 +1,76 @@ +/* +** $Id: lcode.h,v 1.48.1.1 2007/12/27 13:02:25 roberto Exp $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lcode_h +#define lcode_h + +#include "llex.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" + + +/* +** Marks the end of a patch list. It is an invalid value both as an absolute +** address, and as a list link (would link an element to itself). +*/ +#define NO_JUMP (-1) + + +/* +** grep "ORDER OPR" if you change these enums +*/ +typedef enum BinOpr { + OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, + OPR_CONCAT, + OPR_NE, OPR_EQ, + OPR_LT, OPR_LE, OPR_GT, OPR_GE, + OPR_AND, OPR_OR, + OPR_NOBINOPR +} BinOpr; + + +typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; + + +#define getcode(fs,e) ((fs)->f->code[(e)->u.s.info]) + +#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) + +#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) + +LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); +LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); +LUAI_FUNC void luaK_fixline (FuncState *fs, int line); +LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); +LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); +LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); +LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); +LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); +LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); +LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); +LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); +LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); +LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_jump (FuncState *fs); +LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); +LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); +LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); +LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); +LUAI_FUNC int luaK_getlabel (FuncState *fs); +LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); +LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); +LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); +LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); + + +#endif diff --git a/vscript/languages/lua/lua-5.1.4/src/ldblib.c b/vscript/languages/lua/lua-5.1.4/src/ldblib.c new file mode 100644 index 00000000..67de1222 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/ldblib.c @@ -0,0 +1,397 @@ +/* +** $Id: ldblib.c,v 1.104.1.3 2008/01/21 13:11:21 roberto Exp $ +** Interface from Lua to its debug API +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define ldblib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + +static int db_getregistry (lua_State *L) { + lua_pushvalue(L, LUA_REGISTRYINDEX); + return 1; +} + + +static int db_getmetatable (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); /* no metatable */ + } + return 1; +} + + +static int db_setmetatable (lua_State *L) { + int t = lua_type(L, 2); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, + "nil or table expected"); + lua_settop(L, 2); + lua_pushboolean(L, lua_setmetatable(L, 1)); + return 1; +} + + +static int db_getfenv (lua_State *L) { + lua_getfenv(L, 1); + return 1; +} + + +static int db_setfenv (lua_State *L) { + luaL_checktype(L, 2, LUA_TTABLE); + lua_settop(L, 2); + if (lua_setfenv(L, 1) == 0) + luaL_error(L, LUA_QL("setfenv") + " cannot change environment of given object"); + return 1; +} + + +static void settabss (lua_State *L, const char *i, const char *v) { + lua_pushstring(L, v); + lua_setfield(L, -2, i); +} + + +static void settabsi (lua_State *L, const char *i, int v) { + lua_pushinteger(L, v); + lua_setfield(L, -2, i); +} + + +static lua_State *getthread (lua_State *L, int *arg) { + if (lua_isthread(L, 1)) { + *arg = 1; + return lua_tothread(L, 1); + } + else { + *arg = 0; + return L; + } +} + + +static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { + if (L == L1) { + lua_pushvalue(L, -2); + lua_remove(L, -3); + } + else + lua_xmove(L1, L, 1); + lua_setfield(L, -2, fname); +} + + +static int db_getinfo (lua_State *L) { + lua_Debug ar; + int arg; + lua_State *L1 = getthread(L, &arg); + const char *options = luaL_optstring(L, arg+2, "flnSu"); + if (lua_isnumber(L, arg+1)) { + if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) { + lua_pushnil(L); /* level out of range */ + return 1; + } + } + else if (lua_isfunction(L, arg+1)) { + lua_pushfstring(L, ">%s", options); + options = lua_tostring(L, -1); + lua_pushvalue(L, arg+1); + lua_xmove(L, L1, 1); + } + else + return luaL_argerror(L, arg+1, "function or level expected"); + if (!lua_getinfo(L1, options, &ar)) + return luaL_argerror(L, arg+2, "invalid option"); + lua_createtable(L, 0, 2); + if (strchr(options, 'S')) { + settabss(L, "source", ar.source); + settabss(L, "short_src", ar.short_src); + settabsi(L, "linedefined", ar.linedefined); + settabsi(L, "lastlinedefined", ar.lastlinedefined); + settabss(L, "what", ar.what); + } + if (strchr(options, 'l')) + settabsi(L, "currentline", ar.currentline); + if (strchr(options, 'u')) + settabsi(L, "nups", ar.nups); + if (strchr(options, 'n')) { + settabss(L, "name", ar.name); + settabss(L, "namewhat", ar.namewhat); + } + if (strchr(options, 'L')) + treatstackoption(L, L1, "activelines"); + if (strchr(options, 'f')) + treatstackoption(L, L1, "func"); + return 1; /* return table */ +} + + +static int db_getlocal (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + const char *name; + if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2)); + if (name) { + lua_xmove(L1, L, 1); + lua_pushstring(L, name); + lua_pushvalue(L, -2); + return 2; + } + else { + lua_pushnil(L); + return 1; + } +} + + +static int db_setlocal (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + luaL_checkany(L, arg+3); + lua_settop(L, arg+3); + lua_xmove(L, L1, 1); + lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2))); + return 1; +} + + +static int auxupvalue (lua_State *L, int get) { + const char *name; + int n = luaL_checkint(L, 2); + luaL_checktype(L, 1, LUA_TFUNCTION); + if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */ + name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); + if (name == NULL) return 0; + lua_pushstring(L, name); + lua_insert(L, -(get+1)); + return get + 1; +} + + +static int db_getupvalue (lua_State *L) { + return auxupvalue(L, 1); +} + + +static int db_setupvalue (lua_State *L) { + luaL_checkany(L, 3); + return auxupvalue(L, 0); +} + + + +static const char KEY_HOOK = 'h'; + + +static void hookf (lua_State *L, lua_Debug *ar) { + static const char *const hooknames[] = + {"call", "return", "line", "count", "tail return"}; + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_pushlightuserdata(L, L); + lua_rawget(L, -2); + if (lua_isfunction(L, -1)) { + lua_pushstring(L, hooknames[(int)ar->event]); + if (ar->currentline >= 0) + lua_pushinteger(L, ar->currentline); + else lua_pushnil(L); + lua_assert(lua_getinfo(L, "lS", ar)); + lua_call(L, 2, 0); + } +} + + +static int makemask (const char *smask, int count) { + int mask = 0; + if (strchr(smask, 'c')) mask |= LUA_MASKCALL; + if (strchr(smask, 'r')) mask |= LUA_MASKRET; + if (strchr(smask, 'l')) mask |= LUA_MASKLINE; + if (count > 0) mask |= LUA_MASKCOUNT; + return mask; +} + + +static char *unmakemask (int mask, char *smask) { + int i = 0; + if (mask & LUA_MASKCALL) smask[i++] = 'c'; + if (mask & LUA_MASKRET) smask[i++] = 'r'; + if (mask & LUA_MASKLINE) smask[i++] = 'l'; + smask[i] = '\0'; + return smask; +} + + +static void gethooktable (lua_State *L) { + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_rawget(L, LUA_REGISTRYINDEX); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + lua_createtable(L, 0, 1); + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_pushvalue(L, -2); + lua_rawset(L, LUA_REGISTRYINDEX); + } +} + + +static int db_sethook (lua_State *L) { + int arg, mask, count; + lua_Hook func; + lua_State *L1 = getthread(L, &arg); + if (lua_isnoneornil(L, arg+1)) { + lua_settop(L, arg+1); + func = NULL; mask = 0; count = 0; /* turn off hooks */ + } + else { + const char *smask = luaL_checkstring(L, arg+2); + luaL_checktype(L, arg+1, LUA_TFUNCTION); + count = luaL_optint(L, arg+3, 0); + func = hookf; mask = makemask(smask, count); + } + gethooktable(L); + lua_pushlightuserdata(L, L1); + lua_pushvalue(L, arg+1); + lua_rawset(L, -3); /* set new hook */ + lua_pop(L, 1); /* remove hook table */ + lua_sethook(L1, func, mask, count); /* set hooks */ + return 0; +} + + +static int db_gethook (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + char buff[5]; + int mask = lua_gethookmask(L1); + lua_Hook hook = lua_gethook(L1); + if (hook != NULL && hook != hookf) /* external hook? */ + lua_pushliteral(L, "external hook"); + else { + gethooktable(L); + lua_pushlightuserdata(L, L1); + lua_rawget(L, -2); /* get hook */ + lua_remove(L, -2); /* remove hook table */ + } + lua_pushstring(L, unmakemask(mask, buff)); + lua_pushinteger(L, lua_gethookcount(L1)); + return 3; +} + + +static int db_debug (lua_State *L) { + for (;;) { + char buffer[250]; + fputs("lua_debug> ", stderr); + if (fgets(buffer, sizeof(buffer), stdin) == 0 || + strcmp(buffer, "cont\n") == 0) + return 0; + if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || + lua_pcall(L, 0, 0, 0)) { + fputs(lua_tostring(L, -1), stderr); + fputs("\n", stderr); + } + lua_settop(L, 0); /* remove eventual returns */ + } +} + + +#define LEVELS1 12 /* size of the first part of the stack */ +#define LEVELS2 10 /* size of the second part of the stack */ + +static int db_errorfb (lua_State *L) { + int level; + int firstpart = 1; /* still before eventual `...' */ + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + if (lua_isnumber(L, arg+2)) { + level = (int)lua_tointeger(L, arg+2); + lua_pop(L, 1); + } + else + level = (L == L1) ? 1 : 0; /* level 0 may be this own function */ + if (lua_gettop(L) == arg) + lua_pushliteral(L, ""); + else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */ + else lua_pushliteral(L, "\n"); + lua_pushliteral(L, "stack traceback:"); + while (lua_getstack(L1, level++, &ar)) { + if (level > LEVELS1 && firstpart) { + /* no more than `LEVELS2' more levels? */ + if (!lua_getstack(L1, level+LEVELS2, &ar)) + level--; /* keep going */ + else { + lua_pushliteral(L, "\n\t..."); /* too many levels */ + while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */ + level++; + } + firstpart = 0; + continue; + } + lua_pushliteral(L, "\n\t"); + lua_getinfo(L1, "Snl", &ar); + lua_pushfstring(L, "%s:", ar.short_src); + if (ar.currentline > 0) + lua_pushfstring(L, "%d:", ar.currentline); + if (*ar.namewhat != '\0') /* is there a name? */ + lua_pushfstring(L, " in function " LUA_QS, ar.name); + else { + if (*ar.what == 'm') /* main? */ + lua_pushfstring(L, " in main chunk"); + else if (*ar.what == 'C' || *ar.what == 't') + lua_pushliteral(L, " ?"); /* C function or tail call */ + else + lua_pushfstring(L, " in function <%s:%d>", + ar.short_src, ar.linedefined); + } + lua_concat(L, lua_gettop(L) - arg); + } + lua_concat(L, lua_gettop(L) - arg); + return 1; +} + + +static const luaL_Reg dblib[] = { + {"debug", db_debug}, + {"getfenv", db_getfenv}, + {"gethook", db_gethook}, + {"getinfo", db_getinfo}, + {"getlocal", db_getlocal}, + {"getregistry", db_getregistry}, + {"getmetatable", db_getmetatable}, + {"getupvalue", db_getupvalue}, + {"setfenv", db_setfenv}, + {"sethook", db_sethook}, + {"setlocal", db_setlocal}, + {"setmetatable", db_setmetatable}, + {"setupvalue", db_setupvalue}, + {"traceback", db_errorfb}, + {NULL, NULL} +}; + + +LUALIB_API int luaopen_debug (lua_State *L) { + luaL_register(L, LUA_DBLIBNAME, dblib); + return 1; +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/ldebug.c b/vscript/languages/lua/lua-5.1.4/src/ldebug.c new file mode 100644 index 00000000..50ad3d38 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/ldebug.c @@ -0,0 +1,638 @@ +/* +** $Id: ldebug.c,v 2.29.1.6 2008/05/08 16:56:26 roberto Exp $ +** Debug Interface +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + + +#define ldebug_c +#define LUA_CORE + +#include "lua.h" + +#include "lapi.h" +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + + +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); + + +static int currentpc (lua_State *L, CallInfo *ci) { + if (!isLua(ci)) return -1; /* function is not a Lua function? */ + if (ci == L->ci) + ci->savedpc = L->savedpc; + return pcRel(ci->savedpc, ci_func(ci)->l.p); +} + + +static int currentline (lua_State *L, CallInfo *ci) { + int pc = currentpc(L, ci); + if (pc < 0) + return -1; /* only active lua functions have current-line information */ + else + return getline(ci_func(ci)->l.p, pc); +} + + +/* +** this function can be called asynchronous (e.g. during a signal) +*/ +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { + if (func == NULL || mask == 0) { /* turn off hooks? */ + mask = 0; + func = NULL; + } + L->hook = func; + L->basehookcount = count; + resethookcount(L); + L->hookmask = cast_byte(mask); + return 1; +} + + +LUA_API lua_Hook lua_gethook (lua_State *L) { + return L->hook; +} + + +LUA_API int lua_gethookmask (lua_State *L) { + return L->hookmask; +} + + +LUA_API int lua_gethookcount (lua_State *L) { + return L->basehookcount; +} + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { + int status; + CallInfo *ci; + lua_lock(L); + for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { + level--; + if (f_isLua(ci)) /* Lua function? */ + level -= ci->tailcalls; /* skip lost tail calls */ + } + if (level == 0 && ci > L->base_ci) { /* level found? */ + status = 1; + ar->i_ci = cast_int(ci - L->base_ci); + } + else if (level < 0) { /* level is of a lost tail call? */ + status = 1; + ar->i_ci = 0; + } + else status = 0; /* no such level */ + lua_unlock(L); + return status; +} + + +static Proto *getluaproto (CallInfo *ci) { + return (isLua(ci) ? ci_func(ci)->l.p : NULL); +} + + +static const char *findlocal (lua_State *L, CallInfo *ci, int n) { + const char *name; + Proto *fp = getluaproto(ci); + if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL) + return name; /* is a local variable in a Lua function */ + else { + StkId limit = (ci == L->ci) ? L->top : (ci+1)->func; + if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */ + return "(*temporary)"; + else + return NULL; + } +} + + +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { + CallInfo *ci = L->base_ci + ar->i_ci; + const char *name = findlocal(L, ci, n); + lua_lock(L); + if (name) + luaA_pushobject(L, ci->base + (n - 1)); + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { + CallInfo *ci = L->base_ci + ar->i_ci; + const char *name = findlocal(L, ci, n); + lua_lock(L); + if (name) + setobjs2s(L, ci->base + (n - 1), L->top - 1); + L->top--; /* pop value */ + lua_unlock(L); + return name; +} + + +static void funcinfo (lua_Debug *ar, Closure *cl) { + if (cl->c.isC) { + ar->source = "=[C]"; + ar->linedefined = -1; + ar->lastlinedefined = -1; + ar->what = "C"; + } + else { + ar->source = getstr(cl->l.p->source); + ar->linedefined = cl->l.p->linedefined; + ar->lastlinedefined = cl->l.p->lastlinedefined; + ar->what = (ar->linedefined == 0) ? "main" : "Lua"; + } + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); +} + + +static void info_tailcall (lua_Debug *ar) { + ar->name = ar->namewhat = ""; + ar->what = "tail"; + ar->lastlinedefined = ar->linedefined = ar->currentline = -1; + ar->source = "=(tail call)"; + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); + ar->nups = 0; +} + + +static void collectvalidlines (lua_State *L, Closure *f) { + if (f == NULL || f->c.isC) { + setnilvalue(L->top); + } + else { + Table *t = luaH_new(L, 0, 0); + int *lineinfo = f->l.p->lineinfo; + int i; + for (i=0; il.p->sizelineinfo; i++) + setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); + sethvalue(L, L->top, t); + } + incr_top(L); +} + + +static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, + Closure *f, CallInfo *ci) { + int status = 1; + if (f == NULL) { + info_tailcall(ar); + return status; + } + for (; *what; what++) { + switch (*what) { + case 'S': { + funcinfo(ar, f); + break; + } + case 'l': { + ar->currentline = (ci) ? currentline(L, ci) : -1; + break; + } + case 'u': { + ar->nups = f->c.nupvalues; + break; + } + case 'n': { + ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL; + if (ar->namewhat == NULL) { + ar->namewhat = ""; /* not found */ + ar->name = NULL; + } + break; + } + case 'L': + case 'f': /* handled by lua_getinfo */ + break; + default: status = 0; /* invalid option */ + } + } + return status; +} + + +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { + int status; + Closure *f = NULL; + CallInfo *ci = NULL; + lua_lock(L); + if (*what == '>') { + StkId func = L->top - 1; + luai_apicheck(L, ttisfunction(func)); + what++; /* skip the '>' */ + f = clvalue(func); + L->top--; /* pop function */ + } + else if (ar->i_ci != 0) { /* no tail call? */ + ci = L->base_ci + ar->i_ci; + lua_assert(ttisfunction(ci->func)); + f = clvalue(ci->func); + } + status = auxgetinfo(L, what, ar, f, ci); + if (strchr(what, 'f')) { + if (f == NULL) setnilvalue(L->top); + else setclvalue(L, L->top, f); + incr_top(L); + } + if (strchr(what, 'L')) + collectvalidlines(L, f); + lua_unlock(L); + return status; +} + + +/* +** {====================================================== +** Symbolic Execution and code checker +** ======================================================= +*/ + +#define check(x) if (!(x)) return 0; + +#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode) + +#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize) + + + +static int precheck (const Proto *pt) { + check(pt->maxstacksize <= MAXSTACK); + check(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize); + check(!(pt->is_vararg & VARARG_NEEDSARG) || + (pt->is_vararg & VARARG_HASARG)); + check(pt->sizeupvalues <= pt->nups); + check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0); + check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); + return 1; +} + + +#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1]) + +int luaG_checkopenop (Instruction i) { + switch (GET_OPCODE(i)) { + case OP_CALL: + case OP_TAILCALL: + case OP_RETURN: + case OP_SETLIST: { + check(GETARG_B(i) == 0); + return 1; + } + default: return 0; /* invalid instruction after an open call */ + } +} + + +static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) { + switch (mode) { + case OpArgN: check(r == 0); break; + case OpArgU: break; + case OpArgR: checkreg(pt, r); break; + case OpArgK: + check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize); + break; + } + return 1; +} + + +static Instruction symbexec (const Proto *pt, int lastpc, int reg) { + int pc; + int last; /* stores position of last instruction that changed `reg' */ + last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ + check(precheck(pt)); + for (pc = 0; pc < lastpc; pc++) { + Instruction i = pt->code[pc]; + OpCode op = GET_OPCODE(i); + int a = GETARG_A(i); + int b = 0; + int c = 0; + check(op < NUM_OPCODES); + checkreg(pt, a); + switch (getOpMode(op)) { + case iABC: { + b = GETARG_B(i); + c = GETARG_C(i); + check(checkArgMode(pt, b, getBMode(op))); + check(checkArgMode(pt, c, getCMode(op))); + break; + } + case iABx: { + b = GETARG_Bx(i); + if (getBMode(op) == OpArgK) check(b < pt->sizek); + break; + } + case iAsBx: { + b = GETARG_sBx(i); + if (getBMode(op) == OpArgR) { + int dest = pc+1+b; + check(0 <= dest && dest < pt->sizecode); + if (dest > 0) { + int j; + /* check that it does not jump to a setlist count; this + is tricky, because the count from a previous setlist may + have the same value of an invalid setlist; so, we must + go all the way back to the first of them (if any) */ + for (j = 0; j < dest; j++) { + Instruction d = pt->code[dest-1-j]; + if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) break; + } + /* if 'j' is even, previous value is not a setlist (even if + it looks like one) */ + check((j&1) == 0); + } + } + break; + } + } + if (testAMode(op)) { + if (a == reg) last = pc; /* change register `a' */ + } + if (testTMode(op)) { + check(pc+2 < pt->sizecode); /* check skip */ + check(GET_OPCODE(pt->code[pc+1]) == OP_JMP); + } + switch (op) { + case OP_LOADBOOL: { + if (c == 1) { /* does it jump? */ + check(pc+2 < pt->sizecode); /* check its jump */ + check(GET_OPCODE(pt->code[pc+1]) != OP_SETLIST || + GETARG_C(pt->code[pc+1]) != 0); + } + break; + } + case OP_LOADNIL: { + if (a <= reg && reg <= b) + last = pc; /* set registers from `a' to `b' */ + break; + } + case OP_GETUPVAL: + case OP_SETUPVAL: { + check(b < pt->nups); + break; + } + case OP_GETGLOBAL: + case OP_SETGLOBAL: { + check(ttisstring(&pt->k[b])); + break; + } + case OP_SELF: { + checkreg(pt, a+1); + if (reg == a+1) last = pc; + break; + } + case OP_CONCAT: { + check(b < c); /* at least two operands */ + break; + } + case OP_TFORLOOP: { + check(c >= 1); /* at least one result (control variable) */ + checkreg(pt, a+2+c); /* space for results */ + if (reg >= a+2) last = pc; /* affect all regs above its base */ + break; + } + case OP_FORLOOP: + case OP_FORPREP: + checkreg(pt, a+3); + /* go through */ + case OP_JMP: { + int dest = pc+1+b; + /* not full check and jump is forward and do not skip `lastpc'? */ + if (reg != NO_REG && pc < dest && dest <= lastpc) + pc += b; /* do the jump */ + break; + } + case OP_CALL: + case OP_TAILCALL: { + if (b != 0) { + checkreg(pt, a+b-1); + } + c--; /* c = num. returns */ + if (c == LUA_MULTRET) { + check(checkopenop(pt, pc)); + } + else if (c != 0) + checkreg(pt, a+c-1); + if (reg >= a) last = pc; /* affect all registers above base */ + break; + } + case OP_RETURN: { + b--; /* b = num. returns */ + if (b > 0) checkreg(pt, a+b-1); + break; + } + case OP_SETLIST: { + if (b > 0) checkreg(pt, a + b); + if (c == 0) { + pc++; + check(pc < pt->sizecode - 1); + } + break; + } + case OP_CLOSURE: { + int nup, j; + check(b < pt->sizep); + nup = pt->p[b]->nups; + check(pc + nup < pt->sizecode); + for (j = 1; j <= nup; j++) { + OpCode op1 = GET_OPCODE(pt->code[pc + j]); + check(op1 == OP_GETUPVAL || op1 == OP_MOVE); + } + if (reg != NO_REG) /* tracing? */ + pc += nup; /* do not 'execute' these pseudo-instructions */ + break; + } + case OP_VARARG: { + check((pt->is_vararg & VARARG_ISVARARG) && + !(pt->is_vararg & VARARG_NEEDSARG)); + b--; + if (b == LUA_MULTRET) check(checkopenop(pt, pc)); + checkreg(pt, a+b-1); + break; + } + default: break; + } + } + return pt->code[last]; +} + +#undef check +#undef checkjump +#undef checkreg + +/* }====================================================== */ + + +int luaG_checkcode (const Proto *pt) { + return (symbexec(pt, pt->sizecode, NO_REG) != 0); +} + + +static const char *kname (Proto *p, int c) { + if (ISK(c) && ttisstring(&p->k[INDEXK(c)])) + return svalue(&p->k[INDEXK(c)]); + else + return "?"; +} + + +static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, + const char **name) { + if (isLua(ci)) { /* a Lua function? */ + Proto *p = ci_func(ci)->l.p; + int pc = currentpc(L, ci); + Instruction i; + *name = luaF_getlocalname(p, stackpos+1, pc); + if (*name) /* is a local? */ + return "local"; + i = symbexec(p, pc, stackpos); /* try symbolic execution */ + lua_assert(pc != -1); + switch (GET_OPCODE(i)) { + case OP_GETGLOBAL: { + int g = GETARG_Bx(i); /* global index */ + lua_assert(ttisstring(&p->k[g])); + *name = svalue(&p->k[g]); + return "global"; + } + case OP_MOVE: { + int a = GETARG_A(i); + int b = GETARG_B(i); /* move from `b' to `a' */ + if (b < a) + return getobjname(L, ci, b, name); /* get name for `b' */ + break; + } + case OP_GETTABLE: { + int k = GETARG_C(i); /* key index */ + *name = kname(p, k); + return "field"; + } + case OP_GETUPVAL: { + int u = GETARG_B(i); /* upvalue index */ + *name = p->upvalues ? getstr(p->upvalues[u]) : "?"; + return "upvalue"; + } + case OP_SELF: { + int k = GETARG_C(i); /* key index */ + *name = kname(p, k); + return "method"; + } + default: break; + } + } + return NULL; /* no useful name found */ +} + + +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { + Instruction i; + if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1)) + return NULL; /* calling function is not Lua (or is unknown) */ + ci--; /* calling function */ + i = ci_func(ci)->l.p->code[currentpc(L, ci)]; + if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL || + GET_OPCODE(i) == OP_TFORLOOP) + return getobjname(L, ci, GETARG_A(i), name); + else + return NULL; /* no useful name can be found */ +} + + +/* only ANSI way to check whether a pointer points to an array */ +static int isinstack (CallInfo *ci, const TValue *o) { + StkId p; + for (p = ci->base; p < ci->top; p++) + if (o == p) return 1; + return 0; +} + + +void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { + const char *name = NULL; + const char *t = luaT_typenames[ttype(o)]; + const char *kind = (isinstack(L->ci, o)) ? + getobjname(L, L->ci, cast_int(o - L->base), &name) : + NULL; + if (kind) + luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", + op, kind, name, t); + else + luaG_runerror(L, "attempt to %s a %s value", op, t); +} + + +void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { + if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; + lua_assert(!ttisstring(p1) && !ttisnumber(p1)); + luaG_typeerror(L, p1, "concatenate"); +} + + +void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { + TValue temp; + if (luaV_tonumber(p1, &temp) == NULL) + p2 = p1; /* first operand is wrong */ + luaG_typeerror(L, p2, "perform arithmetic on"); +} + + +int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { + const char *t1 = luaT_typenames[ttype(p1)]; + const char *t2 = luaT_typenames[ttype(p2)]; + if (t1[2] == t2[2]) + luaG_runerror(L, "attempt to compare two %s values", t1); + else + luaG_runerror(L, "attempt to compare %s with %s", t1, t2); + return 0; +} + + +static void addinfo (lua_State *L, const char *msg) { + CallInfo *ci = L->ci; + if (isLua(ci)) { /* is Lua code? */ + char buff[LUA_IDSIZE]; /* add file:line information */ + int line = currentline(L, ci); + luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE); + luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); + } +} + + +void luaG_errormsg (lua_State *L) { + if (L->errfunc != 0) { /* is there an error handling function? */ + StkId errfunc = restorestack(L, L->errfunc); + if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); + setobjs2s(L, L->top, L->top - 1); /* move argument */ + setobjs2s(L, L->top - 1, errfunc); /* push function */ + incr_top(L); + luaD_call(L, L->top - 2, 1); /* call it */ + } + luaD_throw(L, LUA_ERRRUN); +} + + +void luaG_runerror (lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + addinfo(L, luaO_pushvfstring(L, fmt, argp)); + va_end(argp); + luaG_errormsg(L); +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/ldebug.h b/vscript/languages/lua/lua-5.1.4/src/ldebug.h new file mode 100644 index 00000000..ba28a972 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/ldebug.h @@ -0,0 +1,33 @@ +/* +** $Id: ldebug.h,v 2.3.1.1 2007/12/27 13:02:25 roberto Exp $ +** Auxiliary functions from Debug Interface module +** See Copyright Notice in lua.h +*/ + +#ifndef ldebug_h +#define ldebug_h + + +#include "lstate.h" + + +#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) + +#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) + +#define resethookcount(L) (L->hookcount = L->basehookcount) + + +LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o, + const char *opname); +LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2); +LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...); +LUAI_FUNC void luaG_errormsg (lua_State *L); +LUAI_FUNC int luaG_checkcode (const Proto *pt); +LUAI_FUNC int luaG_checkopenop (Instruction i); + +#endif diff --git a/vscript/languages/lua/lua-5.1.4/src/ldo.c b/vscript/languages/lua/lua-5.1.4/src/ldo.c new file mode 100644 index 00000000..8de05f72 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/ldo.c @@ -0,0 +1,518 @@ +/* +** $Id: ldo.c,v 2.38.1.3 2008/01/18 22:31:22 roberto Exp $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define ldo_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" +#include "lzio.h" + + + + +/* +** {====================================================== +** Error-recovery functions +** ======================================================= +*/ + + +/* chain list of long jump buffers */ +struct lua_longjmp { + struct lua_longjmp *previous; + luai_jmpbuf b; + volatile int status; /* error code */ +}; + + +void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { + switch (errcode) { + case LUA_ERRMEM: { + setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG)); + break; + } + case LUA_ERRERR: { + setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); + break; + } + case LUA_ERRSYNTAX: + case LUA_ERRRUN: { + setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ + break; + } + } + L->top = oldtop + 1; +} + + +static void restore_stack_limit (lua_State *L) { + lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); + if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */ + int inuse = cast_int(L->ci - L->base_ci); + if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */ + luaD_reallocCI(L, LUAI_MAXCALLS); + } +} + + +static void resetstack (lua_State *L, int status) { + L->ci = L->base_ci; + L->base = L->ci->base; + luaF_close(L, L->base); /* close eventual pending closures */ + luaD_seterrorobj(L, status, L->base); + L->nCcalls = L->baseCcalls; + L->allowhook = 1; + restore_stack_limit(L); + L->errfunc = 0; + L->errorJmp = NULL; +} + + +void luaD_throw (lua_State *L, int errcode) { + if (L->errorJmp) { + L->errorJmp->status = errcode; + LUAI_THROW(L, L->errorJmp); + } + else { + L->status = cast_byte(errcode); + if (G(L)->panic) { + resetstack(L, errcode); + lua_unlock(L); + G(L)->panic(L); + } + exit(EXIT_FAILURE); + } +} + + +int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { + struct lua_longjmp lj; + lj.status = 0; + lj.previous = L->errorJmp; /* chain new error handler */ + L->errorJmp = &lj; + LUAI_TRY(L, &lj, + (*f)(L, ud); + ); + L->errorJmp = lj.previous; /* restore old error handler */ + return lj.status; +} + +/* }====================================================== */ + + +static void correctstack (lua_State *L, TValue *oldstack) { + CallInfo *ci; + GCObject *up; + L->top = (L->top - oldstack) + L->stack; + for (up = L->openupval; up != NULL; up = up->gch.next) + gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; + for (ci = L->base_ci; ci <= L->ci; ci++) { + ci->top = (ci->top - oldstack) + L->stack; + ci->base = (ci->base - oldstack) + L->stack; + ci->func = (ci->func - oldstack) + L->stack; + } + L->base = (L->base - oldstack) + L->stack; +} + + +void luaD_reallocstack (lua_State *L, int newsize) { + TValue *oldstack = L->stack; + int realsize = newsize + 1 + EXTRA_STACK; + lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); + luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue); + L->stacksize = realsize; + L->stack_last = L->stack+newsize; + correctstack(L, oldstack); +} + + +void luaD_reallocCI (lua_State *L, int newsize) { + CallInfo *oldci = L->base_ci; + luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); + L->size_ci = newsize; + L->ci = (L->ci - oldci) + L->base_ci; + L->end_ci = L->base_ci + L->size_ci - 1; +} + + +void luaD_growstack (lua_State *L, int n) { + if (n <= L->stacksize) /* double size is enough? */ + luaD_reallocstack(L, 2*L->stacksize); + else + luaD_reallocstack(L, L->stacksize + n); +} + + +static CallInfo *growCI (lua_State *L) { + if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */ + luaD_throw(L, LUA_ERRERR); + else { + luaD_reallocCI(L, 2*L->size_ci); + if (L->size_ci > LUAI_MAXCALLS) + luaG_runerror(L, "stack overflow"); + } + return ++L->ci; +} + + +void luaD_callhook (lua_State *L, int event, int line) { + lua_Hook hook = L->hook; + if (hook && L->allowhook) { + ptrdiff_t top = savestack(L, L->top); + ptrdiff_t ci_top = savestack(L, L->ci->top); + lua_Debug ar; + ar.event = event; + ar.currentline = line; + if (event == LUA_HOOKTAILRET) + ar.i_ci = 0; /* tail call; no debug information about it */ + else + ar.i_ci = cast_int(L->ci - L->base_ci); + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + L->ci->top = L->top + LUA_MINSTACK; + lua_assert(L->ci->top <= L->stack_last); + L->allowhook = 0; /* cannot call hooks inside a hook */ + lua_unlock(L); + (*hook)(L, &ar); + lua_lock(L); + lua_assert(!L->allowhook); + L->allowhook = 1; + L->ci->top = restorestack(L, ci_top); + L->top = restorestack(L, top); + } +} + + +static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { + int i; + int nfixargs = p->numparams; + Table *htab = NULL; + StkId base, fixed; + for (; actual < nfixargs; ++actual) + setnilvalue(L->top++); +#if defined(LUA_COMPAT_VARARG) + if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */ + int nvar = actual - nfixargs; /* number of extra arguments */ + lua_assert(p->is_vararg & VARARG_HASARG); + luaC_checkGC(L); + htab = luaH_new(L, nvar, 1); /* create `arg' table */ + for (i=0; itop - nvar + i); + /* store counter in field `n' */ + setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar)); + } +#endif + /* move fixed parameters to final position */ + fixed = L->top - actual; /* first fixed argument */ + base = L->top; /* final position of first argument */ + for (i=0; itop++, fixed+i); + setnilvalue(fixed+i); + } + /* add `arg' parameter */ + if (htab) { + sethvalue(L, L->top++, htab); + lua_assert(iswhite(obj2gco(htab))); + } + return base; +} + + +static StkId tryfuncTM (lua_State *L, StkId func) { + const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); + StkId p; + ptrdiff_t funcr = savestack(L, func); + if (!ttisfunction(tm)) + luaG_typeerror(L, func, "call"); + /* Open a hole inside the stack at `func' */ + for (p = L->top; p > func; p--) setobjs2s(L, p, p-1); + incr_top(L); + func = restorestack(L, funcr); /* previous call may change stack */ + setobj2s(L, func, tm); /* tag method is the new function to be called */ + return func; +} + + + +#define inc_ci(L) \ + ((L->ci == L->end_ci) ? growCI(L) : \ + (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci)) + + +int luaD_precall (lua_State *L, StkId func, int nresults) { + LClosure *cl; + ptrdiff_t funcr; + if (!ttisfunction(func)) /* `func' is not a function? */ + func = tryfuncTM(L, func); /* check the `function' tag method */ + funcr = savestack(L, func); + cl = &clvalue(func)->l; + L->ci->savedpc = L->savedpc; + if (!cl->isC) { /* Lua function? prepare its call */ + CallInfo *ci; + StkId st, base; + Proto *p = cl->p; + luaD_checkstack(L, p->maxstacksize); + func = restorestack(L, funcr); + if (!p->is_vararg) { /* no varargs? */ + base = func + 1; + if (L->top > base + p->numparams) + L->top = base + p->numparams; + } + else { /* vararg function */ + int nargs = cast_int(L->top - func) - 1; + base = adjust_varargs(L, p, nargs); + func = restorestack(L, funcr); /* previous call may change the stack */ + } + ci = inc_ci(L); /* now `enter' new function */ + ci->func = func; + L->base = ci->base = base; + ci->top = L->base + p->maxstacksize; + lua_assert(ci->top <= L->stack_last); + L->savedpc = p->code; /* starting point */ + ci->tailcalls = 0; + ci->nresults = nresults; + for (st = L->top; st < ci->top; st++) + setnilvalue(st); + L->top = ci->top; + if (L->hookmask & LUA_MASKCALL) { + L->savedpc++; /* hooks assume 'pc' is already incremented */ + luaD_callhook(L, LUA_HOOKCALL, -1); + L->savedpc--; /* correct 'pc' */ + } + return PCRLUA; + } + else { /* if is a C function, call it */ + CallInfo *ci; + int n; + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + ci = inc_ci(L); /* now `enter' new function */ + ci->func = restorestack(L, funcr); + L->base = ci->base = ci->func + 1; + ci->top = L->top + LUA_MINSTACK; + lua_assert(ci->top <= L->stack_last); + ci->nresults = nresults; + if (L->hookmask & LUA_MASKCALL) + luaD_callhook(L, LUA_HOOKCALL, -1); + lua_unlock(L); + n = (*curr_func(L)->c.f)(L); /* do the actual call */ + lua_lock(L); + if (n < 0) /* yielding? */ + return PCRYIELD; + else { + luaD_poscall(L, L->top - n); + return PCRC; + } + } +} + + +static StkId callrethooks (lua_State *L, StkId firstResult) { + ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ + luaD_callhook(L, LUA_HOOKRET, -1); + if (f_isLua(L->ci)) { /* Lua function? */ + while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */ + luaD_callhook(L, LUA_HOOKTAILRET, -1); + } + return restorestack(L, fr); +} + + +int luaD_poscall (lua_State *L, StkId firstResult) { + StkId res; + int wanted, i; + CallInfo *ci; + if (L->hookmask & LUA_MASKRET) + firstResult = callrethooks(L, firstResult); + ci = L->ci--; + res = ci->func; /* res == final position of 1st result */ + wanted = ci->nresults; + L->base = (ci - 1)->base; /* restore base */ + L->savedpc = (ci - 1)->savedpc; /* restore savedpc */ + /* move results to correct place */ + for (i = wanted; i != 0 && firstResult < L->top; i--) + setobjs2s(L, res++, firstResult++); + while (i-- > 0) + setnilvalue(res++); + L->top = res; + return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ +} + + +/* +** Call a function (C or Lua). The function to be called is at *func. +** The arguments are on the stack, right after the function. +** When returns, all the results are on the stack, starting at the original +** function position. +*/ +void luaD_call (lua_State *L, StkId func, int nResults) { + if (++L->nCcalls >= LUAI_MAXCCALLS) { + if (L->nCcalls == LUAI_MAXCCALLS) + luaG_runerror(L, "C stack overflow"); + else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) + luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ + } + if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */ + luaV_execute(L, 1); /* call it */ + L->nCcalls--; + luaC_checkGC(L); +} + + +static void resume (lua_State *L, void *ud) { + StkId firstArg = cast(StkId, ud); + CallInfo *ci = L->ci; + if (L->status == 0) { /* start coroutine? */ + lua_assert(ci == L->base_ci && firstArg > L->base); + if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA) + return; + } + else { /* resuming from previous yield */ + lua_assert(L->status == LUA_YIELD); + L->status = 0; + if (!f_isLua(ci)) { /* `common' yield? */ + /* finish interrupted execution of `OP_CALL' */ + lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || + GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL); + if (luaD_poscall(L, firstArg)) /* complete it... */ + L->top = L->ci->top; /* and correct top if not multiple results */ + } + else /* yielded inside a hook: just continue its execution */ + L->base = L->ci->base; + } + luaV_execute(L, cast_int(L->ci - L->base_ci)); +} + + +static int resume_error (lua_State *L, const char *msg) { + L->top = L->ci->base; + setsvalue2s(L, L->top, luaS_new(L, msg)); + incr_top(L); + lua_unlock(L); + return LUA_ERRRUN; +} + + +LUA_API int lua_resume (lua_State *L, int nargs) { + int status; + lua_lock(L); + if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci)) + return resume_error(L, "cannot resume non-suspended coroutine"); + if (L->nCcalls >= LUAI_MAXCCALLS) + return resume_error(L, "C stack overflow"); + luai_userstateresume(L, nargs); + lua_assert(L->errfunc == 0); + L->baseCcalls = ++L->nCcalls; + status = luaD_rawrunprotected(L, resume, L->top - nargs); + if (status != 0) { /* error? */ + L->status = cast_byte(status); /* mark thread as `dead' */ + luaD_seterrorobj(L, status, L->top); + L->ci->top = L->top; + } + else { + lua_assert(L->nCcalls == L->baseCcalls); + status = L->status; + } + --L->nCcalls; + lua_unlock(L); + return status; +} + + +LUA_API int lua_yield (lua_State *L, int nresults) { + luai_userstateyield(L, nresults); + lua_lock(L); + if (L->nCcalls > L->baseCcalls) + luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); + L->base = L->top - nresults; /* protect stack slots below */ + L->status = LUA_YIELD; + lua_unlock(L); + return -1; +} + + +int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t old_top, ptrdiff_t ef) { + int status; + unsigned short oldnCcalls = L->nCcalls; + ptrdiff_t old_ci = saveci(L, L->ci); + lu_byte old_allowhooks = L->allowhook; + ptrdiff_t old_errfunc = L->errfunc; + L->errfunc = ef; + status = luaD_rawrunprotected(L, func, u); + if (status != 0) { /* an error occurred? */ + StkId oldtop = restorestack(L, old_top); + luaF_close(L, oldtop); /* close eventual pending closures */ + luaD_seterrorobj(L, status, oldtop); + L->nCcalls = oldnCcalls; + L->ci = restoreci(L, old_ci); + L->base = L->ci->base; + L->savedpc = L->ci->savedpc; + L->allowhook = old_allowhooks; + restore_stack_limit(L); + } + L->errfunc = old_errfunc; + return status; +} + + + +/* +** Execute a protected parser. +*/ +struct SParser { /* data to `f_parser' */ + ZIO *z; + Mbuffer buff; /* buffer to be used by the scanner */ + const char *name; +}; + +static void f_parser (lua_State *L, void *ud) { + int i; + Proto *tf; + Closure *cl; + struct SParser *p = cast(struct SParser *, ud); + int c = luaZ_lookahead(p->z); + luaC_checkGC(L); + tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, + &p->buff, p->name); + cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); + cl->l.p = tf; + for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ + cl->l.upvals[i] = luaF_newupval(L); + setclvalue(L, L->top, cl); + incr_top(L); +} + + +int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) { + struct SParser p; + int status; + p.z = z; p.name = name; + luaZ_initbuffer(L, &p.buff); + status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); + luaZ_freebuffer(L, &p.buff); + return status; +} + + diff --git a/vscript/languages/lua/lua-5.1.4/src/ldo.h b/vscript/languages/lua/lua-5.1.4/src/ldo.h new file mode 100644 index 00000000..98fddac5 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/ldo.h @@ -0,0 +1,57 @@ +/* +** $Id: ldo.h,v 2.7.1.1 2007/12/27 13:02:25 roberto Exp $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + +#ifndef ldo_h +#define ldo_h + + +#include "lobject.h" +#include "lstate.h" +#include "lzio.h" + + +#define luaD_checkstack(L,n) \ + if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \ + luaD_growstack(L, n); \ + else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); + + +#define incr_top(L) {luaD_checkstack(L,1); L->top++;} + +#define savestack(L,p) ((char *)(p) - (char *)L->stack) +#define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) + +#define saveci(L,p) ((char *)(p) - (char *)L->base_ci) +#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n))) + + +/* results from luaD_precall */ +#define PCRLUA 0 /* initiated a call to a Lua function */ +#define PCRC 1 /* did a call to a C function */ +#define PCRYIELD 2 /* C funtion yielded */ + + +/* type of protected functions, to be ran by `runprotected' */ +typedef void (*Pfunc) (lua_State *L, void *ud); + +LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); +LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line); +LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); +LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); +LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t oldtop, ptrdiff_t ef); +LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult); +LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize); +LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); +LUAI_FUNC void luaD_growstack (lua_State *L, int n); + +LUAI_FUNC void luaD_throw (lua_State *L, int errcode); +LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); + +LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); + +#endif + diff --git a/vscript/languages/lua/lua-5.1.4/src/ldump.c b/vscript/languages/lua/lua-5.1.4/src/ldump.c new file mode 100644 index 00000000..c9d3d487 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/ldump.c @@ -0,0 +1,164 @@ +/* +** $Id: ldump.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ +** save precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#include + +#define ldump_c +#define LUA_CORE + +#include "lua.h" + +#include "lobject.h" +#include "lstate.h" +#include "lundump.h" + +typedef struct { + lua_State* L; + lua_Writer writer; + void* data; + int strip; + int status; +} DumpState; + +#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) +#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) + +static void DumpBlock(const void* b, size_t size, DumpState* D) +{ + if (D->status==0) + { + lua_unlock(D->L); + D->status=(*D->writer)(D->L,b,size,D->data); + lua_lock(D->L); + } +} + +static void DumpChar(int y, DumpState* D) +{ + char x=(char)y; + DumpVar(x,D); +} + +static void DumpInt(int x, DumpState* D) +{ + DumpVar(x,D); +} + +static void DumpNumber(lua_Number x, DumpState* D) +{ + DumpVar(x,D); +} + +static void DumpVector(const void* b, int n, size_t size, DumpState* D) +{ + DumpInt(n,D); + DumpMem(b,n,size,D); +} + +static void DumpString(const TString* s, DumpState* D) +{ + if (s==NULL || getstr(s)==NULL) + { + size_t size=0; + DumpVar(size,D); + } + else + { + size_t size=s->tsv.len+1; /* include trailing '\0' */ + DumpVar(size,D); + DumpBlock(getstr(s),size,D); + } +} + +#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) + +static void DumpFunction(const Proto* f, const TString* p, DumpState* D); + +static void DumpConstants(const Proto* f, DumpState* D) +{ + int i,n=f->sizek; + DumpInt(n,D); + for (i=0; ik[i]; + DumpChar(ttype(o),D); + switch (ttype(o)) + { + case LUA_TNIL: + break; + case LUA_TBOOLEAN: + DumpChar(bvalue(o),D); + break; + case LUA_TNUMBER: + DumpNumber(nvalue(o),D); + break; + case LUA_TSTRING: + DumpString(rawtsvalue(o),D); + break; + default: + lua_assert(0); /* cannot happen */ + break; + } + } + n=f->sizep; + DumpInt(n,D); + for (i=0; ip[i],f->source,D); +} + +static void DumpDebug(const Proto* f, DumpState* D) +{ + int i,n; + n= (D->strip) ? 0 : f->sizelineinfo; + DumpVector(f->lineinfo,n,sizeof(int),D); + n= (D->strip) ? 0 : f->sizelocvars; + DumpInt(n,D); + for (i=0; ilocvars[i].varname,D); + DumpInt(f->locvars[i].startpc,D); + DumpInt(f->locvars[i].endpc,D); + } + n= (D->strip) ? 0 : f->sizeupvalues; + DumpInt(n,D); + for (i=0; iupvalues[i],D); +} + +static void DumpFunction(const Proto* f, const TString* p, DumpState* D) +{ + DumpString((f->source==p || D->strip) ? NULL : f->source,D); + DumpInt(f->linedefined,D); + DumpInt(f->lastlinedefined,D); + DumpChar(f->nups,D); + DumpChar(f->numparams,D); + DumpChar(f->is_vararg,D); + DumpChar(f->maxstacksize,D); + DumpCode(f,D); + DumpConstants(f,D); + DumpDebug(f,D); +} + +static void DumpHeader(DumpState* D) +{ + char h[LUAC_HEADERSIZE]; + luaU_header(h); + DumpBlock(h,LUAC_HEADERSIZE,D); +} + +/* +** dump Lua function as precompiled chunk +*/ +int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) +{ + DumpState D; + D.L=L; + D.writer=w; + D.data=data; + D.strip=strip; + D.status=0; + DumpHeader(&D); + DumpFunction(f,NULL,&D); + return D.status; +} diff --git a/vscript/languages/lua/lua-5.1.4/src/lfunc.c b/vscript/languages/lua/lua-5.1.4/src/lfunc.c new file mode 100644 index 00000000..813e88f5 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lfunc.c @@ -0,0 +1,174 @@ +/* +** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 roberto Exp $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + + +#include + +#define lfunc_c +#define LUA_CORE + +#include "lua.h" + +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) { + Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); + luaC_link(L, obj2gco(c), LUA_TFUNCTION); + c->c.isC = 1; + c->c.env = e; + c->c.nupvalues = cast_byte(nelems); + return c; +} + + +Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) { + Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); + luaC_link(L, obj2gco(c), LUA_TFUNCTION); + c->l.isC = 0; + c->l.env = e; + c->l.nupvalues = cast_byte(nelems); + while (nelems--) c->l.upvals[nelems] = NULL; + return c; +} + + +UpVal *luaF_newupval (lua_State *L) { + UpVal *uv = luaM_new(L, UpVal); + luaC_link(L, obj2gco(uv), LUA_TUPVAL); + uv->v = &uv->u.value; + setnilvalue(uv->v); + return uv; +} + + +UpVal *luaF_findupval (lua_State *L, StkId level) { + global_State *g = G(L); + GCObject **pp = &L->openupval; + UpVal *p; + UpVal *uv; + while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) { + lua_assert(p->v != &p->u.value); + if (p->v == level) { /* found a corresponding upvalue? */ + if (isdead(g, obj2gco(p))) /* is it dead? */ + changewhite(obj2gco(p)); /* ressurect it */ + return p; + } + pp = &p->next; + } + uv = luaM_new(L, UpVal); /* not found: create a new one */ + uv->tt = LUA_TUPVAL; + uv->marked = luaC_white(g); + uv->v = level; /* current value lives in the stack */ + uv->next = *pp; /* chain it in the proper position */ + *pp = obj2gco(uv); + uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ + uv->u.l.next = g->uvhead.u.l.next; + uv->u.l.next->u.l.prev = uv; + g->uvhead.u.l.next = uv; + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + return uv; +} + + +static void unlinkupval (UpVal *uv) { + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ + uv->u.l.prev->u.l.next = uv->u.l.next; +} + + +void luaF_freeupval (lua_State *L, UpVal *uv) { + if (uv->v != &uv->u.value) /* is it open? */ + unlinkupval(uv); /* remove from open list */ + luaM_free(L, uv); /* free upvalue */ +} + + +void luaF_close (lua_State *L, StkId level) { + UpVal *uv; + global_State *g = G(L); + while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) { + GCObject *o = obj2gco(uv); + lua_assert(!isblack(o) && uv->v != &uv->u.value); + L->openupval = uv->next; /* remove from `open' list */ + if (isdead(g, o)) + luaF_freeupval(L, uv); /* free upvalue */ + else { + unlinkupval(uv); + setobj(L, &uv->u.value, uv->v); + uv->v = &uv->u.value; /* now current value lives here */ + luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ + } + } +} + + +Proto *luaF_newproto (lua_State *L) { + Proto *f = luaM_new(L, Proto); + luaC_link(L, obj2gco(f), LUA_TPROTO); + f->k = NULL; + f->sizek = 0; + f->p = NULL; + f->sizep = 0; + f->code = NULL; + f->sizecode = 0; + f->sizelineinfo = 0; + f->sizeupvalues = 0; + f->nups = 0; + f->upvalues = NULL; + f->numparams = 0; + f->is_vararg = 0; + f->maxstacksize = 0; + f->lineinfo = NULL; + f->sizelocvars = 0; + f->locvars = NULL; + f->linedefined = 0; + f->lastlinedefined = 0; + f->source = NULL; + return f; +} + + +void luaF_freeproto (lua_State *L, Proto *f) { + luaM_freearray(L, f->code, f->sizecode, Instruction); + luaM_freearray(L, f->p, f->sizep, Proto *); + luaM_freearray(L, f->k, f->sizek, TValue); + luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); + luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); + luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); + luaM_free(L, f); +} + + +void luaF_freeclosure (lua_State *L, Closure *c) { + int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : + sizeLclosure(c->l.nupvalues); + luaM_freemem(L, c, size); +} + + +/* +** Look for n-th local variable at line `line' in function `func'. +** Returns NULL if not found. +*/ +const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { + int i; + for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { + if (pc < f->locvars[i].endpc) { /* is variable active? */ + local_number--; + if (local_number == 0) + return getstr(f->locvars[i].varname); + } + } + return NULL; /* not found */ +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/lfunc.h b/vscript/languages/lua/lua-5.1.4/src/lfunc.h new file mode 100644 index 00000000..a68cf515 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lfunc.h @@ -0,0 +1,34 @@ +/* +** $Id: lfunc.h,v 2.4.1.1 2007/12/27 13:02:25 roberto Exp $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + +#ifndef lfunc_h +#define lfunc_h + + +#include "lobject.h" + + +#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ + cast(int, sizeof(TValue)*((n)-1))) + +#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ + cast(int, sizeof(TValue *)*((n)-1))) + + +LUAI_FUNC Proto *luaF_newproto (lua_State *L); +LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e); +LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e); +LUAI_FUNC UpVal *luaF_newupval (lua_State *L); +LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); +LUAI_FUNC void luaF_close (lua_State *L, StkId level); +LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); +LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c); +LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv); +LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, + int pc); + + +#endif diff --git a/vscript/languages/lua/lua-5.1.4/src/lgc.c b/vscript/languages/lua/lua-5.1.4/src/lgc.c new file mode 100644 index 00000000..d9e0b782 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lgc.c @@ -0,0 +1,711 @@ +/* +** $Id: lgc.c,v 2.38.1.1 2007/12/27 13:02:25 roberto Exp $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#include + +#define lgc_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +#define GCSTEPSIZE 1024u +#define GCSWEEPMAX 40 +#define GCSWEEPCOST 10 +#define GCFINALIZECOST 100 + + +#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS)) + +#define makewhite(g,x) \ + ((x)->gch.marked = cast_byte(((x)->gch.marked & maskmarks) | luaC_white(g))) + +#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) +#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT) + +#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT) + + +#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT) +#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT) + + +#define KEYWEAK bitmask(KEYWEAKBIT) +#define VALUEWEAK bitmask(VALUEWEAKBIT) + + + +#define markvalue(g,o) { checkconsistency(o); \ + if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); } + +#define markobject(g,t) { if (iswhite(obj2gco(t))) \ + reallymarkobject(g, obj2gco(t)); } + + +#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause) + + +static void removeentry (Node *n) { + lua_assert(ttisnil(gval(n))); + if (iscollectable(gkey(n))) + setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */ +} + + +static void reallymarkobject (global_State *g, GCObject *o) { + lua_assert(iswhite(o) && !isdead(g, o)); + white2gray(o); + switch (o->gch.tt) { + case LUA_TSTRING: { + return; + } + case LUA_TUSERDATA: { + Table *mt = gco2u(o)->metatable; + gray2black(o); /* udata are never gray */ + if (mt) markobject(g, mt); + markobject(g, gco2u(o)->env); + return; + } + case LUA_TUPVAL: { + UpVal *uv = gco2uv(o); + markvalue(g, uv->v); + if (uv->v == &uv->u.value) /* closed? */ + gray2black(o); /* open upvalues are never black */ + return; + } + case LUA_TFUNCTION: { + gco2cl(o)->c.gclist = g->gray; + g->gray = o; + break; + } + case LUA_TTABLE: { + gco2h(o)->gclist = g->gray; + g->gray = o; + break; + } + case LUA_TTHREAD: { + gco2th(o)->gclist = g->gray; + g->gray = o; + break; + } + case LUA_TPROTO: { + gco2p(o)->gclist = g->gray; + g->gray = o; + break; + } + default: lua_assert(0); + } +} + + +static void marktmu (global_State *g) { + GCObject *u = g->tmudata; + if (u) { + do { + u = u->gch.next; + makewhite(g, u); /* may be marked, if left from previous GC */ + reallymarkobject(g, u); + } while (u != g->tmudata); + } +} + + +/* move `dead' udata that need finalization to list `tmudata' */ +size_t luaC_separateudata (lua_State *L, int all) { + global_State *g = G(L); + size_t deadmem = 0; + GCObject **p = &g->mainthread->next; + GCObject *curr; + while ((curr = *p) != NULL) { + if (!(iswhite(curr) || all) || isfinalized(gco2u(curr))) + p = &curr->gch.next; /* don't bother with them */ + else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) { + markfinalized(gco2u(curr)); /* don't need finalization */ + p = &curr->gch.next; + } + else { /* must call its gc method */ + deadmem += sizeudata(gco2u(curr)); + markfinalized(gco2u(curr)); + *p = curr->gch.next; + /* link `curr' at the end of `tmudata' list */ + if (g->tmudata == NULL) /* list is empty? */ + g->tmudata = curr->gch.next = curr; /* creates a circular list */ + else { + curr->gch.next = g->tmudata->gch.next; + g->tmudata->gch.next = curr; + g->tmudata = curr; + } + } + } + return deadmem; +} + + +static int traversetable (global_State *g, Table *h) { + int i; + int weakkey = 0; + int weakvalue = 0; + const TValue *mode; + if (h->metatable) + markobject(g, h->metatable); + mode = gfasttm(g, h->metatable, TM_MODE); + if (mode && ttisstring(mode)) { /* is there a weak mode? */ + weakkey = (strchr(svalue(mode), 'k') != NULL); + weakvalue = (strchr(svalue(mode), 'v') != NULL); + if (weakkey || weakvalue) { /* is really weak? */ + h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */ + h->marked |= cast_byte((weakkey << KEYWEAKBIT) | + (weakvalue << VALUEWEAKBIT)); + h->gclist = g->weak; /* must be cleared after GC, ... */ + g->weak = obj2gco(h); /* ... so put in the appropriate list */ + } + } + if (weakkey && weakvalue) return 1; + if (!weakvalue) { + i = h->sizearray; + while (i--) + markvalue(g, &h->array[i]); + } + i = sizenode(h); + while (i--) { + Node *n = gnode(h, i); + lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); + if (ttisnil(gval(n))) + removeentry(n); /* remove empty entries */ + else { + lua_assert(!ttisnil(gkey(n))); + if (!weakkey) markvalue(g, gkey(n)); + if (!weakvalue) markvalue(g, gval(n)); + } + } + return weakkey || weakvalue; +} + + +/* +** All marks are conditional because a GC may happen while the +** prototype is still being created +*/ +static void traverseproto (global_State *g, Proto *f) { + int i; + if (f->source) stringmark(f->source); + for (i=0; isizek; i++) /* mark literals */ + markvalue(g, &f->k[i]); + for (i=0; isizeupvalues; i++) { /* mark upvalue names */ + if (f->upvalues[i]) + stringmark(f->upvalues[i]); + } + for (i=0; isizep; i++) { /* mark nested protos */ + if (f->p[i]) + markobject(g, f->p[i]); + } + for (i=0; isizelocvars; i++) { /* mark local-variable names */ + if (f->locvars[i].varname) + stringmark(f->locvars[i].varname); + } +} + + + +static void traverseclosure (global_State *g, Closure *cl) { + markobject(g, cl->c.env); + if (cl->c.isC) { + int i; + for (i=0; ic.nupvalues; i++) /* mark its upvalues */ + markvalue(g, &cl->c.upvalue[i]); + } + else { + int i; + lua_assert(cl->l.nupvalues == cl->l.p->nups); + markobject(g, cl->l.p); + for (i=0; il.nupvalues; i++) /* mark its upvalues */ + markobject(g, cl->l.upvals[i]); + } +} + + +static void checkstacksizes (lua_State *L, StkId max) { + int ci_used = cast_int(L->ci - L->base_ci); /* number of `ci' in use */ + int s_used = cast_int(max - L->stack); /* part of stack in use */ + if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */ + return; /* do not touch the stacks */ + if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci) + luaD_reallocCI(L, L->size_ci/2); /* still big enough... */ + condhardstacktests(luaD_reallocCI(L, ci_used + 1)); + if (4*s_used < L->stacksize && + 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize) + luaD_reallocstack(L, L->stacksize/2); /* still big enough... */ + condhardstacktests(luaD_reallocstack(L, s_used)); +} + + +static void traversestack (global_State *g, lua_State *l) { + StkId o, lim; + CallInfo *ci; + markvalue(g, gt(l)); + lim = l->top; + for (ci = l->base_ci; ci <= l->ci; ci++) { + lua_assert(ci->top <= l->stack_last); + if (lim < ci->top) lim = ci->top; + } + for (o = l->stack; o < l->top; o++) + markvalue(g, o); + for (; o <= lim; o++) + setnilvalue(o); + checkstacksizes(l, lim); +} + + +/* +** traverse one gray object, turning it to black. +** Returns `quantity' traversed. +*/ +static l_mem propagatemark (global_State *g) { + GCObject *o = g->gray; + lua_assert(isgray(o)); + gray2black(o); + switch (o->gch.tt) { + case LUA_TTABLE: { + Table *h = gco2h(o); + g->gray = h->gclist; + if (traversetable(g, h)) /* table is weak? */ + black2gray(o); /* keep it gray */ + return sizeof(Table) + sizeof(TValue) * h->sizearray + + sizeof(Node) * sizenode(h); + } + case LUA_TFUNCTION: { + Closure *cl = gco2cl(o); + g->gray = cl->c.gclist; + traverseclosure(g, cl); + return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) : + sizeLclosure(cl->l.nupvalues); + } + case LUA_TTHREAD: { + lua_State *th = gco2th(o); + g->gray = th->gclist; + th->gclist = g->grayagain; + g->grayagain = o; + black2gray(o); + traversestack(g, th); + return sizeof(lua_State) + sizeof(TValue) * th->stacksize + + sizeof(CallInfo) * th->size_ci; + } + case LUA_TPROTO: { + Proto *p = gco2p(o); + g->gray = p->gclist; + traverseproto(g, p); + return sizeof(Proto) + sizeof(Instruction) * p->sizecode + + sizeof(Proto *) * p->sizep + + sizeof(TValue) * p->sizek + + sizeof(int) * p->sizelineinfo + + sizeof(LocVar) * p->sizelocvars + + sizeof(TString *) * p->sizeupvalues; + } + default: lua_assert(0); return 0; + } +} + + +static size_t propagateall (global_State *g) { + size_t m = 0; + while (g->gray) m += propagatemark(g); + return m; +} + + +/* +** The next function tells whether a key or value can be cleared from +** a weak table. Non-collectable objects are never removed from weak +** tables. Strings behave as `values', so are never removed too. for +** other objects: if really collected, cannot keep them; for userdata +** being finalized, keep them in keys, but not in values +*/ +static int iscleared (const TValue *o, int iskey) { + if (!iscollectable(o)) return 0; + if (ttisstring(o)) { + stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */ + return 0; + } + return iswhite(gcvalue(o)) || + (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); +} + + +/* +** clear collected entries from weaktables +*/ +static void cleartable (GCObject *l) { + while (l) { + Table *h = gco2h(l); + int i = h->sizearray; + lua_assert(testbit(h->marked, VALUEWEAKBIT) || + testbit(h->marked, KEYWEAKBIT)); + if (testbit(h->marked, VALUEWEAKBIT)) { + while (i--) { + TValue *o = &h->array[i]; + if (iscleared(o, 0)) /* value was collected? */ + setnilvalue(o); /* remove value */ + } + } + i = sizenode(h); + while (i--) { + Node *n = gnode(h, i); + if (!ttisnil(gval(n)) && /* non-empty entry? */ + (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) { + setnilvalue(gval(n)); /* remove value ... */ + removeentry(n); /* remove entry from table */ + } + } + l = h->gclist; + } +} + + +static void freeobj (lua_State *L, GCObject *o) { + switch (o->gch.tt) { + case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; + case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break; + case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; + case LUA_TTABLE: luaH_free(L, gco2h(o)); break; + case LUA_TTHREAD: { + lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread); + luaE_freethread(L, gco2th(o)); + break; + } + case LUA_TSTRING: { + G(L)->strt.nuse--; + luaM_freemem(L, o, sizestring(gco2ts(o))); + break; + } + case LUA_TUSERDATA: { + luaM_freemem(L, o, sizeudata(gco2u(o))); + break; + } + default: lua_assert(0); + } +} + + + +#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) + + +static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { + GCObject *curr; + global_State *g = G(L); + int deadmask = otherwhite(g); + while ((curr = *p) != NULL && count-- > 0) { + if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */ + sweepwholelist(L, &gco2th(curr)->openupval); + if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */ + lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); + makewhite(g, curr); /* make it white (for next cycle) */ + p = &curr->gch.next; + } + else { /* must erase `curr' */ + lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); + *p = curr->gch.next; + if (curr == g->rootgc) /* is the first element of the list? */ + g->rootgc = curr->gch.next; /* adjust first */ + freeobj(L, curr); + } + } + return p; +} + + +static void checkSizes (lua_State *L) { + global_State *g = G(L); + /* check size of string hash */ + if (g->strt.nuse < cast(lu_int32, g->strt.size/4) && + g->strt.size > MINSTRTABSIZE*2) + luaS_resize(L, g->strt.size/2); /* table is too big */ + /* check size of buffer */ + if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */ + size_t newsize = luaZ_sizebuffer(&g->buff) / 2; + luaZ_resizebuffer(L, &g->buff, newsize); + } +} + + +static void GCTM (lua_State *L) { + global_State *g = G(L); + GCObject *o = g->tmudata->gch.next; /* get first element */ + Udata *udata = rawgco2u(o); + const TValue *tm; + /* remove udata from `tmudata' */ + if (o == g->tmudata) /* last element? */ + g->tmudata = NULL; + else + g->tmudata->gch.next = udata->uv.next; + udata->uv.next = g->mainthread->next; /* return it to `root' list */ + g->mainthread->next = o; + makewhite(g, o); + tm = fasttm(L, udata->uv.metatable, TM_GC); + if (tm != NULL) { + lu_byte oldah = L->allowhook; + lu_mem oldt = g->GCthreshold; + L->allowhook = 0; /* stop debug hooks during GC tag method */ + g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */ + setobj2s(L, L->top, tm); + setuvalue(L, L->top+1, udata); + L->top += 2; + luaD_call(L, L->top - 2, 0); + L->allowhook = oldah; /* restore hooks */ + g->GCthreshold = oldt; /* restore threshold */ + } +} + + +/* +** Call all GC tag methods +*/ +void luaC_callGCTM (lua_State *L) { + while (G(L)->tmudata) + GCTM(L); +} + + +void luaC_freeall (lua_State *L) { + global_State *g = G(L); + int i; + g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */ + sweepwholelist(L, &g->rootgc); + for (i = 0; i < g->strt.size; i++) /* free all string lists */ + sweepwholelist(L, &g->strt.hash[i]); +} + + +static void markmt (global_State *g) { + int i; + for (i=0; imt[i]) markobject(g, g->mt[i]); +} + + +/* mark root set */ +static void markroot (lua_State *L) { + global_State *g = G(L); + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + markobject(g, g->mainthread); + /* make global table be traversed before main stack */ + markvalue(g, gt(g->mainthread)); + markvalue(g, registry(L)); + markmt(g); + g->gcstate = GCSpropagate; +} + + +static void remarkupvals (global_State *g) { + UpVal *uv; + for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + if (isgray(obj2gco(uv))) + markvalue(g, uv->v); + } +} + + +static void atomic (lua_State *L) { + global_State *g = G(L); + size_t udsize; /* total size of userdata to be finalized */ + /* remark occasional upvalues of (maybe) dead threads */ + remarkupvals(g); + /* traverse objects cautch by write barrier and by 'remarkupvals' */ + propagateall(g); + /* remark weak tables */ + g->gray = g->weak; + g->weak = NULL; + lua_assert(!iswhite(obj2gco(g->mainthread))); + markobject(g, L); /* mark running thread */ + markmt(g); /* mark basic metatables (again) */ + propagateall(g); + /* remark gray again */ + g->gray = g->grayagain; + g->grayagain = NULL; + propagateall(g); + udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */ + marktmu(g); /* mark `preserved' userdata */ + udsize += propagateall(g); /* remark, to propagate `preserveness' */ + cleartable(g->weak); /* remove collected objects from weak tables */ + /* flip current white */ + g->currentwhite = cast_byte(otherwhite(g)); + g->sweepstrgc = 0; + g->sweepgc = &g->rootgc; + g->gcstate = GCSsweepstring; + g->estimate = g->totalbytes - udsize; /* first estimate */ +} + + +static l_mem singlestep (lua_State *L) { + global_State *g = G(L); + /*lua_checkmemory(L);*/ + switch (g->gcstate) { + case GCSpause: { + markroot(L); /* start a new collection */ + return 0; + } + case GCSpropagate: { + if (g->gray) + return propagatemark(g); + else { /* no more `gray' objects */ + atomic(L); /* finish mark phase */ + return 0; + } + } + case GCSsweepstring: { + lu_mem old = g->totalbytes; + sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); + if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ + g->gcstate = GCSsweep; /* end sweep-string phase */ + lua_assert(old >= g->totalbytes); + g->estimate -= old - g->totalbytes; + return GCSWEEPCOST; + } + case GCSsweep: { + lu_mem old = g->totalbytes; + g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); + if (*g->sweepgc == NULL) { /* nothing more to sweep? */ + checkSizes(L); + g->gcstate = GCSfinalize; /* end sweep phase */ + } + lua_assert(old >= g->totalbytes); + g->estimate -= old - g->totalbytes; + return GCSWEEPMAX*GCSWEEPCOST; + } + case GCSfinalize: { + if (g->tmudata) { + GCTM(L); + if (g->estimate > GCFINALIZECOST) + g->estimate -= GCFINALIZECOST; + return GCFINALIZECOST; + } + else { + g->gcstate = GCSpause; /* end collection */ + g->gcdept = 0; + return 0; + } + } + default: lua_assert(0); return 0; + } +} + + +void luaC_step (lua_State *L) { + global_State *g = G(L); + l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; + if (lim == 0) + lim = (MAX_LUMEM-1)/2; /* no limit */ + g->gcdept += g->totalbytes - g->GCthreshold; + do { + lim -= singlestep(L); + if (g->gcstate == GCSpause) + break; + } while (lim > 0); + if (g->gcstate != GCSpause) { + if (g->gcdept < GCSTEPSIZE) + g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/ + else { + g->gcdept -= GCSTEPSIZE; + g->GCthreshold = g->totalbytes; + } + } + else { + lua_assert(g->totalbytes >= g->estimate); + setthreshold(g); + } +} + + +void luaC_fullgc (lua_State *L) { + global_State *g = G(L); + if (g->gcstate <= GCSpropagate) { + /* reset sweep marks to sweep all elements (returning them to white) */ + g->sweepstrgc = 0; + g->sweepgc = &g->rootgc; + /* reset other collector lists */ + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + g->gcstate = GCSsweepstring; + } + lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate); + /* finish any pending sweep phase */ + while (g->gcstate != GCSfinalize) { + lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep); + singlestep(L); + } + markroot(L); + while (g->gcstate != GCSpause) { + singlestep(L); + } + setthreshold(g); +} + + +void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { + global_State *g = G(L); + lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); + lua_assert(ttype(&o->gch) != LUA_TTABLE); + /* must keep invariant? */ + if (g->gcstate == GCSpropagate) + reallymarkobject(g, v); /* restore invariant */ + else /* don't mind */ + makewhite(g, o); /* mark as white just to avoid other barriers */ +} + + +void luaC_barrierback (lua_State *L, Table *t) { + global_State *g = G(L); + GCObject *o = obj2gco(t); + lua_assert(isblack(o) && !isdead(g, o)); + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); + black2gray(o); /* make table gray (again) */ + t->gclist = g->grayagain; + g->grayagain = o; +} + + +void luaC_link (lua_State *L, GCObject *o, lu_byte tt) { + global_State *g = G(L); + o->gch.next = g->rootgc; + g->rootgc = o; + o->gch.marked = luaC_white(g); + o->gch.tt = tt; +} + + +void luaC_linkupval (lua_State *L, UpVal *uv) { + global_State *g = G(L); + GCObject *o = obj2gco(uv); + o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */ + g->rootgc = o; + if (isgray(o)) { + if (g->gcstate == GCSpropagate) { + gray2black(o); /* closed upvalues need barrier */ + luaC_barrier(L, uv, uv->v); + } + else { /* sweep phase: sweep it (turning it into white) */ + makewhite(g, o); + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); + } + } +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/lgc.h b/vscript/languages/lua/lua-5.1.4/src/lgc.h new file mode 100644 index 00000000..5a8dc605 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lgc.h @@ -0,0 +1,110 @@ +/* +** $Id: lgc.h,v 2.15.1.1 2007/12/27 13:02:25 roberto Exp $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#ifndef lgc_h +#define lgc_h + + +#include "lobject.h" + + +/* +** Possible states of the Garbage Collector +*/ +#define GCSpause 0 +#define GCSpropagate 1 +#define GCSsweepstring 2 +#define GCSsweep 3 +#define GCSfinalize 4 + + +/* +** some userful bit tricks +*/ +#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) +#define setbits(x,m) ((x) |= (m)) +#define testbits(x,m) ((x) & (m)) +#define bitmask(b) (1<<(b)) +#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) +#define l_setbit(x,b) setbits(x, bitmask(b)) +#define resetbit(x,b) resetbits(x, bitmask(b)) +#define testbit(x,b) testbits(x, bitmask(b)) +#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2))) +#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2))) +#define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2))) + + + +/* +** Layout for bit use in `marked' field: +** bit 0 - object is white (type 0) +** bit 1 - object is white (type 1) +** bit 2 - object is black +** bit 3 - for userdata: has been finalized +** bit 3 - for tables: has weak keys +** bit 4 - for tables: has weak values +** bit 5 - object is fixed (should not be collected) +** bit 6 - object is "super" fixed (only the main thread) +*/ + + +#define WHITE0BIT 0 +#define WHITE1BIT 1 +#define BLACKBIT 2 +#define FINALIZEDBIT 3 +#define KEYWEAKBIT 3 +#define VALUEWEAKBIT 4 +#define FIXEDBIT 5 +#define SFIXEDBIT 6 +#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) + + +#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) +#define isblack(x) testbit((x)->gch.marked, BLACKBIT) +#define isgray(x) (!isblack(x) && !iswhite(x)) + +#define otherwhite(g) (g->currentwhite ^ WHITEBITS) +#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS) + +#define changewhite(x) ((x)->gch.marked ^= WHITEBITS) +#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) + +#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) + +#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) + + +#define luaC_checkGC(L) { \ + condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \ + if (G(L)->totalbytes >= G(L)->GCthreshold) \ + luaC_step(L); } + + +#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ + luaC_barrierf(L,obj2gco(p),gcvalue(v)); } + +#define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \ + luaC_barrierback(L,t); } + +#define luaC_objbarrier(L,p,o) \ + { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ + luaC_barrierf(L,obj2gco(p),obj2gco(o)); } + +#define luaC_objbarriert(L,t,o) \ + { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); } + +LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all); +LUAI_FUNC void luaC_callGCTM (lua_State *L); +LUAI_FUNC void luaC_freeall (lua_State *L); +LUAI_FUNC void luaC_step (lua_State *L); +LUAI_FUNC void luaC_fullgc (lua_State *L); +LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt); +LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv); +LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); +LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t); + + +#endif diff --git a/vscript/languages/lua/lua-5.1.4/src/linit.c b/vscript/languages/lua/lua-5.1.4/src/linit.c new file mode 100644 index 00000000..c1f90dfa --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/linit.c @@ -0,0 +1,38 @@ +/* +** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $ +** Initialization of libraries for lua.c +** See Copyright Notice in lua.h +*/ + + +#define linit_c +#define LUA_LIB + +#include "lua.h" + +#include "lualib.h" +#include "lauxlib.h" + + +static const luaL_Reg lualibs[] = { + {"", luaopen_base}, + {LUA_LOADLIBNAME, luaopen_package}, + {LUA_TABLIBNAME, luaopen_table}, + {LUA_IOLIBNAME, luaopen_io}, + {LUA_OSLIBNAME, luaopen_os}, + {LUA_STRLIBNAME, luaopen_string}, + {LUA_MATHLIBNAME, luaopen_math}, + {LUA_DBLIBNAME, luaopen_debug}, + {NULL, NULL} +}; + + +LUALIB_API void luaL_openlibs (lua_State *L) { + const luaL_Reg *lib = lualibs; + for (; lib->func; lib++) { + lua_pushcfunction(L, lib->func); + lua_pushstring(L, lib->name); + lua_call(L, 1, 0); + } +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/liolib.c b/vscript/languages/lua/lua-5.1.4/src/liolib.c new file mode 100644 index 00000000..e79ed1cb --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/liolib.c @@ -0,0 +1,553 @@ +/* +** $Id: liolib.c,v 2.73.1.3 2008/01/18 17:47:43 roberto Exp $ +** Standard I/O (and system) library +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include + +#define liolib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + +#define IO_INPUT 1 +#define IO_OUTPUT 2 + + +static const char *const fnames[] = {"input", "output"}; + + +static int pushresult (lua_State *L, int i, const char *filename) { + int en = errno; /* calls to Lua API may change this value */ + if (i) { + lua_pushboolean(L, 1); + return 1; + } + else { + lua_pushnil(L); + if (filename) + lua_pushfstring(L, "%s: %s", filename, strerror(en)); + else + lua_pushfstring(L, "%s", strerror(en)); + lua_pushinteger(L, en); + return 3; + } +} + + +static void fileerror (lua_State *L, int arg, const char *filename) { + lua_pushfstring(L, "%s: %s", filename, strerror(errno)); + luaL_argerror(L, arg, lua_tostring(L, -1)); +} + + +#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE)) + + +static int io_type (lua_State *L) { + void *ud; + luaL_checkany(L, 1); + ud = lua_touserdata(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); + if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1)) + lua_pushnil(L); /* not a file */ + else if (*((FILE **)ud) == NULL) + lua_pushliteral(L, "closed file"); + else + lua_pushliteral(L, "file"); + return 1; +} + + +static FILE *tofile (lua_State *L) { + FILE **f = tofilep(L); + if (*f == NULL) + luaL_error(L, "attempt to use a closed file"); + return *f; +} + + + +/* +** When creating file handles, always creates a `closed' file handle +** before opening the actual file; so, if there is a memory error, the +** file is not left opened. +*/ +static FILE **newfile (lua_State *L) { + FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *)); + *pf = NULL; /* file handle is currently `closed' */ + luaL_getmetatable(L, LUA_FILEHANDLE); + lua_setmetatable(L, -2); + return pf; +} + + +/* +** function to (not) close the standard files stdin, stdout, and stderr +*/ +static int io_noclose (lua_State *L) { + lua_pushnil(L); + lua_pushliteral(L, "cannot close standard file"); + return 2; +} + + +/* +** function to close 'popen' files +*/ +static int io_pclose (lua_State *L) { + FILE **p = tofilep(L); + int ok = lua_pclose(L, *p); + *p = NULL; + return pushresult(L, ok, NULL); +} + + +/* +** function to close regular files +*/ +static int io_fclose (lua_State *L) { + FILE **p = tofilep(L); + int ok = (fclose(*p) == 0); + *p = NULL; + return pushresult(L, ok, NULL); +} + + +static int aux_close (lua_State *L) { + lua_getfenv(L, 1); + lua_getfield(L, -1, "__close"); + return (lua_tocfunction(L, -1))(L); +} + + +static int io_close (lua_State *L) { + if (lua_isnone(L, 1)) + lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT); + tofile(L); /* make sure argument is a file */ + return aux_close(L); +} + + +static int io_gc (lua_State *L) { + FILE *f = *tofilep(L); + /* ignore closed files */ + if (f != NULL) + aux_close(L); + return 0; +} + + +static int io_tostring (lua_State *L) { + FILE *f = *tofilep(L); + if (f == NULL) + lua_pushliteral(L, "file (closed)"); + else + lua_pushfstring(L, "file (%p)", f); + return 1; +} + + +static int io_open (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + FILE **pf = newfile(L); + *pf = fopen(filename, mode); + return (*pf == NULL) ? pushresult(L, 0, filename) : 1; +} + + +/* +** this function has a separated environment, which defines the +** correct __close for 'popen' files +*/ +static int io_popen (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + FILE **pf = newfile(L); + *pf = lua_popen(L, filename, mode); + return (*pf == NULL) ? pushresult(L, 0, filename) : 1; +} + + +static int io_tmpfile (lua_State *L) { + FILE **pf = newfile(L); + *pf = tmpfile(); + return (*pf == NULL) ? pushresult(L, 0, NULL) : 1; +} + + +static FILE *getiofile (lua_State *L, int findex) { + FILE *f; + lua_rawgeti(L, LUA_ENVIRONINDEX, findex); + f = *(FILE **)lua_touserdata(L, -1); + if (f == NULL) + luaL_error(L, "standard %s file is closed", fnames[findex - 1]); + return f; +} + + +static int g_iofile (lua_State *L, int f, const char *mode) { + if (!lua_isnoneornil(L, 1)) { + const char *filename = lua_tostring(L, 1); + if (filename) { + FILE **pf = newfile(L); + *pf = fopen(filename, mode); + if (*pf == NULL) + fileerror(L, 1, filename); + } + else { + tofile(L); /* check that it's a valid file handle */ + lua_pushvalue(L, 1); + } + lua_rawseti(L, LUA_ENVIRONINDEX, f); + } + /* return current value */ + lua_rawgeti(L, LUA_ENVIRONINDEX, f); + return 1; +} + + +static int io_input (lua_State *L) { + return g_iofile(L, IO_INPUT, "r"); +} + + +static int io_output (lua_State *L) { + return g_iofile(L, IO_OUTPUT, "w"); +} + + +static int io_readline (lua_State *L); + + +static void aux_lines (lua_State *L, int idx, int toclose) { + lua_pushvalue(L, idx); + lua_pushboolean(L, toclose); /* close/not close file when finished */ + lua_pushcclosure(L, io_readline, 2); +} + + +static int f_lines (lua_State *L) { + tofile(L); /* check that it's a valid file handle */ + aux_lines(L, 1, 0); + return 1; +} + + +static int io_lines (lua_State *L) { + if (lua_isnoneornil(L, 1)) { /* no arguments? */ + /* will iterate over default input */ + lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT); + return f_lines(L); + } + else { + const char *filename = luaL_checkstring(L, 1); + FILE **pf = newfile(L); + *pf = fopen(filename, "r"); + if (*pf == NULL) + fileerror(L, 1, filename); + aux_lines(L, lua_gettop(L), 1); + return 1; + } +} + + +/* +** {====================================================== +** READ +** ======================================================= +*/ + + +static int read_number (lua_State *L, FILE *f) { + lua_Number d; + if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) { + lua_pushnumber(L, d); + return 1; + } + else return 0; /* read fails */ +} + + +static int test_eof (lua_State *L, FILE *f) { + int c = getc(f); + ungetc(c, f); + lua_pushlstring(L, NULL, 0); + return (c != EOF); +} + + +static int read_line (lua_State *L, FILE *f) { + luaL_Buffer b; + luaL_buffinit(L, &b); + for (;;) { + size_t l; + char *p = luaL_prepbuffer(&b); + if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ + luaL_pushresult(&b); /* close buffer */ + return (lua_objlen(L, -1) > 0); /* check whether read something */ + } + l = strlen(p); + if (l == 0 || p[l-1] != '\n') + luaL_addsize(&b, l); + else { + luaL_addsize(&b, l - 1); /* do not include `eol' */ + luaL_pushresult(&b); /* close buffer */ + return 1; /* read at least an `eol' */ + } + } +} + + +static int read_chars (lua_State *L, FILE *f, size_t n) { + size_t rlen; /* how much to read */ + size_t nr; /* number of chars actually read */ + luaL_Buffer b; + luaL_buffinit(L, &b); + rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ + do { + char *p = luaL_prepbuffer(&b); + if (rlen > n) rlen = n; /* cannot read more than asked */ + nr = fread(p, sizeof(char), rlen, f); + luaL_addsize(&b, nr); + n -= nr; /* still have to read `n' chars */ + } while (n > 0 && nr == rlen); /* until end of count or eof */ + luaL_pushresult(&b); /* close buffer */ + return (n == 0 || lua_objlen(L, -1) > 0); +} + + +static int g_read (lua_State *L, FILE *f, int first) { + int nargs = lua_gettop(L) - 1; + int success; + int n; + clearerr(f); + if (nargs == 0) { /* no arguments? */ + success = read_line(L, f); + n = first+1; /* to return 1 result */ + } + else { /* ensure stack space for all results and for auxlib's buffer */ + luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); + success = 1; + for (n = first; nargs-- && success; n++) { + if (lua_type(L, n) == LUA_TNUMBER) { + size_t l = (size_t)lua_tointeger(L, n); + success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); + } + else { + const char *p = lua_tostring(L, n); + luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); + switch (p[1]) { + case 'n': /* number */ + success = read_number(L, f); + break; + case 'l': /* line */ + success = read_line(L, f); + break; + case 'a': /* file */ + read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ + success = 1; /* always success */ + break; + default: + return luaL_argerror(L, n, "invalid format"); + } + } + } + } + if (ferror(f)) + return pushresult(L, 0, NULL); + if (!success) { + lua_pop(L, 1); /* remove last result */ + lua_pushnil(L); /* push nil instead */ + } + return n - first; +} + + +static int io_read (lua_State *L) { + return g_read(L, getiofile(L, IO_INPUT), 1); +} + + +static int f_read (lua_State *L) { + return g_read(L, tofile(L), 2); +} + + +static int io_readline (lua_State *L) { + FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1)); + int sucess; + if (f == NULL) /* file is already closed? */ + luaL_error(L, "file is already closed"); + sucess = read_line(L, f); + if (ferror(f)) + return luaL_error(L, "%s", strerror(errno)); + if (sucess) return 1; + else { /* EOF */ + if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */ + lua_settop(L, 0); + lua_pushvalue(L, lua_upvalueindex(1)); + aux_close(L); /* close it */ + } + return 0; + } +} + +/* }====================================================== */ + + +static int g_write (lua_State *L, FILE *f, int arg) { + int nargs = lua_gettop(L) - 1; + int status = 1; + for (; nargs--; arg++) { + if (lua_type(L, arg) == LUA_TNUMBER) { + /* optimization: could be done exactly as for strings */ + status = status && + fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; + } + else { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + status = status && (fwrite(s, sizeof(char), l, f) == l); + } + } + return pushresult(L, status, NULL); +} + + +static int io_write (lua_State *L) { + return g_write(L, getiofile(L, IO_OUTPUT), 1); +} + + +static int f_write (lua_State *L) { + return g_write(L, tofile(L), 2); +} + + +static int f_seek (lua_State *L) { + static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; + static const char *const modenames[] = {"set", "cur", "end", NULL}; + FILE *f = tofile(L); + int op = luaL_checkoption(L, 2, "cur", modenames); + long offset = luaL_optlong(L, 3, 0); + op = fseek(f, offset, mode[op]); + if (op) + return pushresult(L, 0, NULL); /* error */ + else { + lua_pushinteger(L, ftell(f)); + return 1; + } +} + + +static int f_setvbuf (lua_State *L) { + static const int mode[] = {_IONBF, _IOFBF, _IOLBF}; + static const char *const modenames[] = {"no", "full", "line", NULL}; + FILE *f = tofile(L); + int op = luaL_checkoption(L, 2, NULL, modenames); + lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); + int res = setvbuf(f, NULL, mode[op], sz); + return pushresult(L, res == 0, NULL); +} + + + +static int io_flush (lua_State *L) { + return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); +} + + +static int f_flush (lua_State *L) { + return pushresult(L, fflush(tofile(L)) == 0, NULL); +} + + +static const luaL_Reg iolib[] = { + {"close", io_close}, + {"flush", io_flush}, + {"input", io_input}, + {"lines", io_lines}, + {"open", io_open}, + {"output", io_output}, + {"popen", io_popen}, + {"read", io_read}, + {"tmpfile", io_tmpfile}, + {"type", io_type}, + {"write", io_write}, + {NULL, NULL} +}; + + +static const luaL_Reg flib[] = { + {"close", io_close}, + {"flush", f_flush}, + {"lines", f_lines}, + {"read", f_read}, + {"seek", f_seek}, + {"setvbuf", f_setvbuf}, + {"write", f_write}, + {"__gc", io_gc}, + {"__tostring", io_tostring}, + {NULL, NULL} +}; + + +static void createmeta (lua_State *L) { + luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ + lua_pushvalue(L, -1); /* push metatable */ + lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ + luaL_register(L, NULL, flib); /* file methods */ +} + + +static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) { + *newfile(L) = f; + if (k > 0) { + lua_pushvalue(L, -1); + lua_rawseti(L, LUA_ENVIRONINDEX, k); + } + lua_pushvalue(L, -2); /* copy environment */ + lua_setfenv(L, -2); /* set it */ + lua_setfield(L, -3, fname); +} + + +static void newfenv (lua_State *L, lua_CFunction cls) { + lua_createtable(L, 0, 1); + lua_pushcfunction(L, cls); + lua_setfield(L, -2, "__close"); +} + + +LUALIB_API int luaopen_io (lua_State *L) { + createmeta(L); + /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ + newfenv(L, io_fclose); + lua_replace(L, LUA_ENVIRONINDEX); + /* open library */ + luaL_register(L, LUA_IOLIBNAME, iolib); + /* create (and set) default files */ + newfenv(L, io_noclose); /* close function for default files */ + createstdfile(L, stdin, IO_INPUT, "stdin"); + createstdfile(L, stdout, IO_OUTPUT, "stdout"); + createstdfile(L, stderr, 0, "stderr"); + lua_pop(L, 1); /* pop environment for default files */ + lua_getfield(L, -1, "popen"); + newfenv(L, io_pclose); /* create environment for 'popen' */ + lua_setfenv(L, -2); /* set fenv for 'popen' */ + lua_pop(L, 1); /* pop 'popen' */ + return 1; +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/llex.c b/vscript/languages/lua/lua-5.1.4/src/llex.c new file mode 100644 index 00000000..6dc31935 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/llex.c @@ -0,0 +1,461 @@ +/* +** $Id: llex.c,v 2.20.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define llex_c +#define LUA_CORE + +#include "lua.h" + +#include "ldo.h" +#include "llex.h" +#include "lobject.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "lzio.h" + + + +#define next(ls) (ls->current = zgetc(ls->z)) + + + + +#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') + + +/* ORDER RESERVED */ +const char *const luaX_tokens [] = { + "and", "break", "do", "else", "elseif", + "end", "false", "for", "function", "if", + "in", "local", "nil", "not", "or", "repeat", + "return", "then", "true", "until", "while", + "..", "...", "==", ">=", "<=", "~=", + "", "", "", "", + NULL +}; + + +#define save_and_next(ls) (save(ls, ls->current), next(ls)) + + +static void save (LexState *ls, int c) { + Mbuffer *b = ls->buff; + if (b->n + 1 > b->buffsize) { + size_t newsize; + if (b->buffsize >= MAX_SIZET/2) + luaX_lexerror(ls, "lexical element too long", 0); + newsize = b->buffsize * 2; + luaZ_resizebuffer(ls->L, b, newsize); + } + b->buffer[b->n++] = cast(char, c); +} + + +void luaX_init (lua_State *L) { + int i; + for (i=0; itsv.reserved = cast_byte(i+1); /* reserved word */ + } +} + + +#define MAXSRC 80 + + +const char *luaX_token2str (LexState *ls, int token) { + if (token < FIRST_RESERVED) { + lua_assert(token == cast(unsigned char, token)); + return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) : + luaO_pushfstring(ls->L, "%c", token); + } + else + return luaX_tokens[token-FIRST_RESERVED]; +} + + +static const char *txtToken (LexState *ls, int token) { + switch (token) { + case TK_NAME: + case TK_STRING: + case TK_NUMBER: + save(ls, '\0'); + return luaZ_buffer(ls->buff); + default: + return luaX_token2str(ls, token); + } +} + + +void luaX_lexerror (LexState *ls, const char *msg, int token) { + char buff[MAXSRC]; + luaO_chunkid(buff, getstr(ls->source), MAXSRC); + msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg); + if (token) + luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token)); + luaD_throw(ls->L, LUA_ERRSYNTAX); +} + + +void luaX_syntaxerror (LexState *ls, const char *msg) { + luaX_lexerror(ls, msg, ls->t.token); +} + + +TString *luaX_newstring (LexState *ls, const char *str, size_t l) { + lua_State *L = ls->L; + TString *ts = luaS_newlstr(L, str, l); + TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */ + if (ttisnil(o)) + setbvalue(o, 1); /* make sure `str' will not be collected */ + return ts; +} + + +static void inclinenumber (LexState *ls) { + int old = ls->current; + lua_assert(currIsNewline(ls)); + next(ls); /* skip `\n' or `\r' */ + if (currIsNewline(ls) && ls->current != old) + next(ls); /* skip `\n\r' or `\r\n' */ + if (++ls->linenumber >= MAX_INT) + luaX_syntaxerror(ls, "chunk has too many lines"); +} + + +void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { + ls->decpoint = '.'; + ls->L = L; + ls->lookahead.token = TK_EOS; /* no look-ahead token */ + ls->z = z; + ls->fs = NULL; + ls->linenumber = 1; + ls->lastline = 1; + ls->source = source; + luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ + next(ls); /* read first char */ +} + + + +/* +** ======================================================= +** LEXICAL ANALYZER +** ======================================================= +*/ + + + +static int check_next (LexState *ls, const char *set) { + if (!strchr(set, ls->current)) + return 0; + save_and_next(ls); + return 1; +} + + +static void buffreplace (LexState *ls, char from, char to) { + size_t n = luaZ_bufflen(ls->buff); + char *p = luaZ_buffer(ls->buff); + while (n--) + if (p[n] == from) p[n] = to; +} + + +static void trydecpoint (LexState *ls, SemInfo *seminfo) { + /* format error: try to update decimal point separator */ + struct lconv *cv = localeconv(); + char old = ls->decpoint; + ls->decpoint = (cv ? cv->decimal_point[0] : '.'); + buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */ + if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) { + /* format error with correct decimal point: no more options */ + buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ + luaX_lexerror(ls, "malformed number", TK_NUMBER); + } +} + + +/* LUA_NUMBER */ +static void read_numeral (LexState *ls, SemInfo *seminfo) { + lua_assert(isdigit(ls->current)); + do { + save_and_next(ls); + } while (isdigit(ls->current) || ls->current == '.'); + if (check_next(ls, "Ee")) /* `E'? */ + check_next(ls, "+-"); /* optional exponent sign */ + while (isalnum(ls->current) || ls->current == '_') + save_and_next(ls); + save(ls, '\0'); + buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ + if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */ + trydecpoint(ls, seminfo); /* try to update decimal point separator */ +} + + +static int skip_sep (LexState *ls) { + int count = 0; + int s = ls->current; + lua_assert(s == '[' || s == ']'); + save_and_next(ls); + while (ls->current == '=') { + save_and_next(ls); + count++; + } + return (ls->current == s) ? count : (-count) - 1; +} + + +static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { + int cont = 0; + (void)(cont); /* avoid warnings when `cont' is not used */ + save_and_next(ls); /* skip 2nd `[' */ + if (currIsNewline(ls)) /* string starts with a newline? */ + inclinenumber(ls); /* skip it */ + for (;;) { + switch (ls->current) { + case EOZ: + luaX_lexerror(ls, (seminfo) ? "unfinished long string" : + "unfinished long comment", TK_EOS); + break; /* to avoid warnings */ +#if defined(LUA_COMPAT_LSTR) + case '[': { + if (skip_sep(ls) == sep) { + save_and_next(ls); /* skip 2nd `[' */ + cont++; +#if LUA_COMPAT_LSTR == 1 + if (sep == 0) + luaX_lexerror(ls, "nesting of [[...]] is deprecated", '['); +#endif + } + break; + } +#endif + case ']': { + if (skip_sep(ls) == sep) { + save_and_next(ls); /* skip 2nd `]' */ +#if defined(LUA_COMPAT_LSTR) && LUA_COMPAT_LSTR == 2 + cont--; + if (sep == 0 && cont >= 0) break; +#endif + goto endloop; + } + break; + } + case '\n': + case '\r': { + save(ls, '\n'); + inclinenumber(ls); + if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ + break; + } + default: { + if (seminfo) save_and_next(ls); + else next(ls); + } + } + } endloop: + if (seminfo) + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), + luaZ_bufflen(ls->buff) - 2*(2 + sep)); +} + + +static void read_string (LexState *ls, int del, SemInfo *seminfo) { + save_and_next(ls); + while (ls->current != del) { + switch (ls->current) { + case EOZ: + luaX_lexerror(ls, "unfinished string", TK_EOS); + continue; /* to avoid warnings */ + case '\n': + case '\r': + luaX_lexerror(ls, "unfinished string", TK_STRING); + continue; /* to avoid warnings */ + case '\\': { + int c; + next(ls); /* do not save the `\' */ + switch (ls->current) { + case 'a': c = '\a'; break; + case 'b': c = '\b'; break; + case 'f': c = '\f'; break; + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + case 'v': c = '\v'; break; + case '\n': /* go through */ + case '\r': save(ls, '\n'); inclinenumber(ls); continue; + case EOZ: continue; /* will raise an error next loop */ + default: { + if (!isdigit(ls->current)) + save_and_next(ls); /* handles \\, \", \', and \? */ + else { /* \xxx */ + int i = 0; + c = 0; + do { + c = 10*c + (ls->current-'0'); + next(ls); + } while (++i<3 && isdigit(ls->current)); + if (c > UCHAR_MAX) + luaX_lexerror(ls, "escape sequence too large", TK_STRING); + save(ls, c); + } + continue; + } + } + save(ls, c); + next(ls); + continue; + } + default: + save_and_next(ls); + } + } + save_and_next(ls); /* skip delimiter */ + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1, + luaZ_bufflen(ls->buff) - 2); +} + + +static int llex (LexState *ls, SemInfo *seminfo) { + luaZ_resetbuffer(ls->buff); + for (;;) { + switch (ls->current) { + case '\n': + case '\r': { + inclinenumber(ls); + continue; + } + case '-': { + next(ls); + if (ls->current != '-') return '-'; + /* else is a comment */ + next(ls); + if (ls->current == '[') { + int sep = skip_sep(ls); + luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ + if (sep >= 0) { + read_long_string(ls, NULL, sep); /* long comment */ + luaZ_resetbuffer(ls->buff); + continue; + } + } + /* else short comment */ + while (!currIsNewline(ls) && ls->current != EOZ) + next(ls); + continue; + } + case '[': { + int sep = skip_sep(ls); + if (sep >= 0) { + read_long_string(ls, seminfo, sep); + return TK_STRING; + } + else if (sep == -1) return '['; + else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING); + } + case '=': { + next(ls); + if (ls->current != '=') return '='; + else { next(ls); return TK_EQ; } + } + case '<': { + next(ls); + if (ls->current != '=') return '<'; + else { next(ls); return TK_LE; } + } + case '>': { + next(ls); + if (ls->current != '=') return '>'; + else { next(ls); return TK_GE; } + } + case '~': { + next(ls); + if (ls->current != '=') return '~'; + else { next(ls); return TK_NE; } + } + case '"': + case '\'': { + read_string(ls, ls->current, seminfo); + return TK_STRING; + } + case '.': { + save_and_next(ls); + if (check_next(ls, ".")) { + if (check_next(ls, ".")) + return TK_DOTS; /* ... */ + else return TK_CONCAT; /* .. */ + } + else if (!isdigit(ls->current)) return '.'; + else { + read_numeral(ls, seminfo); + return TK_NUMBER; + } + } + case EOZ: { + return TK_EOS; + } + default: { + if (isspace(ls->current)) { + lua_assert(!currIsNewline(ls)); + next(ls); + continue; + } + else if (isdigit(ls->current)) { + read_numeral(ls, seminfo); + return TK_NUMBER; + } + else if (isalpha(ls->current) || ls->current == '_') { + /* identifier or reserved word */ + TString *ts; + do { + save_and_next(ls); + } while (isalnum(ls->current) || ls->current == '_'); + ts = luaX_newstring(ls, luaZ_buffer(ls->buff), + luaZ_bufflen(ls->buff)); + if (ts->tsv.reserved > 0) /* reserved word? */ + return ts->tsv.reserved - 1 + FIRST_RESERVED; + else { + seminfo->ts = ts; + return TK_NAME; + } + } + else { + int c = ls->current; + next(ls); + return c; /* single-char tokens (+ - / ...) */ + } + } + } + } +} + + +void luaX_next (LexState *ls) { + ls->lastline = ls->linenumber; + if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ + ls->t = ls->lookahead; /* use this one */ + ls->lookahead.token = TK_EOS; /* and discharge it */ + } + else + ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */ +} + + +void luaX_lookahead (LexState *ls) { + lua_assert(ls->lookahead.token == TK_EOS); + ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/llex.h b/vscript/languages/lua/lua-5.1.4/src/llex.h new file mode 100644 index 00000000..a9201cee --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/llex.h @@ -0,0 +1,81 @@ +/* +** $Id: llex.h,v 1.58.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + +#ifndef llex_h +#define llex_h + +#include "lobject.h" +#include "lzio.h" + + +#define FIRST_RESERVED 257 + +/* maximum length of a reserved word */ +#define TOKEN_LEN (sizeof("function")/sizeof(char)) + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER RESERVED" +*/ +enum RESERVED { + /* terminal symbols denoted by reserved words */ + TK_AND = FIRST_RESERVED, TK_BREAK, + TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, + TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, + TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, + /* other terminal symbols */ + TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, + TK_NAME, TK_STRING, TK_EOS +}; + +/* number of reserved words */ +#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) + + +/* array with token `names' */ +LUAI_DATA const char *const luaX_tokens []; + + +typedef union { + lua_Number r; + TString *ts; +} SemInfo; /* semantics information */ + + +typedef struct Token { + int token; + SemInfo seminfo; +} Token; + + +typedef struct LexState { + int current; /* current character (charint) */ + int linenumber; /* input line counter */ + int lastline; /* line of last token `consumed' */ + Token t; /* current token */ + Token lookahead; /* look ahead token */ + struct FuncState *fs; /* `FuncState' is private to the parser */ + struct lua_State *L; + ZIO *z; /* input stream */ + Mbuffer *buff; /* buffer for tokens */ + TString *source; /* current source name */ + char decpoint; /* locale decimal point */ +} LexState; + + +LUAI_FUNC void luaX_init (lua_State *L); +LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, + TString *source); +LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); +LUAI_FUNC void luaX_next (LexState *ls); +LUAI_FUNC void luaX_lookahead (LexState *ls); +LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token); +LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s); +LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); + + +#endif diff --git a/vscript/languages/lua/lua-5.1.4/src/llimits.h b/vscript/languages/lua/lua-5.1.4/src/llimits.h new file mode 100644 index 00000000..ca8dcb72 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/llimits.h @@ -0,0 +1,128 @@ +/* +** $Id: llimits.h,v 1.69.1.1 2007/12/27 13:02:25 roberto Exp $ +** Limits, basic types, and some other `installation-dependent' definitions +** See Copyright Notice in lua.h +*/ + +#ifndef llimits_h +#define llimits_h + + +#include +#include + + +#include "lua.h" + + +typedef LUAI_UINT32 lu_int32; + +typedef LUAI_UMEM lu_mem; + +typedef LUAI_MEM l_mem; + + + +/* chars used as small naturals (so that `char' is reserved for characters) */ +typedef unsigned char lu_byte; + + +#define MAX_SIZET ((size_t)(~(size_t)0)-2) + +#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) + + +#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ + +/* +** conversion of pointer to integer +** this is for hashing only; there is no problem if the integer +** cannot hold the whole pointer value +*/ +#define IntPoint(p) ((unsigned int)(lu_mem)(p)) + + + +/* type to ensure maximum alignment */ +typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; + + +/* result of a `usual argument conversion' over lua_Number */ +typedef LUAI_UACNUMBER l_uacNumber; + + +/* internal assertions for in-house debugging */ +#ifdef lua_assert + +#define check_exp(c,e) (lua_assert(c), (e)) +#define api_check(l,e) lua_assert(e) + +#else + +#define lua_assert(c) ((void)0) +#define check_exp(c,e) (e) +#define api_check luai_apicheck + +#endif + + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) /* to avoid warnings */ +#endif + + +#ifndef cast +#define cast(t, exp) ((t)(exp)) +#endif + +#define cast_byte(i) cast(lu_byte, (i)) +#define cast_num(i) cast(lua_Number, (i)) +#define cast_int(i) cast(int, (i)) + + + +/* +** type for virtual-machine instructions +** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) +*/ +typedef lu_int32 Instruction; + + + +/* maximum stack for a Lua function */ +#define MAXSTACK 250 + + + +/* minimum size for the string table (must be power of 2) */ +#ifndef MINSTRTABSIZE +#define MINSTRTABSIZE 32 +#endif + + +/* minimum size for string buffer */ +#ifndef LUA_MINBUFFER +#define LUA_MINBUFFER 32 +#endif + + +#ifndef lua_lock +#define lua_lock(L) ((void) 0) +#define lua_unlock(L) ((void) 0) +#endif + +#ifndef luai_threadyield +#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} +#endif + + +/* +** macro to control inclusion of some hard tests on stack reallocation +*/ +#ifndef HARDSTACKTESTS +#define condhardstacktests(x) ((void)0) +#else +#define condhardstacktests(x) x +#endif + +#endif diff --git a/vscript/languages/lua/lua-5.1.4/src/lmathlib.c b/vscript/languages/lua/lua-5.1.4/src/lmathlib.c new file mode 100644 index 00000000..441fbf73 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lmathlib.c @@ -0,0 +1,263 @@ +/* +** $Id: lmathlib.c,v 1.67.1.1 2007/12/27 13:02:25 roberto Exp $ +** Standard mathematical library +** See Copyright Notice in lua.h +*/ + + +#include +#include + +#define lmathlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#undef PI +#define PI (3.14159265358979323846) +#define RADIANS_PER_DEGREE (PI/180.0) + + + +static int math_abs (lua_State *L) { + lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sin (lua_State *L) { + lua_pushnumber(L, sin(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sinh (lua_State *L) { + lua_pushnumber(L, sinh(luaL_checknumber(L, 1))); + return 1; +} + +static int math_cos (lua_State *L) { + lua_pushnumber(L, cos(luaL_checknumber(L, 1))); + return 1; +} + +static int math_cosh (lua_State *L) { + lua_pushnumber(L, cosh(luaL_checknumber(L, 1))); + return 1; +} + +static int math_tan (lua_State *L) { + lua_pushnumber(L, tan(luaL_checknumber(L, 1))); + return 1; +} + +static int math_tanh (lua_State *L) { + lua_pushnumber(L, tanh(luaL_checknumber(L, 1))); + return 1; +} + +static int math_asin (lua_State *L) { + lua_pushnumber(L, asin(luaL_checknumber(L, 1))); + return 1; +} + +static int math_acos (lua_State *L) { + lua_pushnumber(L, acos(luaL_checknumber(L, 1))); + return 1; +} + +static int math_atan (lua_State *L) { + lua_pushnumber(L, atan(luaL_checknumber(L, 1))); + return 1; +} + +static int math_atan2 (lua_State *L) { + lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; +} + +static int math_ceil (lua_State *L) { + lua_pushnumber(L, ceil(luaL_checknumber(L, 1))); + return 1; +} + +static int math_floor (lua_State *L) { + lua_pushnumber(L, floor(luaL_checknumber(L, 1))); + return 1; +} + +static int math_fmod (lua_State *L) { + lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; +} + +static int math_modf (lua_State *L) { + double ip; + double fp = modf(luaL_checknumber(L, 1), &ip); + lua_pushnumber(L, ip); + lua_pushnumber(L, fp); + return 2; +} + +static int math_sqrt (lua_State *L) { + lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); + return 1; +} + +static int math_pow (lua_State *L) { + lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; +} + +static int math_log (lua_State *L) { + lua_pushnumber(L, log(luaL_checknumber(L, 1))); + return 1; +} + +static int math_log10 (lua_State *L) { + lua_pushnumber(L, log10(luaL_checknumber(L, 1))); + return 1; +} + +static int math_exp (lua_State *L) { + lua_pushnumber(L, exp(luaL_checknumber(L, 1))); + return 1; +} + +static int math_deg (lua_State *L) { + lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE); + return 1; +} + +static int math_rad (lua_State *L) { + lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE); + return 1; +} + +static int math_frexp (lua_State *L) { + int e; + lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e)); + lua_pushinteger(L, e); + return 2; +} + +static int math_ldexp (lua_State *L) { + lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2))); + return 1; +} + + + +static int math_min (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + lua_Number dmin = luaL_checknumber(L, 1); + int i; + for (i=2; i<=n; i++) { + lua_Number d = luaL_checknumber(L, i); + if (d < dmin) + dmin = d; + } + lua_pushnumber(L, dmin); + return 1; +} + + +static int math_max (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + lua_Number dmax = luaL_checknumber(L, 1); + int i; + for (i=2; i<=n; i++) { + lua_Number d = luaL_checknumber(L, i); + if (d > dmax) + dmax = d; + } + lua_pushnumber(L, dmax); + return 1; +} + + +static int math_random (lua_State *L) { + /* the `%' avoids the (rare) case of r==1, and is needed also because on + some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ + lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; + switch (lua_gettop(L)) { /* check number of arguments */ + case 0: { /* no arguments */ + lua_pushnumber(L, r); /* Number between 0 and 1 */ + break; + } + case 1: { /* only upper limit */ + int u = luaL_checkint(L, 1); + luaL_argcheck(L, 1<=u, 1, "interval is empty"); + lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */ + break; + } + case 2: { /* lower and upper limits */ + int l = luaL_checkint(L, 1); + int u = luaL_checkint(L, 2); + luaL_argcheck(L, l<=u, 2, "interval is empty"); + lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */ + break; + } + default: return luaL_error(L, "wrong number of arguments"); + } + return 1; +} + + +static int math_randomseed (lua_State *L) { + srand(luaL_checkint(L, 1)); + return 0; +} + + +static const luaL_Reg mathlib[] = { + {"abs", math_abs}, + {"acos", math_acos}, + {"asin", math_asin}, + {"atan2", math_atan2}, + {"atan", math_atan}, + {"ceil", math_ceil}, + {"cosh", math_cosh}, + {"cos", math_cos}, + {"deg", math_deg}, + {"exp", math_exp}, + {"floor", math_floor}, + {"fmod", math_fmod}, + {"frexp", math_frexp}, + {"ldexp", math_ldexp}, + {"log10", math_log10}, + {"log", math_log}, + {"max", math_max}, + {"min", math_min}, + {"modf", math_modf}, + {"pow", math_pow}, + {"rad", math_rad}, + {"random", math_random}, + {"randomseed", math_randomseed}, + {"sinh", math_sinh}, + {"sin", math_sin}, + {"sqrt", math_sqrt}, + {"tanh", math_tanh}, + {"tan", math_tan}, + {NULL, NULL} +}; + + +/* +** Open math library +*/ +LUALIB_API int luaopen_math (lua_State *L) { + luaL_register(L, LUA_MATHLIBNAME, mathlib); + lua_pushnumber(L, PI); + lua_setfield(L, -2, "pi"); + lua_pushnumber(L, HUGE_VAL); + lua_setfield(L, -2, "huge"); +#if defined(LUA_COMPAT_MOD) + lua_getfield(L, -1, "fmod"); + lua_setfield(L, -2, "mod"); +#endif + return 1; +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/lmem.c b/vscript/languages/lua/lua-5.1.4/src/lmem.c new file mode 100644 index 00000000..ae7d8c96 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lmem.c @@ -0,0 +1,86 @@ +/* +** $Id: lmem.c,v 1.70.1.1 2007/12/27 13:02:25 roberto Exp $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + + +#include + +#define lmem_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +/* +** About the realloc function: +** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); +** (`osize' is the old size, `nsize' is the new size) +** +** Lua ensures that (ptr == NULL) iff (osize == 0). +** +** * frealloc(ud, NULL, 0, x) creates a new block of size `x' +** +** * frealloc(ud, p, x, 0) frees the block `p' +** (in this specific case, frealloc must return NULL). +** particularly, frealloc(ud, NULL, 0, 0) does nothing +** (which is equivalent to free(NULL) in ANSI C) +** +** frealloc returns NULL if it cannot create or reallocate the area +** (any reallocation to an equal or smaller size cannot fail!) +*/ + + + +#define MINSIZEARRAY 4 + + +void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, + int limit, const char *errormsg) { + void *newblock; + int newsize; + if (*size >= limit/2) { /* cannot double it? */ + if (*size >= limit) /* cannot grow even a little? */ + luaG_runerror(L, errormsg); + newsize = limit; /* still have at least one free place */ + } + else { + newsize = (*size)*2; + if (newsize < MINSIZEARRAY) + newsize = MINSIZEARRAY; /* minimum size */ + } + newblock = luaM_reallocv(L, block, *size, newsize, size_elems); + *size = newsize; /* update only when everything else is OK */ + return newblock; +} + + +void *luaM_toobig (lua_State *L) { + luaG_runerror(L, "memory allocation error: block too big"); + return NULL; /* to avoid warnings */ +} + + + +/* +** generic allocation routine. +*/ +void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { + global_State *g = G(L); + lua_assert((osize == 0) == (block == NULL)); + block = (*g->frealloc)(g->ud, block, osize, nsize); + if (block == NULL && nsize > 0) + luaD_throw(L, LUA_ERRMEM); + lua_assert((nsize == 0) == (block == NULL)); + g->totalbytes = (g->totalbytes - osize) + nsize; + return block; +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/lmem.h b/vscript/languages/lua/lua-5.1.4/src/lmem.h new file mode 100644 index 00000000..7c2dcb32 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lmem.h @@ -0,0 +1,49 @@ +/* +** $Id: lmem.h,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + +#ifndef lmem_h +#define lmem_h + + +#include + +#include "llimits.h" +#include "lua.h" + +#define MEMERRMSG "not enough memory" + + +#define luaM_reallocv(L,b,on,n,e) \ + ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \ + luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \ + luaM_toobig(L)) + +#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) +#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) +#define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t)) + +#define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t)) +#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) +#define luaM_newvector(L,n,t) \ + cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) + +#define luaM_growvector(L,v,nelems,size,t,limit,e) \ + if ((nelems)+1 > (size)) \ + ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) + +#define luaM_reallocvector(L, v,oldn,n,t) \ + ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) + + +LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, + size_t size); +LUAI_FUNC void *luaM_toobig (lua_State *L); +LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, + size_t size_elem, int limit, + const char *errormsg); + +#endif + diff --git a/vscript/languages/lua/lua-5.1.4/src/loadlib.c b/vscript/languages/lua/lua-5.1.4/src/loadlib.c new file mode 100644 index 00000000..0d401eba --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/loadlib.c @@ -0,0 +1,666 @@ +/* +** $Id: loadlib.c,v 1.52.1.3 2008/08/06 13:29:28 roberto Exp $ +** Dynamic library loader for Lua +** See Copyright Notice in lua.h +** +** This module contains an implementation of loadlib for Unix systems +** that have dlfcn, an implementation for Darwin (Mac OS X), an +** implementation for Windows, and a stub for other systems. +*/ + + +#include +#include + + +#define loadlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* prefix for open functions in C libraries */ +#define LUA_POF "luaopen_" + +/* separator for open functions in C libraries */ +#define LUA_OFSEP "_" + + +#define LIBPREFIX "LOADLIB: " + +#define POF LUA_POF +#define LIB_FAIL "open" + + +/* error codes for ll_loadfunc */ +#define ERRLIB 1 +#define ERRFUNC 2 + +#define setprogdir(L) ((void)0) + + +static void ll_unloadlib (void *lib); +static void *ll_load (lua_State *L, const char *path); +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); + + + +#if defined(LUA_DL_DLOPEN) +/* +** {======================================================================== +** This is an implementation of loadlib based on the dlfcn interface. +** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, +** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least +** as an emulation layer on top of native functions. +** ========================================================================= +*/ + +#include + +static void ll_unloadlib (void *lib) { + dlclose(lib); +} + + +static void *ll_load (lua_State *L, const char *path) { + void *lib = dlopen(path, RTLD_NOW); + if (lib == NULL) lua_pushstring(L, dlerror()); + return lib; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + lua_CFunction f = (lua_CFunction)dlsym(lib, sym); + if (f == NULL) lua_pushstring(L, dlerror()); + return f; +} + +/* }====================================================== */ + + + +#elif defined(LUA_DL_DLL) +/* +** {====================================================================== +** This is an implementation of loadlib for Windows using native functions. +** ======================================================================= +*/ + +#include + + +#undef setprogdir + +static void setprogdir (lua_State *L) { + char buff[MAX_PATH + 1]; + char *lb; + DWORD nsize = sizeof(buff)/sizeof(char); + DWORD n = GetModuleFileNameA(NULL, buff, nsize); + if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) + luaL_error(L, "unable to get ModuleFileName"); + else { + *lb = '\0'; + luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff); + lua_remove(L, -2); /* remove original string */ + } +} + + +static void pusherror (lua_State *L) { + int error = GetLastError(); + char buffer[128]; + if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, error, 0, buffer, sizeof(buffer), NULL)) + lua_pushstring(L, buffer); + else + lua_pushfstring(L, "system error %d\n", error); +} + +static void ll_unloadlib (void *lib) { + FreeLibrary((HINSTANCE)lib); +} + + +static void *ll_load (lua_State *L, const char *path) { + HINSTANCE lib = LoadLibraryA(path); + if (lib == NULL) pusherror(L); + return lib; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym); + if (f == NULL) pusherror(L); + return f; +} + +/* }====================================================== */ + + + +#elif defined(LUA_DL_DYLD) +/* +** {====================================================================== +** Native Mac OS X / Darwin Implementation +** ======================================================================= +*/ + +#include + + +/* Mac appends a `_' before C function names */ +#undef POF +#define POF "_" LUA_POF + + +static void pusherror (lua_State *L) { + const char *err_str; + const char *err_file; + NSLinkEditErrors err; + int err_num; + NSLinkEditError(&err, &err_num, &err_file, &err_str); + lua_pushstring(L, err_str); +} + + +static const char *errorfromcode (NSObjectFileImageReturnCode ret) { + switch (ret) { + case NSObjectFileImageInappropriateFile: + return "file is not a bundle"; + case NSObjectFileImageArch: + return "library is for wrong CPU type"; + case NSObjectFileImageFormat: + return "bad format"; + case NSObjectFileImageAccess: + return "cannot access file"; + case NSObjectFileImageFailure: + default: + return "unable to load library"; + } +} + + +static void ll_unloadlib (void *lib) { + NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES); +} + + +static void *ll_load (lua_State *L, const char *path) { + NSObjectFileImage img; + NSObjectFileImageReturnCode ret; + /* this would be a rare case, but prevents crashing if it happens */ + if(!_dyld_present()) { + lua_pushliteral(L, "dyld not present"); + return NULL; + } + ret = NSCreateObjectFileImageFromFile(path, &img); + if (ret == NSObjectFileImageSuccess) { + NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE | + NSLINKMODULE_OPTION_RETURN_ON_ERROR); + NSDestroyObjectFileImage(img); + if (mod == NULL) pusherror(L); + return mod; + } + lua_pushstring(L, errorfromcode(ret)); + return NULL; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym); + if (nss == NULL) { + lua_pushfstring(L, "symbol " LUA_QS " not found", sym); + return NULL; + } + return (lua_CFunction)NSAddressOfSymbol(nss); +} + +/* }====================================================== */ + + + +#else +/* +** {====================================================== +** Fallback for other systems +** ======================================================= +*/ + +#undef LIB_FAIL +#define LIB_FAIL "absent" + + +#define DLMSG "dynamic libraries not enabled; check your Lua installation" + + +static void ll_unloadlib (void *lib) { + (void)lib; /* to avoid warnings */ +} + + +static void *ll_load (lua_State *L, const char *path) { + (void)path; /* to avoid warnings */ + lua_pushliteral(L, DLMSG); + return NULL; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + (void)lib; (void)sym; /* to avoid warnings */ + lua_pushliteral(L, DLMSG); + return NULL; +} + +/* }====================================================== */ +#endif + + + +static void **ll_register (lua_State *L, const char *path) { + void **plib; + lua_pushfstring(L, "%s%s", LIBPREFIX, path); + lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */ + if (!lua_isnil(L, -1)) /* is there an entry? */ + plib = (void **)lua_touserdata(L, -1); + else { /* no entry yet; create one */ + lua_pop(L, 1); + plib = (void **)lua_newuserdata(L, sizeof(const void *)); + *plib = NULL; + luaL_getmetatable(L, "_LOADLIB"); + lua_setmetatable(L, -2); + lua_pushfstring(L, "%s%s", LIBPREFIX, path); + lua_pushvalue(L, -2); + lua_settable(L, LUA_REGISTRYINDEX); + } + return plib; +} + + +/* +** __gc tag method: calls library's `ll_unloadlib' function with the lib +** handle +*/ +static int gctm (lua_State *L) { + void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB"); + if (*lib) ll_unloadlib(*lib); + *lib = NULL; /* mark library as closed */ + return 0; +} + + +static int ll_loadfunc (lua_State *L, const char *path, const char *sym) { + void **reg = ll_register(L, path); + if (*reg == NULL) *reg = ll_load(L, path); + if (*reg == NULL) + return ERRLIB; /* unable to load library */ + else { + lua_CFunction f = ll_sym(L, *reg, sym); + if (f == NULL) + return ERRFUNC; /* unable to find function */ + lua_pushcfunction(L, f); + return 0; /* return function */ + } +} + + +static int ll_loadlib (lua_State *L) { + const char *path = luaL_checkstring(L, 1); + const char *init = luaL_checkstring(L, 2); + int stat = ll_loadfunc(L, path, init); + if (stat == 0) /* no errors? */ + return 1; /* return the loaded function */ + else { /* error; error message is on stack top */ + lua_pushnil(L); + lua_insert(L, -2); + lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); + return 3; /* return nil, error message, and where */ + } +} + + + +/* +** {====================================================== +** 'require' function +** ======================================================= +*/ + + +static int readable (const char *filename) { + FILE *f = fopen(filename, "r"); /* try to open file */ + if (f == NULL) return 0; /* open failed */ + fclose(f); + return 1; +} + + +static const char *pushnexttemplate (lua_State *L, const char *path) { + const char *l; + while (*path == *LUA_PATHSEP) path++; /* skip separators */ + if (*path == '\0') return NULL; /* no more templates */ + l = strchr(path, *LUA_PATHSEP); /* find next separator */ + if (l == NULL) l = path + strlen(path); + lua_pushlstring(L, path, l - path); /* template */ + return l; +} + + +static const char *findfile (lua_State *L, const char *name, + const char *pname) { + const char *path; + name = luaL_gsub(L, name, ".", LUA_DIRSEP); + lua_getfield(L, LUA_ENVIRONINDEX, pname); + path = lua_tostring(L, -1); + if (path == NULL) + luaL_error(L, LUA_QL("package.%s") " must be a string", pname); + lua_pushliteral(L, ""); /* error accumulator */ + while ((path = pushnexttemplate(L, path)) != NULL) { + const char *filename; + filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name); + lua_remove(L, -2); /* remove path template */ + if (readable(filename)) /* does file exist and is readable? */ + return filename; /* return that file name */ + lua_pushfstring(L, "\n\tno file " LUA_QS, filename); + lua_remove(L, -2); /* remove file name */ + lua_concat(L, 2); /* add entry to possible error message */ + } + return NULL; /* not found */ +} + + +static void loaderror (lua_State *L, const char *filename) { + luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s", + lua_tostring(L, 1), filename, lua_tostring(L, -1)); +} + + +static int loader_Lua (lua_State *L) { + const char *filename; + const char *name = luaL_checkstring(L, 1); + filename = findfile(L, name, "path"); + if (filename == NULL) return 1; /* library not found in this path */ + if (luaL_loadfile(L, filename) != 0) + loaderror(L, filename); + return 1; /* library loaded successfully */ +} + + +static const char *mkfuncname (lua_State *L, const char *modname) { + const char *funcname; + const char *mark = strchr(modname, *LUA_IGMARK); + if (mark) modname = mark + 1; + funcname = luaL_gsub(L, modname, ".", LUA_OFSEP); + funcname = lua_pushfstring(L, POF"%s", funcname); + lua_remove(L, -2); /* remove 'gsub' result */ + return funcname; +} + + +static int loader_C (lua_State *L) { + const char *funcname; + const char *name = luaL_checkstring(L, 1); + const char *filename = findfile(L, name, "cpath"); + if (filename == NULL) return 1; /* library not found in this path */ + funcname = mkfuncname(L, name); + if (ll_loadfunc(L, filename, funcname) != 0) + loaderror(L, filename); + return 1; /* library loaded successfully */ +} + + +static int loader_Croot (lua_State *L) { + const char *funcname; + const char *filename; + const char *name = luaL_checkstring(L, 1); + const char *p = strchr(name, '.'); + int stat; + if (p == NULL) return 0; /* is root */ + lua_pushlstring(L, name, p - name); + filename = findfile(L, lua_tostring(L, -1), "cpath"); + if (filename == NULL) return 1; /* root not found */ + funcname = mkfuncname(L, name); + if ((stat = ll_loadfunc(L, filename, funcname)) != 0) { + if (stat != ERRFUNC) loaderror(L, filename); /* real error */ + lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, + name, filename); + return 1; /* function not found */ + } + return 1; +} + + +static int loader_preload (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + lua_getfield(L, LUA_ENVIRONINDEX, "preload"); + if (!lua_istable(L, -1)) + luaL_error(L, LUA_QL("package.preload") " must be a table"); + lua_getfield(L, -1, name); + if (lua_isnil(L, -1)) /* not found? */ + lua_pushfstring(L, "\n\tno field package.preload['%s']", name); + return 1; +} + + +static const int sentinel_ = 0; +#define sentinel ((void *)&sentinel_) + + +static int ll_require (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + int i; + lua_settop(L, 1); /* _LOADED table will be at index 2 */ + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_getfield(L, 2, name); + if (lua_toboolean(L, -1)) { /* is it there? */ + if (lua_touserdata(L, -1) == sentinel) /* check loops */ + luaL_error(L, "loop or previous error loading module " LUA_QS, name); + return 1; /* package is already loaded */ + } + /* else must load it; iterate over available loaders */ + lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); + if (!lua_istable(L, -1)) + luaL_error(L, LUA_QL("package.loaders") " must be a table"); + lua_pushliteral(L, ""); /* error message accumulator */ + for (i=1; ; i++) { + lua_rawgeti(L, -2, i); /* get a loader */ + if (lua_isnil(L, -1)) + luaL_error(L, "module " LUA_QS " not found:%s", + name, lua_tostring(L, -2)); + lua_pushstring(L, name); + lua_call(L, 1, 1); /* call it */ + if (lua_isfunction(L, -1)) /* did it find module? */ + break; /* module loaded successfully */ + else if (lua_isstring(L, -1)) /* loader returned error message? */ + lua_concat(L, 2); /* accumulate it */ + else + lua_pop(L, 1); + } + lua_pushlightuserdata(L, sentinel); + lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */ + lua_pushstring(L, name); /* pass name as argument to module */ + lua_call(L, 1, 1); /* run loaded module */ + if (!lua_isnil(L, -1)) /* non-nil return? */ + lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ + lua_getfield(L, 2, name); + if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */ + lua_pushboolean(L, 1); /* use true as result */ + lua_pushvalue(L, -1); /* extra copy to be returned */ + lua_setfield(L, 2, name); /* _LOADED[name] = true */ + } + return 1; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** 'module' function +** ======================================================= +*/ + + +static void setfenv (lua_State *L) { + lua_Debug ar; + if (lua_getstack(L, 1, &ar) == 0 || + lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ + lua_iscfunction(L, -1)) + luaL_error(L, LUA_QL("module") " not called from a Lua function"); + lua_pushvalue(L, -2); + lua_setfenv(L, -2); + lua_pop(L, 1); +} + + +static void dooptions (lua_State *L, int n) { + int i; + for (i = 2; i <= n; i++) { + lua_pushvalue(L, i); /* get option (a function) */ + lua_pushvalue(L, -2); /* module */ + lua_call(L, 1, 0); + } +} + + +static void modinit (lua_State *L, const char *modname) { + const char *dot; + lua_pushvalue(L, -1); + lua_setfield(L, -2, "_M"); /* module._M = module */ + lua_pushstring(L, modname); + lua_setfield(L, -2, "_NAME"); + dot = strrchr(modname, '.'); /* look for last dot in module name */ + if (dot == NULL) dot = modname; + else dot++; + /* set _PACKAGE as package name (full module name minus last part) */ + lua_pushlstring(L, modname, dot - modname); + lua_setfield(L, -2, "_PACKAGE"); +} + + +static int ll_module (lua_State *L) { + const char *modname = luaL_checkstring(L, 1); + int loaded = lua_gettop(L) + 1; /* index of _LOADED table */ + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_getfield(L, loaded, modname); /* get _LOADED[modname] */ + if (!lua_istable(L, -1)) { /* not found? */ + lua_pop(L, 1); /* remove previous result */ + /* try global variable (and create one if it does not exist) */ + if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL) + return luaL_error(L, "name conflict for module " LUA_QS, modname); + lua_pushvalue(L, -1); + lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */ + } + /* check whether table already has a _NAME field */ + lua_getfield(L, -1, "_NAME"); + if (!lua_isnil(L, -1)) /* is table an initialized module? */ + lua_pop(L, 1); + else { /* no; initialize it */ + lua_pop(L, 1); + modinit(L, modname); + } + lua_pushvalue(L, -1); + setfenv(L); + dooptions(L, loaded - 1); + return 0; +} + + +static int ll_seeall (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + if (!lua_getmetatable(L, 1)) { + lua_createtable(L, 0, 1); /* create new metatable */ + lua_pushvalue(L, -1); + lua_setmetatable(L, 1); + } + lua_pushvalue(L, LUA_GLOBALSINDEX); + lua_setfield(L, -2, "__index"); /* mt.__index = _G */ + return 0; +} + + +/* }====================================================== */ + + + +/* auxiliary mark (for internal use) */ +#define AUXMARK "\1" + +static void setpath (lua_State *L, const char *fieldname, const char *envname, + const char *def) { + const char *path = getenv(envname); + if (path == NULL) /* no environment variable? */ + lua_pushstring(L, def); /* use default */ + else { + /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ + path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP, + LUA_PATHSEP AUXMARK LUA_PATHSEP); + luaL_gsub(L, path, AUXMARK, def); + lua_remove(L, -2); + } + setprogdir(L); + lua_setfield(L, -2, fieldname); +} + + +static const luaL_Reg pk_funcs[] = { + {"loadlib", ll_loadlib}, + {"seeall", ll_seeall}, + {NULL, NULL} +}; + + +static const luaL_Reg ll_funcs[] = { + {"module", ll_module}, + {"require", ll_require}, + {NULL, NULL} +}; + + +static const lua_CFunction loaders[] = + {loader_preload, loader_Lua, loader_C, loader_Croot, NULL}; + + +LUALIB_API int luaopen_package (lua_State *L) { + int i; + /* create new type _LOADLIB */ + luaL_newmetatable(L, "_LOADLIB"); + lua_pushcfunction(L, gctm); + lua_setfield(L, -2, "__gc"); + /* create `package' table */ + luaL_register(L, LUA_LOADLIBNAME, pk_funcs); +#if defined(LUA_COMPAT_LOADLIB) + lua_getfield(L, -1, "loadlib"); + lua_setfield(L, LUA_GLOBALSINDEX, "loadlib"); +#endif + lua_pushvalue(L, -1); + lua_replace(L, LUA_ENVIRONINDEX); + /* create `loaders' table */ + lua_createtable(L, 0, sizeof(loaders)/sizeof(loaders[0]) - 1); + /* fill it with pre-defined loaders */ + for (i=0; loaders[i] != NULL; i++) { + lua_pushcfunction(L, loaders[i]); + lua_rawseti(L, -2, i+1); + } + lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */ + setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */ + setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */ + /* store config information */ + lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" + LUA_EXECDIR "\n" LUA_IGMARK); + lua_setfield(L, -2, "config"); + /* set field `loaded' */ + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2); + lua_setfield(L, -2, "loaded"); + /* set field `preload' */ + lua_newtable(L); + lua_setfield(L, -2, "preload"); + lua_pushvalue(L, LUA_GLOBALSINDEX); + luaL_register(L, NULL, ll_funcs); /* open lib into global table */ + lua_pop(L, 1); + return 1; /* return 'package' table */ +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/lobject.c b/vscript/languages/lua/lua-5.1.4/src/lobject.c new file mode 100644 index 00000000..4ff50732 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lobject.c @@ -0,0 +1,214 @@ +/* +** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $ +** Some generic functions over Lua objects +** See Copyright Notice in lua.h +*/ + +#include +#include +#include +#include +#include + +#define lobject_c +#define LUA_CORE + +#include "lua.h" + +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "lvm.h" + + + +const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL}; + + +/* +** 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. +*/ +int luaO_int2fb (unsigned int x) { + int e = 0; /* expoent */ + while (x >= 16) { + x = (x+1) >> 1; + e++; + } + if (x < 8) return x; + else return ((e+1) << 3) | (cast_int(x) - 8); +} + + +/* converts back */ +int luaO_fb2int (int x) { + int e = (x >> 3) & 31; + if (e == 0) return x; + else return ((x & 7)+8) << (e - 1); +} + + +int luaO_log2 (unsigned int x) { + static const lu_byte log_2[256] = { + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 + }; + int l = -1; + while (x >= 256) { l += 8; x >>= 8; } + return l + log_2[x]; + +} + + +int luaO_rawequalObj (const TValue *t1, const TValue *t2) { + if (ttype(t1) != ttype(t2)) return 0; + else switch (ttype(t1)) { + case LUA_TNIL: + return 1; + case LUA_TNUMBER: + return luai_numeq(nvalue(t1), nvalue(t2)); + case LUA_TBOOLEAN: + return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ + case LUA_TLIGHTUSERDATA: + return pvalue(t1) == pvalue(t2); + default: + lua_assert(iscollectable(t1)); + return gcvalue(t1) == gcvalue(t2); + } +} + + +int luaO_str2d (const char *s, lua_Number *result) { + char *endptr; + *result = lua_str2number(s, &endptr); + if (endptr == s) return 0; /* conversion failed */ + if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ + *result = cast_num(strtoul(s, &endptr, 16)); + if (*endptr == '\0') return 1; /* most common case */ + while (isspace(cast(unsigned char, *endptr))) endptr++; + if (*endptr != '\0') return 0; /* invalid trailing characters? */ + return 1; +} + + + +static void pushstr (lua_State *L, const char *str) { + setsvalue2s(L, L->top, luaS_new(L, str)); + incr_top(L); +} + + +/* this function handles only `%d', `%c', %f, %p, and `%s' formats */ +const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { + int n = 1; + pushstr(L, ""); + for (;;) { + const char *e = strchr(fmt, '%'); + if (e == NULL) break; + setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt)); + incr_top(L); + switch (*(e+1)) { + case 's': { + const char *s = va_arg(argp, char *); + if (s == NULL) s = "(null)"; + pushstr(L, s); + break; + } + case 'c': { + char buff[2]; + buff[0] = cast(char, va_arg(argp, int)); + buff[1] = '\0'; + pushstr(L, buff); + break; + } + case 'd': { + setnvalue(L->top, cast_num(va_arg(argp, int))); + incr_top(L); + break; + } + case 'f': { + setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); + incr_top(L); + break; + } + case 'p': { + char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ + sprintf(buff, "%p", va_arg(argp, void *)); + pushstr(L, buff); + break; + } + case '%': { + pushstr(L, "%"); + break; + } + default: { + char buff[3]; + buff[0] = '%'; + buff[1] = *(e+1); + buff[2] = '\0'; + pushstr(L, buff); + break; + } + } + n += 2; + fmt = e+2; + } + pushstr(L, fmt); + luaV_concat(L, n+1, cast_int(L->top - L->base) - 1); + L->top -= n; + return svalue(L->top - 1); +} + + +const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { + const char *msg; + va_list argp; + va_start(argp, fmt); + msg = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + return msg; +} + + +void luaO_chunkid (char *out, const char *source, size_t bufflen) { + if (*source == '=') { + strncpy(out, source+1, bufflen); /* remove first char */ + out[bufflen-1] = '\0'; /* ensures null termination */ + } + else { /* out = "source", or "...source" */ + if (*source == '@') { + size_t l; + source++; /* skip the `@' */ + bufflen -= sizeof(" '...' "); + l = strlen(source); + strcpy(out, ""); + if (l > bufflen) { + source += (l-bufflen); /* get last part of file name */ + strcat(out, "..."); + } + strcat(out, source); + } + else { /* out = [string "string"] */ + size_t len = strcspn(source, "\n\r"); /* stop at first newline */ + bufflen -= sizeof(" [string \"...\"] "); + if (len > bufflen) len = bufflen; + strcpy(out, "[string \""); + if (source[len] != '\0') { /* must truncate? */ + strncat(out, source, len); + strcat(out, "..."); + } + else + strcat(out, source); + strcat(out, "\"]"); + } + } +} diff --git a/vscript/languages/lua/lua-5.1.4/src/lobject.h b/vscript/languages/lua/lua-5.1.4/src/lobject.h new file mode 100644 index 00000000..ccfe404e --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lobject.h @@ -0,0 +1,384 @@ +/* +** $Id: lobject.h,v 2.20.1.2 2008/08/06 13:29:48 roberto Exp $ +** Type definitions for Lua objects +** See Copyright Notice in lua.h +*/ + + +#ifndef lobject_h +#define lobject_h + + +#include + + +#include "llimits.h" +#include "lua.h" + + +/* tags for values visible from Lua */ +#define LAST_TAG LUA_TTHREAD + +#define NUM_TAGS (LAST_TAG+1) + + +/* +** Extra tags for non-values +*/ +#define LUA_TPROTO (LAST_TAG+1) +#define LUA_TUPVAL (LAST_TAG+2) +#define LUA_TDEADKEY (LAST_TAG+3) + + +/* +** Union of all collectable objects +*/ +typedef union GCObject GCObject; + + +/* +** Common Header for all collectable objects (in macro form, to be +** included in other objects) +*/ +#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked + + +/* +** Common header in struct form +*/ +typedef struct GCheader { + CommonHeader; +} GCheader; + + + + +/* +** Union of all Lua values +*/ +typedef union { + GCObject *gc; + void *p; + lua_Number n; + int b; +} Value; + + +/* +** Tagged Values +*/ + +#define TValuefields Value value; int tt + +typedef struct lua_TValue { + TValuefields; +} TValue; + + +/* Macros to test type */ +#define ttisnil(o) (ttype(o) == LUA_TNIL) +#define ttisnumber(o) (ttype(o) == LUA_TNUMBER) +#define ttisstring(o) (ttype(o) == LUA_TSTRING) +#define ttistable(o) (ttype(o) == LUA_TTABLE) +#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION) +#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) +#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) +#define ttisthread(o) (ttype(o) == LUA_TTHREAD) +#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA) + +/* Macros to access values */ +#define ttype(o) ((o)->tt) +#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc) +#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p) +#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n) +#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts) +#define tsvalue(o) (&rawtsvalue(o)->tsv) +#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u) +#define uvalue(o) (&rawuvalue(o)->uv) +#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl) +#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h) +#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b) +#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th) + +#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) + +/* +** for internal debug only +*/ +#define checkconsistency(obj) \ + lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt)) + +#define checkliveness(g,obj) \ + lua_assert(!iscollectable(obj) || \ + ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc))) + + +/* Macros to set values */ +#define setnilvalue(obj) ((obj)->tt=LUA_TNIL) + +#define setnvalue(obj,x) \ + { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; } + +#define setpvalue(obj,x) \ + { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; } + +#define setbvalue(obj,x) \ + { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; } + +#define setsvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \ + checkliveness(G(L),i_o); } + +#define setuvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \ + checkliveness(G(L),i_o); } + +#define setthvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \ + checkliveness(G(L),i_o); } + +#define setclvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \ + checkliveness(G(L),i_o); } + +#define sethvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \ + checkliveness(G(L),i_o); } + +#define setptvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \ + checkliveness(G(L),i_o); } + + + + +#define setobj(L,obj1,obj2) \ + { const TValue *o2=(obj2); TValue *o1=(obj1); \ + o1->value = o2->value; o1->tt=o2->tt; \ + checkliveness(G(L),o1); } + + +/* +** different types of sets, according to destination +*/ + +/* from stack to (same) stack */ +#define setobjs2s setobj +/* to stack (not from same stack) */ +#define setobj2s setobj +#define setsvalue2s setsvalue +#define sethvalue2s sethvalue +#define setptvalue2s setptvalue +/* from table to same table */ +#define setobjt2t setobj +/* to table */ +#define setobj2t setobj +/* to new object */ +#define setobj2n setobj +#define setsvalue2n setsvalue + +#define setttype(obj, tt) (ttype(obj) = (tt)) + + +#define iscollectable(o) (ttype(o) >= LUA_TSTRING) + + + +typedef TValue *StkId; /* index to stack elements */ + + +/* +** String headers for string table +*/ +typedef union TString { + L_Umaxalign dummy; /* ensures maximum alignment for strings */ + struct { + CommonHeader; + lu_byte reserved; + unsigned int hash; +#ifdef LUA_MOD_CASE_INSENSITIVE + unsigned int keyhash; +#endif + size_t len; + } tsv; +} TString; + + +#define getstr(ts) cast(const char *, (ts) + 1) +#define svalue(o) getstr(rawtsvalue(o)) + + + +typedef union Udata { + L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ + struct { + CommonHeader; + struct Table *metatable; + struct Table *env; + size_t len; + } uv; +} Udata; + + + + +/* +** Function Prototypes +*/ +typedef struct Proto { + CommonHeader; + TValue *k; /* constants used by the function */ + Instruction *code; + struct Proto **p; /* functions defined inside the function */ + int *lineinfo; /* map from opcodes to source lines */ + struct LocVar *locvars; /* information about local variables */ + TString **upvalues; /* upvalue names */ + TString *source; + int sizeupvalues; + int sizek; /* size of `k' */ + int sizecode; + int sizelineinfo; + int sizep; /* size of `p' */ + int sizelocvars; + int linedefined; + int lastlinedefined; + GCObject *gclist; + lu_byte nups; /* number of upvalues */ + lu_byte numparams; + lu_byte is_vararg; + lu_byte maxstacksize; +} Proto; + + +/* masks for new-style vararg */ +#define VARARG_HASARG 1 +#define VARARG_ISVARARG 2 +#define VARARG_NEEDSARG 4 + + +typedef struct LocVar { + TString *varname; + int startpc; /* first point where variable is active */ + int endpc; /* first point where variable is dead */ +} LocVar; + + + +/* +** Upvalues +*/ + +typedef struct UpVal { + CommonHeader; + TValue *v; /* points to stack or to its own value */ + union { + TValue value; /* the value (when closed) */ + struct { /* double linked list (when open) */ + struct UpVal *prev; + struct UpVal *next; + } l; + } u; +} UpVal; + + +/* +** Closures +*/ + +#define ClosureHeader \ + CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \ + struct Table *env + +typedef struct CClosure { + ClosureHeader; + lua_CFunction f; + TValue upvalue[1]; +} CClosure; + + +typedef struct LClosure { + ClosureHeader; + struct Proto *p; + UpVal *upvals[1]; +} LClosure; + + +typedef union Closure { + CClosure c; + LClosure l; +} Closure; + + +#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC) +#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC) + + +/* +** Tables +*/ + +typedef union TKey { + struct { + TValuefields; + struct Node *next; /* for chaining */ + } nk; + TValue tvk; +} TKey; + + +typedef struct Node { + TValue i_val; + TKey i_key; +} Node; + + +typedef struct Table { + CommonHeader; + lu_byte flags; /* 1<

lsizenode)) + + +#define luaO_nilobject (&luaO_nilobject_) + +LUAI_DATA const TValue luaO_nilobject_; + +#define ceillog2(x) (luaO_log2((x)-1) + 1) + +LUAI_FUNC int luaO_log2 (unsigned int x); +LUAI_FUNC int luaO_int2fb (unsigned int x); +LUAI_FUNC int luaO_fb2int (int x); +LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2); +LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result); +LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, + va_list argp); +LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); +LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len); + + +#endif + diff --git a/vscript/languages/lua/lua-5.1.4/src/lopcodes.c b/vscript/languages/lua/lua-5.1.4/src/lopcodes.c new file mode 100644 index 00000000..4cc74523 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lopcodes.c @@ -0,0 +1,102 @@ +/* +** $Id: lopcodes.c,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ +** See Copyright Notice in lua.h +*/ + + +#define lopcodes_c +#define LUA_CORE + + +#include "lopcodes.h" + + +/* ORDER OP */ + +const char *const luaP_opnames[NUM_OPCODES+1] = { + "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 +}; + + +#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) + +const lu_byte luaP_opmodes[NUM_OPCODES] = { +/* T A B C mode opcode */ + opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ + ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ + ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */ + ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ + ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */ + ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ + ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ + ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ + ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ + ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ + ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */ + ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ + ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ + ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */ + ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ + ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ + ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ +}; + diff --git a/vscript/languages/lua/lua-5.1.4/src/lopcodes.h b/vscript/languages/lua/lua-5.1.4/src/lopcodes.h new file mode 100644 index 00000000..41224d6e --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lopcodes.h @@ -0,0 +1,268 @@ +/* +** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $ +** Opcodes for Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lopcodes_h +#define lopcodes_h + +#include "llimits.h" + + +/*=========================================================================== + We assume that instructions are unsigned numbers. + All instructions have an opcode in the first 6 bits. + Instructions can have the following fields: + `A' : 8 bits + `B' : 9 bits + `C' : 9 bits + `Bx' : 18 bits (`B' and `C' together) + `sBx' : signed Bx + + A signed argument is represented in excess K; that is, the number + value is the unsigned value minus K. K is exactly the maximum value + for that argument (so that -max is represented by 0, and +max is + represented by 2*max), which is half the maximum for the corresponding + unsigned argument. +===========================================================================*/ + + +enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ + + +/* +** size and position of opcode arguments. +*/ +#define SIZE_C 9 +#define SIZE_B 9 +#define SIZE_Bx (SIZE_C + SIZE_B) +#define SIZE_A 8 + +#define SIZE_OP 6 + +#define POS_OP 0 +#define POS_A (POS_OP + SIZE_OP) +#define POS_C (POS_A + SIZE_A) +#define POS_B (POS_C + SIZE_C) +#define POS_Bx POS_C + + +/* +** limits for opcode arguments. +** we use (signed) int to manipulate most arguments, +** so they must fit in LUAI_BITSINT-1 bits (-1 for sign) +*/ +#if SIZE_Bx < LUAI_BITSINT-1 +#define MAXARG_Bx ((1<>1) /* `sBx' is signed */ +#else +#define MAXARG_Bx MAX_INT +#define MAXARG_sBx MAX_INT +#endif + + +#define MAXARG_A ((1<>POS_OP) & MASK1(SIZE_OP,0))) +#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ + ((cast(Instruction, o)<>POS_A) & MASK1(SIZE_A,0))) +#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ + ((cast(Instruction, u)<>POS_B) & MASK1(SIZE_B,0))) +#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \ + ((cast(Instruction, b)<>POS_C) & MASK1(SIZE_C,0))) +#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \ + ((cast(Instruction, b)<>POS_Bx) & MASK1(SIZE_Bx,0))) +#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \ + ((cast(Instruction, b)< C) then pc++ */ +OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ + +OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ + +OP_FORLOOP,/* A sBx R(A)+=R(A+2); + if R(A) =) R(A)*/ +OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ + +OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ +} OpCode; + + +#define NUM_OPCODES (cast(int, 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 +*/ + +enum OpArgMask { + OpArgN, /* argument is not used */ + OpArgU, /* argument is used */ + OpArgR, /* argument is a register or a jump offset */ + OpArgK /* argument is a constant or register/constant */ +}; + +LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES]; + +#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) +#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3)) +#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3)) +#define testAMode(m) (luaP_opmodes[m] & (1 << 6)) +#define testTMode(m) (luaP_opmodes[m] & (1 << 7)) + + +LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ + + +/* number of list items to accumulate before a SETLIST instruction */ +#define LFIELDS_PER_FLUSH 50 + + +#endif diff --git a/vscript/languages/lua/lua-5.1.4/src/loslib.c b/vscript/languages/lua/lua-5.1.4/src/loslib.c new file mode 100644 index 00000000..da06a572 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/loslib.c @@ -0,0 +1,243 @@ +/* +** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $ +** Standard Operating System library +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include + +#define loslib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +static int os_pushresult (lua_State *L, int i, const char *filename) { + int en = errno; /* calls to Lua API may change this value */ + if (i) { + lua_pushboolean(L, 1); + return 1; + } + else { + lua_pushnil(L); + lua_pushfstring(L, "%s: %s", filename, strerror(en)); + lua_pushinteger(L, en); + return 3; + } +} + + +static int os_execute (lua_State *L) { + lua_pushinteger(L, system(luaL_optstring(L, 1, NULL))); + return 1; +} + + +static int os_remove (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + return os_pushresult(L, remove(filename) == 0, filename); +} + + +static int os_rename (lua_State *L) { + const char *fromname = luaL_checkstring(L, 1); + const char *toname = luaL_checkstring(L, 2); + return os_pushresult(L, rename(fromname, toname) == 0, fromname); +} + + +static int os_tmpname (lua_State *L) { + char buff[LUA_TMPNAMBUFSIZE]; + int err; + lua_tmpnam(buff, err); + if (err) + return luaL_error(L, "unable to generate a unique filename"); + lua_pushstring(L, buff); + return 1; +} + + +static int os_getenv (lua_State *L) { + lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ + return 1; +} + + +static int os_clock (lua_State *L) { + lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); + return 1; +} + + +/* +** {====================================================== +** Time/Date operations +** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, +** wday=%w+1, yday=%j, isdst=? } +** ======================================================= +*/ + +static void setfield (lua_State *L, const char *key, int value) { + lua_pushinteger(L, value); + lua_setfield(L, -2, key); +} + +static void setboolfield (lua_State *L, const char *key, int value) { + if (value < 0) /* undefined? */ + return; /* does not set field */ + lua_pushboolean(L, value); + lua_setfield(L, -2, key); +} + +static int getboolfield (lua_State *L, const char *key) { + int res; + lua_getfield(L, -1, key); + res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1); + lua_pop(L, 1); + return res; +} + + +static int getfield (lua_State *L, const char *key, int d) { + int res; + lua_getfield(L, -1, key); + if (lua_isnumber(L, -1)) + res = (int)lua_tointeger(L, -1); + else { + if (d < 0) + return luaL_error(L, "field " LUA_QS " missing in date table", key); + res = d; + } + lua_pop(L, 1); + return res; +} + + +static int os_date (lua_State *L) { + const char *s = luaL_optstring(L, 1, "%c"); + time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL)); + struct tm *stm; + if (*s == '!') { /* UTC? */ + stm = gmtime(&t); + s++; /* skip `!' */ + } + else + stm = localtime(&t); + if (stm == NULL) /* invalid date? */ + lua_pushnil(L); + else if (strcmp(s, "*t") == 0) { + lua_createtable(L, 0, 9); /* 9 = number of fields */ + setfield(L, "sec", stm->tm_sec); + setfield(L, "min", stm->tm_min); + setfield(L, "hour", stm->tm_hour); + setfield(L, "day", stm->tm_mday); + setfield(L, "month", stm->tm_mon+1); + setfield(L, "year", stm->tm_year+1900); + setfield(L, "wday", stm->tm_wday+1); + setfield(L, "yday", stm->tm_yday+1); + setboolfield(L, "isdst", stm->tm_isdst); + } + else { + char cc[3]; + luaL_Buffer b; + cc[0] = '%'; cc[2] = '\0'; + luaL_buffinit(L, &b); + for (; *s; s++) { + if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */ + luaL_addchar(&b, *s); + else { + size_t reslen; + char buff[200]; /* should be big enough for any conversion result */ + cc[1] = *(++s); + reslen = strftime(buff, sizeof(buff), cc, stm); + luaL_addlstring(&b, buff, reslen); + } + } + luaL_pushresult(&b); + } + return 1; +} + + +static int os_time (lua_State *L) { + time_t t; + if (lua_isnoneornil(L, 1)) /* called without args? */ + t = time(NULL); /* get current time */ + else { + struct tm ts; + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 1); /* make sure table is at the top */ + ts.tm_sec = getfield(L, "sec", 0); + ts.tm_min = getfield(L, "min", 0); + ts.tm_hour = getfield(L, "hour", 12); + ts.tm_mday = getfield(L, "day", -1); + ts.tm_mon = getfield(L, "month", -1) - 1; + ts.tm_year = getfield(L, "year", -1) - 1900; + ts.tm_isdst = getboolfield(L, "isdst"); + t = mktime(&ts); + } + if (t == (time_t)(-1)) + lua_pushnil(L); + else + lua_pushnumber(L, (lua_Number)t); + return 1; +} + + +static int os_difftime (lua_State *L) { + lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), + (time_t)(luaL_optnumber(L, 2, 0)))); + return 1; +} + +/* }====================================================== */ + + +static int os_setlocale (lua_State *L) { + static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, + LC_NUMERIC, LC_TIME}; + static const char *const catnames[] = {"all", "collate", "ctype", "monetary", + "numeric", "time", NULL}; + const char *l = luaL_optstring(L, 1, NULL); + int op = luaL_checkoption(L, 2, "all", catnames); + lua_pushstring(L, setlocale(cat[op], l)); + return 1; +} + + +static int os_exit (lua_State *L) { + exit(luaL_optint(L, 1, EXIT_SUCCESS)); +} + +static const luaL_Reg syslib[] = { + {"clock", os_clock}, + {"date", os_date}, + {"difftime", os_difftime}, + {"execute", os_execute}, + {"exit", os_exit}, + {"getenv", os_getenv}, + {"remove", os_remove}, + {"rename", os_rename}, + {"setlocale", os_setlocale}, + {"time", os_time}, + {"tmpname", os_tmpname}, + {NULL, NULL} +}; + +/* }====================================================== */ + + + +LUALIB_API int luaopen_os (lua_State *L) { + luaL_register(L, LUA_OSLIBNAME, syslib); + return 1; +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/lparser.c b/vscript/languages/lua/lua-5.1.4/src/lparser.c new file mode 100644 index 00000000..15ea35bd --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lparser.c @@ -0,0 +1,1359 @@ +/* +** $Id: lparser.c,v 2.42.1.3 2007/12/28 15:32:23 roberto Exp $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + + +#include + +#define lparser_c +#define LUA_CORE + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" + + + +#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) + +#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) + +#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m) + + +/* +** nodes for block list (list of active blocks) +*/ +typedef struct BlockCnt { + struct BlockCnt *previous; /* chain */ + int breaklist; /* list of jumps out of this loop */ + lu_byte nactvar; /* # active locals outside the breakable structure */ + lu_byte upval; /* true if some variable in the block is an upvalue */ + lu_byte isbreakable; /* true if `block' is a loop */ +} BlockCnt; + + + +/* +** prototypes for recursive non-terminal functions +*/ +static void chunk (LexState *ls); +static void expr (LexState *ls, expdesc *v); + + +static void anchor_token (LexState *ls) { + if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) { + TString *ts = ls->t.seminfo.ts; + luaX_newstring(ls, getstr(ts), ts->tsv.len); + } +} + + +static void error_expected (LexState *ls, int token) { + luaX_syntaxerror(ls, + luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token))); +} + + +static void errorlimit (FuncState *fs, int limit, const char *what) { + const char *msg = (fs->f->linedefined == 0) ? + luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) : + luaO_pushfstring(fs->L, "function at line %d has more than %d %s", + fs->f->linedefined, limit, what); + luaX_lexerror(fs->ls, msg, 0); +} + + +static int testnext (LexState *ls, int c) { + if (ls->t.token == c) { + luaX_next(ls); + return 1; + } + else return 0; +} + + +static void check (LexState *ls, int c) { + if (ls->t.token != c) + error_expected(ls, c); +} + +static void checknext (LexState *ls, int c) { + check(ls, c); + luaX_next(ls); +} + + +#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } + + + +static void check_match (LexState *ls, int what, int who, int where) { + if (!testnext(ls, what)) { + if (where == ls->linenumber) + error_expected(ls, what); + else { + luaX_syntaxerror(ls, luaO_pushfstring(ls->L, + LUA_QS " expected (to close " LUA_QS " at line %d)", + luaX_token2str(ls, what), luaX_token2str(ls, who), where)); + } + } +} + + +static TString *str_checkname (LexState *ls) { + TString *ts; + check(ls, TK_NAME); + ts = ls->t.seminfo.ts; + luaX_next(ls); + return ts; +} + + +static void init_exp (expdesc *e, expkind k, int i) { + e->f = e->t = NO_JUMP; + e->k = k; + e->u.s.info = i; +} + + +static void codestring (LexState *ls, expdesc *e, TString *s) { + init_exp(e, VK, luaK_stringK(ls->fs, s)); +} + + +static void checkname(LexState *ls, expdesc *e) { + codestring(ls, e, str_checkname(ls)); +} + + +#ifdef LUA_MOD_CASE_INSENSITIVE +#define cmpname(s1,s2) ((s1) == (s2) || comparename(s1, s2)) +static int comparename(const TString *s1, const TString *s2) { + return (s1->tsv.keyhash == s2->tsv.keyhash) && + (luai_strcasecmp(getstr(s1), getstr(s2)) == 0); +} +#endif + + +static int registerlocalvar (LexState *ls, TString *varname) { + FuncState *fs = ls->fs; + Proto *f = fs->f; + int oldsize = f->sizelocvars; + luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, + LocVar, SHRT_MAX, "too many local variables"); + while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; + f->locvars[fs->nlocvars].varname = varname; + luaC_objbarrier(ls->L, f, varname); + return fs->nlocvars++; +} + + +#define new_localvarliteral(ls,v,n) \ + new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n) + + +static void new_localvar (LexState *ls, TString *name, int n) { + FuncState *fs = ls->fs; + luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables"); + fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name)); +} + + +static void adjustlocalvars (LexState *ls, int nvars) { + FuncState *fs = ls->fs; + fs->nactvar = cast_byte(fs->nactvar + nvars); + for (; nvars; nvars--) { + getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc; + } +} + + +static void removevars (LexState *ls, int tolevel) { + FuncState *fs = ls->fs; + while (fs->nactvar > tolevel) + getlocvar(fs, --fs->nactvar).endpc = fs->pc; +} + + +static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { + int i; + Proto *f = fs->f; + int oldsize = f->sizeupvalues; + for (i=0; inups; i++) { + if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) { +#ifdef LUA_MOD_CASE_INSENSITIVE + lua_assert(cmpname(f->upvalues[i], name)); +#else + lua_assert(f->upvalues[i] == name); +#endif + return i; + } + } + /* new one */ + luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues"); + luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues, + TString *, MAX_INT, ""); + while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL; + f->upvalues[f->nups] = name; + luaC_objbarrier(fs->L, f, name); + lua_assert(v->k == VLOCAL || v->k == VUPVAL); + fs->upvalues[f->nups].k = cast_byte(v->k); + fs->upvalues[f->nups].info = cast_byte(v->u.s.info); + return f->nups++; +} + + +static int searchvar (FuncState *fs, TString *n) { + int i; + for (i=fs->nactvar-1; i >= 0; i--) { +#ifdef LUA_MOD_CASE_INSENSITIVE + if (cmpname(getlocvar(fs, i).varname, n)) +#else + if (n == getlocvar(fs, i).varname) +#endif + return i; + } + return -1; /* not found */ +} + + +static void markupval (FuncState *fs, int level) { + BlockCnt *bl = fs->bl; + while (bl && bl->nactvar > level) bl = bl->previous; + if (bl) bl->upval = 1; +} + + +static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { + if (fs == NULL) { /* no more levels? */ + init_exp(var, VGLOBAL, NO_REG); /* default is global variable */ + return VGLOBAL; + } + else { + int v = searchvar(fs, n); /* look up at current level */ + if (v >= 0) { + init_exp(var, VLOCAL, v); + if (!base) + markupval(fs, v); /* local will be used as an upval */ + return VLOCAL; + } + else { /* not found at current level; try upper one */ + if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL) + return VGLOBAL; + var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */ + var->k = VUPVAL; /* upvalue in this level */ + return VUPVAL; + } + } +} + + +static void singlevar (LexState *ls, expdesc *var) { + TString *varname = str_checkname(ls); + FuncState *fs = ls->fs; + if (singlevaraux(fs, varname, var, 1) == VGLOBAL) + var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */ +} + + +static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { + FuncState *fs = ls->fs; + int extra = nvars - nexps; + if (hasmultret(e->k)) { + extra++; /* includes call itself */ + if (extra < 0) extra = 0; + luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ + if (extra > 1) luaK_reserveregs(fs, extra-1); + } + else { + if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ + if (extra > 0) { + int reg = fs->freereg; + luaK_reserveregs(fs, extra); + luaK_nil(fs, reg, extra); + } + } +} + + +static void enterlevel (LexState *ls) { + if (++ls->L->nCcalls > LUAI_MAXCCALLS) + luaX_lexerror(ls, "chunk has too many syntax levels", 0); +} + + +#define leavelevel(ls) ((ls)->L->nCcalls--) + + +static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) { + bl->breaklist = NO_JUMP; + bl->isbreakable = isbreakable; + bl->nactvar = fs->nactvar; + bl->upval = 0; + bl->previous = fs->bl; + fs->bl = bl; + lua_assert(fs->freereg == fs->nactvar); +} + + +static void leaveblock (FuncState *fs) { + BlockCnt *bl = fs->bl; + fs->bl = bl->previous; + removevars(fs->ls, bl->nactvar); + if (bl->upval) + luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); + /* a block either controls scope or breaks (never both) */ + lua_assert(!bl->isbreakable || !bl->upval); + lua_assert(bl->nactvar == fs->nactvar); + fs->freereg = fs->nactvar; /* free registers */ + luaK_patchtohere(fs, bl->breaklist); +} + + +static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { + FuncState *fs = ls->fs; + Proto *f = fs->f; + int oldsize = f->sizep; + int i; + luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, + MAXARG_Bx, "constant table overflow"); + while (oldsize < f->sizep) f->p[oldsize++] = NULL; + f->p[fs->np++] = func->f; + luaC_objbarrier(ls->L, f, func->f); + init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); + for (i=0; if->nups; i++) { + OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; + luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); + } +} + + +static void open_func (LexState *ls, FuncState *fs) { + lua_State *L = ls->L; + Proto *f = luaF_newproto(L); + fs->f = f; + fs->prev = ls->fs; /* linked list of funcstates */ + fs->ls = ls; + fs->L = L; + ls->fs = fs; + fs->pc = 0; + fs->lasttarget = -1; + fs->jpc = NO_JUMP; + fs->freereg = 0; + fs->nk = 0; + fs->np = 0; + fs->nlocvars = 0; + fs->nactvar = 0; + fs->bl = NULL; + f->source = ls->source; + f->maxstacksize = 2; /* registers 0/1 are always valid */ + fs->h = luaH_new(L, 0, 0); +#ifdef LUA_MOD_CASE_INSENSITIVE + luaH_setflag(fs->h, TH_SYMTABLE, 0); /* clear symbol table flag for case-sensitive keys */ +#endif + /* anchor table of constants and prototype (to avoid being collected) */ + sethvalue2s(L, L->top, fs->h); + incr_top(L); + setptvalue2s(L, L->top, f); + incr_top(L); +} + + +static void close_func (LexState *ls) { + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Proto *f = fs->f; + removevars(ls, 0); + luaK_ret(fs, 0, 0); /* final return */ + luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); + f->sizecode = fs->pc; + luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); + f->sizelineinfo = fs->pc; + luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); + f->sizek = fs->nk; + luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); + f->sizep = fs->np; + luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); + f->sizelocvars = fs->nlocvars; + luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *); + f->sizeupvalues = f->nups; + lua_assert(luaG_checkcode(f)); + lua_assert(fs->bl == NULL); + ls->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) anchor_token(ls); +} + + +Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { + struct LexState lexstate; + struct FuncState funcstate; + lexstate.buff = buff; + luaX_setinput(L, &lexstate, z, luaS_new(L, name)); + open_func(&lexstate, &funcstate); + funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */ + luaX_next(&lexstate); /* read first token */ + chunk(&lexstate); + check(&lexstate, TK_EOS); + close_func(&lexstate); + lua_assert(funcstate.prev == NULL); + lua_assert(funcstate.f->nups == 0); + lua_assert(lexstate.fs == NULL); + return funcstate.f; +} + + + +/*============================================================*/ +/* GRAMMAR RULES */ +/*============================================================*/ + + +static void field (LexState *ls, expdesc *v) { + /* field -> ['.' | ':'] NAME */ + FuncState *fs = ls->fs; + expdesc key; + luaK_exp2anyreg(fs, v); + luaX_next(ls); /* skip the dot or colon */ + checkname(ls, &key); + luaK_indexed(fs, v, &key); +} + + +static void yindex (LexState *ls, expdesc *v) { + /* index -> '[' expr ']' */ + luaX_next(ls); /* skip the '[' */ + expr(ls, v); + luaK_exp2val(ls->fs, v); + checknext(ls, ']'); +} + + +/* +** {====================================================================== +** Rules for Constructors +** ======================================================================= +*/ + + +struct ConsControl { + expdesc v; /* 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 */ +}; + + +static void recfield (LexState *ls, struct ConsControl *cc) { + /* recfield -> (NAME | `['exp1`]') = exp1 */ + FuncState *fs = ls->fs; + int reg = ls->fs->freereg; + expdesc key, val; + int rkkey; + if (ls->t.token == TK_NAME) { + luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); + checkname(ls, &key); + } + else /* ls->t.token == '[' */ + yindex(ls, &key); + cc->nh++; + checknext(ls, '='); + rkkey = luaK_exp2RK(fs, &key); + expr(ls, &val); + luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val)); + fs->freereg = reg; /* free registers */ +} + + +static void closelistfield (FuncState *fs, struct ConsControl *cc) { + if (cc->v.k == VVOID) return; /* there is no list item */ + luaK_exp2nextreg(fs, &cc->v); + cc->v.k = VVOID; + if (cc->tostore == LFIELDS_PER_FLUSH) { + luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */ + cc->tostore = 0; /* no more items pending */ + } +} + + +static void lastlistfield (FuncState *fs, struct ConsControl *cc) { + if (cc->tostore == 0) return; + if (hasmultret(cc->v.k)) { + luaK_setmultret(fs, &cc->v); + luaK_setlist(fs, 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 != VVOID) + luaK_exp2nextreg(fs, &cc->v); + luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); + } +} + + +static void listfield (LexState *ls, struct ConsControl *cc) { + expr(ls, &cc->v); + luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); + cc->na++; + cc->tostore++; +} + + +static void constructor (LexState *ls, expdesc *t) { + /* constructor -> ?? */ + FuncState *fs = ls->fs; + int line = ls->linenumber; + int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); + struct ConsControl cc; + cc.na = cc.nh = cc.tostore = 0; + cc.t = t; + init_exp(t, VRELOCABLE, pc); + init_exp(&cc.v, VVOID, 0); /* no value (yet) */ + luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ + checknext(ls, '{'); + do { + lua_assert(cc.v.k == VVOID || cc.tostore > 0); + if (ls->t.token == '}') break; + closelistfield(fs, &cc); + switch(ls->t.token) { + case TK_NAME: { /* may be listfields or recfields */ + luaX_lookahead(ls); + if (ls->lookahead.token != '=') /* expression? */ + listfield(ls, &cc); + else + recfield(ls, &cc); + break; + } + case '[': { /* constructor_item -> recfield */ + recfield(ls, &cc); + break; + } + default: { /* constructor_part -> listfield */ + listfield(ls, &cc); + break; + } + } + } while (testnext(ls, ',') || testnext(ls, ';')); + check_match(ls, '}', '{', line); + lastlistfield(fs, &cc); + SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ + SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ +} + +/* }====================================================================== */ + + + +static void parlist (LexState *ls) { + /* parlist -> [ param { `,' param } ] */ + FuncState *fs = ls->fs; + Proto *f = fs->f; + int nparams = 0; + f->is_vararg = 0; + if (ls->t.token != ')') { /* is `parlist' not empty? */ + do { + switch (ls->t.token) { + case TK_NAME: { /* param -> NAME */ + new_localvar(ls, str_checkname(ls), nparams++); + break; + } + case TK_DOTS: { /* param -> `...' */ + luaX_next(ls); +#if defined(LUA_COMPAT_VARARG) + /* use `arg' as default name */ + new_localvarliteral(ls, "arg", nparams++); + f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG; +#endif + f->is_vararg |= VARARG_ISVARARG; + break; + } + default: luaX_syntaxerror(ls, " or " LUA_QL("...") " expected"); + } + } while (!f->is_vararg && testnext(ls, ',')); + } + adjustlocalvars(ls, nparams); + f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG)); + luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ +} + + +static void body (LexState *ls, expdesc *e, int needself, int line) { + /* body -> `(' parlist `)' chunk END */ + FuncState new_fs; + open_func(ls, &new_fs); + new_fs.f->linedefined = line; + checknext(ls, '('); + if (needself) { + new_localvarliteral(ls, "self", 0); + adjustlocalvars(ls, 1); + } + parlist(ls); + checknext(ls, ')'); + chunk(ls); + new_fs.f->lastlinedefined = ls->linenumber; + check_match(ls, TK_END, TK_FUNCTION, line); + close_func(ls); + pushclosure(ls, &new_fs, e); +} + + +static int explist1 (LexState *ls, expdesc *v) { + /* explist1 -> expr { `,' expr } */ + int n = 1; /* at least one expression */ + expr(ls, v); + while (testnext(ls, ',')) { + luaK_exp2nextreg(ls->fs, v); + expr(ls, v); + n++; + } + return n; +} + + +static void funcargs (LexState *ls, expdesc *f) { + FuncState *fs = ls->fs; + expdesc args; + int base, nparams; + int line = ls->linenumber; + switch (ls->t.token) { + case '(': { /* funcargs -> `(' [ explist1 ] `)' */ + if (line != ls->lastline) + luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)"); + luaX_next(ls); + if (ls->t.token == ')') /* arg list is empty? */ + args.k = VVOID; + else { + explist1(ls, &args); + luaK_setmultret(fs, &args); + } + check_match(ls, ')', '(', line); + break; + } + case '{': { /* funcargs -> constructor */ + constructor(ls, &args); + break; + } + case TK_STRING: { /* funcargs -> STRING */ + codestring(ls, &args, ls->t.seminfo.ts); + luaX_next(ls); /* must use `seminfo' before `next' */ + break; + } + default: { + luaX_syntaxerror(ls, "function arguments expected"); + return; + } + } + lua_assert(f->k == VNONRELOC); + base = f->u.s.info; /* base register for call */ + if (hasmultret(args.k)) + nparams = LUA_MULTRET; /* open call */ + else { + if (args.k != VVOID) + luaK_exp2nextreg(fs, &args); /* close last argument */ + nparams = fs->freereg - (base+1); + } + init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); + luaK_fixline(fs, line); + fs->freereg = base+1; /* call remove function and arguments and leaves + (unless changed) one result */ +} + + + + +/* +** {====================================================================== +** Expression parsing +** ======================================================================= +*/ + + +static void prefixexp (LexState *ls, expdesc *v) { + /* prefixexp -> NAME | '(' expr ')' */ + switch (ls->t.token) { + case '(': { + int line = ls->linenumber; + luaX_next(ls); + expr(ls, v); + check_match(ls, ')', '(', line); + luaK_dischargevars(ls->fs, v); + return; + } + case TK_NAME: { + singlevar(ls, v); + return; + } + default: { + luaX_syntaxerror(ls, "unexpected symbol"); + return; + } + } +} + + +static void primaryexp (LexState *ls, expdesc *v) { + /* primaryexp -> + prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ + FuncState *fs = ls->fs; + prefixexp(ls, v); + for (;;) { + switch (ls->t.token) { + case '.': { /* field */ + field(ls, v); + break; + } + case '[': { /* `[' exp1 `]' */ + expdesc key; + luaK_exp2anyreg(fs, v); + yindex(ls, &key); + luaK_indexed(fs, v, &key); + break; + } + case ':': { /* `:' NAME funcargs */ + expdesc key; + luaX_next(ls); + checkname(ls, &key); + luaK_self(fs, v, &key); + funcargs(ls, v); + break; + } + case '(': case TK_STRING: case '{': { /* funcargs */ + luaK_exp2nextreg(fs, v); + funcargs(ls, v); + break; + } + default: return; + } + } +} + + +static void simpleexp (LexState *ls, expdesc *v) { + /* simpleexp -> NUMBER | STRING | NIL | true | false | ... | + constructor | FUNCTION body | primaryexp */ + switch (ls->t.token) { + case TK_NUMBER: { + init_exp(v, VKNUM, 0); + v->u.nval = ls->t.seminfo.r; + break; + } + case TK_STRING: { + codestring(ls, v, ls->t.seminfo.ts); + break; + } + case TK_NIL: { + init_exp(v, VNIL, 0); + break; + } + case TK_TRUE: { + init_exp(v, VTRUE, 0); + break; + } + case TK_FALSE: { + init_exp(v, VFALSE, 0); + break; + } + case TK_DOTS: { /* vararg */ + FuncState *fs = ls->fs; + check_condition(ls, fs->f->is_vararg, + "cannot use " LUA_QL("...") " outside a vararg function"); + fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */ + init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); + break; + } + case '{': { /* constructor */ + constructor(ls, v); + return; + } + case TK_FUNCTION: { + luaX_next(ls); + body(ls, v, 0, ls->linenumber); + return; + } + default: { + primaryexp(ls, v); + return; + } + } + luaX_next(ls); +} + + +static UnOpr getunopr (int op) { + switch (op) { + case TK_NOT: return OPR_NOT; + case '-': return OPR_MINUS; + case '#': return OPR_LEN; + default: return OPR_NOUNOPR; + } +} + + +static BinOpr 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 const struct { + lu_byte left; /* left priority for each binary operator */ + lu_byte right; /* right priority */ +} priority[] = { /* ORDER OPR */ + {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */ + {10, 9}, {5, 4}, /* power and concat (right associative) */ + {3, 3}, {3, 3}, /* equality and inequality */ + {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */ + {2, 2}, {1, 1} /* logical (and/or) */ +}; + +#define 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' +*/ +static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) { + BinOpr op; + UnOpr uop; + enterlevel(ls); + uop = getunopr(ls->t.token); + if (uop != OPR_NOUNOPR) { + luaX_next(ls); + subexpr(ls, v, UNARY_PRIORITY); + luaK_prefix(ls->fs, uop, v); + } + else simpleexp(ls, v); + /* expand while operators have priorities higher than `limit' */ + op = getbinopr(ls->t.token); + while (op != OPR_NOBINOPR && priority[op].left > limit) { + expdesc v2; + BinOpr nextop; + luaX_next(ls); + luaK_infix(ls->fs, op, v); + /* read sub-expression with higher priority */ + nextop = subexpr(ls, &v2, priority[op].right); + luaK_posfix(ls->fs, op, v, &v2); + op = nextop; + } + leavelevel(ls); + return op; /* return first untreated operator */ +} + + +static void expr (LexState *ls, expdesc *v) { + subexpr(ls, v, 0); +} + +/* }==================================================================== */ + + + +/* +** {====================================================================== +** Rules for Statements +** ======================================================================= +*/ + + +static int block_follow (int token) { + switch (token) { + case TK_ELSE: case TK_ELSEIF: case TK_END: + case TK_UNTIL: case TK_EOS: + return 1; + default: return 0; + } +} + + +static void block (LexState *ls) { + /* block -> chunk */ + FuncState *fs = ls->fs; + BlockCnt bl; + enterblock(fs, &bl, 0); + chunk(ls); + lua_assert(bl.breaklist == NO_JUMP); + leaveblock(fs); +} + + +/* +** structure to chain all variables in the left-hand side of an +** assignment +*/ +struct LHS_assign { + struct LHS_assign *prev; + expdesc v; /* variable (global, local, upvalue, or indexed) */ +}; + + +/* +** 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. +*/ +static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { + FuncState *fs = ls->fs; + int extra = fs->freereg; /* eventual position to save local variable */ + int conflict = 0; + for (; lh; lh = lh->prev) { + if (lh->v.k == VINDEXED) { + if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ + conflict = 1; + lh->v.u.s.info = extra; /* previous assignment will use safe copy */ + } + if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */ + conflict = 1; + lh->v.u.s.aux = extra; /* previous assignment will use safe copy */ + } + } + } + if (conflict) { + luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */ + luaK_reserveregs(fs, 1); + } +} + + +static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { + expdesc e; + check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, + "syntax error"); + if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ + struct LHS_assign nv; + nv.prev = lh; + primaryexp(ls, &nv.v); + if (nv.v.k == VLOCAL) + check_conflict(ls, lh, &nv.v); + luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls, + "variables in assignment"); + assignment(ls, &nv, nvars+1); + } + else { /* assignment -> `=' explist1 */ + int nexps; + checknext(ls, '='); + nexps = explist1(ls, &e); + if (nexps != nvars) { + adjust_assign(ls, nvars, nexps, &e); + if (nexps > nvars) + ls->fs->freereg -= nexps - nvars; /* remove extra values */ + } + else { + luaK_setoneret(ls->fs, &e); /* close last expression */ + luaK_storevar(ls->fs, &lh->v, &e); + return; /* avoid default */ + } + } + init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ + luaK_storevar(ls->fs, &lh->v, &e); +} + + +static int cond (LexState *ls) { + /* cond -> exp */ + expdesc v; + expr(ls, &v); /* read condition */ + if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */ + luaK_goiftrue(ls->fs, &v); + return v.f; +} + + +static void breakstat (LexState *ls) { + FuncState *fs = ls->fs; + BlockCnt *bl = fs->bl; + int upval = 0; + while (bl && !bl->isbreakable) { + upval |= bl->upval; + bl = bl->previous; + } + if (!bl) + luaX_syntaxerror(ls, "no loop to break"); + if (upval) + luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); + luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); +} + + +static void whilestat (LexState *ls, int line) { + /* whilestat -> WHILE cond DO block END */ + FuncState *fs = ls->fs; + int whileinit; + int condexit; + BlockCnt bl; + luaX_next(ls); /* skip WHILE */ + whileinit = luaK_getlabel(fs); + condexit = cond(ls); + enterblock(fs, &bl, 1); + checknext(ls, TK_DO); + block(ls); + luaK_patchlist(fs, luaK_jump(fs), whileinit); + check_match(ls, TK_END, TK_WHILE, line); + leaveblock(fs); + luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ +} + + +static void repeatstat (LexState *ls, int line) { + /* repeatstat -> REPEAT block UNTIL cond */ + int condexit; + FuncState *fs = ls->fs; + int repeat_init = luaK_getlabel(fs); + BlockCnt bl1, bl2; + enterblock(fs, &bl1, 1); /* loop block */ + enterblock(fs, &bl2, 0); /* scope block */ + luaX_next(ls); /* skip REPEAT */ + chunk(ls); + check_match(ls, TK_UNTIL, TK_REPEAT, line); + condexit = cond(ls); /* read condition (inside scope block) */ + if (!bl2.upval) { /* no upvalues? */ + leaveblock(fs); /* finish scope */ + luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */ + } + else { /* complete semantics when there are upvalues */ + breakstat(ls); /* if condition then break */ + luaK_patchtohere(ls->fs, condexit); /* else... */ + leaveblock(fs); /* finish scope... */ + luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */ + } + leaveblock(fs); /* finish loop */ +} + + +static int exp1 (LexState *ls) { + expdesc e; + int k; + expr(ls, &e); + k = e.k; + luaK_exp2nextreg(ls->fs, &e); + return k; +} + + +static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { + /* forbody -> DO block */ + BlockCnt bl; + FuncState *fs = ls->fs; + int prep, endfor; + adjustlocalvars(ls, 3); /* control variables */ + checknext(ls, TK_DO); + prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); + enterblock(fs, &bl, 0); /* scope for declared variables */ + adjustlocalvars(ls, nvars); + luaK_reserveregs(fs, nvars); + block(ls); + leaveblock(fs); /* end of scope for declared variables */ + luaK_patchtohere(fs, prep); + endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : + luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars); + luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ + luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1); +} + + +static void fornum (LexState *ls, TString *varname, int line) { + /* fornum -> NAME = exp1,exp1[,exp1] forbody */ + FuncState *fs = ls->fs; + int base = fs->freereg; + new_localvarliteral(ls, "(for index)", 0); + new_localvarliteral(ls, "(for limit)", 1); + new_localvarliteral(ls, "(for step)", 2); + new_localvar(ls, varname, 3); + checknext(ls, '='); + exp1(ls); /* initial value */ + checknext(ls, ','); + exp1(ls); /* limit */ + if (testnext(ls, ',')) + exp1(ls); /* optional step */ + else { /* default step = 1 */ + luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); + luaK_reserveregs(fs, 1); + } + forbody(ls, base, line, 1, 1); +} + + +static void forlist (LexState *ls, TString *indexname) { + /* forlist -> NAME {,NAME} IN explist1 forbody */ + FuncState *fs = ls->fs; + expdesc e; + int nvars = 0; + int line; + int base = fs->freereg; + /* create control variables */ + new_localvarliteral(ls, "(for generator)", nvars++); + new_localvarliteral(ls, "(for state)", nvars++); + new_localvarliteral(ls, "(for control)", nvars++); + /* create declared variables */ + new_localvar(ls, indexname, nvars++); + while (testnext(ls, ',')) + new_localvar(ls, str_checkname(ls), nvars++); + checknext(ls, TK_IN); + line = ls->linenumber; + adjust_assign(ls, 3, explist1(ls, &e), &e); + luaK_checkstack(fs, 3); /* extra space to call generator */ + forbody(ls, base, line, nvars - 3, 0); +} + + +static void forstat (LexState *ls, int line) { + /* forstat -> FOR (fornum | forlist) END */ + FuncState *fs = ls->fs; + TString *varname; + BlockCnt bl; + enterblock(fs, &bl, 1); /* scope for loop and control variables */ + luaX_next(ls); /* skip `for' */ + varname = str_checkname(ls); /* first variable name */ + switch (ls->t.token) { + case '=': fornum(ls, varname, line); break; + case ',': case TK_IN: forlist(ls, varname); break; + default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected"); + } + check_match(ls, TK_END, TK_FOR, line); + leaveblock(fs); /* loop scope (`break' jumps to this point) */ +} + + +static int test_then_block (LexState *ls) { + /* test_then_block -> [IF | ELSEIF] cond THEN block */ + int condexit; + luaX_next(ls); /* skip IF or ELSEIF */ + condexit = cond(ls); + checknext(ls, TK_THEN); + block(ls); /* `then' part */ + return condexit; +} + + +static void ifstat (LexState *ls, int line) { + /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ + FuncState *fs = ls->fs; + int flist; + int escapelist = NO_JUMP; + flist = test_then_block(ls); /* IF cond THEN block */ + while (ls->t.token == TK_ELSEIF) { + luaK_concat(fs, &escapelist, luaK_jump(fs)); + luaK_patchtohere(fs, flist); + flist = test_then_block(ls); /* ELSEIF cond THEN block */ + } + if (ls->t.token == TK_ELSE) { + luaK_concat(fs, &escapelist, luaK_jump(fs)); + luaK_patchtohere(fs, flist); + luaX_next(ls); /* skip ELSE (after patch, for correct line info) */ + block(ls); /* `else' part */ + } + else + luaK_concat(fs, &escapelist, flist); + luaK_patchtohere(fs, escapelist); + check_match(ls, TK_END, TK_IF, line); +} + + +static void localfunc (LexState *ls) { + expdesc v, b; + FuncState *fs = ls->fs; + new_localvar(ls, str_checkname(ls), 0); + init_exp(&v, VLOCAL, fs->freereg); + luaK_reserveregs(fs, 1); + adjustlocalvars(ls, 1); + body(ls, &b, 0, ls->linenumber); + luaK_storevar(fs, &v, &b); + /* debug information will only see the variable after this point! */ + getlocvar(fs, fs->nactvar - 1).startpc = fs->pc; +} + + +static void localstat (LexState *ls) { + /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ + int nvars = 0; + int nexps; + expdesc e; + do { + new_localvar(ls, str_checkname(ls), nvars++); + } while (testnext(ls, ',')); + if (testnext(ls, '=')) + nexps = explist1(ls, &e); + else { + e.k = VVOID; + nexps = 0; + } + adjust_assign(ls, nvars, nexps, &e); + adjustlocalvars(ls, nvars); +} + + +static int funcname (LexState *ls, expdesc *v) { + /* funcname -> NAME {field} [`:' NAME] */ + int needself = 0; + singlevar(ls, v); + while (ls->t.token == '.') + field(ls, v); + if (ls->t.token == ':') { + needself = 1; + field(ls, v); + } + return needself; +} + + +static void funcstat (LexState *ls, int line) { + /* funcstat -> FUNCTION funcname body */ + int needself; + expdesc v, b; + luaX_next(ls); /* skip FUNCTION */ + needself = funcname(ls, &v); + body(ls, &b, needself, line); + luaK_storevar(ls->fs, &v, &b); + luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ +} + + +static void exprstat (LexState *ls) { + /* stat -> func | assignment */ + FuncState *fs = ls->fs; + struct LHS_assign v; + primaryexp(ls, &v.v); + if (v.v.k == VCALL) /* stat -> func */ + SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ + else { /* stat -> assignment */ + v.prev = NULL; + assignment(ls, &v, 1); + } +} + + +static void retstat (LexState *ls) { + /* stat -> RETURN explist */ + FuncState *fs = ls->fs; + expdesc e; + int first, nret; /* registers with returned values */ + luaX_next(ls); /* skip RETURN */ + if (block_follow(ls->t.token) || ls->t.token == ';') + first = nret = 0; /* return no values */ + else { + nret = explist1(ls, &e); /* optional return values */ + if (hasmultret(e.k)) { + luaK_setmultret(fs, &e); + if (e.k == VCALL && nret == 1) { /* tail call? */ + SET_OPCODE(getcode(fs,&e), OP_TAILCALL); + lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar); + } + first = fs->nactvar; + nret = LUA_MULTRET; /* return all values */ + } + else { + if (nret == 1) /* only one single value? */ + first = luaK_exp2anyreg(fs, &e); + else { + luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ + first = fs->nactvar; /* return all `active' values */ + lua_assert(nret == fs->freereg - first); + } + } + } + luaK_ret(fs, first, nret); +} + + +static int statement (LexState *ls) { + int line = ls->linenumber; /* may be needed for error messages */ + switch (ls->t.token) { + case TK_IF: { /* stat -> ifstat */ + ifstat(ls, line); + return 0; + } + case TK_WHILE: { /* stat -> whilestat */ + whilestat(ls, line); + return 0; + } + case TK_DO: { /* stat -> DO block END */ + luaX_next(ls); /* skip DO */ + block(ls); + check_match(ls, TK_END, TK_DO, line); + return 0; + } + case TK_FOR: { /* stat -> forstat */ + forstat(ls, line); + return 0; + } + case TK_REPEAT: { /* stat -> repeatstat */ + repeatstat(ls, line); + return 0; + } + case TK_FUNCTION: { + funcstat(ls, line); /* stat -> funcstat */ + return 0; + } + case TK_LOCAL: { /* stat -> localstat */ + luaX_next(ls); /* skip LOCAL */ + if (testnext(ls, TK_FUNCTION)) /* local function? */ + localfunc(ls); + else + localstat(ls); + return 0; + } + case TK_RETURN: { /* stat -> retstat */ + retstat(ls); + return 1; /* must be last statement */ + } + case TK_BREAK: { /* stat -> breakstat */ + luaX_next(ls); /* skip BREAK */ + breakstat(ls); + return 1; /* must be last statement */ + } + default: { + exprstat(ls); + return 0; /* to avoid warnings */ + } + } +} + + +static void chunk (LexState *ls) { + /* chunk -> { stat [`;'] } */ + int islast = 0; + enterlevel(ls); + while (!islast && !block_follow(ls->t.token)) { + islast = statement(ls); + testnext(ls, ';'); + lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && + ls->fs->freereg >= ls->fs->nactvar); + ls->fs->freereg = ls->fs->nactvar; /* free registers */ + } + leavelevel(ls); +} + +/* }====================================================================== */ diff --git a/vscript/languages/lua/lua-5.1.4/src/lparser.h b/vscript/languages/lua/lua-5.1.4/src/lparser.h new file mode 100644 index 00000000..18836afd --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lparser.h @@ -0,0 +1,82 @@ +/* +** $Id: lparser.h,v 1.57.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + +#ifndef lparser_h +#define lparser_h + +#include "llimits.h" +#include "lobject.h" +#include "lzio.h" + + +/* +** Expression descriptor +*/ + +typedef enum { + VVOID, /* no value */ + VNIL, + VTRUE, + VFALSE, + VK, /* info = index of constant in `k' */ + VKNUM, /* nval = numerical value */ + VLOCAL, /* info = local register */ + VUPVAL, /* info = index of upvalue in `upvalues' */ + VGLOBAL, /* info = index of table; aux = index of global name in `k' */ + VINDEXED, /* info = table register; aux = index register (or `k') */ + VJMP, /* info = instruction pc */ + VRELOCABLE, /* info = instruction pc */ + VNONRELOC, /* info = result register */ + VCALL, /* info = instruction pc */ + VVARARG /* info = instruction pc */ +} expkind; + +typedef struct expdesc { + expkind k; + union { + struct { int info, aux; } s; + lua_Number nval; + } u; + int t; /* patch list of `exit when true' */ + int f; /* patch list of `exit when false' */ +} expdesc; + + +typedef struct upvaldesc { + lu_byte k; + lu_byte info; +} upvaldesc; + + +struct BlockCnt; /* defined in lparser.c */ + + +/* state needed to generate code for a given function */ +typedef struct FuncState { + Proto *f; /* current function header */ + Table *h; /* table to find (and reuse) elements in `k' */ + struct FuncState *prev; /* enclosing function */ + struct LexState *ls; /* lexical state */ + struct lua_State *L; /* copy of the Lua state */ + struct BlockCnt *bl; /* chain of current blocks */ + int pc; /* next position to code (equivalent to `ncode') */ + int lasttarget; /* `pc' of last `jump target' */ + int jpc; /* list of pending jumps to `pc' */ + int freereg; /* first free register */ + int nk; /* number of elements in `k' */ + int np; /* number of elements in `p' */ + short nlocvars; /* number of elements in `locvars' */ + lu_byte nactvar; /* number of active local variables */ + upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */ + unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */ +} FuncState; + + +LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, + const char *name); + + +#endif diff --git a/vscript/languages/lua/lua-5.1.4/src/lstate.c b/vscript/languages/lua/lua-5.1.4/src/lstate.c new file mode 100644 index 00000000..9aa4b1ed --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lstate.c @@ -0,0 +1,217 @@ +/* +** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $ +** Global State +** See Copyright Notice in lua.h +*/ + + +#include + +#define lstate_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE) +#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE) +#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE)) + + +/* +** Main thread combines a thread state and the global state +*/ +typedef struct LG { + lua_State l; + global_State g; +} LG; + + + +static void stack_init (lua_State *L1, lua_State *L) { + /* initialize CallInfo array */ + L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); + L1->ci = L1->base_ci; + L1->size_ci = BASIC_CI_SIZE; + L1->end_ci = L1->base_ci + L1->size_ci - 1; + /* initialize stack array */ + L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); + L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; + L1->top = L1->stack; + L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; + /* initialize first ci */ + L1->ci->func = L1->top; + setnilvalue(L1->top++); /* `function' entry for this `ci' */ + L1->base = L1->ci->base = L1->top; + L1->ci->top = L1->top + LUA_MINSTACK; +} + + +static void freestack (lua_State *L, lua_State *L1) { + luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); + luaM_freearray(L, L1->stack, L1->stacksize, TValue); +} + + +/* +** open parts that may cause memory-allocation errors +*/ +static void f_luaopen (lua_State *L, void *ud) { + global_State *g = G(L); + UNUSED(ud); + stack_init(L, L); /* init stack */ + sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */ + sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */ +#ifdef LUA_MOD_CASE_INSENSITIVE + luaH_setflag(hvalue(registry(L)), TH_SYMTABLE, 0); /* make case-sensitive */ +#endif + luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ + luaT_init(L); + luaX_init(L); + luaS_fix(luaS_newliteral(L, MEMERRMSG)); + g->GCthreshold = 4*g->totalbytes; +} + + +static void preinit_state (lua_State *L, global_State *g) { + G(L) = g; + L->stack = NULL; + L->stacksize = 0; + L->errorJmp = NULL; + L->hook = NULL; + L->hookmask = 0; + L->basehookcount = 0; + L->allowhook = 1; + resethookcount(L); + L->openupval = NULL; + L->size_ci = 0; + L->nCcalls = L->baseCcalls = 0; + L->status = 0; + L->base_ci = L->ci = NULL; + L->savedpc = NULL; + L->errfunc = 0; + setnilvalue(gt(L)); +} + + +static void close_state (lua_State *L) { + global_State *g = G(L); + luaF_close(L, L->stack); /* close all upvalues for this thread */ + luaC_freeall(L); /* collect all objects */ + lua_assert(g->rootgc == obj2gco(L)); + lua_assert(g->strt.nuse == 0); + luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); + luaZ_freebuffer(L, &g->buff); + freestack(L, L); + lua_assert(g->totalbytes == sizeof(LG)); + (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0); +} + + +lua_State *luaE_newthread (lua_State *L) { + lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); + luaC_link(L, obj2gco(L1), LUA_TTHREAD); + preinit_state(L1, G(L)); + stack_init(L1, L); /* init stack */ + setobj2n(L, gt(L1), gt(L)); /* share table of globals */ + L1->hookmask = L->hookmask; + L1->basehookcount = L->basehookcount; + L1->hook = L->hook; + resethookcount(L1); + lua_assert(iswhite(obj2gco(L1))); + return L1; +} + + +void luaE_freethread (lua_State *L, lua_State *L1) { + luaF_close(L1, L1->stack); /* close all upvalues for this thread */ + lua_assert(L1->openupval == NULL); + luai_userstatefree(L1); + freestack(L, L1); + luaM_freemem(L, fromstate(L1), state_size(lua_State)); +} + + +LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { + int i; + lua_State *L; + global_State *g; + void *l = (*f)(ud, NULL, 0, state_size(LG)); + if (l == NULL) return NULL; + L = tostate(l); + g = &((LG *)L)->g; + L->next = NULL; + L->tt = LUA_TTHREAD; + g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); + L->marked = luaC_white(g); + set2bits(L->marked, FIXEDBIT, SFIXEDBIT); + preinit_state(L, g); + g->frealloc = f; + g->ud = ud; + g->mainthread = L; + g->uvhead.u.l.prev = &g->uvhead; + g->uvhead.u.l.next = &g->uvhead; + g->GCthreshold = 0; /* mark it as unfinished state */ + g->strt.size = 0; + g->strt.nuse = 0; + g->strt.hash = NULL; + setnilvalue(registry(L)); + luaZ_initbuffer(L, &g->buff); + g->panic = NULL; + g->gcstate = GCSpause; + g->rootgc = obj2gco(L); + g->sweepstrgc = 0; + g->sweepgc = &g->rootgc; + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + g->tmudata = NULL; + g->totalbytes = sizeof(LG); + g->gcpause = LUAI_GCPAUSE; + g->gcstepmul = LUAI_GCMUL; + g->gcdept = 0; + for (i=0; imt[i] = NULL; + if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { + /* memory allocation error: free partial state */ + close_state(L); + L = NULL; + } + else + luai_userstateopen(L); + return L; +} + + +static void callallgcTM (lua_State *L, void *ud) { + UNUSED(ud); + luaC_callGCTM(L); /* call GC metamethods for all udata */ +} + + +LUA_API void lua_close (lua_State *L) { + L = G(L)->mainthread; /* only the main thread can be closed */ + lua_lock(L); + luaF_close(L, L->stack); /* close all upvalues for this thread */ + luaC_separateudata(L, 1); /* separate udata that have GC metamethods */ + L->errfunc = 0; /* no error function during GC metamethods */ + do { /* repeat until no more errors */ + L->ci = L->base_ci; + L->base = L->top = L->ci->base; + L->nCcalls = L->baseCcalls = 0; + } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0); + lua_assert(G(L)->tmudata == NULL); + luai_userstateclose(L); + close_state(L); +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/lstate.h b/vscript/languages/lua/lua-5.1.4/src/lstate.h new file mode 100644 index 00000000..3bc575b6 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lstate.h @@ -0,0 +1,169 @@ +/* +** $Id: lstate.h,v 2.24.1.2 2008/01/03 15:20:39 roberto Exp $ +** Global State +** See Copyright Notice in lua.h +*/ + +#ifndef lstate_h +#define lstate_h + +#include "lua.h" + +#include "lobject.h" +#include "ltm.h" +#include "lzio.h" + + + +struct lua_longjmp; /* defined in ldo.c */ + + +/* table of globals */ +#define gt(L) (&L->l_gt) + +/* registry */ +#define registry(L) (&G(L)->l_registry) + + +/* extra stack space to handle TM calls and some other extras */ +#define EXTRA_STACK 5 + + +#define BASIC_CI_SIZE 8 + +#define BASIC_STACK_SIZE (2*LUA_MINSTACK) + + + +typedef struct stringtable { + GCObject **hash; + lu_int32 nuse; /* number of elements */ + int size; +} stringtable; + + +/* +** informations about a call +*/ +typedef struct CallInfo { + StkId base; /* base for this function */ + StkId func; /* function index in the stack */ + StkId top; /* top for this function */ + const Instruction *savedpc; + int nresults; /* expected number of results from this function */ + int tailcalls; /* number of tail calls lost under this entry */ +} CallInfo; + + + +#define curr_func(L) (clvalue(L->ci->func)) +#define ci_func(ci) (clvalue((ci)->func)) +#define f_isLua(ci) (!ci_func(ci)->c.isC) +#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci)) + + +/* +** `global state', shared by all threads of this state +*/ +typedef struct global_State { + stringtable strt; /* hash table for strings */ + lua_Alloc frealloc; /* function to reallocate memory */ + void *ud; /* auxiliary data to `frealloc' */ + lu_byte currentwhite; + lu_byte gcstate; /* state of garbage collector */ + int sweepstrgc; /* position of sweep in `strt' */ + GCObject *rootgc; /* list of all collectable objects */ + GCObject **sweepgc; /* position of sweep in `rootgc' */ + GCObject *gray; /* list of gray objects */ + GCObject *grayagain; /* list of objects to be traversed atomically */ + GCObject *weak; /* list of weak tables (to be cleared) */ + GCObject *tmudata; /* last element of list of userdata to be GC */ + Mbuffer buff; /* temporary buffer for string concatentation */ + lu_mem GCthreshold; + lu_mem totalbytes; /* number of bytes currently allocated */ + lu_mem estimate; /* an estimate of number of bytes actually in use */ + lu_mem gcdept; /* how much GC is `behind schedule' */ + int gcpause; /* size of pause between successive GCs */ + int gcstepmul; /* GC `granularity' */ + lua_CFunction panic; /* to be called in unprotected errors */ + TValue l_registry; + struct lua_State *mainthread; + UpVal uvhead; /* head of double-linked list of all open upvalues */ + struct Table *mt[NUM_TAGS]; /* metatables for basic types */ + TString *tmname[TM_N]; /* array with tag-method names */ +} global_State; + + +/* +** `per thread' state +*/ +struct lua_State { + CommonHeader; + lu_byte status; + StkId top; /* first free slot in the stack */ + StkId base; /* base of current function */ + global_State *l_G; + CallInfo *ci; /* call info for current function */ + const Instruction *savedpc; /* `savedpc' of current function */ + StkId stack_last; /* last free slot in the stack */ + StkId stack; /* stack base */ + CallInfo *end_ci; /* points after end of ci array*/ + CallInfo *base_ci; /* array of CallInfo's */ + int stacksize; + int size_ci; /* size of array `base_ci' */ + unsigned short nCcalls; /* number of nested C calls */ + unsigned short baseCcalls; /* nested C calls when resuming coroutine */ + lu_byte hookmask; + lu_byte allowhook; + int basehookcount; + int hookcount; + lua_Hook hook; + TValue l_gt; /* table of globals */ + TValue env; /* temporary place for environments */ + GCObject *openupval; /* list of open upvalues in this stack */ + GCObject *gclist; + struct lua_longjmp *errorJmp; /* current error recover point */ + ptrdiff_t errfunc; /* current error handling function (stack index) */ +}; + + +#define G(L) (L->l_G) + + +/* +** Union of all collectable objects +*/ +union GCObject { + GCheader gch; + union TString ts; + union Udata u; + union Closure cl; + struct Table h; + struct Proto p; + struct UpVal uv; + struct lua_State th; /* thread */ +}; + + +/* macros to convert a GCObject into a specific value */ +#define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts)) +#define gco2ts(o) (&rawgco2ts(o)->tsv) +#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) +#define gco2u(o) (&rawgco2u(o)->uv) +#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl)) +#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) +#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) +#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) +#define ngcotouv(o) \ + check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv)) +#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) + +/* macro to convert any Lua object into a GCObject */ +#define obj2gco(v) (cast(GCObject *, (v))) + + +LUAI_FUNC lua_State *luaE_newthread (lua_State *L); +LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); + +#endif + diff --git a/vscript/languages/lua/lua-5.1.4/src/lstring.c b/vscript/languages/lua/lua-5.1.4/src/lstring.c new file mode 100644 index 00000000..50153550 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lstring.c @@ -0,0 +1,133 @@ +/* +** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ +** String table (keeps all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + + +#include +#ifdef LUA_MOD_CASE_INSENSITIVE +#include +#endif + +#define lstring_c +#define LUA_CORE + +#include "lua.h" + +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" + + + +void luaS_resize (lua_State *L, int newsize) { + GCObject **newhash; + stringtable *tb; + int i; + if (G(L)->gcstate == GCSsweepstring) + return; /* cannot resize during GC traverse */ + newhash = luaM_newvector(L, newsize, GCObject *); + tb = &G(L)->strt; + for (i=0; isize; i++) { + GCObject *p = tb->hash[i]; + while (p) { /* for each node in the list */ + GCObject *next = p->gch.next; /* save next */ + unsigned int h = gco2ts(p)->hash; + int h1 = lmod(h, newsize); /* new position */ + lua_assert(cast_int(h%newsize) == lmod(h, newsize)); + p->gch.next = newhash[h1]; /* chain it */ + newhash[h1] = p; + p = next; + } + } + luaM_freearray(L, tb->hash, tb->size, TString *); + tb->size = newsize; + tb->hash = newhash; +} + + +static TString *newlstr (lua_State *L, const char *str, size_t l, +#ifdef LUA_MOD_CASE_INSENSITIVE + unsigned int h, unsigned int k) { +#else + unsigned int h) { +#endif + TString *ts; + stringtable *tb; + if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) + luaM_toobig(L); + ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString))); + ts->tsv.len = l; + ts->tsv.hash = h; +#ifdef LUA_MOD_CASE_INSENSITIVE + ts->tsv.keyhash = k; +#endif + ts->tsv.marked = luaC_white(G(L)); + ts->tsv.tt = LUA_TSTRING; + ts->tsv.reserved = 0; + memcpy(ts+1, str, l*sizeof(char)); + ((char *)(ts+1))[l] = '\0'; /* ending 0 */ + tb = &G(L)->strt; + h = lmod(h, tb->size); + ts->tsv.next = tb->hash[h]; /* chain new entry */ + tb->hash[h] = obj2gco(ts); + tb->nuse++; + if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) + luaS_resize(L, tb->size*2); /* too crowded */ + return ts; +} + + +TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { + GCObject *o; + unsigned int h = cast(unsigned int, l); /* seed */ +#ifdef LUA_MOD_CASE_INSENSITIVE + unsigned int k = h; +#endif + size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ + size_t l1; + for (l1=l; l1>=step; l1-=step) /* compute hash */ + { + h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1])); +#ifdef LUA_MOD_CASE_INSENSITIVE + k = k ^ ((k<<5)+(k>>2)+cast(unsigned char, tolower(str[l1-1]))); +#endif + } + for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; + o != NULL; + o = o->gch.next) { + TString *ts = rawgco2ts(o); + if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) { + /* string may be dead */ + if (isdead(G(L), o)) changewhite(o); + return ts; + } + } +#ifdef LUA_MOD_CASE_INSENSITIVE + return newlstr(L, str, l, h, k); /* not found */ +#else + return newlstr(L, str, l, h); /* not found */ +#endif +} + + +Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { + Udata *u; + if (s > MAX_SIZET - sizeof(Udata)) + luaM_toobig(L); + u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata))); + u->uv.marked = luaC_white(G(L)); /* is not finalized */ + u->uv.tt = LUA_TUSERDATA; + u->uv.len = s; + u->uv.metatable = NULL; + u->uv.env = e; + /* chain it on udata list (after main thread) */ + u->uv.next = G(L)->mainthread->next; + G(L)->mainthread->next = obj2gco(u); + return u; +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/lstring.h b/vscript/languages/lua/lua-5.1.4/src/lstring.h new file mode 100644 index 00000000..73a2ff8b --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lstring.h @@ -0,0 +1,31 @@ +/* +** $Id: lstring.h,v 1.43.1.1 2007/12/27 13:02:25 roberto Exp $ +** String table (keep all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + +#ifndef lstring_h +#define lstring_h + + +#include "lgc.h" +#include "lobject.h" +#include "lstate.h" + + +#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) + +#define sizeudata(u) (sizeof(union Udata)+(u)->len) + +#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) +#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ + (sizeof(s)/sizeof(char))-1)) + +#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) + +LUAI_FUNC void luaS_resize (lua_State *L, int newsize); +LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); +LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); + + +#endif diff --git a/vscript/languages/lua/lua-5.1.4/src/lstrlib.c b/vscript/languages/lua/lua-5.1.4/src/lstrlib.c new file mode 100644 index 00000000..1b4763d4 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lstrlib.c @@ -0,0 +1,869 @@ +/* +** $Id: lstrlib.c,v 1.132.1.4 2008/07/11 17:27:21 roberto Exp $ +** Standard library for string operations and pattern-matching +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include + +#define lstrlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* macro to `unsign' a character */ +#define uchar(c) ((unsigned char)(c)) + + + +static int str_len (lua_State *L) { + size_t l; + luaL_checklstring(L, 1, &l); + lua_pushinteger(L, l); + return 1; +} + + +static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) { + /* relative string position: negative means back from end */ + if (pos < 0) pos += (ptrdiff_t)len + 1; + return (pos >= 0) ? pos : 0; +} + + +static int str_sub (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l); + ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l); + if (start < 1) start = 1; + if (end > (ptrdiff_t)l) end = (ptrdiff_t)l; + if (start <= end) + lua_pushlstring(L, s+start-1, end-start+1); + else lua_pushliteral(L, ""); + return 1; +} + + +static int str_reverse (lua_State *L) { + size_t l; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + luaL_buffinit(L, &b); + while (l--) luaL_addchar(&b, s[l]); + luaL_pushresult(&b); + return 1; +} + + +static int str_lower (lua_State *L) { + size_t l; + size_t i; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + luaL_buffinit(L, &b); + for (i=0; i 0) + luaL_addlstring(&b, s, l); + luaL_pushresult(&b); + return 1; +} + + +static int str_byte (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l); + ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l); + int n, i; + if (posi <= 0) posi = 1; + if ((size_t)pose > l) pose = l; + if (posi > pose) return 0; /* empty interval; return no values */ + n = (int)(pose - posi + 1); + if (posi + n <= pose) /* overflow? */ + luaL_error(L, "string slice too long"); + luaL_checkstack(L, n, "string slice too long"); + for (i=0; i= ms->level || ms->capture[l].len == CAP_UNFINISHED) + return luaL_error(ms->L, "invalid capture index"); + return l; +} + + +static int capture_to_close (MatchState *ms) { + int level = ms->level; + for (level--; level>=0; level--) + if (ms->capture[level].len == CAP_UNFINISHED) return level; + return luaL_error(ms->L, "invalid pattern capture"); +} + + +static const char *classend (MatchState *ms, const char *p) { + switch (*p++) { + case L_ESC: { + if (*p == '\0') + luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); + return p+1; + } + case '[': { + if (*p == '^') p++; + do { /* look for a `]' */ + if (*p == '\0') + luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); + if (*(p++) == L_ESC && *p != '\0') + p++; /* skip escapes (e.g. `%]') */ + } while (*p != ']'); + return p+1; + } + default: { + return p; + } + } +} + + +static int match_class (int c, int cl) { + int res; + switch (tolower(cl)) { + case 'a' : res = isalpha(c); break; + case 'c' : res = iscntrl(c); break; + case 'd' : res = isdigit(c); break; + case 'l' : res = islower(c); break; + case 'p' : res = ispunct(c); break; + case 's' : res = isspace(c); break; + case 'u' : res = isupper(c); break; + case 'w' : res = isalnum(c); break; + case 'x' : res = isxdigit(c); break; + case 'z' : res = (c == 0); break; + default: return (cl == c); + } + return (islower(cl) ? res : !res); +} + + +static int matchbracketclass (int c, const char *p, const char *ec) { + int sig = 1; + if (*(p+1) == '^') { + sig = 0; + p++; /* skip the `^' */ + } + while (++p < ec) { + if (*p == L_ESC) { + p++; + if (match_class(c, uchar(*p))) + return sig; + } + else if ((*(p+1) == '-') && (p+2 < ec)) { + p+=2; + if (uchar(*(p-2)) <= c && c <= uchar(*p)) + return sig; + } + else if (uchar(*p) == c) return sig; + } + return !sig; +} + + +static int singlematch (int c, const char *p, const char *ep) { + switch (*p) { + case '.': return 1; /* matches any char */ + case L_ESC: return match_class(c, uchar(*(p+1))); + case '[': return matchbracketclass(c, p, ep-1); + default: return (uchar(*p) == c); + } +} + + +static const char *match (MatchState *ms, const char *s, const char *p); + + +static const char *matchbalance (MatchState *ms, const char *s, + const char *p) { + if (*p == 0 || *(p+1) == 0) + luaL_error(ms->L, "unbalanced pattern"); + if (*s != *p) return NULL; + else { + int b = *p; + int e = *(p+1); + int cont = 1; + while (++s < ms->src_end) { + if (*s == e) { + if (--cont == 0) return s+1; + } + else if (*s == b) cont++; + } + } + return NULL; /* string ends out of balance */ +} + + +static const char *max_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + ptrdiff_t i = 0; /* counts maximum expand for item */ + while ((s+i)src_end && singlematch(uchar(*(s+i)), p, ep)) + i++; + /* keeps trying to match with the maximum repetitions */ + while (i>=0) { + const char *res = match(ms, (s+i), ep+1); + if (res) return res; + i--; /* else didn't match; reduce 1 repetition to try again */ + } + return NULL; +} + + +static const char *min_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + for (;;) { + const char *res = match(ms, s, ep+1); + if (res != NULL) + return res; + else if (ssrc_end && singlematch(uchar(*s), p, ep)) + s++; /* try with one more repetition */ + else return NULL; + } +} + + +static const char *start_capture (MatchState *ms, const char *s, + const char *p, int what) { + const char *res; + int level = ms->level; + if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); + ms->capture[level].init = s; + ms->capture[level].len = what; + ms->level = level+1; + if ((res=match(ms, s, p)) == NULL) /* match failed? */ + ms->level--; /* undo capture */ + return res; +} + + +static const char *end_capture (MatchState *ms, const char *s, + const char *p) { + int l = capture_to_close(ms); + const char *res; + ms->capture[l].len = s - ms->capture[l].init; /* close capture */ + if ((res = match(ms, s, p)) == NULL) /* match failed? */ + ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ + return res; +} + + +static const char *match_capture (MatchState *ms, const char *s, int l) { + size_t len; + l = check_capture(ms, l); + len = ms->capture[l].len; + if ((size_t)(ms->src_end-s) >= len && + memcmp(ms->capture[l].init, s, len) == 0) + return s+len; + else return NULL; +} + + +static const char *match (MatchState *ms, const char *s, const char *p) { + init: /* using goto's to optimize tail recursion */ + switch (*p) { + case '(': { /* start capture */ + if (*(p+1) == ')') /* position capture? */ + return start_capture(ms, s, p+2, CAP_POSITION); + else + return start_capture(ms, s, p+1, CAP_UNFINISHED); + } + case ')': { /* end capture */ + return end_capture(ms, s, p+1); + } + case L_ESC: { + switch (*(p+1)) { + case 'b': { /* balanced string? */ + s = matchbalance(ms, s, p+2); + if (s == NULL) return NULL; + p+=4; goto init; /* else return match(ms, s, p+4); */ + } + case 'f': { /* frontier? */ + const char *ep; char previous; + p += 2; + if (*p != '[') + luaL_error(ms->L, "missing " LUA_QL("[") " after " + LUA_QL("%%f") " in pattern"); + ep = classend(ms, p); /* points to what is next */ + previous = (s == ms->src_init) ? '\0' : *(s-1); + if (matchbracketclass(uchar(previous), p, ep-1) || + !matchbracketclass(uchar(*s), p, ep-1)) return NULL; + p=ep; goto init; /* else return match(ms, s, ep); */ + } + default: { + if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */ + s = match_capture(ms, s, uchar(*(p+1))); + if (s == NULL) return NULL; + p+=2; goto init; /* else return match(ms, s, p+2) */ + } + goto dflt; /* case default */ + } + } + } + case '\0': { /* end of pattern */ + return s; /* match succeeded */ + } + case '$': { + if (*(p+1) == '\0') /* is the `$' the last char in pattern? */ + return (s == ms->src_end) ? s : NULL; /* check end of string */ + else goto dflt; + } + default: dflt: { /* it is a pattern item */ + const char *ep = classend(ms, p); /* points to what is next */ + int m = ssrc_end && singlematch(uchar(*s), p, ep); + switch (*ep) { + case '?': { /* optional */ + const char *res; + if (m && ((res=match(ms, s+1, ep+1)) != NULL)) + return res; + p=ep+1; goto init; /* else return match(ms, s, ep+1); */ + } + case '*': { /* 0 or more repetitions */ + return max_expand(ms, s, p, ep); + } + case '+': { /* 1 or more repetitions */ + return (m ? max_expand(ms, s+1, p, ep) : NULL); + } + case '-': { /* 0 or more repetitions (minimum) */ + return min_expand(ms, s, p, ep); + } + default: { + if (!m) return NULL; + s++; p=ep; goto init; /* else return match(ms, s+1, ep); */ + } + } + } + } +} + + + +static const char *lmemfind (const char *s1, size_t l1, + const char *s2, size_t l2) { + if (l2 == 0) return s1; /* empty strings are everywhere */ + else if (l2 > l1) return NULL; /* avoids a negative `l1' */ + else { + const char *init; /* to search for a `*s2' inside `s1' */ + l2--; /* 1st char will be checked by `memchr' */ + l1 = l1-l2; /* `s2' cannot be found after that */ + while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { + init++; /* 1st char is already checked */ + if (memcmp(init, s2+1, l2) == 0) + return init-1; + else { /* correct `l1' and `s1' to try again */ + l1 -= init-s1; + s1 = init; + } + } + return NULL; /* not found */ + } +} + + +static void push_onecapture (MatchState *ms, int i, const char *s, + const char *e) { + if (i >= ms->level) { + if (i == 0) /* ms->level == 0, too */ + lua_pushlstring(ms->L, s, e - s); /* add whole match */ + else + luaL_error(ms->L, "invalid capture index"); + } + else { + ptrdiff_t l = ms->capture[i].len; + if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); + if (l == CAP_POSITION) + lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1); + else + lua_pushlstring(ms->L, ms->capture[i].init, l); + } +} + + +static int push_captures (MatchState *ms, const char *s, const char *e) { + int i; + int nlevels = (ms->level == 0 && s) ? 1 : ms->level; + luaL_checkstack(ms->L, nlevels, "too many captures"); + for (i = 0; i < nlevels; i++) + push_onecapture(ms, i, s, e); + return nlevels; /* number of strings pushed */ +} + + +static int str_find_aux (lua_State *L, int find) { + size_t l1, l2; + const char *s = luaL_checklstring(L, 1, &l1); + const char *p = luaL_checklstring(L, 2, &l2); + ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1; + if (init < 0) init = 0; + else if ((size_t)(init) > l1) init = (ptrdiff_t)l1; + if (find && (lua_toboolean(L, 4) || /* explicit request? */ + strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */ + /* do a plain search */ + const char *s2 = lmemfind(s+init, l1-init, p, l2); + if (s2) { + lua_pushinteger(L, s2-s+1); + lua_pushinteger(L, s2-s+l2); + return 2; + } + } + else { + MatchState ms; + int anchor = (*p == '^') ? (p++, 1) : 0; + const char *s1=s+init; + ms.L = L; + ms.src_init = s; + ms.src_end = s+l1; + do { + const char *res; + ms.level = 0; + if ((res=match(&ms, s1, p)) != NULL) { + if (find) { + lua_pushinteger(L, s1-s+1); /* start */ + lua_pushinteger(L, res-s); /* end */ + return push_captures(&ms, NULL, 0) + 2; + } + else + return push_captures(&ms, s1, res); + } + } while (s1++ < ms.src_end && !anchor); + } + lua_pushnil(L); /* not found */ + return 1; +} + + +static int str_find (lua_State *L) { + return str_find_aux(L, 1); +} + + +static int str_match (lua_State *L) { + return str_find_aux(L, 0); +} + + +static int gmatch_aux (lua_State *L) { + MatchState ms; + size_t ls; + const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); + const char *p = lua_tostring(L, lua_upvalueindex(2)); + const char *src; + ms.L = L; + ms.src_init = s; + ms.src_end = s+ls; + for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); + src <= ms.src_end; + src++) { + const char *e; + ms.level = 0; + if ((e = match(&ms, src, p)) != NULL) { + lua_Integer newstart = e-s; + if (e == src) newstart++; /* empty match? go at least one position */ + lua_pushinteger(L, newstart); + lua_replace(L, lua_upvalueindex(3)); + return push_captures(&ms, src, e); + } + } + return 0; /* not found */ +} + + +static int gmatch (lua_State *L) { + luaL_checkstring(L, 1); + luaL_checkstring(L, 2); + lua_settop(L, 2); + lua_pushinteger(L, 0); + lua_pushcclosure(L, gmatch_aux, 3); + return 1; +} + + +static int gfind_nodef (lua_State *L) { + return luaL_error(L, LUA_QL("string.gfind") " was renamed to " + LUA_QL("string.gmatch")); +} + + +static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, + const char *e) { + size_t l, i; + const char *news = lua_tolstring(ms->L, 3, &l); + for (i = 0; i < l; i++) { + if (news[i] != L_ESC) + luaL_addchar(b, news[i]); + else { + i++; /* skip ESC */ + if (!isdigit(uchar(news[i]))) + luaL_addchar(b, news[i]); + else if (news[i] == '0') + luaL_addlstring(b, s, e - s); + else { + push_onecapture(ms, news[i] - '1', s, e); + luaL_addvalue(b); /* add capture to accumulated result */ + } + } + } +} + + +static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, + const char *e) { + lua_State *L = ms->L; + switch (lua_type(L, 3)) { + case LUA_TNUMBER: + case LUA_TSTRING: { + add_s(ms, b, s, e); + return; + } + case LUA_TFUNCTION: { + int n; + lua_pushvalue(L, 3); + n = push_captures(ms, s, e); + lua_call(L, n, 1); + break; + } + case LUA_TTABLE: { + push_onecapture(ms, 0, s, e); + lua_gettable(L, 3); + break; + } + } + if (!lua_toboolean(L, -1)) { /* nil or false? */ + lua_pop(L, 1); + lua_pushlstring(L, s, e - s); /* keep original text */ + } + else if (!lua_isstring(L, -1)) + luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); + luaL_addvalue(b); /* add result to accumulator */ +} + + +static int str_gsub (lua_State *L) { + size_t srcl; + const char *src = luaL_checklstring(L, 1, &srcl); + const char *p = luaL_checkstring(L, 2); + int tr = lua_type(L, 3); + int max_s = luaL_optint(L, 4, srcl+1); + int anchor = (*p == '^') ? (p++, 1) : 0; + int n = 0; + MatchState ms; + luaL_Buffer b; + luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || + tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, + "string/function/table expected"); + luaL_buffinit(L, &b); + ms.L = L; + ms.src_init = src; + ms.src_end = src+srcl; + while (n < max_s) { + const char *e; + ms.level = 0; + e = match(&ms, src, p); + if (e) { + n++; + add_value(&ms, &b, src, e); + } + if (e && e>src) /* non empty match? */ + src = e; /* skip it */ + else if (src < ms.src_end) + luaL_addchar(&b, *src++); + else break; + if (anchor) break; + } + luaL_addlstring(&b, src, ms.src_end-src); + luaL_pushresult(&b); + lua_pushinteger(L, n); /* number of substitutions */ + return 2; +} + +/* }====================================================== */ + + +/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ +#define MAX_ITEM 512 +/* valid flags in a format specification */ +#define FLAGS "-+ #0" +/* +** maximum size of each format specification (such as '%-099.99d') +** (+10 accounts for %99.99x plus margin of error) +*/ +#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10) + + +static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + luaL_addchar(b, '"'); + while (l--) { + switch (*s) { + case '"': case '\\': case '\n': { + luaL_addchar(b, '\\'); + luaL_addchar(b, *s); + break; + } + case '\r': { + luaL_addlstring(b, "\\r", 2); + break; + } + case '\0': { + luaL_addlstring(b, "\\000", 4); + break; + } + default: { + luaL_addchar(b, *s); + break; + } + } + s++; + } + luaL_addchar(b, '"'); +} + +static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { + const char *p = strfrmt; + while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ + if ((size_t)(p - strfrmt) >= sizeof(FLAGS)) + luaL_error(L, "invalid format (repeated flags)"); + if (isdigit(uchar(*p))) p++; /* skip width */ + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ + if (*p == '.') { + p++; + if (isdigit(uchar(*p))) p++; /* skip precision */ + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ + } + if (isdigit(uchar(*p))) + luaL_error(L, "invalid format (width or precision too long)"); + *(form++) = '%'; + strncpy(form, strfrmt, p - strfrmt + 1); + form += p - strfrmt + 1; + *form = '\0'; + return p; +} + + +static void addintlen (char *form) { + size_t l = strlen(form); + char spec = form[l - 1]; + strcpy(form + l - 1, LUA_INTFRMLEN); + form[l + sizeof(LUA_INTFRMLEN) - 2] = spec; + form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0'; +} + + +static int str_format (lua_State *L) { + int arg = 1; + size_t sfl; + const char *strfrmt = luaL_checklstring(L, arg, &sfl); + const char *strfrmt_end = strfrmt+sfl; + luaL_Buffer b; + luaL_buffinit(L, &b); + while (strfrmt < strfrmt_end) { + if (*strfrmt != L_ESC) + luaL_addchar(&b, *strfrmt++); + else if (*++strfrmt == L_ESC) + luaL_addchar(&b, *strfrmt++); /* %% */ + else { /* format item */ + char form[MAX_FORMAT]; /* to store the format (`%...') */ + char buff[MAX_ITEM]; /* to store the formatted item */ + arg++; + strfrmt = scanformat(L, strfrmt, form); + switch (*strfrmt++) { + case 'c': { + sprintf(buff, form, (int)luaL_checknumber(L, arg)); + break; + } + case 'd': case 'i': { + addintlen(form); + sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg)); + break; + } + case 'o': case 'u': case 'x': case 'X': { + addintlen(form); + sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg)); + break; + } + case 'e': case 'E': case 'f': + case 'g': case 'G': { + sprintf(buff, form, (double)luaL_checknumber(L, arg)); + break; + } + case 'q': { + addquoted(L, &b, arg); + continue; /* skip the 'addsize' at the end */ + } + case 's': { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + if (!strchr(form, '.') && l >= 100) { + /* no precision and string is too long to be formatted; + keep original string */ + lua_pushvalue(L, arg); + luaL_addvalue(&b); + continue; /* skip the `addsize' at the end */ + } + else { + sprintf(buff, form, s); + break; + } + } + default: { /* also treat cases `pnLlh' */ + return luaL_error(L, "invalid option " LUA_QL("%%%c") " to " + LUA_QL("format"), *(strfrmt - 1)); + } + } + luaL_addlstring(&b, buff, strlen(buff)); + } + } + luaL_pushresult(&b); + return 1; +} + + +static const luaL_Reg strlib[] = { + {"byte", str_byte}, + {"char", str_char}, + {"dump", str_dump}, + {"find", str_find}, + {"format", str_format}, + {"gfind", gfind_nodef}, + {"gmatch", gmatch}, + {"gsub", str_gsub}, + {"len", str_len}, + {"lower", str_lower}, + {"match", str_match}, + {"rep", str_rep}, + {"reverse", str_reverse}, + {"sub", str_sub}, + {"upper", str_upper}, + {NULL, NULL} +}; + + +static void createmetatable (lua_State *L) { + lua_createtable(L, 0, 1); /* create metatable for strings */ + lua_pushliteral(L, ""); /* dummy string */ + lua_pushvalue(L, -2); + lua_setmetatable(L, -2); /* set string metatable */ + lua_pop(L, 1); /* pop dummy string */ + lua_pushvalue(L, -2); /* string library... */ + lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */ + lua_pop(L, 1); /* pop metatable */ +} + + +/* +** Open string library +*/ +LUALIB_API int luaopen_string (lua_State *L) { + luaL_register(L, LUA_STRLIBNAME, strlib); +#if defined(LUA_COMPAT_GFIND) + lua_getfield(L, -1, "gmatch"); + lua_setfield(L, -2, "gfind"); +#endif + createmetatable(L); + return 1; +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/ltable.c b/vscript/languages/lua/lua-5.1.4/src/ltable.c new file mode 100644 index 00000000..44f557a8 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/ltable.c @@ -0,0 +1,654 @@ +/* +** $Id: ltable.c,v 2.32.1.2 2007/12/28 15:32:23 roberto Exp $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + + +/* +** Implementation of tables (aka arrays, objects, or hash tables). +** Tables keep its elements in two parts: an array part and a hash part. +** Non-negative integer keys are all candidates to be kept in the array +** part. The actual size of the array is the largest `n' such that at +** least half the slots between 0 and n are in use. +** Hash uses a mix of chained scatter table with Brent's variation. +** A main invariant of these tables is that, if an element is not +** in its main position (i.e. the `original' position that its hash gives +** to it), then the colliding element is in its own main position. +** Hence even when the load factor reaches 100%, performance remains good. +*/ + +#include +#include + +#define ltable_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "ltable.h" + + +/* +** max size of array part is 2^MAXBITS +*/ +#if LUAI_BITSINT > 26 +#define MAXBITS 26 +#else +#define MAXBITS (LUAI_BITSINT-2) +#endif + +#define MAXASIZE (1 << MAXBITS) + + +#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) + +#ifdef LUA_MOD_CASE_INSENSITIVE +#define hashstrstr(t,str) hashpow2(t, (str)->tsv.hash) +#define hashkeystr(t,str) hashpow2(t, (str)->tsv.keyhash) +#define hashstr(t,str) (gflag(t,TH_SYMTABLE) == 0 ? \ + hashstrstr(t, (str)) : hashkeystr(t, (str))) +#else +#define hashstr(t,str) hashpow2(t, (str)->tsv.hash) +#endif +#define hashboolean(t,p) hashpow2(t, p) + + +/* +** for some types, it is better to avoid modulus by power of 2, as +** they tend to have many 2 factors. +*/ +#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) + + +#define hashpointer(t,p) hashmod(t, IntPoint(p)) + + +/* +** number of ints inside a lua_Number +*/ +#define numints cast_int(sizeof(lua_Number)/sizeof(int)) + + + +#define dummynode (&dummynode_) + +static const Node dummynode_ = { + {{NULL}, LUA_TNIL}, /* value */ + {{{NULL}, LUA_TNIL, NULL}} /* key */ +}; + + +/* +** hash for lua_Numbers +*/ +static Node *hashnum (const Table *t, lua_Number n) { + unsigned int a[numints]; + int i; + if (luai_numeq(n, 0)) /* avoid problems with -0 */ + return gnode(t, 0); + memcpy(a, &n, sizeof(a)); + for (i = 1; i < numints; i++) a[0] += a[i]; + return hashmod(t, a[0]); +} + + +#ifdef LUA_MOD_CASE_INSENSITIVE + +static int l_strkeyeq (const Table *t, const TString *ls, const TString *rs) { + const char *l = getstr(ls); + size_t ll = ls->tsv.len; + const char *r = getstr(rs); + size_t lr = rs->tsv.len; + if (ll != lr) return 0; + for (;;) { + int temp = gflag(t,TH_SYMTABLE) == 0 ? strcmp(l, r) : luai_strcasecmp(l, r); + if (temp != 0) return 0; + else { /* strings are equal up to a `\0' */ + size_t len = strlen(l); /* index of first `\0' in both strings */ + if (len == lr) /* r is finished? */ + return (len == ll); + else if (len == ll) /* l is finished? */ + return 0; /* l is smaller than r (because r is not finished) */ + /* both strings longer than `len'; go on comparing (after the `\0') */ + len++; + l += len; ll -= len; r += len; lr -= len; + } + } +} + + +static int equalkey(const Table *t, const Node *n, const StkId key) { + const TValue *tv = key2tval(n); + if (ttisstring(tv) && ttisstring(key)) + return (rawtsvalue(tv) == rawtsvalue(key) || + l_strkeyeq(t, rawtsvalue(tv), rawtsvalue(key))); + return luaO_rawequalObj(tv, key); +} + +#endif + +/* +** returns the `main' position of an element in a table (that is, the index +** of its hash value) +*/ +static Node *mainposition (const Table *t, const TValue *key) { + switch (ttype(key)) { + case LUA_TNUMBER: + return hashnum(t, nvalue(key)); + case LUA_TSTRING: + return hashstr(t, rawtsvalue(key)); + case LUA_TBOOLEAN: + return hashboolean(t, bvalue(key)); + case LUA_TLIGHTUSERDATA: + return hashpointer(t, pvalue(key)); + default: + return hashpointer(t, gcvalue(key)); + } +} + + +/* +** returns the index for `key' if `key' is an appropriate key to live in +** the array part of the table, -1 otherwise. +*/ +static int arrayindex (const TValue *key) { + if (ttisnumber(key)) { + lua_Number n = nvalue(key); + int k; + lua_number2int(k, n); + if (luai_numeq(cast_num(k), n)) + return k; + } + return -1; /* `key' did not match some condition */ +} + + +/* +** returns the index of a `key' for table traversals. First goes all +** elements in the array part, then elements in the hash part. The +** beginning of a traversal is signalled by -1. +*/ +static int findindex (lua_State *L, Table *t, StkId key) { + int i; + if (ttisnil(key)) return -1; /* first iteration */ + i = arrayindex(key); + if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ + return i-1; /* yes; that's the index (corrected to C) */ + else { + Node *n = mainposition(t, key); + do { /* check whether `key' is somewhere in the chain */ + /* key may be dead already, but it is ok to use it in `next' */ +#ifdef LUA_MOD_CASE_INSENSITIVE + if (equalkey(t, n, key) || +#else + if (luaO_rawequalObj(key2tval(n), key) || +#endif + (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) && + gcvalue(gkey(n)) == gcvalue(key))) { + i = cast_int(n - gnode(t, 0)); /* key index in hash table */ + /* hash elements are numbered after array ones */ + return i + t->sizearray; + } + else n = gnext(n); + } while (n); + luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ + return 0; /* to avoid warnings */ + } +} + + +int luaH_next (lua_State *L, Table *t, StkId key) { + int i = findindex(L, t, key); /* find original element */ + for (i++; i < t->sizearray; i++) { /* try first array part */ + if (!ttisnil(&t->array[i])) { /* a non-nil value? */ + setnvalue(key, cast_num(i+1)); + setobj2s(L, key+1, &t->array[i]); + return 1; + } + } + for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ + if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ + setobj2s(L, key, key2tval(gnode(t, i))); + setobj2s(L, key+1, gval(gnode(t, i))); + return 1; + } + } + return 0; /* no more elements */ +} + + +/* +** {============================================================= +** Rehash +** ============================================================== +*/ + + +static int computesizes (int nums[], int *narray) { + int i; + int twotoi; /* 2^i */ + int a = 0; /* number of elements smaller than 2^i */ + int na = 0; /* number of elements to go to array part */ + int n = 0; /* optimal size for array part */ + for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) { + if (nums[i] > 0) { + a += nums[i]; + if (a > twotoi/2) { /* more than half elements present? */ + n = twotoi; /* optimal size (till now) */ + na = a; /* all elements smaller than n will go to array part */ + } + } + if (a == *narray) break; /* all elements already counted */ + } + *narray = n; + lua_assert(*narray/2 <= na && na <= *narray); + return na; +} + + +static int countint (const TValue *key, int *nums) { + int k = arrayindex(key); + if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */ + nums[ceillog2(k)]++; /* count as such */ + return 1; + } + else + return 0; +} + + +static int numusearray (const Table *t, int *nums) { + int lg; + int ttlg; /* 2^lg */ + int ause = 0; /* summation of `nums' */ + int i = 1; /* count to traverse all array keys */ + for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */ + int lc = 0; /* counter */ + int lim = ttlg; + if (lim > t->sizearray) { + lim = t->sizearray; /* adjust upper limit */ + if (i > lim) + break; /* no more elements to count */ + } + /* count elements in range (2^(lg-1), 2^lg] */ + for (; i <= lim; i++) { + if (!ttisnil(&t->array[i-1])) + lc++; + } + nums[lg] += lc; + ause += lc; + } + return ause; +} + + +static int numusehash (const Table *t, int *nums, int *pnasize) { + int totaluse = 0; /* total number of elements */ + int ause = 0; /* summation of `nums' */ + int i = sizenode(t); + while (i--) { + Node *n = &t->node[i]; + if (!ttisnil(gval(n))) { + ause += countint(key2tval(n), nums); + totaluse++; + } + } + *pnasize += ause; + return totaluse; +} + + +static void setarrayvector (lua_State *L, Table *t, int size) { + int i; + luaM_reallocvector(L, t->array, t->sizearray, size, TValue); + for (i=t->sizearray; iarray[i]); + t->sizearray = size; +} + + +static void setnodevector (lua_State *L, Table *t, int size) { + int lsize; + if (size == 0) { /* no elements to hash part? */ + t->node = cast(Node *, dummynode); /* use common `dummynode' */ + lsize = 0; + } + else { + int i; + lsize = ceillog2(size); + if (lsize > MAXBITS) + luaG_runerror(L, "table overflow"); + size = twoto(lsize); + t->node = luaM_newvector(L, size, Node); + for (i=0; ilsizenode = cast_byte(lsize); + t->lastfree = gnode(t, size); /* all positions are free */ +} + + +static void resize (lua_State *L, Table *t, int nasize, int nhsize) { + int i; + int oldasize = t->sizearray; + int oldhsize = t->lsizenode; + Node *nold = t->node; /* save old hash ... */ + if (nasize > oldasize) /* array part must grow? */ + setarrayvector(L, t, nasize); + /* create new hash part with appropriate size */ + setnodevector(L, t, nhsize); + if (nasize < oldasize) { /* array part must shrink? */ + t->sizearray = nasize; + /* re-insert elements from vanishing slice */ + for (i=nasize; iarray[i])) + setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]); + } + /* shrink array */ + luaM_reallocvector(L, t->array, oldasize, nasize, TValue); + } + /* re-insert elements from hash part */ + for (i = twoto(oldhsize) - 1; i >= 0; i--) { + Node *old = nold+i; + if (!ttisnil(gval(old))) + setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old)); + } + if (nold != dummynode) + luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */ +} + + +void luaH_resizearray (lua_State *L, Table *t, int nasize) { + int nsize = (t->node == dummynode) ? 0 : sizenode(t); + resize(L, t, nasize, nsize); +} + + +static void rehash (lua_State *L, Table *t, const TValue *ek) { + int nasize, na; + int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */ + int i; + int totaluse; + for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */ + nasize = numusearray(t, nums); /* count keys in array part */ + totaluse = nasize; /* all those keys are integer keys */ + totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */ + /* count extra key */ + nasize += countint(ek, nums); + totaluse++; + /* compute new size for array part */ + na = computesizes(nums, &nasize); + /* resize the table to new computed sizes */ + resize(L, t, nasize, totaluse - na); +} + + + +/* +** }============================================================= +*/ + + +Table *luaH_new (lua_State *L, int narray, int nhash) { + Table *t = luaM_new(L, Table); + luaC_link(L, obj2gco(t), LUA_TTABLE); + t->metatable = NULL; + t->flags = cast_byte(~0); + /* temporary values (kept only if some malloc fails) */ + t->array = NULL; + t->sizearray = 0; + t->lsizenode = 0; + t->node = cast(Node *, dummynode); + setarrayvector(L, t, narray); + setnodevector(L, t, nhash); + return t; +} + + +void luaH_free (lua_State *L, Table *t) { + if (t->node != dummynode) + luaM_freearray(L, t->node, sizenode(t), Node); + luaM_freearray(L, t->array, t->sizearray, TValue); + luaM_free(L, t); +} + + +static Node *getfreepos (Table *t) { + while (t->lastfree-- > t->node) { + if (ttisnil(gkey(t->lastfree))) + return t->lastfree; + } + return NULL; /* could not find a free place */ +} + + + +/* +** inserts a new key into a hash table; first, check whether key's main +** position is free. If not, check whether colliding node is in its main +** position or not: if it is not, move colliding node to an empty place and +** put new key in its main position; otherwise (colliding node is in its main +** position), new key goes to an empty position. +*/ +static TValue *newkey (lua_State *L, Table *t, const TValue *key) { + Node *mp = mainposition(t, key); + if (!ttisnil(gval(mp)) || mp == dummynode) { + Node *othern; + Node *n = getfreepos(t); /* get a free place */ + if (n == NULL) { /* cannot find a free place? */ + rehash(L, t, key); /* grow table */ + return luaH_set(L, t, key); /* re-insert key into grown table */ + } + lua_assert(n != dummynode); + othern = mainposition(t, key2tval(mp)); + if (othern != mp) { /* is colliding node out of its main position? */ + /* yes; move colliding node into free position */ + while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ + gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ + *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ + gnext(mp) = NULL; /* now `mp' is free */ + setnilvalue(gval(mp)); + } + else { /* colliding node is in its own main position */ + /* new node will go into free position */ + gnext(n) = gnext(mp); /* chain new position */ + gnext(mp) = n; + mp = n; + } + } + gkey(mp)->value = key->value; gkey(mp)->tt = key->tt; + luaC_barriert(L, t, key); + lua_assert(ttisnil(gval(mp))); + return gval(mp); +} + + +/* +** search function for integers +*/ +const TValue *luaH_getnum (Table *t, int key) { + /* (1 <= key && key <= t->sizearray) */ + if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) + return &t->array[key-1]; + else { + lua_Number nk = cast_num(key); + Node *n = hashnum(t, nk); + do { /* check whether `key' is somewhere in the chain */ + if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; + } +} + + +/* +** search function for strings +*/ +const TValue *luaH_getstr (Table *t, TString *key) { + Node *n = hashstr(t, key); + do { /* check whether `key' is somewhere in the chain */ +#ifdef LUA_MOD_CASE_INSENSITIVE + if (ttisstring(gkey(n)) && (rawtsvalue(gkey(n)) == key || + l_strkeyeq(t, rawtsvalue(gkey(n)), key))) +#else + if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key) +#endif + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; +} + + +/* +** main search function +*/ +const TValue *luaH_get (Table *t, const TValue *key) { + switch (ttype(key)) { + case LUA_TNIL: return luaO_nilobject; + case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key)); + case LUA_TNUMBER: { + int k; + lua_Number n = nvalue(key); + lua_number2int(k, n); + if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */ + return luaH_getnum(t, k); /* use specialized version */ + /* else go through */ + } + default: { + Node *n = mainposition(t, key); + do { /* check whether `key' is somewhere in the chain */ + if (luaO_rawequalObj(key2tval(n), key)) + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; + } + } +} + + +TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { + const TValue *p = luaH_get(t, key); +#ifdef LUA_MOD_CASE_INSENSITIVE + t->flags &= 1u<flags = 0; +#endif + if (p != luaO_nilobject) + return cast(TValue *, p); + else { + if (ttisnil(key)) luaG_runerror(L, "table index is nil"); + else if (ttisnumber(key) && luai_numisnan(nvalue(key))) + luaG_runerror(L, "table index is NaN"); + return newkey(L, t, key); + } +} + + +TValue *luaH_setnum (lua_State *L, Table *t, int key) { + const TValue *p = luaH_getnum(t, key); + if (p != luaO_nilobject) + return cast(TValue *, p); + else { + TValue k; + setnvalue(&k, cast_num(key)); + return newkey(L, t, &k); + } +} + + +TValue *luaH_setstr (lua_State *L, Table *t, TString *key) { + const TValue *p = luaH_getstr(t, key); + if (p != luaO_nilobject) + return cast(TValue *, p); + else { + TValue k; + setsvalue(L, &k, key); + return newkey(L, t, &k); + } +} + + +static int unbound_search (Table *t, unsigned int j) { + unsigned int i = j; /* i is zero or a present index */ + j++; + /* find `i' and `j' such that i is present and j is not */ + while (!ttisnil(luaH_getnum(t, j))) { + i = j; + j *= 2; + if (j > cast(unsigned int, MAX_INT)) { /* overflow? */ + /* table was built with bad purposes: resort to linear search */ + i = 1; + while (!ttisnil(luaH_getnum(t, i))) i++; + return i - 1; + } + } + /* now do a binary search between them */ + while (j - i > 1) { + unsigned int m = (i+j)/2; + if (ttisnil(luaH_getnum(t, m))) j = m; + else i = m; + } + return i; +} + + +/* +** 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). +*/ +int luaH_getn (Table *t) { + unsigned int j = t->sizearray; + if (j > 0 && ttisnil(&t->array[j - 1])) { + /* there is a boundary in the array part: (binary) search for it */ + unsigned int i = 0; + while (j - i > 1) { + unsigned int m = (i+j)/2; + if (ttisnil(&t->array[m - 1])) j = m; + else i = m; + } + return i; + } + /* else must find a boundary in hash part */ + else if (t->node == dummynode) /* hash part is empty? */ + return j; /* that is easy... */ + else return unbound_search(t, j); +} + +#ifdef LUA_MOD_CASE_INSENSITIVE + +void luaH_setflag (Table *t, int flag, int v) { + int m = 1u << flag; + v <<= flag; + t->flags = (t->flags & ~m) | (v & m); +} + +int luaH_getflag (Table *t, int flag) { + return (t->flags >> flag) & 1; +} + +#endif + +#if defined(LUA_DEBUG) + +Node *luaH_mainposition (const Table *t, const TValue *key) { + return mainposition(t, key); +} + +int luaH_isdummy (Node *n) { return n == dummynode; } + +#endif diff --git a/vscript/languages/lua/lua-5.1.4/src/ltable.h b/vscript/languages/lua/lua-5.1.4/src/ltable.h new file mode 100644 index 00000000..90343a03 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/ltable.h @@ -0,0 +1,52 @@ +/* +** $Id: ltable.h,v 2.10.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + +#ifndef ltable_h +#define ltable_h + +#include "lobject.h" + + +#define gnode(t,i) (&(t)->node[i]) +#define gkey(n) (&(n)->i_key.nk) +#define gval(n) (&(n)->i_val) +#define gnext(n) ((n)->i_key.nk.next) + +#define key2tval(n) (&(n)->i_key.tvk) + +#ifdef LUA_MOD_CASE_INSENSITIVE + +#define gflag(t,n) ((t)->flags & (1<<(n))) + +/* Symbol table - keys are case-insensitive (set by default) */ +#define TH_SYMTABLE 6 +#define TH_EMPTYTABLE 7 + +LUAI_FUNC void luaH_setflag (Table *t, int flag, int v); +LUAI_FUNC int luaH_getflag (Table *t, int flag); + +#endif + +LUAI_FUNC const TValue *luaH_getnum (Table *t, int key); +LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key); +LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); +LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key); +LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); +LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); +LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash); +LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); +LUAI_FUNC void luaH_free (lua_State *L, Table *t); +LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); +LUAI_FUNC int luaH_getn (Table *t); + + +#if defined(LUA_DEBUG) +LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); +LUAI_FUNC int luaH_isdummy (Node *n); +#endif + + +#endif diff --git a/vscript/languages/lua/lua-5.1.4/src/ltablib.c b/vscript/languages/lua/lua-5.1.4/src/ltablib.c new file mode 100644 index 00000000..76f2ab6d --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/ltablib.c @@ -0,0 +1,313 @@ +/* +** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $ +** Library for Table Manipulation +** See Copyright Notice in lua.h +*/ + + +#include + +#define ltablib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" +#ifdef LUA_MOD_CASE_INSENSITIVE +#include "ltable.h" +#endif + + +#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) + + +static int foreachi (lua_State *L) { + int i; + int n = aux_getn(L, 1); + luaL_checktype(L, 2, LUA_TFUNCTION); + for (i=1; i <= n; i++) { + lua_pushvalue(L, 2); /* function */ + lua_pushinteger(L, i); /* 1st argument */ + lua_rawgeti(L, 1, i); /* 2nd argument */ + lua_call(L, 2, 1); + if (!lua_isnil(L, -1)) + return 1; + lua_pop(L, 1); /* remove nil result */ + } + return 0; +} + + +static int foreach (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checktype(L, 2, LUA_TFUNCTION); + lua_pushnil(L); /* first key */ + while (lua_next(L, 1)) { + lua_pushvalue(L, 2); /* function */ + lua_pushvalue(L, -3); /* key */ + lua_pushvalue(L, -3); /* value */ + lua_call(L, 2, 1); + if (!lua_isnil(L, -1)) + return 1; + lua_pop(L, 2); /* remove value and result */ + } + return 0; +} + + +static int maxn (lua_State *L) { + lua_Number max = 0; + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushnil(L); /* first key */ + while (lua_next(L, 1)) { + lua_pop(L, 1); /* remove value */ + if (lua_type(L, -1) == LUA_TNUMBER) { + lua_Number v = lua_tonumber(L, -1); + if (v > max) max = v; + } + } + lua_pushnumber(L, max); + return 1; +} + + +static int getn (lua_State *L) { + lua_pushinteger(L, aux_getn(L, 1)); + return 1; +} + + +static int setn (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); +#ifndef luaL_setn + luaL_setn(L, 1, luaL_checkint(L, 2)); +#else + luaL_error(L, LUA_QL("setn") " is obsolete"); +#endif + lua_pushvalue(L, 1); + return 1; +} + + +static int tinsert (lua_State *L) { + int e = aux_getn(L, 1) + 1; /* first empty element */ + int pos; /* where to insert new element */ + switch (lua_gettop(L)) { + case 2: { /* called with only 2 arguments */ + pos = e; /* insert new element at the end */ + break; + } + case 3: { + int i; + pos = luaL_checkint(L, 2); /* 2nd argument is the position */ + if (pos > e) e = pos; /* `grow' array if necessary */ + for (i = e; i > pos; i--) { /* move up elements */ + lua_rawgeti(L, 1, i-1); + lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ + } + break; + } + default: { + return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); + } + } + luaL_setn(L, 1, e); /* new size */ + lua_rawseti(L, 1, pos); /* t[pos] = v */ + return 0; +} + + +static int tremove (lua_State *L) { + int e = aux_getn(L, 1); + int pos = luaL_optint(L, 2, e); + if (!(1 <= pos && pos <= e)) /* position is outside bounds? */ + return 0; /* nothing to remove */ + luaL_setn(L, 1, e - 1); /* t.n = n-1 */ + lua_rawgeti(L, 1, pos); /* result = t[pos] */ + for ( ;pos= P */ + while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { + if (i>u) luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[i] */ + } + /* repeat --j until a[j] <= P */ + while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { + if (j + +#define ltm_c +#define LUA_CORE + +#include "lua.h" + +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + + +const char *const luaT_typenames[] = { + "nil", "boolean", "userdata", "number", + "string", "table", "function", "userdata", "thread", + "proto", "upval" +}; + + +void luaT_init (lua_State *L) { + static const char *const luaT_eventname[] = { /* ORDER TM */ + "__index", "__newindex", + "__gc", "__mode", "__eq", + "__add", "__sub", "__mul", "__div", "__mod", + "__pow", "__unm", "__len", "__lt", "__le", + "__concat", "__call" + }; + int i; + for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); + luaS_fix(G(L)->tmname[i]); /* never collect these names */ + } +} + + +/* +** function to be used with macro "fasttm": optimized for absence of +** tag methods +*/ +const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { + const TValue *tm = luaH_getstr(events, ename); + lua_assert(event <= TM_EQ); + if (ttisnil(tm)) { /* no tag method? */ + events->flags |= cast_byte(1u<metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(o)->metatable; + break; + default: + mt = G(L)->mt[ttype(o)]; + } + return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/ltm.h b/vscript/languages/lua/lua-5.1.4/src/ltm.h new file mode 100644 index 00000000..64343b78 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/ltm.h @@ -0,0 +1,54 @@ +/* +** $Id: ltm.h,v 2.6.1.1 2007/12/27 13:02:25 roberto Exp $ +** Tag methods +** See Copyright Notice in lua.h +*/ + +#ifndef ltm_h +#define ltm_h + + +#include "lobject.h" + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER TM" +*/ +typedef enum { + TM_INDEX, + TM_NEWINDEX, + TM_GC, + TM_MODE, + TM_EQ, /* last tag method with `fast' access */ + TM_ADD, + TM_SUB, + TM_MUL, + TM_DIV, + TM_MOD, + TM_POW, + TM_UNM, + TM_LEN, + TM_LT, + TM_LE, + TM_CONCAT, + TM_CALL, + TM_N /* number of elements in the enum */ +} TMS; + + + +#define gfasttm(g,et,e) ((et) == NULL ? NULL : \ + ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) + +#define fasttm(l,et,e) gfasttm(G(l), et, e) + +LUAI_DATA const char *const luaT_typenames[]; + + +LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); +LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, + TMS event); +LUAI_FUNC void luaT_init (lua_State *L); + +#endif diff --git a/vscript/languages/lua/lua-5.1.4/src/lua.c b/vscript/languages/lua/lua-5.1.4/src/lua.c new file mode 100644 index 00000000..3a466093 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lua.c @@ -0,0 +1,392 @@ +/* +** $Id: lua.c,v 1.160.1.2 2007/12/28 15:32:23 roberto Exp $ +** Lua stand-alone interpreter +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include + +#define lua_c + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + +static lua_State *globalL = NULL; + +static const char *progname = LUA_PROGNAME; + + + +static void lstop (lua_State *L, lua_Debug *ar) { + (void)ar; /* unused arg. */ + lua_sethook(L, NULL, 0, 0); + luaL_error(L, "interrupted!"); +} + + +static void laction (int i) { + signal(i, SIG_DFL); /* if another SIGINT happens before lstop, + terminate process (default action) */ + lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); +} + + +static void print_usage (void) { + fprintf(stderr, + "usage: %s [options] [script [args]].\n" + "Available options are:\n" + " -e stat execute string " LUA_QL("stat") "\n" + " -l name require library " LUA_QL("name") "\n" + " -i enter interactive mode after executing " LUA_QL("script") "\n" + " -v show version information\n" + " -- stop handling options\n" + " - execute stdin and stop handling options\n" + , + progname); + fflush(stderr); +} + + +static void l_message (const char *pname, const char *msg) { + if (pname) fprintf(stderr, "%s: ", pname); + fprintf(stderr, "%s\n", msg); + fflush(stderr); +} + + +static int report (lua_State *L, int status) { + if (status && !lua_isnil(L, -1)) { + const char *msg = lua_tostring(L, -1); + if (msg == NULL) msg = "(error object is not a string)"; + l_message(progname, msg); + lua_pop(L, 1); + } + return status; +} + + +static int traceback (lua_State *L) { + if (!lua_isstring(L, 1)) /* 'message' not a string? */ + return 1; /* keep it intact */ + lua_getfield(L, LUA_GLOBALSINDEX, "debug"); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + return 1; + } + lua_getfield(L, -1, "traceback"); + if (!lua_isfunction(L, -1)) { + lua_pop(L, 2); + return 1; + } + lua_pushvalue(L, 1); /* pass error message */ + lua_pushinteger(L, 2); /* skip this function and traceback */ + lua_call(L, 2, 1); /* call debug.traceback */ + return 1; +} + + +static int docall (lua_State *L, int narg, int clear) { + int status; + int base = lua_gettop(L) - narg; /* function index */ + lua_pushcfunction(L, traceback); /* push traceback function */ + lua_insert(L, base); /* put it under chunk and args */ + signal(SIGINT, laction); + status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base); + signal(SIGINT, SIG_DFL); + lua_remove(L, base); /* remove traceback function */ + /* force a complete garbage collection in case of errors */ + if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0); + return status; +} + + +static void print_version (void) { + l_message(NULL, LUA_RELEASE " " LUA_COPYRIGHT); +} + + +static int getargs (lua_State *L, char **argv, int n) { + int narg; + int i; + int argc = 0; + while (argv[argc]) argc++; /* count total number of arguments */ + narg = argc - (n + 1); /* number of arguments to the script */ + luaL_checkstack(L, narg + 3, "too many arguments to script"); + for (i=n+1; i < argc; i++) + lua_pushstring(L, argv[i]); + lua_createtable(L, narg, n + 1); + for (i=0; i < argc; i++) { + lua_pushstring(L, argv[i]); + lua_rawseti(L, -2, i - n); + } + return narg; +} + + +static int dofile (lua_State *L, const char *name) { + int status = luaL_loadfile(L, name) || docall(L, 0, 1); + return report(L, status); +} + + +static int dostring (lua_State *L, const char *s, const char *name) { + int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1); + return report(L, status); +} + + +static int dolibrary (lua_State *L, const char *name) { + lua_getglobal(L, "require"); + lua_pushstring(L, name); + return report(L, docall(L, 1, 1)); +} + + +static const char *get_prompt (lua_State *L, int firstline) { + const char *p; + lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2"); + p = lua_tostring(L, -1); + if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); + lua_pop(L, 1); /* remove global */ + return p; +} + + +static int incomplete (lua_State *L, int status) { + if (status == LUA_ERRSYNTAX) { + size_t lmsg; + const char *msg = lua_tolstring(L, -1, &lmsg); + const char *tp = msg + lmsg - (sizeof(LUA_QL("")) - 1); + if (strstr(msg, LUA_QL("")) == tp) { + lua_pop(L, 1); + return 1; + } + } + return 0; /* else... */ +} + + +static int pushline (lua_State *L, int firstline) { + char buffer[LUA_MAXINPUT]; + char *b = buffer; + size_t l; + const char *prmt = get_prompt(L, firstline); + if (lua_readline(L, b, prmt) == 0) + return 0; /* no input */ + l = strlen(b); + if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ + b[l-1] = '\0'; /* remove it */ + if (firstline && b[0] == '=') /* first line starts with `=' ? */ + lua_pushfstring(L, "return %s", b+1); /* change it to `return' */ + else + lua_pushstring(L, b); + lua_freeline(L, b); + return 1; +} + + +static int loadline (lua_State *L) { + int status; + lua_settop(L, 0); + if (!pushline(L, 1)) + return -1; /* no input */ + for (;;) { /* repeat until gets a complete line */ + status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); + if (!incomplete(L, status)) break; /* cannot try to add lines? */ + if (!pushline(L, 0)) /* no more input? */ + return -1; + lua_pushliteral(L, "\n"); /* add a new line... */ + lua_insert(L, -2); /* ...between the two lines */ + lua_concat(L, 3); /* join them */ + } + lua_saveline(L, 1); + lua_remove(L, 1); /* remove line */ + return status; +} + + +static void dotty (lua_State *L) { + int status; + const char *oldprogname = progname; + progname = NULL; + while ((status = loadline(L)) != -1) { + if (status == 0) status = docall(L, 0, 0); + report(L, status); + if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ + lua_getglobal(L, "print"); + lua_insert(L, 1); + if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) + l_message(progname, lua_pushfstring(L, + "error calling " LUA_QL("print") " (%s)", + lua_tostring(L, -1))); + } + } + lua_settop(L, 0); /* clear stack */ + fputs("\n", stdout); + fflush(stdout); + progname = oldprogname; +} + + +static int handle_script (lua_State *L, char **argv, int n) { + int status; + const char *fname; + int narg = getargs(L, argv, n); /* collect arguments */ + lua_setglobal(L, "arg"); + fname = argv[n]; + if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) + fname = NULL; /* stdin */ + status = luaL_loadfile(L, fname); + lua_insert(L, -(narg+1)); + if (status == 0) + status = docall(L, narg, 0); + else + lua_pop(L, narg); + return report(L, status); +} + + +/* check that argument has no extra characters at the end */ +#define notail(x) {if ((x)[2] != '\0') return -1;} + + +static int collectargs (char **argv, int *pi, int *pv, int *pe) { + int i; + for (i = 1; argv[i] != NULL; i++) { + if (argv[i][0] != '-') /* not an option? */ + return i; + switch (argv[i][1]) { /* option */ + case '-': + notail(argv[i]); + return (argv[i+1] != NULL ? i+1 : 0); + case '\0': + return i; + case 'i': + notail(argv[i]); + *pi = 1; /* go through */ + case 'v': + notail(argv[i]); + *pv = 1; + break; + case 'e': + *pe = 1; /* go through */ + case 'l': + if (argv[i][2] == '\0') { + i++; + if (argv[i] == NULL) return -1; + } + break; + default: return -1; /* invalid option */ + } + } + return 0; +} + + +static int runargs (lua_State *L, char **argv, int n) { + int i; + for (i = 1; i < n; i++) { + if (argv[i] == NULL) continue; + lua_assert(argv[i][0] == '-'); + switch (argv[i][1]) { /* option */ + case 'e': { + const char *chunk = argv[i] + 2; + if (*chunk == '\0') chunk = argv[++i]; + lua_assert(chunk != NULL); + if (dostring(L, chunk, "=(command line)") != 0) + return 1; + break; + } + case 'l': { + const char *filename = argv[i] + 2; + if (*filename == '\0') filename = argv[++i]; + lua_assert(filename != NULL); + if (dolibrary(L, filename)) + return 1; /* stop if file fails */ + break; + } + default: break; + } + } + return 0; +} + + +static int handle_luainit (lua_State *L) { + const char *init = getenv(LUA_INIT); + if (init == NULL) return 0; /* status OK */ + else if (init[0] == '@') + return dofile(L, init+1); + else + return dostring(L, init, "=" LUA_INIT); +} + + +struct Smain { + int argc; + char **argv; + int status; +}; + + +static int pmain (lua_State *L) { + struct Smain *s = (struct Smain *)lua_touserdata(L, 1); + char **argv = s->argv; + int script; + int has_i = 0, has_v = 0, has_e = 0; + globalL = L; + if (argv[0] && argv[0][0]) progname = argv[0]; + lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ + luaL_openlibs(L); /* open libraries */ + lua_gc(L, LUA_GCRESTART, 0); + s->status = handle_luainit(L); + if (s->status != 0) return 0; + script = collectargs(argv, &has_i, &has_v, &has_e); + if (script < 0) { /* invalid args? */ + print_usage(); + s->status = 1; + return 0; + } + if (has_v) print_version(); + s->status = runargs(L, argv, (script > 0) ? script : s->argc); + if (s->status != 0) return 0; + if (script) + s->status = handle_script(L, argv, script); + if (s->status != 0) return 0; + if (has_i) + dotty(L); + else if (script == 0 && !has_e && !has_v) { + if (lua_stdin_is_tty()) { + print_version(); + dotty(L); + } + else dofile(L, NULL); /* executes stdin as a file */ + } + return 0; +} + + +int main (int argc, char **argv) { + int status; + struct Smain s; + lua_State *L = lua_open(); /* create state */ + if (L == NULL) { + l_message(argv[0], "cannot create state: not enough memory"); + return EXIT_FAILURE; + } + s.argc = argc; + s.argv = argv; + status = lua_cpcall(L, &pmain, &s); + report(L, status); + lua_close(L); + return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS; +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/lua.h b/vscript/languages/lua/lua-5.1.4/src/lua.h new file mode 100644 index 00000000..e4bdfd3b --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lua.h @@ -0,0 +1,388 @@ +/* +** $Id: lua.h,v 1.218.1.5 2008/08/06 13:30:12 roberto Exp $ +** Lua - An Extensible Extension Language +** Lua.org, PUC-Rio, Brazil (http://www.lua.org) +** See Copyright Notice at the end of this file +*/ + + +#ifndef lua_h +#define lua_h + +#include +#include + + +#include "luaconf.h" + + +#define LUA_VERSION "Lua 5.1" +#define LUA_RELEASE "Lua 5.1.4" +#define LUA_VERSION_NUM 501 +#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio" +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" + + +/* mark for precompiled code (`Lua') */ +#define LUA_SIGNATURE "\033Lua" + +/* option for multiple returns in `lua_pcall' and `lua_call' */ +#define LUA_MULTRET (-1) + + +/* +** pseudo-indices +*/ +#define LUA_REGISTRYINDEX (-10000) +#define LUA_ENVIRONINDEX (-10001) +#define LUA_GLOBALSINDEX (-10002) +#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) + + +/* thread status; 0 is OK */ +#define LUA_YIELD 1 +#define LUA_ERRRUN 2 +#define LUA_ERRSYNTAX 3 +#define LUA_ERRMEM 4 +#define LUA_ERRERR 5 + + +typedef struct lua_State lua_State; + +typedef int (*lua_CFunction) (lua_State *L); + + +/* +** functions that read/write blocks when loading/dumping Lua chunks +*/ +typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); + +typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); + + +/* +** prototype for memory-allocation functions +*/ +typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); + + +/* +** basic types +*/ +#define LUA_TNONE (-1) + +#define LUA_TNIL 0 +#define LUA_TBOOLEAN 1 +#define LUA_TLIGHTUSERDATA 2 +#define LUA_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 +#define LUA_TFUNCTION 6 +#define LUA_TUSERDATA 7 +#define LUA_TTHREAD 8 + + + +/* minimum Lua stack available to a C function */ +#define LUA_MINSTACK 20 + + +/* +** generic extra include file +*/ +#if defined(LUA_USER_H) +#include LUA_USER_H +#endif + + +/* type of numbers in Lua */ +typedef LUA_NUMBER lua_Number; + + +/* type for integer functions */ +typedef LUA_INTEGER lua_Integer; + + + +/* +** state manipulation +*/ +LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); +LUA_API void (lua_close) (lua_State *L); +LUA_API lua_State *(lua_newthread) (lua_State *L); + +LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); + + +/* +** basic stack manipulation +*/ +LUA_API int (lua_gettop) (lua_State *L); +LUA_API void (lua_settop) (lua_State *L, int idx); +LUA_API void (lua_pushvalue) (lua_State *L, int idx); +LUA_API void (lua_remove) (lua_State *L, int idx); +LUA_API void (lua_insert) (lua_State *L, int idx); +LUA_API void (lua_replace) (lua_State *L, int idx); +LUA_API int (lua_checkstack) (lua_State *L, int sz); + +LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); + + +/* +** access functions (stack -> C) +*/ + +LUA_API int (lua_isnumber) (lua_State *L, int idx); +LUA_API int (lua_isstring) (lua_State *L, int idx); +LUA_API int (lua_iscfunction) (lua_State *L, int idx); +LUA_API int (lua_isuserdata) (lua_State *L, int idx); +LUA_API int (lua_type) (lua_State *L, int idx); +LUA_API const char *(lua_typename) (lua_State *L, int tp); + +LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2); + +LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx); +LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx); +LUA_API int (lua_toboolean) (lua_State *L, int idx); +LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); +LUA_API size_t (lua_objlen) (lua_State *L, int idx); +LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); +LUA_API void *(lua_touserdata) (lua_State *L, int idx); +LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); +LUA_API const void *(lua_topointer) (lua_State *L, int idx); + + +/* +** push functions (C -> stack) +*/ +LUA_API void (lua_pushnil) (lua_State *L); +LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); +LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); +LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l); +LUA_API void (lua_pushstring) (lua_State *L, const char *s); +LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, + va_list argp); +LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); +LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); +LUA_API void (lua_pushboolean) (lua_State *L, int b); +LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); +LUA_API int (lua_pushthread) (lua_State *L); + + +/* +** get functions (Lua -> stack) +*/ +LUA_API void (lua_gettable) (lua_State *L, int idx); +LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawget) (lua_State *L, int idx); +LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); +LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); +LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); +LUA_API int (lua_getmetatable) (lua_State *L, int objindex); +LUA_API void (lua_getfenv) (lua_State *L, int idx); + + +/* +** set functions (stack -> Lua) +*/ +LUA_API void (lua_settable) (lua_State *L, int idx); +LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawset) (lua_State *L, int idx); +LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); +LUA_API int (lua_setmetatable) (lua_State *L, int objindex); +LUA_API int (lua_setfenv) (lua_State *L, int idx); + + +/* +** `load' and `call' functions (load and run Lua code) +*/ +LUA_API void (lua_call) (lua_State *L, int nargs, int nresults); +LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc); +LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); +LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, + const char *chunkname); + +LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); + + +/* +** coroutine functions +*/ +LUA_API int (lua_yield) (lua_State *L, int nresults); +LUA_API int (lua_resume) (lua_State *L, int narg); +LUA_API int (lua_status) (lua_State *L); + +/* +** garbage-collection function and options +*/ + +#define LUA_GCSTOP 0 +#define LUA_GCRESTART 1 +#define LUA_GCCOLLECT 2 +#define LUA_GCCOUNT 3 +#define LUA_GCCOUNTB 4 +#define LUA_GCSTEP 5 +#define LUA_GCSETPAUSE 6 +#define LUA_GCSETSTEPMUL 7 + +LUA_API int (lua_gc) (lua_State *L, int what, int data); + + +/* +** miscellaneous functions +*/ + +LUA_API int (lua_error) (lua_State *L); + +LUA_API int (lua_next) (lua_State *L, int idx); + +LUA_API void (lua_concat) (lua_State *L, int n); + +LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define lua_pop(L,n) lua_settop(L, -(n)-1) + +#define lua_newtable(L) lua_createtable(L, 0, 0) + +#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) + +#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) + +#define lua_strlen(L,i) lua_objlen(L, (i)) + +#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) +#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) +#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) +#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) +#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) +#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) + +#define lua_pushliteral(L, s) \ + lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) + +#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) +#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) + +#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) + + + +/* +** compatibility macros and functions +*/ + +#define lua_open() luaL_newstate() + +#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) + +#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0) + +#define lua_Chunkreader lua_Reader +#define lua_Chunkwriter lua_Writer + + +/* hack */ +LUA_API void lua_setlevel (lua_State *from, lua_State *to); + + +/* +** {====================================================================== +** Debug API +** ======================================================================= +*/ + + +/* +** Event codes +*/ +#define LUA_HOOKCALL 0 +#define LUA_HOOKRET 1 +#define LUA_HOOKLINE 2 +#define LUA_HOOKCOUNT 3 +#define LUA_HOOKTAILRET 4 + + +/* +** Event masks +*/ +#define LUA_MASKCALL (1 << LUA_HOOKCALL) +#define LUA_MASKRET (1 << LUA_HOOKRET) +#define LUA_MASKLINE (1 << LUA_HOOKLINE) +#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) + +typedef struct lua_Debug lua_Debug; /* activation record */ + + +/* Functions to be called by the debuger in specific events */ +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n); +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n); + +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); +LUA_API lua_Hook lua_gethook (lua_State *L); +LUA_API int lua_gethookmask (lua_State *L); +LUA_API int lua_gethookcount (lua_State *L); + + +struct lua_Debug { + int event; + const char *name; /* (n) */ + const char *namewhat; /* (n) `global', `local', `field', `method' */ + const char *what; /* (S) `Lua', `C', `main', `tail' */ + const char *source; /* (S) */ + int currentline; /* (l) */ + int nups; /* (u) number of upvalues */ + int linedefined; /* (S) */ + int lastlinedefined; /* (S) */ + char short_src[LUA_IDSIZE]; /* (S) */ + /* private part */ + int i_ci; /* active function */ +}; + +/* }====================================================================== */ + + +/****************************************************************************** +* Copyright (C) 1994-2008 Lua.org, PUC-Rio. 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. +******************************************************************************/ + + +#endif diff --git a/vscript/languages/lua/lua-5.1.4/src/luac.c b/vscript/languages/lua/lua-5.1.4/src/luac.c new file mode 100644 index 00000000..d0701739 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/luac.c @@ -0,0 +1,200 @@ +/* +** $Id: luac.c,v 1.54 2006/06/02 17:37:11 lhf Exp $ +** Lua compiler (saves bytecodes to files; also list bytecodes) +** See Copyright Notice in lua.h +*/ + +#include +#include +#include +#include + +#define luac_c +#define LUA_CORE + +#include "lua.h" +#include "lauxlib.h" + +#include "ldo.h" +#include "lfunc.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstring.h" +#include "lundump.h" + +#define PROGNAME "luac" /* default program name */ +#define OUTPUT PROGNAME ".out" /* default output file */ + +static int listing=0; /* list bytecodes? */ +static int dumping=1; /* dump bytecodes? */ +static int stripping=0; /* strip debug information? */ +static char Output[]={ OUTPUT }; /* default output file name */ +static const char* output=Output; /* actual output file name */ +static const char* progname=PROGNAME; /* actual program name */ + +static void fatal(const char* message) +{ + fprintf(stderr,"%s: %s\n",progname,message); + exit(EXIT_FAILURE); +} + +static void cannot(const char* what) +{ + fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno)); + exit(EXIT_FAILURE); +} + +static void usage(const char* message) +{ + if (*message=='-') + fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message); + else + fprintf(stderr,"%s: %s\n",progname,message); + fprintf(stderr, + "usage: %s [options] [filenames].\n" + "Available options are:\n" + " - process stdin\n" + " -l list\n" + " -o name output to file " LUA_QL("name") " (default is \"%s\")\n" + " -p parse only\n" + " -s strip debug information\n" + " -v show version information\n" + " -- stop handling options\n", + progname,Output); + exit(EXIT_FAILURE); +} + +#define IS(s) (strcmp(argv[i],s)==0) + +static int doargs(int argc, char* argv[]) +{ + int i; + int version=0; + if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0]; + for (i=1; itop+(i))->l.p) + +static const Proto* combine(lua_State* L, int n) +{ + if (n==1) + return toproto(L,-1); + else + { + int i,pc; + Proto* f=luaF_newproto(L); + setptvalue2s(L,L->top,f); incr_top(L); + f->source=luaS_newliteral(L,"=(" PROGNAME ")"); + f->maxstacksize=1; + pc=2*n+1; + f->code=luaM_newvector(L,pc,Instruction); + f->sizecode=pc; + f->p=luaM_newvector(L,n,Proto*); + f->sizep=n; + pc=0; + for (i=0; ip[i]=toproto(L,i-n-1); + f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i); + f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1); + } + f->code[pc++]=CREATE_ABC(OP_RETURN,0,1,0); + return f; + } +} + +static int writer(lua_State* L, const void* p, size_t size, void* u) +{ + UNUSED(L); + return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0); +} + +struct Smain { + int argc; + char** argv; +}; + +static int pmain(lua_State* L) +{ + struct Smain* s = (struct Smain*)lua_touserdata(L, 1); + int argc=s->argc; + char** argv=s->argv; + const Proto* f; + int i; + if (!lua_checkstack(L,argc)) fatal("too many input files"); + for (i=0; i1); + if (dumping) + { + FILE* D= (output==NULL) ? stdout : fopen(output,"wb"); + if (D==NULL) cannot("open"); + lua_lock(L); + luaU_dump(L,f,writer,D,stripping); + lua_unlock(L); + if (ferror(D)) cannot("write"); + if (fclose(D)) cannot("close"); + } + return 0; +} + +int main(int argc, char* argv[]) +{ + lua_State* L; + struct Smain s; + int i=doargs(argc,argv); + argc-=i; argv+=i; + if (argc<=0) usage("no input files given"); + L=lua_open(); + if (L==NULL) fatal("not enough memory for state"); + s.argc=argc; + s.argv=argv; + if (lua_cpcall(L,pmain,&s)!=0) fatal(lua_tostring(L,-1)); + lua_close(L); + return EXIT_SUCCESS; +} diff --git a/vscript/languages/lua/lua-5.1.4/src/luaconf.h b/vscript/languages/lua/lua-5.1.4/src/luaconf.h new file mode 100644 index 00000000..6347dd36 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/luaconf.h @@ -0,0 +1,775 @@ +/* +** $Id: luaconf.h,v 1.82.1.7 2008/02/11 16:25:08 roberto Exp $ +** Configuration file for Lua +** See Copyright Notice in lua.h +*/ + + +#ifndef lconfig_h +#define lconfig_h + +#include +#include + + +/* +** ================================================================== +** Search for "@@" to find all configurable definitions. +** =================================================================== +*/ + + +/* +@@ LUA_ANSI controls the use of non-ansi features. +** CHANGE it (define it) if you want Lua to avoid the use of any +** non-ansi feature or library. +*/ +#if defined(__STRICT_ANSI__) +#define LUA_ANSI +#endif + + +#if !defined(LUA_ANSI) && defined(_WIN32) +#define LUA_WIN +#endif + +#if defined(LUA_USE_LINUX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ +#define LUA_USE_READLINE /* needs some extra libraries */ +#endif + +#if defined(LUA_USE_MACOSX) +#define LUA_USE_POSIX +#define LUA_DL_DYLD /* does not need extra library */ +#endif + + + +/* +@@ LUA_USE_POSIX includes all functionallity listed as X/Open System +@* Interfaces Extension (XSI). +** CHANGE it (define it) if your system is XSI compatible. +*/ +#if defined(LUA_USE_POSIX) +#define LUA_USE_MKSTEMP +#define LUA_USE_ISATTY +#define LUA_USE_POPEN +#define LUA_USE_ULONGJMP +#endif + + +/* +@@ LUA_PATH and LUA_CPATH are the names of the environment variables that +@* Lua check to set its paths. +@@ LUA_INIT is the name of the environment variable that Lua +@* checks for initialization code. +** CHANGE them if you want different names. +*/ +#define LUA_PATH "LUA_PATH" +#define LUA_CPATH "LUA_CPATH" +#define LUA_INIT "LUA_INIT" + + +/* +@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for +@* Lua libraries. +@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for +@* C libraries. +** CHANGE them if your machine has a non-conventional directory +** hierarchy or if you want to install your libraries in +** non-conventional directories. +*/ +#if defined(_WIN32) +/* +** In Windows, any exclamation mark ('!') in the path is replaced by the +** path of the directory of the executable file of the current process. +*/ +#define LUA_LDIR "!\\lua\\" +#define LUA_CDIR "!\\" +#define LUA_PATH_DEFAULT \ + ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua" +#define LUA_CPATH_DEFAULT \ + ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" + +#else +#define LUA_ROOT "/usr/local/" +#define LUA_LDIR LUA_ROOT "share/lua/5.1/" +#define LUA_CDIR LUA_ROOT "lib/lua/5.1/" +#define LUA_PATH_DEFAULT \ + "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua" +#define LUA_CPATH_DEFAULT \ + "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so" +#endif + + +/* +@@ LUA_DIRSEP is the directory separator (for submodules). +** CHANGE it if your machine does not use "/" as the directory separator +** and is not Windows. (On Windows Lua automatically uses "\".) +*/ +#if defined(_WIN32) +#define LUA_DIRSEP "\\" +#else +#define LUA_DIRSEP "/" +#endif + + +/* +@@ LUA_PATHSEP is the character that separates templates in a path. +@@ LUA_PATH_MARK is the string that marks the substitution points in a +@* template. +@@ LUA_EXECDIR in a Windows path is replaced by the executable's +@* directory. +@@ LUA_IGMARK is a mark to ignore all before it when bulding the +@* luaopen_ function name. +** CHANGE them if for some reason your system cannot use those +** characters. (E.g., if one of those characters is a common character +** in file/directory names.) Probably you do not need to change them. +*/ +#define LUA_PATHSEP ";" +#define LUA_PATH_MARK "?" +#define LUA_EXECDIR "!" +#define LUA_IGMARK "-" + + +/* +@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. +** CHANGE that if ptrdiff_t is not adequate on your machine. (On most +** machines, ptrdiff_t gives a good choice between int or long.) +*/ +#define LUA_INTEGER ptrdiff_t + + +/* +@@ LUA_API is a mark for all core API functions. +@@ LUALIB_API is a mark for all standard library functions. +** CHANGE them if you need to define those functions in some special way. +** For instance, if you want to create one Windows DLL with the core and +** the libraries, you may want to use the following definition (define +** LUA_BUILD_AS_DLL to get it). +*/ +#if defined(LUA_BUILD_AS_DLL) + +#if defined(LUA_CORE) || defined(LUA_LIB) +#define LUA_API __declspec(dllexport) +#else +#define LUA_API __declspec(dllimport) +#endif + +#else + +#define LUA_API extern + +#endif + +/* more often than not the libs go together with the core */ +#define LUALIB_API LUA_API + + +/* +@@ LUAI_FUNC is a mark for all extern functions that are not to be +@* exported to outside modules. +@@ LUAI_DATA is a mark for all extern (const) variables that are not to +@* be exported to outside modules. +** CHANGE them if you need to mark them in some special way. Elf/gcc +** (versions 3.2 and later) mark them as "hidden" to optimize access +** when Lua is compiled as a shared library. +*/ +#if defined(luaall_c) +#define LUAI_FUNC static +#define LUAI_DATA /* empty */ + +#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ + defined(__ELF__) +#define LUAI_FUNC __attribute__((visibility("hidden"))) extern +#define LUAI_DATA LUAI_FUNC + +#else +#define LUAI_FUNC extern +#define LUAI_DATA extern +#endif + + + +/* +@@ LUA_QL describes how error messages quote program elements. +** CHANGE it if you want a different appearance. +*/ +#define LUA_QL(x) "'" x "'" +#define LUA_QS LUA_QL("%s") + + +/* +@@ LUA_IDSIZE gives the maximum size for the description of the source +@* of a function in debug information. +** CHANGE it if you want a different size. +*/ +#define LUA_IDSIZE 60 + + +/* +** {================================================================== +** Stand-alone configuration +** =================================================================== +*/ + +#if defined(lua_c) || defined(luaall_c) + +/* +@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that +@* is, whether we're running lua interactively). +** CHANGE it if you have a better definition for non-POSIX/non-Windows +** systems. +*/ +#if defined(LUA_USE_ISATTY) +#include +#define lua_stdin_is_tty() isatty(0) +#elif defined(LUA_WIN) +#include +#include +#define lua_stdin_is_tty() _isatty(_fileno(stdin)) +#else +#define lua_stdin_is_tty() 1 /* assume stdin is a tty */ +#endif + + +/* +@@ LUA_PROMPT is the default prompt used by stand-alone Lua. +@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua. +** CHANGE them if you want different prompts. (You can also change the +** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.) +*/ +#define LUA_PROMPT "> " +#define LUA_PROMPT2 ">> " + + +/* +@@ LUA_PROGNAME is the default name for the stand-alone Lua program. +** CHANGE it if your stand-alone interpreter has a different name and +** your system is not able to detect that name automatically. +*/ +#define LUA_PROGNAME "lua" + + +/* +@@ LUA_MAXINPUT is the maximum length for an input line in the +@* stand-alone interpreter. +** CHANGE it if you need longer lines. +*/ +#define LUA_MAXINPUT 512 + + +/* +@@ lua_readline defines how to show a prompt and then read a line from +@* the standard input. +@@ lua_saveline defines how to "save" a read line in a "history". +@@ lua_freeline defines how to free a line read by lua_readline. +** CHANGE them if you want to improve this functionality (e.g., by using +** GNU readline and history facilities). +*/ +#if defined(LUA_USE_READLINE) +#include +#include +#include +#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) +#define lua_saveline(L,idx) \ + if (lua_strlen(L,idx) > 0) /* non-empty line? */ \ + add_history(lua_tostring(L, idx)); /* add it to history */ +#define lua_freeline(L,b) ((void)L, free(b)) +#else +#define lua_readline(L,b,p) \ + ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ + fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ +#define lua_saveline(L,idx) { (void)L; (void)idx; } +#define lua_freeline(L,b) { (void)L; (void)b; } +#endif + +#endif + +/* }================================================================== */ + + +/* +@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles +@* as a percentage. +** CHANGE it if you want the GC to run faster or slower (higher values +** mean larger pauses which mean slower collection.) You can also change +** this value dynamically. +*/ +#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */ + + +/* +@@ LUAI_GCMUL defines the default speed of garbage collection relative to +@* memory allocation as a percentage. +** CHANGE it if you want to change the granularity of the garbage +** collection. (Higher values mean coarser collections. 0 represents +** infinity, where each step performs a full collection.) You can also +** change this value dynamically. +*/ +#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ + + + +/* +@@ LUA_COMPAT_GETN controls compatibility with old getn behavior. +** CHANGE it (define it) if you want exact compatibility with the +** behavior of setn/getn in Lua 5.0. +*/ +#undef LUA_COMPAT_GETN + +/* +@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib. +** CHANGE it to undefined as soon as you do not need a global 'loadlib' +** function (the function is still available as 'package.loadlib'). +*/ +#undef LUA_COMPAT_LOADLIB + +/* +@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature. +** CHANGE it to undefined as soon as your programs use only '...' to +** access vararg parameters (instead of the old 'arg' table). +*/ +#define LUA_COMPAT_VARARG + +/* +@@ LUA_COMPAT_MOD controls compatibility with old math.mod function. +** CHANGE it to undefined as soon as your programs use 'math.fmod' or +** the new '%' operator instead of 'math.mod'. +*/ +#define LUA_COMPAT_MOD + +/* +@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting +@* facility. +** CHANGE it to 2 if you want the old behaviour, or undefine it to turn +** off the advisory error when nesting [[...]]. +*/ +#define LUA_COMPAT_LSTR 1 + +/* +@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name. +** CHANGE it to undefined as soon as you rename 'string.gfind' to +** 'string.gmatch'. +*/ +#define LUA_COMPAT_GFIND + +/* +@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib' +@* behavior. +** CHANGE it to undefined as soon as you replace to 'luaL_register' +** your uses of 'luaL_openlib' +*/ +#define LUA_COMPAT_OPENLIB + + + +/* +@@ luai_apicheck is the assert macro used by the Lua-C API. +** CHANGE luai_apicheck if you want Lua to perform some checks in the +** parameters it gets from API calls. This may slow down the interpreter +** a bit, but may be quite useful when debugging C code that interfaces +** with Lua. A useful redefinition is to use assert.h. +*/ +#if defined(LUA_USE_APICHECK) +#include +#define luai_apicheck(L,o) { (void)L; assert(o); } +#else +#define luai_apicheck(L,o) { (void)L; } +#endif + + +/* +@@ LUAI_BITSINT defines the number of bits in an int. +** CHANGE here if Lua cannot automatically detect the number of bits of +** your machine. Probably you do not need to change this. +*/ +/* avoid overflows in comparison */ +#if INT_MAX-20 < 32760 +#define LUAI_BITSINT 16 +#elif INT_MAX > 2147483640L +/* int has at least 32 bits */ +#define LUAI_BITSINT 32 +#else +#error "you must define LUA_BITSINT with number of bits in an integer" +#endif + + +/* +@@ LUAI_UINT32 is an unsigned integer with at least 32 bits. +@@ LUAI_INT32 is an signed integer with at least 32 bits. +@@ LUAI_UMEM is an unsigned integer big enough to count the total +@* memory used by Lua. +@@ LUAI_MEM is a signed integer big enough to count the total memory +@* used by Lua. +** CHANGE here if for some weird reason the default definitions are not +** good enough for your machine. (The definitions in the 'else' +** part always works, but may waste space on machines with 64-bit +** longs.) Probably you do not need to change this. +*/ +#if LUAI_BITSINT >= 32 +#define LUAI_UINT32 unsigned int +#define LUAI_INT32 int +#define LUAI_MAXINT32 INT_MAX +#define LUAI_UMEM size_t +#define LUAI_MEM ptrdiff_t +#else +/* 16-bit ints */ +#define LUAI_UINT32 unsigned long +#define LUAI_INT32 long +#define LUAI_MAXINT32 LONG_MAX +#define LUAI_UMEM unsigned long +#define LUAI_MEM long +#endif + + +/* +@@ LUAI_MAXCALLS limits the number of nested calls. +** CHANGE it if you need really deep recursive calls. This limit is +** arbitrary; its only purpose is to stop infinite recursion before +** exhausting memory. +*/ +#define LUAI_MAXCALLS 20000 + + +/* +@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function +@* can use. +** CHANGE it if you need lots of (Lua) stack space for your C +** functions. This limit is arbitrary; its only purpose is to stop C +** functions to consume unlimited stack space. (must be smaller than +** -LUA_REGISTRYINDEX) +*/ +#define LUAI_MAXCSTACK 8000 + + + +/* +** {================================================================== +** CHANGE (to smaller values) the following definitions if your system +** has a small C stack. (Or you may want to change them to larger +** values if your system has a large C stack and these limits are +** too rigid for you.) Some of these constants control the size of +** stack-allocated arrays used by the compiler or the interpreter, while +** others limit the maximum number of recursive calls that the compiler +** or the interpreter can perform. Values too large may cause a C stack +** overflow for some forms of deep constructs. +** =================================================================== +*/ + + +/* +@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and +@* syntactical nested non-terminals in a program. +*/ +#define LUAI_MAXCCALLS 200 + + +/* +@@ LUAI_MAXVARS is the maximum number of local variables per function +@* (must be smaller than 250). +*/ +#define LUAI_MAXVARS 200 + + +/* +@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function +@* (must be smaller than 250). +*/ +#define LUAI_MAXUPVALUES 60 + + +/* +@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +*/ +#define LUAL_BUFFERSIZE BUFSIZ + +/* }================================================================== */ + + + + +/* +** {================================================================== +@@ LUA_NUMBER is the type of numbers in Lua. +** CHANGE the following definitions only if you want to build Lua +** with a number type different from double. You may also need to +** change lua_number2int & lua_number2integer. +** =================================================================== +*/ + +#define LUA_NUMBER_DOUBLE +#define LUA_NUMBER double + +/* +@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' +@* over a number. +*/ +#define LUAI_UACNUMBER double + + +/* +@@ LUA_NUMBER_SCAN is the format for reading numbers. +@@ LUA_NUMBER_FMT is the format for writing numbers. +@@ lua_number2str converts a number to a string. +@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. +@@ lua_str2number converts a string to a number. +*/ +#define LUA_NUMBER_SCAN "%lf" +#define LUA_NUMBER_FMT "%.14g" +#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) +#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ +#define lua_str2number(s,p) strtod((s), (p)) + + +/* +@@ The luai_num* macros define the primitive operations over numbers. +*/ +#if defined(LUA_CORE) +#include +#define luai_numadd(a,b) ((a)+(b)) +#define luai_numsub(a,b) ((a)-(b)) +#define luai_nummul(a,b) ((a)*(b)) +#define luai_numdiv(a,b) ((a)/(b)) +#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) +#define luai_numpow(a,b) (pow(a,b)) +#define luai_numunm(a) (-(a)) +#define luai_numeq(a,b) ((a)==(b)) +#define luai_numlt(a,b) ((a)<(b)) +#define luai_numle(a,b) ((a)<=(b)) +#define luai_numisnan(a) (!luai_numeq((a), (a))) +#endif + + +/* +@@ lua_number2int is a macro to convert lua_Number to int. +@@ lua_number2integer is a macro to convert lua_Number to lua_Integer. +** CHANGE them if you know a faster way to convert a lua_Number to +** int (with any rounding method and without throwing errors) in your +** system. In Pentium machines, a naive typecast from double to int +** in C is extremely slow, so any alternative is worth trying. +*/ + +/* On a Pentium, resort to a trick */ +#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ + (defined(__i386) || defined (_M_IX86) || defined(__i386__)) + +/* On a Microsoft compiler, use assembler */ +#if defined(_MSC_VER) + +#define lua_number2int(i,d) __asm fld d __asm fistp i +#define lua_number2integer(i,n) lua_number2int(i, n) + +/* the next trick should work on any Pentium, but sometimes clashes + with a DirectX idiosyncrasy */ +#else + +union luai_Cast { double l_d; long l_l; }; +#define lua_number2int(i,d) \ + { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } +#define lua_number2integer(i,n) lua_number2int(i, n) + +#endif + + +/* this option always works, but may be slow */ +#else +#define lua_number2int(i,d) ((i)=(int)(d)) +#define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) + +#endif + +/* }================================================================== */ + + +/* +@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment. +** CHANGE it if your system requires alignments larger than double. (For +** instance, if your system supports long doubles and they must be +** aligned in 16-byte boundaries, then you should add long double in the +** union.) Probably you do not need to change this. +*/ +#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } + + +/* +@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling. +** CHANGE them if you prefer to use longjmp/setjmp even with C++ +** or if want/don't to use _longjmp/_setjmp instead of regular +** longjmp/setjmp. By default, Lua handles errors with exceptions when +** compiling as C++ code, with _longjmp/_setjmp when asked to use them, +** and with longjmp/setjmp otherwise. +*/ +#if defined(__cplusplus) +/* C++ exceptions */ +#define LUAI_THROW(L,c) throw(c) +#define LUAI_TRY(L,c,a) try { a } catch(...) \ + { if ((c)->status == 0) (c)->status = -1; } +#define luai_jmpbuf int /* dummy variable */ + +#elif defined(LUA_USE_ULONGJMP) +/* in Unix, try _longjmp/_setjmp (more efficient) */ +#define LUAI_THROW(L,c) _longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#else +/* default handling with long jumps */ +#define LUAI_THROW(L,c) longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#endif + + +/* +@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern +@* can do during pattern-matching. +** CHANGE it if you need more captures. This limit is arbitrary. +*/ +#define LUA_MAXCAPTURES 32 + + +/* +@@ lua_tmpnam is the function that the OS library uses to create a +@* temporary name. +@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam. +** CHANGE them if you have an alternative to tmpnam (which is considered +** insecure) or if you want the original tmpnam anyway. By default, Lua +** uses tmpnam except when POSIX is available, where it uses mkstemp. +*/ +#if defined(loslib_c) || defined(luaall_c) + +#if defined(LUA_USE_MKSTEMP) +#include +#define LUA_TMPNAMBUFSIZE 32 +#define lua_tmpnam(b,e) { \ + strcpy(b, "/tmp/lua_XXXXXX"); \ + e = mkstemp(b); \ + if (e != -1) close(e); \ + e = (e == -1); } + +#else +#define LUA_TMPNAMBUFSIZE L_tmpnam +#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } +#endif + +#endif + + +/* +@@ lua_popen spawns a new process connected to the current one through +@* the file streams. +** CHANGE it if you have a way to implement it in your system. +*/ +#if defined(LUA_USE_POPEN) + +#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) +#define lua_pclose(L,file) ((void)L, (pclose(file) != -1)) + +#elif defined(LUA_WIN) + +#define lua_popen(L,c,m) ((void)L, _popen(c,m)) +#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1)) + +#else + +#define lua_popen(L,c,m) ((void)((void)c, m), \ + luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) +#define lua_pclose(L,file) ((void)((void)L, file), 0) + +#endif + +/* +@@ LUA_DL_* define which dynamic-library system Lua should use. +** CHANGE here if Lua has problems choosing the appropriate +** dynamic-library system for your platform (either Windows' DLL, Mac's +** dyld, or Unix's dlopen). If your system is some kind of Unix, there +** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for +** it. To use dlopen you also need to adapt the src/Makefile (probably +** adding -ldl to the linker options), so Lua does not select it +** automatically. (When you change the makefile to add -ldl, you must +** also add -DLUA_USE_DLOPEN.) +** If you do not want any kind of dynamic library, undefine all these +** options. +** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD. +*/ +#if defined(LUA_USE_DLOPEN) +#define LUA_DL_DLOPEN +#endif + +#if defined(LUA_WIN) +#define LUA_DL_DLL +#endif + + +/* +@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State +@* (the data goes just *before* the lua_State pointer). +** CHANGE (define) this if you really need that. This value must be +** a multiple of the maximum alignment required for your machine. +*/ +#define LUAI_EXTRASPACE 0 + + +/* +@@ luai_userstate* allow user-specific actions on threads. +** CHANGE them if you defined LUAI_EXTRASPACE and need to do something +** extra when a thread is created/deleted/resumed/yielded. +*/ +#define luai_userstateopen(L) ((void)L) +#define luai_userstateclose(L) ((void)L) +#define luai_userstatethread(L,L1) ((void)L) +#define luai_userstatefree(L) ((void)L) +#define luai_userstateresume(L,n) ((void)L) +#define luai_userstateyield(L,n) ((void)L) + + +/* +@@ LUA_INTFRMLEN is the length modifier for integer conversions +@* in 'string.format'. +@@ LUA_INTFRM_T is the integer type correspoding to the previous length +@* modifier. +** CHANGE them if your system supports long long or does not support long. +*/ + +#if defined(LUA_USELONGLONG) + +#define LUA_INTFRMLEN "ll" +#define LUA_INTFRM_T long long + +#else + +#define LUA_INTFRMLEN "l" +#define LUA_INTFRM_T long + +#endif + +#ifdef LUA_MOD_CASE_INSENSITIVE + +/* +@@ luai_strcasecmp function to compare strings case-insensitively +*/ +// #define luai_strcasecmp(l,r) _V_stricmp(l,r) +#if defined(LUA_WIN) +#define luai_strcasecmp(l,r) _stricmp(l,r) +#else +#define luai_strcasecmp(l,r) strcasecmp(l,r) +#endif + +#endif + +/* =================================================================== */ + +/* +** Local configuration. You can use this space to add your redefinitions +** without modifying the main part of the file. +*/ + + + +#endif + diff --git a/vscript/languages/lua/lua-5.1.4/src/lualib.h b/vscript/languages/lua/lua-5.1.4/src/lualib.h new file mode 100644 index 00000000..469417f6 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lualib.h @@ -0,0 +1,53 @@ +/* +** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lua standard libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lualib_h +#define lualib_h + +#include "lua.h" + + +/* Key to file-handle type */ +#define LUA_FILEHANDLE "FILE*" + + +#define LUA_COLIBNAME "coroutine" +LUALIB_API int (luaopen_base) (lua_State *L); + +#define LUA_TABLIBNAME "table" +LUALIB_API int (luaopen_table) (lua_State *L); + +#define LUA_IOLIBNAME "io" +LUALIB_API int (luaopen_io) (lua_State *L); + +#define LUA_OSLIBNAME "os" +LUALIB_API int (luaopen_os) (lua_State *L); + +#define LUA_STRLIBNAME "string" +LUALIB_API int (luaopen_string) (lua_State *L); + +#define LUA_MATHLIBNAME "math" +LUALIB_API int (luaopen_math) (lua_State *L); + +#define LUA_DBLIBNAME "debug" +LUALIB_API int (luaopen_debug) (lua_State *L); + +#define LUA_LOADLIBNAME "package" +LUALIB_API int (luaopen_package) (lua_State *L); + + +/* open all previous libraries */ +LUALIB_API void (luaL_openlibs) (lua_State *L); + + + +#ifndef lua_assert +#define lua_assert(x) ((void)0) +#endif + + +#endif diff --git a/vscript/languages/lua/lua-5.1.4/src/lundump.c b/vscript/languages/lua/lua-5.1.4/src/lundump.c new file mode 100644 index 00000000..8010a457 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lundump.c @@ -0,0 +1,227 @@ +/* +** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $ +** load precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#include + +#define lundump_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstring.h" +#include "lundump.h" +#include "lzio.h" + +typedef struct { + lua_State* L; + ZIO* Z; + Mbuffer* b; + const char* name; +} LoadState; + +#ifdef LUAC_TRUST_BINARIES +#define IF(c,s) +#define error(S,s) +#else +#define IF(c,s) if (c) error(S,s) + +static void error(LoadState* S, const char* why) +{ + luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why); + luaD_throw(S->L,LUA_ERRSYNTAX); +} +#endif + +#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) +#define LoadByte(S) (lu_byte)LoadChar(S) +#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) +#define LoadVector(S,b,n,size) LoadMem(S,b,n,size) + +static void LoadBlock(LoadState* S, void* b, size_t size) +{ + size_t r=luaZ_read(S->Z,b,size); + IF (r!=0, "unexpected end"); +} + +static int LoadChar(LoadState* S) +{ + char x; + LoadVar(S,x); + return x; +} + +static int LoadInt(LoadState* S) +{ + int x; + LoadVar(S,x); + IF (x<0, "bad integer"); + return x; +} + +static lua_Number LoadNumber(LoadState* S) +{ + lua_Number x; + LoadVar(S,x); + return x; +} + +static TString* LoadString(LoadState* S) +{ + size_t size; + LoadVar(S,size); + if (size==0) + return NULL; + else + { + char* s=luaZ_openspace(S->L,S->b,size); + LoadBlock(S,s,size); + return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ + } +} + +static void LoadCode(LoadState* S, Proto* f) +{ + int n=LoadInt(S); + f->code=luaM_newvector(S->L,n,Instruction); + f->sizecode=n; + LoadVector(S,f->code,n,sizeof(Instruction)); +} + +static Proto* LoadFunction(LoadState* S, TString* p); + +static void LoadConstants(LoadState* S, Proto* f) +{ + int i,n; + n=LoadInt(S); + f->k=luaM_newvector(S->L,n,TValue); + f->sizek=n; + for (i=0; ik[i]); + for (i=0; ik[i]; + int t=LoadChar(S); + switch (t) + { + case LUA_TNIL: + setnilvalue(o); + break; + case LUA_TBOOLEAN: + setbvalue(o,LoadChar(S)!=0); + break; + case LUA_TNUMBER: + setnvalue(o,LoadNumber(S)); + break; + case LUA_TSTRING: + setsvalue2n(S->L,o,LoadString(S)); + break; + default: + error(S,"bad constant"); + break; + } + } + n=LoadInt(S); + f->p=luaM_newvector(S->L,n,Proto*); + f->sizep=n; + for (i=0; ip[i]=NULL; + for (i=0; ip[i]=LoadFunction(S,f->source); +} + +static void LoadDebug(LoadState* S, Proto* f) +{ + int i,n; + n=LoadInt(S); + f->lineinfo=luaM_newvector(S->L,n,int); + f->sizelineinfo=n; + LoadVector(S,f->lineinfo,n,sizeof(int)); + n=LoadInt(S); + f->locvars=luaM_newvector(S->L,n,LocVar); + f->sizelocvars=n; + for (i=0; ilocvars[i].varname=NULL; + for (i=0; ilocvars[i].varname=LoadString(S); + f->locvars[i].startpc=LoadInt(S); + f->locvars[i].endpc=LoadInt(S); + } + n=LoadInt(S); + f->upvalues=luaM_newvector(S->L,n,TString*); + f->sizeupvalues=n; + for (i=0; iupvalues[i]=NULL; + for (i=0; iupvalues[i]=LoadString(S); +} + +static Proto* LoadFunction(LoadState* S, TString* p) +{ + Proto* f; + if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep"); + f=luaF_newproto(S->L); + setptvalue2s(S->L,S->L->top,f); incr_top(S->L); + f->source=LoadString(S); if (f->source==NULL) f->source=p; + f->linedefined=LoadInt(S); + f->lastlinedefined=LoadInt(S); + f->nups=LoadByte(S); + f->numparams=LoadByte(S); + f->is_vararg=LoadByte(S); + f->maxstacksize=LoadByte(S); + LoadCode(S,f); + LoadConstants(S,f); + LoadDebug(S,f); + IF (!luaG_checkcode(f), "bad code"); + S->L->top--; + S->L->nCcalls--; + return f; +} + +static void LoadHeader(LoadState* S) +{ + char h[LUAC_HEADERSIZE]; + char s[LUAC_HEADERSIZE]; + luaU_header(h); + LoadBlock(S,s,LUAC_HEADERSIZE); + IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header"); +} + +/* +** load precompiled chunk +*/ +Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) +{ + LoadState S; + if (*name=='@' || *name=='=') + S.name=name+1; + else if (*name==LUA_SIGNATURE[0]) + S.name="binary string"; + else + S.name=name; + S.L=L; + S.Z=Z; + S.b=buff; + LoadHeader(&S); + return LoadFunction(&S,luaS_newliteral(L,"=?")); +} + +/* +* make header +*/ +void luaU_header (char* h) +{ + int x=1; + memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1); + h+=sizeof(LUA_SIGNATURE)-1; + *h++=(char)LUAC_VERSION; + *h++=(char)LUAC_FORMAT; + *h++=(char)*(char*)&x; /* endianness */ + *h++=(char)sizeof(int); + *h++=(char)sizeof(size_t); + *h++=(char)sizeof(Instruction); + *h++=(char)sizeof(lua_Number); + *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ +} diff --git a/vscript/languages/lua/lua-5.1.4/src/lundump.h b/vscript/languages/lua/lua-5.1.4/src/lundump.h new file mode 100644 index 00000000..c80189db --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lundump.h @@ -0,0 +1,36 @@ +/* +** $Id: lundump.h,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ +** load precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#ifndef lundump_h +#define lundump_h + +#include "lobject.h" +#include "lzio.h" + +/* load one chunk; from lundump.c */ +LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); + +/* make header; from lundump.c */ +LUAI_FUNC void luaU_header (char* h); + +/* dump one chunk; from ldump.c */ +LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); + +#ifdef luac_c +/* print one chunk; from print.c */ +LUAI_FUNC void luaU_print (const Proto* f, int full); +#endif + +/* for header of binary files -- this is Lua 5.1 */ +#define LUAC_VERSION 0x51 + +/* for header of binary files -- this is the official format */ +#define LUAC_FORMAT 0 + +/* size of header of binary files */ +#define LUAC_HEADERSIZE 12 + +#endif diff --git a/vscript/languages/lua/lua-5.1.4/src/lvm.c b/vscript/languages/lua/lua-5.1.4/src/lvm.c new file mode 100644 index 00000000..ee3256ab --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lvm.c @@ -0,0 +1,763 @@ +/* +** $Id: lvm.c,v 2.63.1.3 2007/12/28 15:32:23 roberto Exp $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define lvm_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + + +/* limit for table tag-method chains (to avoid loops) */ +#define MAXTAGLOOP 100 + + +const TValue *luaV_tonumber (const TValue *obj, TValue *n) { + lua_Number num; + if (ttisnumber(obj)) return obj; + if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) { + setnvalue(n, num); + return n; + } + else + return NULL; +} + + +int luaV_tostring (lua_State *L, StkId obj) { + if (!ttisnumber(obj)) + return 0; + else { + char s[LUAI_MAXNUMBER2STR]; + lua_Number n = nvalue(obj); + lua_number2str(s, n); + setsvalue2s(L, obj, luaS_new(L, s)); + return 1; + } +} + + +static void traceexec (lua_State *L, const Instruction *pc) { + lu_byte mask = L->hookmask; + const Instruction *oldpc = L->savedpc; + L->savedpc = pc; + if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { + resethookcount(L); + luaD_callhook(L, LUA_HOOKCOUNT, -1); + } + if (mask & LUA_MASKLINE) { + Proto *p = ci_func(L->ci)->l.p; + int npc = pcRel(pc, p); + int newline = getline(p, npc); + /* call linehook when enter a new function, when jump back (loop), + or when enter a new line */ + if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p))) + luaD_callhook(L, LUA_HOOKLINE, newline); + } +} + + +static void callTMres (lua_State *L, StkId res, const TValue *f, + const TValue *p1, const TValue *p2) { + ptrdiff_t result = savestack(L, res); + setobj2s(L, L->top, f); /* push function */ + setobj2s(L, L->top+1, p1); /* 1st argument */ + setobj2s(L, L->top+2, p2); /* 2nd argument */ + luaD_checkstack(L, 3); + L->top += 3; + luaD_call(L, L->top - 3, 1); + res = restorestack(L, result); + L->top--; + setobjs2s(L, res, L->top); +} + + + +static void callTM (lua_State *L, const TValue *f, const TValue *p1, + const TValue *p2, const TValue *p3) { + setobj2s(L, L->top, f); /* push function */ + setobj2s(L, L->top+1, p1); /* 1st argument */ + setobj2s(L, L->top+2, p2); /* 2nd argument */ + setobj2s(L, L->top+3, p3); /* 3th argument */ + luaD_checkstack(L, 4); + L->top += 4; + luaD_call(L, L->top - 4, 0); +} + + +void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { + int loop; + for (loop = 0; loop < MAXTAGLOOP; loop++) { + const TValue *tm; + if (ttistable(t)) { /* `t' is a table? */ + Table *h = hvalue(t); + const TValue *res = luaH_get(h, key); /* do a primitive get */ + if (!ttisnil(res) || /* result is no nil? */ + (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ + setobj2s(L, val, res); + return; + } + /* else will try the tag method */ + } + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) + luaG_typeerror(L, t, "index"); + if (ttisfunction(tm)) { + callTMres(L, val, tm, t, key); + return; + } + t = tm; /* else repeat with `tm' */ + } + luaG_runerror(L, "loop in gettable"); +} + + +void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { + int loop; + for (loop = 0; loop < MAXTAGLOOP; loop++) { + const TValue *tm; + if (ttistable(t)) { /* `t' is a table? */ + Table *h = hvalue(t); + TValue *oldval = luaH_set(L, h, key); /* do a primitive set */ + if (!ttisnil(oldval) || /* result is no nil? */ + (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ + setobj2t(L, oldval, val); + luaC_barriert(L, h, val); + return; + } + /* else will try the tag method */ + } + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) + luaG_typeerror(L, t, "index"); + if (ttisfunction(tm)) { + callTM(L, tm, t, key, val); + return; + } + t = tm; /* else repeat with `tm' */ + } + luaG_runerror(L, "loop in settable"); +} + + +static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, + StkId res, TMS event) { + const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ + if (ttisnil(tm)) + tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ + if (ttisnil(tm)) return 0; + callTMres(L, res, tm, p1, p2); + return 1; +} + + +static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2, + TMS event) { + const TValue *tm1 = fasttm(L, mt1, event); + const TValue *tm2; + if (tm1 == NULL) return NULL; /* no metamethod */ + if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ + tm2 = fasttm(L, mt2, event); + if (tm2 == NULL) return NULL; /* no metamethod */ + if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */ + return tm1; + return NULL; +} + + +static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, + TMS event) { + const TValue *tm1 = luaT_gettmbyobj(L, p1, event); + const TValue *tm2; + if (ttisnil(tm1)) return -1; /* no metamethod? */ + tm2 = luaT_gettmbyobj(L, p2, event); + if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ + return -1; + callTMres(L, L->top, tm1, p1, p2); + return !l_isfalse(L->top); +} + + +static int l_strcmp (const TString *ls, const TString *rs) { + const char *l = getstr(ls); + size_t ll = ls->tsv.len; + const char *r = getstr(rs); + size_t lr = rs->tsv.len; + for (;;) { + int temp = strcoll(l, r); + if (temp != 0) return temp; + else { /* strings are equal up to a `\0' */ + size_t len = strlen(l); /* index of first `\0' in both strings */ + if (len == lr) /* r is finished? */ + return (len == ll) ? 0 : 1; + else if (len == ll) /* l is finished? */ + return -1; /* l is smaller than r (because r is not finished) */ + /* both strings longer than `len'; go on comparing (after the `\0') */ + len++; + l += len; ll -= len; r += len; lr -= len; + } + } +} + + +int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { + int res; + if (ttype(l) != ttype(r)) + return luaG_ordererror(L, l, r); + else if (ttisnumber(l)) + return luai_numlt(nvalue(l), nvalue(r)); + else if (ttisstring(l)) + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; + else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) + return res; + return luaG_ordererror(L, l, r); +} + + +static int lessequal (lua_State *L, const TValue *l, const TValue *r) { + int res; + if (ttype(l) != ttype(r)) + return luaG_ordererror(L, l, r); + else if (ttisnumber(l)) + return luai_numle(nvalue(l), nvalue(r)); + else if (ttisstring(l)) + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; + else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ + return res; + else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */ + return !res; + return luaG_ordererror(L, l, r); +} + + +int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { + const TValue *tm; + lua_assert(ttype(t1) == ttype(t2)); + switch (ttype(t1)) { + case LUA_TNIL: return 1; + case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); + case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ + case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); + case LUA_TUSERDATA: { + if (uvalue(t1) == uvalue(t2)) return 1; + tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, + TM_EQ); + break; /* will try TM */ + } + case LUA_TTABLE: { + if (hvalue(t1) == hvalue(t2)) return 1; + tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); + break; /* will try TM */ + } + default: return gcvalue(t1) == gcvalue(t2); + } + if (tm == NULL) return 0; /* no TM? */ + callTMres(L, L->top, tm, t1, t2); /* call TM */ + return !l_isfalse(L->top); +} + + +void luaV_concat (lua_State *L, int total, int last) { + do { + StkId top = L->base + last + 1; + int n = 2; /* number of elements handled in this pass (at least 2) */ + if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { + if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) + luaG_concaterror(L, top-2, top-1); + } else if (tsvalue(top-1)->len == 0) /* second op is empty? */ + (void)tostring(L, top - 2); /* result is first op (as string) */ + else { + /* at least two string values; get as many as possible */ + size_t tl = tsvalue(top-1)->len; + char *buffer; + int i; + /* collect total length */ + for (n = 1; n < total && tostring(L, top-n-1); n++) { + size_t l = tsvalue(top-n-1)->len; + if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); + tl += l; + } + buffer = luaZ_openspace(L, &G(L)->buff, tl); + tl = 0; + for (i=n; i>0; i--) { /* concat all strings */ + size_t l = tsvalue(top-i)->len; + memcpy(buffer+tl, svalue(top-i), l); + tl += l; + } + setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); + } + total -= n-1; /* got `n' strings to create 1 new */ + last -= n-1; + } while (total > 1); /* repeat until only 1 result left */ +} + + +static void Arith (lua_State *L, StkId ra, const TValue *rb, + const TValue *rc, TMS op) { + TValue tempb, tempc; + const TValue *b, *c; + if ((b = luaV_tonumber(rb, &tempb)) != NULL && + (c = luaV_tonumber(rc, &tempc)) != NULL) { + lua_Number nb = nvalue(b), nc = nvalue(c); + switch (op) { + case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break; + case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break; + case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break; + case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break; + case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break; + case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break; + case TM_UNM: setnvalue(ra, luai_numunm(nb)); break; + default: lua_assert(0); break; + } + } + else if (!call_binTM(L, rb, rc, ra, op)) + luaG_aritherror(L, rb, rc); +} + + + +/* +** some macros for common tasks in `luaV_execute' +*/ + +#define runtime_check(L, c) { if (!(c)) break; } + +#define RA(i) (base+GETARG_A(i)) +/* to be used after possible stack reallocation */ +#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) +#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) +#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ + ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) +#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ + ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) +#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) + + +#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);} + + +#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; } + + +#define arith_op(op,tm) { \ + TValue *rb = RKB(i); \ + TValue *rc = RKC(i); \ + if (ttisnumber(rb) && ttisnumber(rc)) { \ + lua_Number nb = nvalue(rb), nc = nvalue(rc); \ + setnvalue(ra, op(nb, nc)); \ + } \ + else \ + Protect(Arith(L, ra, rb, rc, tm)); \ + } + + + +void luaV_execute (lua_State *L, int nexeccalls) { + LClosure *cl; + StkId base; + TValue *k; + const Instruction *pc; + reentry: /* entry point */ + lua_assert(isLua(L->ci)); + pc = L->savedpc; + cl = &clvalue(L->ci->func)->l; + base = L->base; + k = cl->p->k; + /* main loop of interpreter */ + for (;;) { + const Instruction i = *pc++; + StkId ra; + if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && + (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { + traceexec(L, pc); + if (L->status == LUA_YIELD) { /* did hook yield? */ + L->savedpc = pc - 1; + return; + } + base = L->base; + } + /* warning!! several calls may realloc the stack and invalidate `ra' */ + ra = RA(i); + lua_assert(base == L->base && L->base == L->ci->base); + lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); + lua_assert(L->top == L->ci->top || luaG_checkopenop(i)); + switch (GET_OPCODE(i)) { + case OP_MOVE: { + setobjs2s(L, ra, RB(i)); + continue; + } + case OP_LOADK: { + setobj2s(L, ra, KBx(i)); + continue; + } + case OP_LOADBOOL: { + setbvalue(ra, GETARG_B(i)); + if (GETARG_C(i)) pc++; /* skip next instruction (if C) */ + continue; + } + case OP_LOADNIL: { + TValue *rb = RB(i); + do { + setnilvalue(rb--); + } while (rb >= ra); + continue; + } + case OP_GETUPVAL: { + int b = GETARG_B(i); + setobj2s(L, ra, cl->upvals[b]->v); + continue; + } + case OP_GETGLOBAL: { + TValue g; + TValue *rb = KBx(i); + sethvalue(L, &g, cl->env); + lua_assert(ttisstring(rb)); + Protect(luaV_gettable(L, &g, rb, ra)); + continue; + } + case OP_GETTABLE: { + Protect(luaV_gettable(L, RB(i), RKC(i), ra)); + continue; + } + case OP_SETGLOBAL: { + TValue g; + sethvalue(L, &g, cl->env); + lua_assert(ttisstring(KBx(i))); + Protect(luaV_settable(L, &g, KBx(i), ra)); + continue; + } + case OP_SETUPVAL: { + UpVal *uv = cl->upvals[GETARG_B(i)]; + setobj(L, uv->v, ra); + luaC_barrier(L, uv, ra); + continue; + } + case OP_SETTABLE: { + Protect(luaV_settable(L, ra, RKB(i), RKC(i))); + continue; + } + case OP_NEWTABLE: { + int b = GETARG_B(i); + int c = GETARG_C(i); + sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c))); + Protect(luaC_checkGC(L)); + continue; + } + case OP_SELF: { + StkId rb = RB(i); + setobjs2s(L, ra+1, rb); + Protect(luaV_gettable(L, rb, RKC(i), ra)); + continue; + } + case OP_ADD: { + arith_op(luai_numadd, TM_ADD); + continue; + } + case OP_SUB: { + arith_op(luai_numsub, TM_SUB); + continue; + } + case OP_MUL: { + arith_op(luai_nummul, TM_MUL); + continue; + } + case OP_DIV: { + arith_op(luai_numdiv, TM_DIV); + continue; + } + case OP_MOD: { + arith_op(luai_nummod, TM_MOD); + continue; + } + case OP_POW: { + arith_op(luai_numpow, TM_POW); + continue; + } + case OP_UNM: { + TValue *rb = RB(i); + if (ttisnumber(rb)) { + lua_Number nb = nvalue(rb); + setnvalue(ra, luai_numunm(nb)); + } + else { + Protect(Arith(L, ra, rb, rb, TM_UNM)); + } + continue; + } + case OP_NOT: { + int res = l_isfalse(RB(i)); /* next assignment may change this value */ + setbvalue(ra, res); + continue; + } + case OP_LEN: { + const TValue *rb = RB(i); + switch (ttype(rb)) { + case LUA_TTABLE: { + setnvalue(ra, cast_num(luaH_getn(hvalue(rb)))); + break; + } + case LUA_TSTRING: { + setnvalue(ra, cast_num(tsvalue(rb)->len)); + break; + } + default: { /* try metamethod */ + Protect( + if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN)) + luaG_typeerror(L, rb, "get length of"); + ) + } + } + continue; + } + case OP_CONCAT: { + int b = GETARG_B(i); + int c = GETARG_C(i); + Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L)); + setobjs2s(L, RA(i), base+b); + continue; + } + case OP_JMP: { + dojump(L, pc, GETARG_sBx(i)); + continue; + } + case OP_EQ: { + TValue *rb = RKB(i); + TValue *rc = RKC(i); + Protect( + if (equalobj(L, rb, rc) == GETARG_A(i)) + dojump(L, pc, GETARG_sBx(*pc)); + ) + pc++; + continue; + } + case OP_LT: { + Protect( + if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) + dojump(L, pc, GETARG_sBx(*pc)); + ) + pc++; + continue; + } + case OP_LE: { + Protect( + if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) + dojump(L, pc, GETARG_sBx(*pc)); + ) + pc++; + continue; + } + case OP_TEST: { + if (l_isfalse(ra) != GETARG_C(i)) + dojump(L, pc, GETARG_sBx(*pc)); + pc++; + continue; + } + case OP_TESTSET: { + TValue *rb = RB(i); + if (l_isfalse(rb) != GETARG_C(i)) { + setobjs2s(L, ra, rb); + dojump(L, pc, GETARG_sBx(*pc)); + } + pc++; + continue; + } + case OP_CALL: { + int b = GETARG_B(i); + int nresults = GETARG_C(i) - 1; + if (b != 0) L->top = ra+b; /* else previous instruction set top */ + L->savedpc = pc; + switch (luaD_precall(L, ra, nresults)) { + case PCRLUA: { + nexeccalls++; + goto reentry; /* restart luaV_execute over new Lua function */ + } + case PCRC: { + /* it was a C function (`precall' called it); adjust results */ + if (nresults >= 0) L->top = L->ci->top; + base = L->base; + continue; + } + default: { + return; /* yield */ + } + } + } + case OP_TAILCALL: { + int b = GETARG_B(i); + if (b != 0) L->top = ra+b; /* else previous instruction set top */ + L->savedpc = pc; + lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); + switch (luaD_precall(L, ra, LUA_MULTRET)) { + case PCRLUA: { + /* tail call: put new frame in place of previous one */ + CallInfo *ci = L->ci - 1; /* previous frame */ + int aux; + StkId func = ci->func; + StkId pfunc = (ci+1)->func; /* previous function index */ + if (L->openupval) luaF_close(L, ci->base); + L->base = ci->base = ci->func + ((ci+1)->base - pfunc); + for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ + setobjs2s(L, func+aux, pfunc+aux); + ci->top = L->top = func+aux; /* correct top */ + lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); + ci->savedpc = L->savedpc; + ci->tailcalls++; /* one more call lost */ + L->ci--; /* remove new frame */ + goto reentry; + } + case PCRC: { /* it was a C function (`precall' called it) */ + base = L->base; + continue; + } + default: { + return; /* yield */ + } + } + } + case OP_RETURN: { + int b = GETARG_B(i); + if (b != 0) L->top = ra+b-1; + if (L->openupval) luaF_close(L, base); + L->savedpc = pc; + b = luaD_poscall(L, ra); + if (--nexeccalls == 0) /* was previous function running `here'? */ + return; /* no: return */ + else { /* yes: continue its execution */ + if (b) L->top = L->ci->top; + lua_assert(isLua(L->ci)); + lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL); + goto reentry; + } + } + case OP_FORLOOP: { + lua_Number step = nvalue(ra+2); + lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */ + lua_Number limit = nvalue(ra+1); + if (luai_numlt(0, step) ? luai_numle(idx, limit) + : luai_numle(limit, idx)) { + dojump(L, pc, GETARG_sBx(i)); /* jump back */ + setnvalue(ra, idx); /* update internal index... */ + setnvalue(ra+3, idx); /* ...and external index */ + } + continue; + } + case OP_FORPREP: { + const TValue *init = ra; + const TValue *plimit = ra+1; + const TValue *pstep = ra+2; + L->savedpc = pc; /* next steps may throw errors */ + if (!tonumber(init, ra)) + luaG_runerror(L, LUA_QL("for") " initial value must be a number"); + else if (!tonumber(plimit, ra+1)) + luaG_runerror(L, LUA_QL("for") " limit must be a number"); + else if (!tonumber(pstep, ra+2)) + luaG_runerror(L, LUA_QL("for") " step must be a number"); + setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep))); + dojump(L, pc, GETARG_sBx(i)); + continue; + } + case OP_TFORLOOP: { + StkId cb = ra + 3; /* call base */ + setobjs2s(L, cb+2, ra+2); + setobjs2s(L, cb+1, ra+1); + setobjs2s(L, cb, ra); + L->top = cb+3; /* func. + 2 args (state and index) */ + Protect(luaD_call(L, cb, GETARG_C(i))); + L->top = L->ci->top; + cb = RA(i) + 3; /* previous call may change the stack */ + if (!ttisnil(cb)) { /* continue loop? */ + setobjs2s(L, cb-1, cb); /* save control variable */ + dojump(L, pc, GETARG_sBx(*pc)); /* jump back */ + } + pc++; + continue; + } + case OP_SETLIST: { + int n = GETARG_B(i); + int c = GETARG_C(i); + int last; + Table *h; + if (n == 0) { + n = cast_int(L->top - ra) - 1; + L->top = L->ci->top; + } + if (c == 0) c = cast_int(*pc++); + runtime_check(L, ttistable(ra)); + h = hvalue(ra); + last = ((c-1)*LFIELDS_PER_FLUSH) + n; + if (last > h->sizearray) /* needs more space? */ + luaH_resizearray(L, h, last); /* pre-alloc it at once */ + for (; n > 0; n--) { + TValue *val = ra+n; + setobj2t(L, luaH_setnum(L, h, last--), val); + luaC_barriert(L, h, val); + } + continue; + } + case OP_CLOSE: { + luaF_close(L, ra); + continue; + } + case OP_CLOSURE: { + Proto *p; + Closure *ncl; + int nup, j; + p = cl->p->p[GETARG_Bx(i)]; + nup = p->nups; + ncl = luaF_newLclosure(L, nup, cl->env); + ncl->l.p = p; + for (j=0; jl.upvals[j] = cl->upvals[GETARG_B(*pc)]; + else { + lua_assert(GET_OPCODE(*pc) == OP_MOVE); + ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc)); + } + } + setclvalue(L, ra, ncl); + Protect(luaC_checkGC(L)); + continue; + } + case OP_VARARG: { + int b = GETARG_B(i) - 1; + int j; + CallInfo *ci = L->ci; + int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1; + if (b == LUA_MULTRET) { + Protect(luaD_checkstack(L, n)); + ra = RA(i); /* previous call may change the stack */ + b = n; + L->top = ra + n; + } + for (j = 0; j < b; j++) { + if (j < n) { + setobjs2s(L, ra + j, ci->base - n + j); + } + else { + setnilvalue(ra + j); + } + } + continue; + } + } + } +} + diff --git a/vscript/languages/lua/lua-5.1.4/src/lvm.h b/vscript/languages/lua/lua-5.1.4/src/lvm.h new file mode 100644 index 00000000..bfe4f567 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lvm.h @@ -0,0 +1,36 @@ +/* +** $Id: lvm.h,v 2.5.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lvm_h +#define lvm_h + + +#include "ldo.h" +#include "lobject.h" +#include "ltm.h" + + +#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o))) + +#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \ + (((o) = luaV_tonumber(o,n)) != NULL)) + +#define equalobj(L,o1,o2) \ + (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) + + +LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); +LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2); +LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); +LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); +LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, + StkId val); +LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, + StkId val); +LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls); +LUAI_FUNC void luaV_concat (lua_State *L, int total, int last); + +#endif diff --git a/vscript/languages/lua/lua-5.1.4/src/lzio.c b/vscript/languages/lua/lua-5.1.4/src/lzio.c new file mode 100644 index 00000000..293edd59 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lzio.c @@ -0,0 +1,82 @@ +/* +** $Id: lzio.c,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ +** a generic input stream interface +** See Copyright Notice in lua.h +*/ + + +#include + +#define lzio_c +#define LUA_CORE + +#include "lua.h" + +#include "llimits.h" +#include "lmem.h" +#include "lstate.h" +#include "lzio.h" + + +int luaZ_fill (ZIO *z) { + size_t size; + lua_State *L = z->L; + const char *buff; + lua_unlock(L); + buff = z->reader(L, z->data, &size); + lua_lock(L); + if (buff == NULL || size == 0) return EOZ; + z->n = size - 1; + z->p = buff; + return char2int(*(z->p++)); +} + + +int luaZ_lookahead (ZIO *z) { + if (z->n == 0) { + if (luaZ_fill(z) == EOZ) + return EOZ; + else { + z->n++; /* luaZ_fill removed first byte; put back it */ + z->p--; + } + } + return char2int(*z->p); +} + + +void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { + z->L = L; + z->reader = reader; + z->data = data; + z->n = 0; + z->p = NULL; +} + + +/* --------------------------------------------------------------- read --- */ +size_t luaZ_read (ZIO *z, void *b, size_t n) { + while (n) { + size_t m; + if (luaZ_lookahead(z) == EOZ) + return n; /* return number of missing bytes */ + m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ + memcpy(b, z->p, m); + z->n -= m; + z->p += m; + b = (char *)b + m; + n -= m; + } + return 0; +} + +/* ------------------------------------------------------------------------ */ +char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { + if (n > buff->buffsize) { + if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; + luaZ_resizebuffer(L, buff, n); + } + return buff->buffer; +} + + diff --git a/vscript/languages/lua/lua-5.1.4/src/lzio.h b/vscript/languages/lua/lua-5.1.4/src/lzio.h new file mode 100644 index 00000000..51d695d8 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/lzio.h @@ -0,0 +1,67 @@ +/* +** $Id: lzio.h,v 1.21.1.1 2007/12/27 13:02:25 roberto Exp $ +** Buffered streams +** See Copyright Notice in lua.h +*/ + + +#ifndef lzio_h +#define lzio_h + +#include "lua.h" + +#include "lmem.h" + + +#define EOZ (-1) /* end of stream */ + +typedef struct Zio ZIO; + +#define char2int(c) cast(int, cast(unsigned char, (c))) + +#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z)) + +typedef struct Mbuffer { + char *buffer; + size_t n; + size_t buffsize; +} Mbuffer; + +#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) + +#define luaZ_buffer(buff) ((buff)->buffer) +#define luaZ_sizebuffer(buff) ((buff)->buffsize) +#define luaZ_bufflen(buff) ((buff)->n) + +#define luaZ_resetbuffer(buff) ((buff)->n = 0) + + +#define luaZ_resizebuffer(L, buff, size) \ + (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ + (buff)->buffsize = size) + +#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) + + +LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); +LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, + void *data); +LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ +LUAI_FUNC int luaZ_lookahead (ZIO *z); + + + +/* --------- Private Part ------------------ */ + +struct Zio { + size_t n; /* bytes still unread */ + const char *p; /* current position in buffer */ + lua_Reader reader; + void* data; /* additional data */ + lua_State *L; /* Lua state (for reader) */ +}; + + +LUAI_FUNC int luaZ_fill (ZIO *z); + +#endif diff --git a/vscript/languages/lua/lua-5.1.4/src/print.c b/vscript/languages/lua/lua-5.1.4/src/print.c new file mode 100644 index 00000000..e240cfc3 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/src/print.c @@ -0,0 +1,227 @@ +/* +** $Id: print.c,v 1.55a 2006/05/31 13:30:05 lhf Exp $ +** print bytecodes +** See Copyright Notice in lua.h +*/ + +#include +#include + +#define luac_c +#define LUA_CORE + +#include "ldebug.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lundump.h" + +#define PrintFunction luaU_print + +#define Sizeof(x) ((int)sizeof(x)) +#define VOID(p) ((const void*)(p)) + +static void PrintString(const TString* ts) +{ + const char* s=getstr(ts); + size_t i,n=ts->tsv.len; + putchar('"'); + for (i=0; ik[i]; + switch (ttype(o)) + { + case LUA_TNIL: + printf("nil"); + break; + case LUA_TBOOLEAN: + printf(bvalue(o) ? "true" : "false"); + break; + case LUA_TNUMBER: + printf(LUA_NUMBER_FMT,nvalue(o)); + break; + case LUA_TSTRING: + PrintString(rawtsvalue(o)); + break; + default: /* cannot happen */ + printf("? type=%d",ttype(o)); + break; + } +} + +static void PrintCode(const Proto* f) +{ + const Instruction* code=f->code; + int pc,n=f->sizecode; + for (pc=0; pc0) printf("[%d]\t",line); else printf("[-]\t"); + printf("%-9s\t",luaP_opnames[o]); + switch (getOpMode(o)) + { + case iABC: + printf("%d",a); + if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b); + if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c); + break; + case iABx: + if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx); + break; + case iAsBx: + if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx); + break; + } + switch (o) + { + case OP_LOADK: + printf("\t; "); PrintConstant(f,bx); + break; + case OP_GETUPVAL: + case OP_SETUPVAL: + printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-"); + break; + case OP_GETGLOBAL: + case OP_SETGLOBAL: + printf("\t; %s",svalue(&f->k[bx])); + break; + case OP_GETTABLE: + case OP_SELF: + if (ISK(c)) { printf("\t; "); PrintConstant(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)) + { + printf("\t; "); + if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-"); + printf(" "); + if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-"); + } + break; + case OP_JMP: + case OP_FORLOOP: + case OP_FORPREP: + printf("\t; to %d",sbx+pc+2); + break; + case OP_CLOSURE: + printf("\t; %p",VOID(f->p[bx])); + break; + case OP_SETLIST: + if (c==0) printf("\t; %d",(int)code[++pc]); + else printf("\t; %d",c); + break; + default: + break; + } + printf("\n"); + } +} + +#define SS(x) (x==1)?"":"s" +#define S(x) x,SS(x) + +static void PrintHeader(const Proto* f) +{ + const char* s=getstr(f->source); + if (*s=='@' || *s=='=') + s++; + else if (*s==LUA_SIGNATURE[0]) + s="(bstring)"; + else + s="(string)"; + printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n", + (f->linedefined==0)?"main":"function",s, + f->linedefined,f->lastlinedefined, + S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f)); + printf("%d%s param%s, %d slot%s, %d upvalue%s, ", + f->numparams,f->is_vararg?"+":"",SS(f->numparams), + S(f->maxstacksize),S(f->nups)); + printf("%d local%s, %d constant%s, %d function%s\n", + S(f->sizelocvars),S(f->sizek),S(f->sizep)); +} + +static void PrintConstants(const Proto* f) +{ + int i,n=f->sizek; + printf("constants (%d) for %p:\n",n,VOID(f)); + for (i=0; isizelocvars; + printf("locals (%d) for %p:\n",n,VOID(f)); + for (i=0; ilocvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1); + } +} + +static void PrintUpvalues(const Proto* f) +{ + int i,n=f->sizeupvalues; + printf("upvalues (%d) for %p:\n",n,VOID(f)); + if (f->upvalues==NULL) return; + for (i=0; iupvalues[i])); + } +} + +void PrintFunction(const Proto* f, int full) +{ + int i,n=f->sizep; + PrintHeader(f); + PrintCode(f); + if (full) + { + PrintConstants(f); + PrintLocals(f); + PrintUpvalues(f); + } + for (i=0; ip[i],full); +} diff --git a/vscript/languages/lua/lua-5.1.4/test/README b/vscript/languages/lua/lua-5.1.4/test/README new file mode 100644 index 00000000..0c7f38bc --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/test/README @@ -0,0 +1,26 @@ +These are simple tests for Lua. Some of them contain useful code. +They are meant to be run to make sure Lua is built correctly and also +to be read, to see how Lua programs look. + +Here is a one-line summary of each program: + + bisect.lua bisection method for solving non-linear equations + cf.lua temperature conversion table (celsius to farenheit) + echo.lua echo command line arguments + env.lua environment variables as automatic global variables + factorial.lua factorial without recursion + fib.lua fibonacci function with cache + fibfor.lua fibonacci numbers with coroutines and generators + globals.lua report global variable usage + hello.lua the first program in every language + life.lua Conway's Game of Life + luac.lua bare-bones luac + printf.lua an implementation of printf + readonly.lua make global variables readonly + sieve.lua the sieve of of Eratosthenes programmed with coroutines + sort.lua two implementations of a sort function + table.lua make table, grouping all data for the same item + trace-calls.lua trace calls + trace-globals.lua trace assigments to global variables + xd.lua hex dump + diff --git a/vscript/languages/lua/lua-5.1.4/test/bisect.lua b/vscript/languages/lua/lua-5.1.4/test/bisect.lua new file mode 100644 index 00000000..f91e69bf --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/test/bisect.lua @@ -0,0 +1,27 @@ +-- bisection method for solving non-linear equations + +delta=1e-6 -- tolerance + +function bisect(f,a,b,fa,fb) + local c=(a+b)/2 + io.write(n," c=",c," a=",a," b=",b,"\n") + if c==a or c==b or math.abs(a-b) posted to lua-l +-- modified to use ANSI terminal escape sequences +-- modified to use for instead of while + +local write=io.write + +ALIVE="¥" DEAD="þ" +ALIVE="O" DEAD="-" + +function delay() -- NOTE: SYSTEM-DEPENDENT, adjust as necessary + for i=1,10000 do end + -- local i=os.clock()+1 while(os.clock() 0 do + local xm1,x,xp1,xi=self.w-1,self.w,1,self.w + while xi > 0 do + local sum = self[ym1][xm1] + self[ym1][x] + self[ym1][xp1] + + self[y][xm1] + self[y][xp1] + + self[yp1][xm1] + self[yp1][x] + self[yp1][xp1] + next[y][x] = ((sum==2) and self[y][x]) or ((sum==3) and 1) or 0 + xm1,x,xp1,xi = x,xp1,xp1+1,xi-1 + end + ym1,y,yp1,yi = y,yp1,yp1+1,yi-1 + end +end + +-- output the array to screen +function _CELLS:draw() + local out="" -- accumulate to reduce flicker + for y=1,self.h do + for x=1,self.w do + out=out..(((self[y][x]>0) and ALIVE) or DEAD) + end + out=out.."\n" + end + write(out) +end + +-- constructor +function CELLS(w,h) + local c = ARRAY2D(w,h) + c.spawn = _CELLS.spawn + c.evolve = _CELLS.evolve + c.draw = _CELLS.draw + return c +end + +-- +-- shapes suitable for use with spawn() above +-- +HEART = { 1,0,1,1,0,1,1,1,1; w=3,h=3 } +GLIDER = { 0,0,1,1,0,1,0,1,1; w=3,h=3 } +EXPLODE = { 0,1,0,1,1,1,1,0,1,0,1,0; w=3,h=4 } +FISH = { 0,1,1,1,1,1,0,0,0,1,0,0,0,0,1,1,0,0,1,0; w=5,h=4 } +BUTTERFLY = { 1,0,0,0,1,0,1,1,1,0,1,0,0,0,1,1,0,1,0,1,1,0,0,0,1; w=5,h=5 } + +-- the main routine +function LIFE(w,h) + -- create two arrays + local thisgen = CELLS(w,h) + local nextgen = CELLS(w,h) + + -- create some life + -- about 1000 generations of fun, then a glider steady-state + thisgen:spawn(GLIDER,5,4) + thisgen:spawn(EXPLODE,25,10) + thisgen:spawn(FISH,4,12) + + -- run until break + local gen=1 + write("\027[2J") -- ANSI clear screen + while 1 do + thisgen:evolve(nextgen) + thisgen,nextgen = nextgen,thisgen + write("\027[H") -- ANSI home cursor + thisgen:draw() + write("Life - generation ",gen,"\n") + gen=gen+1 + if gen>2000 then break end + --delay() -- no delay + end +end + +LIFE(40,20) diff --git a/vscript/languages/lua/lua-5.1.4/test/luac.lua b/vscript/languages/lua/lua-5.1.4/test/luac.lua new file mode 100644 index 00000000..96a0a97c --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/test/luac.lua @@ -0,0 +1,7 @@ +-- bare-bones luac in Lua +-- usage: lua luac.lua file.lua + +assert(arg[1]~=nil and arg[2]==nil,"usage: lua luac.lua file.lua") +f=assert(io.open("luac.out","wb")) +assert(f:write(string.dump(assert(loadfile(arg[1]))))) +assert(f:close()) diff --git a/vscript/languages/lua/lua-5.1.4/test/printf.lua b/vscript/languages/lua/lua-5.1.4/test/printf.lua new file mode 100644 index 00000000..58c63ff5 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/test/printf.lua @@ -0,0 +1,7 @@ +-- an implementation of printf + +function printf(...) + io.write(string.format(...)) +end + +printf("Hello %s from %s on %s\n",os.getenv"USER" or "there",_VERSION,os.date()) diff --git a/vscript/languages/lua/lua-5.1.4/test/readonly.lua b/vscript/languages/lua/lua-5.1.4/test/readonly.lua new file mode 100644 index 00000000..85c0b4e0 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/test/readonly.lua @@ -0,0 +1,12 @@ +-- make global variables readonly + +local f=function (t,i) error("cannot redefine global variable `"..i.."'",2) end +local g={} +local G=getfenv() +setmetatable(g,{__index=G,__newindex=f}) +setfenv(1,g) + +-- an example +rawset(g,"x",3) +x=2 +y=1 -- cannot redefine `y' diff --git a/vscript/languages/lua/lua-5.1.4/test/sieve.lua b/vscript/languages/lua/lua-5.1.4/test/sieve.lua new file mode 100644 index 00000000..0871bb21 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/test/sieve.lua @@ -0,0 +1,29 @@ +-- the sieve of of Eratosthenes programmed with coroutines +-- typical usage: lua -e N=1000 sieve.lua | column + +-- generate all the numbers from 2 to n +function gen (n) + return coroutine.wrap(function () + for i=2,n do coroutine.yield(i) end + end) +end + +-- filter the numbers generated by `g', removing multiples of `p' +function filter (p, g) + return coroutine.wrap(function () + while 1 do + local n = g() + if n == nil then return end + if math.mod(n, p) ~= 0 then coroutine.yield(n) end + end + end) +end + +N=N or 1000 -- from command line +x = gen(N) -- generate primes up to N +while 1 do + local n = x() -- pick a number until done + if n == nil then break end + print(n) -- must be a prime number + x = filter(n, x) -- now remove its multiples +end diff --git a/vscript/languages/lua/lua-5.1.4/test/sort.lua b/vscript/languages/lua/lua-5.1.4/test/sort.lua new file mode 100644 index 00000000..0bcb15f8 --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/test/sort.lua @@ -0,0 +1,66 @@ +-- two implementations of a sort function +-- this is an example only. Lua has now a built-in function "sort" + +-- extracted from Programming Pearls, page 110 +function qsort(x,l,u,f) + if ly end) + show("after reverse selection sort",x) + qsort(x,1,n,function (x,y) return x>> ",string.rep(" ",level)) + if t~=nil and t.currentline>=0 then io.write(t.short_src,":",t.currentline," ") end + t=debug.getinfo(2) + if event=="call" then + level=level+1 + else + level=level-1 if level<0 then level=0 end + end + if t.what=="main" then + if event=="call" then + io.write("begin ",t.short_src) + else + io.write("end ",t.short_src) + end + elseif t.what=="Lua" then +-- table.foreach(t,print) + io.write(event," ",t.name or "(Lua)"," <",t.linedefined,":",t.short_src,">") + else + io.write(event," ",t.name or "(C)"," [",t.what,"] ") + end + io.write("\n") +end + +debug.sethook(hook,"cr") +level=0 diff --git a/vscript/languages/lua/lua-5.1.4/test/trace-globals.lua b/vscript/languages/lua/lua-5.1.4/test/trace-globals.lua new file mode 100644 index 00000000..295e670c --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/test/trace-globals.lua @@ -0,0 +1,38 @@ +-- trace assigments to global variables + +do + -- a tostring that quotes strings. note the use of the original tostring. + local _tostring=tostring + local tostring=function(a) + if type(a)=="string" then + return string.format("%q",a) + else + return _tostring(a) + end + end + + local log=function (name,old,new) + local t=debug.getinfo(3,"Sl") + local line=t.currentline + io.write(t.short_src) + if line>=0 then io.write(":",line) end + io.write(": ",name," is now ",tostring(new)," (was ",tostring(old),")","\n") + end + + local g={} + local set=function (t,name,value) + log(name,g[name],value) + g[name]=value + end + setmetatable(getfenv(),{__index=g,__newindex=set}) +end + +-- an example + +a=1 +b=2 +a=10 +b=20 +b=nil +b=200 +print(a,b,c) diff --git a/vscript/languages/lua/lua-5.1.4/test/xd.lua b/vscript/languages/lua/lua-5.1.4/test/xd.lua new file mode 100644 index 00000000..ebc3effc --- /dev/null +++ b/vscript/languages/lua/lua-5.1.4/test/xd.lua @@ -0,0 +1,14 @@ +-- hex dump +-- usage: lua xd.lua < file + +local offset=0 +while true do + local s=io.read(16) + if s==nil then return end + io.write(string.format("%08X ",offset)) + string.gsub(s,"(.)", + function (c) io.write(string.format("%02X ",string.byte(c))) end) + io.write(string.rep(" ",3*(16-string.len(s)))) + io.write(" ",string.gsub(s,"%c","."),"\n") + offset=offset+16 +end diff --git a/vscript/languages/lua/vlua/vec3.cpp b/vscript/languages/lua/vlua/vec3.cpp new file mode 100644 index 00000000..5bea78f1 --- /dev/null +++ b/vscript/languages/lua/vlua/vec3.cpp @@ -0,0 +1,284 @@ +#include + +#if !defined(OSX) && !defined (LINUX) +extern "C" +{ +#endif + +#include "lua.h" +#include "lauxlib.h" + +#if !defined(OSX) && !defined (LINUX) +} +#endif + +#include "vec3.h" + + +#define VEC3_TYPE "Vec3" +#define VEC3_NAME "Vec3" + + +Vector *lua_getvec3( lua_State *pState, int i ) +{ + if ( luaL_checkudata( pState, i, VEC3_TYPE ) == NULL ) + { + luaL_typerror( pState, i, VEC3_TYPE ); + } + + return ( Vector * )lua_touserdata( pState, i ); +} + + +Vector lua_getvec3ByValue( lua_State *pState, int i ) +{ + if ( lua_isnumber( pState, i ) ) + { + float flValue = lua_tonumber( pState, i ); + + return Vector( flValue, flValue, flValue ); + } + if ( luaL_checkudata( pState, i, VEC3_TYPE ) == NULL ) + { + luaL_typerror( pState, i, VEC3_TYPE ); + } + + return *( Vector * )lua_touserdata( pState, i ); +} + + +static Vector *lua_allocvec3( lua_State *pState ) +{ + Vector *v =( Vector *)lua_newuserdata( pState, sizeof( Vector ) ); + luaL_getmetatable( pState, VEC3_TYPE ); + lua_setmetatable( pState, -2 ); + + return v; +} + + +Vector *lua_newvec3( lua_State *pState, const Vector *Value ) +{ + Vector *v; + + v = lua_allocvec3( pState ); + v->x = Value->x; + v->y = Value->y; + v->z = Value->z; + + return v; +} + + +static int vec3_new( lua_State *pState ) +{ + Vector *v; + + lua_settop( pState, 3 ); + v = lua_allocvec3( pState ); + v->x = luaL_optnumber( pState, 1, 0 ); + v->y = luaL_optnumber( pState, 2, 0 ); + v->z = luaL_optnumber( pState, 3, 0 ); + + return 1; +} + + +static int vec3_index( lua_State *pState ) +{ + const char *pszKey = luaL_checkstring( pState, 2 ); + + if ( pszKey[ 1 ] == '\0' ) + { + Vector *v = lua_getvec3( pState, 1 ); + switch ( pszKey[ 0 ] ) + { + case '1': case 'x': case 'r': + lua_pushnumber( pState, v->x ); + return 1; + + case '2': case 'y': case 'g': + lua_pushnumber( pState, v->y ); + return 1; + + case '3': case 'z': case 'b': + lua_pushnumber( pState, v->z ); + return 1; + } + } + + lua_getfield( pState, LUA_REGISTRYINDEX, VEC3_TYPE ); + lua_pushstring( pState, pszKey ); + lua_rawget( pState, -2 ); + + return 1; +} + + +static int vec3_newindex( lua_State *pState ) +{ + const char *pszKey = luaL_checkstring( pState, 2 ); + + if ( pszKey[ 1 ] == '\0' ) + { + Vector *v = lua_getvec3( pState, 1 ); + float flValue = luaL_checknumber( pState, 3 ); + switch ( pszKey[ 0 ] ) + { + case '1': case 'x': case 'r': + v->x = flValue; + break; + + case '2': case 'y': case 'g': + v->y = flValue; + break; + + case '3': case 'z': case 'b': + v->z = flValue; + break; + + default: + break; + } + } + + return 1; +} + +static int vec3_tostring( lua_State *pState ) +{ + char s[ 64 ]; + Vector *v = lua_getvec3( pState, 1 ); + + sprintf( s, "%s %p", VEC3_TYPE, ( void * )v ); + + lua_pushstring( pState, s ); + + return 1; +} + + +static int vec3_add( lua_State *pState ) +{ + Vector v1 = lua_getvec3ByValue( pState, 1 ); + Vector v2 = lua_getvec3ByValue( pState, 2 ); + + Vector vResult = v1 + v2; + + lua_newvec3( pState, &vResult ); + + return 1; +} + + +static int vec3_subtract( lua_State *pState ) +{ + Vector v1 = lua_getvec3ByValue( pState, 1 ); + Vector v2 = lua_getvec3ByValue( pState, 2 ); + + Vector vResult = v1 - v2; + + lua_newvec3( pState, &vResult ); + + return 1; +} + + +static int vec3_multiply( lua_State *pState ) +{ + Vector v1 = lua_getvec3ByValue( pState, 1 ); + Vector v2 = lua_getvec3ByValue( pState, 2 ); + + Vector vResult = v1 * v2; + + lua_newvec3( pState, &vResult ); + + return 1; +} + + +static int vec3_divide( lua_State *pState ) +{ + Vector v1 = lua_getvec3ByValue( pState, 1 ); + Vector v2 = lua_getvec3ByValue( pState, 2 ); + + Vector vResult = v1 / v2; + + lua_newvec3( pState, &vResult ); + + return 1; +} + + +static int vec3_length( lua_State *pState ) +{ + Vector v1 = lua_getvec3ByValue( pState, 1 ); + + float flResult = v1.Length(); + + lua_pushnumber( pState, flResult ); + + return 1; +} + + +static int vec3_equal( lua_State *pState ) +{ + Vector v1 = lua_getvec3ByValue( pState, 1 ); + Vector v2 = lua_getvec3ByValue( pState, 2 ); + + return ( v1 == v2 ? 1 : 0 ); +} + + +static int vec3_dot( lua_State *pState ) +{ + Vector v1 = lua_getvec3ByValue( pState, 1 ); + Vector v2 = lua_getvec3ByValue( pState, 2 ); + + float flResult = v1.Dot( v2 ); + + lua_pushnumber( pState, flResult ); + + return 1; +} + + +static int vec3_cross( lua_State *pState ) +{ + Vector v1 = lua_getvec3ByValue( pState, 1 ); + Vector v2 = lua_getvec3ByValue( pState,2 ); + + Vector vResult = v1,Cross( v2 ); + + lua_newvec3( pState, &vResult ); + + return 1; +} + + +static const luaL_reg Registrations[] = +{ + { "__index", vec3_index }, + { "__newindex", vec3_newindex }, + { "__tostring", vec3_tostring }, + { "__add", vec3_add }, + { "__sub", vec3_subtract }, + { "__mul", vec3_multiply }, + { "__div", vec3_divide }, + { "__len", vec3_length }, + { "__eq", vec3_equal }, + { "dot", vec3_dot }, + { "cross", vec3_cross }, + { NULL, NULL } +}; + + +LUALIB_API int luaopen_vec3( lua_State *pState ) +{ + luaL_newmetatable( pState, VEC3_TYPE ); + luaL_register( pState, NULL, Registrations ); + lua_register( pState, VEC3_NAME, vec3_new ); + + return 1; +} diff --git a/vscript/languages/lua/vlua/vec3.h b/vscript/languages/lua/vlua/vec3.h new file mode 100644 index 00000000..9d386497 --- /dev/null +++ b/vscript/languages/lua/vlua/vec3.h @@ -0,0 +1,19 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +//===========================================================================// + +#ifndef VEC3_H +#define VEC3_H +#ifdef _WIN32 +#pragma once +#endif + +#include "mathlib/vector.h" + +extern int luaopen_vec3(lua_State *L); +extern Vector *lua_getvec3(lua_State *L, int i); +extern Vector *lua_newvec3( lua_State *L, const Vector *Value ); + +#endif // VEC3_H diff --git a/vscript/languages/lua/vlua/vlua.cpp b/vscript/languages/lua/vlua/vlua.cpp new file mode 100644 index 00000000..fe8bc3cb --- /dev/null +++ b/vscript/languages/lua/vlua/vlua.cpp @@ -0,0 +1,1502 @@ +//========== Copyright � 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: +// +//============================================================================= + +#include +#if defined(POSIX) +#include +#include +#else +#include +#include +#include +#endif + +#include "platform.h" + +#if !defined(OSX) && !defined(POSIX) +extern "C" +{ +#endif +#include "lua.h" +#include "lauxlib.h" +#include "lualib.h" +#ifdef getstr // Already defined in curses.h on linux +#undef getstr +#endif +#include "lobject.h" +#include "lstate.h" +#include "ldo.h" +#if !defined(OSX) && !defined(POSIX) +} +#endif + +#include "vec3.h" + +#include "tier1/utlmap.h" + +#include "datamap.h" +#include "tier1/functors.h" +#include "tier1/utlvector.h" +#include "tier1/utlhash.h" +#include "tier1/utlbuffer.h" +#include "tier1/fmtstr.h" +#include "tier1/convar.h" +#include "mathlib/vector.h" +#include "vstdlib/random.h" + +#include "vscript/ivscript.h" + +#include + +//#include "init_nut.h" + +#include "memdbgon.h" + +#ifdef VLUA_DEBUG_SERIALIZATION +static int lastType; +#endif + + +//------------------------------------------------------------------------- +// Helpers +//------------------------------------------------------------------------- + +static const char *FieldTypeToString( int type ) +{ + switch( type ) + { + case FIELD_VOID: return "void"; + case FIELD_FLOAT: return "float"; + case FIELD_CSTRING: return "string"; + case FIELD_VECTOR: return "Vector"; + case FIELD_INTEGER: return "int"; + case FIELD_BOOLEAN: return "bool"; + case FIELD_CHARACTER: return "char"; + case FIELD_HSCRIPT: return "handle"; + default: return ""; + } +} + + +static const char *LUATypeToString( int nLUAType ) +{ + switch( nLUAType ) + { + case LUA_TNUMBER: return "FLOAT"; + case LUA_TBOOLEAN: return "BOOL"; + case LUA_TSTRING: return "STRING"; + case LUA_TNIL: return "NULL"; + case LUA_TTABLE: return "TABLE"; + case LUA_TUSERDATA: return "USERDATA"; + case LUA_TTHREAD: return "THREAD"; + } + return ""; +} + + +class CLuaVM : public IScriptVM +{ + lua_State *m_LuaState; + ScriptOutputFunc_t m_OutputFunc; + ScriptErrorFunc_t m_ErrorFunc; + int64 m_iUniqueIdSerialNumber; + +// CUtlHashFast m_TypeMap; + + struct InstanceContext_t + { + void *pInstance; + ScriptClassDesc_t *pClassDesc; + char szName[ 64 ]; + }; + + +public: + CLuaVM( lua_State *pState = NULL ) + { + m_LuaState = pState; + m_iUniqueIdSerialNumber = 0; + + m_OutputFunc = NULL; + m_ErrorFunc = NULL; + +// m_TypeMap.Init( 256 ); + } + + static int PrintFunc( lua_State *pState ) + { + ScriptOutputFunc_t m_OutputFunc = *( ( ScriptOutputFunc_t * )lua_touserdata( pState, lua_upvalueindex( 1 ) ) ); + CUtlString Output; + + int n = lua_gettop( pState ); /* number of arguments */ + int i; + lua_getglobal( pState, "towstring" ); + lua_getglobal( pState, "tostring" ); + for ( i=1; i <= n; i++ ) + { + const char *s = NULL; + lua_pushvalue( pState, -1 ); /* function to be called */ + lua_pushvalue( pState, i ); /* value to print */ + lua_call( pState, 1, 1 ); + s = lua_tostring( pState, -1 ); /* get result */ + if ( s == NULL ) + { + return luaL_error( pState, LUA_QL( "tostring" ) " must return a string to " LUA_QL( "print" ) ); + } + if ( i > 1 ) + { + Output += "\t"; + } + if ( s ) + { + Output += s; + } + lua_pop( pState, 1 ); /* pop result */ + } + + if ( m_OutputFunc ) + { + m_OutputFunc( Output ); + } + else + { + Msg( "%s\n", Output.Get() ); + } + + return 0; + } + + void HandleError( const char *pszErrorText ) + { + if ( m_ErrorFunc ) + { + m_ErrorFunc( SCRIPT_LEVEL_WARNING, pszErrorText ); + } + else + { + Msg( pszErrorText ); + } + } + + static int FatalErrorHandler( lua_State *pState ) + { + const char *err = lua_tostring( pState, 1 ); + + throw( err ); + } + + void FatalError( const char *pszError ) + { + if ( m_ErrorFunc ) + { + m_ErrorFunc( SCRIPT_LEVEL_ERROR, pszError ); + } + else + { + Msg( pszError ); + } + } + + int GetStackSize( ) + { + return ( ( char * )m_LuaState->stack_last - ( char * )m_LuaState->top ) / sizeof( TValue ); + } + + static void stackDump (lua_State *L) + { + int i; + int top = lua_gettop(L); + for (i = 1; i <= top; i++) { /* repeat for each level */ + int t = lua_type(L, i); + switch (t) { + + case LUA_TSTRING: /* strings */ + printf("`%s'", lua_tostring(L, i)); + break; + + case LUA_TBOOLEAN: /* booleans */ + printf(lua_toboolean(L, i) ? "true" : "false"); + break; + + case LUA_TNUMBER: /* numbers */ + printf("%g", lua_tonumber(L, i)); + break; + + default: /* other values */ + printf("%s", lua_typename(L, t)); + break; + + } + printf(" "); /* put a separator */ + } + printf("\n"); /* end the listing */ + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + static void PushVariant( lua_State *pState, const ScriptVariant_t &value ) + { + switch ( value.m_type ) + { + case FIELD_VOID: + lua_pushnil( pState ); + break; + + case FIELD_FLOAT: + lua_pushnumber( pState, value.m_float ); + break; + + case FIELD_CSTRING: + lua_pushstring( pState, value ); + break; + + case FIELD_VECTOR: + lua_newvec3( pState, value.m_pVector ); + break; + + case FIELD_INTEGER: + lua_pushinteger( pState, value.m_int ); + break; + + case FIELD_BOOLEAN: + lua_pushboolean( pState, value.m_bool ); + break; + + case FIELD_CHARACTER: + { + char sz[2]; + + sz[0] = value.m_char; + sz[1] = 0; + lua_pushlstring( pState, sz, 1 ); + break; + } + + case FIELD_HSCRIPT: + if ( value.m_hScript == NULL ) + { + lua_pushnil( pState ); + } + else + { + lua_rawgeti( pState, LUA_REGISTRYINDEX, size_cast< int > ( ( intp )value.m_hScript ) ); + Assert( lua_isnil( pState, -1 ) == false ); + } + break; + } + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + static bool ConvertToVariant( int nStackIndex, lua_State *pState, ScriptVariant_t *pReturn ) + { + switch ( lua_type( pState, nStackIndex ) ) + { + case LUA_TNIL: + pReturn->m_type = FIELD_VOID; + break; + case LUA_TNUMBER: + *pReturn = ( float )lua_tonumber( pState, nStackIndex ); + break; + case LUA_TBOOLEAN: + *pReturn = ( lua_toboolean( pState, nStackIndex ) != 0 ); + break; + case LUA_TSTRING: + { + int size = strlen( lua_tostring( pState, nStackIndex ) ) + 1; + pReturn->m_type = FIELD_CSTRING; + pReturn->m_pszString = new char[ size ]; + memcpy( (void *)pReturn->m_pszString, lua_tostring( pState, nStackIndex ), size ); + pReturn->m_flags |= SV_FREE; + } + break; +#if 0 + case OT_INSTANCE: + { + SQUserPointer pVector; + sq_pushobject( m_hVM, object ); + SQRESULT getResult = sq_getinstanceup( m_hVM, -1, &pVector, TYPETAG_VECTOR ); + sq_poptop( m_hVM ); + if ( getResult == SQ_OK ) + { + pReturn->m_type = FIELD_VECTOR; + pReturn->m_pVector = new Vector( *((Vector *)pVector) ); + pReturn->m_flags |= SV_FREE; + break; + } + } + // fall through +#endif + default: + { + Assert( nStackIndex == -1 ); + pReturn->m_type = FIELD_HSCRIPT; + pReturn->m_hScript = ( HSCRIPT )( intp )luaL_ref( pState, LUA_REGISTRYINDEX ); + } + } + return true; + } + + static void ReleaseVariant( lua_State *pState, ScriptVariant_t &value ) + { + if ( value.m_type == FIELD_HSCRIPT ) + { + luaL_unref( pState, LUA_REGISTRYINDEX, size_cast< int >( ( intp )value.m_hScript ) ); + } + else + { + value.Free(); + } + value.m_type = FIELD_VOID; + } + + virtual bool Init( ) + { + m_LuaState = luaL_newstate(); + luaL_openlibs( m_LuaState ); + luaopen_vec3( m_LuaState ); + + lua_atpanic( m_LuaState, FatalErrorHandler ); + + SetOutputCallback( NULL ); + + return true; + } + + virtual void Shutdown() + { + if ( m_LuaState ) + { + lua_close( m_LuaState ); + m_LuaState = NULL; + } + +// m_TypeMap.Purge(); + } + + virtual bool ConnectDebugger() + { + Assert( 0 ); + return false; + } + + virtual void DisconnectDebugger() + { + Assert( 0 ); + } + + virtual ScriptLanguage_t GetLanguage() + { + return SL_LUA; + } + + virtual const char *GetLanguageName() + { + return "Lua"; + } + + virtual void AddSearchPath( const char *pszSearchPath ) + { + lua_getfield( m_LuaState, LUA_GLOBALSINDEX, "package" ); + if ( !lua_istable( m_LuaState, -1 ) ) + { + Assert( 0 ); + lua_pop( m_LuaState, 1 ); + return; + } + + lua_getfield( m_LuaState, -1, "path" ); + if ( !lua_isstring( m_LuaState, -1 ) ) + { + Assert( 0 ); + lua_pop( m_LuaState, 1 ); + return; + } + + CUtlString szNewPath; + + szNewPath = lua_tostring( m_LuaState, -1 ); + szNewPath += ";"; + szNewPath += pszSearchPath; + szNewPath += "\\?.lua"; + + lua_pushstring( m_LuaState, szNewPath ); + lua_setfield( m_LuaState, -3, "path" ); + + lua_pop( m_LuaState, 2 ); + } + + virtual bool Frame( float simTime ) + { + if ( m_LuaState ) + { + Msg( "Garbage Collecting...\n" ); + lua_gc( m_LuaState, LUA_GCCOLLECT, 0 ); + } + +#if 0 + if ( m_hDbg ) + { + sq_rdbg_update( m_hDbg ); + if ( !m_hDbg->IsConnected() ) + DisconnectDebugger(); + } +#endif + + return true; + } + + virtual ScriptStatus_t Run( const char *pszScript, bool bWait = true ) + { + Assert( 0 ); + return SCRIPT_ERROR; + } + + virtual HSCRIPT CompileScript( const char *pszScript, const char *pszId = NULL ) + { + int nResult = luaL_loadbuffer( m_LuaState, pszScript, strlen( pszScript ), pszId ); + + if ( nResult == 0 ) + { + int func_ref = luaL_ref( m_LuaState, LUA_REGISTRYINDEX ); + +// lua_rawgeti( m_LuaState, LUA_REGISTRYINDEX, func_ref ); +// lua_call( m_LuaState, 0, 0 ); + + return ( HSCRIPT )( intp )func_ref; + } + else + { + const char *pszErrorText = lua_tostring( m_LuaState, -1 ); + HandleError( pszErrorText ); + } + + return INVALID_HSCRIPT; + } + + virtual void ReleaseScript( HSCRIPT hScript) + { + luaL_unref( m_LuaState, LUA_REGISTRYINDEX, size_cast< int > ( ( intp )hScript ) ); + } + + virtual ScriptStatus_t Run( HSCRIPT hScript, HSCRIPT hScope = NULL, bool bWait = true ) + { + lua_rawgeti( m_LuaState, LUA_REGISTRYINDEX, size_cast< int >( ( intp )hScript ) ); + int nResult = lua_pcall( m_LuaState, 0, LUA_MULTRET, 0 ); + + switch( nResult ) + { + case LUA_ERRRUN: + { + const char *pszErrorText = lua_tostring( m_LuaState, -1 ); + HandleError( pszErrorText ); + return SCRIPT_ERROR; + } + + case LUA_ERRMEM: + { + const char *pszErrorText = lua_tostring( m_LuaState, -1 ); + HandleError( pszErrorText ); + return SCRIPT_ERROR; + } + + case LUA_ERRERR: + { + const char *pszErrorText = lua_tostring( m_LuaState, -1 ); + HandleError( pszErrorText ); + return SCRIPT_ERROR; + } + } + + return SCRIPT_DONE; + } + + virtual ScriptStatus_t Run( HSCRIPT hScript, bool bWait ) + { + Assert( 0 ); + return SCRIPT_ERROR; + } + + // stack good + virtual HSCRIPT CreateScope( const char *pszScope, HSCRIPT hParent = NULL ) + { + return NULL; + } + + virtual void ReleaseScope( HSCRIPT hScript ) + { + } + + // stack good + virtual HSCRIPT LookupFunction( const char *pszFunction, HSCRIPT hScope = NULL ) + { + if ( hScope ) + { + lua_rawgeti( m_LuaState, LUA_REGISTRYINDEX, size_cast< int >( ( intp )hScope ) ); + if ( lua_isnil( m_LuaState, -1 ) ) + { + Assert( 0 ); + lua_pop( m_LuaState, 1 ); + return NULL; + } + + lua_getfield( m_LuaState, -1, pszFunction ); + if ( lua_isnil( m_LuaState, -1 ) || !lua_isfunction( m_LuaState, -1 ) ) + { + lua_pop( m_LuaState, 2 ); + return NULL; + } + + int func_ref = luaL_ref( m_LuaState, LUA_REGISTRYINDEX ); + lua_pop( m_LuaState, 1 ); + + return ( HSCRIPT )( intp )func_ref; + } + else + { + lua_getfield( m_LuaState, LUA_GLOBALSINDEX, pszFunction ); + if ( lua_isnil( m_LuaState, -1 ) || !lua_isfunction( m_LuaState, -1 ) ) + { + lua_pop( m_LuaState, 1 ); + return NULL; + } + + int func_ref = luaL_ref( m_LuaState, LUA_REGISTRYINDEX ); + + return ( HSCRIPT )( intp )func_ref; + } + } + + // stack good + virtual void ReleaseFunction( HSCRIPT hScript ) + { + luaL_unref( m_LuaState, LUA_REGISTRYINDEX, size_cast( ( intp )hScript ) ); + } + + // stack good + virtual ScriptStatus_t ExecuteFunction( HSCRIPT hFunction, ScriptVariant_t *pArgs, int nArgs, ScriptVariant_t *pReturn, HSCRIPT hScope, bool bWait ) + { + if ( hScope == INVALID_HSCRIPT ) + { + DevWarning( "ExecuteFunction: Invalid scope handed to script VM\n" ); + return SCRIPT_ERROR; + } + +#if 0 + if ( m_hDbg ) + { + extern bool g_bSqDbgTerminateScript; + if ( g_bSqDbgTerminateScript ) + { + DisconnectDebugger(); + g_bSqDbgTerminateScript = false; + } + } +#endif + + Assert( bWait ); + + try + { + if ( hFunction ) + { + int nStackSize = GetStackSize(); + + lua_rawgeti( m_LuaState, LUA_REGISTRYINDEX, size_cast< int >( ( intp )hFunction ) ); + + int nTopStack = lua_gettop( m_LuaState ); + + if ( hScope ) + { + lua_rawgeti( m_LuaState, LUA_REGISTRYINDEX, size_cast< int >( ( intp )hScope ) ); + } + + for ( int i = 0; i < nArgs; i++ ) + { + PushVariant( m_LuaState, pArgs[i] ); + } + + lua_call( m_LuaState, lua_gettop( m_LuaState ) - nTopStack, ( pReturn ? 1 : 0 ) ); + if ( pReturn ) + { + ConvertToVariant( -1, m_LuaState, pReturn ); + } + + lua_pop( m_LuaState, nStackSize - GetStackSize() ); + + return SCRIPT_DONE; + } + + if ( pReturn ) + { + pReturn->m_type = FIELD_VOID; + } + } + catch( const char *pszString ) + { + FatalError( pszString ); + } + + return SCRIPT_ERROR; + } + + // stack good + static int TranslateCall( lua_State *pState ) + { + int nActualParams = lua_gettop( pState ); + ScriptFunctionBinding_t *pVMScriptFunction = ( ScriptFunctionBinding_t * )lua_touserdata( pState, lua_upvalueindex( 1 ) ); + int nFormalParams = pVMScriptFunction->m_desc.m_Parameters.Count(); + CUtlVectorFixed params; + ScriptVariant_t returnValue; + bool bCallFree = false; + + params.SetSize( nFormalParams ); + + void *pObject = NULL; + + if ( nActualParams ) + { + int nOffset = 1; + + if ( ( pVMScriptFunction->m_flags & SF_MEMBER_FUNC ) ) + { + InstanceContext_t *pInstanceContext = ( InstanceContext_t * )lua_touserdata( pState, nOffset ); + pObject = pInstanceContext->pInstance; + + if ( pInstanceContext->pClassDesc->pHelper ) + { + pObject = pInstanceContext->pClassDesc->pHelper->GetProxied( pObject ); + } + + if ( !pObject ) + { +// sq_throwerror( hVM, "Accessed null instance" ); + return SCRIPT_ERROR; + } + + nOffset++; + nActualParams--; + } + + int iLimit = ( nActualParams < nFormalParams ? nActualParams : nFormalParams ); + ScriptDataType_t *pCurParamType = pVMScriptFunction->m_desc.m_Parameters.Base(); + + for ( int i = 0; i < iLimit; i++, pCurParamType++ ) + { + switch ( *pCurParamType ) + { + case FIELD_FLOAT: + params[ i ] = ( float )lua_tonumber( pState, i + nOffset ); + break; + + case FIELD_CSTRING: + params[ i ] = lua_tostring( pState, i + nOffset ); + break; + + case FIELD_VECTOR: + { + params[ i ] = lua_getvec3( pState, i + nOffset ); + break; + } + + case FIELD_INTEGER: + params[ i ] = ( int )lua_tonumber( pState, i + nOffset ); + break; + + case FIELD_BOOLEAN: + params[ i ] = ( lua_toboolean( pState, i + nOffset ) != 0 ); + break; + + case FIELD_CHARACTER: + params[ i ] = lua_tostring( pState, i + nOffset )[0]; + break; + + case FIELD_HSCRIPT: + { + lua_pushvalue( pState, i + nOffset ); + params[ i ] = ( HSCRIPT )( intp )luaL_ref( pState, LUA_REGISTRYINDEX ); +// params[ i ].m_flags |= SV_FREE; + bCallFree = true; + break; + } + + default: + break; + } + } + } + + (*pVMScriptFunction->m_pfnBinding)( pVMScriptFunction->m_pFunction, pObject, params.Base(), params.Count(), ( pVMScriptFunction->m_desc.m_ReturnType != FIELD_VOID ) ? &returnValue : NULL ); + + if ( pVMScriptFunction->m_desc.m_ReturnType != FIELD_VOID ) + { + PushVariant( pState, returnValue ); + } + + if ( bCallFree ) + { + for ( int i = 0; i < params.Count(); i++ ) + { + ReleaseVariant( pState, params[ i ] ); +// params[i].Free(); + } + } + + return ( ( pVMScriptFunction->m_desc.m_ReturnType != FIELD_VOID ) ? 1 : 0 ) ; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + // stack good + void RegisterFunctionGuts( ScriptFunctionBinding_t *pScriptFunction, HSCRIPT pOwningClass = NULL ) + { + char szTypeMask[ 64 ]; + + if ( pScriptFunction->m_desc.m_Parameters.Count() > ARRAYSIZE(szTypeMask) - 1 ) + { + AssertMsg1( 0, "Too many agruments for script function %s\n", pScriptFunction->m_desc.m_pszFunction ); + return; + } + + szTypeMask[0] = '.'; + char *pCurrent = &szTypeMask[1]; + for ( int i = 0; i < pScriptFunction->m_desc.m_Parameters.Count(); i++, pCurrent++ ) + { + switch ( pScriptFunction->m_desc.m_Parameters[i] ) + { + case FIELD_CSTRING: + *pCurrent = 's'; + break; + case FIELD_FLOAT: + case FIELD_INTEGER: + *pCurrent = 'n'; + break; + case FIELD_BOOLEAN: + *pCurrent = 'b'; + break; + + case FIELD_VECTOR: + *pCurrent = 'x'; + break; + + case FIELD_HSCRIPT: + *pCurrent = '.'; + break; + + case FIELD_CHARACTER: + default: + *pCurrent = FIELD_VOID; + AssertMsg( 0 , "Not supported" ); + break; + } + } + + int nStackIndex = LUA_GLOBALSINDEX; + if ( pOwningClass ) + { + lua_rawgeti( m_LuaState, LUA_REGISTRYINDEX, size_cast< int >( ( intp )pOwningClass ) ); + if ( !lua_isnil( m_LuaState, -1 ) ) + { + nStackIndex = lua_gettop( m_LuaState ); + } + } + + Assert( pCurrent - szTypeMask < ARRAYSIZE(szTypeMask) - 1 ); + *pCurrent = 0; + lua_pushstring( m_LuaState, pScriptFunction->m_desc.m_pszScriptName ); + lua_pushlightuserdata( m_LuaState, pScriptFunction ); + lua_pushcclosure( m_LuaState, &TranslateCall, 1 ); + lua_settable( m_LuaState, nStackIndex ); + + if ( pOwningClass ) + { + lua_pop( m_LuaState, 1 ); + } + + if ( nStackIndex == LUA_GLOBALSINDEX ) + { + Msg( "VLua: Registered GLOBAL function %s\n", pScriptFunction->m_desc.m_pszScriptName ); + } + else + { + Msg( "VLua: Registered TABLE function %s\n", pScriptFunction->m_desc.m_pszScriptName ); + } + +#if 0 + if ( developer.GetInt() ) + { + const char *pszHide = SCRIPT_HIDE; + if ( !pScriptFunction->m_desc.m_pszDescription || *pScriptFunction->m_desc.m_pszDescription != *pszHide ) + { + std::string name; + std::string signature; + + if ( pClassDesc ) + { + name += pClassDesc->m_pszScriptName; + name += "::"; + } + + name += pScriptFunction->m_desc.m_pszScriptName; + + signature += FieldTypeToString( pScriptFunction->m_desc.m_ReturnType ); + signature += ' '; + signature += name; + signature += '('; + for ( int i = 0; i < pScriptFunction->m_desc.m_Parameters.Count(); i++ ) + { + if ( i != 0 ) + { + signature += ", "; + } + + signature+= FieldTypeToString( pScriptFunction->m_desc.m_Parameters[i] ); + } + signature += ')'; + + sq_pushobject( m_hVM, LookupObject( "RegisterFunctionDocumentation", NULL, false ) ); + sq_pushroottable( m_hVM ); + sq_pushobject( m_hVM, hFunction ); + sq_pushstring( m_hVM, name.c_str(), name.length() ); + sq_pushstring( m_hVM, signature.c_str(), signature.length() ); + sq_pushstring( m_hVM, pScriptFunction->m_desc.m_pszDescription, -1 ); + sq_call( m_hVM, 5, false, /*false*/ true ); + sq_pop( m_hVM, 1 ); + } + } +#endif + } + + virtual void RegisterFunction( ScriptFunctionBinding_t *pScriptFunction ) + { + RegisterFunctionGuts( pScriptFunction ); + } + + static int custom_index( lua_State *pState ) + { + InstanceContext_t *pInstanceContext = ( ( InstanceContext_t * )lua_touserdata( pState, 1 ) ); + ScriptClassDesc_t *pVMScriptFunction = pInstanceContext->pClassDesc; + const char *pszKey = luaL_checkstring( pState, 2 ); + + while( pVMScriptFunction ) + { + lua_getfield( pState, LUA_REGISTRYINDEX, pVMScriptFunction->m_pszClassname ); + if ( lua_isnil( pState, -1 ) ) + { + break; + } + lua_pushstring( pState, pszKey ); + lua_rawget( pState, -2 ); + + if ( lua_isnil( pState, -1 ) ) + { + lua_pop( pState, 2 ); + pVMScriptFunction = pVMScriptFunction->m_pBaseDesc; + } + else + { + break; + } + } + + return 1; + } + +/* + static int custom_gc( lua_State *pState ) + { + InstanceContext_t *pInstanceContext = ( ( InstanceContext_t * )lua_touserdata( pState, 1 ) ); + + return 0; + } +*/ + + // stack good + virtual bool RegisterClass( ScriptClassDesc_t *pClassDesc ) + { + if ( luaL_newmetatable( m_LuaState, pClassDesc->m_pszScriptName ) == 0 ) + { + lua_pop( m_LuaState, 1 ); + return true; + } + +// lua_pushcclosure( m_LuaState, custom_gc, 0 ); +// lua_setfield( m_LuaState, -2, "__gc" ); + lua_pushcclosure( m_LuaState, custom_index, 0 ); + lua_setfield( m_LuaState, -2, "__index" ); + + HSCRIPT ClassReference = ( HSCRIPT )( intp )luaL_ref( m_LuaState, LUA_REGISTRYINDEX ); + + for ( int i = 0; i < pClassDesc->m_FunctionBindings.Count(); i++ ) + { + RegisterFunctionGuts( &pClassDesc->m_FunctionBindings[i], ClassReference ); + } + + if ( pClassDesc->m_pBaseDesc ) + { + RegisterClass( pClassDesc->m_pBaseDesc ); + } + + luaL_unref( m_LuaState, LUA_REGISTRYINDEX, size_cast< int >( ( intp )ClassReference ) ); + + return true; + } + + + // stack good + virtual HSCRIPT RegisterInstance( ScriptClassDesc_t *pClassDesc, void *pInstance ) + { + HSCRIPT Instance = NULL; + + if ( !RegisterClass( pClassDesc ) ) + { + return NULL; + } + + InstanceContext_t *pInstanceContext = ( InstanceContext_t * )lua_newuserdata( m_LuaState, sizeof( InstanceContext_t ) ); + pInstanceContext->pInstance = pInstance; + pInstanceContext->pClassDesc = pClassDesc; + luaL_getmetatable( m_LuaState, pClassDesc->m_pszScriptName ); + lua_setmetatable( m_LuaState, -2 ); + + Instance = ( HSCRIPT )( intp )luaL_ref( m_LuaState, LUA_REGISTRYINDEX ); + + return Instance; + } + + // stack good + virtual void SetInstanceUniqeId( HSCRIPT hInstance, const char *pszId ) + { +#if 0 + TValue *pValue = ( TValue * )hInstance; + if ( !hInstance ) + { + Assert( 0 ); + return; + } + + Assert( ttislightuserdata( pValue ) ); + InstanceContext_t *pInstanceContext = ( InstanceContext_t * )( pValue->value.p ); + if ( pInstanceContext == NULL ) + { + Assert( 0 ); + return; + } + + lua_getfield( m_LuaState, LUA_REGISTRYINDEX, pInstanceContext->szName ); //-- + strcpy( pInstanceContext->szName, pszId ); + lua_setfield( m_LuaState, LUA_REGISTRYINDEX, pInstanceContext->szName ); //-- +#endif + Assert( 0 ); + } + + // stack good + virtual void RemoveInstance( HSCRIPT hInstance ) + { +#if 0 + TValue *pValue = ( TValue * )hInstance; + if ( !pValue ) + { + Assert( 0 ); + return; + } + + Assert( ttislightuserdata( pValue ) ); + InstanceContext_t *pInstanceContext = ( InstanceContext_t * )( pValue->value.p ); + + lua_pushnil( m_LuaState ); + lua_setfield( m_LuaState, LUA_REGISTRYINDEX, pInstanceContext->szName ); +// lua_pushnil( m_LuaState ); //-- +// lua_setfield( m_LuaState, LUA_GLOBALSINDEX, pInstanceContext->szName ); //-- + + delete pInstanceContext; + delete pValue; +#endif + Assert( 0 ); + } + + virtual void *GetInstanceValue( HSCRIPT hInstance, ScriptClassDesc_t *pExpectedType = NULL ) + { + Assert( 0 ); + return NULL; + } + + virtual bool GenerateUniqueKey( const char *pszRoot, char *pBuf, int nBufSize ) + { + Assert( V_strlen(pszRoot) + 32 <= nBufSize ); + Q_snprintf( pBuf, nBufSize, "_%x%I64x_%s", RandomInt(0, 0xfff), m_iUniqueIdSerialNumber++, pszRoot ); // random to limit key compare when serial number gets large + return true; + } + + // stack good + virtual bool ValueExists( HSCRIPT hScope, const char *pszKey ) + { + Assert( hScope == NULL ); + + lua_getfield( m_LuaState, LUA_GLOBALSINDEX, pszKey ); + bool bResult = ( lua_isnil( m_LuaState, -1 ) == false ); + + lua_pop( m_LuaState, 1 ); + + return bResult; + } + + virtual bool SetValue( HSCRIPT hScope, const char *pszKey, const char *pszValue ) + { + // Not supported yet. + Assert(0); + return false; + } + + // stack good + virtual bool SetValue( HSCRIPT hScope, const char *pszKey, const ScriptVariant_t &value ) + { + if ( hScope ) + { +// Msg( "SetValue: SCOPE %s\n", pszKey ); + lua_rawgeti( m_LuaState, LUA_REGISTRYINDEX, size_cast< int >( ( intp )hScope ) ); + lua_pushstring( m_LuaState, pszKey ); + PushVariant( m_LuaState, value ); + lua_settable( m_LuaState, -3 ); + + lua_pop( m_LuaState, 1 ); + } + else + { +// Msg( "SetValue: NORMAL %s\n", pszKey ); + lua_pushstring( m_LuaState, pszKey ); + PushVariant( m_LuaState, value ); + lua_settable( m_LuaState, LUA_GLOBALSINDEX ); + } + + return true; + } + + virtual bool SetValue( HSCRIPT hScope, int nIndex, const ScriptVariant_t &value ) + { + Assert( hScope ); + + lua_rawgeti( m_LuaState, LUA_REGISTRYINDEX, size_cast< int >( ( intp )hScope ) ); + lua_pushinteger( m_LuaState, nIndex ); + PushVariant( m_LuaState, value ); + lua_settable( m_LuaState, -3 ); + + return true; + } + + virtual void CreateTable( ScriptVariant_t &Result ) + { + lua_newtable( m_LuaState ); + ConvertToVariant( -1, m_LuaState, &Result ); + } + + // stack good + virtual int GetNumTableEntries( HSCRIPT hScope ) + { + // Should this also check for 0? + if ( hScope == INVALID_HSCRIPT ) + return 0; + + int nCount = 0; + + lua_rawgeti( m_LuaState, LUA_REGISTRYINDEX, size_cast< int >( ( intp )hScope ) ); +// int count = lua_objlen( m_LuaState, -1 ); + + lua_pushnil( m_LuaState ); /* first key */ + while ( lua_next( m_LuaState, -2 ) != 0 ) + { + /* key is at index -2 and value at index -1 */ +// Msg ("%s - %s\n", lua_typename(m_LuaState, lua_type(m_LuaState, -2)), lua_typename(m_LuaState, lua_type(m_LuaState, -1))); + nCount++; + lua_pop( m_LuaState, 1 ); /* removes value; keeps key for next iteration */ + } + + lua_pop( m_LuaState, 1 ); /* removes value; keeps key for next iteration */ + + return nCount; + } + + // stack good + virtual int GetKeyValue( HSCRIPT hScope, int nIterator, ScriptVariant_t *pKey, ScriptVariant_t *pValue ) + { + int nCount = 0; + int nStackSize = GetStackSize(); + + lua_rawgeti( m_LuaState, LUA_REGISTRYINDEX, size_cast< int >( ( intp )hScope ) ); + // int count = lua_objlen( m_LuaState, -1 ); + + lua_pushnil( m_LuaState ); /* first key */ + while ( lua_next( m_LuaState, -2 ) != 0 && nCount < nIterator ) + { + nCount++; + lua_pop( m_LuaState, 1 ); /* removes value; keeps key for next iteration */ + } + +// Msg ("%s - %s\n", lua_typename(m_LuaState, lua_type(m_LuaState, -2)), lua_typename(m_LuaState, lua_type(m_LuaState, -1))); + + ConvertToVariant( -2, m_LuaState, pKey ); + ConvertToVariant( -1, m_LuaState, pValue ); + + lua_pop( m_LuaState, 3 ); /* removes value; keeps key for next iteration */ + + lua_pop( m_LuaState, nStackSize - GetStackSize() ); + + return nCount + 1; + } + + virtual bool GetValue( HSCRIPT hScope, const char *pszKey, ScriptVariant_t *pValue ) + { + int nStackSize = GetStackSize(); + + if ( hScope ) + { + lua_rawgeti( m_LuaState, LUA_REGISTRYINDEX, size_cast< int >( ( intp )hScope ) ); + lua_getfield( m_LuaState, -1, pszKey ); + if ( lua_isnil( m_LuaState, -1 ) ) + { + lua_pop( m_LuaState, nStackSize - GetStackSize() ); + return false; + } + } + else + { + lua_getfield( m_LuaState, LUA_GLOBALSINDEX, pszKey ); + if ( lua_isnil( m_LuaState, -1 ) ) + { + lua_pop( m_LuaState, nStackSize - GetStackSize() ); + return false; + } + } + + ConvertToVariant( -1, m_LuaState, pValue ); + lua_pop( m_LuaState, nStackSize - GetStackSize() ); + + return true; + } + + virtual bool GetValue( HSCRIPT hScope, int nIndex, ScriptVariant_t *pValue ) + { + if ( hScope ) + { + int nStackSize = GetStackSize(); + + lua_rawgeti( m_LuaState, LUA_REGISTRYINDEX, size_cast< int >( ( intp )hScope ) ); + lua_rawgeti( m_LuaState, -1, nIndex ); + if ( lua_isnil( m_LuaState, -1 ) ) + { + lua_pop( m_LuaState, nStackSize - GetStackSize() ); + return false; + } + + ConvertToVariant( -1, m_LuaState, pValue ); + lua_pop( m_LuaState, nStackSize - GetStackSize() ); + + return true; + } + + return false; + } + + virtual void ReleaseValue( ScriptVariant_t &value ) + { + ReleaseVariant( m_LuaState, value ); + } + + virtual bool ClearValue( HSCRIPT hScope, const char *pszKey ) + { + Assert( 0 ); + return false; + } + + virtual void WriteState( CUtlBuffer *pBuffer ) + { + Assert( 0 ); + } + + virtual void ReadState( CUtlBuffer *pBuffer ) + { + Assert( 0 ); + } + + virtual void RemoveOrphanInstances() + { + Assert( 0 ); + } + + virtual void DumpState() + { + Assert( 0 ); + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + virtual bool RaiseException( const char *pszExceptionText ) + { + return true; + } + + virtual void SetOutputCallback( ScriptOutputFunc_t pFunc ) + { + m_OutputFunc = pFunc; + + lua_pushstring( m_LuaState, "print" ); + ScriptOutputFunc_t *pOutputCallback = ( ScriptOutputFunc_t * )lua_newuserdata( m_LuaState, sizeof( ScriptOutputFunc_t ) ); + *pOutputCallback = m_OutputFunc; + lua_pushcclosure( m_LuaState, PrintFunc, 1 ); + lua_settable( m_LuaState, LUA_GLOBALSINDEX ); + } + + virtual void SetErrorCallback( ScriptErrorFunc_t pFunc ) + { + m_ErrorFunc = pFunc; + } +}; + + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +IScriptVM *ScriptCreateLuaVM() +{ + return new CLuaVM; +} + +void ScriptDestroyLuaVM( IScriptVM *pVM ) +{ + CLuaVM *pLuaVM = assert_cast< CLuaVM * >( pVM ); + delete pLuaVM; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +#ifdef VLUA_TEST +CLuaVM g_LuaVM; +IScriptVM *g_pScriptVM = &g_LuaVM; + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#include +#include "fasttimer.h" + +static void FromScript_AddBehavior( const char *pBehaviorName, HSCRIPT hTable ) +{ + ScriptVariant_t KeyVariant, ValueVariant; + + Msg( "Behavior: %s\n", pBehaviorName ); + + int nInterator = 0; + int index = g_pScriptVM->GetNumTableEntries( hTable ); + for( int i = 0; i < index; i++ ) + { + nInterator = g_pScriptVM->GetKeyValue( hTable, nInterator, &KeyVariant, &ValueVariant ); + + Msg( " %d: %s / %s\n", i, KeyVariant.m_pszString, ValueVariant.m_pszString ); + + g_pScriptVM->ReleaseValue( KeyVariant ); + g_pScriptVM->ReleaseValue( ValueVariant ); + } +} + +static Vector MyVectorAdd( Vector A, Vector B ) +{ + return A + B; +} + +void TestOutput( const char *pszText ) +{ + Msg( "%s\n", pszText ); +} + +bool TestError( const char *pszText ) +{ + Msg( "%s\n", pszText ); + + return true; +} + + +class CMyClass +{ +public: + bool Foo( int ); + void Bar( HSCRIPT TableA, HSCRIPT TableB ); + float FooBar( int, const char * ); + float OverlyTechnicalName( bool ); +}; + +bool CMyClass::Foo( int test ) +{ + return true; +} + +void CMyClass::Bar( HSCRIPT TableA, HSCRIPT TableB ) +{ + ScriptVariant_t MyValue; + +// g_pScriptVM->CreateTable( MyTable ); + + MyValue = 10; + g_pScriptVM->SetValue( TableA, 1, MyValue ); + MyValue = 20; + g_pScriptVM->SetValue( TableA, 2, MyValue ); + MyValue = 30; + g_pScriptVM->SetValue( TableA, 3, MyValue ); + + MyValue = 100; + g_pScriptVM->SetValue( TableB, 1, MyValue ); + MyValue = 200; + g_pScriptVM->SetValue( TableB, 2, MyValue ); + MyValue = 300; + g_pScriptVM->SetValue( TableB, 3, MyValue ); + +// return MyTable; +} + +float CMyClass::FooBar( int test1, const char *test2 ) +{ + return 2.34f; +} + +float CMyClass::OverlyTechnicalName( bool test ) +{ + return 4.56f; +} + +BEGIN_SCRIPTDESC_ROOT_NAMED( CMyClass , "CMyClass", SCRIPT_SINGLETON "" ) + DEFINE_SCRIPTFUNC( Foo, "" ) + DEFINE_SCRIPTFUNC( Bar, "" ) + DEFINE_SCRIPTFUNC( FooBar, "" ) + DEFINE_SCRIPTFUNC_NAMED( OverlyTechnicalName, "SimpleMemberName", "" ) +END_SCRIPTDESC(); + +class CMyDerivedClass : public CMyClass +{ +public: + float DerivedFunc() const; +}; + +BEGIN_SCRIPTDESC( CMyDerivedClass, CMyClass, SCRIPT_SINGLETON "" ) + DEFINE_SCRIPTFUNC( DerivedFunc, "" ) +END_SCRIPTDESC(); + +float CMyDerivedClass::DerivedFunc() const +{ + return 8.91f; +} + +CMyDerivedClass derivedInstance; + +void AnotherFunction() +{ + // Manual class exposure + g_pScriptVM->RegisterClass( GetScriptDescForClass( CMyClass ) ); + + // Auto registration by instance + g_pScriptVM->RegisterInstance( &derivedInstance, "theInstance" ); +} + +int main( int argc, const char **argv) +{ + if ( argc < 2 ) + { + printf( "No script specified" ); + return 1; + } + g_pScriptVM->Init(); + + g_pScriptVM->SetOutputCallback( TestOutput ); + g_pScriptVM->SetErrorCallback( TestError ); + + AnotherFunction(); + + CCycleCount count; + count.Sample(); + RandomSeed( time( NULL ) ^ count.GetMicroseconds() ); + ScriptRegisterFunction( g_pScriptVM, RandomFloat, "" ); + ScriptRegisterFunction( g_pScriptVM, RandomInt, "" ); + + ScriptRegisterFunction( g_pScriptVM, FromScript_AddBehavior, "" ); + ScriptRegisterFunction( g_pScriptVM, MyVectorAdd, "" ); + + if ( argc == 3 && *argv[2] == 'd' ) + { + g_pScriptVM->ConnectDebugger(); + } + + int key; + CScriptScope scope; + scope.Init( "TestScope" ); + do + { + const char *pszScript = argv[1]; + FILE *hFile = fopen( pszScript, "rb" ); + if ( !hFile ) + { + printf( "\"%s\" not found.\n", pszScript ); + return 1; + } + + int nFileLen = _filelength( _fileno( hFile ) ); + char *pBuf = new char[nFileLen + 1]; + fread( pBuf, 1, nFileLen, hFile ); + pBuf[nFileLen] = 0; + fclose( hFile ); + + if (1) + { + printf( "Executing script \"%s\"\n----------------------------------------\n", pszScript ); + HSCRIPT hScript = g_pScriptVM->CompileScript( pBuf, ( strrchr( pszScript, '\\' ) ? strrchr( pszScript, '\\' ) + 1 : pszScript ) ); + if ( hScript ) + { + if ( scope.Run( hScript ) != SCRIPT_ERROR ) + { + printf( "----------------------------------------\n" ); + printf("Script complete. Press q to exit, m to dump memory usage, enter to run again.\n"); + } + else + { + printf( "----------------------------------------\n" ); + printf("Script execution error. Press q to exit, m to dump memory usage, enter to run again.\n"); + } + g_pScriptVM->ReleaseScript( hScript ); + } + else + { + printf( "----------------------------------------\n" ); + printf("Script failed to compile. Press q to exit, m to dump memory usage, enter to run again.\n"); + } + } + key = _getch(); // Keypress before exit + if ( key == 'm' ) + { + Msg( "%d\n", g_pMemAlloc->GetSize( NULL ) ); + } + delete pBuf; + } while ( key != 'q' ); + + scope.Term(); +// g_pScriptVM->DisconnectDebugger(); + + g_pScriptVM->Shutdown(); + return 0; +} + +#endif + + +// add a check stack auto class to each function + diff --git a/vscript/languages/lua/vlua/vlua.h b/vscript/languages/lua/vlua/vlua.h new file mode 100644 index 00000000..9fffd6b4 --- /dev/null +++ b/vscript/languages/lua/vlua/vlua.h @@ -0,0 +1,17 @@ +//========== Copyright © 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: +// +//============================================================================= + +#ifndef VLUA_H +#define VLUA_H + +#if defined( _WIN32 ) +#pragma once +#endif + +IScriptVM *ScriptCreateLuaVM(); +void ScriptDestroyLuaVM( IScriptVM *pVM ); + +#endif // VLUA_H diff --git a/vscript/languages/lua/vlua/vlua.vpc b/vscript/languages/lua/vlua/vlua.vpc new file mode 100644 index 00000000..bd9f9544 --- /dev/null +++ b/vscript/languages/lua/vlua/vlua.vpc @@ -0,0 +1,122 @@ +//----------------------------------------------------------------------------- +// Project Script +//----------------------------------------------------------------------------- + +$Macro SRCDIR "..\..\..\.." +$Macro OUTBINDIR "." + +$Include "$SRCDIR\vpc_scripts\source_exe_con_win32_base.vpc" + +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE,..\lua-5.1.4\src\" + $PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE;VLUA_TEST;MSVC" + } +} + +$Project "vlua" +{ + $Folder "Source Files" + { + $File "..\..\..\..\public\vscript\ivscript.h" + $File "..\..\..\..\public\vscript\vscript_templates.h" + $File "vlua.cpp" + { + $Configuration + { + $Compiler + { + // "SQPlus" need exceptions. If commit to squirrel, look into removing that + $AdditionalOptions "/EHa" + } + } + } + $File "vec3.cpp" + $File "vec3.h" + } + + $Folder "Lua" + { + $Folder "lua-5.1.4" + { + $Folder "Source Files" + { + $File "..\lua-5.1.4\src\lapi.c" \ + "..\lua-5.1.4\src\lauxlib.c" \ + "..\lua-5.1.4\src\lbaselib.c" \ + "..\lua-5.1.4\src\lcode.c" \ + "..\lua-5.1.4\src\ldblib.c" \ + "..\lua-5.1.4\src\ldebug.c" \ + "..\lua-5.1.4\src\ldo.c" \ + "..\lua-5.1.4\src\ldump.c" \ + "..\lua-5.1.4\src\lfunc.c" \ + "..\lua-5.1.4\src\lgc.c" \ + "..\lua-5.1.4\src\linit.c" \ + "..\lua-5.1.4\src\liolib.c" \ + "..\lua-5.1.4\src\llex.c" \ + "..\lua-5.1.4\src\lmathlib.c" \ + "..\lua-5.1.4\src\lmem.c" \ + "..\lua-5.1.4\src\loadlib.c" \ + "..\lua-5.1.4\src\lobject.c" \ + "..\lua-5.1.4\src\lopcodes.c" \ + "..\lua-5.1.4\src\loslib.c" \ + "..\lua-5.1.4\src\lparser.c" \ + "..\lua-5.1.4\src\lstate.c" \ + "..\lua-5.1.4\src\lstring.c" \ + "..\lua-5.1.4\src\lstrlib.c" \ + "..\lua-5.1.4\src\ltable.c" \ + "..\lua-5.1.4\src\ltablib.c" \ + "..\lua-5.1.4\src\ltm.c" \ + "..\lua-5.1.4\src\lundump.c" \ + "..\lua-5.1.4\src\lvm.c" \ + "..\lua-5.1.4\src\lzio.c" \ + "..\lua-5.1.4\src\print.c" + { + $Configuration + { + $Compiler + { + $WarningLevel "Level 3 (/W3)" + $Detect64bitPortabilityIssues "No" + $CompileAs "Default" + } + } + } + } + $Folder "Header Files" + { + $File "..\lua-5.1.4\src\lapi.h" \ + "..\lua-5.1.4\src\lauxlib.h" \ + "..\lua-5.1.4\src\lcode.h" \ + "..\lua-5.1.4\src\ldebug.h" \ + "..\lua-5.1.4\src\ldo.h" \ + "..\lua-5.1.4\src\lfunc.h" \ + "..\lua-5.1.4\src\lgc.h" \ + "..\lua-5.1.4\src\llex.h" \ + "..\lua-5.1.4\src\llimits.h" \ + "..\lua-5.1.4\src\lmem.h" \ + "..\lua-5.1.4\src\lobject.h" \ + "..\lua-5.1.4\src\lopcodes.h" \ + "..\lua-5.1.4\src\lparser.h" \ + "..\lua-5.1.4\src\lstate.h" \ + "..\lua-5.1.4\src\lstring.h" \ + "..\lua-5.1.4\src\ltable.h" \ + "..\lua-5.1.4\src\ltm.h" \ + "..\lua-5.1.4\src\lua.h" \ + "..\lua-5.1.4\src\luaconf.h" \ + "..\lua-5.1.4\src\lualib.h" \ + "..\lua-5.1.4\src\lundump.h" \ + "..\lua-5.1.4\src\lvm.h" \ + "..\lua-5.1.4\src\lzio.h" + } + } + } + + $Folder "Link Libraries" + { + $File "$SRCDIR\lib\public\mathlib.lib" + } +} + diff --git a/vscript/languages/python/python-2.5.1/include/abstract.h b/vscript/languages/python/python-2.5.1/include/abstract.h new file mode 100644 index 00000000..14510c6a --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/abstract.h @@ -0,0 +1,1276 @@ +#ifndef Py_ABSTRACTOBJECT_H +#define Py_ABSTRACTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef PY_SSIZE_T_CLEAN +#define PyObject_CallFunction _PyObject_CallFunction_SizeT +#define PyObject_CallMethod _PyObject_CallMethod_SizeT +#endif + +/* Abstract Object Interface (many thanks to Jim Fulton) */ + +/* + PROPOSAL: A Generic Python Object Interface for Python C Modules + +Problem + + Python modules written in C that must access Python objects must do + so through routines whose interfaces are described by a set of + include files. Unfortunately, these routines vary according to the + object accessed. To use these routines, the C programmer must check + the type of the object being used and must call a routine based on + the object type. For example, to access an element of a sequence, + the programmer must determine whether the sequence is a list or a + tuple: + + if(is_tupleobject(o)) + e=gettupleitem(o,i) + else if(is_listitem(o)) + e=getlistitem(o,i) + + If the programmer wants to get an item from another type of object + that provides sequence behavior, there is no clear way to do it + correctly. + + The persistent programmer may peruse object.h and find that the + _typeobject structure provides a means of invoking up to (currently + about) 41 special operators. So, for example, a routine can get an + item from any object that provides sequence behavior. However, to + use this mechanism, the programmer must make their code dependent on + the current Python implementation. + + Also, certain semantics, especially memory management semantics, may + differ by the type of object being used. Unfortunately, these + semantics are not clearly described in the current include files. + An abstract interface providing more consistent semantics is needed. + +Proposal + + I propose the creation of a standard interface (with an associated + library of routines and/or macros) for generically obtaining the + services of Python objects. This proposal can be viewed as one + components of a Python C interface consisting of several components. + + From the viewpoint of C access to Python services, we have (as + suggested by Guido in off-line discussions): + + - "Very high level layer": two or three functions that let you exec or + eval arbitrary Python code given as a string in a module whose name is + given, passing C values in and getting C values out using + mkvalue/getargs style format strings. This does not require the user + to declare any variables of type "PyObject *". This should be enough + to write a simple application that gets Python code from the user, + execs it, and returns the output or errors. (Error handling must also + be part of this API.) + + - "Abstract objects layer": which is the subject of this proposal. + It has many functions operating on objects, and lest you do many + things from C that you can also write in Python, without going + through the Python parser. + + - "Concrete objects layer": This is the public type-dependent + interface provided by the standard built-in types, such as floats, + strings, and lists. This interface exists and is currently + documented by the collection of include files provided with the + Python distributions. + + From the point of view of Python accessing services provided by C + modules: + + - "Python module interface": this interface consist of the basic + routines used to define modules and their members. Most of the + current extensions-writing guide deals with this interface. + + - "Built-in object interface": this is the interface that a new + built-in type must provide and the mechanisms and rules that a + developer of a new built-in type must use and follow. + + This proposal is a "first-cut" that is intended to spur + discussion. See especially the lists of notes. + + The Python C object interface will provide four protocols: object, + numeric, sequence, and mapping. Each protocol consists of a + collection of related operations. If an operation that is not + provided by a particular type is invoked, then a standard exception, + NotImplementedError is raised with a operation name as an argument. + In addition, for convenience this interface defines a set of + constructors for building objects of built-in types. This is needed + so new objects can be returned from C functions that otherwise treat + objects generically. + +Memory Management + + For all of the functions described in this proposal, if a function + retains a reference to a Python object passed as an argument, then the + function will increase the reference count of the object. It is + unnecessary for the caller to increase the reference count of an + argument in anticipation of the object's retention. + + All Python objects returned from functions should be treated as new + objects. Functions that return objects assume that the caller will + retain a reference and the reference count of the object has already + been incremented to account for this fact. A caller that does not + retain a reference to an object that is returned from a function + must decrement the reference count of the object (using + DECREF(object)) to prevent memory leaks. + + Note that the behavior mentioned here is different from the current + behavior for some objects (e.g. lists and tuples) when certain + type-specific routines are called directly (e.g. setlistitem). The + proposed abstraction layer will provide a consistent memory + management interface, correcting for inconsistent behavior for some + built-in types. + +Protocols + +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ + +/* Object Protocol: */ + + /* Implemented elsewhere: + + int PyObject_Print(PyObject *o, FILE *fp, int flags); + + Print an object, o, on file, fp. Returns -1 on + error. The flags argument is used to enable certain printing + options. The only option currently supported is Py_Print_RAW. + + (What should be said about Py_Print_RAW?) + + */ + + /* Implemented elsewhere: + + int PyObject_HasAttrString(PyObject *o, char *attr_name); + + Returns 1 if o has the attribute attr_name, and 0 otherwise. + This is equivalent to the Python expression: + hasattr(o,attr_name). + + This function always succeeds. + + */ + + /* Implemented elsewhere: + + PyObject* PyObject_GetAttrString(PyObject *o, char *attr_name); + + Retrieve an attributed named attr_name form object o. + Returns the attribute value on success, or NULL on failure. + This is the equivalent of the Python expression: o.attr_name. + + */ + + /* Implemented elsewhere: + + int PyObject_HasAttr(PyObject *o, PyObject *attr_name); + + Returns 1 if o has the attribute attr_name, and 0 otherwise. + This is equivalent to the Python expression: + hasattr(o,attr_name). + + This function always succeeds. + + */ + + /* Implemented elsewhere: + + PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name); + + Retrieve an attributed named attr_name form object o. + Returns the attribute value on success, or NULL on failure. + This is the equivalent of the Python expression: o.attr_name. + + */ + + + /* Implemented elsewhere: + + int PyObject_SetAttrString(PyObject *o, char *attr_name, PyObject *v); + + Set the value of the attribute named attr_name, for object o, + to the value, v. Returns -1 on failure. This is + the equivalent of the Python statement: o.attr_name=v. + + */ + + /* Implemented elsewhere: + + int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v); + + Set the value of the attribute named attr_name, for object o, + to the value, v. Returns -1 on failure. This is + the equivalent of the Python statement: o.attr_name=v. + + */ + + /* implemented as a macro: + + int PyObject_DelAttrString(PyObject *o, char *attr_name); + + Delete attribute named attr_name, for object o. Returns + -1 on failure. This is the equivalent of the Python + statement: del o.attr_name. + + */ +#define PyObject_DelAttrString(O,A) PyObject_SetAttrString((O),(A),NULL) + + /* implemented as a macro: + + int PyObject_DelAttr(PyObject *o, PyObject *attr_name); + + Delete attribute named attr_name, for object o. Returns -1 + on failure. This is the equivalent of the Python + statement: del o.attr_name. + + */ +#define PyObject_DelAttr(O,A) PyObject_SetAttr((O),(A),NULL) + + PyAPI_FUNC(int) PyObject_Cmp(PyObject *o1, PyObject *o2, int *result); + + /* + Compare the values of o1 and o2 using a routine provided by + o1, if one exists, otherwise with a routine provided by o2. + The result of the comparison is returned in result. Returns + -1 on failure. This is the equivalent of the Python + statement: result=cmp(o1,o2). + + */ + + /* Implemented elsewhere: + + int PyObject_Compare(PyObject *o1, PyObject *o2); + + Compare the values of o1 and o2 using a routine provided by + o1, if one exists, otherwise with a routine provided by o2. + Returns the result of the comparison on success. On error, + the value returned is undefined. This is equivalent to the + Python expression: cmp(o1,o2). + + */ + + /* Implemented elsewhere: + + PyObject *PyObject_Repr(PyObject *o); + + Compute the string representation of object, o. Returns the + string representation on success, NULL on failure. This is + the equivalent of the Python expression: repr(o). + + Called by the repr() built-in function and by reverse quotes. + + */ + + /* Implemented elsewhere: + + PyObject *PyObject_Str(PyObject *o); + + Compute the string representation of object, o. Returns the + string representation on success, NULL on failure. This is + the equivalent of the Python expression: str(o).) + + Called by the str() built-in function and by the print + statement. + + */ + + /* Implemented elsewhere: + + PyObject *PyObject_Unicode(PyObject *o); + + Compute the unicode representation of object, o. Returns the + unicode representation on success, NULL on failure. This is + the equivalent of the Python expression: unistr(o).) + + Called by the unistr() built-in function. + + */ + + /* Declared elsewhere + + PyAPI_FUNC(int) PyCallable_Check(PyObject *o); + + Determine if the object, o, is callable. Return 1 if the + object is callable and 0 otherwise. + + This function always succeeds. + + */ + + + + PyAPI_FUNC(PyObject *) PyObject_Call(PyObject *callable_object, + PyObject *args, PyObject *kw); + + /* + Call a callable Python object, callable_object, with + arguments and keywords arguments. The 'args' argument can not be + NULL, but the 'kw' argument can be NULL. + + */ + + PyAPI_FUNC(PyObject *) PyObject_CallObject(PyObject *callable_object, + PyObject *args); + + /* + Call a callable Python object, callable_object, with + arguments given by the tuple, args. If no arguments are + needed, then args may be NULL. Returns the result of the + call on success, or NULL on failure. This is the equivalent + of the Python expression: apply(o,args). + + */ + + PyAPI_FUNC(PyObject *) PyObject_CallFunction(PyObject *callable_object, + char *format, ...); + + /* + Call a callable Python object, callable_object, with a + variable number of C arguments. The C arguments are described + using a mkvalue-style format string. The format may be NULL, + indicating that no arguments are provided. Returns the + result of the call on success, or NULL on failure. This is + the equivalent of the Python expression: apply(o,args). + + */ + + + PyAPI_FUNC(PyObject *) PyObject_CallMethod(PyObject *o, char *m, + char *format, ...); + + /* + Call the method named m of object o with a variable number of + C arguments. The C arguments are described by a mkvalue + format string. The format may be NULL, indicating that no + arguments are provided. Returns the result of the call on + success, or NULL on failure. This is the equivalent of the + Python expression: o.method(args). + */ + + PyAPI_FUNC(PyObject *) _PyObject_CallFunction_SizeT(PyObject *callable, + char *format, ...); + PyAPI_FUNC(PyObject *) _PyObject_CallMethod_SizeT(PyObject *o, + char *name, + char *format, ...); + + PyAPI_FUNC(PyObject *) PyObject_CallFunctionObjArgs(PyObject *callable, + ...); + + /* + Call a callable Python object, callable_object, with a + variable number of C arguments. The C arguments are provided + as PyObject * values, terminated by a NULL. Returns the + result of the call on success, or NULL on failure. This is + the equivalent of the Python expression: apply(o,args). + */ + + + PyAPI_FUNC(PyObject *) PyObject_CallMethodObjArgs(PyObject *o, + PyObject *m, ...); + + /* + Call the method named m of object o with a variable number of + C arguments. The C arguments are provided as PyObject * + values, terminated by NULL. Returns the result of the call + on success, or NULL on failure. This is the equivalent of + the Python expression: o.method(args). + */ + + + /* Implemented elsewhere: + + long PyObject_Hash(PyObject *o); + + Compute and return the hash, hash_value, of an object, o. On + failure, return -1. This is the equivalent of the Python + expression: hash(o). + + */ + + + /* Implemented elsewhere: + + int PyObject_IsTrue(PyObject *o); + + Returns 1 if the object, o, is considered to be true, 0 if o is + considered to be false and -1 on failure. This is equivalent to the + Python expression: not not o + + */ + + /* Implemented elsewhere: + + int PyObject_Not(PyObject *o); + + Returns 0 if the object, o, is considered to be true, 1 if o is + considered to be false and -1 on failure. This is equivalent to the + Python expression: not o + + */ + + PyAPI_FUNC(PyObject *) PyObject_Type(PyObject *o); + + /* + On success, returns a type object corresponding to the object + type of object o. On failure, returns NULL. This is + equivalent to the Python expression: type(o). + */ + + PyAPI_FUNC(Py_ssize_t) PyObject_Size(PyObject *o); + + /* + Return the size of object o. If the object, o, provides + both sequence and mapping protocols, the sequence size is + returned. On error, -1 is returned. This is the equivalent + to the Python expression: len(o). + + */ + + /* For DLL compatibility */ +#undef PyObject_Length + PyAPI_FUNC(Py_ssize_t) PyObject_Length(PyObject *o); +#define PyObject_Length PyObject_Size + + PyAPI_FUNC(Py_ssize_t) _PyObject_LengthHint(PyObject *o); + + /* + Return the size of object o. If the object, o, provides + both sequence and mapping protocols, the sequence size is + returned. On error, -1 is returned. If the object provides + a __length_hint__() method, its value is returned. This is an + internal undocumented API provided for performance reasons; + for compatibility, don't use it outside the core. This is the + equivalent to the Python expression: + try: + return len(o) + except (AttributeError, TypeError): + exc_type, exc_value, exc_tb = sys.exc_info() + try: + return o.__length_hint__() + except: + pass + raise exc_type, exc_value, exc_tb + */ + + PyAPI_FUNC(PyObject *) PyObject_GetItem(PyObject *o, PyObject *key); + + /* + Return element of o corresponding to the object, key, or NULL + on failure. This is the equivalent of the Python expression: + o[key]. + + */ + + PyAPI_FUNC(int) PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v); + + /* + Map the object, key, to the value, v. Returns + -1 on failure. This is the equivalent of the Python + statement: o[key]=v. + */ + + PyAPI_FUNC(int) PyObject_DelItemString(PyObject *o, char *key); + + /* + Remove the mapping for object, key, from the object *o. + Returns -1 on failure. This is equivalent to + the Python statement: del o[key]. + */ + + PyAPI_FUNC(int) PyObject_DelItem(PyObject *o, PyObject *key); + + /* + Delete the mapping for key from *o. Returns -1 on failure. + This is the equivalent of the Python statement: del o[key]. + */ + + PyAPI_FUNC(int) PyObject_AsCharBuffer(PyObject *obj, + const char **buffer, + Py_ssize_t *buffer_len); + + /* + Takes an arbitrary object which must support the (character, + single segment) buffer interface and returns a pointer to a + read-only memory location useable as character based input + for subsequent processing. + + 0 is returned on success. buffer and buffer_len are only + set in case no error occurs. Otherwise, -1 is returned and + an exception set. + + */ + + PyAPI_FUNC(int) PyObject_CheckReadBuffer(PyObject *obj); + + /* + Checks whether an arbitrary object supports the (character, + single segment) buffer interface. Returns 1 on success, 0 + on failure. + + */ + + PyAPI_FUNC(int) PyObject_AsReadBuffer(PyObject *obj, + const void **buffer, + Py_ssize_t *buffer_len); + + /* + Same as PyObject_AsCharBuffer() except that this API expects + (readable, single segment) buffer interface and returns a + pointer to a read-only memory location which can contain + arbitrary data. + + 0 is returned on success. buffer and buffer_len are only + set in case no error occurrs. Otherwise, -1 is returned and + an exception set. + + */ + + PyAPI_FUNC(int) PyObject_AsWriteBuffer(PyObject *obj, + void **buffer, + Py_ssize_t *buffer_len); + + /* + Takes an arbitrary object which must support the (writeable, + single segment) buffer interface and returns a pointer to a + writeable memory location in buffer of size buffer_len. + + 0 is returned on success. buffer and buffer_len are only + set in case no error occurrs. Otherwise, -1 is returned and + an exception set. + + */ + +/* Iterators */ + + PyAPI_FUNC(PyObject *) PyObject_GetIter(PyObject *); + /* Takes an object and returns an iterator for it. + This is typically a new iterator but if the argument + is an iterator, this returns itself. */ + +#define PyIter_Check(obj) \ + (PyType_HasFeature((obj)->ob_type, Py_TPFLAGS_HAVE_ITER) && \ + (obj)->ob_type->tp_iternext != NULL) + + PyAPI_FUNC(PyObject *) PyIter_Next(PyObject *); + /* Takes an iterator object and calls its tp_iternext slot, + returning the next value. If the iterator is exhausted, + this returns NULL without setting an exception. + NULL with an exception means an error occurred. */ + +/* Number Protocol:*/ + + PyAPI_FUNC(int) PyNumber_Check(PyObject *o); + + /* + Returns 1 if the object, o, provides numeric protocols, and + false otherwise. + + This function always succeeds. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Add(PyObject *o1, PyObject *o2); + + /* + Returns the result of adding o1 and o2, or null on failure. + This is the equivalent of the Python expression: o1+o2. + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Subtract(PyObject *o1, PyObject *o2); + + /* + Returns the result of subtracting o2 from o1, or null on + failure. This is the equivalent of the Python expression: + o1-o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Multiply(PyObject *o1, PyObject *o2); + + /* + Returns the result of multiplying o1 and o2, or null on + failure. This is the equivalent of the Python expression: + o1*o2. + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Divide(PyObject *o1, PyObject *o2); + + /* + Returns the result of dividing o1 by o2, or null on failure. + This is the equivalent of the Python expression: o1/o2. + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_FloorDivide(PyObject *o1, PyObject *o2); + + /* + Returns the result of dividing o1 by o2 giving an integral result, + or null on failure. + This is the equivalent of the Python expression: o1//o2. + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_TrueDivide(PyObject *o1, PyObject *o2); + + /* + Returns the result of dividing o1 by o2 giving a float result, + or null on failure. + This is the equivalent of the Python expression: o1/o2. + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Remainder(PyObject *o1, PyObject *o2); + + /* + Returns the remainder of dividing o1 by o2, or null on + failure. This is the equivalent of the Python expression: + o1%o2. + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Divmod(PyObject *o1, PyObject *o2); + + /* + See the built-in function divmod. Returns NULL on failure. + This is the equivalent of the Python expression: + divmod(o1,o2). + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Power(PyObject *o1, PyObject *o2, + PyObject *o3); + + /* + See the built-in function pow. Returns NULL on failure. + This is the equivalent of the Python expression: + pow(o1,o2,o3), where o3 is optional. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Negative(PyObject *o); + + /* + Returns the negation of o on success, or null on failure. + This is the equivalent of the Python expression: -o. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Positive(PyObject *o); + + /* + Returns the (what?) of o on success, or NULL on failure. + This is the equivalent of the Python expression: +o. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Absolute(PyObject *o); + + /* + Returns the absolute value of o, or null on failure. This is + the equivalent of the Python expression: abs(o). + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Invert(PyObject *o); + + /* + Returns the bitwise negation of o on success, or NULL on + failure. This is the equivalent of the Python expression: + ~o. + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Lshift(PyObject *o1, PyObject *o2); + + /* + Returns the result of left shifting o1 by o2 on success, or + NULL on failure. This is the equivalent of the Python + expression: o1 << o2. + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Rshift(PyObject *o1, PyObject *o2); + + /* + Returns the result of right shifting o1 by o2 on success, or + NULL on failure. This is the equivalent of the Python + expression: o1 >> o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_And(PyObject *o1, PyObject *o2); + + /* + Returns the result of bitwise and of o1 and o2 on success, or + NULL on failure. This is the equivalent of the Python + expression: o1&o2. + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Xor(PyObject *o1, PyObject *o2); + + /* + Returns the bitwise exclusive or of o1 by o2 on success, or + NULL on failure. This is the equivalent of the Python + expression: o1^o2. + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Or(PyObject *o1, PyObject *o2); + + /* + Returns the result of bitwise or on o1 and o2 on success, or + NULL on failure. This is the equivalent of the Python + expression: o1|o2. + + */ + + /* Implemented elsewhere: + + int PyNumber_Coerce(PyObject **p1, PyObject **p2); + + This function takes the addresses of two variables of type + PyObject*. + + If the objects pointed to by *p1 and *p2 have the same type, + increment their reference count and return 0 (success). + If the objects can be converted to a common numeric type, + replace *p1 and *p2 by their converted value (with 'new' + reference counts), and return 0. + If no conversion is possible, or if some other error occurs, + return -1 (failure) and don't increment the reference counts. + The call PyNumber_Coerce(&o1, &o2) is equivalent to the Python + statement o1, o2 = coerce(o1, o2). + + */ + +#define PyIndex_Check(obj) \ + ((obj)->ob_type->tp_as_number != NULL && \ + PyType_HasFeature((obj)->ob_type, Py_TPFLAGS_HAVE_INDEX) && \ + (obj)->ob_type->tp_as_number->nb_index != NULL) + + PyAPI_FUNC(PyObject *) PyNumber_Index(PyObject *o); + + /* + Returns the object converted to a Python long or int + or NULL with an error raised on failure. + */ + + PyAPI_FUNC(Py_ssize_t) PyNumber_AsSsize_t(PyObject *o, PyObject *exc); + + /* + Returns the object converted to Py_ssize_t by going through + PyNumber_Index first. If an overflow error occurs while + converting the int-or-long to Py_ssize_t, then the second argument + is the error-type to return. If it is NULL, then the overflow error + is cleared and the value is clipped. + */ + + PyAPI_FUNC(PyObject *) PyNumber_Int(PyObject *o); + + /* + Returns the o converted to an integer object on success, or + NULL on failure. This is the equivalent of the Python + expression: int(o). + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Long(PyObject *o); + + /* + Returns the o converted to a long integer object on success, + or NULL on failure. This is the equivalent of the Python + expression: long(o). + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Float(PyObject *o); + + /* + Returns the o converted to a float object on success, or NULL + on failure. This is the equivalent of the Python expression: + float(o). + */ + +/* In-place variants of (some of) the above number protocol functions */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceAdd(PyObject *o1, PyObject *o2); + + /* + Returns the result of adding o2 to o1, possibly in-place, or null + on failure. This is the equivalent of the Python expression: + o1 += o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceSubtract(PyObject *o1, PyObject *o2); + + /* + Returns the result of subtracting o2 from o1, possibly in-place or + null on failure. This is the equivalent of the Python expression: + o1 -= o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceMultiply(PyObject *o1, PyObject *o2); + + /* + Returns the result of multiplying o1 by o2, possibly in-place, or + null on failure. This is the equivalent of the Python expression: + o1 *= o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceDivide(PyObject *o1, PyObject *o2); + + /* + Returns the result of dividing o1 by o2, possibly in-place, or null + on failure. This is the equivalent of the Python expression: + o1 /= o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceFloorDivide(PyObject *o1, + PyObject *o2); + + /* + Returns the result of dividing o1 by o2 giving an integral result, + possibly in-place, or null on failure. + This is the equivalent of the Python expression: + o1 /= o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceTrueDivide(PyObject *o1, + PyObject *o2); + + /* + Returns the result of dividing o1 by o2 giving a float result, + possibly in-place, or null on failure. + This is the equivalent of the Python expression: + o1 /= o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2); + + /* + Returns the remainder of dividing o1 by o2, possibly in-place, or + null on failure. This is the equivalent of the Python expression: + o1 %= o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlacePower(PyObject *o1, PyObject *o2, + PyObject *o3); + + /* + Returns the result of raising o1 to the power of o2, possibly + in-place, or null on failure. This is the equivalent of the Python + expression: o1 **= o2, or pow(o1, o2, o3) if o3 is present. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceLshift(PyObject *o1, PyObject *o2); + + /* + Returns the result of left shifting o1 by o2, possibly in-place, or + null on failure. This is the equivalent of the Python expression: + o1 <<= o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceRshift(PyObject *o1, PyObject *o2); + + /* + Returns the result of right shifting o1 by o2, possibly in-place or + null on failure. This is the equivalent of the Python expression: + o1 >>= o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceAnd(PyObject *o1, PyObject *o2); + + /* + Returns the result of bitwise and of o1 and o2, possibly in-place, + or null on failure. This is the equivalent of the Python + expression: o1 &= o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceXor(PyObject *o1, PyObject *o2); + + /* + Returns the bitwise exclusive or of o1 by o2, possibly in-place, or + null on failure. This is the equivalent of the Python expression: + o1 ^= o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceOr(PyObject *o1, PyObject *o2); + + /* + Returns the result of bitwise or of o1 and o2, possibly in-place, + or null on failure. This is the equivalent of the Python + expression: o1 |= o2. + + */ + + +/* Sequence protocol:*/ + + PyAPI_FUNC(int) PySequence_Check(PyObject *o); + + /* + Return 1 if the object provides sequence protocol, and zero + otherwise. + + This function always succeeds. + + */ + + PyAPI_FUNC(Py_ssize_t) PySequence_Size(PyObject *o); + + /* + Return the size of sequence object o, or -1 on failure. + + */ + + /* For DLL compatibility */ +#undef PySequence_Length + PyAPI_FUNC(Py_ssize_t) PySequence_Length(PyObject *o); +#define PySequence_Length PySequence_Size + + + PyAPI_FUNC(PyObject *) PySequence_Concat(PyObject *o1, PyObject *o2); + + /* + Return the concatenation of o1 and o2 on success, and NULL on + failure. This is the equivalent of the Python + expression: o1+o2. + + */ + + PyAPI_FUNC(PyObject *) PySequence_Repeat(PyObject *o, Py_ssize_t count); + + /* + Return the result of repeating sequence object o count times, + or NULL on failure. This is the equivalent of the Python + expression: o1*count. + + */ + + PyAPI_FUNC(PyObject *) PySequence_GetItem(PyObject *o, Py_ssize_t i); + + /* + Return the ith element of o, or NULL on failure. This is the + equivalent of the Python expression: o[i]. + */ + + PyAPI_FUNC(PyObject *) PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2); + + /* + Return the slice of sequence object o between i1 and i2, or + NULL on failure. This is the equivalent of the Python + expression: o[i1:i2]. + + */ + + PyAPI_FUNC(int) PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v); + + /* + Assign object v to the ith element of o. Returns + -1 on failure. This is the equivalent of the Python + statement: o[i]=v. + + */ + + PyAPI_FUNC(int) PySequence_DelItem(PyObject *o, Py_ssize_t i); + + /* + Delete the ith element of object v. Returns + -1 on failure. This is the equivalent of the Python + statement: del o[i]. + */ + + PyAPI_FUNC(int) PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2, + PyObject *v); + + /* + Assign the sequence object, v, to the slice in sequence + object, o, from i1 to i2. Returns -1 on failure. This is the + equivalent of the Python statement: o[i1:i2]=v. + */ + + PyAPI_FUNC(int) PySequence_DelSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2); + + /* + Delete the slice in sequence object, o, from i1 to i2. + Returns -1 on failure. This is the equivalent of the Python + statement: del o[i1:i2]. + */ + + PyAPI_FUNC(PyObject *) PySequence_Tuple(PyObject *o); + + /* + Returns the sequence, o, as a tuple on success, and NULL on failure. + This is equivalent to the Python expression: tuple(o) + */ + + + PyAPI_FUNC(PyObject *) PySequence_List(PyObject *o); + /* + Returns the sequence, o, as a list on success, and NULL on failure. + This is equivalent to the Python expression: list(o) + */ + + PyAPI_FUNC(PyObject *) PySequence_Fast(PyObject *o, const char* m); + /* + Returns the sequence, o, as a tuple, unless it's already a + tuple or list. Use PySequence_Fast_GET_ITEM to access the + members of this list, and PySequence_Fast_GET_SIZE to get its length. + + Returns NULL on failure. If the object does not support iteration, + raises a TypeError exception with m as the message text. + */ + +#define PySequence_Fast_GET_SIZE(o) \ + (PyList_Check(o) ? PyList_GET_SIZE(o) : PyTuple_GET_SIZE(o)) + /* + Return the size of o, assuming that o was returned by + PySequence_Fast and is not NULL. + */ + +#define PySequence_Fast_GET_ITEM(o, i)\ + (PyList_Check(o) ? PyList_GET_ITEM(o, i) : PyTuple_GET_ITEM(o, i)) + /* + Return the ith element of o, assuming that o was returned by + PySequence_Fast, and that i is within bounds. + */ + +#define PySequence_ITEM(o, i)\ + ( o->ob_type->tp_as_sequence->sq_item(o, i) ) + /* Assume tp_as_sequence and sq_item exist and that i does not + need to be corrected for a negative index + */ + +#define PySequence_Fast_ITEMS(sf) \ + (PyList_Check(sf) ? ((PyListObject *)(sf))->ob_item \ + : ((PyTupleObject *)(sf))->ob_item) + /* Return a pointer to the underlying item array for + an object retured by PySequence_Fast */ + + PyAPI_FUNC(Py_ssize_t) PySequence_Count(PyObject *o, PyObject *value); + + /* + Return the number of occurrences on value on o, that is, + return the number of keys for which o[key]==value. On + failure, return -1. This is equivalent to the Python + expression: o.count(value). + */ + + PyAPI_FUNC(int) PySequence_Contains(PyObject *seq, PyObject *ob); + /* + Return -1 if error; 1 if ob in seq; 0 if ob not in seq. + Use __contains__ if possible, else _PySequence_IterSearch(). + */ + +#define PY_ITERSEARCH_COUNT 1 +#define PY_ITERSEARCH_INDEX 2 +#define PY_ITERSEARCH_CONTAINS 3 + PyAPI_FUNC(Py_ssize_t) _PySequence_IterSearch(PyObject *seq, + PyObject *obj, int operation); + /* + Iterate over seq. Result depends on the operation: + PY_ITERSEARCH_COUNT: return # of times obj appears in seq; -1 if + error. + PY_ITERSEARCH_INDEX: return 0-based index of first occurrence of + obj in seq; set ValueError and return -1 if none found; + also return -1 on error. + PY_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on + error. + */ + +/* For DLL-level backwards compatibility */ +#undef PySequence_In + PyAPI_FUNC(int) PySequence_In(PyObject *o, PyObject *value); + +/* For source-level backwards compatibility */ +#define PySequence_In PySequence_Contains + + /* + Determine if o contains value. If an item in o is equal to + X, return 1, otherwise return 0. On error, return -1. This + is equivalent to the Python expression: value in o. + */ + + PyAPI_FUNC(Py_ssize_t) PySequence_Index(PyObject *o, PyObject *value); + + /* + Return the first index for which o[i]=value. On error, + return -1. This is equivalent to the Python + expression: o.index(value). + */ + +/* In-place versions of some of the above Sequence functions. */ + + PyAPI_FUNC(PyObject *) PySequence_InPlaceConcat(PyObject *o1, PyObject *o2); + + /* + Append o2 to o1, in-place when possible. Return the resulting + object, which could be o1, or NULL on failure. This is the + equivalent of the Python expression: o1 += o2. + + */ + + PyAPI_FUNC(PyObject *) PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count); + + /* + Repeat o1 by count, in-place when possible. Return the resulting + object, which could be o1, or NULL on failure. This is the + equivalent of the Python expression: o1 *= count. + + */ + +/* Mapping protocol:*/ + + PyAPI_FUNC(int) PyMapping_Check(PyObject *o); + + /* + Return 1 if the object provides mapping protocol, and zero + otherwise. + + This function always succeeds. + */ + + PyAPI_FUNC(Py_ssize_t) PyMapping_Size(PyObject *o); + + /* + Returns the number of keys in object o on success, and -1 on + failure. For objects that do not provide sequence protocol, + this is equivalent to the Python expression: len(o). + */ + + /* For DLL compatibility */ +#undef PyMapping_Length + PyAPI_FUNC(Py_ssize_t) PyMapping_Length(PyObject *o); +#define PyMapping_Length PyMapping_Size + + + /* implemented as a macro: + + int PyMapping_DelItemString(PyObject *o, char *key); + + Remove the mapping for object, key, from the object *o. + Returns -1 on failure. This is equivalent to + the Python statement: del o[key]. + */ +#define PyMapping_DelItemString(O,K) PyObject_DelItemString((O),(K)) + + /* implemented as a macro: + + int PyMapping_DelItem(PyObject *o, PyObject *key); + + Remove the mapping for object, key, from the object *o. + Returns -1 on failure. This is equivalent to + the Python statement: del o[key]. + */ +#define PyMapping_DelItem(O,K) PyObject_DelItem((O),(K)) + + PyAPI_FUNC(int) PyMapping_HasKeyString(PyObject *o, char *key); + + /* + On success, return 1 if the mapping object has the key, key, + and 0 otherwise. This is equivalent to the Python expression: + o.has_key(key). + + This function always succeeds. + */ + + PyAPI_FUNC(int) PyMapping_HasKey(PyObject *o, PyObject *key); + + /* + Return 1 if the mapping object has the key, key, + and 0 otherwise. This is equivalent to the Python expression: + o.has_key(key). + + This function always succeeds. + + */ + + /* Implemented as macro: + + PyObject *PyMapping_Keys(PyObject *o); + + On success, return a list of the keys in object o. On + failure, return NULL. This is equivalent to the Python + expression: o.keys(). + */ +#define PyMapping_Keys(O) PyObject_CallMethod(O,"keys",NULL) + + /* Implemented as macro: + + PyObject *PyMapping_Values(PyObject *o); + + On success, return a list of the values in object o. On + failure, return NULL. This is equivalent to the Python + expression: o.values(). + */ +#define PyMapping_Values(O) PyObject_CallMethod(O,"values",NULL) + + /* Implemented as macro: + + PyObject *PyMapping_Items(PyObject *o); + + On success, return a list of the items in object o, where + each item is a tuple containing a key-value pair. On + failure, return NULL. This is equivalent to the Python + expression: o.items(). + + */ +#define PyMapping_Items(O) PyObject_CallMethod(O,"items",NULL) + + PyAPI_FUNC(PyObject *) PyMapping_GetItemString(PyObject *o, char *key); + + /* + Return element of o corresponding to the object, key, or NULL + on failure. This is the equivalent of the Python expression: + o[key]. + */ + + PyAPI_FUNC(int) PyMapping_SetItemString(PyObject *o, char *key, + PyObject *value); + + /* + Map the object, key, to the value, v. Returns + -1 on failure. This is the equivalent of the Python + statement: o[key]=v. + */ + + +PyAPI_FUNC(int) PyObject_IsInstance(PyObject *object, PyObject *typeorclass); + /* isinstance(object, typeorclass) */ + +PyAPI_FUNC(int) PyObject_IsSubclass(PyObject *object, PyObject *typeorclass); + /* issubclass(object, typeorclass) */ + + +#ifdef __cplusplus +} +#endif +#endif /* Py_ABSTRACTOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/asdl.h b/vscript/languages/python/python-2.5.1/include/asdl.h new file mode 100644 index 00000000..84e837e7 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/asdl.h @@ -0,0 +1,45 @@ +#ifndef Py_ASDL_H +#define Py_ASDL_H + +typedef PyObject * identifier; +typedef PyObject * string; +typedef PyObject * object; + +#ifndef __cplusplus +typedef enum {false, true} bool; +#endif + +/* It would be nice if the code generated by asdl_c.py was completely + independent of Python, but it is a goal the requires too much work + at this stage. So, for example, I'll represent identifiers as + interned Python strings. +*/ + +/* XXX A sequence should be typed so that its use can be typechecked. */ + +typedef struct { + int size; + void *elements[1]; +} asdl_seq; + +typedef struct { + int size; + int elements[1]; +} asdl_int_seq; + +asdl_seq *asdl_seq_new(int size, PyArena *arena); +asdl_int_seq *asdl_int_seq_new(int size, PyArena *arena); + +#define asdl_seq_GET(S, I) (S)->elements[(I)] +#define asdl_seq_LEN(S) ((S) == NULL ? 0 : (S)->size) +#ifdef Py_DEBUG +#define asdl_seq_SET(S, I, V) { \ + int _asdl_i = (I); \ + assert((S) && _asdl_i < (S)->size); \ + (S)->elements[_asdl_i] = (V); \ +} +#else +#define asdl_seq_SET(S, I, V) (S)->elements[I] = (V) +#endif + +#endif /* !Py_ASDL_H */ diff --git a/vscript/languages/python/python-2.5.1/include/ast.h b/vscript/languages/python/python-2.5.1/include/ast.h new file mode 100644 index 00000000..cc14b7fd --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/ast.h @@ -0,0 +1,13 @@ +#ifndef Py_AST_H +#define Py_AST_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(mod_ty) PyAST_FromNode(const node *, PyCompilerFlags *flags, + const char *, PyArena *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_AST_H */ diff --git a/vscript/languages/python/python-2.5.1/include/bitset.h b/vscript/languages/python/python-2.5.1/include/bitset.h new file mode 100644 index 00000000..faeb4191 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/bitset.h @@ -0,0 +1,32 @@ + +#ifndef Py_BITSET_H +#define Py_BITSET_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Bitset interface */ + +#define BYTE char + +typedef BYTE *bitset; + +bitset newbitset(int nbits); +void delbitset(bitset bs); +#define testbit(ss, ibit) (((ss)[BIT2BYTE(ibit)] & BIT2MASK(ibit)) != 0) +int addbit(bitset bs, int ibit); /* Returns 0 if already set */ +int samebitset(bitset bs1, bitset bs2, int nbits); +void mergebitset(bitset bs1, bitset bs2, int nbits); + +#define BITSPERBYTE (8*sizeof(BYTE)) +#define NBYTES(nbits) (((nbits) + BITSPERBYTE - 1) / BITSPERBYTE) + +#define BIT2BYTE(ibit) ((ibit) / BITSPERBYTE) +#define BIT2SHIFT(ibit) ((ibit) % BITSPERBYTE) +#define BIT2MASK(ibit) (1 << BIT2SHIFT(ibit)) +#define BYTE2BIT(ibyte) ((ibyte) * BITSPERBYTE) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_BITSET_H */ diff --git a/vscript/languages/python/python-2.5.1/include/boolobject.h b/vscript/languages/python/python-2.5.1/include/boolobject.h new file mode 100644 index 00000000..7f9ad01a --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/boolobject.h @@ -0,0 +1,36 @@ +/* Boolean object interface */ + +#ifndef Py_BOOLOBJECT_H +#define Py_BOOLOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +typedef PyIntObject PyBoolObject; + +PyAPI_DATA(PyTypeObject) PyBool_Type; + +#define PyBool_Check(x) ((x)->ob_type == &PyBool_Type) + +/* Py_False and Py_True are the only two bools in existence. +Don't forget to apply Py_INCREF() when returning either!!! */ + +/* Don't use these directly */ +PyAPI_DATA(PyIntObject) _Py_ZeroStruct, _Py_TrueStruct; + +/* Use these macros */ +#define Py_False ((PyObject *) &_Py_ZeroStruct) +#define Py_True ((PyObject *) &_Py_TrueStruct) + +/* Macros for returning Py_True or Py_False, respectively */ +#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True +#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False + +/* Function to return a bool from a C long */ +PyAPI_FUNC(PyObject *) PyBool_FromLong(long); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_BOOLOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/bufferobject.h b/vscript/languages/python/python-2.5.1/include/bufferobject.h new file mode 100644 index 00000000..75ba4963 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/bufferobject.h @@ -0,0 +1,33 @@ + +/* Buffer object interface */ + +/* Note: the object's structure is private */ + +#ifndef Py_BUFFEROBJECT_H +#define Py_BUFFEROBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +PyAPI_DATA(PyTypeObject) PyBuffer_Type; + +#define PyBuffer_Check(op) ((op)->ob_type == &PyBuffer_Type) + +#define Py_END_OF_BUFFER (-1) + +PyAPI_FUNC(PyObject *) PyBuffer_FromObject(PyObject *base, + Py_ssize_t offset, Py_ssize_t size); +PyAPI_FUNC(PyObject *) PyBuffer_FromReadWriteObject(PyObject *base, + Py_ssize_t offset, + Py_ssize_t size); + +PyAPI_FUNC(PyObject *) PyBuffer_FromMemory(void *ptr, Py_ssize_t size); +PyAPI_FUNC(PyObject *) PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size); + +PyAPI_FUNC(PyObject *) PyBuffer_New(Py_ssize_t size); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_BUFFEROBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/cellobject.h b/vscript/languages/python/python-2.5.1/include/cellobject.h new file mode 100644 index 00000000..fd186e28 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/cellobject.h @@ -0,0 +1,28 @@ +/* Cell object interface */ + +#ifndef Py_CELLOBJECT_H +#define Py_CELLOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_HEAD + PyObject *ob_ref; /* Content of the cell or NULL when empty */ +} PyCellObject; + +PyAPI_DATA(PyTypeObject) PyCell_Type; + +#define PyCell_Check(op) ((op)->ob_type == &PyCell_Type) + +PyAPI_FUNC(PyObject *) PyCell_New(PyObject *); +PyAPI_FUNC(PyObject *) PyCell_Get(PyObject *); +PyAPI_FUNC(int) PyCell_Set(PyObject *, PyObject *); + +#define PyCell_GET(op) (((PyCellObject *)(op))->ob_ref) +#define PyCell_SET(op, v) (((PyCellObject *)(op))->ob_ref = v) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_TUPLEOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/ceval.h b/vscript/languages/python/python-2.5.1/include/ceval.h new file mode 100644 index 00000000..f4411977 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/ceval.h @@ -0,0 +1,157 @@ +#ifndef Py_CEVAL_H +#define Py_CEVAL_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Interface to random parts in ceval.c */ + +PyAPI_FUNC(PyObject *) PyEval_CallObjectWithKeywords( + PyObject *, PyObject *, PyObject *); + +/* DLL-level Backwards compatibility: */ +#undef PyEval_CallObject +PyAPI_FUNC(PyObject *) PyEval_CallObject(PyObject *, PyObject *); + +/* Inline this */ +#define PyEval_CallObject(func,arg) \ + PyEval_CallObjectWithKeywords(func, arg, (PyObject *)NULL) + +PyAPI_FUNC(PyObject *) PyEval_CallFunction(PyObject *obj, + const char *format, ...); +PyAPI_FUNC(PyObject *) PyEval_CallMethod(PyObject *obj, + const char *methodname, + const char *format, ...); + +PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); +PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); + +struct _frame; /* Avoid including frameobject.h */ + +PyAPI_FUNC(PyObject *) PyEval_GetBuiltins(void); +PyAPI_FUNC(PyObject *) PyEval_GetGlobals(void); +PyAPI_FUNC(PyObject *) PyEval_GetLocals(void); +PyAPI_FUNC(struct _frame *) PyEval_GetFrame(void); +PyAPI_FUNC(int) PyEval_GetRestricted(void); + +/* Look at the current frame's (if any) code's co_flags, and turn on + the corresponding compiler flags in cf->cf_flags. Return 1 if any + flag was set, else return 0. */ +PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf); + +PyAPI_FUNC(int) Py_FlushLine(void); + +PyAPI_FUNC(int) Py_AddPendingCall(int (*func)(void *), void *arg); +PyAPI_FUNC(int) Py_MakePendingCalls(void); + +/* Protection against deeply nested recursive calls */ +PyAPI_FUNC(void) Py_SetRecursionLimit(int); +PyAPI_FUNC(int) Py_GetRecursionLimit(void); + +#define Py_EnterRecursiveCall(where) \ + (_Py_MakeRecCheck(PyThreadState_GET()->recursion_depth) && \ + _Py_CheckRecursiveCall(where)) +#define Py_LeaveRecursiveCall() \ + (--PyThreadState_GET()->recursion_depth) +PyAPI_FUNC(int) _Py_CheckRecursiveCall(char *where); +PyAPI_DATA(int) _Py_CheckRecursionLimit; +#ifdef USE_STACKCHECK +# define _Py_MakeRecCheck(x) (++(x) > --_Py_CheckRecursionLimit) +#else +# define _Py_MakeRecCheck(x) (++(x) > _Py_CheckRecursionLimit) +#endif + +PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *); +PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *); + +PyAPI_FUNC(PyObject *) PyEval_GetCallStats(PyObject *); +PyAPI_FUNC(PyObject *) PyEval_EvalFrame(struct _frame *); +PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx(struct _frame *f, int exc); + +/* this used to be handled on a per-thread basis - now just two globals */ +PyAPI_DATA(volatile int) _Py_Ticker; +PyAPI_DATA(int) _Py_CheckInterval; + +/* Interface for threads. + + A module that plans to do a blocking system call (or something else + that lasts a long time and doesn't touch Python data) can allow other + threads to run as follows: + + ...preparations here... + Py_BEGIN_ALLOW_THREADS + ...blocking system call here... + Py_END_ALLOW_THREADS + ...interpret result here... + + The Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS pair expands to a + {}-surrounded block. + To leave the block in the middle (e.g., with return), you must insert + a line containing Py_BLOCK_THREADS before the return, e.g. + + if (...premature_exit...) { + Py_BLOCK_THREADS + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } + + An alternative is: + + Py_BLOCK_THREADS + if (...premature_exit...) { + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } + Py_UNBLOCK_THREADS + + For convenience, that the value of 'errno' is restored across + Py_END_ALLOW_THREADS and Py_BLOCK_THREADS. + + WARNING: NEVER NEST CALLS TO Py_BEGIN_ALLOW_THREADS AND + Py_END_ALLOW_THREADS!!! + + The function PyEval_InitThreads() should be called only from + initthread() in "threadmodule.c". + + Note that not yet all candidates have been converted to use this + mechanism! +*/ + +PyAPI_FUNC(PyThreadState *) PyEval_SaveThread(void); +PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *); + +#ifdef WITH_THREAD + +PyAPI_FUNC(int) PyEval_ThreadsInitialized(void); +PyAPI_FUNC(void) PyEval_InitThreads(void); +PyAPI_FUNC(void) PyEval_AcquireLock(void); +PyAPI_FUNC(void) PyEval_ReleaseLock(void); +PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate); +PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate); +PyAPI_FUNC(void) PyEval_ReInitThreads(void); + +#define Py_BEGIN_ALLOW_THREADS { \ + PyThreadState *_save; \ + _save = PyEval_SaveThread(); +#define Py_BLOCK_THREADS PyEval_RestoreThread(_save); +#define Py_UNBLOCK_THREADS _save = PyEval_SaveThread(); +#define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \ + } + +#else /* !WITH_THREAD */ + +#define Py_BEGIN_ALLOW_THREADS { +#define Py_BLOCK_THREADS +#define Py_UNBLOCK_THREADS +#define Py_END_ALLOW_THREADS } + +#endif /* !WITH_THREAD */ + +PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CEVAL_H */ diff --git a/vscript/languages/python/python-2.5.1/include/classobject.h b/vscript/languages/python/python-2.5.1/include/classobject.h new file mode 100644 index 00000000..8f8db7d8 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/classobject.h @@ -0,0 +1,81 @@ + +/* Class object interface */ + +/* Revealing some structures (not for general use) */ + +#ifndef Py_CLASSOBJECT_H +#define Py_CLASSOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_HEAD + PyObject *cl_bases; /* A tuple of class objects */ + PyObject *cl_dict; /* A dictionary */ + PyObject *cl_name; /* A string */ + /* The following three are functions or NULL */ + PyObject *cl_getattr; + PyObject *cl_setattr; + PyObject *cl_delattr; +} PyClassObject; + +typedef struct { + PyObject_HEAD + PyClassObject *in_class; /* The class object */ + PyObject *in_dict; /* A dictionary */ + PyObject *in_weakreflist; /* List of weak references */ +} PyInstanceObject; + +typedef struct { + PyObject_HEAD + PyObject *im_func; /* The callable object implementing the method */ + PyObject *im_self; /* The instance it is bound to, or NULL */ + PyObject *im_class; /* The class that asked for the method */ + PyObject *im_weakreflist; /* List of weak references */ +} PyMethodObject; + +PyAPI_DATA(PyTypeObject) PyClass_Type, PyInstance_Type, PyMethod_Type; + +#define PyClass_Check(op) ((op)->ob_type == &PyClass_Type) +#define PyInstance_Check(op) ((op)->ob_type == &PyInstance_Type) +#define PyMethod_Check(op) ((op)->ob_type == &PyMethod_Type) + +PyAPI_FUNC(PyObject *) PyClass_New(PyObject *, PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyInstance_New(PyObject *, PyObject *, + PyObject *); +PyAPI_FUNC(PyObject *) PyInstance_NewRaw(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *, PyObject *); + +PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *); +PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *); +PyAPI_FUNC(PyObject *) PyMethod_Class(PyObject *); + +/* Look up attribute with name (a string) on instance object pinst, using + * only the instance and base class dicts. If a descriptor is found in + * a class dict, the descriptor is returned without calling it. + * Returns NULL if nothing found, else a borrowed reference to the + * value associated with name in the dict in which name was found. + * The point of this routine is that it never calls arbitrary Python + * code, so is always "safe": all it does is dict lookups. The function + * can't fail, never sets an exception, and NULL is not an error (it just + * means "not found"). + */ +PyAPI_FUNC(PyObject *) _PyInstance_Lookup(PyObject *pinst, PyObject *name); + +/* Macros for direct access to these values. Type checks are *not* + done, so use with care. */ +#define PyMethod_GET_FUNCTION(meth) \ + (((PyMethodObject *)meth) -> im_func) +#define PyMethod_GET_SELF(meth) \ + (((PyMethodObject *)meth) -> im_self) +#define PyMethod_GET_CLASS(meth) \ + (((PyMethodObject *)meth) -> im_class) + +PyAPI_FUNC(int) PyClass_IsSubclass(PyObject *, PyObject *); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CLASSOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/cobject.h b/vscript/languages/python/python-2.5.1/include/cobject.h new file mode 100644 index 00000000..ad23ac8d --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/cobject.h @@ -0,0 +1,54 @@ + +/* C objects to be exported from one extension module to another. + + C objects are used for communication between extension modules. + They provide a way for an extension module to export a C interface + to other extension modules, so that extension modules can use the + Python import mechanism to link to one another. + +*/ + +#ifndef Py_COBJECT_H +#define Py_COBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyCObject_Type; + +#define PyCObject_Check(op) ((op)->ob_type == &PyCObject_Type) + +/* Create a PyCObject from a pointer to a C object and an optional + destructor function. If the second argument is non-null, then it + will be called with the first argument if and when the PyCObject is + destroyed. + +*/ +PyAPI_FUNC(PyObject *) PyCObject_FromVoidPtr( + void *cobj, void (*destruct)(void*)); + + +/* Create a PyCObject from a pointer to a C object, a description object, + and an optional destructor function. If the third argument is non-null, + then it will be called with the first and second arguments if and when + the PyCObject is destroyed. +*/ +PyAPI_FUNC(PyObject *) PyCObject_FromVoidPtrAndDesc( + void *cobj, void *desc, void (*destruct)(void*,void*)); + +/* Retrieve a pointer to a C object from a PyCObject. */ +PyAPI_FUNC(void *) PyCObject_AsVoidPtr(PyObject *); + +/* Retrieve a pointer to a description object from a PyCObject. */ +PyAPI_FUNC(void *) PyCObject_GetDesc(PyObject *); + +/* Import a pointer to a C object from a module using a PyCObject. */ +PyAPI_FUNC(void *) PyCObject_Import(char *module_name, char *cobject_name); + +/* Modify a C object. Fails (==0) if object has a destructor. */ +PyAPI_FUNC(int) PyCObject_SetVoidPtr(PyObject *self, void *cobj); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_COBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/code.h b/vscript/languages/python/python-2.5.1/include/code.h new file mode 100644 index 00000000..334ebab4 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/code.h @@ -0,0 +1,94 @@ +/* Definitions for bytecode */ + +#ifndef Py_CODE_H +#define Py_CODE_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Bytecode object */ +typedef struct { + PyObject_HEAD + int co_argcount; /* #arguments, except *args */ + int co_nlocals; /* #local variables */ + int co_stacksize; /* #entries needed for evaluation stack */ + int co_flags; /* CO_..., see below */ + PyObject *co_code; /* instruction opcodes */ + PyObject *co_consts; /* list (constants used) */ + PyObject *co_names; /* list of strings (names used) */ + PyObject *co_varnames; /* tuple of strings (local variable names) */ + PyObject *co_freevars; /* tuple of strings (free variable names) */ + PyObject *co_cellvars; /* tuple of strings (cell variable names) */ + /* The rest doesn't count for hash/cmp */ + PyObject *co_filename; /* string (where it was loaded from) */ + PyObject *co_name; /* string (name, for reference) */ + int co_firstlineno; /* first source line number */ + PyObject *co_lnotab; /* string (encoding addr<->lineno mapping) */ + void *co_zombieframe; /* for optimization only (see frameobject.c) */ +} PyCodeObject; + +/* Masks for co_flags above */ +#define CO_OPTIMIZED 0x0001 +#define CO_NEWLOCALS 0x0002 +#define CO_VARARGS 0x0004 +#define CO_VARKEYWORDS 0x0008 +#define CO_NESTED 0x0010 +#define CO_GENERATOR 0x0020 +/* The CO_NOFREE flag is set if there are no free or cell variables. + This information is redundant, but it allows a single flag test + to determine whether there is any extra work to be done when the + call frame it setup. +*/ +#define CO_NOFREE 0x0040 + +#if 0 +/* This is no longer used. Stopped defining in 2.5, do not re-use. */ +#define CO_GENERATOR_ALLOWED 0x1000 +#endif +#define CO_FUTURE_DIVISION 0x2000 +#define CO_FUTURE_ABSOLUTE_IMPORT 0x4000 /* do absolute imports by default */ +#define CO_FUTURE_WITH_STATEMENT 0x8000 + +/* This should be defined if a future statement modifies the syntax. + For example, when a keyword is added. +*/ +#define PY_PARSER_REQUIRES_FUTURE_KEYWORD + +#define CO_MAXBLOCKS 20 /* Max static block nesting within a function */ + +PyAPI_DATA(PyTypeObject) PyCode_Type; + +#define PyCode_Check(op) ((op)->ob_type == &PyCode_Type) +#define PyCode_GetNumFree(op) (PyTuple_GET_SIZE((op)->co_freevars)) + +/* Public interface */ +PyAPI_FUNC(PyCodeObject *) PyCode_New( + int, int, int, int, PyObject *, PyObject *, PyObject *, PyObject *, + PyObject *, PyObject *, PyObject *, PyObject *, int, PyObject *); + /* same as struct above */ +PyAPI_FUNC(int) PyCode_Addr2Line(PyCodeObject *, int); + +/* for internal use only */ +#define _PyCode_GETCODEPTR(co, pp) \ + ((*(co)->co_code->ob_type->tp_as_buffer->bf_getreadbuffer) \ + ((co)->co_code, 0, (void **)(pp))) + +typedef struct _addr_pair { + int ap_lower; + int ap_upper; +} PyAddrPair; + +/* Check whether lasti (an instruction offset) falls outside bounds + and whether it is a line number that should be traced. Returns + a line number if it should be traced or -1 if the line should not. + + If lasti is not within bounds, updates bounds. +*/ + +PyAPI_FUNC(int) PyCode_CheckLineNumber(PyCodeObject* co, + int lasti, PyAddrPair *bounds); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CODE_H */ diff --git a/vscript/languages/python/python-2.5.1/include/codecs.h b/vscript/languages/python/python-2.5.1/include/codecs.h new file mode 100644 index 00000000..0d76241d --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/codecs.h @@ -0,0 +1,167 @@ +#ifndef Py_CODECREGISTRY_H +#define Py_CODECREGISTRY_H +#ifdef __cplusplus +extern "C" { +#endif + +/* ------------------------------------------------------------------------ + + Python Codec Registry and support functions + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +Copyright (c) Corporation for National Research Initiatives. + + ------------------------------------------------------------------------ */ + +/* Register a new codec search function. + + As side effect, this tries to load the encodings package, if not + yet done, to make sure that it is always first in the list of + search functions. + + The search_function's refcount is incremented by this function. */ + +PyAPI_FUNC(int) PyCodec_Register( + PyObject *search_function + ); + +/* Codec register lookup API. + + Looks up the given encoding and returns a CodecInfo object with + function attributes which implement the different aspects of + processing the encoding. + + The encoding string is looked up converted to all lower-case + characters. This makes encodings looked up through this mechanism + effectively case-insensitive. + + If no codec is found, a KeyError is set and NULL returned. + + As side effect, this tries to load the encodings package, if not + yet done. This is part of the lazy load strategy for the encodings + package. + + */ + +PyAPI_FUNC(PyObject *) _PyCodec_Lookup( + const char *encoding + ); + +/* Generic codec based encoding API. + + object is passed through the encoder function found for the given + encoding using the error handling method defined by errors. errors + may be NULL to use the default method defined for the codec. + + Raises a LookupError in case no encoder can be found. + + */ + +PyAPI_FUNC(PyObject *) PyCodec_Encode( + PyObject *object, + const char *encoding, + const char *errors + ); + +/* Generic codec based decoding API. + + object is passed through the decoder function found for the given + encoding using the error handling method defined by errors. errors + may be NULL to use the default method defined for the codec. + + Raises a LookupError in case no encoder can be found. + + */ + +PyAPI_FUNC(PyObject *) PyCodec_Decode( + PyObject *object, + const char *encoding, + const char *errors + ); + +/* --- Codec Lookup APIs -------------------------------------------------- + + All APIs return a codec object with incremented refcount and are + based on _PyCodec_Lookup(). The same comments w/r to the encoding + name also apply to these APIs. + +*/ + +/* Get an encoder function for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_Encoder( + const char *encoding + ); + +/* Get a decoder function for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_Decoder( + const char *encoding + ); + +/* Get a IncrementalEncoder object for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_IncrementalEncoder( + const char *encoding, + const char *errors + ); + +/* Get a IncrementalDecoder object function for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_IncrementalDecoder( + const char *encoding, + const char *errors + ); + +/* Get a StreamReader factory function for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_StreamReader( + const char *encoding, + PyObject *stream, + const char *errors + ); + +/* Get a StreamWriter factory function for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_StreamWriter( + const char *encoding, + PyObject *stream, + const char *errors + ); + +/* Unicode encoding error handling callback registry API */ + +/* Register the error handling callback function error under the name + name. This function will be called by the codec when it encounters + unencodable characters/undecodable bytes and doesn't know the + callback name, when name is specified as the error parameter + in the call to the encode/decode function. + Return 0 on success, -1 on error */ +PyAPI_FUNC(int) PyCodec_RegisterError(const char *name, PyObject *error); + +/* Lookup the error handling callback function registered under the + name error. As a special case NULL can be passed, in which case + the error handling callback for "strict" will be returned. */ +PyAPI_FUNC(PyObject *) PyCodec_LookupError(const char *name); + +/* raise exc as an exception */ +PyAPI_FUNC(PyObject *) PyCodec_StrictErrors(PyObject *exc); + +/* ignore the unicode error, skipping the faulty input */ +PyAPI_FUNC(PyObject *) PyCodec_IgnoreErrors(PyObject *exc); + +/* replace the unicode error with ? or U+FFFD */ +PyAPI_FUNC(PyObject *) PyCodec_ReplaceErrors(PyObject *exc); + +/* replace the unicode encode error with XML character references */ +PyAPI_FUNC(PyObject *) PyCodec_XMLCharRefReplaceErrors(PyObject *exc); + +/* replace the unicode encode error with backslash escapes (\x, \u and \U) */ +PyAPI_FUNC(PyObject *) PyCodec_BackslashReplaceErrors(PyObject *exc); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CODECREGISTRY_H */ diff --git a/vscript/languages/python/python-2.5.1/include/compile.h b/vscript/languages/python/python-2.5.1/include/compile.h new file mode 100644 index 00000000..2bde6fb5 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/compile.h @@ -0,0 +1,39 @@ + +#ifndef Py_COMPILE_H +#define Py_COMPILE_H + +#include "code.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Public interface */ +struct _node; /* Declare the existence of this type */ +PyAPI_FUNC(PyCodeObject *) PyNode_Compile(struct _node *, const char *); + +/* Future feature support */ + +typedef struct { + int ff_features; /* flags set by future statements */ + int ff_lineno; /* line number of last future statement */ +} PyFutureFeatures; + +#define FUTURE_NESTED_SCOPES "nested_scopes" +#define FUTURE_GENERATORS "generators" +#define FUTURE_DIVISION "division" +#define FUTURE_ABSOLUTE_IMPORT "absolute_import" +#define FUTURE_WITH_STATEMENT "with_statement" + +struct _mod; /* Declare the existence of this type */ +PyAPI_FUNC(PyCodeObject *) PyAST_Compile(struct _mod *, const char *, + PyCompilerFlags *, PyArena *); +PyAPI_FUNC(PyFutureFeatures *) PyFuture_FromAST(struct _mod *, const char *); + +#define ERR_LATE_FUTURE \ +"from __future__ imports must occur at the beginning of the file" + +#ifdef __cplusplus +} +#endif +#endif /* !Py_COMPILE_H */ diff --git a/vscript/languages/python/python-2.5.1/include/complexobject.h b/vscript/languages/python/python-2.5.1/include/complexobject.h new file mode 100644 index 00000000..e59bf2ca --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/complexobject.h @@ -0,0 +1,58 @@ +/* Complex number structure */ + +#ifndef Py_COMPLEXOBJECT_H +#define Py_COMPLEXOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + double real; + double imag; +} Py_complex; + +/* Operations on complex numbers from complexmodule.c */ + +#define c_sum _Py_c_sum +#define c_diff _Py_c_diff +#define c_neg _Py_c_neg +#define c_prod _Py_c_prod +#define c_quot _Py_c_quot +#define c_pow _Py_c_pow + +PyAPI_FUNC(Py_complex) c_sum(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) c_diff(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) c_neg(Py_complex); +PyAPI_FUNC(Py_complex) c_prod(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) c_quot(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) c_pow(Py_complex, Py_complex); + + +/* Complex object interface */ + +/* +PyComplexObject represents a complex number with double-precision +real and imaginary parts. +*/ + +typedef struct { + PyObject_HEAD + Py_complex cval; +} PyComplexObject; + +PyAPI_DATA(PyTypeObject) PyComplex_Type; + +#define PyComplex_Check(op) PyObject_TypeCheck(op, &PyComplex_Type) +#define PyComplex_CheckExact(op) ((op)->ob_type == &PyComplex_Type) + +PyAPI_FUNC(PyObject *) PyComplex_FromCComplex(Py_complex); +PyAPI_FUNC(PyObject *) PyComplex_FromDoubles(double real, double imag); + +PyAPI_FUNC(double) PyComplex_RealAsDouble(PyObject *op); +PyAPI_FUNC(double) PyComplex_ImagAsDouble(PyObject *op); +PyAPI_FUNC(Py_complex) PyComplex_AsCComplex(PyObject *op); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_COMPLEXOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/cstringio.h b/vscript/languages/python/python-2.5.1/include/cstringio.h new file mode 100644 index 00000000..25fc9dd0 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/cstringio.h @@ -0,0 +1,70 @@ +#ifndef Py_CSTRINGIO_H +#define Py_CSTRINGIO_H +#ifdef __cplusplus +extern "C" { +#endif +/* + + This header provides access to cStringIO objects from C. + Functions are provided for calling cStringIO objects and + macros are provided for testing whether you have cStringIO + objects. + + Before calling any of the functions or macros, you must initialize + the routines with: + + PycString_IMPORT + + This would typically be done in your init function. + +*/ +#define PycString_IMPORT \ + PycStringIO = (struct PycStringIO_CAPI*)PyCObject_Import("cStringIO", \ + "cStringIO_CAPI") + +/* Basic functions to manipulate cStringIO objects from C */ + +static struct PycStringIO_CAPI { + + /* Read a string from an input object. If the last argument + is -1, the remainder will be read. + */ + int(*cread)(PyObject *, char **, Py_ssize_t); + + /* Read a line from an input object. Returns the length of the read + line as an int and a pointer inside the object buffer as char** (so + the caller doesn't have to provide its own buffer as destination). + */ + int(*creadline)(PyObject *, char **); + + /* Write a string to an output object*/ + int(*cwrite)(PyObject *, const char *, Py_ssize_t); + + /* Get the output object as a Python string (returns new reference). */ + PyObject *(*cgetvalue)(PyObject *); + + /* Create a new output object */ + PyObject *(*NewOutput)(int); + + /* Create an input object from a Python string + (copies the Python string reference). + */ + PyObject *(*NewInput)(PyObject *); + + /* The Python types for cStringIO input and output objects. + Note that you can do input on an output object. + */ + PyTypeObject *InputType, *OutputType; + +} *PycStringIO; + +/* These can be used to test if you have one */ +#define PycStringIO_InputCheck(O) \ + ((O)->ob_type==PycStringIO->InputType) +#define PycStringIO_OutputCheck(O) \ + ((O)->ob_type==PycStringIO->OutputType) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CSTRINGIO_H */ diff --git a/vscript/languages/python/python-2.5.1/include/datetime.h b/vscript/languages/python/python-2.5.1/include/datetime.h new file mode 100644 index 00000000..db0f3aa5 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/datetime.h @@ -0,0 +1,245 @@ +/* datetime.h + */ + +#ifndef DATETIME_H +#define DATETIME_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Fields are packed into successive bytes, each viewed as unsigned and + * big-endian, unless otherwise noted: + * + * byte offset + * 0 year 2 bytes, 1-9999 + * 2 month 1 byte, 1-12 + * 3 day 1 byte, 1-31 + * 4 hour 1 byte, 0-23 + * 5 minute 1 byte, 0-59 + * 6 second 1 byte, 0-59 + * 7 usecond 3 bytes, 0-999999 + * 10 + */ + +/* # of bytes for year, month, and day. */ +#define _PyDateTime_DATE_DATASIZE 4 + +/* # of bytes for hour, minute, second, and usecond. */ +#define _PyDateTime_TIME_DATASIZE 6 + +/* # of bytes for year, month, day, hour, minute, second, and usecond. */ +#define _PyDateTime_DATETIME_DATASIZE 10 + + +typedef struct +{ + PyObject_HEAD + long hashcode; /* -1 when unknown */ + int days; /* -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS */ + int seconds; /* 0 <= seconds < 24*3600 is invariant */ + int microseconds; /* 0 <= microseconds < 1000000 is invariant */ +} PyDateTime_Delta; + +typedef struct +{ + PyObject_HEAD /* a pure abstract base clase */ +} PyDateTime_TZInfo; + + +/* The datetime and time types have hashcodes, and an optional tzinfo member, + * present if and only if hastzinfo is true. + */ +#define _PyTZINFO_HEAD \ + PyObject_HEAD \ + long hashcode; \ + char hastzinfo; /* boolean flag */ + +/* No _PyDateTime_BaseTZInfo is allocated; it's just to have something + * convenient to cast to, when getting at the hastzinfo member of objects + * starting with _PyTZINFO_HEAD. + */ +typedef struct +{ + _PyTZINFO_HEAD +} _PyDateTime_BaseTZInfo; + +/* All time objects are of PyDateTime_TimeType, but that can be allocated + * in two ways, with or without a tzinfo member. Without is the same as + * tzinfo == None, but consumes less memory. _PyDateTime_BaseTime is an + * internal struct used to allocate the right amount of space for the + * "without" case. + */ +#define _PyDateTime_TIMEHEAD \ + _PyTZINFO_HEAD \ + unsigned char data[_PyDateTime_TIME_DATASIZE]; + +typedef struct +{ + _PyDateTime_TIMEHEAD +} _PyDateTime_BaseTime; /* hastzinfo false */ + +typedef struct +{ + _PyDateTime_TIMEHEAD + PyObject *tzinfo; +} PyDateTime_Time; /* hastzinfo true */ + + +/* All datetime objects are of PyDateTime_DateTimeType, but that can be + * allocated in two ways too, just like for time objects above. In addition, + * the plain date type is a base class for datetime, so it must also have + * a hastzinfo member (although it's unused there). + */ +typedef struct +{ + _PyTZINFO_HEAD + unsigned char data[_PyDateTime_DATE_DATASIZE]; +} PyDateTime_Date; + +#define _PyDateTime_DATETIMEHEAD \ + _PyTZINFO_HEAD \ + unsigned char data[_PyDateTime_DATETIME_DATASIZE]; + +typedef struct +{ + _PyDateTime_DATETIMEHEAD +} _PyDateTime_BaseDateTime; /* hastzinfo false */ + +typedef struct +{ + _PyDateTime_DATETIMEHEAD + PyObject *tzinfo; +} PyDateTime_DateTime; /* hastzinfo true */ + + +/* Apply for date and datetime instances. */ +#define PyDateTime_GET_YEAR(o) ((((PyDateTime_Date*)o)->data[0] << 8) | \ + ((PyDateTime_Date*)o)->data[1]) +#define PyDateTime_GET_MONTH(o) (((PyDateTime_Date*)o)->data[2]) +#define PyDateTime_GET_DAY(o) (((PyDateTime_Date*)o)->data[3]) + +#define PyDateTime_DATE_GET_HOUR(o) (((PyDateTime_DateTime*)o)->data[4]) +#define PyDateTime_DATE_GET_MINUTE(o) (((PyDateTime_DateTime*)o)->data[5]) +#define PyDateTime_DATE_GET_SECOND(o) (((PyDateTime_DateTime*)o)->data[6]) +#define PyDateTime_DATE_GET_MICROSECOND(o) \ + ((((PyDateTime_DateTime*)o)->data[7] << 16) | \ + (((PyDateTime_DateTime*)o)->data[8] << 8) | \ + ((PyDateTime_DateTime*)o)->data[9]) + +/* Apply for time instances. */ +#define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)o)->data[0]) +#define PyDateTime_TIME_GET_MINUTE(o) (((PyDateTime_Time*)o)->data[1]) +#define PyDateTime_TIME_GET_SECOND(o) (((PyDateTime_Time*)o)->data[2]) +#define PyDateTime_TIME_GET_MICROSECOND(o) \ + ((((PyDateTime_Time*)o)->data[3] << 16) | \ + (((PyDateTime_Time*)o)->data[4] << 8) | \ + ((PyDateTime_Time*)o)->data[5]) + + +/* Define structure for C API. */ +typedef struct { + /* type objects */ + PyTypeObject *DateType; + PyTypeObject *DateTimeType; + PyTypeObject *TimeType; + PyTypeObject *DeltaType; + PyTypeObject *TZInfoType; + + /* constructors */ + PyObject *(*Date_FromDate)(int, int, int, PyTypeObject*); + PyObject *(*DateTime_FromDateAndTime)(int, int, int, int, int, int, int, + PyObject*, PyTypeObject*); + PyObject *(*Time_FromTime)(int, int, int, int, PyObject*, PyTypeObject*); + PyObject *(*Delta_FromDelta)(int, int, int, int, PyTypeObject*); + + /* constructors for the DB API */ + PyObject *(*DateTime_FromTimestamp)(PyObject*, PyObject*, PyObject*); + PyObject *(*Date_FromTimestamp)(PyObject*, PyObject*); + +} PyDateTime_CAPI; + + +/* "magic" constant used to partially protect against developer mistakes. */ +#define DATETIME_API_MAGIC 0x414548d5 + +#ifdef Py_BUILD_CORE + +/* Macros for type checking when building the Python core. */ +#define PyDate_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateType) +#define PyDate_CheckExact(op) ((op)->ob_type == &PyDateTime_DateType) + +#define PyDateTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeType) +#define PyDateTime_CheckExact(op) ((op)->ob_type == &PyDateTime_DateTimeType) + +#define PyTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeType) +#define PyTime_CheckExact(op) ((op)->ob_type == &PyDateTime_TimeType) + +#define PyDelta_Check(op) PyObject_TypeCheck(op, &PyDateTime_DeltaType) +#define PyDelta_CheckExact(op) ((op)->ob_type == &PyDateTime_DeltaType) + +#define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType) +#define PyTZInfo_CheckExact(op) ((op)->ob_type == &PyDateTime_TZInfoType) + +#else + +/* Define global variable for the C API and a macro for setting it. */ +static PyDateTime_CAPI *PyDateTimeAPI; + +#define PyDateTime_IMPORT \ + PyDateTimeAPI = (PyDateTime_CAPI*) PyCObject_Import("datetime", \ + "datetime_CAPI") + +/* This macro would be used if PyCObject_ImportEx() was created. +#define PyDateTime_IMPORT \ + PyDateTimeAPI = (PyDateTime_CAPI*) PyCObject_ImportEx("datetime", \ + "datetime_CAPI", \ + DATETIME_API_MAGIC) +*/ + +/* Macros for type checking when not building the Python core. */ +#define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType) +#define PyDate_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->DateType) + +#define PyDateTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType) +#define PyDateTime_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->DateTimeType) + +#define PyTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TimeType) +#define PyTime_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->TimeType) + +#define PyDelta_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DeltaType) +#define PyDelta_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->DeltaType) + +#define PyTZInfo_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TZInfoType) +#define PyTZInfo_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->TZInfoType) + +/* Macros for accessing constructors in a simplified fashion. */ +#define PyDate_FromDate(year, month, day) \ + PyDateTimeAPI->Date_FromDate(year, month, day, PyDateTimeAPI->DateType) + +#define PyDateTime_FromDateAndTime(year, month, day, hour, min, sec, usec) \ + PyDateTimeAPI->DateTime_FromDateAndTime(year, month, day, hour, \ + min, sec, usec, Py_None, PyDateTimeAPI->DateTimeType) + +#define PyTime_FromTime(hour, minute, second, usecond) \ + PyDateTimeAPI->Time_FromTime(hour, minute, second, usecond, \ + Py_None, PyDateTimeAPI->TimeType) + +#define PyDelta_FromDSU(days, seconds, useconds) \ + PyDateTimeAPI->Delta_FromDelta(days, seconds, useconds, 1, \ + PyDateTimeAPI->DeltaType) + +/* Macros supporting the DB API. */ +#define PyDateTime_FromTimestamp(args) \ + PyDateTimeAPI->DateTime_FromTimestamp( \ + (PyObject*) (PyDateTimeAPI->DateTimeType), args, NULL) + +#define PyDate_FromTimestamp(args) \ + PyDateTimeAPI->Date_FromTimestamp( \ + (PyObject*) (PyDateTimeAPI->DateType), args) + +#endif /* Py_BUILD_CORE */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/vscript/languages/python/python-2.5.1/include/descrobject.h b/vscript/languages/python/python-2.5.1/include/descrobject.h new file mode 100644 index 00000000..a74af600 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/descrobject.h @@ -0,0 +1,91 @@ +/* Descriptors */ +#ifndef Py_DESCROBJECT_H +#define Py_DESCROBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef PyObject *(*getter)(PyObject *, void *); +typedef int (*setter)(PyObject *, PyObject *, void *); + +typedef struct PyGetSetDef { + char *name; + getter get; + setter set; + char *doc; + void *closure; +} PyGetSetDef; + +typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args, + void *wrapped); + +typedef PyObject *(*wrapperfunc_kwds)(PyObject *self, PyObject *args, + void *wrapped, PyObject *kwds); + +struct wrapperbase { + char *name; + int offset; + void *function; + wrapperfunc wrapper; + char *doc; + int flags; + PyObject *name_strobj; +}; + +/* Flags for above struct */ +#define PyWrapperFlag_KEYWORDS 1 /* wrapper function takes keyword args */ + +/* Various kinds of descriptor objects */ + +#define PyDescr_COMMON \ + PyObject_HEAD \ + PyTypeObject *d_type; \ + PyObject *d_name + +typedef struct { + PyDescr_COMMON; +} PyDescrObject; + +typedef struct { + PyDescr_COMMON; + PyMethodDef *d_method; +} PyMethodDescrObject; + +typedef struct { + PyDescr_COMMON; + struct PyMemberDef *d_member; +} PyMemberDescrObject; + +typedef struct { + PyDescr_COMMON; + PyGetSetDef *d_getset; +} PyGetSetDescrObject; + +typedef struct { + PyDescr_COMMON; + struct wrapperbase *d_base; + void *d_wrapped; /* This can be any function pointer */ +} PyWrapperDescrObject; + +PyAPI_DATA(PyTypeObject) PyWrapperDescr_Type; + +PyAPI_FUNC(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *); +PyAPI_FUNC(PyObject *) PyDescr_NewClassMethod(PyTypeObject *, PyMethodDef *); +PyAPI_FUNC(PyObject *) PyDescr_NewMember(PyTypeObject *, + struct PyMemberDef *); +PyAPI_FUNC(PyObject *) PyDescr_NewGetSet(PyTypeObject *, + struct PyGetSetDef *); +PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *, + struct wrapperbase *, void *); +#define PyDescr_IsData(d) ((d)->ob_type->tp_descr_set != NULL) + +PyAPI_FUNC(PyObject *) PyDictProxy_New(PyObject *); +PyAPI_FUNC(PyObject *) PyWrapper_New(PyObject *, PyObject *); + + +PyAPI_DATA(PyTypeObject) PyProperty_Type; +#ifdef __cplusplus +} +#endif +#endif /* !Py_DESCROBJECT_H */ + diff --git a/vscript/languages/python/python-2.5.1/include/dictobject.h b/vscript/languages/python/python-2.5.1/include/dictobject.h new file mode 100644 index 00000000..44b0838e --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/dictobject.h @@ -0,0 +1,141 @@ +#ifndef Py_DICTOBJECT_H +#define Py_DICTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Dictionary object type -- mapping from hashable object to object */ + +/* The distribution includes a separate file, Objects/dictnotes.txt, + describing explorations into dictionary design and optimization. + It covers typical dictionary use patterns, the parameters for + tuning dictionaries, and several ideas for possible optimizations. +*/ + +/* +There are three kinds of slots in the table: + +1. Unused. me_key == me_value == NULL + Does not hold an active (key, value) pair now and never did. Unused can + transition to Active upon key insertion. This is the only case in which + me_key is NULL, and is each slot's initial state. + +2. Active. me_key != NULL and me_key != dummy and me_value != NULL + Holds an active (key, value) pair. Active can transition to Dummy upon + key deletion. This is the only case in which me_value != NULL. + +3. Dummy. me_key == dummy and me_value == NULL + Previously held an active (key, value) pair, but that was deleted and an + active pair has not yet overwritten the slot. Dummy can transition to + Active upon key insertion. Dummy slots cannot be made Unused again + (cannot have me_key set to NULL), else the probe sequence in case of + collision would have no way to know they were once active. + +Note: .popitem() abuses the me_hash field of an Unused or Dummy slot to +hold a search finger. The me_hash field of Unused or Dummy slots has no +meaning otherwise. +*/ + +/* PyDict_MINSIZE is the minimum size of a dictionary. This many slots are + * allocated directly in the dict object (in the ma_smalltable member). + * It must be a power of 2, and at least 4. 8 allows dicts with no more + * than 5 active entries to live in ma_smalltable (and so avoid an + * additional malloc); instrumentation suggested this suffices for the + * majority of dicts (consisting mostly of usually-small instance dicts and + * usually-small dicts created to pass keyword arguments). + */ +#define PyDict_MINSIZE 8 + +typedef struct { + /* Cached hash code of me_key. Note that hash codes are C longs. + * We have to use Py_ssize_t instead because dict_popitem() abuses + * me_hash to hold a search finger. + */ + Py_ssize_t me_hash; + PyObject *me_key; + PyObject *me_value; +} PyDictEntry; + +/* +To ensure the lookup algorithm terminates, there must be at least one Unused +slot (NULL key) in the table. +The value ma_fill is the number of non-NULL keys (sum of Active and Dummy); +ma_used is the number of non-NULL, non-dummy keys (== the number of non-NULL +values == the number of Active items). +To avoid slowing down lookups on a near-full table, we resize the table when +it's two-thirds full. +*/ +typedef struct _dictobject PyDictObject; +struct _dictobject { + PyObject_HEAD + Py_ssize_t ma_fill; /* # Active + # Dummy */ + Py_ssize_t ma_used; /* # Active */ + + /* The table contains ma_mask + 1 slots, and that's a power of 2. + * We store the mask instead of the size because the mask is more + * frequently needed. + */ + Py_ssize_t ma_mask; + + /* ma_table points to ma_smalltable for small tables, else to + * additional malloc'ed memory. ma_table is never NULL! This rule + * saves repeated runtime null-tests in the workhorse getitem and + * setitem calls. + */ + PyDictEntry *ma_table; + PyDictEntry *(*ma_lookup)(PyDictObject *mp, PyObject *key, long hash); + PyDictEntry ma_smalltable[PyDict_MINSIZE]; +}; + +PyAPI_DATA(PyTypeObject) PyDict_Type; + +#define PyDict_Check(op) PyObject_TypeCheck(op, &PyDict_Type) +#define PyDict_CheckExact(op) ((op)->ob_type == &PyDict_Type) + +PyAPI_FUNC(PyObject *) PyDict_New(void); +PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key); +PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item); +PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key); +PyAPI_FUNC(void) PyDict_Clear(PyObject *mp); +PyAPI_FUNC(int) PyDict_Next( + PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value); +PyAPI_FUNC(int) _PyDict_Next( + PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, long *hash); +PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp); +PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp); +PyAPI_FUNC(PyObject *) PyDict_Items(PyObject *mp); +PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObject *mp); +PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp); +PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key); +PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, long hash); + +/* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */ +PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other); + +/* PyDict_Merge updates/merges from a mapping object (an object that + supports PyMapping_Keys() and PyObject_GetItem()). If override is true, + the last occurrence of a key wins, else the first. The Python + dict.update(other) is equivalent to PyDict_Merge(dict, other, 1). +*/ +PyAPI_FUNC(int) PyDict_Merge(PyObject *mp, + PyObject *other, + int override); + +/* PyDict_MergeFromSeq2 updates/merges from an iterable object producing + iterable objects of length 2. If override is true, the last occurrence + of a key wins, else the first. The Python dict constructor dict(seq2) + is equivalent to dict={}; PyDict_MergeFromSeq(dict, seq2, 1). +*/ +PyAPI_FUNC(int) PyDict_MergeFromSeq2(PyObject *d, + PyObject *seq2, + int override); + +PyAPI_FUNC(PyObject *) PyDict_GetItemString(PyObject *dp, const char *key); +PyAPI_FUNC(int) PyDict_SetItemString(PyObject *dp, const char *key, PyObject *item); +PyAPI_FUNC(int) PyDict_DelItemString(PyObject *dp, const char *key); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_DICTOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/enumobject.h b/vscript/languages/python/python-2.5.1/include/enumobject.h new file mode 100644 index 00000000..c14dbfc8 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/enumobject.h @@ -0,0 +1,17 @@ +#ifndef Py_ENUMOBJECT_H +#define Py_ENUMOBJECT_H + +/* Enumerate Object */ + +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyEnum_Type; +PyAPI_DATA(PyTypeObject) PyReversed_Type; + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_ENUMOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/errcode.h b/vscript/languages/python/python-2.5.1/include/errcode.h new file mode 100644 index 00000000..becec80c --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/errcode.h @@ -0,0 +1,36 @@ +#ifndef Py_ERRCODE_H +#define Py_ERRCODE_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Error codes passed around between file input, tokenizer, parser and + interpreter. This is necessary so we can turn them into Python + exceptions at a higher level. Note that some errors have a + slightly different meaning when passed from the tokenizer to the + parser than when passed from the parser to the interpreter; e.g. + the parser only returns E_EOF when it hits EOF immediately, and it + never returns E_OK. */ + +#define E_OK 10 /* No error */ +#define E_EOF 11 /* End Of File */ +#define E_INTR 12 /* Interrupted */ +#define E_TOKEN 13 /* Bad token */ +#define E_SYNTAX 14 /* Syntax error */ +#define E_NOMEM 15 /* Ran out of memory */ +#define E_DONE 16 /* Parsing complete */ +#define E_ERROR 17 /* Execution error */ +#define E_TABSPACE 18 /* Inconsistent mixing of tabs and spaces */ +#define E_OVERFLOW 19 /* Node had too many children */ +#define E_TOODEEP 20 /* Too many indentation levels */ +#define E_DEDENT 21 /* No matching outer block for dedent */ +#define E_DECODE 22 /* Error in decoding into Unicode */ +#define E_EOFS 23 /* EOF in triple-quoted string */ +#define E_EOLS 24 /* EOL in single-quoted string */ +#define E_LINECONT 25 /* Unexpected characters after a line continuation */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_ERRCODE_H */ diff --git a/vscript/languages/python/python-2.5.1/include/eval.h b/vscript/languages/python/python-2.5.1/include/eval.h new file mode 100644 index 00000000..b78dfe0f --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/eval.h @@ -0,0 +1,25 @@ + +/* Interface to execute compiled code */ + +#ifndef Py_EVAL_H +#define Py_EVAL_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(PyObject *) PyEval_EvalCode(PyCodeObject *, PyObject *, PyObject *); + +PyAPI_FUNC(PyObject *) PyEval_EvalCodeEx(PyCodeObject *co, + PyObject *globals, + PyObject *locals, + PyObject **args, int argc, + PyObject **kwds, int kwdc, + PyObject **defs, int defc, + PyObject *closure); + +PyAPI_FUNC(PyObject *) _PyEval_CallTracing(PyObject *func, PyObject *args); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_EVAL_H */ diff --git a/vscript/languages/python/python-2.5.1/include/fileobject.h b/vscript/languages/python/python-2.5.1/include/fileobject.h new file mode 100644 index 00000000..ebbb521d --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/fileobject.h @@ -0,0 +1,63 @@ + +/* File object interface */ + +#ifndef Py_FILEOBJECT_H +#define Py_FILEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_HEAD + FILE *f_fp; + PyObject *f_name; + PyObject *f_mode; + int (*f_close)(FILE *); + int f_softspace; /* Flag used by 'print' command */ + int f_binary; /* Flag which indicates whether the file is + open in binary (1) or text (0) mode */ + char* f_buf; /* Allocated readahead buffer */ + char* f_bufend; /* Points after last occupied position */ + char* f_bufptr; /* Current buffer position */ + char *f_setbuf; /* Buffer for setbuf(3) and setvbuf(3) */ + int f_univ_newline; /* Handle any newline convention */ + int f_newlinetypes; /* Types of newlines seen */ + int f_skipnextlf; /* Skip next \n */ + PyObject *f_encoding; + PyObject *weakreflist; /* List of weak references */ +} PyFileObject; + +PyAPI_DATA(PyTypeObject) PyFile_Type; + +#define PyFile_Check(op) PyObject_TypeCheck(op, &PyFile_Type) +#define PyFile_CheckExact(op) ((op)->ob_type == &PyFile_Type) + +PyAPI_FUNC(PyObject *) PyFile_FromString(char *, char *); +PyAPI_FUNC(void) PyFile_SetBufSize(PyObject *, int); +PyAPI_FUNC(int) PyFile_SetEncoding(PyObject *, const char *); +PyAPI_FUNC(PyObject *) PyFile_FromFile(FILE *, char *, char *, + int (*)(FILE *)); +PyAPI_FUNC(FILE *) PyFile_AsFile(PyObject *); +PyAPI_FUNC(PyObject *) PyFile_Name(PyObject *); +PyAPI_FUNC(PyObject *) PyFile_GetLine(PyObject *, int); +PyAPI_FUNC(int) PyFile_WriteObject(PyObject *, PyObject *, int); +PyAPI_FUNC(int) PyFile_SoftSpace(PyObject *, int); +PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *); +PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *); + +/* The default encoding used by the platform file system APIs + If non-NULL, this is different than the default encoding for strings +*/ +PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding; + +/* Routines to replace fread() and fgets() which accept any of \r, \n + or \r\n as line terminators. +*/ +#define PY_STDIOTEXTMODE "b" +char *Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *); +size_t Py_UniversalNewlineFread(char *, size_t, FILE *, PyObject *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FILEOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/floatobject.h b/vscript/languages/python/python-2.5.1/include/floatobject.h new file mode 100644 index 00000000..f695de85 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/floatobject.h @@ -0,0 +1,100 @@ + +/* Float object interface */ + +/* +PyFloatObject represents a (double precision) floating point number. +*/ + +#ifndef Py_FLOATOBJECT_H +#define Py_FLOATOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_HEAD + double ob_fval; +} PyFloatObject; + +PyAPI_DATA(PyTypeObject) PyFloat_Type; + +#define PyFloat_Check(op) PyObject_TypeCheck(op, &PyFloat_Type) +#define PyFloat_CheckExact(op) ((op)->ob_type == &PyFloat_Type) + +/* Return Python float from string PyObject. Second argument ignored on + input, and, if non-NULL, NULL is stored into *junk (this tried to serve a + purpose once but can't be made to work as intended). */ +PyAPI_FUNC(PyObject *) PyFloat_FromString(PyObject*, char** junk); + +/* Return Python float from C double. */ +PyAPI_FUNC(PyObject *) PyFloat_FromDouble(double); + +/* Extract C double from Python float. The macro version trades safety for + speed. */ +PyAPI_FUNC(double) PyFloat_AsDouble(PyObject *); +#define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval) + +/* Write repr(v) into the char buffer argument, followed by null byte. The + buffer must be "big enough"; >= 100 is very safe. + PyFloat_AsReprString(buf, x) strives to print enough digits so that + PyFloat_FromString(buf) then reproduces x exactly. */ +PyAPI_FUNC(void) PyFloat_AsReprString(char*, PyFloatObject *v); + +/* Write str(v) into the char buffer argument, followed by null byte. The + buffer must be "big enough"; >= 100 is very safe. Note that it's + unusual to be able to get back the float you started with from + PyFloat_AsString's result -- use PyFloat_AsReprString() if you want to + preserve precision across conversions. */ +PyAPI_FUNC(void) PyFloat_AsString(char*, PyFloatObject *v); + +/* _PyFloat_{Pack,Unpack}{4,8} + * + * The struct and pickle (at least) modules need an efficient platform- + * independent way to store floating-point values as byte strings. + * The Pack routines produce a string from a C double, and the Unpack + * routines produce a C double from such a string. The suffix (4 or 8) + * specifies the number of bytes in the string. + * + * On platforms that appear to use (see _PyFloat_Init()) IEEE-754 formats + * these functions work by copying bits. On other platforms, the formats the + * 4- byte format is identical to the IEEE-754 single precision format, and + * the 8-byte format to the IEEE-754 double precision format, although the + * packing of INFs and NaNs (if such things exist on the platform) isn't + * handled correctly, and attempting to unpack a string containing an IEEE + * INF or NaN will raise an exception. + * + * On non-IEEE platforms with more precision, or larger dynamic range, than + * 754 supports, not all values can be packed; on non-IEEE platforms with less + * precision, or smaller dynamic range, not all values can be unpacked. What + * happens in such cases is partly accidental (alas). + */ + +/* The pack routines write 4 or 8 bytes, starting at p. le is a bool + * argument, true if you want the string in little-endian format (exponent + * last, at p+3 or p+7), false if you want big-endian format (exponent + * first, at p). + * Return value: 0 if all is OK, -1 if error (and an exception is + * set, most likely OverflowError). + * There are two problems on non-IEEE platforms: + * 1): What this does is undefined if x is a NaN or infinity. + * 2): -0.0 and +0.0 produce the same string. + */ +PyAPI_FUNC(int) _PyFloat_Pack4(double x, unsigned char *p, int le); +PyAPI_FUNC(int) _PyFloat_Pack8(double x, unsigned char *p, int le); + +/* The unpack routines read 4 or 8 bytes, starting at p. le is a bool + * argument, true if the string is in little-endian format (exponent + * last, at p+3 or p+7), false if big-endian (exponent first, at p). + * Return value: The unpacked double. On error, this is -1.0 and + * PyErr_Occurred() is true (and an exception is set, most likely + * OverflowError). Note that on a non-IEEE platform this will refuse + * to unpack a string that represents a NaN or infinity. + */ +PyAPI_FUNC(double) _PyFloat_Unpack4(const unsigned char *p, int le); +PyAPI_FUNC(double) _PyFloat_Unpack8(const unsigned char *p, int le); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FLOATOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/frameobject.h b/vscript/languages/python/python-2.5.1/include/frameobject.h new file mode 100644 index 00000000..794f6515 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/frameobject.h @@ -0,0 +1,81 @@ + +/* Frame object interface */ + +#ifndef Py_FRAMEOBJECT_H +#define Py_FRAMEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int b_type; /* what kind of block this is */ + int b_handler; /* where to jump to find handler */ + int b_level; /* value stack level to pop to */ +} PyTryBlock; + +typedef struct _frame { + PyObject_VAR_HEAD + struct _frame *f_back; /* previous frame, or NULL */ + PyCodeObject *f_code; /* code segment */ + PyObject *f_builtins; /* builtin symbol table (PyDictObject) */ + PyObject *f_globals; /* global symbol table (PyDictObject) */ + PyObject *f_locals; /* local symbol table (any mapping) */ + PyObject **f_valuestack; /* points after the last local */ + /* Next free slot in f_valuestack. Frame creation sets to f_valuestack. + Frame evaluation usually NULLs it, but a frame that yields sets it + to the current stack top. */ + PyObject **f_stacktop; + PyObject *f_trace; /* Trace function */ + + /* If an exception is raised in this frame, the next three are used to + * record the exception info (if any) originally in the thread state. See + * comments before set_exc_info() -- it's not obvious. + * Invariant: if _type is NULL, then so are _value and _traceback. + * Desired invariant: all three are NULL, or all three are non-NULL. That + * one isn't currently true, but "should be". + */ + PyObject *f_exc_type, *f_exc_value, *f_exc_traceback; + + PyThreadState *f_tstate; + int f_lasti; /* Last instruction if called */ + /* As of 2.3 f_lineno is only valid when tracing is active (i.e. when + f_trace is set) -- at other times use PyCode_Addr2Line instead. */ + int f_lineno; /* Current line number */ + int f_iblock; /* index in f_blockstack */ + PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */ + PyObject *f_localsplus[1]; /* locals+stack, dynamically sized */ +} PyFrameObject; + + +/* Standard object interface */ + +PyAPI_DATA(PyTypeObject) PyFrame_Type; + +#define PyFrame_Check(op) ((op)->ob_type == &PyFrame_Type) +#define PyFrame_IsRestricted(f) \ + ((f)->f_builtins != (f)->f_tstate->interp->builtins) + +PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *, + PyObject *, PyObject *); + + +/* The rest of the interface is specific for frame objects */ + +/* Block management functions */ + +PyAPI_FUNC(void) PyFrame_BlockSetup(PyFrameObject *, int, int, int); +PyAPI_FUNC(PyTryBlock *) PyFrame_BlockPop(PyFrameObject *); + +/* Extend the value stack */ + +PyAPI_FUNC(PyObject **) PyFrame_ExtendStack(PyFrameObject *, int, int); + +/* Conversions between "fast locals" and locals in dictionary */ + +PyAPI_FUNC(void) PyFrame_LocalsToFast(PyFrameObject *, int); +PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FRAMEOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/funcobject.h b/vscript/languages/python/python-2.5.1/include/funcobject.h new file mode 100644 index 00000000..59c19bb1 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/funcobject.h @@ -0,0 +1,76 @@ + +/* Function object interface */ + +#ifndef Py_FUNCOBJECT_H +#define Py_FUNCOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Function objects and code objects should not be confused with each other: + * + * Function objects are created by the execution of the 'def' statement. + * They reference a code object in their func_code attribute, which is a + * purely syntactic object, i.e. nothing more than a compiled version of some + * source code lines. There is one code object per source code "fragment", + * but each code object can be referenced by zero or many function objects + * depending only on how many times the 'def' statement in the source was + * executed so far. + */ + +typedef struct { + PyObject_HEAD + PyObject *func_code; /* A code object */ + PyObject *func_globals; /* A dictionary (other mappings won't do) */ + PyObject *func_defaults; /* NULL or a tuple */ + PyObject *func_closure; /* NULL or a tuple of cell objects */ + PyObject *func_doc; /* The __doc__ attribute, can be anything */ + PyObject *func_name; /* The __name__ attribute, a string object */ + PyObject *func_dict; /* The __dict__ attribute, a dict or NULL */ + PyObject *func_weakreflist; /* List of weak references */ + PyObject *func_module; /* The __module__ attribute, can be anything */ + + /* Invariant: + * func_closure contains the bindings for func_code->co_freevars, so + * PyTuple_Size(func_closure) == PyCode_GetNumFree(func_code) + * (func_closure may be NULL if PyCode_GetNumFree(func_code) == 0). + */ +} PyFunctionObject; + +PyAPI_DATA(PyTypeObject) PyFunction_Type; + +#define PyFunction_Check(op) ((op)->ob_type == &PyFunction_Type) + +PyAPI_FUNC(PyObject *) PyFunction_New(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetCode(PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetGlobals(PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetModule(PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetDefaults(PyObject *); +PyAPI_FUNC(int) PyFunction_SetDefaults(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetClosure(PyObject *); +PyAPI_FUNC(int) PyFunction_SetClosure(PyObject *, PyObject *); + +/* Macros for direct access to these values. Type checks are *not* + done, so use with care. */ +#define PyFunction_GET_CODE(func) \ + (((PyFunctionObject *)func) -> func_code) +#define PyFunction_GET_GLOBALS(func) \ + (((PyFunctionObject *)func) -> func_globals) +#define PyFunction_GET_MODULE(func) \ + (((PyFunctionObject *)func) -> func_module) +#define PyFunction_GET_DEFAULTS(func) \ + (((PyFunctionObject *)func) -> func_defaults) +#define PyFunction_GET_CLOSURE(func) \ + (((PyFunctionObject *)func) -> func_closure) + +/* The classmethod and staticmethod types lives here, too */ +PyAPI_DATA(PyTypeObject) PyClassMethod_Type; +PyAPI_DATA(PyTypeObject) PyStaticMethod_Type; + +PyAPI_FUNC(PyObject *) PyClassMethod_New(PyObject *); +PyAPI_FUNC(PyObject *) PyStaticMethod_New(PyObject *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FUNCOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/genobject.h b/vscript/languages/python/python-2.5.1/include/genobject.h new file mode 100644 index 00000000..ca844320 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/genobject.h @@ -0,0 +1,37 @@ + +/* Generator object interface */ + +#ifndef Py_GENOBJECT_H +#define Py_GENOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +struct _frame; /* Avoid including frameobject.h */ + +typedef struct { + PyObject_HEAD + /* The gi_ prefix is intended to remind of generator-iterator. */ + + /* Note: gi_frame can be NULL if the generator is "finished" */ + struct _frame *gi_frame; + + /* True if generator is being executed. */ + int gi_running; + + /* List of weak reference. */ + PyObject *gi_weakreflist; +} PyGenObject; + +PyAPI_DATA(PyTypeObject) PyGen_Type; + +#define PyGen_Check(op) PyObject_TypeCheck(op, &PyGen_Type) +#define PyGen_CheckExact(op) ((op)->ob_type == &PyGen_Type) + +PyAPI_FUNC(PyObject *) PyGen_New(struct _frame *); +PyAPI_FUNC(int) PyGen_NeedsFinalizing(PyGenObject *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_GENOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/graminit.h b/vscript/languages/python/python-2.5.1/include/graminit.h new file mode 100644 index 00000000..9af182a5 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/graminit.h @@ -0,0 +1,84 @@ +#define single_input 256 +#define file_input 257 +#define eval_input 258 +#define decorator 259 +#define decorators 260 +#define funcdef 261 +#define parameters 262 +#define varargslist 263 +#define fpdef 264 +#define fplist 265 +#define stmt 266 +#define simple_stmt 267 +#define small_stmt 268 +#define expr_stmt 269 +#define augassign 270 +#define print_stmt 271 +#define del_stmt 272 +#define pass_stmt 273 +#define flow_stmt 274 +#define break_stmt 275 +#define continue_stmt 276 +#define return_stmt 277 +#define yield_stmt 278 +#define raise_stmt 279 +#define import_stmt 280 +#define import_name 281 +#define import_from 282 +#define import_as_name 283 +#define dotted_as_name 284 +#define import_as_names 285 +#define dotted_as_names 286 +#define dotted_name 287 +#define global_stmt 288 +#define exec_stmt 289 +#define assert_stmt 290 +#define compound_stmt 291 +#define if_stmt 292 +#define while_stmt 293 +#define for_stmt 294 +#define try_stmt 295 +#define with_stmt 296 +#define with_var 297 +#define except_clause 298 +#define suite 299 +#define testlist_safe 300 +#define old_test 301 +#define old_lambdef 302 +#define test 303 +#define or_test 304 +#define and_test 305 +#define not_test 306 +#define comparison 307 +#define comp_op 308 +#define expr 309 +#define xor_expr 310 +#define and_expr 311 +#define shift_expr 312 +#define arith_expr 313 +#define term 314 +#define factor 315 +#define power 316 +#define atom 317 +#define listmaker 318 +#define testlist_gexp 319 +#define lambdef 320 +#define trailer 321 +#define subscriptlist 322 +#define subscript 323 +#define sliceop 324 +#define exprlist 325 +#define testlist 326 +#define dictmaker 327 +#define classdef 328 +#define arglist 329 +#define argument 330 +#define list_iter 331 +#define list_for 332 +#define list_if 333 +#define gen_iter 334 +#define gen_for 335 +#define gen_if 336 +#define testlist1 337 +#define encoding_decl 338 +#define yield_expr 339 diff --git a/vscript/languages/python/python-2.5.1/include/grammar.h b/vscript/languages/python/python-2.5.1/include/grammar.h new file mode 100644 index 00000000..8426da30 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/grammar.h @@ -0,0 +1,93 @@ + +/* Grammar interface */ + +#ifndef Py_GRAMMAR_H +#define Py_GRAMMAR_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "bitset.h" /* Sigh... */ + +/* A label of an arc */ + +typedef struct { + int lb_type; + char *lb_str; +} label; + +#define EMPTY 0 /* Label number 0 is by definition the empty label */ + +/* A list of labels */ + +typedef struct { + int ll_nlabels; + label *ll_label; +} labellist; + +/* An arc from one state to another */ + +typedef struct { + short a_lbl; /* Label of this arc */ + short a_arrow; /* State where this arc goes to */ +} arc; + +/* A state in a DFA */ + +typedef struct { + int s_narcs; + arc *s_arc; /* Array of arcs */ + + /* Optional accelerators */ + int s_lower; /* Lowest label index */ + int s_upper; /* Highest label index */ + int *s_accel; /* Accelerator */ + int s_accept; /* Nonzero for accepting state */ +} state; + +/* A DFA */ + +typedef struct { + int d_type; /* Non-terminal this represents */ + char *d_name; /* For printing */ + int d_initial; /* Initial state */ + int d_nstates; + state *d_state; /* Array of states */ + bitset d_first; +} dfa; + +/* A grammar */ + +typedef struct { + int g_ndfas; + dfa *g_dfa; /* Array of DFAs */ + labellist g_ll; + int g_start; /* Start symbol of the grammar */ + int g_accel; /* Set if accelerators present */ +} grammar; + +/* FUNCTIONS */ + +grammar *newgrammar(int start); +dfa *adddfa(grammar *g, int type, char *name); +int addstate(dfa *d); +void addarc(dfa *d, int from, int to, int lbl); +dfa *PyGrammar_FindDFA(grammar *g, int type); + +int addlabel(labellist *ll, int type, char *str); +int findlabel(labellist *ll, int type, char *str); +char *PyGrammar_LabelRepr(label *lb); +void translatelabels(grammar *g); + +void addfirstsets(grammar *g); + +void PyGrammar_AddAccelerators(grammar *g); +void PyGrammar_RemoveAccelerators(grammar *); + +void printgrammar(grammar *g, FILE *fp); +void printnonterminals(grammar *g, FILE *fp); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_GRAMMAR_H */ diff --git a/vscript/languages/python/python-2.5.1/include/import.h b/vscript/languages/python/python-2.5.1/include/import.h new file mode 100644 index 00000000..414e059a --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/import.h @@ -0,0 +1,64 @@ + +/* Module definition and import interface */ + +#ifndef Py_IMPORT_H +#define Py_IMPORT_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(long) PyImport_GetMagicNumber(void); +PyAPI_FUNC(PyObject *) PyImport_ExecCodeModule(char *name, PyObject *co); +PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleEx( + char *name, PyObject *co, char *pathname); +PyAPI_FUNC(PyObject *) PyImport_GetModuleDict(void); +PyAPI_FUNC(PyObject *) PyImport_AddModule(const char *name); +PyAPI_FUNC(PyObject *) PyImport_ImportModule(const char *name); +PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevel(char *name, + PyObject *globals, PyObject *locals, PyObject *fromlist, int level); + +/* For DLL compatibility */ +#undef PyImport_ImportModuleEx +PyAPI_FUNC(PyObject *) PyImport_ImportModuleEx( + char *name, PyObject *globals, PyObject *locals, PyObject *fromlist); +#define PyImport_ImportModuleEx(n, g, l, f) \ + PyImport_ImportModuleLevel(n, g, l, f, -1) + +PyAPI_FUNC(PyObject *) PyImport_Import(PyObject *name); +PyAPI_FUNC(PyObject *) PyImport_ReloadModule(PyObject *m); +PyAPI_FUNC(void) PyImport_Cleanup(void); +PyAPI_FUNC(int) PyImport_ImportFrozenModule(char *); + +PyAPI_FUNC(struct filedescr *) _PyImport_FindModule( + const char *, PyObject *, char *, size_t, FILE **, PyObject **); +PyAPI_FUNC(int) _PyImport_IsScript(struct filedescr *); +PyAPI_FUNC(void) _PyImport_ReInitLock(void); + +PyAPI_FUNC(PyObject *)_PyImport_FindExtension(char *, char *); +PyAPI_FUNC(PyObject *)_PyImport_FixupExtension(char *, char *); + +struct _inittab { + char *name; + void (*initfunc)(void); +}; + +PyAPI_DATA(struct _inittab *) PyImport_Inittab; + +PyAPI_FUNC(int) PyImport_AppendInittab(char *name, void (*initfunc)(void)); +PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab); + +struct _frozen { + char *name; + unsigned char *code; + int size; +}; + +/* Embedding apps may change this pointer to point to their favorite + collection of frozen modules: */ + +PyAPI_DATA(struct _frozen *) PyImport_FrozenModules; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_IMPORT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/intobject.h b/vscript/languages/python/python-2.5.1/include/intobject.h new file mode 100644 index 00000000..1f4846e8 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/intobject.h @@ -0,0 +1,64 @@ + +/* Integer object interface */ + +/* +PyIntObject represents a (long) integer. This is an immutable object; +an integer cannot change its value after creation. + +There are functions to create new integer objects, to test an object +for integer-ness, and to get the integer value. The latter functions +returns -1 and sets errno to EBADF if the object is not an PyIntObject. +None of the functions should be applied to nil objects. + +The type PyIntObject is (unfortunately) exposed here so we can declare +_Py_TrueStruct and _Py_ZeroStruct in boolobject.h; don't use this. +*/ + +#ifndef Py_INTOBJECT_H +#define Py_INTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_HEAD + long ob_ival; +} PyIntObject; + +PyAPI_DATA(PyTypeObject) PyInt_Type; + +#define PyInt_Check(op) PyObject_TypeCheck(op, &PyInt_Type) +#define PyInt_CheckExact(op) ((op)->ob_type == &PyInt_Type) + +PyAPI_FUNC(PyObject *) PyInt_FromString(char*, char**, int); +#ifdef Py_USING_UNICODE +PyAPI_FUNC(PyObject *) PyInt_FromUnicode(Py_UNICODE*, Py_ssize_t, int); +#endif +PyAPI_FUNC(PyObject *) PyInt_FromLong(long); +PyAPI_FUNC(PyObject *) PyInt_FromSize_t(size_t); +PyAPI_FUNC(PyObject *) PyInt_FromSsize_t(Py_ssize_t); +PyAPI_FUNC(long) PyInt_AsLong(PyObject *); +PyAPI_FUNC(Py_ssize_t) PyInt_AsSsize_t(PyObject *); +PyAPI_FUNC(unsigned long) PyInt_AsUnsignedLongMask(PyObject *); +#ifdef HAVE_LONG_LONG +PyAPI_FUNC(unsigned PY_LONG_LONG) PyInt_AsUnsignedLongLongMask(PyObject *); +#endif + +PyAPI_FUNC(long) PyInt_GetMax(void); + +/* Macro, trading safety for speed */ +#define PyInt_AS_LONG(op) (((PyIntObject *)(op))->ob_ival) + +/* These aren't really part of the Int object, but they're handy; the protos + * are necessary for systems that need the magic of PyAPI_FUNC and that want + * to have stropmodule as a dynamically loaded module instead of building it + * into the main Python shared library/DLL. Guido thinks I'm weird for + * building it this way. :-) [cjh] + */ +PyAPI_FUNC(unsigned long) PyOS_strtoul(char *, char **, int); +PyAPI_FUNC(long) PyOS_strtol(char *, char **, int); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/intrcheck.h b/vscript/languages/python/python-2.5.1/include/intrcheck.h new file mode 100644 index 00000000..3b67ed0d --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/intrcheck.h @@ -0,0 +1,15 @@ + +#ifndef Py_INTRCHECK_H +#define Py_INTRCHECK_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(int) PyOS_InterruptOccurred(void); +PyAPI_FUNC(void) PyOS_InitInterrupts(void); +PyAPI_FUNC(void) PyOS_AfterFork(void); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTRCHECK_H */ diff --git a/vscript/languages/python/python-2.5.1/include/iterobject.h b/vscript/languages/python/python-2.5.1/include/iterobject.h new file mode 100644 index 00000000..c078ebb2 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/iterobject.h @@ -0,0 +1,23 @@ +#ifndef Py_ITEROBJECT_H +#define Py_ITEROBJECT_H +/* Iterators (the basic kind, over a sequence) */ +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PySeqIter_Type; + +#define PySeqIter_Check(op) ((op)->ob_type == &PySeqIter_Type) + +PyAPI_FUNC(PyObject *) PySeqIter_New(PyObject *); + +PyAPI_DATA(PyTypeObject) PyCallIter_Type; + +#define PyCallIter_Check(op) ((op)->ob_type == &PyCallIter_Type) + +PyAPI_FUNC(PyObject *) PyCallIter_New(PyObject *, PyObject *); +#ifdef __cplusplus +} +#endif +#endif /* !Py_ITEROBJECT_H */ + diff --git a/vscript/languages/python/python-2.5.1/include/listobject.h b/vscript/languages/python/python-2.5.1/include/listobject.h new file mode 100644 index 00000000..d9012ce9 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/listobject.h @@ -0,0 +1,67 @@ + +/* List object interface */ + +/* +Another generally useful object type is an list of object pointers. +This is a mutable type: the list items can be changed, and items can be +added or removed. Out-of-range indices or non-list objects are ignored. + +*** WARNING *** PyList_SetItem does not increment the new item's reference +count, but does decrement the reference count of the item it replaces, +if not nil. It does *decrement* the reference count if it is *not* +inserted in the list. Similarly, PyList_GetItem does not increment the +returned item's reference count. +*/ + +#ifndef Py_LISTOBJECT_H +#define Py_LISTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_VAR_HEAD + /* Vector of pointers to list elements. list[0] is ob_item[0], etc. */ + PyObject **ob_item; + + /* ob_item contains space for 'allocated' elements. The number + * currently in use is ob_size. + * Invariants: + * 0 <= ob_size <= allocated + * len(list) == ob_size + * ob_item == NULL implies ob_size == allocated == 0 + * list.sort() temporarily sets allocated to -1 to detect mutations. + * + * Items must normally not be NULL, except during construction when + * the list is not yet visible outside the function that builds it. + */ + Py_ssize_t allocated; +} PyListObject; + +PyAPI_DATA(PyTypeObject) PyList_Type; + +#define PyList_Check(op) PyObject_TypeCheck(op, &PyList_Type) +#define PyList_CheckExact(op) ((op)->ob_type == &PyList_Type) + +PyAPI_FUNC(PyObject *) PyList_New(Py_ssize_t size); +PyAPI_FUNC(Py_ssize_t) PyList_Size(PyObject *); +PyAPI_FUNC(PyObject *) PyList_GetItem(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyList_SetItem(PyObject *, Py_ssize_t, PyObject *); +PyAPI_FUNC(int) PyList_Insert(PyObject *, Py_ssize_t, PyObject *); +PyAPI_FUNC(int) PyList_Append(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyList_GetSlice(PyObject *, Py_ssize_t, Py_ssize_t); +PyAPI_FUNC(int) PyList_SetSlice(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *); +PyAPI_FUNC(int) PyList_Sort(PyObject *); +PyAPI_FUNC(int) PyList_Reverse(PyObject *); +PyAPI_FUNC(PyObject *) PyList_AsTuple(PyObject *); +PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *); + +/* Macro, trading safety for speed */ +#define PyList_GET_ITEM(op, i) (((PyListObject *)(op))->ob_item[i]) +#define PyList_SET_ITEM(op, i, v) (((PyListObject *)(op))->ob_item[i] = (v)) +#define PyList_GET_SIZE(op) (((PyListObject *)(op))->ob_size) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_LISTOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/longintrepr.h b/vscript/languages/python/python-2.5.1/include/longintrepr.h new file mode 100644 index 00000000..b1574ba5 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/longintrepr.h @@ -0,0 +1,63 @@ +#ifndef Py_LONGINTREPR_H +#define Py_LONGINTREPR_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* This is published for the benefit of "friend" marshal.c only. */ + +/* Parameters of the long integer representation. + These shouldn't have to be changed as C should guarantee that a short + contains at least 16 bits, but it's made changeable anyway. + Note: 'digit' should be able to hold 2*MASK+1, and 'twodigits' + should be able to hold the intermediate results in 'mul' + (at most (BASE-1)*(2*BASE+1) == MASK*(2*MASK+3)). + Also, x_sub assumes that 'digit' is an unsigned type, and overflow + is handled by taking the result mod 2**N for some N > SHIFT. + And, at some places it is assumed that MASK fits in an int, as well. + long_pow() requires that SHIFT be divisible by 5. */ + +typedef unsigned short digit; +typedef unsigned int wdigit; /* digit widened to parameter size */ +#define BASE_TWODIGITS_TYPE long +typedef unsigned BASE_TWODIGITS_TYPE twodigits; +typedef BASE_TWODIGITS_TYPE stwodigits; /* signed variant of twodigits */ + +#define SHIFT 15 +#define BASE ((digit)1 << SHIFT) +#define MASK ((int)(BASE - 1)) + +#if SHIFT % 5 != 0 +#error "longobject.c requires that SHIFT be divisible by 5" +#endif + +/* Long integer representation. + The absolute value of a number is equal to + SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i) + Negative numbers are represented with ob_size < 0; + zero is represented by ob_size == 0. + In a normalized number, ob_digit[abs(ob_size)-1] (the most significant + digit) is never zero. Also, in all cases, for all valid i, + 0 <= ob_digit[i] <= MASK. + The allocation function takes care of allocating extra memory + so that ob_digit[0] ... ob_digit[abs(ob_size)-1] are actually available. + + CAUTION: Generic code manipulating subtypes of PyVarObject has to + aware that longs abuse ob_size's sign bit. +*/ + +struct _longobject { + PyObject_VAR_HEAD + digit ob_digit[1]; +}; + +PyAPI_FUNC(PyLongObject *) _PyLong_New(Py_ssize_t); + +/* Return a copy of src. */ +PyAPI_FUNC(PyObject *) _PyLong_Copy(PyLongObject *src); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_LONGINTREPR_H */ diff --git a/vscript/languages/python/python-2.5.1/include/longobject.h b/vscript/languages/python/python-2.5.1/include/longobject.h new file mode 100644 index 00000000..eef4e9b4 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/longobject.h @@ -0,0 +1,114 @@ +#ifndef Py_LONGOBJECT_H +#define Py_LONGOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Long (arbitrary precision) integer object interface */ + +typedef struct _longobject PyLongObject; /* Revealed in longintrepr.h */ + +PyAPI_DATA(PyTypeObject) PyLong_Type; + +#define PyLong_Check(op) PyObject_TypeCheck(op, &PyLong_Type) +#define PyLong_CheckExact(op) ((op)->ob_type == &PyLong_Type) + +PyAPI_FUNC(PyObject *) PyLong_FromLong(long); +PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLong(unsigned long); +PyAPI_FUNC(PyObject *) PyLong_FromDouble(double); +PyAPI_FUNC(long) PyLong_AsLong(PyObject *); +PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLong(PyObject *); +PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLongMask(PyObject *); + +/* For use by intobject.c only */ +PyAPI_FUNC(Py_ssize_t) _PyLong_AsSsize_t(PyObject *); +PyAPI_FUNC(PyObject *) _PyLong_FromSize_t(size_t); +PyAPI_FUNC(PyObject *) _PyLong_FromSsize_t(Py_ssize_t); +PyAPI_DATA(int) _PyLong_DigitValue[256]; + +/* _PyLong_AsScaledDouble returns a double x and an exponent e such that + the true value is approximately equal to x * 2**(SHIFT*e). e is >= 0. + x is 0.0 if and only if the input is 0 (in which case, e and x are both + zeroes). Overflow is impossible. Note that the exponent returned must + be multiplied by SHIFT! There may not be enough room in an int to store + e*SHIFT directly. */ +PyAPI_FUNC(double) _PyLong_AsScaledDouble(PyObject *vv, int *e); + +PyAPI_FUNC(double) PyLong_AsDouble(PyObject *); +PyAPI_FUNC(PyObject *) PyLong_FromVoidPtr(void *); +PyAPI_FUNC(void *) PyLong_AsVoidPtr(PyObject *); + +#ifdef HAVE_LONG_LONG +PyAPI_FUNC(PyObject *) PyLong_FromLongLong(PY_LONG_LONG); +PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG); +PyAPI_FUNC(PY_LONG_LONG) PyLong_AsLongLong(PyObject *); +PyAPI_FUNC(unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLong(PyObject *); +PyAPI_FUNC(unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLongMask(PyObject *); +#endif /* HAVE_LONG_LONG */ + +PyAPI_FUNC(PyObject *) PyLong_FromString(char *, char **, int); +#ifdef Py_USING_UNICODE +PyAPI_FUNC(PyObject *) PyLong_FromUnicode(Py_UNICODE*, Py_ssize_t, int); +#endif + +/* _PyLong_Sign. Return 0 if v is 0, -1 if v < 0, +1 if v > 0. + v must not be NULL, and must be a normalized long. + There are no error cases. +*/ +PyAPI_FUNC(int) _PyLong_Sign(PyObject *v); + + +/* _PyLong_NumBits. Return the number of bits needed to represent the + absolute value of a long. For example, this returns 1 for 1 and -1, 2 + for 2 and -2, and 2 for 3 and -3. It returns 0 for 0. + v must not be NULL, and must be a normalized long. + (size_t)-1 is returned and OverflowError set if the true result doesn't + fit in a size_t. +*/ +PyAPI_FUNC(size_t) _PyLong_NumBits(PyObject *v); + +/* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in + base 256, and return a Python long with the same numeric value. + If n is 0, the integer is 0. Else: + If little_endian is 1/true, bytes[n-1] is the MSB and bytes[0] the LSB; + else (little_endian is 0/false) bytes[0] is the MSB and bytes[n-1] the + LSB. + If is_signed is 0/false, view the bytes as a non-negative integer. + If is_signed is 1/true, view the bytes as a 2's-complement integer, + non-negative if bit 0x80 of the MSB is clear, negative if set. + Error returns: + + Return NULL with the appropriate exception set if there's not + enough memory to create the Python long. +*/ +PyAPI_FUNC(PyObject *) _PyLong_FromByteArray( + const unsigned char* bytes, size_t n, + int little_endian, int is_signed); + +/* _PyLong_AsByteArray: Convert the least-significant 8*n bits of long + v to a base-256 integer, stored in array bytes. Normally return 0, + return -1 on error. + If little_endian is 1/true, store the MSB at bytes[n-1] and the LSB at + bytes[0]; else (little_endian is 0/false) store the MSB at bytes[0] and + the LSB at bytes[n-1]. + If is_signed is 0/false, it's an error if v < 0; else (v >= 0) n bytes + are filled and there's nothing special about bit 0x80 of the MSB. + If is_signed is 1/true, bytes is filled with the 2's-complement + representation of v's value. Bit 0x80 of the MSB is the sign bit. + Error returns (-1): + + is_signed is 0 and v < 0. TypeError is set in this case, and bytes + isn't altered. + + n isn't big enough to hold the full mathematical value of v. For + example, if is_signed is 0 and there are more digits in the v than + fit in n; or if is_signed is 1, v < 0, and n is just 1 bit shy of + being large enough to hold a sign bit. OverflowError is set in this + case, but bytes holds the least-signficant n bytes of the true value. +*/ +PyAPI_FUNC(int) _PyLong_AsByteArray(PyLongObject* v, + unsigned char* bytes, size_t n, + int little_endian, int is_signed); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_LONGOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/marshal.h b/vscript/languages/python/python-2.5.1/include/marshal.h new file mode 100644 index 00000000..411fdca3 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/marshal.h @@ -0,0 +1,25 @@ + +/* Interface for marshal.c */ + +#ifndef Py_MARSHAL_H +#define Py_MARSHAL_H +#ifdef __cplusplus +extern "C" { +#endif + +#define Py_MARSHAL_VERSION 2 + +PyAPI_FUNC(void) PyMarshal_WriteLongToFile(long, FILE *, int); +PyAPI_FUNC(void) PyMarshal_WriteObjectToFile(PyObject *, FILE *, int); +PyAPI_FUNC(PyObject *) PyMarshal_WriteObjectToString(PyObject *, int); + +PyAPI_FUNC(long) PyMarshal_ReadLongFromFile(FILE *); +PyAPI_FUNC(int) PyMarshal_ReadShortFromFile(FILE *); +PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromFile(FILE *); +PyAPI_FUNC(PyObject *) PyMarshal_ReadLastObjectFromFile(FILE *); +PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(char *, Py_ssize_t); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_MARSHAL_H */ diff --git a/vscript/languages/python/python-2.5.1/include/metagrammar.h b/vscript/languages/python/python-2.5.1/include/metagrammar.h new file mode 100644 index 00000000..15c8ef8f --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/metagrammar.h @@ -0,0 +1,18 @@ +#ifndef Py_METAGRAMMAR_H +#define Py_METAGRAMMAR_H +#ifdef __cplusplus +extern "C" { +#endif + + +#define MSTART 256 +#define RULE 257 +#define RHS 258 +#define ALT 259 +#define ITEM 260 +#define ATOM 261 + +#ifdef __cplusplus +} +#endif +#endif /* !Py_METAGRAMMAR_H */ diff --git a/vscript/languages/python/python-2.5.1/include/methodobject.h b/vscript/languages/python/python-2.5.1/include/methodobject.h new file mode 100644 index 00000000..c887d947 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/methodobject.h @@ -0,0 +1,91 @@ + +/* Method object interface */ + +#ifndef Py_METHODOBJECT_H +#define Py_METHODOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* This is about the type 'builtin_function_or_method', + not Python methods in user-defined classes. See classobject.h + for the latter. */ + +PyAPI_DATA(PyTypeObject) PyCFunction_Type; + +#define PyCFunction_Check(op) ((op)->ob_type == &PyCFunction_Type) + +typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); +typedef PyObject *(*PyCFunctionWithKeywords)(PyObject *, PyObject *, + PyObject *); +typedef PyObject *(*PyNoArgsFunction)(PyObject *); + +PyAPI_FUNC(PyCFunction) PyCFunction_GetFunction(PyObject *); +PyAPI_FUNC(PyObject *) PyCFunction_GetSelf(PyObject *); +PyAPI_FUNC(int) PyCFunction_GetFlags(PyObject *); + +/* Macros for direct access to these values. Type checks are *not* + done, so use with care. */ +#define PyCFunction_GET_FUNCTION(func) \ + (((PyCFunctionObject *)func) -> m_ml -> ml_meth) +#define PyCFunction_GET_SELF(func) \ + (((PyCFunctionObject *)func) -> m_self) +#define PyCFunction_GET_FLAGS(func) \ + (((PyCFunctionObject *)func) -> m_ml -> ml_flags) +PyAPI_FUNC(PyObject *) PyCFunction_Call(PyObject *, PyObject *, PyObject *); + +struct PyMethodDef { + const char *ml_name; /* The name of the built-in function/method */ + PyCFunction ml_meth; /* The C function that implements it */ + int ml_flags; /* Combination of METH_xxx flags, which mostly + describe the args expected by the C func */ + const char *ml_doc; /* The __doc__ attribute, or NULL */ +}; +typedef struct PyMethodDef PyMethodDef; + +PyAPI_FUNC(PyObject *) Py_FindMethod(PyMethodDef[], PyObject *, const char *); + +#define PyCFunction_New(ML, SELF) PyCFunction_NewEx((ML), (SELF), NULL) +PyAPI_FUNC(PyObject *) PyCFunction_NewEx(PyMethodDef *, PyObject *, + PyObject *); + +/* Flag passed to newmethodobject */ +#define METH_OLDARGS 0x0000 +#define METH_VARARGS 0x0001 +#define METH_KEYWORDS 0x0002 +/* METH_NOARGS and METH_O must not be combined with the flags above. */ +#define METH_NOARGS 0x0004 +#define METH_O 0x0008 + +/* METH_CLASS and METH_STATIC are a little different; these control + the construction of methods for a class. These cannot be used for + functions in modules. */ +#define METH_CLASS 0x0010 +#define METH_STATIC 0x0020 + +/* METH_COEXIST allows a method to be entered eventhough a slot has + already filled the entry. When defined, the flag allows a separate + method, "__contains__" for example, to coexist with a defined + slot like sq_contains. */ + +#define METH_COEXIST 0x0040 + +typedef struct PyMethodChain { + PyMethodDef *methods; /* Methods of this type */ + struct PyMethodChain *link; /* NULL or base type */ +} PyMethodChain; + +PyAPI_FUNC(PyObject *) Py_FindMethodInChain(PyMethodChain *, PyObject *, + const char *); + +typedef struct { + PyObject_HEAD + PyMethodDef *m_ml; /* Description of the C function to call */ + PyObject *m_self; /* Passed as 'self' arg to the C func, can be NULL */ + PyObject *m_module; /* The __module__ attribute, can be anything */ +} PyCFunctionObject; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_METHODOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/modsupport.h b/vscript/languages/python/python-2.5.1/include/modsupport.h new file mode 100644 index 00000000..23d5d3a0 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/modsupport.h @@ -0,0 +1,133 @@ + +#ifndef Py_MODSUPPORT_H +#define Py_MODSUPPORT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Module support interface */ + +#include + +/* If PY_SSIZE_T_CLEAN is defined, each functions treats #-specifier + to mean Py_ssize_t */ +#ifdef PY_SSIZE_T_CLEAN +#define PyArg_Parse _PyArg_Parse_SizeT +#define PyArg_ParseTuple _PyArg_ParseTuple_SizeT +#define PyArg_ParseTupleAndKeywords _PyArg_ParseTupleAndKeywords_SizeT +#define PyArg_VaParse _PyArg_VaParse_SizeT +#define PyArg_VaParseTupleAndKeywords _PyArg_VaParseTupleAndKeywords_SizeT +#define Py_BuildValue _Py_BuildValue_SizeT +#define Py_VaBuildValue _Py_VaBuildValue_SizeT +#else +PyAPI_FUNC(PyObject *) _Py_VaBuildValue_SizeT(const char *, va_list); +#endif + +PyAPI_FUNC(int) PyArg_Parse(PyObject *, const char *, ...); +PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...); +PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, + const char *, char **, ...); +PyAPI_FUNC(int) PyArg_UnpackTuple(PyObject *, const char *, Py_ssize_t, Py_ssize_t, ...); +PyAPI_FUNC(PyObject *) Py_BuildValue(const char *, ...); +PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...); +PyAPI_FUNC(int) _PyArg_NoKeywords(const char *funcname, PyObject *kw); + +PyAPI_FUNC(int) PyArg_VaParse(PyObject *, const char *, va_list); +PyAPI_FUNC(int) PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *, + const char *, char **, va_list); +PyAPI_FUNC(PyObject *) Py_VaBuildValue(const char *, va_list); + +PyAPI_FUNC(int) PyModule_AddObject(PyObject *, const char *, PyObject *); +PyAPI_FUNC(int) PyModule_AddIntConstant(PyObject *, const char *, long); +PyAPI_FUNC(int) PyModule_AddStringConstant(PyObject *, const char *, const char *); + + +#define PYTHON_API_VERSION 1013 +#define PYTHON_API_STRING "1013" +/* The API version is maintained (independently from the Python version) + so we can detect mismatches between the interpreter and dynamically + loaded modules. These are diagnosed by an error message but + the module is still loaded (because the mismatch can only be tested + after loading the module). The error message is intended to + explain the core dump a few seconds later. + + The symbol PYTHON_API_STRING defines the same value as a string + literal. *** PLEASE MAKE SURE THE DEFINITIONS MATCH. *** + + Please add a line or two to the top of this log for each API + version change: + + 22-Feb-2006 MvL 1013 PEP 353 - long indices for sequence lengths + + 19-Aug-2002 GvR 1012 Changes to string object struct for + interning changes, saving 3 bytes. + + 17-Jul-2001 GvR 1011 Descr-branch, just to be on the safe side + + 25-Jan-2001 FLD 1010 Parameters added to PyCode_New() and + PyFrame_New(); Python 2.1a2 + + 14-Mar-2000 GvR 1009 Unicode API added + + 3-Jan-1999 GvR 1007 Decided to change back! (Don't reuse 1008!) + + 3-Dec-1998 GvR 1008 Python 1.5.2b1 + + 18-Jan-1997 GvR 1007 string interning and other speedups + + 11-Oct-1996 GvR renamed Py_Ellipses to Py_Ellipsis :-( + + 30-Jul-1996 GvR Slice and ellipses syntax added + + 23-Jul-1996 GvR For 1.4 -- better safe than sorry this time :-) + + 7-Nov-1995 GvR Keyword arguments (should've been done at 1.3 :-( ) + + 10-Jan-1995 GvR Renamed globals to new naming scheme + + 9-Jan-1995 GvR Initial version (incompatible with older API) +*/ + +#ifdef MS_WINDOWS +/* Special defines for Windows versions used to live here. Things + have changed, and the "Version" is now in a global string variable. + Reason for this is that this for easier branding of a "custom DLL" + without actually needing a recompile. */ +#endif /* MS_WINDOWS */ + +#if SIZEOF_SIZE_T != SIZEOF_INT +/* On a 64-bit system, rename the Py_InitModule4 so that 2.4 + modules cannot get loaded into a 2.5 interpreter */ +#define Py_InitModule4 Py_InitModule4_64 +#endif + +#ifdef Py_TRACE_REFS + /* When we are tracing reference counts, rename Py_InitModule4 so + modules compiled with incompatible settings will generate a + link-time error. */ + #if SIZEOF_SIZE_T != SIZEOF_INT + #undef Py_InitModule4 + #define Py_InitModule4 Py_InitModule4TraceRefs_64 + #else + #define Py_InitModule4 Py_InitModule4TraceRefs + #endif +#endif + +PyAPI_FUNC(PyObject *) Py_InitModule4(const char *name, PyMethodDef *methods, + const char *doc, PyObject *self, + int apiver); + +#define Py_InitModule(name, methods) \ + Py_InitModule4(name, methods, (char *)NULL, (PyObject *)NULL, \ + PYTHON_API_VERSION) + +#define Py_InitModule3(name, methods, doc) \ + Py_InitModule4(name, methods, doc, (PyObject *)NULL, \ + PYTHON_API_VERSION) + +PyAPI_DATA(char *) _Py_PackageContext; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_MODSUPPORT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/moduleobject.h b/vscript/languages/python/python-2.5.1/include/moduleobject.h new file mode 100644 index 00000000..3d278af8 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/moduleobject.h @@ -0,0 +1,24 @@ + +/* Module object interface */ + +#ifndef Py_MODULEOBJECT_H +#define Py_MODULEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyModule_Type; + +#define PyModule_Check(op) PyObject_TypeCheck(op, &PyModule_Type) +#define PyModule_CheckExact(op) ((op)->ob_type == &PyModule_Type) + +PyAPI_FUNC(PyObject *) PyModule_New(const char *); +PyAPI_FUNC(PyObject *) PyModule_GetDict(PyObject *); +PyAPI_FUNC(char *) PyModule_GetName(PyObject *); +PyAPI_FUNC(char *) PyModule_GetFilename(PyObject *); +PyAPI_FUNC(void) _PyModule_Clear(PyObject *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_MODULEOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/node.h b/vscript/languages/python/python-2.5.1/include/node.h new file mode 100644 index 00000000..e23e709f --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/node.h @@ -0,0 +1,40 @@ + +/* Parse tree node interface */ + +#ifndef Py_NODE_H +#define Py_NODE_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _node { + short n_type; + char *n_str; + int n_lineno; + int n_col_offset; + int n_nchildren; + struct _node *n_child; +} node; + +PyAPI_FUNC(node *) PyNode_New(int type); +PyAPI_FUNC(int) PyNode_AddChild(node *n, int type, + char *str, int lineno, int col_offset); +PyAPI_FUNC(void) PyNode_Free(node *n); + +/* Node access functions */ +#define NCH(n) ((n)->n_nchildren) + +#define CHILD(n, i) (&(n)->n_child[i]) +#define RCHILD(n, i) (CHILD(n, NCH(n) + i)) +#define TYPE(n) ((n)->n_type) +#define STR(n) ((n)->n_str) + +/* Assert that the type of a node is what we expect */ +#define REQ(n, type) assert(TYPE(n) == (type)) + +PyAPI_FUNC(void) PyNode_ListTree(node *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_NODE_H */ diff --git a/vscript/languages/python/python-2.5.1/include/object.h b/vscript/languages/python/python-2.5.1/include/object.h new file mode 100644 index 00000000..b0817e6e --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/object.h @@ -0,0 +1,868 @@ +#ifndef Py_OBJECT_H +#define Py_OBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Object and type object interface */ + +/* +Objects are structures allocated on the heap. Special rules apply to +the use of objects to ensure they are properly garbage-collected. +Objects are never allocated statically or on the stack; they must be +accessed through special macros and functions only. (Type objects are +exceptions to the first rule; the standard types are represented by +statically initialized type objects, although work on type/class unification +for Python 2.2 made it possible to have heap-allocated type objects too). + +An object has a 'reference count' that is increased or decreased when a +pointer to the object is copied or deleted; when the reference count +reaches zero there are no references to the object left and it can be +removed from the heap. + +An object has a 'type' that determines what it represents and what kind +of data it contains. An object's type is fixed when it is created. +Types themselves are represented as objects; an object contains a +pointer to the corresponding type object. The type itself has a type +pointer pointing to the object representing the type 'type', which +contains a pointer to itself!). + +Objects do not float around in memory; once allocated an object keeps +the same size and address. Objects that must hold variable-size data +can contain pointers to variable-size parts of the object. Not all +objects of the same type have the same size; but the size cannot change +after allocation. (These restrictions are made so a reference to an +object can be simply a pointer -- moving an object would require +updating all the pointers, and changing an object's size would require +moving it if there was another object right next to it.) + +Objects are always accessed through pointers of the type 'PyObject *'. +The type 'PyObject' is a structure that only contains the reference count +and the type pointer. The actual memory allocated for an object +contains other data that can only be accessed after casting the pointer +to a pointer to a longer structure type. This longer type must start +with the reference count and type fields; the macro PyObject_HEAD should be +used for this (to accommodate for future changes). The implementation +of a particular object type can cast the object pointer to the proper +type and back. + +A standard interface exists for objects that contain an array of items +whose size is determined when the object is allocated. +*/ + +/* Py_DEBUG implies Py_TRACE_REFS. */ +#if defined(Py_DEBUG) && !defined(Py_TRACE_REFS) +#define Py_TRACE_REFS +#endif + +/* Py_TRACE_REFS implies Py_REF_DEBUG. */ +#if defined(Py_TRACE_REFS) && !defined(Py_REF_DEBUG) +#define Py_REF_DEBUG +#endif + +#ifdef Py_TRACE_REFS +/* Define pointers to support a doubly-linked list of all live heap objects. */ +#define _PyObject_HEAD_EXTRA \ + struct _object *_ob_next; \ + struct _object *_ob_prev; + +#define _PyObject_EXTRA_INIT 0, 0, + +#else +#define _PyObject_HEAD_EXTRA +#define _PyObject_EXTRA_INIT +#endif + +/* PyObject_HEAD defines the initial segment of every PyObject. */ +#define PyObject_HEAD \ + _PyObject_HEAD_EXTRA \ + Py_ssize_t ob_refcnt; \ + struct _typeobject *ob_type; + +#define PyObject_HEAD_INIT(type) \ + _PyObject_EXTRA_INIT \ + 1, type, + +/* PyObject_VAR_HEAD defines the initial segment of all variable-size + * container objects. These end with a declaration of an array with 1 + * element, but enough space is malloc'ed so that the array actually + * has room for ob_size elements. Note that ob_size is an element count, + * not necessarily a byte count. + */ +#define PyObject_VAR_HEAD \ + PyObject_HEAD \ + Py_ssize_t ob_size; /* Number of items in variable part */ +#define Py_INVALID_SIZE (Py_ssize_t)-1 + +/* Nothing is actually declared to be a PyObject, but every pointer to + * a Python object can be cast to a PyObject*. This is inheritance built + * by hand. Similarly every pointer to a variable-size Python object can, + * in addition, be cast to PyVarObject*. + */ +typedef struct _object { + PyObject_HEAD +} PyObject; + +typedef struct { + PyObject_VAR_HEAD +} PyVarObject; + + +/* +Type objects contain a string containing the type name (to help somewhat +in debugging), the allocation parameters (see PyObject_New() and +PyObject_NewVar()), +and methods for accessing objects of the type. Methods are optional, a +nil pointer meaning that particular kind of access is not available for +this type. The Py_DECREF() macro uses the tp_dealloc method without +checking for a nil pointer; it should always be implemented except if +the implementation can guarantee that the reference count will never +reach zero (e.g., for statically allocated type objects). + +NB: the methods for certain type groups are now contained in separate +method blocks. +*/ + +typedef PyObject * (*unaryfunc)(PyObject *); +typedef PyObject * (*binaryfunc)(PyObject *, PyObject *); +typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *); +typedef int (*inquiry)(PyObject *); +typedef Py_ssize_t (*lenfunc)(PyObject *); +typedef int (*coercion)(PyObject **, PyObject **); +typedef PyObject *(*intargfunc)(PyObject *, int) Py_DEPRECATED(2.5); +typedef PyObject *(*intintargfunc)(PyObject *, int, int) Py_DEPRECATED(2.5); +typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t); +typedef PyObject *(*ssizessizeargfunc)(PyObject *, Py_ssize_t, Py_ssize_t); +typedef int(*intobjargproc)(PyObject *, int, PyObject *); +typedef int(*intintobjargproc)(PyObject *, int, int, PyObject *); +typedef int(*ssizeobjargproc)(PyObject *, Py_ssize_t, PyObject *); +typedef int(*ssizessizeobjargproc)(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *); +typedef int(*objobjargproc)(PyObject *, PyObject *, PyObject *); + +/* int-based buffer interface */ +typedef int (*getreadbufferproc)(PyObject *, int, void **); +typedef int (*getwritebufferproc)(PyObject *, int, void **); +typedef int (*getsegcountproc)(PyObject *, int *); +typedef int (*getcharbufferproc)(PyObject *, int, char **); +/* ssize_t-based buffer interface */ +typedef Py_ssize_t (*readbufferproc)(PyObject *, Py_ssize_t, void **); +typedef Py_ssize_t (*writebufferproc)(PyObject *, Py_ssize_t, void **); +typedef Py_ssize_t (*segcountproc)(PyObject *, Py_ssize_t *); +typedef Py_ssize_t (*charbufferproc)(PyObject *, Py_ssize_t, char **); + +typedef int (*objobjproc)(PyObject *, PyObject *); +typedef int (*visitproc)(PyObject *, void *); +typedef int (*traverseproc)(PyObject *, visitproc, void *); + +typedef struct { + /* For numbers without flag bit Py_TPFLAGS_CHECKTYPES set, all + arguments are guaranteed to be of the object's type (modulo + coercion hacks -- i.e. if the type's coercion function + returns other types, then these are allowed as well). Numbers that + have the Py_TPFLAGS_CHECKTYPES flag bit set should check *both* + arguments for proper type and implement the necessary conversions + in the slot functions themselves. */ + + binaryfunc nb_add; + binaryfunc nb_subtract; + binaryfunc nb_multiply; + binaryfunc nb_divide; + binaryfunc nb_remainder; + binaryfunc nb_divmod; + ternaryfunc nb_power; + unaryfunc nb_negative; + unaryfunc nb_positive; + unaryfunc nb_absolute; + inquiry nb_nonzero; + unaryfunc nb_invert; + binaryfunc nb_lshift; + binaryfunc nb_rshift; + binaryfunc nb_and; + binaryfunc nb_xor; + binaryfunc nb_or; + coercion nb_coerce; + unaryfunc nb_int; + unaryfunc nb_long; + unaryfunc nb_float; + unaryfunc nb_oct; + unaryfunc nb_hex; + /* Added in release 2.0 */ + binaryfunc nb_inplace_add; + binaryfunc nb_inplace_subtract; + binaryfunc nb_inplace_multiply; + binaryfunc nb_inplace_divide; + binaryfunc nb_inplace_remainder; + ternaryfunc nb_inplace_power; + binaryfunc nb_inplace_lshift; + binaryfunc nb_inplace_rshift; + binaryfunc nb_inplace_and; + binaryfunc nb_inplace_xor; + binaryfunc nb_inplace_or; + + /* Added in release 2.2 */ + /* The following require the Py_TPFLAGS_HAVE_CLASS flag */ + binaryfunc nb_floor_divide; + binaryfunc nb_true_divide; + binaryfunc nb_inplace_floor_divide; + binaryfunc nb_inplace_true_divide; + + /* Added in release 2.5 */ + unaryfunc nb_index; +} PyNumberMethods; + +typedef struct { + lenfunc sq_length; + binaryfunc sq_concat; + ssizeargfunc sq_repeat; + ssizeargfunc sq_item; + ssizessizeargfunc sq_slice; + ssizeobjargproc sq_ass_item; + ssizessizeobjargproc sq_ass_slice; + objobjproc sq_contains; + /* Added in release 2.0 */ + binaryfunc sq_inplace_concat; + ssizeargfunc sq_inplace_repeat; +} PySequenceMethods; + +typedef struct { + lenfunc mp_length; + binaryfunc mp_subscript; + objobjargproc mp_ass_subscript; +} PyMappingMethods; + +typedef struct { + readbufferproc bf_getreadbuffer; + writebufferproc bf_getwritebuffer; + segcountproc bf_getsegcount; + charbufferproc bf_getcharbuffer; +} PyBufferProcs; + + +typedef void (*freefunc)(void *); +typedef void (*destructor)(PyObject *); +typedef int (*printfunc)(PyObject *, FILE *, int); +typedef PyObject *(*getattrfunc)(PyObject *, char *); +typedef PyObject *(*getattrofunc)(PyObject *, PyObject *); +typedef int (*setattrfunc)(PyObject *, char *, PyObject *); +typedef int (*setattrofunc)(PyObject *, PyObject *, PyObject *); +typedef int (*cmpfunc)(PyObject *, PyObject *); +typedef PyObject *(*reprfunc)(PyObject *); +typedef long (*hashfunc)(PyObject *); +typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int); +typedef PyObject *(*getiterfunc) (PyObject *); +typedef PyObject *(*iternextfunc) (PyObject *); +typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *, PyObject *); +typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *); +typedef int (*initproc)(PyObject *, PyObject *, PyObject *); +typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *); +typedef PyObject *(*allocfunc)(struct _typeobject *, Py_ssize_t); + +typedef struct _typeobject { + PyObject_VAR_HEAD + const char *tp_name; /* For printing, in format "." */ + Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */ + + /* Methods to implement standard operations */ + + destructor tp_dealloc; + printfunc tp_print; + getattrfunc tp_getattr; + setattrfunc tp_setattr; + cmpfunc tp_compare; + reprfunc tp_repr; + + /* Method suites for standard classes */ + + PyNumberMethods *tp_as_number; + PySequenceMethods *tp_as_sequence; + PyMappingMethods *tp_as_mapping; + + /* More standard operations (here for binary compatibility) */ + + hashfunc tp_hash; + ternaryfunc tp_call; + reprfunc tp_str; + getattrofunc tp_getattro; + setattrofunc tp_setattro; + + /* Functions to access object as input/output buffer */ + PyBufferProcs *tp_as_buffer; + + /* Flags to define presence of optional/expanded features */ + long tp_flags; + + const char *tp_doc; /* Documentation string */ + + /* Assigned meaning in release 2.0 */ + /* call function for all accessible objects */ + traverseproc tp_traverse; + + /* delete references to contained objects */ + inquiry tp_clear; + + /* Assigned meaning in release 2.1 */ + /* rich comparisons */ + richcmpfunc tp_richcompare; + + /* weak reference enabler */ + Py_ssize_t tp_weaklistoffset; + + /* Added in release 2.2 */ + /* Iterators */ + getiterfunc tp_iter; + iternextfunc tp_iternext; + + /* Attribute descriptor and subclassing stuff */ + struct PyMethodDef *tp_methods; + struct PyMemberDef *tp_members; + struct PyGetSetDef *tp_getset; + struct _typeobject *tp_base; + PyObject *tp_dict; + descrgetfunc tp_descr_get; + descrsetfunc tp_descr_set; + Py_ssize_t tp_dictoffset; + initproc tp_init; + allocfunc tp_alloc; + newfunc tp_new; + freefunc tp_free; /* Low-level free-memory routine */ + inquiry tp_is_gc; /* For PyObject_IS_GC */ + PyObject *tp_bases; + PyObject *tp_mro; /* method resolution order */ + PyObject *tp_cache; + PyObject *tp_subclasses; + PyObject *tp_weaklist; + destructor tp_del; + +#ifdef COUNT_ALLOCS + /* these must be last and never explicitly initialized */ + Py_ssize_t tp_allocs; + Py_ssize_t tp_frees; + Py_ssize_t tp_maxalloc; + struct _typeobject *tp_prev; + struct _typeobject *tp_next; +#endif +} PyTypeObject; + + +/* The *real* layout of a type object when allocated on the heap */ +typedef struct _heaptypeobject { + /* Note: there's a dependency on the order of these members + in slotptr() in typeobject.c . */ + PyTypeObject ht_type; + PyNumberMethods as_number; + PyMappingMethods as_mapping; + PySequenceMethods as_sequence; /* as_sequence comes after as_mapping, + so that the mapping wins when both + the mapping and the sequence define + a given operator (e.g. __getitem__). + see add_operators() in typeobject.c . */ + PyBufferProcs as_buffer; + PyObject *ht_name, *ht_slots; + /* here are optional user slots, followed by the members. */ +} PyHeapTypeObject; + +/* access macro to the members which are floating "behind" the object */ +#define PyHeapType_GET_MEMBERS(etype) \ + ((PyMemberDef *)(((char *)etype) + (etype)->ht_type.ob_type->tp_basicsize)) + + +/* Generic type check */ +PyAPI_FUNC(int) PyType_IsSubtype(PyTypeObject *, PyTypeObject *); +#define PyObject_TypeCheck(ob, tp) \ + ((ob)->ob_type == (tp) || PyType_IsSubtype((ob)->ob_type, (tp))) + +PyAPI_DATA(PyTypeObject) PyType_Type; /* built-in 'type' */ +PyAPI_DATA(PyTypeObject) PyBaseObject_Type; /* built-in 'object' */ +PyAPI_DATA(PyTypeObject) PySuper_Type; /* built-in 'super' */ + +#define PyType_Check(op) PyObject_TypeCheck(op, &PyType_Type) +#define PyType_CheckExact(op) ((op)->ob_type == &PyType_Type) + +PyAPI_FUNC(int) PyType_Ready(PyTypeObject *); +PyAPI_FUNC(PyObject *) PyType_GenericAlloc(PyTypeObject *, Py_ssize_t); +PyAPI_FUNC(PyObject *) PyType_GenericNew(PyTypeObject *, + PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *); + +/* Generic operations on objects */ +PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int); +PyAPI_FUNC(void) _PyObject_Dump(PyObject *); +PyAPI_FUNC(PyObject *) PyObject_Repr(PyObject *); +PyAPI_FUNC(PyObject *) _PyObject_Str(PyObject *); +PyAPI_FUNC(PyObject *) PyObject_Str(PyObject *); +#ifdef Py_USING_UNICODE +PyAPI_FUNC(PyObject *) PyObject_Unicode(PyObject *); +#endif +PyAPI_FUNC(int) PyObject_Compare(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyObject_RichCompare(PyObject *, PyObject *, int); +PyAPI_FUNC(int) PyObject_RichCompareBool(PyObject *, PyObject *, int); +PyAPI_FUNC(PyObject *) PyObject_GetAttrString(PyObject *, const char *); +PyAPI_FUNC(int) PyObject_SetAttrString(PyObject *, const char *, PyObject *); +PyAPI_FUNC(int) PyObject_HasAttrString(PyObject *, const char *); +PyAPI_FUNC(PyObject *) PyObject_GetAttr(PyObject *, PyObject *); +PyAPI_FUNC(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *); +PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *); +PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *); +PyAPI_FUNC(PyObject *) PyObject_SelfIter(PyObject *); +PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *); +PyAPI_FUNC(int) PyObject_GenericSetAttr(PyObject *, + PyObject *, PyObject *); +PyAPI_FUNC(long) PyObject_Hash(PyObject *); +PyAPI_FUNC(int) PyObject_IsTrue(PyObject *); +PyAPI_FUNC(int) PyObject_Not(PyObject *); +PyAPI_FUNC(int) PyCallable_Check(PyObject *); +PyAPI_FUNC(int) PyNumber_Coerce(PyObject **, PyObject **); +PyAPI_FUNC(int) PyNumber_CoerceEx(PyObject **, PyObject **); + +PyAPI_FUNC(void) PyObject_ClearWeakRefs(PyObject *); + +/* A slot function whose address we need to compare */ +extern int _PyObject_SlotCompare(PyObject *, PyObject *); + + +/* PyObject_Dir(obj) acts like Python __builtin__.dir(obj), returning a + list of strings. PyObject_Dir(NULL) is like __builtin__.dir(), + returning the names of the current locals. In this case, if there are + no current locals, NULL is returned, and PyErr_Occurred() is false. +*/ +PyAPI_FUNC(PyObject *) PyObject_Dir(PyObject *); + + +/* Helpers for printing recursive container types */ +PyAPI_FUNC(int) Py_ReprEnter(PyObject *); +PyAPI_FUNC(void) Py_ReprLeave(PyObject *); + +/* Helpers for hash functions */ +PyAPI_FUNC(long) _Py_HashDouble(double); +PyAPI_FUNC(long) _Py_HashPointer(void*); + +/* Helper for passing objects to printf and the like */ +#define PyObject_REPR(obj) PyString_AS_STRING(PyObject_Repr(obj)) + +/* Flag bits for printing: */ +#define Py_PRINT_RAW 1 /* No string quotes etc. */ + +/* +`Type flags (tp_flags) + +These flags are used to extend the type structure in a backwards-compatible +fashion. Extensions can use the flags to indicate (and test) when a given +type structure contains a new feature. The Python core will use these when +introducing new functionality between major revisions (to avoid mid-version +changes in the PYTHON_API_VERSION). + +Arbitration of the flag bit positions will need to be coordinated among +all extension writers who publically release their extensions (this will +be fewer than you might expect!).. + +Python 1.5.2 introduced the bf_getcharbuffer slot into PyBufferProcs. + +Type definitions should use Py_TPFLAGS_DEFAULT for their tp_flags value. + +Code can use PyType_HasFeature(type_ob, flag_value) to test whether the +given type object has a specified feature. +*/ + +/* PyBufferProcs contains bf_getcharbuffer */ +#define Py_TPFLAGS_HAVE_GETCHARBUFFER (1L<<0) + +/* PySequenceMethods contains sq_contains */ +#define Py_TPFLAGS_HAVE_SEQUENCE_IN (1L<<1) + +/* This is here for backwards compatibility. Extensions that use the old GC + * API will still compile but the objects will not be tracked by the GC. */ +#define Py_TPFLAGS_GC 0 /* used to be (1L<<2) */ + +/* PySequenceMethods and PyNumberMethods contain in-place operators */ +#define Py_TPFLAGS_HAVE_INPLACEOPS (1L<<3) + +/* PyNumberMethods do their own coercion */ +#define Py_TPFLAGS_CHECKTYPES (1L<<4) + +/* tp_richcompare is defined */ +#define Py_TPFLAGS_HAVE_RICHCOMPARE (1L<<5) + +/* Objects which are weakly referencable if their tp_weaklistoffset is >0 */ +#define Py_TPFLAGS_HAVE_WEAKREFS (1L<<6) + +/* tp_iter is defined */ +#define Py_TPFLAGS_HAVE_ITER (1L<<7) + +/* New members introduced by Python 2.2 exist */ +#define Py_TPFLAGS_HAVE_CLASS (1L<<8) + +/* Set if the type object is dynamically allocated */ +#define Py_TPFLAGS_HEAPTYPE (1L<<9) + +/* Set if the type allows subclassing */ +#define Py_TPFLAGS_BASETYPE (1L<<10) + +/* Set if the type is 'ready' -- fully initialized */ +#define Py_TPFLAGS_READY (1L<<12) + +/* Set while the type is being 'readied', to prevent recursive ready calls */ +#define Py_TPFLAGS_READYING (1L<<13) + +/* Objects support garbage collection (see objimp.h) */ +#define Py_TPFLAGS_HAVE_GC (1L<<14) + +/* These two bits are preserved for Stackless Python, next after this is 17 */ +#ifdef STACKLESS +#define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION (3L<<15) +#else +#define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION 0 +#endif + +/* Objects support nb_index in PyNumberMethods */ +#define Py_TPFLAGS_HAVE_INDEX (1L<<17) + +#define Py_TPFLAGS_DEFAULT ( \ + Py_TPFLAGS_HAVE_GETCHARBUFFER | \ + Py_TPFLAGS_HAVE_SEQUENCE_IN | \ + Py_TPFLAGS_HAVE_INPLACEOPS | \ + Py_TPFLAGS_HAVE_RICHCOMPARE | \ + Py_TPFLAGS_HAVE_WEAKREFS | \ + Py_TPFLAGS_HAVE_ITER | \ + Py_TPFLAGS_HAVE_CLASS | \ + Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | \ + Py_TPFLAGS_HAVE_INDEX | \ + 0) + +#define PyType_HasFeature(t,f) (((t)->tp_flags & (f)) != 0) + + +/* +The macros Py_INCREF(op) and Py_DECREF(op) are used to increment or decrement +reference counts. Py_DECREF calls the object's deallocator function when +the refcount falls to 0; for +objects that don't contain references to other objects or heap memory +this can be the standard function free(). Both macros can be used +wherever a void expression is allowed. The argument must not be a +NIL pointer. If it may be NIL, use Py_XINCREF/Py_XDECREF instead. +The macro _Py_NewReference(op) initialize reference counts to 1, and +in special builds (Py_REF_DEBUG, Py_TRACE_REFS) performs additional +bookkeeping appropriate to the special build. + +We assume that the reference count field can never overflow; this can +be proven when the size of the field is the same as the pointer size, so +we ignore the possibility. Provided a C int is at least 32 bits (which +is implicitly assumed in many parts of this code), that's enough for +about 2**31 references to an object. + +XXX The following became out of date in Python 2.2, but I'm not sure +XXX what the full truth is now. Certainly, heap-allocated type objects +XXX can and should be deallocated. +Type objects should never be deallocated; the type pointer in an object +is not considered to be a reference to the type object, to save +complications in the deallocation function. (This is actually a +decision that's up to the implementer of each new type so if you want, +you can count such references to the type object.) + +*** WARNING*** The Py_DECREF macro must have a side-effect-free argument +since it may evaluate its argument multiple times. (The alternative +would be to mace it a proper function or assign it to a global temporary +variable first, both of which are slower; and in a multi-threaded +environment the global variable trick is not safe.) +*/ + +/* First define a pile of simple helper macros, one set per special + * build symbol. These either expand to the obvious things, or to + * nothing at all when the special mode isn't in effect. The main + * macros can later be defined just once then, yet expand to different + * things depending on which special build options are and aren't in effect. + * Trust me : while painful, this is 20x easier to understand than, + * e.g, defining _Py_NewReference five different times in a maze of nested + * #ifdefs (we used to do that -- it was impenetrable). + */ +#ifdef Py_REF_DEBUG +PyAPI_DATA(Py_ssize_t) _Py_RefTotal; +PyAPI_FUNC(void) _Py_NegativeRefcount(const char *fname, + int lineno, PyObject *op); +PyAPI_FUNC(PyObject *) _PyDict_Dummy(void); +PyAPI_FUNC(PyObject *) _PySet_Dummy(void); +PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void); +#define _Py_INC_REFTOTAL _Py_RefTotal++ +#define _Py_DEC_REFTOTAL _Py_RefTotal-- +#define _Py_REF_DEBUG_COMMA , +#define _Py_CHECK_REFCNT(OP) \ +{ if ((OP)->ob_refcnt < 0) \ + _Py_NegativeRefcount(__FILE__, __LINE__, \ + (PyObject *)(OP)); \ +} +#else +#define _Py_INC_REFTOTAL +#define _Py_DEC_REFTOTAL +#define _Py_REF_DEBUG_COMMA +#define _Py_CHECK_REFCNT(OP) /* a semicolon */; +#endif /* Py_REF_DEBUG */ + +#ifdef COUNT_ALLOCS +PyAPI_FUNC(void) inc_count(PyTypeObject *); +PyAPI_FUNC(void) dec_count(PyTypeObject *); +#define _Py_INC_TPALLOCS(OP) inc_count((OP)->ob_type) +#define _Py_INC_TPFREES(OP) dec_count((OP)->ob_type) +#define _Py_DEC_TPFREES(OP) (OP)->ob_type->tp_frees-- +#define _Py_COUNT_ALLOCS_COMMA , +#else +#define _Py_INC_TPALLOCS(OP) +#define _Py_INC_TPFREES(OP) +#define _Py_DEC_TPFREES(OP) +#define _Py_COUNT_ALLOCS_COMMA +#endif /* COUNT_ALLOCS */ + +#ifdef Py_TRACE_REFS +/* Py_TRACE_REFS is such major surgery that we call external routines. */ +PyAPI_FUNC(void) _Py_NewReference(PyObject *); +PyAPI_FUNC(void) _Py_ForgetReference(PyObject *); +PyAPI_FUNC(void) _Py_Dealloc(PyObject *); +PyAPI_FUNC(void) _Py_PrintReferences(FILE *); +PyAPI_FUNC(void) _Py_PrintReferenceAddresses(FILE *); +PyAPI_FUNC(void) _Py_AddToAllObjects(PyObject *, int force); + +#else +/* Without Py_TRACE_REFS, there's little enough to do that we expand code + * inline. + */ +#define _Py_NewReference(op) ( \ + _Py_INC_TPALLOCS(op) _Py_COUNT_ALLOCS_COMMA \ + _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \ + (op)->ob_refcnt = 1) + +#define _Py_ForgetReference(op) _Py_INC_TPFREES(op) + +#define _Py_Dealloc(op) ( \ + _Py_INC_TPFREES(op) _Py_COUNT_ALLOCS_COMMA \ + (*(op)->ob_type->tp_dealloc)((PyObject *)(op))) +#endif /* !Py_TRACE_REFS */ + +#define Py_INCREF(op) ( \ + _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \ + (op)->ob_refcnt++) + +#define Py_DECREF(op) \ + if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ + --(op)->ob_refcnt != 0) \ + _Py_CHECK_REFCNT(op) \ + else \ + _Py_Dealloc((PyObject *)(op)) + +/* Safely decref `op` and set `op` to NULL, especially useful in tp_clear + * and tp_dealloc implementatons. + * + * Note that "the obvious" code can be deadly: + * + * Py_XDECREF(op); + * op = NULL; + * + * Typically, `op` is something like self->containee, and `self` is done + * using its `containee` member. In the code sequence above, suppose + * `containee` is non-NULL with a refcount of 1. Its refcount falls to + * 0 on the first line, which can trigger an arbitrary amount of code, + * possibly including finalizers (like __del__ methods or weakref callbacks) + * coded in Python, which in turn can release the GIL and allow other threads + * to run, etc. Such code may even invoke methods of `self` again, or cause + * cyclic gc to trigger, but-- oops! --self->containee still points to the + * object being torn down, and it may be in an insane state while being torn + * down. This has in fact been a rich historic source of miserable (rare & + * hard-to-diagnose) segfaulting (and other) bugs. + * + * The safe way is: + * + * Py_CLEAR(op); + * + * That arranges to set `op` to NULL _before_ decref'ing, so that any code + * triggered as a side-effect of `op` getting torn down no longer believes + * `op` points to a valid object. + * + * There are cases where it's safe to use the naive code, but they're brittle. + * For example, if `op` points to a Python integer, you know that destroying + * one of those can't cause problems -- but in part that relies on that + * Python integers aren't currently weakly referencable. Best practice is + * to use Py_CLEAR() even if you can't think of a reason for why you need to. + */ +#define Py_CLEAR(op) \ + do { \ + if (op) { \ + PyObject *tmp = (PyObject *)(op); \ + (op) = NULL; \ + Py_DECREF(tmp); \ + } \ + } while (0) + +/* Macros to use in case the object pointer may be NULL: */ +#define Py_XINCREF(op) if ((op) == NULL) ; else Py_INCREF(op) +#define Py_XDECREF(op) if ((op) == NULL) ; else Py_DECREF(op) + +/* +These are provided as conveniences to Python runtime embedders, so that +they can have object code that is not dependent on Python compilation flags. +*/ +PyAPI_FUNC(void) Py_IncRef(PyObject *); +PyAPI_FUNC(void) Py_DecRef(PyObject *); + +/* +_Py_NoneStruct is an object of undefined type which can be used in contexts +where NULL (nil) is not suitable (since NULL often means 'error'). + +Don't forget to apply Py_INCREF() when returning this value!!! +*/ +PyAPI_DATA(PyObject) _Py_NoneStruct; /* Don't use this directly */ +#define Py_None (&_Py_NoneStruct) + +/* Macro for returning Py_None from a function */ +#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None + +/* +Py_NotImplemented is a singleton used to signal that an operation is +not implemented for a given type combination. +*/ +PyAPI_DATA(PyObject) _Py_NotImplementedStruct; /* Don't use this directly */ +#define Py_NotImplemented (&_Py_NotImplementedStruct) + +/* Rich comparison opcodes */ +#define Py_LT 0 +#define Py_LE 1 +#define Py_EQ 2 +#define Py_NE 3 +#define Py_GT 4 +#define Py_GE 5 + +/* Maps Py_LT to Py_GT, ..., Py_GE to Py_LE. + * Defined in object.c. + */ +PyAPI_DATA(int) _Py_SwappedOp[]; + +/* +Define staticforward and statichere for source compatibility with old +C extensions. + +The staticforward define was needed to support certain broken C +compilers (notably SCO ODT 3.0, perhaps early AIX as well) botched the +static keyword when it was used with a forward declaration of a static +initialized structure. Standard C allows the forward declaration with +static, and we've decided to stop catering to broken C compilers. +(In fact, we expect that the compilers are all fixed eight years later.) +*/ + +#define staticforward static +#define statichere static + + +/* +More conventions +================ + +Argument Checking +----------------- + +Functions that take objects as arguments normally don't check for nil +arguments, but they do check the type of the argument, and return an +error if the function doesn't apply to the type. + +Failure Modes +------------- + +Functions may fail for a variety of reasons, including running out of +memory. This is communicated to the caller in two ways: an error string +is set (see errors.h), and the function result differs: functions that +normally return a pointer return NULL for failure, functions returning +an integer return -1 (which could be a legal return value too!), and +other functions return 0 for success and -1 for failure. +Callers should always check for errors before using the result. If +an error was set, the caller must either explicitly clear it, or pass +the error on to its caller. + +Reference Counts +---------------- + +It takes a while to get used to the proper usage of reference counts. + +Functions that create an object set the reference count to 1; such new +objects must be stored somewhere or destroyed again with Py_DECREF(). +Some functions that 'store' objects, such as PyTuple_SetItem() and +PyList_SetItem(), +don't increment the reference count of the object, since the most +frequent use is to store a fresh object. Functions that 'retrieve' +objects, such as PyTuple_GetItem() and PyDict_GetItemString(), also +don't increment +the reference count, since most frequently the object is only looked at +quickly. Thus, to retrieve an object and store it again, the caller +must call Py_INCREF() explicitly. + +NOTE: functions that 'consume' a reference count, like +PyList_SetItem(), consume the reference even if the object wasn't +successfully stored, to simplify error handling. + +It seems attractive to make other functions that take an object as +argument consume a reference count; however, this may quickly get +confusing (even the current practice is already confusing). Consider +it carefully, it may save lots of calls to Py_INCREF() and Py_DECREF() at +times. +*/ + + +/* Trashcan mechanism, thanks to Christian Tismer. + +When deallocating a container object, it's possible to trigger an unbounded +chain of deallocations, as each Py_DECREF in turn drops the refcount on "the +next" object in the chain to 0. This can easily lead to stack faults, and +especially in threads (which typically have less stack space to work with). + +A container object that participates in cyclic gc can avoid this by +bracketing the body of its tp_dealloc function with a pair of macros: + +static void +mytype_dealloc(mytype *p) +{ + ... declarations go here ... + + PyObject_GC_UnTrack(p); // must untrack first + Py_TRASHCAN_SAFE_BEGIN(p) + ... The body of the deallocator goes here, including all calls ... + ... to Py_DECREF on contained objects. ... + Py_TRASHCAN_SAFE_END(p) +} + +CAUTION: Never return from the middle of the body! If the body needs to +"get out early", put a label immediately before the Py_TRASHCAN_SAFE_END +call, and goto it. Else the call-depth counter (see below) will stay +above 0 forever, and the trashcan will never get emptied. + +How it works: The BEGIN macro increments a call-depth counter. So long +as this counter is small, the body of the deallocator is run directly without +further ado. But if the counter gets large, it instead adds p to a list of +objects to be deallocated later, skips the body of the deallocator, and +resumes execution after the END macro. The tp_dealloc routine then returns +without deallocating anything (and so unbounded call-stack depth is avoided). + +When the call stack finishes unwinding again, code generated by the END macro +notices this, and calls another routine to deallocate all the objects that +may have been added to the list of deferred deallocations. In effect, a +chain of N deallocations is broken into N / PyTrash_UNWIND_LEVEL pieces, +with the call stack never exceeding a depth of PyTrash_UNWIND_LEVEL. +*/ + +PyAPI_FUNC(void) _PyTrash_deposit_object(PyObject*); +PyAPI_FUNC(void) _PyTrash_destroy_chain(void); +PyAPI_DATA(int) _PyTrash_delete_nesting; +PyAPI_DATA(PyObject *) _PyTrash_delete_later; + +#define PyTrash_UNWIND_LEVEL 50 + +#define Py_TRASHCAN_SAFE_BEGIN(op) \ + if (_PyTrash_delete_nesting < PyTrash_UNWIND_LEVEL) { \ + ++_PyTrash_delete_nesting; + /* The body of the deallocator is here. */ +#define Py_TRASHCAN_SAFE_END(op) \ + --_PyTrash_delete_nesting; \ + if (_PyTrash_delete_later && _PyTrash_delete_nesting <= 0) \ + _PyTrash_destroy_chain(); \ + } \ + else \ + _PyTrash_deposit_object((PyObject*)op); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/objimpl.h b/vscript/languages/python/python-2.5.1/include/objimpl.h new file mode 100644 index 00000000..03b6a8d4 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/objimpl.h @@ -0,0 +1,336 @@ +/* The PyObject_ memory family: high-level object memory interfaces. + See pymem.h for the low-level PyMem_ family. +*/ + +#ifndef Py_OBJIMPL_H +#define Py_OBJIMPL_H + +#include "pymem.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEWARE: + + Each interface exports both functions and macros. Extension modules should + use the functions, to ensure binary compatibility across Python versions. + Because the Python implementation is free to change internal details, and + the macros may (or may not) expose details for speed, if you do use the + macros you must recompile your extensions with each Python release. + + Never mix calls to PyObject_ memory functions with calls to the platform + malloc/realloc/ calloc/free, or with calls to PyMem_. +*/ + +/* +Functions and macros for modules that implement new object types. + + - PyObject_New(type, typeobj) allocates memory for a new object of the given + type, and initializes part of it. 'type' must be the C structure type used + to represent the object, and 'typeobj' the address of the corresponding + type object. Reference count and type pointer are filled in; the rest of + the bytes of the object are *undefined*! The resulting expression type is + 'type *'. The size of the object is determined by the tp_basicsize field + of the type object. + + - PyObject_NewVar(type, typeobj, n) is similar but allocates a variable-size + object with room for n items. In addition to the refcount and type pointer + fields, this also fills in the ob_size field. + + - PyObject_Del(op) releases the memory allocated for an object. It does not + run a destructor -- it only frees the memory. PyObject_Free is identical. + + - PyObject_Init(op, typeobj) and PyObject_InitVar(op, typeobj, n) don't + allocate memory. Instead of a 'type' parameter, they take a pointer to a + new object (allocated by an arbitrary allocator), and initialize its object + header fields. + +Note that objects created with PyObject_{New, NewVar} are allocated using the +specialized Python allocator (implemented in obmalloc.c), if WITH_PYMALLOC is +enabled. In addition, a special debugging allocator is used if PYMALLOC_DEBUG +is also #defined. + +In case a specific form of memory management is needed (for example, if you +must use the platform malloc heap(s), or shared memory, or C++ local storage or +operator new), you must first allocate the object with your custom allocator, +then pass its pointer to PyObject_{Init, InitVar} for filling in its Python- +specific fields: reference count, type pointer, possibly others. You should +be aware that Python no control over these objects because they don't +cooperate with the Python memory manager. Such objects may not be eligible +for automatic garbage collection and you have to make sure that they are +released accordingly whenever their destructor gets called (cf. the specific +form of memory management you're using). + +Unless you have specific memory management requirements, use +PyObject_{New, NewVar, Del}. +*/ + +/* + * Raw object memory interface + * =========================== + */ + +/* Functions to call the same malloc/realloc/free as used by Python's + object allocator. If WITH_PYMALLOC is enabled, these may differ from + the platform malloc/realloc/free. The Python object allocator is + designed for fast, cache-conscious allocation of many "small" objects, + and with low hidden memory overhead. + + PyObject_Malloc(0) returns a unique non-NULL pointer if possible. + + PyObject_Realloc(NULL, n) acts like PyObject_Malloc(n). + PyObject_Realloc(p != NULL, 0) does not return NULL, or free the memory + at p. + + Returned pointers must be checked for NULL explicitly; no action is + performed on failure other than to return NULL (no warning it printed, no + exception is set, etc). + + For allocating objects, use PyObject_{New, NewVar} instead whenever + possible. The PyObject_{Malloc, Realloc, Free} family is exposed + so that you can exploit Python's small-block allocator for non-object + uses. If you must use these routines to allocate object memory, make sure + the object gets initialized via PyObject_{Init, InitVar} after obtaining + the raw memory. +*/ +PyAPI_FUNC(void *) PyObject_Malloc(size_t); +PyAPI_FUNC(void *) PyObject_Realloc(void *, size_t); +PyAPI_FUNC(void) PyObject_Free(void *); + + +/* Macros */ +#ifdef WITH_PYMALLOC +#ifdef PYMALLOC_DEBUG /* WITH_PYMALLOC && PYMALLOC_DEBUG */ +PyAPI_FUNC(void *) _PyObject_DebugMalloc(size_t nbytes); +PyAPI_FUNC(void *) _PyObject_DebugRealloc(void *p, size_t nbytes); +PyAPI_FUNC(void) _PyObject_DebugFree(void *p); +PyAPI_FUNC(void) _PyObject_DebugDumpAddress(const void *p); +PyAPI_FUNC(void) _PyObject_DebugCheckAddress(const void *p); +PyAPI_FUNC(void) _PyObject_DebugMallocStats(void); +#define PyObject_MALLOC _PyObject_DebugMalloc +#define PyObject_Malloc _PyObject_DebugMalloc +#define PyObject_REALLOC _PyObject_DebugRealloc +#define PyObject_Realloc _PyObject_DebugRealloc +#define PyObject_FREE _PyObject_DebugFree +#define PyObject_Free _PyObject_DebugFree + +#else /* WITH_PYMALLOC && ! PYMALLOC_DEBUG */ +#define PyObject_MALLOC PyObject_Malloc +#define PyObject_REALLOC PyObject_Realloc +#define PyObject_FREE PyObject_Free +#endif + +#else /* ! WITH_PYMALLOC */ +#define PyObject_MALLOC PyMem_MALLOC +#define PyObject_REALLOC PyMem_REALLOC +#define PyObject_FREE PyMem_FREE + +#endif /* WITH_PYMALLOC */ + +#define PyObject_Del PyObject_Free +#define PyObject_DEL PyObject_FREE + +/* for source compatibility with 2.2 */ +#define _PyObject_Del PyObject_Free + +/* + * Generic object allocator interface + * ================================== + */ + +/* Functions */ +PyAPI_FUNC(PyObject *) PyObject_Init(PyObject *, PyTypeObject *); +PyAPI_FUNC(PyVarObject *) PyObject_InitVar(PyVarObject *, + PyTypeObject *, Py_ssize_t); +PyAPI_FUNC(PyObject *) _PyObject_New(PyTypeObject *); +PyAPI_FUNC(PyVarObject *) _PyObject_NewVar(PyTypeObject *, Py_ssize_t); + +#define PyObject_New(type, typeobj) \ + ( (type *) _PyObject_New(typeobj) ) +#define PyObject_NewVar(type, typeobj, n) \ + ( (type *) _PyObject_NewVar((typeobj), (n)) ) + +/* Macros trading binary compatibility for speed. See also pymem.h. + Note that these macros expect non-NULL object pointers.*/ +#define PyObject_INIT(op, typeobj) \ + ( (op)->ob_type = (typeobj), _Py_NewReference((PyObject *)(op)), (op) ) +#define PyObject_INIT_VAR(op, typeobj, size) \ + ( (op)->ob_size = (size), PyObject_INIT((op), (typeobj)) ) + +#define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize ) + +/* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a + vrbl-size object with nitems items, exclusive of gc overhead (if any). The + value is rounded up to the closest multiple of sizeof(void *), in order to + ensure that pointer fields at the end of the object are correctly aligned + for the platform (this is of special importance for subclasses of, e.g., + str or long, so that pointers can be stored after the embedded data). + + Note that there's no memory wastage in doing this, as malloc has to + return (at worst) pointer-aligned memory anyway. +*/ +#if ((SIZEOF_VOID_P - 1) & SIZEOF_VOID_P) != 0 +# error "_PyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2" +#endif + +#define _PyObject_VAR_SIZE(typeobj, nitems) \ + (size_t) \ + ( ( (typeobj)->tp_basicsize + \ + (nitems)*(typeobj)->tp_itemsize + \ + (SIZEOF_VOID_P - 1) \ + ) & ~(SIZEOF_VOID_P - 1) \ + ) + +#define PyObject_NEW(type, typeobj) \ +( (type *) PyObject_Init( \ + (PyObject *) PyObject_MALLOC( _PyObject_SIZE(typeobj) ), (typeobj)) ) + +#define PyObject_NEW_VAR(type, typeobj, n) \ +( (type *) PyObject_InitVar( \ + (PyVarObject *) PyObject_MALLOC(_PyObject_VAR_SIZE((typeobj),(n)) ),\ + (typeobj), (n)) ) + +/* This example code implements an object constructor with a custom + allocator, where PyObject_New is inlined, and shows the important + distinction between two steps (at least): + 1) the actual allocation of the object storage; + 2) the initialization of the Python specific fields + in this storage with PyObject_{Init, InitVar}. + + PyObject * + YourObject_New(...) + { + PyObject *op; + + op = (PyObject *) Your_Allocator(_PyObject_SIZE(YourTypeStruct)); + if (op == NULL) + return PyErr_NoMemory(); + + PyObject_Init(op, &YourTypeStruct); + + op->ob_field = value; + ... + return op; + } + + Note that in C++, the use of the new operator usually implies that + the 1st step is performed automatically for you, so in a C++ class + constructor you would start directly with PyObject_Init/InitVar +*/ + +/* + * Garbage Collection Support + * ========================== + */ + +/* C equivalent of gc.collect(). */ +PyAPI_FUNC(Py_ssize_t) PyGC_Collect(void); + +/* Test if a type has a GC head */ +#define PyType_IS_GC(t) PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC) + +/* Test if an object has a GC head */ +#define PyObject_IS_GC(o) (PyType_IS_GC((o)->ob_type) && \ + ((o)->ob_type->tp_is_gc == NULL || (o)->ob_type->tp_is_gc(o))) + +PyAPI_FUNC(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, Py_ssize_t); +#define PyObject_GC_Resize(type, op, n) \ + ( (type *) _PyObject_GC_Resize((PyVarObject *)(op), (n)) ) + +/* for source compatibility with 2.2 */ +#define _PyObject_GC_Del PyObject_GC_Del + +/* GC information is stored BEFORE the object structure. */ +typedef union _gc_head { + struct { + union _gc_head *gc_next; + union _gc_head *gc_prev; + Py_ssize_t gc_refs; + } gc; + long double dummy; /* force worst-case alignment */ +} PyGC_Head; + +extern PyGC_Head *_PyGC_generation0; + +#define _Py_AS_GC(o) ((PyGC_Head *)(o)-1) + +#define _PyGC_REFS_UNTRACKED (-2) +#define _PyGC_REFS_REACHABLE (-3) +#define _PyGC_REFS_TENTATIVELY_UNREACHABLE (-4) + +/* Tell the GC to track this object. NB: While the object is tracked the + * collector it must be safe to call the ob_traverse method. */ +#define _PyObject_GC_TRACK(o) do { \ + PyGC_Head *g = _Py_AS_GC(o); \ + if (g->gc.gc_refs != _PyGC_REFS_UNTRACKED) \ + Py_FatalError("GC object already tracked"); \ + g->gc.gc_refs = _PyGC_REFS_REACHABLE; \ + g->gc.gc_next = _PyGC_generation0; \ + g->gc.gc_prev = _PyGC_generation0->gc.gc_prev; \ + g->gc.gc_prev->gc.gc_next = g; \ + _PyGC_generation0->gc.gc_prev = g; \ + } while (0); + +/* Tell the GC to stop tracking this object. + * gc_next doesn't need to be set to NULL, but doing so is a good + * way to provoke memory errors if calling code is confused. + */ +#define _PyObject_GC_UNTRACK(o) do { \ + PyGC_Head *g = _Py_AS_GC(o); \ + assert(g->gc.gc_refs != _PyGC_REFS_UNTRACKED); \ + g->gc.gc_refs = _PyGC_REFS_UNTRACKED; \ + g->gc.gc_prev->gc.gc_next = g->gc.gc_next; \ + g->gc.gc_next->gc.gc_prev = g->gc.gc_prev; \ + g->gc.gc_next = NULL; \ + } while (0); + +PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t); +PyAPI_FUNC(PyObject *) _PyObject_GC_New(PyTypeObject *); +PyAPI_FUNC(PyVarObject *) _PyObject_GC_NewVar(PyTypeObject *, Py_ssize_t); +PyAPI_FUNC(void) PyObject_GC_Track(void *); +PyAPI_FUNC(void) PyObject_GC_UnTrack(void *); +PyAPI_FUNC(void) PyObject_GC_Del(void *); + +#define PyObject_GC_New(type, typeobj) \ + ( (type *) _PyObject_GC_New(typeobj) ) +#define PyObject_GC_NewVar(type, typeobj, n) \ + ( (type *) _PyObject_GC_NewVar((typeobj), (n)) ) + + +/* Utility macro to help write tp_traverse functions. + * To use this macro, the tp_traverse function must name its arguments + * "visit" and "arg". This is intended to keep tp_traverse functions + * looking as much alike as possible. + */ +#define Py_VISIT(op) \ + do { \ + if (op) { \ + int vret = visit((PyObject *)(op), arg); \ + if (vret) \ + return vret; \ + } \ + } while (0) + +/* This is here for the sake of backwards compatibility. Extensions that + * use the old GC API will still compile but the objects will not be + * tracked by the GC. */ +#define PyGC_HEAD_SIZE 0 +#define PyObject_GC_Init(op) +#define PyObject_GC_Fini(op) +#define PyObject_AS_GC(op) (op) +#define PyObject_FROM_GC(op) (op) + + +/* Test if a type supports weak references */ +#define PyType_SUPPORTS_WEAKREFS(t) \ + (PyType_HasFeature((t), Py_TPFLAGS_HAVE_WEAKREFS) \ + && ((t)->tp_weaklistoffset > 0)) + +#define PyObject_GET_WEAKREFS_LISTPTR(o) \ + ((PyObject **) (((char *) (o)) + (o)->ob_type->tp_weaklistoffset)) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OBJIMPL_H */ diff --git a/vscript/languages/python/python-2.5.1/include/opcode.h b/vscript/languages/python/python-2.5.1/include/opcode.h new file mode 100644 index 00000000..d8cb2cd4 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/opcode.h @@ -0,0 +1,152 @@ +#ifndef Py_OPCODE_H +#define Py_OPCODE_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Instruction opcodes for compiled code */ + +#define STOP_CODE 0 +#define POP_TOP 1 +#define ROT_TWO 2 +#define ROT_THREE 3 +#define DUP_TOP 4 +#define ROT_FOUR 5 +#define NOP 9 + +#define UNARY_POSITIVE 10 +#define UNARY_NEGATIVE 11 +#define UNARY_NOT 12 +#define UNARY_CONVERT 13 + +#define UNARY_INVERT 15 + +#define LIST_APPEND 18 +#define BINARY_POWER 19 + +#define BINARY_MULTIPLY 20 +#define BINARY_DIVIDE 21 +#define BINARY_MODULO 22 +#define BINARY_ADD 23 +#define BINARY_SUBTRACT 24 +#define BINARY_SUBSCR 25 +#define BINARY_FLOOR_DIVIDE 26 +#define BINARY_TRUE_DIVIDE 27 +#define INPLACE_FLOOR_DIVIDE 28 +#define INPLACE_TRUE_DIVIDE 29 + +#define SLICE 30 +/* Also uses 31-33 */ + +#define STORE_SLICE 40 +/* Also uses 41-43 */ + +#define DELETE_SLICE 50 +/* Also uses 51-53 */ + +#define INPLACE_ADD 55 +#define INPLACE_SUBTRACT 56 +#define INPLACE_MULTIPLY 57 +#define INPLACE_DIVIDE 58 +#define INPLACE_MODULO 59 +#define STORE_SUBSCR 60 +#define DELETE_SUBSCR 61 + +#define BINARY_LSHIFT 62 +#define BINARY_RSHIFT 63 +#define BINARY_AND 64 +#define BINARY_XOR 65 +#define BINARY_OR 66 +#define INPLACE_POWER 67 +#define GET_ITER 68 + +#define PRINT_EXPR 70 +#define PRINT_ITEM 71 +#define PRINT_NEWLINE 72 +#define PRINT_ITEM_TO 73 +#define PRINT_NEWLINE_TO 74 +#define INPLACE_LSHIFT 75 +#define INPLACE_RSHIFT 76 +#define INPLACE_AND 77 +#define INPLACE_XOR 78 +#define INPLACE_OR 79 +#define BREAK_LOOP 80 +#define WITH_CLEANUP 81 +#define LOAD_LOCALS 82 +#define RETURN_VALUE 83 +#define IMPORT_STAR 84 +#define EXEC_STMT 85 +#define YIELD_VALUE 86 +#define POP_BLOCK 87 +#define END_FINALLY 88 +#define BUILD_CLASS 89 + +#define HAVE_ARGUMENT 90 /* Opcodes from here have an argument: */ + +#define STORE_NAME 90 /* Index in name list */ +#define DELETE_NAME 91 /* "" */ +#define UNPACK_SEQUENCE 92 /* Number of sequence items */ +#define FOR_ITER 93 + +#define STORE_ATTR 95 /* Index in name list */ +#define DELETE_ATTR 96 /* "" */ +#define STORE_GLOBAL 97 /* "" */ +#define DELETE_GLOBAL 98 /* "" */ +#define DUP_TOPX 99 /* number of items to duplicate */ +#define LOAD_CONST 100 /* Index in const list */ +#define LOAD_NAME 101 /* Index in name list */ +#define BUILD_TUPLE 102 /* Number of tuple items */ +#define BUILD_LIST 103 /* Number of list items */ +#define BUILD_MAP 104 /* Always zero for now */ +#define LOAD_ATTR 105 /* Index in name list */ +#define COMPARE_OP 106 /* Comparison operator */ +#define IMPORT_NAME 107 /* Index in name list */ +#define IMPORT_FROM 108 /* Index in name list */ + +#define JUMP_FORWARD 110 /* Number of bytes to skip */ +#define JUMP_IF_FALSE 111 /* "" */ +#define JUMP_IF_TRUE 112 /* "" */ +#define JUMP_ABSOLUTE 113 /* Target byte offset from beginning of code */ + +#define LOAD_GLOBAL 116 /* Index in name list */ + +#define CONTINUE_LOOP 119 /* Start of loop (absolute) */ +#define SETUP_LOOP 120 /* Target address (absolute) */ +#define SETUP_EXCEPT 121 /* "" */ +#define SETUP_FINALLY 122 /* "" */ + +#define LOAD_FAST 124 /* Local variable number */ +#define STORE_FAST 125 /* Local variable number */ +#define DELETE_FAST 126 /* Local variable number */ + +#define RAISE_VARARGS 130 /* Number of raise arguments (1, 2 or 3) */ +/* CALL_FUNCTION_XXX opcodes defined below depend on this definition */ +#define CALL_FUNCTION 131 /* #args + (#kwargs<<8) */ +#define MAKE_FUNCTION 132 /* #defaults */ +#define BUILD_SLICE 133 /* Number of items */ + +#define MAKE_CLOSURE 134 /* #free vars */ +#define LOAD_CLOSURE 135 /* Load free variable from closure */ +#define LOAD_DEREF 136 /* Load and dereference from closure cell */ +#define STORE_DEREF 137 /* Store into cell */ + +/* The next 3 opcodes must be contiguous and satisfy + (CALL_FUNCTION_VAR - CALL_FUNCTION) & 3 == 1 */ +#define CALL_FUNCTION_VAR 140 /* #args + (#kwargs<<8) */ +#define CALL_FUNCTION_KW 141 /* #args + (#kwargs<<8) */ +#define CALL_FUNCTION_VAR_KW 142 /* #args + (#kwargs<<8) */ + +/* Support for opargs more than 16 bits long */ +#define EXTENDED_ARG 143 + + +enum cmp_op {PyCmp_LT=Py_LT, PyCmp_LE=Py_LE, PyCmp_EQ=Py_EQ, PyCmp_NE=Py_NE, PyCmp_GT=Py_GT, PyCmp_GE=Py_GE, + PyCmp_IN, PyCmp_NOT_IN, PyCmp_IS, PyCmp_IS_NOT, PyCmp_EXC_MATCH, PyCmp_BAD}; + +#define HAS_ARG(op) ((op) >= HAVE_ARGUMENT) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OPCODE_H */ diff --git a/vscript/languages/python/python-2.5.1/include/osdefs.h b/vscript/languages/python/python-2.5.1/include/osdefs.h new file mode 100644 index 00000000..69376593 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/osdefs.h @@ -0,0 +1,55 @@ +#ifndef Py_OSDEFS_H +#define Py_OSDEFS_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Operating system dependencies */ + +/* Mod by chrish: QNX has WATCOM, but isn't DOS */ +#if !defined(__QNX__) +#if defined(MS_WINDOWS) || defined(__BORLANDC__) || defined(__WATCOMC__) || defined(__DJGPP__) || defined(PYOS_OS2) +#if defined(PYOS_OS2) && defined(PYCC_GCC) +#define MAXPATHLEN 260 +#define SEP '/' +#define ALTSEP '\\' +#else +#define SEP '\\' +#define ALTSEP '/' +#define MAXPATHLEN 256 +#endif +#define DELIM ';' +#endif +#endif + +#ifdef RISCOS +#define SEP '.' +#define MAXPATHLEN 256 +#define DELIM ',' +#endif + + +/* Filename separator */ +#ifndef SEP +#define SEP '/' +#endif + +/* Max pathname length */ +#ifndef MAXPATHLEN +#if defined(PATH_MAX) && PATH_MAX > 1024 +#define MAXPATHLEN PATH_MAX +#else +#define MAXPATHLEN 1024 +#endif +#endif + +/* Search path entry delimiter */ +#ifndef DELIM +#define DELIM ':' +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OSDEFS_H */ diff --git a/vscript/languages/python/python-2.5.1/include/parsetok.h b/vscript/languages/python/python-2.5.1/include/parsetok.h new file mode 100644 index 00000000..0f87e81f --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/parsetok.h @@ -0,0 +1,50 @@ + +/* Parser-tokenizer link interface */ + +#ifndef Py_PARSETOK_H +#define Py_PARSETOK_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int error; + const char *filename; + int lineno; + int offset; + char *text; + int token; + int expected; +} perrdetail; + +#if 0 +#define PyPARSE_YIELD_IS_KEYWORD 0x0001 +#endif + +#define PyPARSE_DONT_IMPLY_DEDENT 0x0002 + +#define PyPARSE_WITH_IS_KEYWORD 0x0003 + +PyAPI_FUNC(node *) PyParser_ParseString(const char *, grammar *, int, + perrdetail *); +PyAPI_FUNC(node *) PyParser_ParseFile (FILE *, const char *, grammar *, int, + char *, char *, perrdetail *); + +PyAPI_FUNC(node *) PyParser_ParseStringFlags(const char *, grammar *, int, + perrdetail *, int); +PyAPI_FUNC(node *) PyParser_ParseFileFlags(FILE *, const char *, grammar *, + int, char *, char *, + perrdetail *, int); + +PyAPI_FUNC(node *) PyParser_ParseStringFlagsFilename(const char *, + const char *, + grammar *, int, + perrdetail *, int); + +/* Note that he following function is defined in pythonrun.c not parsetok.c. */ +PyAPI_FUNC(void) PyParser_SetError(perrdetail *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PARSETOK_H */ diff --git a/vscript/languages/python/python-2.5.1/include/patchlevel.h b/vscript/languages/python/python-2.5.1/include/patchlevel.h new file mode 100644 index 00000000..85efe3b2 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/patchlevel.h @@ -0,0 +1,40 @@ + +/* Newfangled version identification scheme. + + This scheme was added in Python 1.5.2b2; before that time, only PATCHLEVEL + was available. To test for presence of the scheme, test for + defined(PY_MAJOR_VERSION). + + When the major or minor version changes, the VERSION variable in + configure.in must also be changed. + + There is also (independent) API version information in modsupport.h. +*/ + +/* Values for PY_RELEASE_LEVEL */ +#define PY_RELEASE_LEVEL_ALPHA 0xA +#define PY_RELEASE_LEVEL_BETA 0xB +#define PY_RELEASE_LEVEL_GAMMA 0xC /* For release candidates */ +#define PY_RELEASE_LEVEL_FINAL 0xF /* Serial should be 0 here */ + /* Higher for patch releases */ + +/* Version parsed out into numeric values */ +#define PY_MAJOR_VERSION 2 +#define PY_MINOR_VERSION 5 +#define PY_MICRO_VERSION 1 +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL +#define PY_RELEASE_SERIAL 0 + +/* Version as a string */ +#define PY_VERSION "2.5.1" + +/* Subversion Revision number of this file (not of the repository) */ +#define PY_PATCHLEVEL_REVISION "$Revision: 54863 $" + +/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. + Use this for numeric comparisons, e.g. #if PY_VERSION_HEX >= ... */ +#define PY_VERSION_HEX ((PY_MAJOR_VERSION << 24) | \ + (PY_MINOR_VERSION << 16) | \ + (PY_MICRO_VERSION << 8) | \ + (PY_RELEASE_LEVEL << 4) | \ + (PY_RELEASE_SERIAL << 0)) diff --git a/vscript/languages/python/python-2.5.1/include/pgen.h b/vscript/languages/python/python-2.5.1/include/pgen.h new file mode 100644 index 00000000..8a325ed0 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/pgen.h @@ -0,0 +1,18 @@ +#ifndef Py_PGEN_H +#define Py_PGEN_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Parser generator interface */ + +extern grammar *meta_grammar(void); + +struct _node; +extern grammar *pgen(struct _node *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PGEN_H */ diff --git a/vscript/languages/python/python-2.5.1/include/pgenheaders.h b/vscript/languages/python/python-2.5.1/include/pgenheaders.h new file mode 100644 index 00000000..2049ae32 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/pgenheaders.h @@ -0,0 +1,42 @@ +#ifndef Py_PGENHEADERS_H +#define Py_PGENHEADERS_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Include files and extern declarations used by most of the parser. */ + +#include "Python.h" + +PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...) + Py_GCC_ATTRIBUTE((format(printf, 1, 2))); +PyAPI_FUNC(void) PySys_WriteStderr(const char *format, ...) + Py_GCC_ATTRIBUTE((format(printf, 1, 2))); + +#define addarc _Py_addarc +#define addbit _Py_addbit +#define adddfa _Py_adddfa +#define addfirstsets _Py_addfirstsets +#define addlabel _Py_addlabel +#define addstate _Py_addstate +#define delbitset _Py_delbitset +#define dumptree _Py_dumptree +#define findlabel _Py_findlabel +#define mergebitset _Py_mergebitset +#define meta_grammar _Py_meta_grammar +#define newbitset _Py_newbitset +#define newgrammar _Py_newgrammar +#define pgen _Py_pgen +#define printgrammar _Py_printgrammar +#define printnonterminals _Py_printnonterminals +#define printtree _Py_printtree +#define samebitset _Py_samebitset +#define showtree _Py_showtree +#define tok_dump _Py_tok_dump +#define translatelabels _Py_translatelabels + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PGENHEADERS_H */ diff --git a/vscript/languages/python/python-2.5.1/include/py_curses.h b/vscript/languages/python/python-2.5.1/include/py_curses.h new file mode 100644 index 00000000..aaff4bd8 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/py_curses.h @@ -0,0 +1,176 @@ + +#ifndef Py_CURSES_H +#define Py_CURSES_H + +#ifdef __APPLE__ +/* +** On Mac OS X 10.2 [n]curses.h and stdlib.h use different guards +** against multiple definition of wchar_t. +*/ +#ifdef _BSD_WCHAR_T_DEFINED_ +#define _WCHAR_T +#endif +#endif + +#ifdef __FreeBSD__ +/* +** On FreeBSD, [n]curses.h and stdlib.h/wchar.h use different guards +** against multiple definition of wchar_t and wint_t. +*/ +#ifdef _XOPEN_SOURCE_EXTENDED +#ifndef __FreeBSD_version +#include +#endif +#if __FreeBSD_version >= 500000 +#ifndef __wchar_t +#define __wchar_t +#endif +#ifndef __wint_t +#define __wint_t +#endif +#else +#ifndef _WCHAR_T +#define _WCHAR_T +#endif +#ifndef _WINT_T +#define _WINT_T +#endif +#endif +#endif +#endif + +#ifdef HAVE_NCURSES_H +#include +#else +#include +#ifdef HAVE_TERM_H +/* for tigetstr, which is not declared in SysV curses */ +#include +#endif +#endif + +#ifdef HAVE_NCURSES_H +/* configure was checking , but we will + use , which has all these features. */ +#ifndef WINDOW_HAS_FLAGS +#define WINDOW_HAS_FLAGS 1 +#endif +#ifndef MVWDELCH_IS_EXPRESSION +#define MVWDELCH_IS_EXPRESSION 1 +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define PyCurses_API_pointers 4 + +/* Type declarations */ + +typedef struct { + PyObject_HEAD + WINDOW *win; +} PyCursesWindowObject; + +#define PyCursesWindow_Check(v) ((v)->ob_type == &PyCursesWindow_Type) + +#ifdef CURSES_MODULE +/* This section is used when compiling _cursesmodule.c */ + +#else +/* This section is used in modules that use the _cursesmodule API */ + +static void **PyCurses_API; + +#define PyCursesWindow_Type (*(PyTypeObject *) PyCurses_API[0]) +#define PyCursesSetupTermCalled {if (! ((int (*)(void))PyCurses_API[1]) () ) return NULL;} +#define PyCursesInitialised {if (! ((int (*)(void))PyCurses_API[2]) () ) return NULL;} +#define PyCursesInitialisedColor {if (! ((int (*)(void))PyCurses_API[3]) () ) return NULL;} + +#define import_curses() \ +{ \ + PyObject *module = PyImport_ImportModule("_curses"); \ + if (module != NULL) { \ + PyObject *module_dict = PyModule_GetDict(module); \ + PyObject *c_api_object = PyDict_GetItemString(module_dict, "_C_API"); \ + if (PyCObject_Check(c_api_object)) { \ + PyCurses_API = (void **)PyCObject_AsVoidPtr(c_api_object); \ + } \ + } \ +} +#endif + +/* general error messages */ +static char *catchall_ERR = "curses function returned ERR"; +static char *catchall_NULL = "curses function returned NULL"; + +/* Function Prototype Macros - They are ugly but very, very useful. ;-) + + X - function name + TYPE - parameter Type + ERGSTR - format string for construction of the return value + PARSESTR - format string for argument parsing + */ + +#define NoArgNoReturnFunction(X) \ +static PyObject *PyCurses_ ## X (PyObject *self) \ +{ \ + PyCursesInitialised \ + return PyCursesCheckERR(X(), # X); } + +#define NoArgOrFlagNoReturnFunction(X) \ +static PyObject *PyCurses_ ## X (PyObject *self, PyObject *args) \ +{ \ + int flag = 0; \ + PyCursesInitialised \ + switch(PyTuple_Size(args)) { \ + case 0: \ + return PyCursesCheckERR(X(), # X); \ + case 1: \ + if (!PyArg_ParseTuple(args, "i;True(1) or False(0)", &flag)) return NULL; \ + if (flag) return PyCursesCheckERR(X(), # X); \ + else return PyCursesCheckERR(no ## X (), # X); \ + default: \ + PyErr_SetString(PyExc_TypeError, # X " requires 0 or 1 arguments"); \ + return NULL; } } + +#define NoArgReturnIntFunction(X) \ +static PyObject *PyCurses_ ## X (PyObject *self) \ +{ \ + PyCursesInitialised \ + return PyInt_FromLong((long) X()); } + + +#define NoArgReturnStringFunction(X) \ +static PyObject *PyCurses_ ## X (PyObject *self) \ +{ \ + PyCursesInitialised \ + return PyString_FromString(X()); } + +#define NoArgTrueFalseFunction(X) \ +static PyObject *PyCurses_ ## X (PyObject *self) \ +{ \ + PyCursesInitialised \ + if (X () == FALSE) { \ + Py_INCREF(Py_False); \ + return Py_False; \ + } \ + Py_INCREF(Py_True); \ + return Py_True; } + +#define NoArgNoReturnVoidFunction(X) \ +static PyObject *PyCurses_ ## X (PyObject *self) \ +{ \ + PyCursesInitialised \ + X(); \ + Py_INCREF(Py_None); \ + return Py_None; } + +#ifdef __cplusplus +} +#endif + +#endif /* !defined(Py_CURSES_H) */ + + diff --git a/vscript/languages/python/python-2.5.1/include/pyarena.h b/vscript/languages/python/python-2.5.1/include/pyarena.h new file mode 100644 index 00000000..5f193fec --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/pyarena.h @@ -0,0 +1,62 @@ +/* An arena-like memory interface for the compiler. + */ + +#ifndef Py_PYARENA_H +#define Py_PYARENA_H + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct _arena PyArena; + + /* PyArena_New() and PyArena_Free() create a new arena and free it, + respectively. Once an arena has been created, it can be used + to allocate memory via PyArena_Malloc(). Pointers to PyObject can + also be registered with the arena via PyArena_AddPyObject(), and the + arena will ensure that the PyObjects stay alive at least until + PyArena_Free() is called. When an arena is freed, all the memory it + allocated is freed, the arena releases internal references to registered + PyObject*, and none of its pointers are valid. + XXX (tim) What does "none of its pointers are valid" mean? Does it + XXX mean that pointers previously obtained via PyArena_Malloc() are + XXX no longer valid? (That's clearly true, but not sure that's what + XXX the text is trying to say.) + + PyArena_New() returns an arena pointer. On error, it + returns a negative number and sets an exception. + XXX (tim): Not true. On error, PyArena_New() actually returns NULL, + XXX and looks like it may or may not set an exception (e.g., if the + XXX internal PyList_New(0) returns NULL, PyArena_New() passes that on + XXX and an exception is set; OTOH, if the internal + XXX block_new(DEFAULT_BLOCK_SIZE) returns NULL, that's passed on but + XXX an exception is not set in that case). + */ + PyAPI_FUNC(PyArena *) PyArena_New(void); + PyAPI_FUNC(void) PyArena_Free(PyArena *); + + /* Mostly like malloc(), return the address of a block of memory spanning + * `size` bytes, or return NULL (without setting an exception) if enough + * new memory can't be obtained. Unlike malloc(0), PyArena_Malloc() with + * size=0 does not guarantee to return a unique pointer (the pointer + * returned may equal one or more other pointers obtained from + * PyArena_Malloc()). + * Note that pointers obtained via PyArena_Malloc() must never be passed to + * the system free() or realloc(), or to any of Python's similar memory- + * management functions. PyArena_Malloc()-obtained pointers remain valid + * until PyArena_Free(ar) is called, at which point all pointers obtained + * from the arena `ar` become invalid simultaneously. + */ + PyAPI_FUNC(void *) PyArena_Malloc(PyArena *, size_t size); + + /* This routine isn't a proper arena allocation routine. It takes + * a PyObject* and records it so that it can be DECREFed when the + * arena is freed. + */ + PyAPI_FUNC(int) PyArena_AddPyObject(PyArena *, PyObject *); + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_PYARENA_H */ diff --git a/vscript/languages/python/python-2.5.1/include/pyconfig.h b/vscript/languages/python/python-2.5.1/include/pyconfig.h new file mode 100644 index 00000000..20201d09 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/pyconfig.h @@ -0,0 +1,688 @@ +#ifndef Py_CONFIG_H +#define Py_CONFIG_H + +/* pyconfig.h. NOT Generated automatically by configure. + +This is a manually maintained version used for the Watcom, +Borland and Microsoft Visual C++ compilers. It is a +standard part of the Python distribution. + +WINDOWS DEFINES: +The code specific to Windows should be wrapped around one of +the following #defines + +MS_WIN64 - Code specific to the MS Win64 API +MS_WIN32 - Code specific to the MS Win32 (and Win64) API (obsolete, this covers all supported APIs) +MS_WINDOWS - Code specific to Windows, but all versions. +MS_WINCE - Code specific to Windows CE +Py_ENABLE_SHARED - Code if the Python core is built as a DLL. + +Also note that neither "_M_IX86" or "_MSC_VER" should be used for +any purpose other than "Windows Intel x86 specific" and "Microsoft +compiler specific". Therefore, these should be very rare. + + +NOTE: The following symbols are deprecated: +NT, WIN32, USE_DL_EXPORT, USE_DL_IMPORT, DL_EXPORT, DL_IMPORT +MS_CORE_DLL. + +*/ + +#ifdef _WIN32_WCE +#define MS_WINCE +#endif + +/* Visual Studio 2005 introduces deprecation warnings for + "insecure" and POSIX functions. The insecure functions should + be replaced by *_s versions (according to Microsoft); the + POSIX functions by _* versions (which, according to Microsoft, + would be ISO C conforming). Neither renaming is feasible, so + we just silence the warnings. */ + +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif +#ifndef _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_NONSTDC_NO_DEPRECATE 1 +#endif + +/* Windows CE does not have these */ +#ifndef MS_WINCE +#define HAVE_IO_H +#define HAVE_SYS_UTIME_H +#define HAVE_TEMPNAM +#define HAVE_TMPFILE +#define HAVE_TMPNAM +#define HAVE_CLOCK +#define HAVE_STRERROR +#endif + +#ifdef HAVE_IO_H +#include +#endif + +#define HAVE_HYPOT +#define HAVE_STRFTIME +#define DONT_HAVE_SIG_ALARM +#define DONT_HAVE_SIG_PAUSE +#define LONG_BIT 32 +#define WORD_BIT 32 +#define PREFIX "" +#define EXEC_PREFIX "" + +#define MS_WIN32 /* only support win32 and greater. */ +#define MS_WINDOWS +#ifndef PYTHONPATH +# define PYTHONPATH ".\\DLLs;.\\lib;.\\lib\\plat-win;.\\lib\\lib-tk" +#endif +#define NT_THREADS +#define WITH_THREAD +#ifndef NETSCAPE_PI +#define USE_SOCKET +#endif + +#ifdef MS_WINCE +/* Python uses GetVersion() to distinguish between + * Windows NT and 9x/ME where OS Unicode support is concerned. + * Windows CE supports Unicode in the same way as NT so we + * define the missing GetVersion() accordingly. + */ +#define GetVersion() (4) +/* Windows CE does not support environment variables */ +#define getenv(v) (NULL) +#define environ (NULL) +#endif + +/* Compiler specific defines */ + +/* ------------------------------------------------------------------------*/ +/* Microsoft C defines _MSC_VER */ +#ifdef _MSC_VER + +/* We want COMPILER to expand to a string containing _MSC_VER's *value*. + * This is horridly tricky, because the stringization operator only works + * on macro arguments, and doesn't evaluate macros passed *as* arguments. + * Attempts simpler than the following appear doomed to produce "_MSC_VER" + * literally in the string. + */ +#define _Py_PASTE_VERSION(SUFFIX) \ + ("[MSC v." _Py_STRINGIZE(_MSC_VER) " " SUFFIX "]") +/* e.g., this produces, after compile-time string catenation, + * ("[MSC v.1200 32 bit (Intel)]") + * + * _Py_STRINGIZE(_MSC_VER) expands to + * _Py_STRINGIZE1((_MSC_VER)) expands to + * _Py_STRINGIZE2(_MSC_VER) but as this call is the result of token-pasting + * it's scanned again for macros and so further expands to (under MSVC 6) + * _Py_STRINGIZE2(1200) which then expands to + * "1200" + */ +#define _Py_STRINGIZE(X) _Py_STRINGIZE1((X)) +#define _Py_STRINGIZE1(X) _Py_STRINGIZE2 ## X +#define _Py_STRINGIZE2(X) #X + +/* MSVC defines _WINxx to differentiate the windows platform types + + Note that for compatibility reasons _WIN32 is defined on Win32 + *and* on Win64. For the same reasons, in Python, MS_WIN32 is + defined on Win32 *and* Win64. Win32 only code must therefore be + guarded as follows: + #if defined(MS_WIN32) && !defined(MS_WIN64) +*/ +#ifdef _WIN64 +#define MS_WIN64 +#endif + +/* set the COMPILER */ +#ifdef MS_WIN64 +#ifdef _M_IX86 +#define COMPILER _Py_PASTE_VERSION("64 bit (Intel)") +#elif defined(_M_IA64) +#define COMPILER _Py_PASTE_VERSION("64 bit (Itanium)") +#elif defined(_M_AMD64) +#define COMPILER _Py_PASTE_VERSION("64 bit (AMD64)") +#else +#define COMPILER _Py_PASTE_VERSION("64 bit (Unknown)") +#endif +#endif /* MS_WIN64 */ + +/* _W64 is not defined for VC6 or eVC4 */ +#ifndef _W64 +#define _W64 +#endif + +/* Define like size_t, omitting the "unsigned" */ +#ifdef MS_WIN64 +typedef __int64 ssize_t; +#else +typedef _W64 int ssize_t; +#endif +#define HAVE_SSIZE_T 1 + +#if defined(MS_WIN32) && !defined(MS_WIN64) +#ifdef _M_IX86 +#define COMPILER _Py_PASTE_VERSION("32 bit (Intel)") +#else +#define COMPILER _Py_PASTE_VERSION("32 bit (Unknown)") +#endif +#endif /* MS_WIN32 && !MS_WIN64 */ + +typedef int pid_t; +#define hypot _hypot + +#include +#define Py_IS_NAN _isnan +#define Py_IS_INFINITY(X) (!_finite(X) && !_isnan(X)) +#define Py_IS_FINITE(X) _finite(X) + +/* Turn off warnings about deprecated C runtime functions in + VisualStudio .NET 2005 */ +#if _MSC_VER >= 1400 && !defined _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE +#endif + +#endif /* _MSC_VER */ + +/* define some ANSI types that are not defined in earlier Win headers */ +#if defined(_MSC_VER) && _MSC_VER >= 1200 +/* This file only exists in VC 6.0 or higher */ +#include +#endif + +/* ------------------------------------------------------------------------*/ +/* The Borland compiler defines __BORLANDC__ */ +/* XXX These defines are likely incomplete, but should be easy to fix. */ +#ifdef __BORLANDC__ +#define COMPILER "[Borland]" + +#ifdef _WIN32 +/* tested with BCC 5.5 (__BORLANDC__ >= 0x0550) + */ + +typedef int pid_t; +/* BCC55 seems to understand __declspec(dllimport), it is used in its + own header files (winnt.h, ...) - so we can do nothing and get the default*/ + +#undef HAVE_SYS_UTIME_H +#define HAVE_UTIME_H +#define HAVE_DIRENT_H + +/* rename a few functions for the Borland compiler */ +#include +#define _chsize chsize +#define _setmode setmode + +#else /* !_WIN32 */ +#error "Only Win32 and later are supported" +#endif /* !_WIN32 */ + +#endif /* BORLANDC */ + +/* ------------------------------------------------------------------------*/ +/* egcs/gnu-win32 defines __GNUC__ and _WIN32 */ +#if defined(__GNUC__) && defined(_WIN32) +/* XXX These defines are likely incomplete, but should be easy to fix. + They should be complete enough to build extension modules. */ +/* Suggested by Rene Liebscher to avoid a GCC 2.91.* + bug that requires structure imports. More recent versions of the + compiler don't exhibit this bug. +*/ +#if (__GNUC__==2) && (__GNUC_MINOR__<=91) +#warning "Please use an up-to-date version of gcc! (>2.91 recommended)" +#endif + +#define COMPILER "[gcc]" +#define hypot _hypot +#define PY_LONG_LONG long long +#endif /* GNUC */ + +/* ------------------------------------------------------------------------*/ +/* lcc-win32 defines __LCC__ */ +#if defined(__LCC__) +/* XXX These defines are likely incomplete, but should be easy to fix. + They should be complete enough to build extension modules. */ + +#define COMPILER "[lcc-win32]" +typedef int pid_t; +/* __declspec() is supported here too - do nothing to get the defaults */ + +#endif /* LCC */ + +/* ------------------------------------------------------------------------*/ +/* End of compilers - finish up */ + +#ifndef NO_STDIO_H +# include +#endif + +/* 64 bit ints are usually spelt __int64 unless compiler has overridden */ +#define HAVE_LONG_LONG 1 +#ifndef PY_LONG_LONG +# define PY_LONG_LONG __int64 +#endif + +/* For Windows the Python core is in a DLL by default. Test +Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ +#if !defined(MS_NO_COREDLL) && !defined(Py_NO_ENABLE_SHARED) +# define Py_ENABLE_SHARED 1 /* standard symbol for shared library */ +# define MS_COREDLL /* deprecated old symbol */ +#endif /* !MS_NO_COREDLL && ... */ + +/* Deprecated USE_DL_EXPORT macro - please use Py_BUILD_CORE */ +#ifdef USE_DL_EXPORT +# define Py_BUILD_CORE +#endif /* USE_DL_EXPORT */ + +/* All windows compilers that use this header support __declspec */ +#define HAVE_DECLSPEC_DLL + +/* For an MSVC DLL, we can nominate the .lib files used by extensions */ +#ifdef MS_COREDLL +# ifndef Py_BUILD_CORE /* not building the core - must be an ext */ +# if defined(_MSC_VER) + /* So MSVC users need not specify the .lib file in + their Makefile (other compilers are generally + taken care of by distutils.) */ +# ifdef _DEBUG +# pragma comment(lib,"python25_d.lib") +# else +# pragma comment(lib,"python25.lib") +# endif /* _DEBUG */ +# endif /* _MSC_VER */ +# endif /* Py_BUILD_CORE */ +#endif /* MS_COREDLL */ + +#if defined(MS_WIN64) +/* maintain "win32" sys.platform for backward compatibility of Python code, + the Win64 API should be close enough to the Win32 API to make this + preferable */ +# define PLATFORM "win32" +# define SIZEOF_VOID_P 8 +# define SIZEOF_TIME_T 8 +# define SIZEOF_OFF_T 4 +# define SIZEOF_FPOS_T 8 +# define SIZEOF_HKEY 8 +# define SIZEOF_SIZE_T 8 +/* configure.in defines HAVE_LARGEFILE_SUPPORT iff HAVE_LONG_LONG, + sizeof(off_t) > sizeof(long), and sizeof(PY_LONG_LONG) >= sizeof(off_t). + On Win64 the second condition is not true, but if fpos_t replaces off_t + then this is true. The uses of HAVE_LARGEFILE_SUPPORT imply that Win64 + should define this. */ +# define HAVE_LARGEFILE_SUPPORT +#elif defined(MS_WIN32) +# define PLATFORM "win32" +# define HAVE_LARGEFILE_SUPPORT +# define SIZEOF_VOID_P 4 +# define SIZEOF_OFF_T 4 +# define SIZEOF_FPOS_T 8 +# define SIZEOF_HKEY 4 +# define SIZEOF_SIZE_T 4 + /* MS VS2005 changes time_t to an 64-bit type on all platforms */ +# if defined(_MSC_VER) && _MSC_VER >= 1400 +# define SIZEOF_TIME_T 8 +# else +# define SIZEOF_TIME_T 4 +# endif +#endif + +#ifdef _DEBUG +# define Py_DEBUG +#endif + + +#ifdef MS_WIN32 + +#define SIZEOF_SHORT 2 +#define SIZEOF_INT 4 +#define SIZEOF_LONG 4 +#define SIZEOF_LONG_LONG 8 +#define SIZEOF_DOUBLE 8 +#define SIZEOF_FLOAT 4 + +/* VC 7.1 has them and VC 6.0 does not. VC 6.0 has a version number of 1200. + Microsoft eMbedded Visual C++ 4.0 has a version number of 1201 and doesn't + define these. + If some compiler does not provide them, modify the #if appropriately. */ +#if defined(_MSC_VER) +#if _MSC_VER > 1201 +#define HAVE_UINTPTR_T 1 +#define HAVE_INTPTR_T 1 +#else +/* VC6 & eVC4 don't support the C99 LL suffix for 64-bit integer literals */ +#define Py_LL(x) x##I64 +#endif /* _MSC_VER > 1200 */ +#endif /* _MSC_VER */ + +#endif + +/* Fairly standard from here! */ + +/* Define if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +/* #undef _ALL_SOURCE */ +#endif + +/* Define to empty if the keyword does not work. */ +/* #define const */ + +/* Define to 1 if you have the header file. */ +#ifndef MS_WINCE +#define HAVE_CONIO_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef MS_WINCE +#define HAVE_DIRECT_H 1 +#endif + +/* Define if you have dirent.h. */ +/* #define DIRENT 1 */ + +/* Define to the type of elements in the array set by `getgroups'. + Usually this is either `int' or `gid_t'. */ +/* #undef GETGROUPS_T */ + +/* Define to `int' if doesn't define. */ +/* #undef gid_t */ + +/* Define if your struct tm has tm_zone. */ +/* #undef HAVE_TM_ZONE */ + +/* Define if you don't have tm_zone but do have the external array + tzname. */ +#define HAVE_TZNAME + +/* Define to `int' if doesn't define. */ +/* #undef mode_t */ + +/* Define if you don't have dirent.h, but have ndir.h. */ +/* #undef NDIR */ + +/* Define to `long' if doesn't define. */ +/* #undef off_t */ + +/* Define to `int' if doesn't define. */ +/* #undef pid_t */ + +/* Define if the system does not provide POSIX.1 features except + with this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define if you need to in order for stat and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* Define to `int' if doesn't define. */ +#if _MSC_VER + 0 >= 1300 +/* VC.NET typedefs socklen_t in ws2tcpip.h. */ +#else +#define socklen_t int +#endif + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you don't have dirent.h, but have sys/dir.h. */ +/* #undef SYSDIR */ + +/* Define if you don't have dirent.h, but have sys/ndir.h. */ +/* #undef SYSNDIR */ + +/* Define if you can safely include both and . */ +/* #undef TIME_WITH_SYS_TIME */ + +/* Define if your declares struct tm. */ +/* #define TM_IN_SYS_TIME 1 */ + +/* Define to `int' if doesn't define. */ +/* #undef uid_t */ + +/* Define if the closedir function returns void instead of int. */ +/* #undef VOID_CLOSEDIR */ + +/* Define if getpgrp() must be called as getpgrp(0) + and (consequently) setpgrp() as setpgrp(0, 0). */ +/* #undef GETPGRP_HAVE_ARGS */ + +/* Define this if your time.h defines altzone */ +/* #define HAVE_ALTZONE */ + +/* Define if you have the putenv function. */ +#ifndef MS_WINCE +#define HAVE_PUTENV +#endif + +/* Define if your compiler supports function prototypes */ +#define HAVE_PROTOTYPES + +/* Define if you can safely include both and + (which you can't on SCO ODT 3.0). */ +/* #undef SYS_SELECT_WITH_SYS_TIME */ + +/* Define if you want documentation strings in extension modules */ +#define WITH_DOC_STRINGS 1 + +/* Define if you want to compile in rudimentary thread support */ +/* #undef WITH_THREAD */ + +/* Define if you want to use the GNU readline library */ +/* #define WITH_READLINE 1 */ + +/* Define if you want to have a Unicode type. */ +#define Py_USING_UNICODE + +/* Define as the integral type used for Unicode representation. */ +#define PY_UNICODE_TYPE unsigned short + +/* Define as the size of the unicode type. */ +#define Py_UNICODE_SIZE SIZEOF_SHORT + +/* Define if you have a useable wchar_t type defined in wchar.h; useable + means wchar_t must be 16-bit unsigned type. (see + Include/unicodeobject.h). */ +#if Py_UNICODE_SIZE == 2 +#define HAVE_USABLE_WCHAR_T + +/* Define to indicate that the Python Unicode representation can be passed + as-is to Win32 Wide API. */ +#define Py_WIN_WIDE_FILENAMES +#endif + +/* Use Python's own small-block memory-allocator. */ +#define WITH_PYMALLOC 1 + +/* Define if you have clock. */ +/* #define HAVE_CLOCK */ + +/* Define when any dynamic module loading is enabled */ +#define HAVE_DYNAMIC_LOADING + +/* Define if you have ftime. */ +#ifndef MS_WINCE +#define HAVE_FTIME +#endif + +/* Define if you have getpeername. */ +#define HAVE_GETPEERNAME + +/* Define if you have getpgrp. */ +/* #undef HAVE_GETPGRP */ + +/* Define if you have getpid. */ +#ifndef MS_WINCE +#define HAVE_GETPID +#endif + +/* Define if you have gettimeofday. */ +/* #undef HAVE_GETTIMEOFDAY */ + +/* Define if you have getwd. */ +/* #undef HAVE_GETWD */ + +/* Define if you have lstat. */ +/* #undef HAVE_LSTAT */ + +/* Define if you have the mktime function. */ +#define HAVE_MKTIME + +/* Define if you have nice. */ +/* #undef HAVE_NICE */ + +/* Define if you have readlink. */ +/* #undef HAVE_READLINK */ + +/* Define if you have select. */ +/* #undef HAVE_SELECT */ + +/* Define if you have setpgid. */ +/* #undef HAVE_SETPGID */ + +/* Define if you have setpgrp. */ +/* #undef HAVE_SETPGRP */ + +/* Define if you have setsid. */ +/* #undef HAVE_SETSID */ + +/* Define if you have setvbuf. */ +#define HAVE_SETVBUF + +/* Define if you have siginterrupt. */ +/* #undef HAVE_SIGINTERRUPT */ + +/* Define if you have symlink. */ +/* #undef HAVE_SYMLINK */ + +/* Define if you have tcgetpgrp. */ +/* #undef HAVE_TCGETPGRP */ + +/* Define if you have tcsetpgrp. */ +/* #undef HAVE_TCSETPGRP */ + +/* Define if you have times. */ +/* #undef HAVE_TIMES */ + +/* Define if you have uname. */ +/* #undef HAVE_UNAME */ + +/* Define if you have waitpid. */ +/* #undef HAVE_WAITPID */ + +/* Define to 1 if you have the `wcscoll' function. */ +#ifndef MS_WINCE +#define HAVE_WCSCOLL 1 +#endif + +/* Define if you have the header file. */ +/* #undef HAVE_DLFCN_H */ + +/* Define to 1 if you have the header file. */ +#ifndef MS_WINCE +#define HAVE_ERRNO_H 1 +#endif + +/* Define if you have the header file. */ +#ifndef MS_WINCE +#define HAVE_FCNTL_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef MS_WINCE +#define HAVE_PROCESS_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef MS_WINCE +#define HAVE_SIGNAL_H 1 +#endif + +/* Define if you have the prototypes. */ +#define HAVE_STDARG_PROTOTYPES + +/* Define if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_AUDIOIO_H */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_PARAM_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_SELECT_H 1 */ + +/* Define to 1 if you have the header file. */ +#ifndef MS_WINCE +#define HAVE_SYS_STAT_H 1 +#endif + +/* Define if you have the header file. */ +/* #define HAVE_SYS_TIME_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_TIMES_H 1 */ + +/* Define to 1 if you have the header file. */ +#ifndef MS_WINCE +#define HAVE_SYS_TYPES_H 1 +#endif + +/* Define if you have the header file. */ +/* #define HAVE_SYS_UN_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_UTIME_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_UTSNAME_H 1 */ + +/* Define if you have the header file. */ +/* #undef HAVE_THREAD_H */ + +/* Define if you have the header file. */ +/* #define HAVE_UNISTD_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_UTIME_H 1 */ + +/* Define if the compiler provides a wchar.h header file. */ +#define HAVE_WCHAR_H 1 + +/* Define if you have the dl library (-ldl). */ +/* #undef HAVE_LIBDL */ + +/* Define if you have the mpc library (-lmpc). */ +/* #undef HAVE_LIBMPC */ + +/* Define if you have the nsl library (-lnsl). */ +#define HAVE_LIBNSL 1 + +/* Define if you have the seq library (-lseq). */ +/* #undef HAVE_LIBSEQ */ + +/* Define if you have the socket library (-lsocket). */ +#define HAVE_LIBSOCKET 1 + +/* Define if you have the sun library (-lsun). */ +/* #undef HAVE_LIBSUN */ + +/* Define if you have the termcap library (-ltermcap). */ +/* #undef HAVE_LIBTERMCAP */ + +/* Define if you have the termlib library (-ltermlib). */ +/* #undef HAVE_LIBTERMLIB */ + +/* Define if you have the thread library (-lthread). */ +/* #undef HAVE_LIBTHREAD */ + +/* WinSock does not use a bitmask in select, and uses + socket handles greater than FD_SETSIZE */ +#define Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE + +#endif /* !Py_CONFIG_H */ diff --git a/vscript/languages/python/python-2.5.1/include/pydebug.h b/vscript/languages/python/python-2.5.1/include/pydebug.h new file mode 100644 index 00000000..f49a98e4 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/pydebug.h @@ -0,0 +1,34 @@ + +#ifndef Py_PYDEBUG_H +#define Py_PYDEBUG_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(int) Py_DebugFlag; +PyAPI_DATA(int) Py_VerboseFlag; +PyAPI_DATA(int) Py_InteractiveFlag; +PyAPI_DATA(int) Py_OptimizeFlag; +PyAPI_DATA(int) Py_NoSiteFlag; +PyAPI_DATA(int) Py_UseClassExceptionsFlag; +PyAPI_DATA(int) Py_FrozenFlag; +PyAPI_DATA(int) Py_TabcheckFlag; +PyAPI_DATA(int) Py_UnicodeFlag; +PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; +PyAPI_DATA(int) Py_DivisionWarningFlag; +/* _XXX Py_QnewFlag should go away in 3.0. It's true iff -Qnew is passed, + on the command line, and is used in 2.2 by ceval.c to make all "/" divisions + true divisions (which they will be in 3.0). */ +PyAPI_DATA(int) _Py_QnewFlag; + +/* this is a wrapper around getenv() that pays attention to + Py_IgnoreEnvironmentFlag. It should be used for getting variables like + PYTHONPATH and PYTHONHOME from the environment */ +#define Py_GETENV(s) (Py_IgnoreEnvironmentFlag ? NULL : getenv(s)) + +PyAPI_FUNC(void) Py_FatalError(const char *message); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYDEBUG_H */ diff --git a/vscript/languages/python/python-2.5.1/include/pyerrors.h b/vscript/languages/python/python-2.5.1/include/pyerrors.h new file mode 100644 index 00000000..9532e32b --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/pyerrors.h @@ -0,0 +1,334 @@ +#ifndef Py_ERRORS_H +#define Py_ERRORS_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Error objects */ + +typedef struct { + PyObject_HEAD + PyObject *dict; + PyObject *args; + PyObject *message; +} PyBaseExceptionObject; + +typedef struct { + PyObject_HEAD + PyObject *dict; + PyObject *args; + PyObject *message; + PyObject *msg; + PyObject *filename; + PyObject *lineno; + PyObject *offset; + PyObject *text; + PyObject *print_file_and_line; +} PySyntaxErrorObject; + +#ifdef Py_USING_UNICODE +typedef struct { + PyObject_HEAD + PyObject *dict; + PyObject *args; + PyObject *message; + PyObject *encoding; + PyObject *object; + PyObject *start; + PyObject *end; + PyObject *reason; +} PyUnicodeErrorObject; +#endif + +typedef struct { + PyObject_HEAD + PyObject *dict; + PyObject *args; + PyObject *message; + PyObject *code; +} PySystemExitObject; + +typedef struct { + PyObject_HEAD + PyObject *dict; + PyObject *args; + PyObject *message; + PyObject *myerrno; + PyObject *strerror; + PyObject *filename; +} PyEnvironmentErrorObject; + +#ifdef MS_WINDOWS +typedef struct { + PyObject_HEAD + PyObject *dict; + PyObject *args; + PyObject *message; + PyObject *myerrno; + PyObject *strerror; + PyObject *filename; + PyObject *winerror; +} PyWindowsErrorObject; +#endif + +/* Error handling definitions */ + +PyAPI_FUNC(void) PyErr_SetNone(PyObject *); +PyAPI_FUNC(void) PyErr_SetObject(PyObject *, PyObject *); +PyAPI_FUNC(void) PyErr_SetString(PyObject *, const char *); +PyAPI_FUNC(PyObject *) PyErr_Occurred(void); +PyAPI_FUNC(void) PyErr_Clear(void); +PyAPI_FUNC(void) PyErr_Fetch(PyObject **, PyObject **, PyObject **); +PyAPI_FUNC(void) PyErr_Restore(PyObject *, PyObject *, PyObject *); + +#ifdef Py_DEBUG +#define _PyErr_OCCURRED() PyErr_Occurred() +#else +#define _PyErr_OCCURRED() (_PyThreadState_Current->curexc_type) +#endif + +/* Error testing and normalization */ +PyAPI_FUNC(int) PyErr_GivenExceptionMatches(PyObject *, PyObject *); +PyAPI_FUNC(int) PyErr_ExceptionMatches(PyObject *); +PyAPI_FUNC(void) PyErr_NormalizeException(PyObject**, PyObject**, PyObject**); + +/* */ + +#define PyExceptionClass_Check(x) \ + (PyClass_Check((x)) \ + || (PyType_Check((x)) && PyType_IsSubtype( \ + (PyTypeObject*)(x), (PyTypeObject*)PyExc_BaseException))) + + +#define PyExceptionInstance_Check(x) \ + (PyInstance_Check((x)) || \ + (PyType_IsSubtype((x)->ob_type, (PyTypeObject*)PyExc_BaseException))) + +#define PyExceptionClass_Name(x) \ + (PyClass_Check((x)) \ + ? PyString_AS_STRING(((PyClassObject*)(x))->cl_name) \ + : (char *)(((PyTypeObject*)(x))->tp_name)) + +#define PyExceptionInstance_Class(x) \ + ((PyInstance_Check((x)) \ + ? (PyObject*)((PyInstanceObject*)(x))->in_class \ + : (PyObject*)((x)->ob_type))) + + +/* Predefined exceptions */ + +PyAPI_DATA(PyObject *) PyExc_BaseException; +PyAPI_DATA(PyObject *) PyExc_Exception; +PyAPI_DATA(PyObject *) PyExc_StopIteration; +PyAPI_DATA(PyObject *) PyExc_GeneratorExit; +PyAPI_DATA(PyObject *) PyExc_StandardError; +PyAPI_DATA(PyObject *) PyExc_ArithmeticError; +PyAPI_DATA(PyObject *) PyExc_LookupError; + +PyAPI_DATA(PyObject *) PyExc_AssertionError; +PyAPI_DATA(PyObject *) PyExc_AttributeError; +PyAPI_DATA(PyObject *) PyExc_EOFError; +PyAPI_DATA(PyObject *) PyExc_FloatingPointError; +PyAPI_DATA(PyObject *) PyExc_EnvironmentError; +PyAPI_DATA(PyObject *) PyExc_IOError; +PyAPI_DATA(PyObject *) PyExc_OSError; +PyAPI_DATA(PyObject *) PyExc_ImportError; +PyAPI_DATA(PyObject *) PyExc_IndexError; +PyAPI_DATA(PyObject *) PyExc_KeyError; +PyAPI_DATA(PyObject *) PyExc_KeyboardInterrupt; +PyAPI_DATA(PyObject *) PyExc_MemoryError; +PyAPI_DATA(PyObject *) PyExc_NameError; +PyAPI_DATA(PyObject *) PyExc_OverflowError; +PyAPI_DATA(PyObject *) PyExc_RuntimeError; +PyAPI_DATA(PyObject *) PyExc_NotImplementedError; +PyAPI_DATA(PyObject *) PyExc_SyntaxError; +PyAPI_DATA(PyObject *) PyExc_IndentationError; +PyAPI_DATA(PyObject *) PyExc_TabError; +PyAPI_DATA(PyObject *) PyExc_ReferenceError; +PyAPI_DATA(PyObject *) PyExc_SystemError; +PyAPI_DATA(PyObject *) PyExc_SystemExit; +PyAPI_DATA(PyObject *) PyExc_TypeError; +PyAPI_DATA(PyObject *) PyExc_UnboundLocalError; +PyAPI_DATA(PyObject *) PyExc_UnicodeError; +PyAPI_DATA(PyObject *) PyExc_UnicodeEncodeError; +PyAPI_DATA(PyObject *) PyExc_UnicodeDecodeError; +PyAPI_DATA(PyObject *) PyExc_UnicodeTranslateError; +PyAPI_DATA(PyObject *) PyExc_ValueError; +PyAPI_DATA(PyObject *) PyExc_ZeroDivisionError; +#ifdef MS_WINDOWS +PyAPI_DATA(PyObject *) PyExc_WindowsError; +#endif +#ifdef __VMS +PyAPI_DATA(PyObject *) PyExc_VMSError; +#endif + +PyAPI_DATA(PyObject *) PyExc_MemoryErrorInst; + +/* Predefined warning categories */ +PyAPI_DATA(PyObject *) PyExc_Warning; +PyAPI_DATA(PyObject *) PyExc_UserWarning; +PyAPI_DATA(PyObject *) PyExc_DeprecationWarning; +PyAPI_DATA(PyObject *) PyExc_PendingDeprecationWarning; +PyAPI_DATA(PyObject *) PyExc_SyntaxWarning; +PyAPI_DATA(PyObject *) PyExc_RuntimeWarning; +PyAPI_DATA(PyObject *) PyExc_FutureWarning; +PyAPI_DATA(PyObject *) PyExc_ImportWarning; +PyAPI_DATA(PyObject *) PyExc_UnicodeWarning; + + +/* Convenience functions */ + +PyAPI_FUNC(int) PyErr_BadArgument(void); +PyAPI_FUNC(PyObject *) PyErr_NoMemory(void); +PyAPI_FUNC(PyObject *) PyErr_SetFromErrno(PyObject *); +PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilenameObject( + PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilename(PyObject *, char *); +#ifdef Py_WIN_WIDE_FILENAMES +PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithUnicodeFilename( + PyObject *, Py_UNICODE *); +#endif /* Py_WIN_WIDE_FILENAMES */ + +PyAPI_FUNC(PyObject *) PyErr_Format(PyObject *, const char *, ...) + Py_GCC_ATTRIBUTE((format(printf, 2, 3))); + +#ifdef MS_WINDOWS +PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithFilenameObject( + int, const char *); +PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithFilename( + int, const char *); +#ifdef Py_WIN_WIDE_FILENAMES +PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithUnicodeFilename( + int, const Py_UNICODE *); +#endif /* Py_WIN_WIDE_FILENAMES */ +PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErr(int); +PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilenameObject( + PyObject *,int, PyObject *); +PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilename( + PyObject *,int, const char *); +#ifdef Py_WIN_WIDE_FILENAMES +PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithUnicodeFilename( + PyObject *,int, const Py_UNICODE *); +#endif /* Py_WIN_WIDE_FILENAMES */ +PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErr(PyObject *, int); +#endif /* MS_WINDOWS */ + +/* Export the old function so that the existing API remains available: */ +PyAPI_FUNC(void) PyErr_BadInternalCall(void); +PyAPI_FUNC(void) _PyErr_BadInternalCall(char *filename, int lineno); +/* Mask the old API with a call to the new API for code compiled under + Python 2.0: */ +#define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__) + +/* Function to create a new exception */ +PyAPI_FUNC(PyObject *) PyErr_NewException(char *name, PyObject *base, + PyObject *dict); +PyAPI_FUNC(void) PyErr_WriteUnraisable(PyObject *); + +/* Issue a warning or exception */ +PyAPI_FUNC(int) PyErr_WarnEx(PyObject *category, const char *msg, + Py_ssize_t stack_level); +PyAPI_FUNC(int) PyErr_WarnExplicit(PyObject *, const char *, + const char *, int, + const char *, PyObject *); +/* PyErr_Warn is only for backwards compatability and will be removed. + Use PyErr_WarnEx instead. */ +#define PyErr_Warn(category, msg) PyErr_WarnEx(category, msg, 1) + +/* In sigcheck.c or signalmodule.c */ +PyAPI_FUNC(int) PyErr_CheckSignals(void); +PyAPI_FUNC(void) PyErr_SetInterrupt(void); + +/* Support for adding program text to SyntaxErrors */ +PyAPI_FUNC(void) PyErr_SyntaxLocation(const char *, int); +PyAPI_FUNC(PyObject *) PyErr_ProgramText(const char *, int); + +#ifdef Py_USING_UNICODE +/* The following functions are used to create and modify unicode + exceptions from C */ + +/* create a UnicodeDecodeError object */ +PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_Create( + const char *, const char *, Py_ssize_t, Py_ssize_t, Py_ssize_t, const char *); + +/* create a UnicodeEncodeError object */ +PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_Create( + const char *, const Py_UNICODE *, Py_ssize_t, Py_ssize_t, Py_ssize_t, const char *); + +/* create a UnicodeTranslateError object */ +PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_Create( + const Py_UNICODE *, Py_ssize_t, Py_ssize_t, Py_ssize_t, const char *); + +/* get the encoding attribute */ +PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetEncoding(PyObject *); +PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_GetEncoding(PyObject *); + +/* get the object attribute */ +PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetObject(PyObject *); +PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_GetObject(PyObject *); +PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_GetObject(PyObject *); + +/* get the value of the start attribute (the int * may not be NULL) + return 0 on success, -1 on failure */ +PyAPI_FUNC(int) PyUnicodeEncodeError_GetStart(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) PyUnicodeDecodeError_GetStart(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) PyUnicodeTranslateError_GetStart(PyObject *, Py_ssize_t *); + +/* assign a new value to the start attribute + return 0 on success, -1 on failure */ +PyAPI_FUNC(int) PyUnicodeEncodeError_SetStart(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyUnicodeDecodeError_SetStart(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyUnicodeTranslateError_SetStart(PyObject *, Py_ssize_t); + +/* get the value of the end attribute (the int *may not be NULL) + return 0 on success, -1 on failure */ +PyAPI_FUNC(int) PyUnicodeEncodeError_GetEnd(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) PyUnicodeDecodeError_GetEnd(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) PyUnicodeTranslateError_GetEnd(PyObject *, Py_ssize_t *); + +/* assign a new value to the end attribute + return 0 on success, -1 on failure */ +PyAPI_FUNC(int) PyUnicodeEncodeError_SetEnd(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyUnicodeDecodeError_SetEnd(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyUnicodeTranslateError_SetEnd(PyObject *, Py_ssize_t); + +/* get the value of the reason attribute */ +PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetReason(PyObject *); +PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_GetReason(PyObject *); +PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_GetReason(PyObject *); + +/* assign a new value to the reason attribute + return 0 on success, -1 on failure */ +PyAPI_FUNC(int) PyUnicodeEncodeError_SetReason( + PyObject *, const char *); +PyAPI_FUNC(int) PyUnicodeDecodeError_SetReason( + PyObject *, const char *); +PyAPI_FUNC(int) PyUnicodeTranslateError_SetReason( + PyObject *, const char *); +#endif + + +/* These APIs aren't really part of the error implementation, but + often needed to format error messages; the native C lib APIs are + not available on all platforms, which is why we provide emulations + for those platforms in Python/mysnprintf.c, + WARNING: The return value of snprintf varies across platforms; do + not rely on any particular behavior; eventually the C99 defn may + be reliable. +*/ +#if defined(MS_WIN32) && !defined(HAVE_SNPRINTF) +# define HAVE_SNPRINTF +# define snprintf _snprintf +# define vsnprintf _vsnprintf +#endif + +#include +PyAPI_FUNC(int) PyOS_snprintf(char *str, size_t size, const char *format, ...) + Py_GCC_ATTRIBUTE((format(printf, 3, 4))); +PyAPI_FUNC(int) PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va) + Py_GCC_ATTRIBUTE((format(printf, 3, 0))); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_ERRORS_H */ diff --git a/vscript/languages/python/python-2.5.1/include/pyexpat.h b/vscript/languages/python/python-2.5.1/include/pyexpat.h new file mode 100644 index 00000000..1e79f4e7 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/pyexpat.h @@ -0,0 +1,47 @@ +/* Stuff to export relevant 'expat' entry points from pyexpat to other + * parser modules, such as cElementTree. */ + +/* note: you must import expat.h before importing this module! */ + +#define PyExpat_CAPI_MAGIC "pyexpat.expat_CAPI 1.0" + +struct PyExpat_CAPI +{ + char* magic; /* set to PyExpat_CAPI_MAGIC */ + int size; /* set to sizeof(struct PyExpat_CAPI) */ + int MAJOR_VERSION; + int MINOR_VERSION; + int MICRO_VERSION; + /* pointers to selected expat functions. add new functions at + the end, if needed */ + const XML_LChar * (*ErrorString)(enum XML_Error code); + enum XML_Error (*GetErrorCode)(XML_Parser parser); + XML_Size (*GetErrorColumnNumber)(XML_Parser parser); + XML_Size (*GetErrorLineNumber)(XML_Parser parser); + enum XML_Status (*Parse)( + XML_Parser parser, const char *s, int len, int isFinal); + XML_Parser (*ParserCreate_MM)( + const XML_Char *encoding, const XML_Memory_Handling_Suite *memsuite, + const XML_Char *namespaceSeparator); + void (*ParserFree)(XML_Parser parser); + void (*SetCharacterDataHandler)( + XML_Parser parser, XML_CharacterDataHandler handler); + void (*SetCommentHandler)( + XML_Parser parser, XML_CommentHandler handler); + void (*SetDefaultHandlerExpand)( + XML_Parser parser, XML_DefaultHandler handler); + void (*SetElementHandler)( + XML_Parser parser, XML_StartElementHandler start, + XML_EndElementHandler end); + void (*SetNamespaceDeclHandler)( + XML_Parser parser, XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end); + void (*SetProcessingInstructionHandler)( + XML_Parser parser, XML_ProcessingInstructionHandler handler); + void (*SetUnknownEncodingHandler)( + XML_Parser parser, XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + void (*SetUserData)(XML_Parser parser, void *userData); + /* always add new stuff to the end! */ +}; + diff --git a/vscript/languages/python/python-2.5.1/include/pyfpe.h b/vscript/languages/python/python-2.5.1/include/pyfpe.h new file mode 100644 index 00000000..19110ab0 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/pyfpe.h @@ -0,0 +1,176 @@ +#ifndef Py_PYFPE_H +#define Py_PYFPE_H +#ifdef __cplusplus +extern "C" { +#endif +/* + --------------------------------------------------------------------- + / Copyright (c) 1996. \ + | The Regents of the University of California. | + | All rights reserved. | + | | + | Permission to use, copy, modify, and distribute this software for | + | any purpose without fee is hereby granted, provided that this en- | + | tire notice is included in all copies of any software which is or | + | includes a copy or modification of this software and in all | + | copies of the supporting documentation for such software. | + | | + | This work was produced at the University of California, Lawrence | + | Livermore National Laboratory under contract no. W-7405-ENG-48 | + | between the U.S. Department of Energy and The Regents of the | + | University of California for the operation of UC LLNL. | + | | + | DISCLAIMER | + | | + | This software was prepared as an account of work sponsored by an | + | agency of the United States Government. Neither the United States | + | Government nor the University of California nor any of their em- | + | ployees, makes any warranty, express or implied, or assumes any | + | liability or responsibility for the accuracy, completeness, or | + | usefulness of any information, apparatus, product, or process | + | disclosed, or represents that its use would not infringe | + | privately-owned rights. Reference herein to any specific commer- | + | cial products, process, or service by trade name, trademark, | + | manufacturer, or otherwise, does not necessarily constitute or | + | imply its endorsement, recommendation, or favoring by the United | + | States Government or the University of California. The views and | + | opinions of authors expressed herein do not necessarily state or | + | reflect those of the United States Government or the University | + | of California, and shall not be used for advertising or product | + \ endorsement purposes. / + --------------------------------------------------------------------- +*/ + +/* + * Define macros for handling SIGFPE. + * Lee Busby, LLNL, November, 1996 + * busby1@llnl.gov + * + ********************************************* + * Overview of the system for handling SIGFPE: + * + * This file (Include/pyfpe.h) defines a couple of "wrapper" macros for + * insertion into your Python C code of choice. Their proper use is + * discussed below. The file Python/pyfpe.c defines a pair of global + * variables PyFPE_jbuf and PyFPE_counter which are used by the signal + * handler for SIGFPE to decide if a particular exception was protected + * by the macros. The signal handler itself, and code for enabling the + * generation of SIGFPE in the first place, is in a (new) Python module + * named fpectl. This module is standard in every respect. It can be loaded + * either statically or dynamically as you choose, and like any other + * Python module, has no effect until you import it. + * + * In the general case, there are three steps toward handling SIGFPE in any + * Python code: + * + * 1) Add the *_PROTECT macros to your C code as required to protect + * dangerous floating point sections. + * + * 2) Turn on the inclusion of the code by adding the ``--with-fpectl'' + * flag at the time you run configure. If the fpectl or other modules + * which use the *_PROTECT macros are to be dynamically loaded, be + * sure they are compiled with WANT_SIGFPE_HANDLER defined. + * + * 3) When python is built and running, import fpectl, and execute + * fpectl.turnon_sigfpe(). This sets up the signal handler and enables + * generation of SIGFPE whenever an exception occurs. From this point + * on, any properly trapped SIGFPE should result in the Python + * FloatingPointError exception. + * + * Step 1 has been done already for the Python kernel code, and should be + * done soon for the NumPy array package. Step 2 is usually done once at + * python install time. Python's behavior with respect to SIGFPE is not + * changed unless you also do step 3. Thus you can control this new + * facility at compile time, or run time, or both. + * + ******************************** + * Using the macros in your code: + * + * static PyObject *foobar(PyObject *self,PyObject *args) + * { + * .... + * PyFPE_START_PROTECT("Error in foobar", return 0) + * result = dangerous_op(somearg1, somearg2, ...); + * PyFPE_END_PROTECT(result) + * .... + * } + * + * If a floating point error occurs in dangerous_op, foobar returns 0 (NULL), + * after setting the associated value of the FloatingPointError exception to + * "Error in foobar". ``Dangerous_op'' can be a single operation, or a block + * of code, function calls, or any combination, so long as no alternate + * return is possible before the PyFPE_END_PROTECT macro is reached. + * + * The macros can only be used in a function context where an error return + * can be recognized as signaling a Python exception. (Generally, most + * functions that return a PyObject * will qualify.) + * + * Guido's original design suggestion for PyFPE_START_PROTECT and + * PyFPE_END_PROTECT had them open and close a local block, with a locally + * defined jmp_buf and jmp_buf pointer. This would allow recursive nesting + * of the macros. The Ansi C standard makes it clear that such local + * variables need to be declared with the "volatile" type qualifier to keep + * setjmp from corrupting their values. Some current implementations seem + * to be more restrictive. For example, the HPUX man page for setjmp says + * + * Upon the return from a setjmp() call caused by a longjmp(), the + * values of any non-static local variables belonging to the routine + * from which setjmp() was called are undefined. Code which depends on + * such values is not guaranteed to be portable. + * + * I therefore decided on a more limited form of nesting, using a counter + * variable (PyFPE_counter) to keep track of any recursion. If an exception + * occurs in an ``inner'' pair of macros, the return will apparently + * come from the outermost level. + * + */ + +#ifdef WANT_SIGFPE_HANDLER +#include +#include +#include +extern jmp_buf PyFPE_jbuf; +extern int PyFPE_counter; +extern double PyFPE_dummy(void *); + +#define PyFPE_START_PROTECT(err_string, leave_stmt) \ +if (!PyFPE_counter++ && setjmp(PyFPE_jbuf)) { \ + PyErr_SetString(PyExc_FloatingPointError, err_string); \ + PyFPE_counter = 0; \ + leave_stmt; \ +} + +/* + * This (following) is a heck of a way to decrement a counter. However, + * unless the macro argument is provided, code optimizers will sometimes move + * this statement so that it gets executed *before* the unsafe expression + * which we're trying to protect. That pretty well messes things up, + * of course. + * + * If the expression(s) you're trying to protect don't happen to return a + * value, you will need to manufacture a dummy result just to preserve the + * correct ordering of statements. Note that the macro passes the address + * of its argument (so you need to give it something which is addressable). + * If your expression returns multiple results, pass the last such result + * to PyFPE_END_PROTECT. + * + * Note that PyFPE_dummy returns a double, which is cast to int. + * This seeming insanity is to tickle the Floating Point Unit (FPU). + * If an exception has occurred in a preceding floating point operation, + * some architectures (notably Intel 80x86) will not deliver the interrupt + * until the *next* floating point operation. This is painful if you've + * already decremented PyFPE_counter. + */ +#define PyFPE_END_PROTECT(v) PyFPE_counter -= (int)PyFPE_dummy(&(v)); + +#else + +#define PyFPE_START_PROTECT(err_string, leave_stmt) +#define PyFPE_END_PROTECT(v) + +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYFPE_H */ diff --git a/vscript/languages/python/python-2.5.1/include/pygetopt.h b/vscript/languages/python/python-2.5.1/include/pygetopt.h new file mode 100644 index 00000000..80908bea --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/pygetopt.h @@ -0,0 +1,17 @@ + +#ifndef Py_PYGETOPT_H +#define Py_PYGETOPT_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(int) _PyOS_opterr; +PyAPI_DATA(int) _PyOS_optind; +PyAPI_DATA(char *) _PyOS_optarg; + +PyAPI_FUNC(int) _PyOS_GetOpt(int argc, char **argv, char *optstring); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYGETOPT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/pymactoolbox.h b/vscript/languages/python/python-2.5.1/include/pymactoolbox.h new file mode 100644 index 00000000..92799e97 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/pymactoolbox.h @@ -0,0 +1,189 @@ +/* +** pymactoolbox.h - globals defined in mactoolboxglue.c +*/ +#ifndef Py_PYMACTOOLBOX_H +#define Py_PYMACTOOLBOX_H +#ifdef __cplusplus + extern "C" { +#endif + +#include +#include + +/* +** Helper routines for error codes and such. +*/ +char *PyMac_StrError(int); /* strerror with mac errors */ +extern PyObject *PyMac_OSErrException; /* Exception for OSErr */ +PyObject *PyMac_GetOSErrException(void); /* Initialize & return it */ +PyObject *PyErr_Mac(PyObject *, int); /* Exception with a mac error */ +PyObject *PyMac_Error(OSErr); /* Uses PyMac_GetOSErrException */ +extern OSErr PyMac_GetFullPathname(FSSpec *, char *, int); /* convert + fsspec->path */ +/* +** These conversion routines are defined in mactoolboxglue.c itself. +*/ +int PyMac_GetOSType(PyObject *, OSType *); /* argument parser for OSType */ +PyObject *PyMac_BuildOSType(OSType); /* Convert OSType to PyObject */ + +PyObject *PyMac_BuildNumVersion(NumVersion);/* Convert NumVersion to PyObject */ + +int PyMac_GetStr255(PyObject *, Str255); /* argument parser for Str255 */ +PyObject *PyMac_BuildStr255(Str255); /* Convert Str255 to PyObject */ +PyObject *PyMac_BuildOptStr255(Str255); /* Convert Str255 to PyObject, + NULL to None */ + +int PyMac_GetRect(PyObject *, Rect *); /* argument parser for Rect */ +PyObject *PyMac_BuildRect(Rect *); /* Convert Rect to PyObject */ + +int PyMac_GetPoint(PyObject *, Point *); /* argument parser for Point */ +PyObject *PyMac_BuildPoint(Point); /* Convert Point to PyObject */ + +int PyMac_GetEventRecord(PyObject *, EventRecord *); /* argument parser for + EventRecord */ +PyObject *PyMac_BuildEventRecord(EventRecord *); /* Convert EventRecord to + PyObject */ + +int PyMac_GetFixed(PyObject *, Fixed *); /* argument parser for Fixed */ +PyObject *PyMac_BuildFixed(Fixed); /* Convert Fixed to PyObject */ +int PyMac_Getwide(PyObject *, wide *); /* argument parser for wide */ +PyObject *PyMac_Buildwide(wide *); /* Convert wide to PyObject */ + +/* +** The rest of the routines are implemented by extension modules. If they are +** dynamically loaded mactoolboxglue will contain a stub implementation of the +** routine, which imports the module, whereupon the module's init routine will +** communicate the routine pointer back to the stub. +** If USE_TOOLBOX_OBJECT_GLUE is not defined there is no glue code, and the +** extension modules simply declare the routine. This is the case for static +** builds (and could be the case for MacPython CFM builds, because CFM extension +** modules can reference each other without problems). +*/ + +#ifdef USE_TOOLBOX_OBJECT_GLUE +/* +** These macros are used in the module init code. If we use toolbox object glue +** it sets the function pointer to point to the real function. +*/ +#define PyMac_INIT_TOOLBOX_OBJECT_NEW(object, rtn) { \ + extern PyObject *(*PyMacGluePtr_##rtn)(object); \ + PyMacGluePtr_##rtn = _##rtn; \ +} +#define PyMac_INIT_TOOLBOX_OBJECT_CONVERT(object, rtn) { \ + extern int (*PyMacGluePtr_##rtn)(PyObject *, object *); \ + PyMacGluePtr_##rtn = _##rtn; \ +} +#else +/* +** If we don't use toolbox object glue the init macros are empty. Moreover, we define +** _xxx_New to be the same as xxx_New, and the code in mactoolboxglue isn't included. +*/ +#define PyMac_INIT_TOOLBOX_OBJECT_NEW(object, rtn) +#define PyMac_INIT_TOOLBOX_OBJECT_CONVERT(object, rtn) +#endif /* USE_TOOLBOX_OBJECT_GLUE */ + +/* macfs exports */ +int PyMac_GetFSSpec(PyObject *, FSSpec *); /* argument parser for FSSpec */ +PyObject *PyMac_BuildFSSpec(FSSpec *); /* Convert FSSpec to PyObject */ + +int PyMac_GetFSRef(PyObject *, FSRef *); /* argument parser for FSRef */ +PyObject *PyMac_BuildFSRef(FSRef *); /* Convert FSRef to PyObject */ + +/* AE exports */ +extern PyObject *AEDesc_New(AppleEvent *); /* XXXX Why passed by address?? */ +extern PyObject *AEDesc_NewBorrowed(AppleEvent *); +extern int AEDesc_Convert(PyObject *, AppleEvent *); + +/* Cm exports */ +extern PyObject *CmpObj_New(Component); +extern int CmpObj_Convert(PyObject *, Component *); +extern PyObject *CmpInstObj_New(ComponentInstance); +extern int CmpInstObj_Convert(PyObject *, ComponentInstance *); + +/* Ctl exports */ +extern PyObject *CtlObj_New(ControlHandle); +extern int CtlObj_Convert(PyObject *, ControlHandle *); + +/* Dlg exports */ +extern PyObject *DlgObj_New(DialogPtr); +extern int DlgObj_Convert(PyObject *, DialogPtr *); +extern PyObject *DlgObj_WhichDialog(DialogPtr); + +/* Drag exports */ +extern PyObject *DragObj_New(DragReference); +extern int DragObj_Convert(PyObject *, DragReference *); + +/* List exports */ +extern PyObject *ListObj_New(ListHandle); +extern int ListObj_Convert(PyObject *, ListHandle *); + +/* Menu exports */ +extern PyObject *MenuObj_New(MenuHandle); +extern int MenuObj_Convert(PyObject *, MenuHandle *); + +/* Qd exports */ +extern PyObject *GrafObj_New(GrafPtr); +extern int GrafObj_Convert(PyObject *, GrafPtr *); +extern PyObject *BMObj_New(BitMapPtr); +extern int BMObj_Convert(PyObject *, BitMapPtr *); +extern PyObject *QdRGB_New(RGBColor *); +extern int QdRGB_Convert(PyObject *, RGBColor *); + +/* Qdoffs exports */ +extern PyObject *GWorldObj_New(GWorldPtr); +extern int GWorldObj_Convert(PyObject *, GWorldPtr *); + +/* Qt exports */ +extern PyObject *TrackObj_New(Track); +extern int TrackObj_Convert(PyObject *, Track *); +extern PyObject *MovieObj_New(Movie); +extern int MovieObj_Convert(PyObject *, Movie *); +extern PyObject *MovieCtlObj_New(MovieController); +extern int MovieCtlObj_Convert(PyObject *, MovieController *); +extern PyObject *TimeBaseObj_New(TimeBase); +extern int TimeBaseObj_Convert(PyObject *, TimeBase *); +extern PyObject *UserDataObj_New(UserData); +extern int UserDataObj_Convert(PyObject *, UserData *); +extern PyObject *MediaObj_New(Media); +extern int MediaObj_Convert(PyObject *, Media *); + +/* Res exports */ +extern PyObject *ResObj_New(Handle); +extern int ResObj_Convert(PyObject *, Handle *); +extern PyObject *OptResObj_New(Handle); +extern int OptResObj_Convert(PyObject *, Handle *); + +/* TE exports */ +extern PyObject *TEObj_New(TEHandle); +extern int TEObj_Convert(PyObject *, TEHandle *); + +/* Win exports */ +extern PyObject *WinObj_New(WindowPtr); +extern int WinObj_Convert(PyObject *, WindowPtr *); +extern PyObject *WinObj_WhichWindow(WindowPtr); + +/* CF exports */ +extern PyObject *CFObj_New(CFTypeRef); +extern int CFObj_Convert(PyObject *, CFTypeRef *); +extern PyObject *CFTypeRefObj_New(CFTypeRef); +extern int CFTypeRefObj_Convert(PyObject *, CFTypeRef *); +extern PyObject *CFStringRefObj_New(CFStringRef); +extern int CFStringRefObj_Convert(PyObject *, CFStringRef *); +extern PyObject *CFMutableStringRefObj_New(CFMutableStringRef); +extern int CFMutableStringRefObj_Convert(PyObject *, CFMutableStringRef *); +extern PyObject *CFArrayRefObj_New(CFArrayRef); +extern int CFArrayRefObj_Convert(PyObject *, CFArrayRef *); +extern PyObject *CFMutableArrayRefObj_New(CFMutableArrayRef); +extern int CFMutableArrayRefObj_Convert(PyObject *, CFMutableArrayRef *); +extern PyObject *CFDictionaryRefObj_New(CFDictionaryRef); +extern int CFDictionaryRefObj_Convert(PyObject *, CFDictionaryRef *); +extern PyObject *CFMutableDictionaryRefObj_New(CFMutableDictionaryRef); +extern int CFMutableDictionaryRefObj_Convert(PyObject *, CFMutableDictionaryRef *); +extern PyObject *CFURLRefObj_New(CFURLRef); +extern int CFURLRefObj_Convert(PyObject *, CFURLRef *); +extern int OptionalCFURLRefObj_Convert(PyObject *, CFURLRef *); + +#ifdef __cplusplus + } +#endif +#endif diff --git a/vscript/languages/python/python-2.5.1/include/pymem.h b/vscript/languages/python/python-2.5.1/include/pymem.h new file mode 100644 index 00000000..671f967c --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/pymem.h @@ -0,0 +1,105 @@ +/* The PyMem_ family: low-level memory allocation interfaces. + See objimpl.h for the PyObject_ memory family. +*/ + +#ifndef Py_PYMEM_H +#define Py_PYMEM_H + +#include "pyport.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEWARE: + + Each interface exports both functions and macros. Extension modules should + use the functions, to ensure binary compatibility across Python versions. + Because the Python implementation is free to change internal details, and + the macros may (or may not) expose details for speed, if you do use the + macros you must recompile your extensions with each Python release. + + Never mix calls to PyMem_ with calls to the platform malloc/realloc/ + calloc/free. For example, on Windows different DLLs may end up using + different heaps, and if you use PyMem_Malloc you'll get the memory from the + heap used by the Python DLL; it could be a disaster if you free()'ed that + directly in your own extension. Using PyMem_Free instead ensures Python + can return the memory to the proper heap. As another example, in + PYMALLOC_DEBUG mode, Python wraps all calls to all PyMem_ and PyObject_ + memory functions in special debugging wrappers that add additional + debugging info to dynamic memory blocks. The system routines have no idea + what to do with that stuff, and the Python wrappers have no idea what to do + with raw blocks obtained directly by the system routines then. +*/ + +/* + * Raw memory interface + * ==================== + */ + +/* Functions + + Functions supplying platform-independent semantics for malloc/realloc/ + free. These functions make sure that allocating 0 bytes returns a distinct + non-NULL pointer (whenever possible -- if we're flat out of memory, NULL + may be returned), even if the platform malloc and realloc don't. + Returned pointers must be checked for NULL explicitly. No action is + performed on failure (no exception is set, no warning is printed, etc). +*/ + +PyAPI_FUNC(void *) PyMem_Malloc(size_t); +PyAPI_FUNC(void *) PyMem_Realloc(void *, size_t); +PyAPI_FUNC(void) PyMem_Free(void *); + +/* Starting from Python 1.6, the wrappers Py_{Malloc,Realloc,Free} are + no longer supported. They used to call PyErr_NoMemory() on failure. */ + +/* Macros. */ +#ifdef PYMALLOC_DEBUG +/* Redirect all memory operations to Python's debugging allocator. */ +#define PyMem_MALLOC PyObject_MALLOC +#define PyMem_REALLOC PyObject_REALLOC +#define PyMem_FREE PyObject_FREE + +#else /* ! PYMALLOC_DEBUG */ + +/* PyMem_MALLOC(0) means malloc(1). Some systems would return NULL + for malloc(0), which would be treated as an error. Some platforms + would return a pointer with no memory behind it, which would break + pymalloc. To solve these problems, allocate an extra byte. */ +#define PyMem_MALLOC(n) malloc((n) ? (n) : 1) +#define PyMem_REALLOC(p, n) realloc((p), (n) ? (n) : 1) +#define PyMem_FREE free + +#endif /* PYMALLOC_DEBUG */ + +/* + * Type-oriented memory interface + * ============================== + * + * These are carried along for historical reasons. There's rarely a good + * reason to use them anymore (you can just as easily do the multiply and + * cast yourself). + */ + +#define PyMem_New(type, n) \ + ( (type *) PyMem_Malloc((n) * sizeof(type)) ) +#define PyMem_NEW(type, n) \ + ( (type *) PyMem_MALLOC((n) * sizeof(type)) ) + +#define PyMem_Resize(p, type, n) \ + ( (p) = (type *) PyMem_Realloc((p), (n) * sizeof(type)) ) +#define PyMem_RESIZE(p, type, n) \ + ( (p) = (type *) PyMem_REALLOC((p), (n) * sizeof(type)) ) + +/* PyMem{Del,DEL} are left over from ancient days, and shouldn't be used + * anymore. They're just confusing aliases for PyMem_{Free,FREE} now. + */ +#define PyMem_Del PyMem_Free +#define PyMem_DEL PyMem_FREE + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_PYMEM_H */ diff --git a/vscript/languages/python/python-2.5.1/include/pyport.h b/vscript/languages/python/python-2.5.1/include/pyport.h new file mode 100644 index 00000000..6fe3f0b5 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/pyport.h @@ -0,0 +1,771 @@ +#ifndef Py_PYPORT_H +#define Py_PYPORT_H + +#include "pyconfig.h" /* include for defines */ + +#ifdef HAVE_STDINT_H +#include +#endif + +/************************************************************************** +Symbols and macros to supply platform-independent interfaces to basic +C language & library operations whose spellings vary across platforms. + +Please try to make documentation here as clear as possible: by definition, +the stuff here is trying to illuminate C's darkest corners. + +Config #defines referenced here: + +SIGNED_RIGHT_SHIFT_ZERO_FILLS +Meaning: To be defined iff i>>j does not extend the sign bit when i is a + signed integral type and i < 0. +Used in: Py_ARITHMETIC_RIGHT_SHIFT + +Py_DEBUG +Meaning: Extra checks compiled in for debug mode. +Used in: Py_SAFE_DOWNCAST + +HAVE_UINTPTR_T +Meaning: The C9X type uintptr_t is supported by the compiler +Used in: Py_uintptr_t + +HAVE_LONG_LONG +Meaning: The compiler supports the C type "long long" +Used in: PY_LONG_LONG + +**************************************************************************/ + + +/* For backward compatibility only. Obsolete, do not use. */ +#ifdef HAVE_PROTOTYPES +#define Py_PROTO(x) x +#else +#define Py_PROTO(x) () +#endif +#ifndef Py_FPROTO +#define Py_FPROTO(x) Py_PROTO(x) +#endif + +/* typedefs for some C9X-defined synonyms for integral types. + * + * The names in Python are exactly the same as the C9X names, except with a + * Py_ prefix. Until C9X is universally implemented, this is the only way + * to ensure that Python gets reliable names that don't conflict with names + * in non-Python code that are playing their own tricks to define the C9X + * names. + * + * NOTE: don't go nuts here! Python has no use for *most* of the C9X + * integral synonyms. Only define the ones we actually need. + */ + +#ifdef HAVE_LONG_LONG +#ifndef PY_LONG_LONG +#define PY_LONG_LONG long long +#endif +#endif /* HAVE_LONG_LONG */ + +/* uintptr_t is the C9X name for an unsigned integral type such that a + * legitimate void* can be cast to uintptr_t and then back to void* again + * without loss of information. Similarly for intptr_t, wrt a signed + * integral type. + */ +#ifdef HAVE_UINTPTR_T +typedef uintptr_t Py_uintptr_t; +typedef intptr_t Py_intptr_t; + +#elif SIZEOF_VOID_P <= SIZEOF_INT +typedef unsigned int Py_uintptr_t; +typedef int Py_intptr_t; + +#elif SIZEOF_VOID_P <= SIZEOF_LONG +typedef unsigned long Py_uintptr_t; +typedef long Py_intptr_t; + +#elif defined(HAVE_LONG_LONG) && (SIZEOF_VOID_P <= SIZEOF_LONG_LONG) +typedef unsigned PY_LONG_LONG Py_uintptr_t; +typedef PY_LONG_LONG Py_intptr_t; + +#else +# error "Python needs a typedef for Py_uintptr_t in pyport.h." +#endif /* HAVE_UINTPTR_T */ + +/* Py_ssize_t is a signed integral type such that sizeof(Py_ssize_t) == + * sizeof(size_t). C99 doesn't define such a thing directly (size_t is an + * unsigned integral type). See PEP 353 for details. + */ +#ifdef HAVE_SSIZE_T +typedef ssize_t Py_ssize_t; +#elif SIZEOF_VOID_P == SIZEOF_SIZE_T +typedef Py_intptr_t Py_ssize_t; +#else +# error "Python needs a typedef for Py_ssize_t in pyport.h." +#endif + +/* Largest positive value of type Py_ssize_t. */ +#define PY_SSIZE_T_MAX ((Py_ssize_t)(((size_t)-1)>>1)) +/* Smallest negative value of type Py_ssize_t. */ +#define PY_SSIZE_T_MIN (-PY_SSIZE_T_MAX-1) + +/* PY_FORMAT_SIZE_T is a platform-specific modifier for use in a printf + * format to convert an argument with the width of a size_t or Py_ssize_t. + * C99 introduced "z" for this purpose, but not all platforms support that; + * e.g., MS compilers use "I" instead. + * + * These "high level" Python format functions interpret "z" correctly on + * all platforms (Python interprets the format string itself, and does whatever + * the platform C requires to convert a size_t/Py_ssize_t argument): + * + * PyString_FromFormat + * PyErr_Format + * PyString_FromFormatV + * + * Lower-level uses require that you interpolate the correct format modifier + * yourself (e.g., calling printf, fprintf, sprintf, PyOS_snprintf); for + * example, + * + * Py_ssize_t index; + * fprintf(stderr, "index %" PY_FORMAT_SIZE_T "d sucks\n", index); + * + * That will expand to %ld, or %Id, or to something else correct for a + * Py_ssize_t on the platform. + */ +#ifndef PY_FORMAT_SIZE_T +# if SIZEOF_SIZE_T == SIZEOF_INT && !defined(__APPLE__) +# define PY_FORMAT_SIZE_T "" +# elif SIZEOF_SIZE_T == SIZEOF_LONG +# define PY_FORMAT_SIZE_T "l" +# elif defined(MS_WINDOWS) +# define PY_FORMAT_SIZE_T "I" +# else +# error "This platform's pyconfig.h needs to define PY_FORMAT_SIZE_T" +# endif +#endif + +/* Py_LOCAL can be used instead of static to get the fastest possible calling + * convention for functions that are local to a given module. + * + * Py_LOCAL_INLINE does the same thing, and also explicitly requests inlining, + * for platforms that support that. + * + * If PY_LOCAL_AGGRESSIVE is defined before python.h is included, more + * "aggressive" inlining/optimizaion is enabled for the entire module. This + * may lead to code bloat, and may slow things down for those reasons. It may + * also lead to errors, if the code relies on pointer aliasing. Use with + * care. + * + * NOTE: You can only use this for functions that are entirely local to a + * module; functions that are exported via method tables, callbacks, etc, + * should keep using static. + */ + +#undef USE_INLINE /* XXX - set via configure? */ + +#if defined(_MSC_VER) +#if defined(PY_LOCAL_AGGRESSIVE) +/* enable more aggressive optimization for visual studio */ +#pragma optimize("agtw", on) +#endif +/* ignore warnings if the compiler decides not to inline a function */ +#pragma warning(disable: 4710) +/* fastest possible local call under MSVC */ +#define Py_LOCAL(type) static type __fastcall +#define Py_LOCAL_INLINE(type) static __inline type __fastcall +#elif defined(USE_INLINE) +#define Py_LOCAL(type) static type +#define Py_LOCAL_INLINE(type) static inline type +#else +#define Py_LOCAL(type) static type +#define Py_LOCAL_INLINE(type) static type +#endif + +/* Py_MEMCPY can be used instead of memcpy in cases where the copied blocks + * are often very short. While most platforms have highly optimized code for + * large transfers, the setup costs for memcpy are often quite high. MEMCPY + * solves this by doing short copies "in line". + */ + +#if defined(_MSC_VER) +#define Py_MEMCPY(target, source, length) do { \ + size_t i_, n_ = (length); \ + char *t_ = (void*) (target); \ + const char *s_ = (void*) (source); \ + if (n_ >= 16) \ + memcpy(t_, s_, n_); \ + else \ + for (i_ = 0; i_ < n_; i_++) \ + t_[i_] = s_[i_]; \ + } while (0) +#else +#define Py_MEMCPY memcpy +#endif + +#include + +#include /* Moved here from the math section, before extern "C" */ + +/******************************************** + * WRAPPER FOR and/or * + ********************************************/ + +#ifdef TIME_WITH_SYS_TIME +#include +#include +#else /* !TIME_WITH_SYS_TIME */ +#ifdef HAVE_SYS_TIME_H +#include +#else /* !HAVE_SYS_TIME_H */ +#include +#endif /* !HAVE_SYS_TIME_H */ +#endif /* !TIME_WITH_SYS_TIME */ + + +/****************************** + * WRAPPER FOR * + ******************************/ + +/* NB caller must include */ + +#ifdef HAVE_SYS_SELECT_H + +#include + +#endif /* !HAVE_SYS_SELECT_H */ + +/******************************* + * stat() and fstat() fiddling * + *******************************/ + +/* We expect that stat and fstat exist on most systems. + * It's confirmed on Unix, Mac and Windows. + * If you don't have them, add + * #define DONT_HAVE_STAT + * and/or + * #define DONT_HAVE_FSTAT + * to your pyconfig.h. Python code beyond this should check HAVE_STAT and + * HAVE_FSTAT instead. + * Also + * #define HAVE_SYS_STAT_H + * if exists on your platform, and + * #define HAVE_STAT_H + * if does. + */ +#ifndef DONT_HAVE_STAT +#define HAVE_STAT +#endif + +#ifndef DONT_HAVE_FSTAT +#define HAVE_FSTAT +#endif + +#ifdef RISCOS +#include +#include "unixstuff.h" +#endif + +#ifdef HAVE_SYS_STAT_H +#if defined(PYOS_OS2) && defined(PYCC_GCC) +#include +#endif +#include +#elif defined(HAVE_STAT_H) +#include +#endif + +#if defined(PYCC_VACPP) +/* VisualAge C/C++ Failed to Define MountType Field in sys/stat.h */ +#define S_IFMT (S_IFDIR|S_IFCHR|S_IFREG) +#endif + +#ifndef S_ISREG +#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG) +#endif + +#ifndef S_ISDIR +#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR) +#endif + + +#ifdef __cplusplus +/* Move this down here since some C++ #include's don't like to be included + inside an extern "C" */ +extern "C" { +#endif + + +/* Py_ARITHMETIC_RIGHT_SHIFT + * C doesn't define whether a right-shift of a signed integer sign-extends + * or zero-fills. Here a macro to force sign extension: + * Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) + * Return I >> J, forcing sign extension. + * Requirements: + * I is of basic signed type TYPE (char, short, int, long, or long long). + * TYPE is one of char, short, int, long, or long long, although long long + * must not be used except on platforms that support it. + * J is an integer >= 0 and strictly less than the number of bits in TYPE + * (because C doesn't define what happens for J outside that range either). + * Caution: + * I may be evaluated more than once. + */ +#ifdef SIGNED_RIGHT_SHIFT_ZERO_FILLS +#define Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) \ + ((I) < 0 ? ~((~(unsigned TYPE)(I)) >> (J)) : (I) >> (J)) +#else +#define Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) ((I) >> (J)) +#endif + +/* Py_FORCE_EXPANSION(X) + * "Simply" returns its argument. However, macro expansions within the + * argument are evaluated. This unfortunate trickery is needed to get + * token-pasting to work as desired in some cases. + */ +#define Py_FORCE_EXPANSION(X) X + +/* Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) + * Cast VALUE to type NARROW from type WIDE. In Py_DEBUG mode, this + * assert-fails if any information is lost. + * Caution: + * VALUE may be evaluated more than once. + */ +#ifdef Py_DEBUG +#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) \ + (assert((WIDE)(NARROW)(VALUE) == (VALUE)), (NARROW)(VALUE)) +#else +#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) (NARROW)(VALUE) +#endif + +/* Py_IS_NAN(X) + * Return 1 if float or double arg is a NaN, else 0. + * Caution: + * X is evaluated more than once. + * This may not work on all platforms. Each platform has *some* + * way to spell this, though -- override in pyconfig.h if you have + * a platform where it doesn't work. + */ +#ifndef Py_IS_NAN +#define Py_IS_NAN(X) ((X) != (X)) +#endif + +/* Py_IS_INFINITY(X) + * Return 1 if float or double arg is an infinity, else 0. + * Caution: + * X is evaluated more than once. + * This implementation may set the underflow flag if |X| is very small; + * it really can't be implemented correctly (& easily) before C99. + * Override in pyconfig.h if you have a better spelling on your platform. + */ +#ifndef Py_IS_INFINITY +#define Py_IS_INFINITY(X) ((X) && (X)*0.5 == (X)) +#endif + +/* Py_IS_FINITE(X) + * Return 1 if float or double arg is neither infinite nor NAN, else 0. + * Some compilers (e.g. VisualStudio) have intrisics for this, so a special + * macro for this particular test is useful + */ +#ifndef Py_IS_FINITE +#define Py_IS_FINITE(X) (!Py_IS_INFINITY(X) && !Py_IS_NAN(X)) +#endif + +/* HUGE_VAL is supposed to expand to a positive double infinity. Python + * uses Py_HUGE_VAL instead because some platforms are broken in this + * respect. We used to embed code in pyport.h to try to worm around that, + * but different platforms are broken in conflicting ways. If you're on + * a platform where HUGE_VAL is defined incorrectly, fiddle your Python + * config to #define Py_HUGE_VAL to something that works on your platform. + */ +#ifndef Py_HUGE_VAL +#define Py_HUGE_VAL HUGE_VAL +#endif + +/* Py_OVERFLOWED(X) + * Return 1 iff a libm function overflowed. Set errno to 0 before calling + * a libm function, and invoke this macro after, passing the function + * result. + * Caution: + * This isn't reliable. C99 no longer requires libm to set errno under + * any exceptional condition, but does require +- HUGE_VAL return + * values on overflow. A 754 box *probably* maps HUGE_VAL to a + * double infinity, and we're cool if that's so, unless the input + * was an infinity and an infinity is the expected result. A C89 + * system sets errno to ERANGE, so we check for that too. We're + * out of luck if a C99 754 box doesn't map HUGE_VAL to +Inf, or + * if the returned result is a NaN, or if a C89 box returns HUGE_VAL + * in non-overflow cases. + * X is evaluated more than once. + * Some platforms have better way to spell this, so expect some #ifdef'ery. + * + * OpenBSD uses 'isinf()' because a compiler bug on that platform causes + * the longer macro version to be mis-compiled. This isn't optimal, and + * should be removed once a newer compiler is available on that platform. + * The system that had the failure was running OpenBSD 3.2 on Intel, with + * gcc 2.95.3. + * + * According to Tim's checkin, the FreeBSD systems use isinf() to work + * around a FPE bug on that platform. + */ +#if defined(__FreeBSD__) || defined(__OpenBSD__) +#define Py_OVERFLOWED(X) isinf(X) +#else +#define Py_OVERFLOWED(X) ((X) != 0.0 && (errno == ERANGE || \ + (X) == Py_HUGE_VAL || \ + (X) == -Py_HUGE_VAL)) +#endif + +/* Py_SET_ERRNO_ON_MATH_ERROR(x) + * If a libm function did not set errno, but it looks like the result + * overflowed or not-a-number, set errno to ERANGE or EDOM. Set errno + * to 0 before calling a libm function, and invoke this macro after, + * passing the function result. + * Caution: + * This isn't reliable. See Py_OVERFLOWED comments. + * X is evaluated more than once. + */ +#if defined(__FreeBSD__) || defined(__OpenBSD__) || (defined(__hpux) && defined(__ia64)) +#define _Py_SET_EDOM_FOR_NAN(X) if (isnan(X)) errno = EDOM; +#else +#define _Py_SET_EDOM_FOR_NAN(X) ; +#endif +#define Py_SET_ERRNO_ON_MATH_ERROR(X) \ + do { \ + if (errno == 0) { \ + if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL) \ + errno = ERANGE; \ + else _Py_SET_EDOM_FOR_NAN(X) \ + } \ + } while(0) + +/* Py_SET_ERANGE_ON_OVERFLOW(x) + * An alias of Py_SET_ERRNO_ON_MATH_ERROR for backward-compatibility. + */ +#define Py_SET_ERANGE_IF_OVERFLOW(X) Py_SET_ERRNO_ON_MATH_ERROR(X) + +/* Py_ADJUST_ERANGE1(x) + * Py_ADJUST_ERANGE2(x, y) + * Set errno to 0 before calling a libm function, and invoke one of these + * macros after, passing the function result(s) (Py_ADJUST_ERANGE2 is useful + * for functions returning complex results). This makes two kinds of + * adjustments to errno: (A) If it looks like the platform libm set + * errno=ERANGE due to underflow, clear errno. (B) If it looks like the + * platform libm overflowed but didn't set errno, force errno to ERANGE. In + * effect, we're trying to force a useful implementation of C89 errno + * behavior. + * Caution: + * This isn't reliable. See Py_OVERFLOWED comments. + * X and Y may be evaluated more than once. + */ +#define Py_ADJUST_ERANGE1(X) \ + do { \ + if (errno == 0) { \ + if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL) \ + errno = ERANGE; \ + } \ + else if (errno == ERANGE && (X) == 0.0) \ + errno = 0; \ + } while(0) + +#define Py_ADJUST_ERANGE2(X, Y) \ + do { \ + if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL || \ + (Y) == Py_HUGE_VAL || (Y) == -Py_HUGE_VAL) { \ + if (errno == 0) \ + errno = ERANGE; \ + } \ + else if (errno == ERANGE) \ + errno = 0; \ + } while(0) + +/* Py_DEPRECATED(version) + * Declare a variable, type, or function deprecated. + * Usage: + * extern int old_var Py_DEPRECATED(2.3); + * typedef int T1 Py_DEPRECATED(2.4); + * extern int x() Py_DEPRECATED(2.5); + */ +#if defined(__GNUC__) && ((__GNUC__ >= 4) || \ + (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) +#define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__)) +#else +#define Py_DEPRECATED(VERSION_UNUSED) +#endif + +/************************************************************************** +Prototypes that are missing from the standard include files on some systems +(and possibly only some versions of such systems.) + +Please be conservative with adding new ones, document them and enclose them +in platform-specific #ifdefs. +**************************************************************************/ + +#ifdef SOLARIS +/* Unchecked */ +extern int gethostname(char *, int); +#endif + +#ifdef __BEOS__ +/* Unchecked */ +/* It's in the libs, but not the headers... - [cjh] */ +int shutdown( int, int ); +#endif + +#ifdef HAVE__GETPTY +#include /* we need to import mode_t */ +extern char * _getpty(int *, int, mode_t, int); +#endif + +#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) +#if !defined(HAVE_PTY_H) && !defined(HAVE_LIBUTIL_H) +/* BSDI does not supply a prototype for the 'openpty' and 'forkpty' + functions, even though they are included in libutil. */ +#include +extern int openpty(int *, int *, char *, struct termios *, struct winsize *); +extern int forkpty(int *, char *, struct termios *, struct winsize *); +#endif /* !defined(HAVE_PTY_H) && !defined(HAVE_LIBUTIL_H) */ +#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */ + + +/* These are pulled from various places. It isn't obvious on what platforms + they are necessary, nor what the exact prototype should look like (which + is likely to vary between platforms!) If you find you need one of these + declarations, please move them to a platform-specific block and include + proper prototypes. */ +#if 0 + +/* From Modules/resource.c */ +extern int getrusage(); +extern int getpagesize(); + +/* From Python/sysmodule.c and Modules/posixmodule.c */ +extern int fclose(FILE *); + +/* From Modules/posixmodule.c */ +extern int fdatasync(int); +#endif /* 0 */ + + +/************************ + * WRAPPER FOR * + ************************/ + +#ifndef HAVE_HYPOT +extern double hypot(double, double); +#endif + + +/* On 4.4BSD-descendants, ctype functions serves the whole range of + * wchar_t character set rather than single byte code points only. + * This characteristic can break some operations of string object + * including str.upper() and str.split() on UTF-8 locales. This + * workaround was provided by Tim Robbins of FreeBSD project. + */ + +#ifdef __FreeBSD__ +#include +#if __FreeBSD_version > 500039 +#include +#include +#undef isalnum +#define isalnum(c) iswalnum(btowc(c)) +#undef isalpha +#define isalpha(c) iswalpha(btowc(c)) +#undef islower +#define islower(c) iswlower(btowc(c)) +#undef isspace +#define isspace(c) iswspace(btowc(c)) +#undef isupper +#define isupper(c) iswupper(btowc(c)) +#undef tolower +#define tolower(c) towlower(btowc(c)) +#undef toupper +#define toupper(c) towupper(btowc(c)) +#endif +#endif + + +/* Declarations for symbol visibility. + + PyAPI_FUNC(type): Declares a public Python API function and return type + PyAPI_DATA(type): Declares public Python data and its type + PyMODINIT_FUNC: A Python module init function. If these functions are + inside the Python core, they are private to the core. + If in an extension module, it may be declared with + external linkage depending on the platform. + + As a number of platforms support/require "__declspec(dllimport/dllexport)", + we support a HAVE_DECLSPEC_DLL macro to save duplication. +*/ + +/* + All windows ports, except cygwin, are handled in PC/pyconfig.h. + + BeOS and cygwin are the only other autoconf platform requiring special + linkage handling and both of these use __declspec(). +*/ +#if defined(__CYGWIN__) || defined(__BEOS__) +# define HAVE_DECLSPEC_DLL +#endif + +/* only get special linkage if built as shared or platform is Cygwin */ +#if defined(Py_ENABLE_SHARED) || defined(__CYGWIN__) +# if defined(HAVE_DECLSPEC_DLL) +# ifdef Py_BUILD_CORE +# define PyAPI_FUNC(RTYPE) __declspec(dllexport) RTYPE +# define PyAPI_DATA(RTYPE) extern __declspec(dllexport) RTYPE + /* module init functions inside the core need no external linkage */ + /* except for Cygwin to handle embedding (FIXME: BeOS too?) */ +# if defined(__CYGWIN__) +# define PyMODINIT_FUNC __declspec(dllexport) void +# else /* __CYGWIN__ */ +# define PyMODINIT_FUNC void +# endif /* __CYGWIN__ */ +# else /* Py_BUILD_CORE */ + /* Building an extension module, or an embedded situation */ + /* public Python functions and data are imported */ + /* Under Cygwin, auto-import functions to prevent compilation */ + /* failures similar to http://python.org/doc/FAQ.html#3.24 */ +# if !defined(__CYGWIN__) +# define PyAPI_FUNC(RTYPE) __declspec(dllimport) RTYPE +# endif /* !__CYGWIN__ */ +# define PyAPI_DATA(RTYPE) extern __declspec(dllimport) RTYPE + /* module init functions outside the core must be exported */ +# if defined(__cplusplus) +# define PyMODINIT_FUNC extern "C" __declspec(dllexport) void +# else /* __cplusplus */ +# define PyMODINIT_FUNC __declspec(dllexport) void +# endif /* __cplusplus */ +# endif /* Py_BUILD_CORE */ +# endif /* HAVE_DECLSPEC */ +#endif /* Py_ENABLE_SHARED */ + +/* If no external linkage macros defined by now, create defaults */ +#ifndef PyAPI_FUNC +# define PyAPI_FUNC(RTYPE) RTYPE +#endif +#ifndef PyAPI_DATA +# define PyAPI_DATA(RTYPE) extern RTYPE +#endif +#ifndef PyMODINIT_FUNC +# if defined(__cplusplus) +# define PyMODINIT_FUNC extern "C" void +# else /* __cplusplus */ +# define PyMODINIT_FUNC void +# endif /* __cplusplus */ +#endif + +/* Deprecated DL_IMPORT and DL_EXPORT macros */ +#if defined(Py_ENABLE_SHARED) && defined (HAVE_DECLSPEC_DLL) +# if defined(Py_BUILD_CORE) +# define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE +# define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE +# else +# define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE +# define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE +# endif +#endif +#ifndef DL_EXPORT +# define DL_EXPORT(RTYPE) RTYPE +#endif +#ifndef DL_IMPORT +# define DL_IMPORT(RTYPE) RTYPE +#endif +/* End of deprecated DL_* macros */ + +/* If the fd manipulation macros aren't defined, + here is a set that should do the job */ + +#if 0 /* disabled and probably obsolete */ + +#ifndef FD_SETSIZE +#define FD_SETSIZE 256 +#endif + +#ifndef FD_SET + +typedef long fd_mask; + +#define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */ +#ifndef howmany +#define howmany(x, y) (((x)+((y)-1))/(y)) +#endif /* howmany */ + +typedef struct fd_set { + fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)]; +} fd_set; + +#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) +#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) +#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) +#define FD_ZERO(p) memset((char *)(p), '\0', sizeof(*(p))) + +#endif /* FD_SET */ + +#endif /* fd manipulation macros */ + + +/* limits.h constants that may be missing */ + +#ifndef INT_MAX +#define INT_MAX 2147483647 +#endif + +#ifndef LONG_MAX +#if SIZEOF_LONG == 4 +#define LONG_MAX 0X7FFFFFFFL +#elif SIZEOF_LONG == 8 +#define LONG_MAX 0X7FFFFFFFFFFFFFFFL +#else +#error "could not set LONG_MAX in pyport.h" +#endif +#endif + +#ifndef LONG_MIN +#define LONG_MIN (-LONG_MAX-1) +#endif + +#ifndef LONG_BIT +#define LONG_BIT (8 * SIZEOF_LONG) +#endif + +#if LONG_BIT != 8 * SIZEOF_LONG +/* 04-Oct-2000 LONG_BIT is apparently (mis)defined as 64 on some recent + * 32-bit platforms using gcc. We try to catch that here at compile-time + * rather than waiting for integer multiplication to trigger bogus + * overflows. + */ +#error "LONG_BIT definition appears wrong for platform (bad gcc/glibc config?)." +#endif + +#ifdef __cplusplus +} +#endif + +/* + * Hide GCC attributes from compilers that don't support them. + */ +#if (!defined(__GNUC__) || __GNUC__ < 2 || \ + (__GNUC__ == 2 && __GNUC_MINOR__ < 7) ) && \ + !defined(RISCOS) +#define Py_GCC_ATTRIBUTE(x) +#else +#define Py_GCC_ATTRIBUTE(x) __attribute__(x) +#endif + +/* Eliminate end-of-loop code not reached warnings from SunPro C + * when using do{...}while(0) macros + */ +#ifdef __SUNPRO_C +#pragma error_messages (off,E_END_OF_LOOP_CODE_NOT_REACHED) +#endif + +/* + * Older Microsoft compilers don't support the C99 long long literal suffixes, + * so these will be defined in PC/pyconfig.h for those compilers. + */ +#ifndef Py_LL +#define Py_LL(x) x##LL +#endif + +#ifndef Py_ULL +#define Py_ULL(x) Py_LL(x##U) +#endif + +#endif /* Py_PYPORT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/pystate.h b/vscript/languages/python/python-2.5.1/include/pystate.h new file mode 100644 index 00000000..4919d99b --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/pystate.h @@ -0,0 +1,195 @@ + +/* Thread and interpreter state structures and their interfaces */ + + +#ifndef Py_PYSTATE_H +#define Py_PYSTATE_H +#ifdef __cplusplus +extern "C" { +#endif + +/* State shared between threads */ + +struct _ts; /* Forward */ +struct _is; /* Forward */ + +typedef struct _is { + + struct _is *next; + struct _ts *tstate_head; + + PyObject *modules; + PyObject *sysdict; + PyObject *builtins; + PyObject *modules_reloading; + + PyObject *codec_search_path; + PyObject *codec_search_cache; + PyObject *codec_error_registry; + +#ifdef HAVE_DLOPEN + int dlopenflags; +#endif +#ifdef WITH_TSC + int tscdump; +#endif + +} PyInterpreterState; + + +/* State unique per thread */ + +struct _frame; /* Avoid including frameobject.h */ + +/* Py_tracefunc return -1 when raising an exception, or 0 for success. */ +typedef int (*Py_tracefunc)(PyObject *, struct _frame *, int, PyObject *); + +/* The following values are used for 'what' for tracefunc functions: */ +#define PyTrace_CALL 0 +#define PyTrace_EXCEPTION 1 +#define PyTrace_LINE 2 +#define PyTrace_RETURN 3 +#define PyTrace_C_CALL 4 +#define PyTrace_C_EXCEPTION 5 +#define PyTrace_C_RETURN 6 + +typedef struct _ts { + /* See Python/ceval.c for comments explaining most fields */ + + struct _ts *next; + PyInterpreterState *interp; + + struct _frame *frame; + int recursion_depth; + /* 'tracing' keeps track of the execution depth when tracing/profiling. + This is to prevent the actual trace/profile code from being recorded in + the trace/profile. */ + int tracing; + int use_tracing; + + Py_tracefunc c_profilefunc; + Py_tracefunc c_tracefunc; + PyObject *c_profileobj; + PyObject *c_traceobj; + + PyObject *curexc_type; + PyObject *curexc_value; + PyObject *curexc_traceback; + + PyObject *exc_type; + PyObject *exc_value; + PyObject *exc_traceback; + + PyObject *dict; /* Stores per-thread state */ + + /* tick_counter is incremented whenever the check_interval ticker + * reaches zero. The purpose is to give a useful measure of the number + * of interpreted bytecode instructions in a given thread. This + * extremely lightweight statistic collector may be of interest to + * profilers (like psyco.jit()), although nothing in the core uses it. + */ + int tick_counter; + + int gilstate_counter; + + PyObject *async_exc; /* Asynchronous exception to raise */ + long thread_id; /* Thread id where this tstate was created */ + + /* XXX signal handlers should also be here */ + +} PyThreadState; + + +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_New(void); +PyAPI_FUNC(void) PyInterpreterState_Clear(PyInterpreterState *); +PyAPI_FUNC(void) PyInterpreterState_Delete(PyInterpreterState *); + +PyAPI_FUNC(PyThreadState *) PyThreadState_New(PyInterpreterState *); +PyAPI_FUNC(void) PyThreadState_Clear(PyThreadState *); +PyAPI_FUNC(void) PyThreadState_Delete(PyThreadState *); +#ifdef WITH_THREAD +PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void); +#endif + +PyAPI_FUNC(PyThreadState *) PyThreadState_Get(void); +PyAPI_FUNC(PyThreadState *) PyThreadState_Swap(PyThreadState *); +PyAPI_FUNC(PyObject *) PyThreadState_GetDict(void); +PyAPI_FUNC(int) PyThreadState_SetAsyncExc(long, PyObject *); + + +/* Variable and macro for in-line access to current thread state */ + +PyAPI_DATA(PyThreadState *) _PyThreadState_Current; + +#ifdef Py_DEBUG +#define PyThreadState_GET() PyThreadState_Get() +#else +#define PyThreadState_GET() (_PyThreadState_Current) +#endif + +typedef + enum {PyGILState_LOCKED, PyGILState_UNLOCKED} + PyGILState_STATE; + +/* Ensure that the current thread is ready to call the Python + C API, regardless of the current state of Python, or of its + thread lock. This may be called as many times as desired + by a thread so long as each call is matched with a call to + PyGILState_Release(). In general, other thread-state APIs may + be used between _Ensure() and _Release() calls, so long as the + thread-state is restored to its previous state before the Release(). + For example, normal use of the Py_BEGIN_ALLOW_THREADS/ + Py_END_ALLOW_THREADS macros are acceptable. + + The return value is an opaque "handle" to the thread state when + PyGILState_Ensure() was called, and must be passed to + PyGILState_Release() to ensure Python is left in the same state. Even + though recursive calls are allowed, these handles can *not* be shared - + each unique call to PyGILState_Ensure must save the handle for its + call to PyGILState_Release. + + When the function returns, the current thread will hold the GIL. + + Failure is a fatal error. +*/ +PyAPI_FUNC(PyGILState_STATE) PyGILState_Ensure(void); + +/* Release any resources previously acquired. After this call, Python's + state will be the same as it was prior to the corresponding + PyGILState_Ensure() call (but generally this state will be unknown to + the caller, hence the use of the GILState API.) + + Every call to PyGILState_Ensure must be matched by a call to + PyGILState_Release on the same thread. +*/ +PyAPI_FUNC(void) PyGILState_Release(PyGILState_STATE); + +/* Helper/diagnostic function - get the current thread state for + this thread. May return NULL if no GILState API has been used + on the current thread. Note the main thread always has such a + thread-state, even if no auto-thread-state call has been made + on the main thread. +*/ +PyAPI_FUNC(PyThreadState *) PyGILState_GetThisThreadState(void); + +/* The implementation of sys._current_frames() Returns a dict mapping + thread id to that thread's current frame. +*/ +PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(void); + +/* Routines for advanced debuggers, requested by David Beazley. + Don't use unless you know what you are doing! */ +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Head(void); +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Next(PyInterpreterState *); +PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(PyInterpreterState *); +PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *); + +typedef struct _frame *(*PyThreadFrameGetter)(PyThreadState *self_); + +/* hook for PyEval_GetFrame(), requested for Psyco */ +PyAPI_DATA(PyThreadFrameGetter) _PyThreadState_GetFrame; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYSTATE_H */ diff --git a/vscript/languages/python/python-2.5.1/include/pystrtod.h b/vscript/languages/python/python-2.5.1/include/pystrtod.h new file mode 100644 index 00000000..c6921da1 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/pystrtod.h @@ -0,0 +1,18 @@ +#ifndef Py_STRTOD_H +#define Py_STRTOD_H + +#ifdef __cplusplus +extern "C" { +#endif + + +PyAPI_FUNC(double) PyOS_ascii_strtod(const char *str, char **ptr); +PyAPI_FUNC(double) PyOS_ascii_atof(const char *str); +PyAPI_FUNC(char *) PyOS_ascii_formatd(char *buffer, size_t buf_len, const char *format, double d); + + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_STRTOD_H */ diff --git a/vscript/languages/python/python-2.5.1/include/python-ast.h b/vscript/languages/python/python-2.5.1/include/python-ast.h new file mode 100644 index 00000000..5d4147bf --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/python-ast.h @@ -0,0 +1,501 @@ +/* File automatically generated by Parser/asdl_c.py */ + +#include "asdl.h" + +typedef struct _mod *mod_ty; + +typedef struct _stmt *stmt_ty; + +typedef struct _expr *expr_ty; + +typedef enum _expr_context { Load=1, Store=2, Del=3, AugLoad=4, AugStore=5, + Param=6 } expr_context_ty; + +typedef struct _slice *slice_ty; + +typedef enum _boolop { And=1, Or=2 } boolop_ty; + +typedef enum _operator { Add=1, Sub=2, Mult=3, Div=4, Mod=5, Pow=6, LShift=7, + RShift=8, BitOr=9, BitXor=10, BitAnd=11, FloorDiv=12 } + operator_ty; + +typedef enum _unaryop { Invert=1, Not=2, UAdd=3, USub=4 } unaryop_ty; + +typedef enum _cmpop { Eq=1, NotEq=2, Lt=3, LtE=4, Gt=5, GtE=6, Is=7, IsNot=8, + In=9, NotIn=10 } cmpop_ty; + +typedef struct _comprehension *comprehension_ty; + +typedef struct _excepthandler *excepthandler_ty; + +typedef struct _arguments *arguments_ty; + +typedef struct _keyword *keyword_ty; + +typedef struct _alias *alias_ty; + + +enum _mod_kind {Module_kind=1, Interactive_kind=2, Expression_kind=3, + Suite_kind=4}; +struct _mod { + enum _mod_kind kind; + union { + struct { + asdl_seq *body; + } Module; + + struct { + asdl_seq *body; + } Interactive; + + struct { + expr_ty body; + } Expression; + + struct { + asdl_seq *body; + } Suite; + + } v; +}; + +enum _stmt_kind {FunctionDef_kind=1, ClassDef_kind=2, Return_kind=3, + Delete_kind=4, Assign_kind=5, AugAssign_kind=6, Print_kind=7, + For_kind=8, While_kind=9, If_kind=10, With_kind=11, + Raise_kind=12, TryExcept_kind=13, TryFinally_kind=14, + Assert_kind=15, Import_kind=16, ImportFrom_kind=17, + Exec_kind=18, Global_kind=19, Expr_kind=20, Pass_kind=21, + Break_kind=22, Continue_kind=23}; +struct _stmt { + enum _stmt_kind kind; + union { + struct { + identifier name; + arguments_ty args; + asdl_seq *body; + asdl_seq *decorators; + } FunctionDef; + + struct { + identifier name; + asdl_seq *bases; + asdl_seq *body; + } ClassDef; + + struct { + expr_ty value; + } Return; + + struct { + asdl_seq *targets; + } Delete; + + struct { + asdl_seq *targets; + expr_ty value; + } Assign; + + struct { + expr_ty target; + operator_ty op; + expr_ty value; + } AugAssign; + + struct { + expr_ty dest; + asdl_seq *values; + bool nl; + } Print; + + struct { + expr_ty target; + expr_ty iter; + asdl_seq *body; + asdl_seq *orelse; + } For; + + struct { + expr_ty test; + asdl_seq *body; + asdl_seq *orelse; + } While; + + struct { + expr_ty test; + asdl_seq *body; + asdl_seq *orelse; + } If; + + struct { + expr_ty context_expr; + expr_ty optional_vars; + asdl_seq *body; + } With; + + struct { + expr_ty type; + expr_ty inst; + expr_ty tback; + } Raise; + + struct { + asdl_seq *body; + asdl_seq *handlers; + asdl_seq *orelse; + } TryExcept; + + struct { + asdl_seq *body; + asdl_seq *finalbody; + } TryFinally; + + struct { + expr_ty test; + expr_ty msg; + } Assert; + + struct { + asdl_seq *names; + } Import; + + struct { + identifier module; + asdl_seq *names; + int level; + } ImportFrom; + + struct { + expr_ty body; + expr_ty globals; + expr_ty locals; + } Exec; + + struct { + asdl_seq *names; + } Global; + + struct { + expr_ty value; + } Expr; + + } v; + int lineno; + int col_offset; +}; + +enum _expr_kind {BoolOp_kind=1, BinOp_kind=2, UnaryOp_kind=3, Lambda_kind=4, + IfExp_kind=5, Dict_kind=6, ListComp_kind=7, + GeneratorExp_kind=8, Yield_kind=9, Compare_kind=10, + Call_kind=11, Repr_kind=12, Num_kind=13, Str_kind=14, + Attribute_kind=15, Subscript_kind=16, Name_kind=17, + List_kind=18, Tuple_kind=19}; +struct _expr { + enum _expr_kind kind; + union { + struct { + boolop_ty op; + asdl_seq *values; + } BoolOp; + + struct { + expr_ty left; + operator_ty op; + expr_ty right; + } BinOp; + + struct { + unaryop_ty op; + expr_ty operand; + } UnaryOp; + + struct { + arguments_ty args; + expr_ty body; + } Lambda; + + struct { + expr_ty test; + expr_ty body; + expr_ty orelse; + } IfExp; + + struct { + asdl_seq *keys; + asdl_seq *values; + } Dict; + + struct { + expr_ty elt; + asdl_seq *generators; + } ListComp; + + struct { + expr_ty elt; + asdl_seq *generators; + } GeneratorExp; + + struct { + expr_ty value; + } Yield; + + struct { + expr_ty left; + asdl_int_seq *ops; + asdl_seq *comparators; + } Compare; + + struct { + expr_ty func; + asdl_seq *args; + asdl_seq *keywords; + expr_ty starargs; + expr_ty kwargs; + } Call; + + struct { + expr_ty value; + } Repr; + + struct { + object n; + } Num; + + struct { + string s; + } Str; + + struct { + expr_ty value; + identifier attr; + expr_context_ty ctx; + } Attribute; + + struct { + expr_ty value; + slice_ty slice; + expr_context_ty ctx; + } Subscript; + + struct { + identifier id; + expr_context_ty ctx; + } Name; + + struct { + asdl_seq *elts; + expr_context_ty ctx; + } List; + + struct { + asdl_seq *elts; + expr_context_ty ctx; + } Tuple; + + } v; + int lineno; + int col_offset; +}; + +enum _slice_kind {Ellipsis_kind=1, Slice_kind=2, ExtSlice_kind=3, Index_kind=4}; +struct _slice { + enum _slice_kind kind; + union { + struct { + expr_ty lower; + expr_ty upper; + expr_ty step; + } Slice; + + struct { + asdl_seq *dims; + } ExtSlice; + + struct { + expr_ty value; + } Index; + + } v; +}; + +struct _comprehension { + expr_ty target; + expr_ty iter; + asdl_seq *ifs; +}; + +struct _excepthandler { + expr_ty type; + expr_ty name; + asdl_seq *body; + int lineno; + int col_offset; +}; + +struct _arguments { + asdl_seq *args; + identifier vararg; + identifier kwarg; + asdl_seq *defaults; +}; + +struct _keyword { + identifier arg; + expr_ty value; +}; + +struct _alias { + identifier name; + identifier asname; +}; + + +#define Module(a0, a1) _Py_Module(a0, a1) +mod_ty _Py_Module(asdl_seq * body, PyArena *arena); +#define Interactive(a0, a1) _Py_Interactive(a0, a1) +mod_ty _Py_Interactive(asdl_seq * body, PyArena *arena); +#define Expression(a0, a1) _Py_Expression(a0, a1) +mod_ty _Py_Expression(expr_ty body, PyArena *arena); +#define Suite(a0, a1) _Py_Suite(a0, a1) +mod_ty _Py_Suite(asdl_seq * body, PyArena *arena); +#define FunctionDef(a0, a1, a2, a3, a4, a5, a6) _Py_FunctionDef(a0, a1, a2, a3, a4, a5, a6) +stmt_ty _Py_FunctionDef(identifier name, arguments_ty args, asdl_seq * body, + asdl_seq * decorators, int lineno, int col_offset, + PyArena *arena); +#define ClassDef(a0, a1, a2, a3, a4, a5) _Py_ClassDef(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_ClassDef(identifier name, asdl_seq * bases, asdl_seq * body, int + lineno, int col_offset, PyArena *arena); +#define Return(a0, a1, a2, a3) _Py_Return(a0, a1, a2, a3) +stmt_ty _Py_Return(expr_ty value, int lineno, int col_offset, PyArena *arena); +#define Delete(a0, a1, a2, a3) _Py_Delete(a0, a1, a2, a3) +stmt_ty _Py_Delete(asdl_seq * targets, int lineno, int col_offset, PyArena + *arena); +#define Assign(a0, a1, a2, a3, a4) _Py_Assign(a0, a1, a2, a3, a4) +stmt_ty _Py_Assign(asdl_seq * targets, expr_ty value, int lineno, int + col_offset, PyArena *arena); +#define AugAssign(a0, a1, a2, a3, a4, a5) _Py_AugAssign(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_AugAssign(expr_ty target, operator_ty op, expr_ty value, int + lineno, int col_offset, PyArena *arena); +#define Print(a0, a1, a2, a3, a4, a5) _Py_Print(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_Print(expr_ty dest, asdl_seq * values, bool nl, int lineno, int + col_offset, PyArena *arena); +#define For(a0, a1, a2, a3, a4, a5, a6) _Py_For(a0, a1, a2, a3, a4, a5, a6) +stmt_ty _Py_For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * + orelse, int lineno, int col_offset, PyArena *arena); +#define While(a0, a1, a2, a3, a4, a5) _Py_While(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, + int col_offset, PyArena *arena); +#define If(a0, a1, a2, a3, a4, a5) _Py_If(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, + int col_offset, PyArena *arena); +#define With(a0, a1, a2, a3, a4, a5) _Py_With(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_With(expr_ty context_expr, expr_ty optional_vars, asdl_seq * body, + int lineno, int col_offset, PyArena *arena); +#define Raise(a0, a1, a2, a3, a4, a5) _Py_Raise(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, int + col_offset, PyArena *arena); +#define TryExcept(a0, a1, a2, a3, a4, a5) _Py_TryExcept(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, + int lineno, int col_offset, PyArena *arena); +#define TryFinally(a0, a1, a2, a3, a4) _Py_TryFinally(a0, a1, a2, a3, a4) +stmt_ty _Py_TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno, int + col_offset, PyArena *arena); +#define Assert(a0, a1, a2, a3, a4) _Py_Assert(a0, a1, a2, a3, a4) +stmt_ty _Py_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, + PyArena *arena); +#define Import(a0, a1, a2, a3) _Py_Import(a0, a1, a2, a3) +stmt_ty _Py_Import(asdl_seq * names, int lineno, int col_offset, PyArena + *arena); +#define ImportFrom(a0, a1, a2, a3, a4, a5) _Py_ImportFrom(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_ImportFrom(identifier module, asdl_seq * names, int level, int + lineno, int col_offset, PyArena *arena); +#define Exec(a0, a1, a2, a3, a4, a5) _Py_Exec(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_Exec(expr_ty body, expr_ty globals, expr_ty locals, int lineno, int + col_offset, PyArena *arena); +#define Global(a0, a1, a2, a3) _Py_Global(a0, a1, a2, a3) +stmt_ty _Py_Global(asdl_seq * names, int lineno, int col_offset, PyArena + *arena); +#define Expr(a0, a1, a2, a3) _Py_Expr(a0, a1, a2, a3) +stmt_ty _Py_Expr(expr_ty value, int lineno, int col_offset, PyArena *arena); +#define Pass(a0, a1, a2) _Py_Pass(a0, a1, a2) +stmt_ty _Py_Pass(int lineno, int col_offset, PyArena *arena); +#define Break(a0, a1, a2) _Py_Break(a0, a1, a2) +stmt_ty _Py_Break(int lineno, int col_offset, PyArena *arena); +#define Continue(a0, a1, a2) _Py_Continue(a0, a1, a2) +stmt_ty _Py_Continue(int lineno, int col_offset, PyArena *arena); +#define BoolOp(a0, a1, a2, a3, a4) _Py_BoolOp(a0, a1, a2, a3, a4) +expr_ty _Py_BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset, + PyArena *arena); +#define BinOp(a0, a1, a2, a3, a4, a5) _Py_BinOp(a0, a1, a2, a3, a4, a5) +expr_ty _Py_BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int + col_offset, PyArena *arena); +#define UnaryOp(a0, a1, a2, a3, a4) _Py_UnaryOp(a0, a1, a2, a3, a4) +expr_ty _Py_UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, + PyArena *arena); +#define Lambda(a0, a1, a2, a3, a4) _Py_Lambda(a0, a1, a2, a3, a4) +expr_ty _Py_Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, + PyArena *arena); +#define IfExp(a0, a1, a2, a3, a4, a5) _Py_IfExp(a0, a1, a2, a3, a4, a5) +expr_ty _Py_IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int + col_offset, PyArena *arena); +#define Dict(a0, a1, a2, a3, a4) _Py_Dict(a0, a1, a2, a3, a4) +expr_ty _Py_Dict(asdl_seq * keys, asdl_seq * values, int lineno, int + col_offset, PyArena *arena); +#define ListComp(a0, a1, a2, a3, a4) _Py_ListComp(a0, a1, a2, a3, a4) +expr_ty _Py_ListComp(expr_ty elt, asdl_seq * generators, int lineno, int + col_offset, PyArena *arena); +#define GeneratorExp(a0, a1, a2, a3, a4) _Py_GeneratorExp(a0, a1, a2, a3, a4) +expr_ty _Py_GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int + col_offset, PyArena *arena); +#define Yield(a0, a1, a2, a3) _Py_Yield(a0, a1, a2, a3) +expr_ty _Py_Yield(expr_ty value, int lineno, int col_offset, PyArena *arena); +#define Compare(a0, a1, a2, a3, a4, a5) _Py_Compare(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, + int lineno, int col_offset, PyArena *arena); +#define Call(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Call(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty + starargs, expr_ty kwargs, int lineno, int col_offset, PyArena + *arena); +#define Repr(a0, a1, a2, a3) _Py_Repr(a0, a1, a2, a3) +expr_ty _Py_Repr(expr_ty value, int lineno, int col_offset, PyArena *arena); +#define Num(a0, a1, a2, a3) _Py_Num(a0, a1, a2, a3) +expr_ty _Py_Num(object n, int lineno, int col_offset, PyArena *arena); +#define Str(a0, a1, a2, a3) _Py_Str(a0, a1, a2, a3) +expr_ty _Py_Str(string s, int lineno, int col_offset, PyArena *arena); +#define Attribute(a0, a1, a2, a3, a4, a5) _Py_Attribute(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int + lineno, int col_offset, PyArena *arena); +#define Subscript(a0, a1, a2, a3, a4, a5) _Py_Subscript(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int + lineno, int col_offset, PyArena *arena); +#define Name(a0, a1, a2, a3, a4) _Py_Name(a0, a1, a2, a3, a4) +expr_ty _Py_Name(identifier id, expr_context_ty ctx, int lineno, int + col_offset, PyArena *arena); +#define List(a0, a1, a2, a3, a4) _Py_List(a0, a1, a2, a3, a4) +expr_ty _Py_List(asdl_seq * elts, expr_context_ty ctx, int lineno, int + col_offset, PyArena *arena); +#define Tuple(a0, a1, a2, a3, a4) _Py_Tuple(a0, a1, a2, a3, a4) +expr_ty _Py_Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int + col_offset, PyArena *arena); +#define Ellipsis(a0) _Py_Ellipsis(a0) +slice_ty _Py_Ellipsis(PyArena *arena); +#define Slice(a0, a1, a2, a3) _Py_Slice(a0, a1, a2, a3) +slice_ty _Py_Slice(expr_ty lower, expr_ty upper, expr_ty step, PyArena *arena); +#define ExtSlice(a0, a1) _Py_ExtSlice(a0, a1) +slice_ty _Py_ExtSlice(asdl_seq * dims, PyArena *arena); +#define Index(a0, a1) _Py_Index(a0, a1) +slice_ty _Py_Index(expr_ty value, PyArena *arena); +#define comprehension(a0, a1, a2, a3) _Py_comprehension(a0, a1, a2, a3) +comprehension_ty _Py_comprehension(expr_ty target, expr_ty iter, asdl_seq * + ifs, PyArena *arena); +#define excepthandler(a0, a1, a2, a3, a4, a5) _Py_excepthandler(a0, a1, a2, a3, a4, a5) +excepthandler_ty _Py_excepthandler(expr_ty type, expr_ty name, asdl_seq * body, + int lineno, int col_offset, PyArena *arena); +#define arguments(a0, a1, a2, a3, a4) _Py_arguments(a0, a1, a2, a3, a4) +arguments_ty _Py_arguments(asdl_seq * args, identifier vararg, identifier + kwarg, asdl_seq * defaults, PyArena *arena); +#define keyword(a0, a1, a2) _Py_keyword(a0, a1, a2) +keyword_ty _Py_keyword(identifier arg, expr_ty value, PyArena *arena); +#define alias(a0, a1, a2) _Py_alias(a0, a1, a2) +alias_ty _Py_alias(identifier name, identifier asname, PyArena *arena); + +PyObject* PyAST_mod2obj(mod_ty t); diff --git a/vscript/languages/python/python-2.5.1/include/python.h b/vscript/languages/python/python-2.5.1/include/python.h new file mode 100644 index 00000000..f0be28fa --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/python.h @@ -0,0 +1,173 @@ +#ifndef Py_PYTHON_H +#define Py_PYTHON_H +/* Since this is a "meta-include" file, no #ifdef __cplusplus / extern "C" { */ + +/* Include nearly all Python header files */ + +#include "patchlevel.h" +#include "pyconfig.h" + +/* Cyclic gc is always enabled, starting with release 2.3a1. Supply the + * old symbol for the benefit of extension modules written before then + * that may be conditionalizing on it. The core doesn't use it anymore. + */ +#ifndef WITH_CYCLE_GC +#define WITH_CYCLE_GC 1 +#endif + +#include + +#ifndef UCHAR_MAX +#error "Something's broken. UCHAR_MAX should be defined in limits.h." +#endif + +#if UCHAR_MAX != 255 +#error "Python's source code assumes C's unsigned char is an 8-bit type." +#endif + +#if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE) +#define _SGI_MP_SOURCE +#endif + +#include +#ifndef NULL +# error "Python.h requires that stdio.h define NULL." +#endif + +#include +#ifdef HAVE_ERRNO_H +#include +#endif +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +/* For uintptr_t, intptr_t */ +#ifdef HAVE_STDDEF_H +#include +#endif + +/* CAUTION: Build setups should ensure that NDEBUG is defined on the + * compiler command line when building Python in release mode; else + * assert() calls won't be removed. + */ +#include + +#include "pyport.h" + +/* pyconfig.h or pyport.h may or may not define DL_IMPORT */ +#ifndef DL_IMPORT /* declarations for DLL import/export */ +#define DL_IMPORT(RTYPE) RTYPE +#endif +#ifndef DL_EXPORT /* declarations for DLL import/export */ +#define DL_EXPORT(RTYPE) RTYPE +#endif + +/* Debug-mode build with pymalloc implies PYMALLOC_DEBUG. + * PYMALLOC_DEBUG is in error if pymalloc is not in use. + */ +#if defined(Py_DEBUG) && defined(WITH_PYMALLOC) && !defined(PYMALLOC_DEBUG) +#define PYMALLOC_DEBUG +#endif +#if defined(PYMALLOC_DEBUG) && !defined(WITH_PYMALLOC) +#error "PYMALLOC_DEBUG requires WITH_PYMALLOC" +#endif +#include "pymem.h" + +#include "object.h" +#include "objimpl.h" + +#include "pydebug.h" + +#include "unicodeobject.h" +#include "intobject.h" +#include "boolobject.h" +#include "longobject.h" +#include "floatobject.h" +#ifndef WITHOUT_COMPLEX +#include "complexobject.h" +#endif +#include "rangeobject.h" +#include "stringobject.h" +#include "bufferobject.h" +#include "tupleobject.h" +#include "listobject.h" +#include "dictobject.h" +#include "enumobject.h" +#include "setobject.h" +#include "methodobject.h" +#include "moduleobject.h" +#include "funcobject.h" +#include "classobject.h" +#include "fileobject.h" +#include "cobject.h" +#include "traceback.h" +#include "sliceobject.h" +#include "cellobject.h" +#include "iterobject.h" +#include "genobject.h" +#include "descrobject.h" +#include "weakrefobject.h" + +#include "codecs.h" +#include "pyerrors.h" + +#include "pystate.h" + +#include "pyarena.h" +#include "modsupport.h" +#include "pythonrun.h" +#include "ceval.h" +#include "sysmodule.h" +#include "intrcheck.h" +#include "import.h" + +#include "abstract.h" + +#include "compile.h" +#include "eval.h" + +#include "pystrtod.h" + +/* _Py_Mangle is defined in compile.c */ +PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name); + +/* PyArg_GetInt is deprecated and should not be used, use PyArg_Parse(). */ +#define PyArg_GetInt(v, a) PyArg_Parse((v), "i", (a)) + +/* PyArg_NoArgs should not be necessary. + Set ml_flags in the PyMethodDef to METH_NOARGS. */ +#define PyArg_NoArgs(v) PyArg_Parse(v, "") + +/* Convert a possibly signed character to a nonnegative int */ +/* XXX This assumes characters are 8 bits wide */ +#ifdef __CHAR_UNSIGNED__ +#define Py_CHARMASK(c) (c) +#else +#define Py_CHARMASK(c) ((c) & 0xff) +#endif + +#include "pyfpe.h" + +/* These definitions must match corresponding definitions in graminit.h. + There's code in compile.c that checks that they are the same. */ +#define Py_single_input 256 +#define Py_file_input 257 +#define Py_eval_input 258 + +#ifdef HAVE_PTH +/* GNU pth user-space thread support */ +#include +#endif + +/* Define macros for inline documentation. */ +#define PyDoc_VAR(name) static char name[] +#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str) +#ifdef WITH_DOC_STRINGS +#define PyDoc_STR(str) str +#else +#define PyDoc_STR(str) "" +#endif + +#endif /* !Py_PYTHON_H */ diff --git a/vscript/languages/python/python-2.5.1/include/pythonrun.h b/vscript/languages/python/python-2.5.1/include/pythonrun.h new file mode 100644 index 00000000..cfc40e3a --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/pythonrun.h @@ -0,0 +1,171 @@ + +/* Interfaces to parse and execute pieces of python code */ + +#ifndef Py_PYTHONRUN_H +#define Py_PYTHONRUN_H +#ifdef __cplusplus +extern "C" { +#endif + +#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \ + CO_FUTURE_WITH_STATEMENT) +#define PyCF_MASK_OBSOLETE (CO_NESTED) +#define PyCF_SOURCE_IS_UTF8 0x0100 +#define PyCF_DONT_IMPLY_DEDENT 0x0200 +#define PyCF_ONLY_AST 0x0400 + +typedef struct { + int cf_flags; /* bitmask of CO_xxx flags relevant to future */ +} PyCompilerFlags; + +PyAPI_FUNC(void) Py_SetProgramName(char *); +PyAPI_FUNC(char *) Py_GetProgramName(void); + +PyAPI_FUNC(void) Py_SetPythonHome(char *); +PyAPI_FUNC(char *) Py_GetPythonHome(void); + +PyAPI_FUNC(void) Py_Initialize(void); +PyAPI_FUNC(void) Py_InitializeEx(int); +PyAPI_FUNC(void) Py_Finalize(void); +PyAPI_FUNC(int) Py_IsInitialized(void); +PyAPI_FUNC(PyThreadState *) Py_NewInterpreter(void); +PyAPI_FUNC(void) Py_EndInterpreter(PyThreadState *); + +PyAPI_FUNC(int) PyRun_AnyFileFlags(FILE *, const char *, PyCompilerFlags *); +PyAPI_FUNC(int) PyRun_AnyFileExFlags(FILE *, const char *, int, PyCompilerFlags *); +PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *); +PyAPI_FUNC(int) PyRun_SimpleFileExFlags(FILE *, const char *, int, PyCompilerFlags *); +PyAPI_FUNC(int) PyRun_InteractiveOneFlags(FILE *, const char *, PyCompilerFlags *); +PyAPI_FUNC(int) PyRun_InteractiveLoopFlags(FILE *, const char *, PyCompilerFlags *); + +PyAPI_FUNC(struct _mod *) PyParser_ASTFromString(const char *, const char *, + int, PyCompilerFlags *flags, + PyArena *); +PyAPI_FUNC(struct _mod *) PyParser_ASTFromFile(FILE *, const char *, int, + char *, char *, + PyCompilerFlags *, int *, + PyArena *); +#define PyParser_SimpleParseString(S, B) \ + PyParser_SimpleParseStringFlags(S, B, 0) +#define PyParser_SimpleParseFile(FP, S, B) \ + PyParser_SimpleParseFileFlags(FP, S, B, 0) +PyAPI_FUNC(struct _node *) PyParser_SimpleParseStringFlags(const char *, int, + int); +PyAPI_FUNC(struct _node *) PyParser_SimpleParseFileFlags(FILE *, const char *, + int, int); + +PyAPI_FUNC(PyObject *) PyRun_StringFlags(const char *, int, PyObject *, + PyObject *, PyCompilerFlags *); + +PyAPI_FUNC(PyObject *) PyRun_FileExFlags(FILE *, const char *, int, + PyObject *, PyObject *, int, + PyCompilerFlags *); + +#define Py_CompileString(str, p, s) Py_CompileStringFlags(str, p, s, NULL) +PyAPI_FUNC(PyObject *) Py_CompileStringFlags(const char *, const char *, int, + PyCompilerFlags *); +PyAPI_FUNC(struct symtable *) Py_SymtableString(const char *, const char *, int); + +PyAPI_FUNC(void) PyErr_Print(void); +PyAPI_FUNC(void) PyErr_PrintEx(int); +PyAPI_FUNC(void) PyErr_Display(PyObject *, PyObject *, PyObject *); + +PyAPI_FUNC(int) Py_AtExit(void (*func)(void)); + +PyAPI_FUNC(void) Py_Exit(int); + +PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *); + +/* Bootstrap */ +PyAPI_FUNC(int) Py_Main(int argc, char **argv); + +/* Use macros for a bunch of old variants */ +#define PyRun_String(str, s, g, l) PyRun_StringFlags(str, s, g, l, NULL) +#define PyRun_AnyFile(fp, name) PyRun_AnyFileExFlags(fp, name, 0, NULL) +#define PyRun_AnyFileEx(fp, name, closeit) \ + PyRun_AnyFileExFlags(fp, name, closeit, NULL) +#define PyRun_AnyFileFlags(fp, name, flags) \ + PyRun_AnyFileExFlags(fp, name, 0, flags) +#define PyRun_SimpleString(s) PyRun_SimpleStringFlags(s, NULL) +#define PyRun_SimpleFile(f, p) PyRun_SimpleFileExFlags(f, p, 0, NULL) +#define PyRun_SimpleFileEx(f, p, c) PyRun_SimpleFileExFlags(f, p, c, NULL) +#define PyRun_InteractiveOne(f, p) PyRun_InteractiveOneFlags(f, p, NULL) +#define PyRun_InteractiveLoop(f, p) PyRun_InteractiveLoopFlags(f, p, NULL) +#define PyRun_File(fp, p, s, g, l) \ + PyRun_FileExFlags(fp, p, s, g, l, 0, NULL) +#define PyRun_FileEx(fp, p, s, g, l, c) \ + PyRun_FileExFlags(fp, p, s, g, l, c, NULL) +#define PyRun_FileFlags(fp, p, s, g, l, flags) \ + PyRun_FileExFlags(fp, p, s, g, l, 0, flags) + +/* In getpath.c */ +PyAPI_FUNC(char *) Py_GetProgramFullPath(void); +PyAPI_FUNC(char *) Py_GetPrefix(void); +PyAPI_FUNC(char *) Py_GetExecPrefix(void); +PyAPI_FUNC(char *) Py_GetPath(void); + +/* In their own files */ +PyAPI_FUNC(const char *) Py_GetVersion(void); +PyAPI_FUNC(const char *) Py_GetPlatform(void); +PyAPI_FUNC(const char *) Py_GetCopyright(void); +PyAPI_FUNC(const char *) Py_GetCompiler(void); +PyAPI_FUNC(const char *) Py_GetBuildInfo(void); +PyAPI_FUNC(const char *) _Py_svnversion(void); +PyAPI_FUNC(const char *) Py_SubversionRevision(void); +PyAPI_FUNC(const char *) Py_SubversionShortBranch(void); + +/* Internal -- various one-time initializations */ +PyAPI_FUNC(PyObject *) _PyBuiltin_Init(void); +PyAPI_FUNC(PyObject *) _PySys_Init(void); +PyAPI_FUNC(void) _PyImport_Init(void); +PyAPI_FUNC(void) _PyExc_Init(void); +PyAPI_FUNC(void) _PyImportHooks_Init(void); +PyAPI_FUNC(int) _PyFrame_Init(void); +PyAPI_FUNC(int) _PyInt_Init(void); +PyAPI_FUNC(void) _PyFloat_Init(void); + +/* Various internal finalizers */ +PyAPI_FUNC(void) _PyExc_Fini(void); +PyAPI_FUNC(void) _PyImport_Fini(void); +PyAPI_FUNC(void) PyMethod_Fini(void); +PyAPI_FUNC(void) PyFrame_Fini(void); +PyAPI_FUNC(void) PyCFunction_Fini(void); +PyAPI_FUNC(void) PyTuple_Fini(void); +PyAPI_FUNC(void) PyList_Fini(void); +PyAPI_FUNC(void) PySet_Fini(void); +PyAPI_FUNC(void) PyString_Fini(void); +PyAPI_FUNC(void) PyInt_Fini(void); +PyAPI_FUNC(void) PyFloat_Fini(void); +PyAPI_FUNC(void) PyOS_FiniInterrupts(void); + +/* Stuff with no proper home (yet) */ +PyAPI_FUNC(char *) PyOS_Readline(FILE *, FILE *, char *); +PyAPI_DATA(int) (*PyOS_InputHook)(void); +PyAPI_DATA(char) *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, char *); +PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState; + +/* Stack size, in "pointers" (so we get extra safety margins + on 64-bit platforms). On a 32-bit platform, this translates + to a 8k margin. */ +#define PYOS_STACK_MARGIN 2048 + +#if defined(WIN32) && !defined(MS_WIN64) && defined(_MSC_VER) +/* Enable stack checking under Microsoft C */ +#define USE_STACKCHECK +#endif + +#ifdef USE_STACKCHECK +/* Check that we aren't overflowing our stack */ +PyAPI_FUNC(int) PyOS_CheckStack(void); +#endif + +/* Signals */ +typedef void (*PyOS_sighandler_t)(int); +PyAPI_FUNC(PyOS_sighandler_t) PyOS_getsig(int); +PyAPI_FUNC(PyOS_sighandler_t) PyOS_setsig(int, PyOS_sighandler_t); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYTHONRUN_H */ diff --git a/vscript/languages/python/python-2.5.1/include/pythread.h b/vscript/languages/python/python-2.5.1/include/pythread.h new file mode 100644 index 00000000..f26db160 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/pythread.h @@ -0,0 +1,47 @@ + +#ifndef Py_PYTHREAD_H +#define Py_PYTHREAD_H + +#define NO_EXIT_PROG /* don't define PyThread_exit_prog() */ + /* (the result is no use of signals on SGI) */ + +typedef void *PyThread_type_lock; +typedef void *PyThread_type_sema; + +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(void) PyThread_init_thread(void); +PyAPI_FUNC(long) PyThread_start_new_thread(void (*)(void *), void *); +PyAPI_FUNC(void) PyThread_exit_thread(void); +PyAPI_FUNC(void) PyThread__PyThread_exit_thread(void); +PyAPI_FUNC(long) PyThread_get_thread_ident(void); + +PyAPI_FUNC(PyThread_type_lock) PyThread_allocate_lock(void); +PyAPI_FUNC(void) PyThread_free_lock(PyThread_type_lock); +PyAPI_FUNC(int) PyThread_acquire_lock(PyThread_type_lock, int); +#define WAIT_LOCK 1 +#define NOWAIT_LOCK 0 +PyAPI_FUNC(void) PyThread_release_lock(PyThread_type_lock); + +PyAPI_FUNC(size_t) PyThread_get_stacksize(void); +PyAPI_FUNC(int) PyThread_set_stacksize(size_t); + +#ifndef NO_EXIT_PROG +PyAPI_FUNC(void) PyThread_exit_prog(int); +PyAPI_FUNC(void) PyThread__PyThread_exit_prog(int); +#endif + +/* Thread Local Storage (TLS) API */ +PyAPI_FUNC(int) PyThread_create_key(void); +PyAPI_FUNC(void) PyThread_delete_key(int); +PyAPI_FUNC(int) PyThread_set_key_value(int, void *); +PyAPI_FUNC(void *) PyThread_get_key_value(int); +PyAPI_FUNC(void) PyThread_delete_key_value(int key); + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_PYTHREAD_H */ diff --git a/vscript/languages/python/python-2.5.1/include/rangeobject.h b/vscript/languages/python/python-2.5.1/include/rangeobject.h new file mode 100644 index 00000000..359bcb69 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/rangeobject.h @@ -0,0 +1,28 @@ + +/* Range object interface */ + +#ifndef Py_RANGEOBJECT_H +#define Py_RANGEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* This is about the type 'xrange', not the built-in function range(), which + returns regular lists. */ + +/* +A range object represents an integer range. This is an immutable object; +a range cannot change its value after creation. + +Range objects behave like the corresponding tuple objects except that +they are represented by a start, stop, and step datamembers. +*/ + +PyAPI_DATA(PyTypeObject) PyRange_Type; + +#define PyRange_Check(op) ((op)->ob_type == &PyRange_Type) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_RANGEOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/setobject.h b/vscript/languages/python/python-2.5.1/include/setobject.h new file mode 100644 index 00000000..750a2a8a --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/setobject.h @@ -0,0 +1,93 @@ +/* Set object interface */ + +#ifndef Py_SETOBJECT_H +#define Py_SETOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* +There are three kinds of slots in the table: + +1. Unused: key == NULL +2. Active: key != NULL and key != dummy +3. Dummy: key == dummy + +Note: .pop() abuses the hash field of an Unused or Dummy slot to +hold a search finger. The hash field of Unused or Dummy slots has +no meaning otherwise. +*/ + +#define PySet_MINSIZE 8 + +typedef struct { + long hash; /* cached hash code for the entry key */ + PyObject *key; +} setentry; + + +/* +This data structure is shared by set and frozenset objects. +*/ + +typedef struct _setobject PySetObject; +struct _setobject { + PyObject_HEAD + + Py_ssize_t fill; /* # Active + # Dummy */ + Py_ssize_t used; /* # Active */ + + /* The table contains mask + 1 slots, and that's a power of 2. + * We store the mask instead of the size because the mask is more + * frequently needed. + */ + Py_ssize_t mask; + + /* table points to smalltable for small tables, else to + * additional malloc'ed memory. table is never NULL! This rule + * saves repeated runtime null-tests. + */ + setentry *table; + setentry *(*lookup)(PySetObject *so, PyObject *key, long hash); + setentry smalltable[PySet_MINSIZE]; + + long hash; /* only used by frozenset objects */ + PyObject *weakreflist; /* List of weak references */ +}; + +PyAPI_DATA(PyTypeObject) PySet_Type; +PyAPI_DATA(PyTypeObject) PyFrozenSet_Type; + +/* Invariants for frozensets: + * data is immutable. + * hash is the hash of the frozenset or -1 if not computed yet. + * Invariants for sets: + * hash is -1 + */ + +#define PyFrozenSet_CheckExact(ob) ((ob)->ob_type == &PyFrozenSet_Type) +#define PyAnySet_CheckExact(ob) \ + ((ob)->ob_type == &PySet_Type || (ob)->ob_type == &PyFrozenSet_Type) +#define PyAnySet_Check(ob) \ + ((ob)->ob_type == &PySet_Type || (ob)->ob_type == &PyFrozenSet_Type || \ + PyType_IsSubtype((ob)->ob_type, &PySet_Type) || \ + PyType_IsSubtype((ob)->ob_type, &PyFrozenSet_Type)) + +PyAPI_FUNC(PyObject *) PySet_New(PyObject *); +PyAPI_FUNC(PyObject *) PyFrozenSet_New(PyObject *); +PyAPI_FUNC(Py_ssize_t) PySet_Size(PyObject *anyset); +#define PySet_GET_SIZE(so) (((PySetObject *)(so))->used) +PyAPI_FUNC(int) PySet_Clear(PyObject *set); +PyAPI_FUNC(int) PySet_Contains(PyObject *anyset, PyObject *key); +PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key); +PyAPI_FUNC(int) PySet_Add(PyObject *set, PyObject *key); +PyAPI_FUNC(int) _PySet_Next(PyObject *set, Py_ssize_t *pos, PyObject **key); +PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash); +PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set); +PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_SETOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/sliceobject.h b/vscript/languages/python/python-2.5.1/include/sliceobject.h new file mode 100644 index 00000000..dbc34b2a --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/sliceobject.h @@ -0,0 +1,43 @@ +#ifndef Py_SLICEOBJECT_H +#define Py_SLICEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* The unique ellipsis object "..." */ + +PyAPI_DATA(PyObject) _Py_EllipsisObject; /* Don't use this directly */ + +#define Py_Ellipsis (&_Py_EllipsisObject) + +/* Slice object interface */ + +/* + +A slice object containing start, stop, and step data members (the +names are from range). After much talk with Guido, it was decided to +let these be any arbitrary python type. Py_None stands for omitted values. +*/ + +typedef struct { + PyObject_HEAD + PyObject *start, *stop, *step; /* not NULL */ +} PySliceObject; + +PyAPI_DATA(PyTypeObject) PySlice_Type; + +#define PySlice_Check(op) ((op)->ob_type == &PySlice_Type) + +PyAPI_FUNC(PyObject *) PySlice_New(PyObject* start, PyObject* stop, + PyObject* step); +PyAPI_FUNC(PyObject *) _PySlice_FromIndices(Py_ssize_t start, Py_ssize_t stop); +PyAPI_FUNC(int) PySlice_GetIndices(PySliceObject *r, Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step); +PyAPI_FUNC(int) PySlice_GetIndicesEx(PySliceObject *r, Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, + Py_ssize_t *step, Py_ssize_t *slicelength); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_SLICEOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/stringobject.h b/vscript/languages/python/python-2.5.1/include/stringobject.h new file mode 100644 index 00000000..5f8a6f02 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/stringobject.h @@ -0,0 +1,183 @@ + +/* String object interface */ + +#ifndef Py_STRINGOBJECT_H +#define Py_STRINGOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* +Type PyStringObject represents a character string. An extra zero byte is +reserved at the end to ensure it is zero-terminated, but a size is +present so strings with null bytes in them can be represented. This +is an immutable object type. + +There are functions to create new string objects, to test +an object for string-ness, and to get the +string value. The latter function returns a null pointer +if the object is not of the proper type. +There is a variant that takes an explicit size as well as a +variant that assumes a zero-terminated string. Note that none of the +functions should be applied to nil objects. +*/ + +/* Caching the hash (ob_shash) saves recalculation of a string's hash value. + Interning strings (ob_sstate) tries to ensure that only one string + object with a given value exists, so equality tests can be one pointer + comparison. This is generally restricted to strings that "look like" + Python identifiers, although the intern() builtin can be used to force + interning of any string. + Together, these sped the interpreter by up to 20%. */ + +typedef struct { + PyObject_VAR_HEAD + long ob_shash; + int ob_sstate; + char ob_sval[1]; + + /* Invariants: + * ob_sval contains space for 'ob_size+1' elements. + * ob_sval[ob_size] == 0. + * ob_shash is the hash of the string or -1 if not computed yet. + * ob_sstate != 0 iff the string object is in stringobject.c's + * 'interned' dictionary; in this case the two references + * from 'interned' to this object are *not counted* in ob_refcnt. + */ +} PyStringObject; + +#define SSTATE_NOT_INTERNED 0 +#define SSTATE_INTERNED_MORTAL 1 +#define SSTATE_INTERNED_IMMORTAL 2 + +PyAPI_DATA(PyTypeObject) PyBaseString_Type; +PyAPI_DATA(PyTypeObject) PyString_Type; + +#define PyString_Check(op) PyObject_TypeCheck(op, &PyString_Type) +#define PyString_CheckExact(op) ((op)->ob_type == &PyString_Type) + +PyAPI_FUNC(PyObject *) PyString_FromStringAndSize(const char *, Py_ssize_t); +PyAPI_FUNC(PyObject *) PyString_FromString(const char *); +PyAPI_FUNC(PyObject *) PyString_FromFormatV(const char*, va_list) + Py_GCC_ATTRIBUTE((format(printf, 1, 0))); +PyAPI_FUNC(PyObject *) PyString_FromFormat(const char*, ...) + Py_GCC_ATTRIBUTE((format(printf, 1, 2))); +PyAPI_FUNC(Py_ssize_t) PyString_Size(PyObject *); +PyAPI_FUNC(char *) PyString_AsString(PyObject *); +PyAPI_FUNC(PyObject *) PyString_Repr(PyObject *, int); +PyAPI_FUNC(void) PyString_Concat(PyObject **, PyObject *); +PyAPI_FUNC(void) PyString_ConcatAndDel(PyObject **, PyObject *); +PyAPI_FUNC(int) _PyString_Resize(PyObject **, Py_ssize_t); +PyAPI_FUNC(int) _PyString_Eq(PyObject *, PyObject*); +PyAPI_FUNC(PyObject *) PyString_Format(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyString_FormatLong(PyObject*, int, int, + int, char**, int*); +PyAPI_FUNC(PyObject *) PyString_DecodeEscape(const char *, Py_ssize_t, + const char *, Py_ssize_t, + const char *); + +PyAPI_FUNC(void) PyString_InternInPlace(PyObject **); +PyAPI_FUNC(void) PyString_InternImmortal(PyObject **); +PyAPI_FUNC(PyObject *) PyString_InternFromString(const char *); +PyAPI_FUNC(void) _Py_ReleaseInternedStrings(void); + +/* Use only if you know it's a string */ +#define PyString_CHECK_INTERNED(op) (((PyStringObject *)(op))->ob_sstate) + +/* Macro, trading safety for speed */ +#define PyString_AS_STRING(op) (((PyStringObject *)(op))->ob_sval) +#define PyString_GET_SIZE(op) (((PyStringObject *)(op))->ob_size) + +/* _PyString_Join(sep, x) is like sep.join(x). sep must be PyStringObject*, + x must be an iterable object. */ +PyAPI_FUNC(PyObject *) _PyString_Join(PyObject *sep, PyObject *x); + +/* --- Generic Codecs ----------------------------------------------------- */ + +/* Create an object by decoding the encoded string s of the + given size. */ + +PyAPI_FUNC(PyObject*) PyString_Decode( + const char *s, /* encoded string */ + Py_ssize_t size, /* size of buffer */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Encodes a char buffer of the given size and returns a + Python object. */ + +PyAPI_FUNC(PyObject*) PyString_Encode( + const char *s, /* string char buffer */ + Py_ssize_t size, /* number of chars to encode */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Encodes a string object and returns the result as Python + object. */ + +PyAPI_FUNC(PyObject*) PyString_AsEncodedObject( + PyObject *str, /* string object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Encodes a string object and returns the result as Python string + object. + + If the codec returns an Unicode object, the object is converted + back to a string using the default encoding. + + DEPRECATED - use PyString_AsEncodedObject() instead. */ + +PyAPI_FUNC(PyObject*) PyString_AsEncodedString( + PyObject *str, /* string object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Decodes a string object and returns the result as Python + object. */ + +PyAPI_FUNC(PyObject*) PyString_AsDecodedObject( + PyObject *str, /* string object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Decodes a string object and returns the result as Python string + object. + + If the codec returns an Unicode object, the object is converted + back to a string using the default encoding. + + DEPRECATED - use PyString_AsDecodedObject() instead. */ + +PyAPI_FUNC(PyObject*) PyString_AsDecodedString( + PyObject *str, /* string object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Provides access to the internal data buffer and size of a string + object or the default encoded version of an Unicode object. Passing + NULL as *len parameter will force the string buffer to be + 0-terminated (passing a string with embedded NULL characters will + cause an exception). */ + +PyAPI_FUNC(int) PyString_AsStringAndSize( + register PyObject *obj, /* string or Unicode object */ + register char **s, /* pointer to buffer variable */ + register Py_ssize_t *len /* pointer to length variable or NULL + (only possible for 0-terminated + strings) */ + ); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_STRINGOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/structmember.h b/vscript/languages/python/python-2.5.1/include/structmember.h new file mode 100644 index 00000000..e761f6d9 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/structmember.h @@ -0,0 +1,93 @@ +#ifndef Py_STRUCTMEMBER_H +#define Py_STRUCTMEMBER_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Interface to map C struct members to Python object attributes */ + +#include /* For offsetof */ + +/* The offsetof() macro calculates the offset of a structure member + in its structure. Unfortunately this cannot be written down + portably, hence it is provided by a Standard C header file. + For pre-Standard C compilers, here is a version that usually works + (but watch out!): */ + +#ifndef offsetof +#define offsetof(type, member) ( (int) & ((type*)0) -> member ) +#endif + +/* An array of memberlist structures defines the name, type and offset + of selected members of a C structure. These can be read by + PyMember_Get() and set by PyMember_Set() (except if their READONLY flag + is set). The array must be terminated with an entry whose name + pointer is NULL. */ + +struct memberlist { + /* Obsolete version, for binary backwards compatibility */ + char *name; + int type; + int offset; + int flags; +}; + +typedef struct PyMemberDef { + /* Current version, use this */ + char *name; + int type; + Py_ssize_t offset; + int flags; + char *doc; +} PyMemberDef; + +/* Types */ +#define T_SHORT 0 +#define T_INT 1 +#define T_LONG 2 +#define T_FLOAT 3 +#define T_DOUBLE 4 +#define T_STRING 5 +#define T_OBJECT 6 +/* XXX the ordering here is weird for binary compatibility */ +#define T_CHAR 7 /* 1-character string */ +#define T_BYTE 8 /* 8-bit signed int */ +/* unsigned variants: */ +#define T_UBYTE 9 +#define T_USHORT 10 +#define T_UINT 11 +#define T_ULONG 12 + +/* Added by Jack: strings contained in the structure */ +#define T_STRING_INPLACE 13 + +#define T_OBJECT_EX 16 /* Like T_OBJECT, but raises AttributeError + when the value is NULL, instead of + converting to None. */ +#ifdef HAVE_LONG_LONG +#define T_LONGLONG 17 +#define T_ULONGLONG 18 +#endif /* HAVE_LONG_LONG */ + +/* Flags */ +#define READONLY 1 +#define RO READONLY /* Shorthand */ +#define READ_RESTRICTED 2 +#define WRITE_RESTRICTED 4 +#define RESTRICTED (READ_RESTRICTED | WRITE_RESTRICTED) + + +/* Obsolete API, for binary backwards compatibility */ +PyAPI_FUNC(PyObject *) PyMember_Get(const char *, struct memberlist *, const char *); +PyAPI_FUNC(int) PyMember_Set(char *, struct memberlist *, const char *, PyObject *); + +/* Current API, use this */ +PyAPI_FUNC(PyObject *) PyMember_GetOne(const char *, struct PyMemberDef *); +PyAPI_FUNC(int) PyMember_SetOne(char *, struct PyMemberDef *, PyObject *); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_STRUCTMEMBER_H */ diff --git a/vscript/languages/python/python-2.5.1/include/structseq.h b/vscript/languages/python/python-2.5.1/include/structseq.h new file mode 100644 index 00000000..e662916f --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/structseq.h @@ -0,0 +1,41 @@ + +/* Tuple object interface */ + +#ifndef Py_STRUCTSEQ_H +#define Py_STRUCTSEQ_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct PyStructSequence_Field { + char *name; + char *doc; +} PyStructSequence_Field; + +typedef struct PyStructSequence_Desc { + char *name; + char *doc; + struct PyStructSequence_Field *fields; + int n_in_sequence; +} PyStructSequence_Desc; + +extern char* PyStructSequence_UnnamedField; + +PyAPI_FUNC(void) PyStructSequence_InitType(PyTypeObject *type, + PyStructSequence_Desc *desc); + +PyAPI_FUNC(PyObject *) PyStructSequence_New(PyTypeObject* type); + +typedef struct { + PyObject_VAR_HEAD + PyObject *ob_item[1]; +} PyStructSequence; + +/* Macro, *only* to be used to fill in brand new objects */ +#define PyStructSequence_SET_ITEM(op, i, v) \ + (((PyStructSequence *)(op))->ob_item[i] = v) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_STRUCTSEQ_H */ diff --git a/vscript/languages/python/python-2.5.1/include/symtable.h b/vscript/languages/python/python-2.5.1/include/symtable.h new file mode 100644 index 00000000..1e5996dc --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/symtable.h @@ -0,0 +1,103 @@ +#ifndef Py_SYMTABLE_H +#define Py_SYMTABLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum _block_type { FunctionBlock, ClassBlock, ModuleBlock } + _Py_block_ty; + +struct _symtable_entry; + +struct symtable { + const char *st_filename; /* name of file being compiled */ + struct _symtable_entry *st_cur; /* current symbol table entry */ + struct _symtable_entry *st_top; /* module entry */ + PyObject *st_symbols; /* dictionary of symbol table entries */ + PyObject *st_stack; /* stack of namespace info */ + PyObject *st_global; /* borrowed ref to MODULE in st_symbols */ + int st_nblocks; /* number of blocks */ + PyObject *st_private; /* name of current class or NULL */ + int st_tmpname; /* temporary name counter */ + PyFutureFeatures *st_future; /* module's future features */ +}; + +typedef struct _symtable_entry { + PyObject_HEAD + PyObject *ste_id; /* int: key in st_symbols */ + PyObject *ste_symbols; /* dict: name to flags */ + PyObject *ste_name; /* string: name of block */ + PyObject *ste_varnames; /* list of variable names */ + PyObject *ste_children; /* list of child ids */ + _Py_block_ty ste_type; /* module, class, or function */ + int ste_unoptimized; /* false if namespace is optimized */ + unsigned ste_nested : 1; /* true if block is nested */ + unsigned ste_free : 1; /* true if block has free variables */ + unsigned ste_child_free : 1; /* true if a child block has free vars, + including free refs to globals */ + unsigned ste_generator : 1; /* true if namespace is a generator */ + unsigned ste_varargs : 1; /* true if block has varargs */ + unsigned ste_varkeywords : 1; /* true if block has varkeywords */ + unsigned ste_returns_value : 1; /* true if namespace uses return with + an argument */ + int ste_lineno; /* first line of block */ + int ste_opt_lineno; /* lineno of last exec or import * */ + int ste_tmpname; /* counter for listcomp temp vars */ + struct symtable *ste_table; +} PySTEntryObject; + +PyAPI_DATA(PyTypeObject) PySTEntry_Type; + +#define PySTEntry_Check(op) ((op)->ob_type == &PySTEntry_Type) + +PyAPI_FUNC(int) PyST_GetScope(PySTEntryObject *, PyObject *); + +PyAPI_FUNC(struct symtable *) PySymtable_Build(mod_ty, const char *, + PyFutureFeatures *); +PyAPI_FUNC(PySTEntryObject *) PySymtable_Lookup(struct symtable *, void *); + +PyAPI_FUNC(void) PySymtable_Free(struct symtable *); + +/* Flags for def-use information */ + +#define DEF_GLOBAL 1 /* global stmt */ +#define DEF_LOCAL 2 /* assignment in code block */ +#define DEF_PARAM 2<<1 /* formal parameter */ +#define USE 2<<2 /* name is used */ +#define DEF_STAR 2<<3 /* parameter is star arg */ +#define DEF_DOUBLESTAR 2<<4 /* parameter is star-star arg */ +#define DEF_INTUPLE 2<<5 /* name defined in tuple in parameters */ +#define DEF_FREE 2<<6 /* name used but not defined in nested block */ +#define DEF_FREE_GLOBAL 2<<7 /* free variable is actually implicit global */ +#define DEF_FREE_CLASS 2<<8 /* free variable from class's method */ +#define DEF_IMPORT 2<<9 /* assignment occurred via import */ + +#define DEF_BOUND (DEF_LOCAL | DEF_PARAM | DEF_IMPORT) + +/* GLOBAL_EXPLICIT and GLOBAL_IMPLICIT are used internally by the symbol + table. GLOBAL is returned from PyST_GetScope() for either of them. + It is stored in ste_symbols at bits 12-14. +*/ +#define SCOPE_OFF 11 +#define SCOPE_MASK 7 + +#define LOCAL 1 +#define GLOBAL_EXPLICIT 2 +#define GLOBAL_IMPLICIT 3 +#define FREE 4 +#define CELL 5 + +/* The following three names are used for the ste_unoptimized bit field */ +#define OPT_IMPORT_STAR 1 +#define OPT_EXEC 2 +#define OPT_BARE_EXEC 4 +#define OPT_TOPLEVEL 8 /* top-level names, including eval and exec */ + +#define GENERATOR 1 +#define GENERATOR_EXPRESSION 2 + +#ifdef __cplusplus +} +#endif +#endif /* !Py_SYMTABLE_H */ diff --git a/vscript/languages/python/python-2.5.1/include/sysmodule.h b/vscript/languages/python/python-2.5.1/include/sysmodule.h new file mode 100644 index 00000000..1c9b187f --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/sysmodule.h @@ -0,0 +1,30 @@ + +/* System module interface */ + +#ifndef Py_SYSMODULE_H +#define Py_SYSMODULE_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(PyObject *) PySys_GetObject(char *); +PyAPI_FUNC(int) PySys_SetObject(char *, PyObject *); +PyAPI_FUNC(FILE *) PySys_GetFile(char *, FILE *); +PyAPI_FUNC(void) PySys_SetArgv(int, char **); +PyAPI_FUNC(void) PySys_SetPath(char *); + +PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...) + Py_GCC_ATTRIBUTE((format(printf, 1, 2))); +PyAPI_FUNC(void) PySys_WriteStderr(const char *format, ...) + Py_GCC_ATTRIBUTE((format(printf, 1, 2))); + +PyAPI_DATA(PyObject *) _PySys_TraceFunc, *_PySys_ProfileFunc; +PyAPI_DATA(int) _PySys_CheckInterval; + +PyAPI_FUNC(void) PySys_ResetWarnOptions(void); +PyAPI_FUNC(void) PySys_AddWarnOption(char *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_SYSMODULE_H */ diff --git a/vscript/languages/python/python-2.5.1/include/timefuncs.h b/vscript/languages/python/python-2.5.1/include/timefuncs.h new file mode 100644 index 00000000..553142db --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/timefuncs.h @@ -0,0 +1,23 @@ +/* timefuncs.h + */ + +/* Utility function related to timemodule.c. */ + +#ifndef TIMEFUNCS_H +#define TIMEFUNCS_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Cast double x to time_t, but raise ValueError if x is too large + * to fit in a time_t. ValueError is set on return iff the return + * value is (time_t)-1 and PyErr_Occurred(). + */ +PyAPI_FUNC(time_t) _PyTime_DoubleToTimet(double x); + + +#ifdef __cplusplus +} +#endif +#endif /* TIMEFUNCS_H */ diff --git a/vscript/languages/python/python-2.5.1/include/token.h b/vscript/languages/python/python-2.5.1/include/token.h new file mode 100644 index 00000000..4250000d --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/token.h @@ -0,0 +1,83 @@ + +/* Token types */ + +#ifndef Py_TOKEN_H +#define Py_TOKEN_H +#ifdef __cplusplus +extern "C" { +#endif + +#define ENDMARKER 0 +#define NAME 1 +#define NUMBER 2 +#define STRING 3 +#define NEWLINE 4 +#define INDENT 5 +#define DEDENT 6 +#define LPAR 7 +#define RPAR 8 +#define LSQB 9 +#define RSQB 10 +#define COLON 11 +#define COMMA 12 +#define SEMI 13 +#define PLUS 14 +#define MINUS 15 +#define STAR 16 +#define SLASH 17 +#define VBAR 18 +#define AMPER 19 +#define LESS 20 +#define GREATER 21 +#define EQUAL 22 +#define DOT 23 +#define PERCENT 24 +#define BACKQUOTE 25 +#define LBRACE 26 +#define RBRACE 27 +#define EQEQUAL 28 +#define NOTEQUAL 29 +#define LESSEQUAL 30 +#define GREATEREQUAL 31 +#define TILDE 32 +#define CIRCUMFLEX 33 +#define LEFTSHIFT 34 +#define RIGHTSHIFT 35 +#define DOUBLESTAR 36 +#define PLUSEQUAL 37 +#define MINEQUAL 38 +#define STAREQUAL 39 +#define SLASHEQUAL 40 +#define PERCENTEQUAL 41 +#define AMPEREQUAL 42 +#define VBAREQUAL 43 +#define CIRCUMFLEXEQUAL 44 +#define LEFTSHIFTEQUAL 45 +#define RIGHTSHIFTEQUAL 46 +#define DOUBLESTAREQUAL 47 +#define DOUBLESLASH 48 +#define DOUBLESLASHEQUAL 49 +#define AT 50 +/* Don't forget to update the table _PyParser_TokenNames in tokenizer.c! */ +#define OP 51 +#define ERRORTOKEN 52 +#define N_TOKENS 53 + +/* Special definitions for cooperation with parser */ + +#define NT_OFFSET 256 + +#define ISTERMINAL(x) ((x) < NT_OFFSET) +#define ISNONTERMINAL(x) ((x) >= NT_OFFSET) +#define ISEOF(x) ((x) == ENDMARKER) + + +PyAPI_DATA(char *) _PyParser_TokenNames[]; /* Token names */ +PyAPI_FUNC(int) PyToken_OneChar(int); +PyAPI_FUNC(int) PyToken_TwoChars(int, int); +PyAPI_FUNC(int) PyToken_ThreeChars(int, int, int); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_TOKEN_H */ diff --git a/vscript/languages/python/python-2.5.1/include/traceback.h b/vscript/languages/python/python-2.5.1/include/traceback.h new file mode 100644 index 00000000..6501600c --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/traceback.h @@ -0,0 +1,30 @@ + +#ifndef Py_TRACEBACK_H +#define Py_TRACEBACK_H +#ifdef __cplusplus +extern "C" { +#endif + +struct _frame; + +/* Traceback interface */ + +typedef struct _traceback { + PyObject_HEAD + struct _traceback *tb_next; + struct _frame *tb_frame; + int tb_lasti; + int tb_lineno; +} PyTracebackObject; + +PyAPI_FUNC(int) PyTraceBack_Here(struct _frame *); +PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *); + +/* Reveal traceback type so we can typecheck traceback objects */ +PyAPI_DATA(PyTypeObject) PyTraceBack_Type; +#define PyTraceBack_Check(v) ((v)->ob_type == &PyTraceBack_Type) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_TRACEBACK_H */ diff --git a/vscript/languages/python/python-2.5.1/include/tupleobject.h b/vscript/languages/python/python-2.5.1/include/tupleobject.h new file mode 100644 index 00000000..8c37cabd --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/tupleobject.h @@ -0,0 +1,57 @@ + +/* Tuple object interface */ + +#ifndef Py_TUPLEOBJECT_H +#define Py_TUPLEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* +Another generally useful object type is a tuple of object pointers. +For Python, this is an immutable type. C code can change the tuple items +(but not their number), and even use tuples are general-purpose arrays of +object references, but in general only brand new tuples should be mutated, +not ones that might already have been exposed to Python code. + +*** WARNING *** PyTuple_SetItem does not increment the new item's reference +count, but does decrement the reference count of the item it replaces, +if not nil. It does *decrement* the reference count if it is *not* +inserted in the tuple. Similarly, PyTuple_GetItem does not increment the +returned item's reference count. +*/ + +typedef struct { + PyObject_VAR_HEAD + PyObject *ob_item[1]; + + /* ob_item contains space for 'ob_size' elements. + * Items must normally not be NULL, except during construction when + * the tuple is not yet visible outside the function that builds it. + */ +} PyTupleObject; + +PyAPI_DATA(PyTypeObject) PyTuple_Type; + +#define PyTuple_Check(op) PyObject_TypeCheck(op, &PyTuple_Type) +#define PyTuple_CheckExact(op) ((op)->ob_type == &PyTuple_Type) + +PyAPI_FUNC(PyObject *) PyTuple_New(Py_ssize_t size); +PyAPI_FUNC(Py_ssize_t) PyTuple_Size(PyObject *); +PyAPI_FUNC(PyObject *) PyTuple_GetItem(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyTuple_SetItem(PyObject *, Py_ssize_t, PyObject *); +PyAPI_FUNC(PyObject *) PyTuple_GetSlice(PyObject *, Py_ssize_t, Py_ssize_t); +PyAPI_FUNC(int) _PyTuple_Resize(PyObject **, Py_ssize_t); +PyAPI_FUNC(PyObject *) PyTuple_Pack(Py_ssize_t, ...); + +/* Macro, trading safety for speed */ +#define PyTuple_GET_ITEM(op, i) (((PyTupleObject *)(op))->ob_item[i]) +#define PyTuple_GET_SIZE(op) (((PyTupleObject *)(op))->ob_size) + +/* Macro, *only* to be used to fill in brand new tuples */ +#define PyTuple_SET_ITEM(op, i, v) (((PyTupleObject *)(op))->ob_item[i] = v) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_TUPLEOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/ucnhash.h b/vscript/languages/python/python-2.5.1/include/ucnhash.h new file mode 100644 index 00000000..6231c98b --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/ucnhash.h @@ -0,0 +1,31 @@ +/* Unicode name database interface */ + +#ifndef Py_UCNHASH_H +#define Py_UCNHASH_H +#ifdef __cplusplus +extern "C" { +#endif + +/* revised ucnhash CAPI interface (exported through a PyCObject) */ + +typedef struct { + + /* Size of this struct */ + int size; + + /* Get name for a given character code. Returns non-zero if + success, zero if not. Does not set Python exceptions. + If self is NULL, data come from the default version of the database. + If it is not NULL, it should be a unicodedata.ucd_X_Y_Z object */ + int (*getname)(PyObject *self, Py_UCS4 code, char* buffer, int buflen); + + /* Get character code for a given name. Same error handling + as for getname. */ + int (*getcode)(PyObject *self, const char* name, int namelen, Py_UCS4* code); + +} _PyUnicode_Name_CAPI; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_UCNHASH_H */ diff --git a/vscript/languages/python/python-2.5.1/include/unicodeobject.h b/vscript/languages/python/python-2.5.1/include/unicodeobject.h new file mode 100644 index 00000000..33aa1858 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/unicodeobject.h @@ -0,0 +1,1265 @@ +#ifndef Py_UNICODEOBJECT_H +#define Py_UNICODEOBJECT_H + +/* + +Unicode implementation based on original code by Fredrik Lundh, +modified by Marc-Andre Lemburg (mal@lemburg.com) according to the +Unicode Integration Proposal (see file Misc/unicode.txt). + +Copyright (c) Corporation for National Research Initiatives. + + + Original header: + -------------------------------------------------------------------- + + * Yet another Unicode string type for Python. This type supports the + * 16-bit Basic Multilingual Plane (BMP) only. + * + * Written by Fredrik Lundh, January 1999. + * + * Copyright (c) 1999 by Secret Labs AB. + * Copyright (c) 1999 by Fredrik Lundh. + * + * fredrik@pythonware.com + * http://www.pythonware.com + * + * -------------------------------------------------------------------- + * This Unicode String Type is + * + * Copyright (c) 1999 by Secret Labs AB + * Copyright (c) 1999 by Fredrik Lundh + * + * By obtaining, using, and/or copying this software and/or its + * associated documentation, you agree that you have read, understood, + * and will comply with the following terms and conditions: + * + * Permission to use, copy, modify, and distribute this software and its + * associated documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appears in all + * copies, and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of Secret Labs + * AB or the author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. + * + * SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * -------------------------------------------------------------------- */ + +#include + +/* === Internal API ======================================================= */ + +/* --- Internal Unicode Format -------------------------------------------- */ + +#ifndef Py_USING_UNICODE + +#define PyUnicode_Check(op) 0 +#define PyUnicode_CheckExact(op) 0 + +#else + +/* FIXME: MvL's new implementation assumes that Py_UNICODE_SIZE is + properly set, but the default rules below doesn't set it. I'll + sort this out some other day -- fredrik@pythonware.com */ + +#ifndef Py_UNICODE_SIZE +#error Must define Py_UNICODE_SIZE +#endif + +/* Setting Py_UNICODE_WIDE enables UCS-4 storage. Otherwise, Unicode + strings are stored as UCS-2 (with limited support for UTF-16) */ + +#if Py_UNICODE_SIZE >= 4 +#define Py_UNICODE_WIDE +#endif + +/* Set these flags if the platform has "wchar.h", "wctype.h" and the + wchar_t type is a 16-bit unsigned type */ +/* #define HAVE_WCHAR_H */ +/* #define HAVE_USABLE_WCHAR_T */ + +/* Defaults for various platforms */ +#ifndef PY_UNICODE_TYPE + +/* Windows has a usable wchar_t type (unless we're using UCS-4) */ +# if defined(MS_WIN32) && Py_UNICODE_SIZE == 2 +# define HAVE_USABLE_WCHAR_T +# define PY_UNICODE_TYPE wchar_t +# endif + +# if defined(Py_UNICODE_WIDE) +# define PY_UNICODE_TYPE Py_UCS4 +# endif + +#endif + +/* If the compiler provides a wchar_t type we try to support it + through the interface functions PyUnicode_FromWideChar() and + PyUnicode_AsWideChar(). */ + +#ifdef HAVE_USABLE_WCHAR_T +# ifndef HAVE_WCHAR_H +# define HAVE_WCHAR_H +# endif +#endif + +#ifdef HAVE_WCHAR_H +/* Work around a cosmetic bug in BSDI 4.x wchar.h; thanks to Thomas Wouters */ +# ifdef _HAVE_BSDI +# include +# endif +# include +#endif + +/* + * Use this typedef when you need to represent a UTF-16 surrogate pair + * as single unsigned integer. + */ +#if SIZEOF_INT >= 4 +typedef unsigned int Py_UCS4; +#elif SIZEOF_LONG >= 4 +typedef unsigned long Py_UCS4; +#endif + +typedef PY_UNICODE_TYPE Py_UNICODE; + +/* --- UCS-2/UCS-4 Name Mangling ------------------------------------------ */ + +/* Unicode API names are mangled to assure that UCS-2 and UCS-4 builds + produce different external names and thus cause import errors in + case Python interpreters and extensions with mixed compiled in + Unicode width assumptions are combined. */ + +#ifndef Py_UNICODE_WIDE + +# define PyUnicode_AsASCIIString PyUnicodeUCS2_AsASCIIString +# define PyUnicode_AsCharmapString PyUnicodeUCS2_AsCharmapString +# define PyUnicode_AsEncodedObject PyUnicodeUCS2_AsEncodedObject +# define PyUnicode_AsEncodedString PyUnicodeUCS2_AsEncodedString +# define PyUnicode_AsLatin1String PyUnicodeUCS2_AsLatin1String +# define PyUnicode_AsRawUnicodeEscapeString PyUnicodeUCS2_AsRawUnicodeEscapeString +# define PyUnicode_AsUTF16String PyUnicodeUCS2_AsUTF16String +# define PyUnicode_AsUTF8String PyUnicodeUCS2_AsUTF8String +# define PyUnicode_AsUnicode PyUnicodeUCS2_AsUnicode +# define PyUnicode_AsUnicodeEscapeString PyUnicodeUCS2_AsUnicodeEscapeString +# define PyUnicode_AsWideChar PyUnicodeUCS2_AsWideChar +# define PyUnicode_Compare PyUnicodeUCS2_Compare +# define PyUnicode_Concat PyUnicodeUCS2_Concat +# define PyUnicode_Contains PyUnicodeUCS2_Contains +# define PyUnicode_Count PyUnicodeUCS2_Count +# define PyUnicode_Decode PyUnicodeUCS2_Decode +# define PyUnicode_DecodeASCII PyUnicodeUCS2_DecodeASCII +# define PyUnicode_DecodeCharmap PyUnicodeUCS2_DecodeCharmap +# define PyUnicode_DecodeLatin1 PyUnicodeUCS2_DecodeLatin1 +# define PyUnicode_DecodeRawUnicodeEscape PyUnicodeUCS2_DecodeRawUnicodeEscape +# define PyUnicode_DecodeUTF16 PyUnicodeUCS2_DecodeUTF16 +# define PyUnicode_DecodeUTF16Stateful PyUnicodeUCS2_DecodeUTF16Stateful +# define PyUnicode_DecodeUTF8 PyUnicodeUCS2_DecodeUTF8 +# define PyUnicode_DecodeUTF8Stateful PyUnicodeUCS2_DecodeUTF8Stateful +# define PyUnicode_DecodeUnicodeEscape PyUnicodeUCS2_DecodeUnicodeEscape +# define PyUnicode_Encode PyUnicodeUCS2_Encode +# define PyUnicode_EncodeASCII PyUnicodeUCS2_EncodeASCII +# define PyUnicode_EncodeCharmap PyUnicodeUCS2_EncodeCharmap +# define PyUnicode_EncodeDecimal PyUnicodeUCS2_EncodeDecimal +# define PyUnicode_EncodeLatin1 PyUnicodeUCS2_EncodeLatin1 +# define PyUnicode_EncodeRawUnicodeEscape PyUnicodeUCS2_EncodeRawUnicodeEscape +# define PyUnicode_EncodeUTF16 PyUnicodeUCS2_EncodeUTF16 +# define PyUnicode_EncodeUTF8 PyUnicodeUCS2_EncodeUTF8 +# define PyUnicode_EncodeUnicodeEscape PyUnicodeUCS2_EncodeUnicodeEscape +# define PyUnicode_Find PyUnicodeUCS2_Find +# define PyUnicode_Format PyUnicodeUCS2_Format +# define PyUnicode_FromEncodedObject PyUnicodeUCS2_FromEncodedObject +# define PyUnicode_FromObject PyUnicodeUCS2_FromObject +# define PyUnicode_FromOrdinal PyUnicodeUCS2_FromOrdinal +# define PyUnicode_FromUnicode PyUnicodeUCS2_FromUnicode +# define PyUnicode_FromWideChar PyUnicodeUCS2_FromWideChar +# define PyUnicode_GetDefaultEncoding PyUnicodeUCS2_GetDefaultEncoding +# define PyUnicode_GetMax PyUnicodeUCS2_GetMax +# define PyUnicode_GetSize PyUnicodeUCS2_GetSize +# define PyUnicode_Join PyUnicodeUCS2_Join +# define PyUnicode_Partition PyUnicodeUCS2_Partition +# define PyUnicode_RPartition PyUnicodeUCS2_RPartition +# define PyUnicode_RSplit PyUnicodeUCS2_RSplit +# define PyUnicode_Replace PyUnicodeUCS2_Replace +# define PyUnicode_Resize PyUnicodeUCS2_Resize +# define PyUnicode_RichCompare PyUnicodeUCS2_RichCompare +# define PyUnicode_SetDefaultEncoding PyUnicodeUCS2_SetDefaultEncoding +# define PyUnicode_Split PyUnicodeUCS2_Split +# define PyUnicode_Splitlines PyUnicodeUCS2_Splitlines +# define PyUnicode_Tailmatch PyUnicodeUCS2_Tailmatch +# define PyUnicode_Translate PyUnicodeUCS2_Translate +# define PyUnicode_TranslateCharmap PyUnicodeUCS2_TranslateCharmap +# define _PyUnicode_AsDefaultEncodedString _PyUnicodeUCS2_AsDefaultEncodedString +# define _PyUnicode_Fini _PyUnicodeUCS2_Fini +# define _PyUnicode_Init _PyUnicodeUCS2_Init +# define _PyUnicode_IsAlpha _PyUnicodeUCS2_IsAlpha +# define _PyUnicode_IsDecimalDigit _PyUnicodeUCS2_IsDecimalDigit +# define _PyUnicode_IsDigit _PyUnicodeUCS2_IsDigit +# define _PyUnicode_IsLinebreak _PyUnicodeUCS2_IsLinebreak +# define _PyUnicode_IsLowercase _PyUnicodeUCS2_IsLowercase +# define _PyUnicode_IsNumeric _PyUnicodeUCS2_IsNumeric +# define _PyUnicode_IsTitlecase _PyUnicodeUCS2_IsTitlecase +# define _PyUnicode_IsUppercase _PyUnicodeUCS2_IsUppercase +# define _PyUnicode_IsWhitespace _PyUnicodeUCS2_IsWhitespace +# define _PyUnicode_ToDecimalDigit _PyUnicodeUCS2_ToDecimalDigit +# define _PyUnicode_ToDigit _PyUnicodeUCS2_ToDigit +# define _PyUnicode_ToLowercase _PyUnicodeUCS2_ToLowercase +# define _PyUnicode_ToNumeric _PyUnicodeUCS2_ToNumeric +# define _PyUnicode_ToTitlecase _PyUnicodeUCS2_ToTitlecase +# define _PyUnicode_ToUppercase _PyUnicodeUCS2_ToUppercase + +#else + +# define PyUnicode_AsASCIIString PyUnicodeUCS4_AsASCIIString +# define PyUnicode_AsCharmapString PyUnicodeUCS4_AsCharmapString +# define PyUnicode_AsEncodedObject PyUnicodeUCS4_AsEncodedObject +# define PyUnicode_AsEncodedString PyUnicodeUCS4_AsEncodedString +# define PyUnicode_AsLatin1String PyUnicodeUCS4_AsLatin1String +# define PyUnicode_AsRawUnicodeEscapeString PyUnicodeUCS4_AsRawUnicodeEscapeString +# define PyUnicode_AsUTF16String PyUnicodeUCS4_AsUTF16String +# define PyUnicode_AsUTF8String PyUnicodeUCS4_AsUTF8String +# define PyUnicode_AsUnicode PyUnicodeUCS4_AsUnicode +# define PyUnicode_AsUnicodeEscapeString PyUnicodeUCS4_AsUnicodeEscapeString +# define PyUnicode_AsWideChar PyUnicodeUCS4_AsWideChar +# define PyUnicode_Compare PyUnicodeUCS4_Compare +# define PyUnicode_Concat PyUnicodeUCS4_Concat +# define PyUnicode_Contains PyUnicodeUCS4_Contains +# define PyUnicode_Count PyUnicodeUCS4_Count +# define PyUnicode_Decode PyUnicodeUCS4_Decode +# define PyUnicode_DecodeASCII PyUnicodeUCS4_DecodeASCII +# define PyUnicode_DecodeCharmap PyUnicodeUCS4_DecodeCharmap +# define PyUnicode_DecodeLatin1 PyUnicodeUCS4_DecodeLatin1 +# define PyUnicode_DecodeRawUnicodeEscape PyUnicodeUCS4_DecodeRawUnicodeEscape +# define PyUnicode_DecodeUTF16 PyUnicodeUCS4_DecodeUTF16 +# define PyUnicode_DecodeUTF16Stateful PyUnicodeUCS4_DecodeUTF16Stateful +# define PyUnicode_DecodeUTF8 PyUnicodeUCS4_DecodeUTF8 +# define PyUnicode_DecodeUTF8Stateful PyUnicodeUCS4_DecodeUTF8Stateful +# define PyUnicode_DecodeUnicodeEscape PyUnicodeUCS4_DecodeUnicodeEscape +# define PyUnicode_Encode PyUnicodeUCS4_Encode +# define PyUnicode_EncodeASCII PyUnicodeUCS4_EncodeASCII +# define PyUnicode_EncodeCharmap PyUnicodeUCS4_EncodeCharmap +# define PyUnicode_EncodeDecimal PyUnicodeUCS4_EncodeDecimal +# define PyUnicode_EncodeLatin1 PyUnicodeUCS4_EncodeLatin1 +# define PyUnicode_EncodeRawUnicodeEscape PyUnicodeUCS4_EncodeRawUnicodeEscape +# define PyUnicode_EncodeUTF16 PyUnicodeUCS4_EncodeUTF16 +# define PyUnicode_EncodeUTF8 PyUnicodeUCS4_EncodeUTF8 +# define PyUnicode_EncodeUnicodeEscape PyUnicodeUCS4_EncodeUnicodeEscape +# define PyUnicode_Find PyUnicodeUCS4_Find +# define PyUnicode_Format PyUnicodeUCS4_Format +# define PyUnicode_FromEncodedObject PyUnicodeUCS4_FromEncodedObject +# define PyUnicode_FromObject PyUnicodeUCS4_FromObject +# define PyUnicode_FromOrdinal PyUnicodeUCS4_FromOrdinal +# define PyUnicode_FromUnicode PyUnicodeUCS4_FromUnicode +# define PyUnicode_FromWideChar PyUnicodeUCS4_FromWideChar +# define PyUnicode_GetDefaultEncoding PyUnicodeUCS4_GetDefaultEncoding +# define PyUnicode_GetMax PyUnicodeUCS4_GetMax +# define PyUnicode_GetSize PyUnicodeUCS4_GetSize +# define PyUnicode_Join PyUnicodeUCS4_Join +# define PyUnicode_Partition PyUnicodeUCS4_Partition +# define PyUnicode_RPartition PyUnicodeUCS4_RPartition +# define PyUnicode_RSplit PyUnicodeUCS4_RSplit +# define PyUnicode_Replace PyUnicodeUCS4_Replace +# define PyUnicode_Resize PyUnicodeUCS4_Resize +# define PyUnicode_RichCompare PyUnicodeUCS4_RichCompare +# define PyUnicode_SetDefaultEncoding PyUnicodeUCS4_SetDefaultEncoding +# define PyUnicode_Split PyUnicodeUCS4_Split +# define PyUnicode_Splitlines PyUnicodeUCS4_Splitlines +# define PyUnicode_Tailmatch PyUnicodeUCS4_Tailmatch +# define PyUnicode_Translate PyUnicodeUCS4_Translate +# define PyUnicode_TranslateCharmap PyUnicodeUCS4_TranslateCharmap +# define _PyUnicode_AsDefaultEncodedString _PyUnicodeUCS4_AsDefaultEncodedString +# define _PyUnicode_Fini _PyUnicodeUCS4_Fini +# define _PyUnicode_Init _PyUnicodeUCS4_Init +# define _PyUnicode_IsAlpha _PyUnicodeUCS4_IsAlpha +# define _PyUnicode_IsDecimalDigit _PyUnicodeUCS4_IsDecimalDigit +# define _PyUnicode_IsDigit _PyUnicodeUCS4_IsDigit +# define _PyUnicode_IsLinebreak _PyUnicodeUCS4_IsLinebreak +# define _PyUnicode_IsLowercase _PyUnicodeUCS4_IsLowercase +# define _PyUnicode_IsNumeric _PyUnicodeUCS4_IsNumeric +# define _PyUnicode_IsTitlecase _PyUnicodeUCS4_IsTitlecase +# define _PyUnicode_IsUppercase _PyUnicodeUCS4_IsUppercase +# define _PyUnicode_IsWhitespace _PyUnicodeUCS4_IsWhitespace +# define _PyUnicode_ToDecimalDigit _PyUnicodeUCS4_ToDecimalDigit +# define _PyUnicode_ToDigit _PyUnicodeUCS4_ToDigit +# define _PyUnicode_ToLowercase _PyUnicodeUCS4_ToLowercase +# define _PyUnicode_ToNumeric _PyUnicodeUCS4_ToNumeric +# define _PyUnicode_ToTitlecase _PyUnicodeUCS4_ToTitlecase +# define _PyUnicode_ToUppercase _PyUnicodeUCS4_ToUppercase + + +#endif + +/* --- Internal Unicode Operations ---------------------------------------- */ + +/* If you want Python to use the compiler's wctype.h functions instead + of the ones supplied with Python, define WANT_WCTYPE_FUNCTIONS or + configure Python using --with-wctype-functions. This reduces the + interpreter's code size. */ + +#if defined(HAVE_USABLE_WCHAR_T) && defined(WANT_WCTYPE_FUNCTIONS) + +#include + +#define Py_UNICODE_ISSPACE(ch) iswspace(ch) + +#define Py_UNICODE_ISLOWER(ch) iswlower(ch) +#define Py_UNICODE_ISUPPER(ch) iswupper(ch) +#define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch) +#define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch) + +#define Py_UNICODE_TOLOWER(ch) towlower(ch) +#define Py_UNICODE_TOUPPER(ch) towupper(ch) +#define Py_UNICODE_TOTITLE(ch) _PyUnicode_ToTitlecase(ch) + +#define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch) +#define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch) +#define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch) + +#define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch) +#define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch) +#define Py_UNICODE_TONUMERIC(ch) _PyUnicode_ToNumeric(ch) + +#define Py_UNICODE_ISALPHA(ch) iswalpha(ch) + +#else + +#define Py_UNICODE_ISSPACE(ch) _PyUnicode_IsWhitespace(ch) + +#define Py_UNICODE_ISLOWER(ch) _PyUnicode_IsLowercase(ch) +#define Py_UNICODE_ISUPPER(ch) _PyUnicode_IsUppercase(ch) +#define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch) +#define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch) + +#define Py_UNICODE_TOLOWER(ch) _PyUnicode_ToLowercase(ch) +#define Py_UNICODE_TOUPPER(ch) _PyUnicode_ToUppercase(ch) +#define Py_UNICODE_TOTITLE(ch) _PyUnicode_ToTitlecase(ch) + +#define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch) +#define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch) +#define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch) + +#define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch) +#define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch) +#define Py_UNICODE_TONUMERIC(ch) _PyUnicode_ToNumeric(ch) + +#define Py_UNICODE_ISALPHA(ch) _PyUnicode_IsAlpha(ch) + +#endif + +#define Py_UNICODE_ISALNUM(ch) \ + (Py_UNICODE_ISALPHA(ch) || \ + Py_UNICODE_ISDECIMAL(ch) || \ + Py_UNICODE_ISDIGIT(ch) || \ + Py_UNICODE_ISNUMERIC(ch)) + +#define Py_UNICODE_COPY(target, source, length) \ + Py_MEMCPY((target), (source), (length)*sizeof(Py_UNICODE)) + +#define Py_UNICODE_FILL(target, value, length) do\ + {Py_ssize_t i_; Py_UNICODE *t_ = (target); Py_UNICODE v_ = (value);\ + for (i_ = 0; i_ < (length); i_++) t_[i_] = v_;\ + } while (0) + +/* check if substring matches at given offset. the offset must be + valid, and the substring must not be empty */ +#define Py_UNICODE_MATCH(string, offset, substring) \ + ((*((string)->str + (offset)) == *((substring)->str)) && \ + ((*((string)->str + (offset) + (substring)->length-1) == *((substring)->str + (substring)->length-1))) && \ + !memcmp((string)->str + (offset), (substring)->str, (substring)->length*sizeof(Py_UNICODE))) + +#ifdef __cplusplus +extern "C" { +#endif + +/* --- Unicode Type ------------------------------------------------------- */ + +typedef struct { + PyObject_HEAD + Py_ssize_t length; /* Length of raw Unicode data in buffer */ + Py_UNICODE *str; /* Raw Unicode buffer */ + long hash; /* Hash value; -1 if not set */ + PyObject *defenc; /* (Default) Encoded version as Python + string, or NULL; this is used for + implementing the buffer protocol */ +} PyUnicodeObject; + +PyAPI_DATA(PyTypeObject) PyUnicode_Type; + +#define PyUnicode_Check(op) PyObject_TypeCheck(op, &PyUnicode_Type) +#define PyUnicode_CheckExact(op) ((op)->ob_type == &PyUnicode_Type) + +/* Fast access macros */ +#define PyUnicode_GET_SIZE(op) \ + (((PyUnicodeObject *)(op))->length) +#define PyUnicode_GET_DATA_SIZE(op) \ + (((PyUnicodeObject *)(op))->length * sizeof(Py_UNICODE)) +#define PyUnicode_AS_UNICODE(op) \ + (((PyUnicodeObject *)(op))->str) +#define PyUnicode_AS_DATA(op) \ + ((const char *)((PyUnicodeObject *)(op))->str) + +/* --- Constants ---------------------------------------------------------- */ + +/* This Unicode character will be used as replacement character during + decoding if the errors argument is set to "replace". Note: the + Unicode character U+FFFD is the official REPLACEMENT CHARACTER in + Unicode 3.0. */ + +#define Py_UNICODE_REPLACEMENT_CHARACTER ((Py_UNICODE) 0xFFFD) + +/* === Public API ========================================================= */ + +/* --- Plain Py_UNICODE --------------------------------------------------- */ + +/* Create a Unicode Object from the Py_UNICODE buffer u of the given + size. + + u may be NULL which causes the contents to be undefined. It is the + user's responsibility to fill in the needed data afterwards. Note + that modifying the Unicode object contents after construction is + only allowed if u was set to NULL. + + The buffer is copied into the new object. */ + +PyAPI_FUNC(PyObject*) PyUnicode_FromUnicode( + const Py_UNICODE *u, /* Unicode buffer */ + Py_ssize_t size /* size of buffer */ + ); + +/* Return a read-only pointer to the Unicode object's internal + Py_UNICODE buffer. */ + +PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode( + PyObject *unicode /* Unicode object */ + ); + +/* Get the length of the Unicode object. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_GetSize( + PyObject *unicode /* Unicode object */ + ); + +/* Get the maximum ordinal for a Unicode character. */ +PyAPI_FUNC(Py_UNICODE) PyUnicode_GetMax(void); + +/* Resize an already allocated Unicode object to the new size length. + + *unicode is modified to point to the new (resized) object and 0 + returned on success. + + This API may only be called by the function which also called the + Unicode constructor. The refcount on the object must be 1. Otherwise, + an error is returned. + + Error handling is implemented as follows: an exception is set, -1 + is returned and *unicode left untouched. + +*/ + +PyAPI_FUNC(int) PyUnicode_Resize( + PyObject **unicode, /* Pointer to the Unicode object */ + Py_ssize_t length /* New length */ + ); + +/* Coerce obj to an Unicode object and return a reference with + *incremented* refcount. + + Coercion is done in the following way: + + 1. String and other char buffer compatible objects are decoded + under the assumptions that they contain data using the current + default encoding. Decoding is done in "strict" mode. + + 2. All other objects (including Unicode objects) raise an + exception. + + The API returns NULL in case of an error. The caller is responsible + for decref'ing the returned objects. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_FromEncodedObject( + register PyObject *obj, /* Object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Coerce obj to an Unicode object and return a reference with + *incremented* refcount. + + Unicode objects are passed back as-is (subclasses are converted to + true Unicode objects), all other objects are delegated to + PyUnicode_FromEncodedObject(obj, NULL, "strict") which results in + using the default encoding as basis for decoding the object. + + The API returns NULL in case of an error. The caller is responsible + for decref'ing the returned objects. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_FromObject( + register PyObject *obj /* Object */ + ); + +/* --- wchar_t support for platforms which support it --------------------- */ + +#ifdef HAVE_WCHAR_H + +/* Create a Unicode Object from the whcar_t buffer w of the given + size. + + The buffer is copied into the new object. */ + +PyAPI_FUNC(PyObject*) PyUnicode_FromWideChar( + register const wchar_t *w, /* wchar_t buffer */ + Py_ssize_t size /* size of buffer */ + ); + +/* Copies the Unicode Object contents into the wchar_t buffer w. At + most size wchar_t characters are copied. + + Note that the resulting wchar_t string may or may not be + 0-terminated. It is the responsibility of the caller to make sure + that the wchar_t string is 0-terminated in case this is required by + the application. + + Returns the number of wchar_t characters copied (excluding a + possibly trailing 0-termination character) or -1 in case of an + error. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_AsWideChar( + PyUnicodeObject *unicode, /* Unicode object */ + register wchar_t *w, /* wchar_t buffer */ + Py_ssize_t size /* size of buffer */ + ); + +#endif + +/* --- Unicode ordinals --------------------------------------------------- */ + +/* Create a Unicode Object from the given Unicode code point ordinal. + + The ordinal must be in range(0x10000) on narrow Python builds + (UCS2), and range(0x110000) on wide builds (UCS4). A ValueError is + raised in case it is not. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_FromOrdinal(int ordinal); + +/* === Builtin Codecs ===================================================== + + Many of these APIs take two arguments encoding and errors. These + parameters encoding and errors have the same semantics as the ones + of the builtin unicode() API. + + Setting encoding to NULL causes the default encoding to be used. + + Error handling is set by errors which may also be set to NULL + meaning to use the default handling defined for the codec. Default + error handling for all builtin codecs is "strict" (ValueErrors are + raised). + + The codecs all use a similar interface. Only deviation from the + generic ones are documented. + +*/ + +/* --- Manage the default encoding ---------------------------------------- */ + +/* Return a Python string holding the default encoded value of the + Unicode object. + + The resulting string is cached in the Unicode object for subsequent + usage by this function. The cached version is needed to implement + the character buffer interface and will live (at least) as long as + the Unicode object itself. + + The refcount of the string is *not* incremented. + + *** Exported for internal use by the interpreter only !!! *** + +*/ + +PyAPI_FUNC(PyObject *) _PyUnicode_AsDefaultEncodedString( + PyObject *, const char *); + +/* Returns the currently active default encoding. + + The default encoding is currently implemented as run-time settable + process global. This may change in future versions of the + interpreter to become a parameter which is managed on a per-thread + basis. + + */ + +PyAPI_FUNC(const char*) PyUnicode_GetDefaultEncoding(void); + +/* Sets the currently active default encoding. + + Returns 0 on success, -1 in case of an error. + + */ + +PyAPI_FUNC(int) PyUnicode_SetDefaultEncoding( + const char *encoding /* Encoding name in standard form */ + ); + +/* --- Generic Codecs ----------------------------------------------------- */ + +/* Create a Unicode object by decoding the encoded string s of the + given size. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Decode( + const char *s, /* encoded string */ + Py_ssize_t size, /* size of buffer */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Encodes a Py_UNICODE buffer of the given size and returns a + Python string object. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Encode( + const Py_UNICODE *s, /* Unicode char buffer */ + Py_ssize_t size, /* number of Py_UNICODE chars to encode */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Encodes a Unicode object and returns the result as Python + object. */ + +PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedObject( + PyObject *unicode, /* Unicode object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Encodes a Unicode object and returns the result as Python string + object. */ + +PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedString( + PyObject *unicode, /* Unicode object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_BuildEncodingMap( + PyObject* string /* 256 character map */ + ); + + +/* --- UTF-7 Codecs ------------------------------------------------------- */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF7( + const char *string, /* UTF-7 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF7( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* number of Py_UNICODE chars to encode */ + int encodeSetO, /* force the encoder to encode characters in + Set O, as described in RFC2152 */ + int encodeWhiteSpace, /* force the encoder to encode space, tab, + carriage return and linefeed characters */ + const char *errors /* error handling */ + ); + +/* --- UTF-8 Codecs ------------------------------------------------------- */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF8( + const char *string, /* UTF-8 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF8Stateful( + const char *string, /* UTF-8 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + Py_ssize_t *consumed /* bytes consumed */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsUTF8String( + PyObject *unicode /* Unicode object */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF8( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* number of Py_UNICODE chars to encode */ + const char *errors /* error handling */ + ); + +/* --- UTF-16 Codecs ------------------------------------------------------ */ + +/* Decodes length bytes from a UTF-16 encoded buffer string and returns + the corresponding Unicode object. + + errors (if non-NULL) defines the error handling. It defaults + to "strict". + + If byteorder is non-NULL, the decoder starts decoding using the + given byte order: + + *byteorder == -1: little endian + *byteorder == 0: native order + *byteorder == 1: big endian + + In native mode, the first two bytes of the stream are checked for a + BOM mark. If found, the BOM mark is analysed, the byte order + adjusted and the BOM skipped. In the other modes, no BOM mark + interpretation is done. After completion, *byteorder is set to the + current byte order at the end of input data. + + If byteorder is NULL, the codec starts in native order mode. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF16( + const char *string, /* UTF-16 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + int *byteorder /* pointer to byteorder to use + 0=native;-1=LE,1=BE; updated on + exit */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF16Stateful( + const char *string, /* UTF-16 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + int *byteorder, /* pointer to byteorder to use + 0=native;-1=LE,1=BE; updated on + exit */ + Py_ssize_t *consumed /* bytes consumed */ + ); + +/* Returns a Python string using the UTF-16 encoding in native byte + order. The string always starts with a BOM mark. */ + +PyAPI_FUNC(PyObject*) PyUnicode_AsUTF16String( + PyObject *unicode /* Unicode object */ + ); + +/* Returns a Python string object holding the UTF-16 encoded value of + the Unicode data. + + If byteorder is not 0, output is written according to the following + byte order: + + byteorder == -1: little endian + byteorder == 0: native byte order (writes a BOM mark) + byteorder == 1: big endian + + If byteorder is 0, the output string will always start with the + Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark is + prepended. + + Note that Py_UNICODE data is being interpreted as UTF-16 reduced to + UCS-2. This trick makes it possible to add full UTF-16 capabilities + at a later point without compromising the APIs. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF16( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* number of Py_UNICODE chars to encode */ + const char *errors, /* error handling */ + int byteorder /* byteorder to use 0=BOM+native;-1=LE,1=BE */ + ); + +/* --- Unicode-Escape Codecs ---------------------------------------------- */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUnicodeEscape( + const char *string, /* Unicode-Escape encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsUnicodeEscapeString( + PyObject *unicode /* Unicode object */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeUnicodeEscape( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length /* Number of Py_UNICODE chars to encode */ + ); + +/* --- Raw-Unicode-Escape Codecs ------------------------------------------ */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeRawUnicodeEscape( + const char *string, /* Raw-Unicode-Escape encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsRawUnicodeEscapeString( + PyObject *unicode /* Unicode object */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeRawUnicodeEscape( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length /* Number of Py_UNICODE chars to encode */ + ); + +/* --- Unicode Internal Codec --------------------------------------------- + + Only for internal use in _codecsmodule.c */ + +PyObject *_PyUnicode_DecodeUnicodeInternal( + const char *string, + Py_ssize_t length, + const char *errors + ); + +/* --- Latin-1 Codecs ----------------------------------------------------- + + Note: Latin-1 corresponds to the first 256 Unicode ordinals. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeLatin1( + const char *string, /* Latin-1 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsLatin1String( + PyObject *unicode /* Unicode object */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeLatin1( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + const char *errors /* error handling */ + ); + +/* --- ASCII Codecs ------------------------------------------------------- + + Only 7-bit ASCII data is excepted. All other codes generate errors. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeASCII( + const char *string, /* ASCII encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsASCIIString( + PyObject *unicode /* Unicode object */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeASCII( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + const char *errors /* error handling */ + ); + +/* --- Character Map Codecs ----------------------------------------------- + + This codec uses mappings to encode and decode characters. + + Decoding mappings must map single string characters to single + Unicode characters, integers (which are then interpreted as Unicode + ordinals) or None (meaning "undefined mapping" and causing an + error). + + Encoding mappings must map single Unicode characters to single + string characters, integers (which are then interpreted as Latin-1 + ordinals) or None (meaning "undefined mapping" and causing an + error). + + If a character lookup fails with a LookupError, the character is + copied as-is meaning that its ordinal value will be interpreted as + Unicode or Latin-1 ordinal resp. Because of this mappings only need + to contain those mappings which map characters to different code + points. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeCharmap( + const char *string, /* Encoded string */ + Py_ssize_t length, /* size of string */ + PyObject *mapping, /* character mapping + (char ordinal -> unicode ordinal) */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsCharmapString( + PyObject *unicode, /* Unicode object */ + PyObject *mapping /* character mapping + (unicode ordinal -> char ordinal) */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeCharmap( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + PyObject *mapping, /* character mapping + (unicode ordinal -> char ordinal) */ + const char *errors /* error handling */ + ); + +/* Translate a Py_UNICODE buffer of the given length by applying a + character mapping table to it and return the resulting Unicode + object. + + The mapping table must map Unicode ordinal integers to Unicode + ordinal integers or None (causing deletion of the character). + + Mapping tables may be dictionaries or sequences. Unmapped character + ordinals (ones which cause a LookupError) are left untouched and + are copied as-is. + +*/ + +PyAPI_FUNC(PyObject *) PyUnicode_TranslateCharmap( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + PyObject *table, /* Translate table */ + const char *errors /* error handling */ + ); + +#ifdef MS_WIN32 + +/* --- MBCS codecs for Windows -------------------------------------------- */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeMBCS( + const char *string, /* MBCS encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeMBCSStateful( + const char *string, /* MBCS encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + Py_ssize_t *consumed /* bytes consumed */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsMBCSString( + PyObject *unicode /* Unicode object */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeMBCS( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + const char *errors /* error handling */ + ); + +#endif /* MS_WIN32 */ + +/* --- Decimal Encoder ---------------------------------------------------- */ + +/* Takes a Unicode string holding a decimal value and writes it into + an output buffer using standard ASCII digit codes. + + The output buffer has to provide at least length+1 bytes of storage + area. The output string is 0-terminated. + + The encoder converts whitespace to ' ', decimal characters to their + corresponding ASCII digit and all other Latin-1 characters except + \0 as-is. Characters outside this range (Unicode ordinals 1-256) + are treated as errors. This includes embedded NULL bytes. + + Error handling is defined by the errors argument: + + NULL or "strict": raise a ValueError + "ignore": ignore the wrong characters (these are not copied to the + output buffer) + "replace": replaces illegal characters with '?' + + Returns 0 on success, -1 on failure. + +*/ + +PyAPI_FUNC(int) PyUnicode_EncodeDecimal( + Py_UNICODE *s, /* Unicode buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + char *output, /* Output buffer; must have size >= length */ + const char *errors /* error handling */ + ); + +/* --- Methods & Slots ---------------------------------------------------- + + These are capable of handling Unicode objects and strings on input + (we refer to them as strings in the descriptions) and return + Unicode objects or integers as apporpriate. */ + +/* Concat two strings giving a new Unicode string. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Concat( + PyObject *left, /* Left string */ + PyObject *right /* Right string */ + ); + +/* Split a string giving a list of Unicode strings. + + If sep is NULL, splitting will be done at all whitespace + substrings. Otherwise, splits occur at the given separator. + + At most maxsplit splits will be done. If negative, no limit is set. + + Separators are not included in the resulting list. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_Split( + PyObject *s, /* String to split */ + PyObject *sep, /* String separator */ + Py_ssize_t maxsplit /* Maxsplit count */ + ); + +/* Dito, but split at line breaks. + + CRLF is considered to be one line break. Line breaks are not + included in the resulting list. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Splitlines( + PyObject *s, /* String to split */ + int keepends /* If true, line end markers are included */ + ); + +/* Partition a string using a given separator. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Partition( + PyObject *s, /* String to partition */ + PyObject *sep /* String separator */ + ); + +/* Partition a string using a given separator, searching from the end of the + string. */ + +PyAPI_FUNC(PyObject*) PyUnicode_RPartition( + PyObject *s, /* String to partition */ + PyObject *sep /* String separator */ + ); + +/* Split a string giving a list of Unicode strings. + + If sep is NULL, splitting will be done at all whitespace + substrings. Otherwise, splits occur at the given separator. + + At most maxsplit splits will be done. But unlike PyUnicode_Split + PyUnicode_RSplit splits from the end of the string. If negative, + no limit is set. + + Separators are not included in the resulting list. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_RSplit( + PyObject *s, /* String to split */ + PyObject *sep, /* String separator */ + Py_ssize_t maxsplit /* Maxsplit count */ + ); + +/* Translate a string by applying a character mapping table to it and + return the resulting Unicode object. + + The mapping table must map Unicode ordinal integers to Unicode + ordinal integers or None (causing deletion of the character). + + Mapping tables may be dictionaries or sequences. Unmapped character + ordinals (ones which cause a LookupError) are left untouched and + are copied as-is. + +*/ + +PyAPI_FUNC(PyObject *) PyUnicode_Translate( + PyObject *str, /* String */ + PyObject *table, /* Translate table */ + const char *errors /* error handling */ + ); + +/* Join a sequence of strings using the given separator and return + the resulting Unicode string. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Join( + PyObject *separator, /* Separator string */ + PyObject *seq /* Sequence object */ + ); + +/* Return 1 if substr matches str[start:end] at the given tail end, 0 + otherwise. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_Tailmatch( + PyObject *str, /* String */ + PyObject *substr, /* Prefix or Suffix string */ + Py_ssize_t start, /* Start index */ + Py_ssize_t end, /* Stop index */ + int direction /* Tail end: -1 prefix, +1 suffix */ + ); + +/* Return the first position of substr in str[start:end] using the + given search direction or -1 if not found. -2 is returned in case + an error occurred and an exception is set. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_Find( + PyObject *str, /* String */ + PyObject *substr, /* Substring to find */ + Py_ssize_t start, /* Start index */ + Py_ssize_t end, /* Stop index */ + int direction /* Find direction: +1 forward, -1 backward */ + ); + +/* Count the number of occurrences of substr in str[start:end]. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_Count( + PyObject *str, /* String */ + PyObject *substr, /* Substring to count */ + Py_ssize_t start, /* Start index */ + Py_ssize_t end /* Stop index */ + ); + +/* Replace at most maxcount occurrences of substr in str with replstr + and return the resulting Unicode object. */ + +PyAPI_FUNC(PyObject *) PyUnicode_Replace( + PyObject *str, /* String */ + PyObject *substr, /* Substring to find */ + PyObject *replstr, /* Substring to replace */ + Py_ssize_t maxcount /* Max. number of replacements to apply; + -1 = all */ + ); + +/* Compare two strings and return -1, 0, 1 for less than, equal, + greater than resp. */ + +PyAPI_FUNC(int) PyUnicode_Compare( + PyObject *left, /* Left string */ + PyObject *right /* Right string */ + ); + +/* Rich compare two strings and return one of the following: + + - NULL in case an exception was raised + - Py_True or Py_False for successfuly comparisons + - Py_NotImplemented in case the type combination is unknown + + Note that Py_EQ and Py_NE comparisons can cause a UnicodeWarning in + case the conversion of the arguments to Unicode fails with a + UnicodeDecodeError. + + Possible values for op: + + Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE + +*/ + +PyAPI_FUNC(PyObject *) PyUnicode_RichCompare( + PyObject *left, /* Left string */ + PyObject *right, /* Right string */ + int op /* Operation: Py_EQ, Py_NE, Py_GT, etc. */ + ); + +/* Apply a argument tuple or dictionary to a format string and return + the resulting Unicode string. */ + +PyAPI_FUNC(PyObject *) PyUnicode_Format( + PyObject *format, /* Format string */ + PyObject *args /* Argument tuple or dictionary */ + ); + +/* Checks whether element is contained in container and return 1/0 + accordingly. + + element has to coerce to an one element Unicode string. -1 is + returned in case of an error. */ + +PyAPI_FUNC(int) PyUnicode_Contains( + PyObject *container, /* Container string */ + PyObject *element /* Element string */ + ); + +/* Externally visible for str.strip(unicode) */ +PyAPI_FUNC(PyObject *) _PyUnicode_XStrip( + PyUnicodeObject *self, + int striptype, + PyObject *sepobj + ); + +/* === Characters Type APIs =============================================== */ + +/* These should not be used directly. Use the Py_UNICODE_IS* and + Py_UNICODE_TO* macros instead. + + These APIs are implemented in Objects/unicodectype.c. + +*/ + +PyAPI_FUNC(int) _PyUnicode_IsLowercase( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsUppercase( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsTitlecase( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsWhitespace( + const Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsLinebreak( + const Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(Py_UNICODE) _PyUnicode_ToLowercase( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(Py_UNICODE) _PyUnicode_ToUppercase( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(Py_UNICODE) _PyUnicode_ToTitlecase( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_ToDecimalDigit( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_ToDigit( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(double) _PyUnicode_ToNumeric( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsDecimalDigit( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsDigit( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsNumeric( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsAlpha( + Py_UNICODE ch /* Unicode character */ + ); + +#ifdef __cplusplus +} +#endif +#endif /* Py_USING_UNICODE */ +#endif /* !Py_UNICODEOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/include/weakrefobject.h b/vscript/languages/python/python-2.5.1/include/weakrefobject.h new file mode 100644 index 00000000..0a659b02 --- /dev/null +++ b/vscript/languages/python/python-2.5.1/include/weakrefobject.h @@ -0,0 +1,75 @@ +/* Weak references objects for Python. */ + +#ifndef Py_WEAKREFOBJECT_H +#define Py_WEAKREFOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct _PyWeakReference PyWeakReference; + +/* PyWeakReference is the base struct for the Python ReferenceType, ProxyType, + * and CallableProxyType. + */ +struct _PyWeakReference { + PyObject_HEAD + + /* The object to which this is a weak reference, or Py_None if none. + * Note that this is a stealth reference: wr_object's refcount is + * not incremented to reflect this pointer. + */ + PyObject *wr_object; + + /* A callable to invoke when wr_object dies, or NULL if none. */ + PyObject *wr_callback; + + /* A cache for wr_object's hash code. As usual for hashes, this is -1 + * if the hash code isn't known yet. + */ + long hash; + + /* If wr_object is weakly referenced, wr_object has a doubly-linked NULL- + * terminated list of weak references to it. These are the list pointers. + * If wr_object goes away, wr_object is set to Py_None, and these pointers + * have no meaning then. + */ + PyWeakReference *wr_prev; + PyWeakReference *wr_next; +}; + +PyAPI_DATA(PyTypeObject) _PyWeakref_RefType; +PyAPI_DATA(PyTypeObject) _PyWeakref_ProxyType; +PyAPI_DATA(PyTypeObject) _PyWeakref_CallableProxyType; + +#define PyWeakref_CheckRef(op) PyObject_TypeCheck(op, &_PyWeakref_RefType) +#define PyWeakref_CheckRefExact(op) \ + ((op)->ob_type == &_PyWeakref_RefType) +#define PyWeakref_CheckProxy(op) \ + (((op)->ob_type == &_PyWeakref_ProxyType) || \ + ((op)->ob_type == &_PyWeakref_CallableProxyType)) + +/* This macro calls PyWeakref_CheckRef() last since that can involve a + function call; this makes it more likely that the function call + will be avoided. */ +#define PyWeakref_Check(op) \ + (PyWeakref_CheckRef(op) || PyWeakref_CheckProxy(op)) + + +PyAPI_FUNC(PyObject *) PyWeakref_NewRef(PyObject *ob, + PyObject *callback); +PyAPI_FUNC(PyObject *) PyWeakref_NewProxy(PyObject *ob, + PyObject *callback); +PyAPI_FUNC(PyObject *) PyWeakref_GetObject(PyObject *ref); + +PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head); + +PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self); + +#define PyWeakref_GET_OBJECT(ref) (((PyWeakReference *)(ref))->wr_object) + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_WEAKREFOBJECT_H */ diff --git a/vscript/languages/python/python-2.5.1/win32release/python.exe b/vscript/languages/python/python-2.5.1/win32release/python.exe new file mode 100644 index 0000000000000000000000000000000000000000..d3645a115aae3dcc750707c083dd772f79ed76fa GIT binary patch literal 26624 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 literal 0 HcmV?d00001 diff --git a/vscript/languages/python/python-2.5.1/win32release/python25.lib b/vscript/languages/python/python-2.5.1/win32release/python25.lib new file mode 100644 index 0000000000000000000000000000000000000000..f348ee3b21e5bea4c9b3b2f6670a6b2d59ff2b3e GIT binary patch literal 199302 zcmdSC3v^vY6+b*P7b_wnA|fIpA|j$qm|MmaY`o6BUdvo?{ z_Uw6{nK^r2aa3=kZ}8|{-mriC?~RiVn>c0S?AvZ9<(~V|e*2p$KN3#IWR2p$HDdGr^RD7*04+D1s9qNAQYu481oCMewEz z8D4d?Pz3wz!SJr9g(B#k!*KA`LJ_?54u*~;LJ=Ht3PaCcLJ{l-9KkV9KdkEE$oQ5OjwTfuO^Hsk{^bt=P&52F47 z_J_|1UV}6Ma`_D!)Xy&w8gAK3RGvLq$oHar0F?=y_`O%iGY@1~d5n+*XI{pz@>)Ct zR;>l>%kZIFg(O(Jh2cYs@eDZobwd4U5yOp-3k8rjJ;m_thL8j|gOA|4rx|W|Mo5C2 z?_l`$Bj9^PRGx+3@4ya%>(16t5$lA!5%v;%<7kGPU>CuSu!rClv}JU6^PWVy1iK?&u$kb)R~VRx--$x)y+ngtJ_q%9j!<{37Zr6k!?Q0(T?XvDs|I-y zWC%Wf6T>I=5mLkX_yt@9-GIt-HfWIRCP1!b;C}o9o-18eXLxa1CoPeB%-?nONV$j{uz@YyHv{3yfxYlQq9 z?EcDr3|CDOl3@K)3|~G-NP;V7GF){z=zy!HRkS05dy$VHqC7v0u>l}|eu$8F5L_wL zM{m|3e}0jWKZWcMW(j#K%HwDE3VEl3+*v~YWFzo53wh6tLVa>?hVyR|3LrP#Bh<$a z)F6Md2s)kupl*HQVup`&3Ptd-4I1P<#|e2C(p?8SKzi>`Tf1{ z_f;C?kKu#wP5|#5A@4>VynR5(+t7wSxlV)p*@@s^i+o_r0La@eh3${Prpq#hN93-USu{<}5E+wT?X zm+%F_hwsxM?`$EDlQhV?P?vuA1a$4kaKRL$3*3*8haaDZ-y4vBqydn>fPV?@JDlNO z)Fps=)4m$yuV5R&FL!6S?=tWKezBP0mnb8Gd*K^`Up@hT_ynLFY{K80g#69JLjD?U zl;AfFhF_!J5!`>E2KDPB1%bRD^^@Q?LWBC{7UY-UEDiF3TZD!O9~bhslNcW81P<`q zD;OR`{nM}pziXfuWeSjwtrGHKx&{;ADnJrVFXzI{aQI)LSlPIPw;u2>yirm*COI4Xna1;4OzTJh~g6 zcN6ka_>$mHC*T*h5}ba$26Ye0n&9ULYmo1`Oc1D_!G8dG`b-V#XE)*bCeS8oPv0>;TBe z4;At+!wi4EKu8Vy;ur8&_@7`4@=Nfi+cc>A(Ov=aFAr%@zj+X8J&5$TG5j4e1lzz* z@We?B|7ZzGu&tY6>+6IBs0a7cAh%wGXTTFki{KwSG5j5EkKi8yYZd?`0p7E z&m0b2fd8PK6a4#VhNqtZ{}V#(bOJ+Vvrq&N-6+(vu40&QflvgZli^{s2ZCqs%J3}M zOYkt-Ccy;s8w8cp86KJkeSqJ?PXy0iiC@%H0&z2gS|b#JyqKY)APabS4~9RWFCkF7 zF+8{p`3J~D7@ z_$mBFuqVNu-YMX#jkjx%Uq`*wFpA$%q4v6(;l*q5i}pkC z;(ZzZfOH66WZ;p*g?jzYLLG|s^m^oLAKd)nW8|Vbjzk%WCTk+lp_#?`k;7|839J31V+kihG%+LWm!OV#aZym;a zC*a$tZyI3h#*-MHxB|N8FwEM7^#s5a)Kh|K`)R1Ce#~iM|1o_+#T-{+cc=7 z*5DcN_kDz#KFIL*^YILr4m$|8PGHy<`5}1oqYOV@iM#{$h3^P9-^8%nL#R6s;a%%= zQK?)dHfMX2K@~GiEVNI~(=`rfy(3vK!+DU>eGX;I4~> zI_@F^2jUm-cHlLv!Y{$D8svCGFzke1z>0$mti$g*q5cND0rJsZHK;S7hu}TyHOPNG zCK#6C7x3iS8q|AF5gPtB6MTm-U~EzZ?}ZNtPM^+j##-oH3%NZQ{&}&G0QLA?&?z*i zGxh|}o^7v=DVsRpjYFW}I77#1RZg02G?7QhaIcie9Pw08iy;b($Q*g)_d z}3S)MbGD;)xp6xA%rF zq(iXiR)+7uPJsM8`Zj?2!6UHcDu%^-2?dZ}yj_FZv>VFjR}Aw}hW$5ckiXj`)L#}G zfM5OssGiI4*cPnA0Qw+H&_9o%??F5hEMur{1wZ=R-@#UZs>1gK11F(B0}nv1M|}gR z*8#8LBK!hgJ4=Jya2ei%E)#0$H4KBu?^5`ZU<>jLsL0jO3Htz&+Qg|hFw~C{ir}w% zGBl6FGxQLga+d+*@f5%aY$Z5tH-;@&LN{Ot`5`zJ_7DsWGMx4__y8k&Ff!a3VR)iY1b^MeFnWMc1hqRE8V^7YFtSQRZ5v<(EaMr_k2AsLU0Ma}YuzD)P z``|Nz_us+rKG;mK3jQN_Kgx|@)x`|&gAWN--@x$1B%ugCa4ExMJK+~)L9k|bh7X>M zU&v^99KV3GHwpE@yBOA9B^1GjRx_M^66k;rfsbJ884MrV2hV`DM=_j>^49?Wo^!Yc zN&V|N@E<|za?tl?*t!`y08j15@Z<)e2%c69+u%cjC#NuMTYzW4Kc_SNdv~D-{&7FU zzt#&y@HA{A_}3u}|GXLefPbIO@D%(;@VUzvJ_S6%#TPJqVVO__*RNo>ZhxT&o<^Av zT#CFATzd<{h6jZrxcp#-8#;x$Y!kz!4e$c42S34;r!ZW7q)-H(Lb(!r5p{>)bNe!U z_9&qUzKr}3d}%tv*Y^~P;M!vtu30A(!3NYXg0FTneBp8A0q~WT3}3nx@_^64PJ++F zZvo;Fsk^;LW33^iNOF*GvTQ$%-;&l?+AQf>6iu5}Lg z_EkG-{hl{N>KvcHwCXt{WRQ0E*ywP;=4>+fH1);xhSwRVu1PNSX(OYa z(Il>MLE6&>t9_?>E|<2!2b|NZ!(GEeeK|utDYbQesi{N>w0BioW!gQ-<*cK*pxWC% zb!=du8YEz{7!w1Ff&zAK1I}@DENRw<$67%S4Vxzf79-QMTh)<_?;IuIMkY$Q9mUzv zSzjJz%NSv>jw>lS!{y4&IAeCRYivp1aBs8e4b708*6zkwb^6e7cCFd!MRU#M#gmG*O{>@X+Sz95&bGN@!>ysw z;c=giajz!?sg!2j5&~YERH3J_gn)NWwYIc1=xuN=wFGBxM}M(H(zrld*U;&K-<&Q+ zJ54B%k$O>?MTdO3I^xRH7234k;o-SebkhAjlvKCP4w{|qk_sFyl{xj=QY(-kGvd(K z(O6on=-vd!;gq3uv>LsALB%yC?Fo)I*X?VZvnBSi$)ELbklmSMwZ7I+z2@_lCAyU7 zGzW(UiZ)ubsZTa6)NcXPcMf@mAZBBXy0%r*``B&Pv2) zdb+ogW|VEFXS#etx|3v|1ult7TF)2b)N{k0DK9hn84VrHX@k9u()nUYbkS&O?oUhtfqaIF)N%y~V8&n+ao&!w24R z{f^~z<~T~gJ*_@g3p#tpYw)Sve%4{N$Ci7#v)#{b3hsgOLbB~@0&;jl+N*v zuI`?hjrz#Edic7OU^~aBjt${;qK4IjAy*aPz8t!9yl3XnaJ6f^iC4?%)q!5Th|H+< z)%$}{7@|EVR2y})>oJVfuUC+1^k%J9QctbBm$}uE zdLx)-wBw01v=OwVh~K5ijnLPHT#A+_(qNG;Z$3LEq$K0>s>=(>YFy{|wCeD15Bdd9 z_ZUM(Kafy0#!w^OTDFL>=Jd?%J+<0dtx@q)V-7mO3<)KRVJ~3!Rul-G<1?1^4)@Hh zHkMYW)kj8A=^8VKd&9SdME`;TI7S57r-|Y8YO^nKeMB+bl%r`;x2E&x(T1X`$L@9NVTUi)YmE)jhu!wFEO)`cMGEpA9|k7MtuOyH7Uf1V3^7D zZme#^gNJj2BOzbfs<__R-ZMw@R-?npC&Ld}Jd}`2!4_-QUxV|KtVMj>z1Gwbp{H!8%=C)!~5x6C)jueSa?Sd4kPeJap?E zYn0O!F&IlD96N*af?{&Hn^Ui!I_CCoa+H8M(&$t~Sd+GO+B9xwJsr(O^`ZXGR`Axn z1Ef?7Dod%FkOsGzbZ3u@*27h>6z@6F=HfBSvO0q2rOCK41Pilyu^dlUgD-xYVjxPx zD)mKuJqxN!v3D4*p$8EZVZMG`+$UYeY=560>W4jp|4hiyXt#t9>w`U{Q`EBdy;P z+e$kQD_xSHLt8#4Xy*i+d54bq(n`r}zQwTmlq-id8|bW_-eDS(;<*>u5#kMJ)bnW` zjWJX`OC~+Mwh|k{bLfzYRRK!Hyd`<=7|W{x1twYyC?I?0kG3#3KfOwCTu_Licy4cP zsh`tD7*P9q`iBPGxJ6Wl(SO&fZjGLa8bR3|!O?;h`bB=4dGHy?Q@s>cO-p4$nwOY8 z(z~>yIlVr%#OI}q>hWkT!{t&j)k{%l%qc}(sL!w`Y9BSn++IEVC_s3vZXkw-N9%5e z!xD_p+D03Gm(&m$qp7Ej)!h;RQyJ4aPGb`7r7g$O2Tqju!YB|r$B%DdH%srlIXe<$ zpij>uc#zL1ji`ZCsemPb7kx2aIaZ95)q(0f+StswG0rq=uuy{Bw6Of7PsIdQ7@IKx4iPqSlih68Ra^-w}H5{r6=$EvAPi!?k7 zNBeujLp0iai!?miQfk3i5TBIGg{Q@~CcMT<=eue3(O`*Er_3m$#qStI&h==+mu!wi z%n8kE#%7g8@Yv|`hvjb zZEVCfNKByUosfKgJa#AR%bUP>kC%|~)(JVZ?xk3%=#EYa6bQ^~{bFr^xIr=9*Z}ET zJ)69tF!#)A%Wq3WD1I>Oc(EdfWS--D8?|Vq047-+b99YkhPHxMHR6LCl*N?B67%YI zdD~VW;`Lag7rj~1Lur*B9a=bwS9`ySkfV59oMFlhH4|+^b@_}HeN{|C!Xqd}3Ui}0 z_@ymY7@&>TdSgT{)0OGY(2cdUxw){`=pAbIMl%O8Nzc+lBFjwe?Z*cA7)_jGyCQ<) z)vF{mtRDpnEM>$pysoasg-9h<$wGzJL#tg2YeO`zr;VLjyu?R!Cv9(8i8k8*2eqEn z=|fpabqyGE5pTF=J#RwuMw?L!(kqqPisdi zv`ezUoY!gXx4BHbp3SS}WsU7CL6Pe0m{$*%^Qp$bZ3%KkpWbt&lLNH10;YO6GJ>2e zG?;AjTdijAnTAD&aALFrEU;RSL(vSDkY<-}dUdo>3TiPjYi!Qu5W6)(bcNLfl@IT{IYryyqC%Nh zZ_TDxU>X;z)+sKTut>|3*$x*a!!w?2ffQ?XT9`|4CZ=ES4{gV#crz;TMB>tb(d9LC zRzSD?O3_T-=VHe@Euk;UwQPrrJhre|ZDjq`-MeHvZa_)R2){TftyU2iB|4+FY^YJM zQDsQe2;EbXK#rx%F=&S2a=tM!@k_!)7UKPSNgd5sPo^4Uqv3o44CYEtyiT=6*)#s*r-wkTg3D-mY^8Z(ZW0R z5`4>*DQ!AqlGeGzKQ2kLLXj`3l#5K^=I%NyV;~)2u`Mq`IsYUE=&BOU=JF;K`N)W_ zR(%u;duZAE1>YqSR6rW+Qu|F3+u_m)=<|u(Y1r~3d@$ppUFe{eC-tLbDqO-ya0$ zA5mS_+!4idVb+Y0VD;7qT3w^j0UuWD@qtz%d4Fg|(wRZqoea&R zv!Ax93JBXMnL3Q)p{U^g0MGU*uH>`^I>z2zw}WheR{Pvx86TCOe=X%V7``&cR^xo zz=dvf+Hk#z_XgW&N{BJqoVE`(w_FO)=&7+3o0(6@(qajBPS6#q%^s3*M11H#D2KiDbI1d(iD*1z6 z9QDBm9Ki^^5#u|@kDZ1C8pFc~*WkHAoEtKMTv)>x9v=KQgJnnx`LR{#m3m%Ahm6>c z!f_DGi#qR_9VtY@my7&%W5n-B34d0(E|ZY4G=G*5GS9_kO5L3%kF2mH__tb%t8W%z zOPh(+e#}0wTQhWeG;hcfaqyQ_!)S8jc2za8A!6NzqHWRJqQY=3&irt$a-Ryx564b(Z zmzh;KyyIj757Ob@zY$2uPHsUJ^W1(rxZC_0shH?wm>SM(d}gEcViqUgfrDT*)SIDJ zt9MC3G@&}F87o?Cq*AIAg%6ONaW>bHc{3lnl9A3kxR;Yt5mhwJNr_YD?$# zHeD+!r!z(C3wmhMW^qEh2bcvosZW(eOHg;T;M;%+U%N z!{oG8LkXjNN=3`bq|o*tMvbdBP!yoOHd-UfX3^l8GcF5CYkTG4d4jZ(^I6WF8N8jx z;#?!Gz{WG*2#GVtm_8Sowu9vatbeRVo2)*QPOeMccdM~S$7cS$M& z$5`{j9+g>)ykE$Sk_ymuCB84y5Tz(uSu-YwKrk-*HoATJm)FJ<2u}j^e z1D#tJ=|M^tyA@mX*5e0?`QiMs2+rchI2@ zOEIDy%}k+Nq~i%)L;P_+ZgQMw%IZkm8xItLb3>KeP17)#1fvm`t7qf}H%c4+E=(G% zS(cG;*&JlO7Mg1qoN%G+Y$6@afaKUoJe!6m7+yP$XSfrRQ=WvW^Oksm=k4nquJ-3U zAj}OSD&7j`B3O`hqkF{nxL6<>M8pdmDAE%%vMk=wDd&i#d1+3UZZZJ~H59pGEnR~c zOxhcfuz2}krwMEH(QcJBA;Xf$Q)#u84jH_x_8&GUeE#wVl<|2@k%_L?G~H=7AC}4M zpj39ml9UINFSpQ)`9Tu-Bu7gm;_t{KfijYvqeaZt3SVPO$f(NnB4oeIvcp}33~i)o zWKJpLL(X7mETBU~JPY$?+NoGz%Iq3GH;$U2x82b~-LN5Cg7L~D0=fykYuZaOYjD1i z0#X8{*VN1`#Q7yef@e{0h;Upn8ud!=I?)%UnB*gkCQg?IZ}(;7$cVx+WMH7Bg(-2Z zZkJff5lVB-_9g92bd)6f)&@5uMb5EQ2+Y{4Vrx!VzOE78?hLdrQCHjO3mC$gx&zQXaczr03hl2TC zdT1KPXUW~PF&DhOfi$}|I@Y39GG7pZfc2R^XGd$sk-Dsi;aS$KjpFmjmix9?O9oi| zoMrMz=4mxr^|7GKfqhMj^Bfrlpv)WU%;HNcqYNF*a@ru)&wY;c`>sbDzNq{(i^iZz z)6s+(6fniB2yw8J1Gl4U(GfDwRlqw|G)~J#erI`&bWezu>f+`lNYtF_2$g)ela?Su zk*rnFZ}5(F`j`*??#(h-$AxTC^$fy)c;1la1gJ|0HXbv0hl0xkPOsPE9pmgK#iO%6 zETA0%@6p-ZJG|pGrN`Z7L2*Jwt-#?sd??`=GYIqDhdCF<-|g!zGLb~AhCmf^jeXPR zU{8N_xZ0}r(ANUGc~YU|6}oX}^b9NEL$m&dcFnv0L=tTvr&NvD!f zofO!8il(h;oaaD9Dq00DvN=M)tGmDw8%!;?R3{ZwDvI)1NT@(}lASa+DDWGs<4QX+ zlTC|ud|@djNcUJ635~J>z6amU;8V}OQ*B?Y&o$sXbiC*5Pi>QTx)O5dcuMfuEmC4` zcC=2XIKd2svy7#>@&*JtXuecb-%gAqI`AD}Z@eE7pe)@Mn(ddE#bPZNW?Z(!e6q|M zkt}~)^2}&(=;L$*(Vl7aA!-dvBABPULwK+|PsX{T*>m(f8T}Ks{F_1VRHRrfED#4q zVErK_=ElI~^B6K~g5D*nHt-cDnlLM2o>^F#@N#&YEN9B-h)pa=GdUx-om80|=Z|`g z=6J0SC)~ZgVLmequ2?w7@PsZls%D`i&bh%YreO2R6PBEOJHa$X8W{5YOo{bJFL7B? zj0^^@3?Wk-oI7t&p&%_oMm907AR5sV$2*s2^hTK|Xw}p>b12>T9X2dtM+_R|j9Ps7 z*0o1V2zVjiJvh`1RC;eYxf~PvpRS(XX5Y|I51k$AZ3V5ZNC~)`^irB*wuFEepT-5R z1x_ua5mRNXhUF6a+%{eVP4Uc0JjtL$i~-v7g|jxxL^#jk-DK&O+ELS=lVp;LDXdG^ z09=5BFbeZ)Is38Z9mcB&rZqH)iTN@nycV=Lqg z-{y~I{1KQHaKL6%xK4es+^l*SsW`<)Uho;C0x>?IGAT3G3zT!f7J8lH@W);tkHl^Q z4$f0P^U21Qw3sNAtru9wh?+>y=$mtA_l^e4jkU}9~A}&?R6dE5QDQn!dF0Z<)t#8u_DtpA_CM? zBeoSW=si=sukJWq8h;IKE1V;+1>A_U&72xi8?ybv**erDfb;&veYG6T+p7C;%|h8u zykYImGQl(EP;NE{S)xnVSjv*V^2fGXDpKkiAHnfYTn~}#JC+l0Xm&{*??a|fpe-65 zqRA%~pt9Yj=cLj|ddy_V$yOvc8W^{Rr5;r>+uD4oN92Na7_Lf<(==>2AeKw=4x2$? zxo^qXQs<+nJbemrQQDk`)zkC(EZCw#>CNm#h}Wb|L`b%G`cMh0`!`oPD(An4*U?svIsIw{DOnX(Wwe zCHyH#^LGqj>WZ*t@y=U-Wt)+6r`3Cz8cIxo7b!Y_?CDaJ^(8Z4R*C>ckZy)8DND1- z&_HNptW{JuvG1BoQgPEyDJipO8*||zA<{2PsUU^J-MQ>Dr5b(y^4URKGck9WaAD(PV`k+`QA%jOc z-Bco7eF$eBu!TsnrOA+NkS9o*2b{!%Or6V>uF}T}bcg z<$LUU@VR_2k>pkHgy>|JVlv(0y)j(19`3^$xgvv;)yIi&*rX&uI&9>rPHG5wHA(sm znZzQRlj!GjEvJU}PaA=dw0(}&Aecp?EFHNsip~6jc^n#i2vCfnskc8^W-G_#<5gP3{+lOvW`zPrAVt~P3GbI1`(&u)e^`&JuP(3m5Y z-k!f^?rTCW<&d6AwyT+FciiA&A$~1h*gf-&hub1*!w{3)Vo|!X5_+n@ zlB~rUm44k+3*Y|S#2Es24Og6GSP6PK>HdK2) zb&ReY$sJ@T*t3|j>`oJ92#!^!(a}5})AV>U5j)z`W63Vu>f(CZEGb4}MTxGD%;&`s zV;T0NDW<$+dlonPgn62VNbV(;8&YfqeP*lgLg96u_H`=D>hzgXN6R>(ke!I;By=fp zMZ?{-k@kXyw!E=MTI`wMK!DS54JmX|#1PB6#+Sa^hVlibSO@0_ewflO7fg>OxxjbK z7iGLTjd?p*1I@g{%wbYy!uIKWMB(1H#}{iNH?uFy7omAGGHgx{_8z#W!LjGy@Qbk{ zp*ksDS1_5~p?u`{VofwRk6v~YH`uv#h+fd93$e5~6+5T4Q}Rfg2}T%8uy5xeC}r)9 zdDq4qu{2)6S~x!9!=sgwV}fox$ud-EYeytkGqi028!H0~oE>knY*-blBj1TR0S58+O?{Q*=A(lmC?qqJ$ zz7>>lr&_sJ%#Mqu;|V!pY2)YZ`zFg6>!SYN&!cmrSIiMhhx@8IN{k~-rl9g=88O7N z?v%)L;1u)c^Kcknfb{t+9tBipeMZCu#ne<&Gu)vZ$KQwE5y-zKBN(n5r zUtR_|#aS!i1Qj!+}x64+n5x!la-kDawSfhrNpI6@Oz*V2Tf7p$P<*Pov6gRS156F zuM!u&Nr|IhrNkclDDm{Wl$ZnD)dwqa$4ix1(xJpDhbXaE5B}ayiN}wDu9K8_;vgmN zhyJUe>lx6_g6u@3vF2q;>NQGi0e#J}N^G92#A@JAfbQEt8+=NN zs~%C}F4%TI(pk5Q5_i8^iCf;S#8&9J3U-|f`8#%2;wad3)N^15=#M^IiHF{*!~x*n zv3OZ+PR$|3tN^CQBNApCa~yCMePD@EsointfQ2c9X#F)O9G48PanckL=E_66MfAt|=3m0~e|Uw5_?i+%*( z-UwgaBt_%fz~3yz)7MGy%nef9fxjOC?vZCz#4+EI;%wm8iHhjFQHrC#0iBS!6@Q<1 zixdm4mtyprQr!PtCH4gVA^g1oGMj#(#DpIxvHn}&1<%!xI~Th5hs-b;P*+$?hd#GXdq-cSDKVT-FPxz!1tKs(+@SE`W)fY>#2cGYlhjxO$Hv@mor{UX6 z0iT5}m!UlIe9|Sb2e<#u?BDl`1Zl?3gqiP(4GYEqxk!p z`OyD4Dfat{6qBxkPu5Fu(3j!sE2Ov_&r`l8#R=C+vGbKuJoZ)O56^ev`JyjKu@cYA zfZq%CU_Er~3E6Ix?_L|ExDfhw`x5dBJr`e%as~fdJnx3T*Fpal$X$F5WC3@59(jeX zo$tl(50R%2D{;urr8wjcDXs+E{81$?!t-7~m15QpkiT1{xc6sLs5_-N3;Y{@0v_OR zya(m?NhNMOAAZ|}vimsNBWO=SZZ+WIPbks(5hXT!Oo`*bd*xlgtwUS;o)pJH=Fkh3 zxMU;J`9Asr{JrmwrI_$tDdvE_`EJyK+fmlH!G5H1BGO+AzNxV7Qs5qeEtey`r+_;Y zI_`muH(Y?W4Y|eVDRC##Jsr9(xd?3)c3gwHy#>z$u=8%v?}hHYe~Gd|-doT$2{ulF zeNP~N`$1+3bj|q@${se|fZu&!_r_mHark{G2l#E@HzAE*pdvpxzVW*OzX#qg#gV^8|BGJ%+!okz7T}f#&|V&dEx$z@!rxcm zcMm+T0bB+CRgWRn=`Ht4wS@4#JE_ft}w0sP_M+X&pzpgjTn2|J;0 zte|c`gz@27N?b4jbzfl2dl){#m~|v@Tk!Y3z@HAjdEk59@6m69b{T$e2JafB#KjV0 z66kw?_ryP-Y=GMa8x8?}Bhq-_cNjYXk8cA1bCoz_SF{1ZW6wi92222MU^gWMaQD0q z?er}40jtrD@%!{G7+Y5%@9#%{1=`?u(U$P{0XtR1#&5yCpF(y|C9eA~?0XT)7=Pc4 z@$B}E@b%X*z5uS?ONq5FM*G0;zWCh;8#jXYaE#?UzaHgxC~U#+k&~2oaw6Ku8 z+=c#nEBLR3kN5a7<{L+0%>Of<--dDY`AXb+H2m;K*o?Zl>KN2L(C+C#eVd7~7~}ow zZ$mHOB-nDr6KI=|*)$7&o}$El(~t(nfIT6%JM?bDc(w+=`}`fgnvOb&-+S;oVJp(x z7juX=!|$-+Nc?>h#`lNduhTKcUR9}xm8c6x;dc`3dg55Lml?1NHq65B*+^%@RE&LS zLr>!Gi|<0+I!=iL0Z+aib^~?=G|)D70vxmgeHY-SzX6YS_2e0-U++Oa{)K)VaQ2f@ zobq0@70?d>{`%8l3!bOrcP)7L0R3Xr)4Lu=d4hjW;P(F`#x=myH=vvV_rTw$EJWMu zf}RB^vv=Sb@I*IsbRxa)piiEs#7=m==ysGDaQDx}eC3D8)2;Bu9E|M~F)zCl`M~dz zo6#?!J{$zzjX%QJis#Mn)v}+$50II1hY}~Fu3Z0Gv~8rf3iWUWbWA=Tu*Azguf5D3-$PJloRUS`LJ;t(x0;k{)as$ei3~K%5*Y#Zv}1&Z0-L%+T9P(hM;e+ z#pnybvm4U*74kTBKH675%KdlfZ~p@O0OwXwZy!TD=|i0b?Lqu518fEUMDQJm-;)M_ zdp-QI9?!3X9{{sp|79C6#xKQubr5#rck&k0Gt`}p;C~YR+6|{--dV?d>aQ5Tn#d3S zzUvg!alqCQqkS6#c%&O{Qnco-vLjqfc?v1 z3*f|MsHb?|4{#571|CP6z;&-gJ30$K!|%iR-Ebyk0aI7Qw)bJ4{eI}i?*XfjKm2_$ zepli72GA!x0sB6HI`kOwg5TZOpo~8VI({DqY&si$!ShvX;lB^T-*|o;zh`Vk8^rHX zz^^?Qb^{JS2Y6 zUWW1kek=G+xe~s+8hMBOz!%XzpzEm5BCRhY?JuG1zplhFkY9HV{0AM~Uq#-K#>%gt z&Vv5nXJFswp$pGvgLg6PeEJIH3$`2xnF*J`_HV!^SHVYsjgY?_b__#q1JZf=(~u|r z^{5v}e>MI-3o>T`e?Igc0y}nv?rUM=Maa_@*gNTK@HJo%de=d&8~ND@dD$5<5B&%J zdj>eb<==##kl%^;9RPmA5h(BfD)I3N0^`j|Vn8ibRn@OPEk7wQl%JBHke`uD#DEwS zRk2i@BA%{7#GM4T!+S|;yUpaaizFQTrI8@8^kr@OX4>1J@EtaeQ~?^iTJtrvA9dzBYr9# z5f6*si(iXBh+m0&#c#wf#QoxT;!*KS@sM~x+$SCszZL%x&xlRxui|TJSNS(lk>alYCt4ET1cPk$(|V3VEk`o_tDd6I;cT;_u?0;%RZZ zXo-E)OVsJQ{EuIB5#r3kT=UO%Wugq$s6U>@-yN>@jdxN`6KyV zdAr;wH_6-N9rF9~R=Hd)Q#CcNM%1u+z4*2Kt-MeEO8#6vD1Rv*kiU^XllRE`43@>vSg8Ksm| zJE>0fRy9%mLp`Cks=ups;v#XexI}zXyio0>UZnO{FH8|Jx5aDJ-SV|+cky!Z zYVlgJrnnMR_|2Dt0UB6wE*wGi_`>hwECR7LY=I7RG(U+devp> zBWk@mSFKg&s5R*{)RUU$k}#LF=A z>lQB%&lT?yUE)n*uGmMsSj-mtiJip0Vh`~=vA=k>_^!H5eNWx0zNLPkzN5ac?omHg zKT)gXL+U|wzxuWMow`>&s{W=PR)0~yQIDuUt6!*Jsm@T`n~#tdQAOOZBzeN z|58t?N@eGYtfZ+-pQ+aM>x61P>FRZ+%vPWgF z%I=k2D!W$pth}J|{K|_fFRi?!vTtR-%F8RSs2p55pz`X}R9;ir zUCx)&}BW%4wA|D<@Z$RYoh#N`GZq z<;2ST%6lpcDvioe<&?^z%1M>Z%6MgYWnpEY^3KYN%DXGQl@ltnEAOhDT3K9~RXL;b z-pY*1>6POvODgZHOs~wVtgH-HK3G{>SyQ=FjEYOt3)BYnc`WyQOnpLKt3If{sCH4i zsrQS|%FE^FsLGL*H&)(OnNm5r@}|mLDl;qZuY91gr#fFuR~_mWu|>UDeOKHnHi;jJJH$qD znJgO@URU|KS|a*`(P1bVA9jvLh|4iX+~r1z8pes$dZhTY87sc|Ka3VX{GY~)Kj{(U zvHuT@8E=v^<#BRv*&!#(*U2N~QF5X@Qoc(1JBze5tM|R4$%2&#Loi z5$l!zpBuA&CT>)J7CSa_J*CI4pZ*_@UK`E$br(jkv;Ls}H-Hc~qa`j1! zb62YWTch0XlX319r6b)wmE2gjLX9dK?~YP4)sByOAJU`V>dHA7`93P%BhD8;Q#}54 zs|9Lzb)nj#-l0~AKJjAJE8_96LI(g5_r^w3v5&NsPLaCxvyN1W&j9VFphxm2oHndv z8kSOjOhH6*A1up-m%|n@_!9T+?z&i(jjk_cl)3xUikDsm+Br@UR)Z^-fEXJXz{eYu zL3~_Wr*I?@((kDTob+vq{!B3|;;02#;{ktv0&TTYf*!+P2Zb2y`ICu- z_$J8Q#|Bk+4r2lXQym_r&w8~E`rGD+{)RG*AMR~7!yCCFMkxO1rjPz~Y)&4Pnj*k7 zCearhnoJlS$%HT*CE4L^s^IDCp|8lA&^l-ib?e|koP?(Hc^NC)XO1!8V>Z~O8Tfce z`W!HrC_)sdE6|G|=8ftIJ~_o#K>GZBDB)?WJ)rR?McPWA=7Q={TsFsH&)F)ADKP3| z?P(@)^rG53LRCK0!C2iy0t4unMjyu=3$n9#?i@OWgR=n{KT`C@6*$^EjgGS6Pd1#f zR1M4U{Mn*Oh1qA1^e)Aj%K8{WbcJeQ`*4V-%ByRlt~~bMjLva~*DXxfIEUiz@=0re zY7J5#%K&wJgW_Uqhv>Nejrs~5_f9jxGkhY&Ke|6bSh8d-9o|Dw= zk!daB<2va_eQ%7m1{Du2t{U7(l{G$i5^@WFIMB? z|IMY7Rs0DmvCXXNgI3IBqucP)v53i8E0fdxs|hJ+O`TWw!v*P{M@LCjvs0b(pU3* zB}=)Ekk1cwWI!%O;x^~hGRnz1NY-%iwoB0A!i2U*FBlSOX>UN*J+a@~nBt||XH{2M z3cD3#WnP^JALG12CVY$09OLNwSKyXsoTH{A`|L3a*bx5hs|ZnMtiWeXee@xd;cg7I zstaq4-k~Oqv>Hu!1$A&J1inHVtO1TcGIyNR-0amh5z=>=?%JRrL!^*I8AYxNCwN+d z{-d$TX|)KGB~n2s7uDKHX-vR{?vCPu;G+ocLr4-hN}tXYN61(kxF~bfojWrOj$?}& z-vD>)aD9o6h2~LIHp7v2YLhhjRrQdd4W>X9>{HLFJ6IFqu;HeCnw{_cP6bS)ov6GF zE-5e5Dd2@M*DVdZV!9V9GD&u+}EAdIUIw7U3%SCevZgPpU+1Q+4sqTs__@pOf; zpA}dP<{}6fpYo*`J6mTd%4({KaDfzs&+nN!j5s4YLLo)>a~NcF3?DRF+)P~KN1q1U zn#7zgMJ>lv+!F|1FKNbOB#nT>&}t{UwzcXeFkI&_;7HEAM`*NZb|KDuv!W|$h!5(0 zh~_)Av^7?-HOM~0rfHe*qe7CD*5ARtGDYo&DQfioCBD$esGDg>y zvmT9U7E!KOuxiY#!piC5(Qhhxs1GlnFt-9|{qcrj3Rl>B4iY z%l7_S+Fk06a*z6MDo!A5sRoY;Dy$#cUKR||Z6t_fYn4eOluSs$GKXfSTIB}`hoV26 zDYkAFkbWd_f zbE>taEnK+gIZg2wS#7b~>t<=0VNT|DTT)eae{f9WStt3ICJk(am-N)o7Ef<~OSPaUxQmXTXu$$A2yMIzH5fnXID?v-A`!yB0U1w@OiL74bucSq zX6?*2bNgsUZC0TrOj|Y#cDa#9jKb}#FvDHj>fZxAjbeE`gENRw<$GD&7r9loK?HTAh zQ~%U-7iK%0UYQ7Z_#U_df=5`B#&q0o$ge{lF~W;W2B9aQff78|8wD{FSrs#xfYl-+ z%MG$jLtFK8nu9|Fx*&~lM%i3^_&hW^tUHOAGGDJp#JEn1@lrH%L3IQlmYK!ISYkm* zx`^M{!plp>BD&eKEQ^claq9h5J*2xNV|54+86s@oYPbs?$+%)(btzuw=^8&*RU)@^ z(rtz@J#|seHwC9;ypeT-$v+~2N71zL%xi0WdxZ|dO&x}wYtX8OeofHv!{bQan$vNG zD_mfvj-5V+q|D=yFAlQz_&9{SNhn}yn)`w@YN@*f1v1U(!Cj=Q8MTz&c_GH=9^CkL zUH<9~>(5xB<_#ciqD510q*r{0MzP`+ktjbdpcgR+NF73TjtV4>Pb6qc$jp02rca<*SK zM7;Y!E}#QJYZ8db~Lg+CD!#&1I?0D+Fi4-O1 zG7&R1P9%Vh1lUWVogU+@4RIN9UkfNTX3qFEVbiM*PFoc08sUwrr%@xaFWWBEx0`f& zj0sP#WjI!N_*s6yr(=i(Y(anSxPWsn><(!cB^|=NJW`DcaYf15dLzT}nE4~@(-HLp zX+yzcEdm!udU34=PuQFm-{pA}X8Vy;Mp4kWI62^oM%ymOap}0Gtlr!*LzV}-y!s*7 zwqxFBCJ!pay*My3>n<0USCtR|=gAwr)+(X#`SoIiXKA$&*|gJz?G zyg84vdcWsu1oYa03j$O?;t~>h!Cn(eMbNC~x04m#-Yw1E*M z8@Mqa?OzLqBwHDh!295{7&}9A2phDPc$)NP90rkRqRU^*h~n&|5e-7HC$@VRt>O9G`sRY}P4 zAjr98@?pqhDfV42~&+U2}7@hdgaE+1>rYH1vrWf22 z%I4gX&{N%L3>?C@#4`z9J15L~kzUAsk)_~(BFlE{EVv=jkn=>5B~8RcuF?VG{Pe(7 zPD3!uY;fdcF)}m=UHEqLY=Sq( z>FiK=##qD+3~7-#La`CxeL4(z?G$E04SO2*A{^{7ht2d1=Gz3c1cYn%GF&rLO|EHZ zUK>ylmB80ii^QDL#2<`e66$D&!0>r^yRbnojGZ{}gnDQ9L)<;;xJ*r7@V1C=f5M~L z#`VKQjBzVulr@uH;o5qrnW3*~#~7B`j?PA7-&P^@EVZ-V#UCmWJI7n(fs3RLl0`kuMgWpjH^tp>F~?{HBK(S^Zh zskBa7-@p}t#&h&Er;4+znubP=YPS?eBwZc}73Wb;-U@m2m;Hse@&%XmMRx$Ai0$G> zP!SjPhIO@P_T0|-3%Yxz&*+-AV0LHs`~^Lu+LB3!AuQ*-g>&W1cz} z>-hTJ4hu+@s+R$~otWpz5fWU<=W=J&e@7!Hg9+y~&LwCU8U1$$ECqf_q*u zHky@BQm0Sb`fv>j=h;Z}L2(=nrt6C6s9}?jSOx_HkNaZNhw5}{n6yAZA0z8%P91Mm zI~omr*S$k__4N){`|bHP&+N{*SkyHAt&)ABSw}`6p=stoXD&n5f;PQ2VL5Q9V(Ji` zGq8v*Tt=>+%<&(yoCh+GNV+Q7{q&#$2UL5M3C475RfaZwjCQxZChRcVoze(t4K!k4 z14i%GMr=5Pj}#(>e8{PjHYhzS?^Vni($}}RY$S;kQ$Qc2wYV(^+6?Nd_BM2|Xe@(b z*~>LP`+!cAzIsLCgt6aW(WBlypfW;(qkGMniPy#HUTNY9SIPO*i^rOH-i|BCy}zgv z?7ZUHV-{8QId@JgcgY~}H?UETg~?Gm64O)H#}KqNme6c9>f=3qJPeaSbWt54+FY?l z+aB3V8r-}{PfPvHTq)kXuGs6O3S@J0TZ*S?g1uy{Kr6lQs@>IR;YDq!#_)=+l-BlU zu(r8#*JQ!R;Viq|6=&_P74T?X<^{|e=4FWHjudCfe4w~UiY)dDfu`4rB7f|38@(Wi zbl^nHuuaw9oq}&e)Vs~}VPMLGyzv)LKl!s`<*G=%bz z+n{KO8fTC&Mb+g29m0fc7>76ki>2w8Z45}I&s?sN#}=65a1XJfT+oM74ql-t=;s#z zy#mdvnk+u? zDi7*3IJ>gUg^)<8=x~Sqr=%%0u5d0)L=_G`>Q?MA4 zqD=UT$dDw6MMR4_3a!+@!tn22VPbm4GsxDA+So|a zdzobv9~#3ZlwV&l+KI?V`SJR!zg7>$>^pS8>_TRQd@go{3!D*BP56umWzJ58xROvB zA&Va5U6_oB;=*dg*kW*vknTS~2(jj1MgbMhFUW6Zb&-Q^gxuyMdtbeY8#N;nfFl&k zam1k}{ul0a!dGTPHcmy75cQUjr@$O#l(vRC`H-u`z=+qpKGGRm{@yE-ybrmNwa$~n z#CL#odui*pI1b^FSjB-n5@bns)1E>XQxe)E)WiWkQcPMk<6s{VcN+4;5ox(K3jC3y z@G4E5e(IntVLeuB%%p$WLB*;f*p(9&cOz)Vbg@H(-q|i5_yB$D3kYo)6+8;>K zCbyJv7n;N=#C|~sn!(^m6{nuj;OL`?h}dl6OFryyBVLb+WX3U?NQ8=TvY^YJMQK+jN)klm9t=GF6NIh+4_aHl#oq>_H8hSEOD>i)yXJCKaj^RsrNQ`?uXBg&p<&ap98yK!H&ydW<=k}@$7Bj0@QtQjv zgl|b&Ls@GLC0jJ;(rW#1XU3+kR(%xH-G&J^71oR{JzC{tG$EhTIKmCmlp<|<*b*Ru z-j5Fx>F!;U;iluxej*7w_E4I6Lg<#c|3ZbL6xZ>9|Bkb;AbaV0V= zS+6Wax059-q5}^ZOR~&-tMe}3e z;q+wFBSq=Yf1I5j55H2-p_mfKkxFPodhguYqc!mq!^V_~ z`J>lkJ>N-QMUl-g=9HJV=p;`zA{45QiwNa}LL%C0kgO}%I-acC^7$xvx|K?lf6@NqOOZ>|xG$>Gf1 zF+?G=675_&+2CM0Y-FiM^e!FhOIMHsau8fAQO!&RgBcyBTf$P}MV4n`Cc7cogx*T+ z!ZcXNCQI@}q88vzkN~TLbQRc>x)DV1@~lxDuNa+%CE^fDY;Afoj4id-B8QzPo1O$eaImwIHTSS=rKXpqF_6Uv=`hH2lz_X+VtuIpLFA< zZ@)wfG7>A`h+d`Sq%bj;3$@1!oQ1@>UrADc3VV>m_(~rl>M-%ctR;+W>P=SfC5?>> zOrzkrcv;nA^+A+G9(7WOT#1s3GODFrq_Kz(opmN9U~?(O(-f_hBalTZ<03XksL}!7 zpv^fM>p2cSM#wB7Y#f0TSSloLSDF~&rb8Ia{X#8ShQc1D7No|M%_0#p)>w22DV+ql zGz#r3poD?WT!B!oD6ueKC5h&97MG@tXlA~mx5-$vskf>5mW*Q}c!l*P7vsyM?APjP zVy5briN%#Qii(zro931K7-!@s@*Pc>L!&(hFVXENPtj7ZDT$|+nxiN3WRDG;mStdb zc8H~5i;J`7GzZbvLLBYw4O7gu07;?MQ1&^Tjv|q;qT~v!z$L6kaPf)0yb!PE{j-@ETZE9)9{w~x74vds$F78#??N;UBa7pe!16e%)3NQ zsh`_8IPxrF#RakOtae~|8=WKK1!(H9^?cgI#S2KZJ5fp+9c$5N1-{uK3CCRAxCWKZ z`VH&&c|jT$X@>}ZHr2Fo2!@gN0#Qc0czXp((?s112un@4y#UqBpj;fjkdL(C^Uf4C z7UP1*e2&uw;-gRJY*f7hk%kq0a>hjID=?6!N~QHIq=Xuui{v3O`r07Kl#kM93k3We z!!I$2w5B_!fo>+X6K3XO+G%XRG+jFNL#Lv#zYr{s*rfHB5Vq==+}LP;iKfB{Afv*#}t;^c6S;VjI|9iHMJB`Ts1fy-$en=qmK2!#bgz7m*9Q&K#jW-CGb24^w@ z9fiEa^IXGNcvUu0|8U~J_`(*`QacS*|HLnYDJ41T9g^EAW!iRyHAC^uz@!2WD-LN;qv{V8i0ThV5MA_kg( zi{TtULMN64v4ftoZTWQL?8r4;amk>8~PO0vA_NE|7$psO%WIss71bW!Zcf+q78hcyWuL9&dF ztzI2RGDDAErkow=pymlWvSdL|X#$1Oz-a=dEUWQQ;Utpfb|{D!9|)0bIcQYjd^cfT zJW8Jz?5#xG#>5sag%Bdzq9#OYY`QC=GfC@d{$o=!8%Zf)vt?SGy8di6X##ZWD2j6F zvJ+BLp?nxjFB;R+o`Ii>Au$W`eB8vWn+3I3cN>r|Rm=o@jg&Z-1q-!3MC(tOf+@5y zmQThMY%m9Anti?D2X97(%`eC#m4p+wQE(C;=($O9Fx+VOB!t$?h%s9mQki@701^e; zOtdqD54o8q+rXO%l}?QmjLH^Mq0)sxIBCA#mLabCW0-5Cqlb;wsXuNFOtSd+4a z4r~(g>KFE|R)3YQxy%uC1W-!|&P}AfVo1X1rK5r7#F*w{g63G@32#fN7le2ZkG0>dq?a?+%@TmM>08J9BO&| zvg^>v+=lUSy$_sw?qykHVkm`wh-0BT%>gMkg9v)rqlLeM#z%NsKn%8c zDYc{bVQhrW)#vjsrQD3`s9(`(R9{onxbLi zVs#NA^O_7(drfhu*Sw-MN@jbFI$Gv-SzPefe3B-+z88)2Z=N_^n#0lq|{hV{QpL6C_&-Cnc z{A)|yE4~lV2JLUEySlo%y1H6?&13Czg!sHDTkC37@dJ|U?p^T(JnU&&Qfqi=r%6v?!I!%<)xxL<^RzqDT1%$|rdRG}-pD z8c1GG#Nen^c?(fQ1X-!dS^|0%dVAk2i>N8zGOG3VzO21(?1s=D|73SYys7*U^^+zD z1*r2=ZSp{z@pW2(WMRCbaBL5(pEJ~||MtFP)c`I(p}n#EyrOs9h;?wap^ZuLR|85y~@GmXJ!51^1bYcl_4ittE}Dg(!#y((%Z6yl~9-n%Zc)wvdpmhWwqF_`o11y z6F)%L4avg8+V@&{p_{U7{$Rh{EP)$(?Vi8xrciqzR*f(#7v6^RFy@+KrMc@fad9P1}s3aB}a5#d~9U`Q+YvG%3h3Cr0mx4_v)N?|Xa4RaUtq zbtfqUQ5;RxiYu3&%TTqs5~$G8;F`#3G9;8!oB3`#$%-xYj_J3JFQ{c0m9`F~a~ zr6k`HLrVEpmal9Il)qUNe=bnvyFGuJelvf!ECj88yDSIYdtWUIUA#G(9gfsWL+c-9 zGl5#*+3|61h7{TIUo{({_pVVg+W1AIo#fwA%10aD*NRB@J}Zs~_DV^YpY#e!7jI=J zrFvzhd++8aj?`k%#z#hpY4cOz=4SPxwGU*uY3;qN0B?4FUTH*;)tsFT@;-rBUI@?M zhGd_(`AVpmlqiEx#@$?HyPVYqKbSfg`-k+9cY7K4WJMx%^ z5NX2x68r zjnABqKyNzvG;b(mng5mThKQN17vrG^?&VO3+?rnD?1D`boObFl`wRJ7S>BEU5nt_< z((e6zM?vl0XZikkR#w}1FJF|a>G%Sie_vgQmhW1vE%sFn3!rW%8e5n2L+Yp0M_Os4 z-p5wO?&86nb-Q~X%Ie)>Kea+$Wa)^AA67qXQc)vi?XG-mRQ@)9x~-xa%uaErr$J>uIlE+FXks$vb6=(@KTf_ z|G@3m)3a(H_iCf}esy)DQJ-(u+xZls{;Wt&*N+a1UlZ>dr&Pq-y*lc>9~Ncy$O2NP zjQXQ`IVSsa;Q>}>65+!pW&VU9T;EJ~s;dFX91}d+j~zTu3(){rZ)8QDa2o! zsMoe>CXLP{bR7??t~RXcyCUlK*aGwl!uKAbC=0K=kr#(o-^feEEAPlc@ya`Sx%l22 zO40aRi_2>At7<0JZeD*~Wz~v_6+?#>pIkiEXk4;z;lfK74=-B2Xvv~QOX!92&m#Hf zC6`|=|8&!#V+-~lI`hL%y!MC%Lqi7-W&bR=cuE9(&K%EQ4h@aaAD&RWkpI7W=*X29 z*QctT>Y0m+kB*@~e1ZP`v3z5H`v28Ki*A$OTPoikI-LHnfOy6C#QRqdExc_%`v1{G zhlrO$hp9rHJ9PAs2hp422gN_)LC?AUsCD&PD{WIjqJ`&fI&b0F==$rjPtE@vMsJ9} zDSlyS=z#1`N78=}%>JZu=rL+^l7^o5oZBBTbjKY9QT!e8k9ffSh6=H-9vaFXdA4{b z6Ht)$FWy-qzC&*e^}aJ)z9Zg0P5ejxBYu5o=nDBt{BOUZ3HoovzL%(vn~Ngq%i`h1 zioWcZ>C5}F#}f}Z~x~-Cu!C-AR1DA(U*M7+--Rx5%*V#S#qlS>wM`@TOOdYo)Tr%(W=;eN$MdlB=R98S-omTMQHGTc*v$4TJnk;Y=T%zJ)`_WlI_kG%Zy%Y zqG>Psk+V0E8$Bx8^)PB#vS;RfJ3+D{-d#!_dDs+R$TKy=c!i5=$S0Zg}gs!F>+Kaw4#iONSF1o8llncus8JAw>w%8XC z@hFQ(iGteAOB$NJB0}t={cM-mZ1xf`2Op!ct*MI70>0DTq{ilYlm#ucMpa+*r9oh} zIyRT9ygMo@;Gh!tvlW^h?{4z49jrj!uv=fxAbmZ~hw1P3)MZ>2&sd|yOh$4@kg*04~~ebIooagu{Zc?K#%d(jsUjEs}> zQCN-)dmyq$J(@jEk@Csiqw-R=FbO>~BgU+86K=P&6BIStKk zVW2^$>1?snmY6`59;!j7>%7tY#ygd;7j_5Ox-)bh?YKF+lij9hy?CY^B~oi6j1fdT zOG-%l2x31nJ7gW$p1{7HEoCccws0ytR9ns|Wm7IHR0(`-S>n-_<7xDtD|y8Qh=U`Y zr;w~Eg0GE0rt=jNsehm?L92=jq;81Ti=Y?4YF#L0Qm&D-8d2@LzVy)J;fo;nMN%?_ zXA8*gwP8TKSdmb@4pWtCFLd8C^NG0AB`PtvHPO0ZkjEd~mWeU~mI(B=aF}_6hooG*c2&fYFGv=0h?AArp zlEbA;-b+_i-d>Cb5I$kJgB_?G-9byDC?0LB6gm_1Kv6h@N@6=E- zTAAHLC9C&nY0a#@=tpZ&l;oZ&v3C=(O5peEuxCCLE5UoYczG2$4XVEAOGd!FT4$;k zC#x83wD!dWBW8ulq*!-(AG3yJ>n$3kD{W?0k0n@Rft(`-lM+g^-VBX;E%o&0#iT>4 zRHpA)qdJu~8XA$P$YZ#+@cMF1vK>FZbpS1UT`psO?2z19_4f0? zmIZ6dF@s8>Fl)K2()-dMz*}eVM^2X>&2AaD3SCM!EamTX@f z$V3sN`zp-AMvU&Kktm~H?I!I-UwsCw$^8`)P2B??YZaRoXRHCse3Qx)N9DrW5|FC7 z$Cn-3wcR}x+gGo7G6O_b?4%--JPfD)ye48OtERBBGoPUr1hn8(-h!)}-MI*nQk1Kf zC&{SY*iX-){g9cGnct&RpP|ATM)yUXYi1Rq zIDe%nqV}R6*-#E=y(Cc~Z3_AXdR%CK;^vaoD{-(+RNSExu4;eng%OsBokMfNyh@`=h@wKyzL0Wz$?e^srS=rZDrtG`Tn(kZ=tp0Wg=rh4 z;2bd!XXvP`tfT4lu`}Wj;e-6o z5VzkwYZsB#{9x-De8zyQZOc5GFOD0@wk3Pr+jsMP}AR zwI|8eBH|v+z>$aM(uZk8QDZ=daoZW?PCQ&=xrS6s+9NcYE11EifoSX_720k}m)JFy z(zQ!e-c4^#wzi6@9c$G950qRA}~jjLDj(5<*n)OzkbcH-aJn zk5!1RdMDZ3Y*p)Rk)o?Z)h7s@V;?7(RC=VcqPD$TZzZHL+jJnmU4e!^-X`W1k3yN? z#L5#CriiE%x4`O1cDs7!(S@X`Pc(?~PFWS9!Tah*z=&`24|t9zzS6ed7a_A`)b8~4?VKu4dY6CIt%rhyiH zwn3vKfcAl-sD1bxo0yfVRi)YsJq6?NxjONhMmlMQs#SVlJqX6(^K_o@qk<#jXutA* zbe@R1P?5M!VkDD9?ZxLSOi`mSpNNfN!6q*CjEi&0y1hUlW;?(|jcmtJS$1y%uj7RZ zH?OZ6M^@xPzDQ$cmy`|Iw|cQnjN@B@mVJrF%tD26n7|giRAG)+cO)(#TYCWSWhyVL z%{@)gFU`%+Ui4*qJflQ-I4{?EqE>St4UNfHC^R`LgfYmgt{diu-Kw7bE0JINO1YOy z)umU^dS`Ynp^IX(>|w1jwHJN0EYQ|hDa>}8ZU?8Ou>;ArdC0QAT48p`s84n~Nfahn z@w}#Fis~+&Z60=SdZO53cj>hyaTS%cPx7#Xyc$C5L%v^ta=~6#a#wFy6Qx}}5eRV- z?ez++yxJfN71)C}DAZlGB)hs*Z_=1O`Noo#m1L(nJy~VYC{hBQeUrlNcDk*^sXS~+ z0rAZxF}sqoN*i6-?IbEhYv_LL4~lcXr6i7Sa5Sh2?uUgkSl+6zvWfsPc%U`kX7b|n z9~g~qSBT9iaXc)VJqIg;cj(kzj%H=gAIQSJv*b~5B?fI6?7qB9qfMsOR(_3-y#WwY zSKnPyX1XjZm-z}I=NlQ&A2I%wuad(qeU2eZceN~TzwN01PCk?&V% zX@^RXG_nJm$y5X`vZx;@xf{kKuuvT7g9?kT&6#ebJ0lR$S+@_BM0p3;o}4ST)&g(& zwvtXo%@Zm_T63up+uEU3^M@5CUG-UaDlVT0r2L3QbWU7+CYUQfS~4jT*_0*=d0I{R(XC zmlP(2vz$P-jKBhYx#VR>JseHSmJfM%UnzNUWCObTRfW~dJ`L7YwAT7sNfft^6!)n* z8kO6Js7=3~$9qL)E8X2I{--TFv=^akkZ&j~k--^(21dg-4O)zBD>OfTOX1N@wx~*_ zwccJtIz4Mhaf0~U3eDbZKM7mC9eBRn(;oC9Lci+oLdN$_5PyV6x)Atq0vhpvkR3Nr&i1-7O=o)r>BAA7K zD2a`<+94ArZ?g*27BI8_Nau+wdj~G#k9B4g9;&?X6O|XERyG*#Kh;V3W z9C&;FT#oomN9`dWbv*n+N|#-TyRtzEoEy{mQ0oa=^OqKnW{GYv5sbiJsl+wac4s1u zl97W(#IH4Gy;%=!Q6S%MR8}t8L@MMAWTKODzg3x5xdPRi_TvSjmi(O@3z>e#7z-eZ z@cTll^p>PaY8hUy2Kfe|D<%X$bW^r&XGpirp;1aQMkQ_=J!83 zm{!Uy-=2Yey+7H+RmpU<+b~l$`Bc!hf3~S{vJAnv|BKC(myfGG$oGBGs^zZ+(;E6w zTlH@SjfP|#jRpGicbgeYe}LurhqML7*tAW7+Nb^4RAhPnS;#0dC9>O%=n6dD2(bGR z+3NXhC*! zB4ycx&&TL2+JXhyjb?&l4?p&JK(pe0xkUM08=?w&6uXV8jO?!y>Hgy;rDoJSo$6$$ zwt%(v0UC9L(wLj!o<7)@IZ)%R-j&qE`5sr}a`h8sFWd=G&BHKUF6z^R3~nc0pMv@E z;Cz%w-KDrJxypG9hvxpHX!jwStYl-?RcGq8_1(Eiy0lwuRP9Ay_7%u_s6|bux{XBC z;L)`a6dAlJ+H$YG__ZCLAhjfX7w%(a*VNx^yqLeGjyb)DkVpF zsbk5Gq@g!4f2IKz_(*NEMzZ+8Ke($VDfuI5)j7Fw^$4v=j*?7Dh^tbPk?kb#TNLaQ z9c|M#RRiw?MimE+kv&*QXS*isw)9v$aZ3Jfg>)h|K9+{>qX0X1tjZd1(=JiPFsoe2 z(4B5~S81D@Z7NrnP})XwM*O?3+73Rq4l*c?^RXjvkw<%c$&C<|M`Q2=g+wv=7@7mD z+KD<%Y%rRt6Lrj=Wbk6>Dq5ePZ1A%Cjzeb&VAD>~d9qlH4&;tS6c0GH ztGCJN$RZPA+Jok)^Hf%QqDvK8hQe#xw2Av+@c^&yhI^wqE%q4Z8RZY z6M=p#QfRb`GGP6Xgpu0lG0#31Trnjy_U=-hOhY0`f^yx zM5`cAIuv_+fw8<)quI*@E(`4hEwfk=c%D8J`|Ha!p1Q;gvscLXyWGnRmlb&?S3s`4 ztmXDAlKDz6JDiJFWmjq3IJcG~{k@066Zy}sL^p1`B1>>jgBPwr=uFwY9JB~Tu*$vK zAiC1{*zE~+XIB_J=dzkT%cB+9N{d*AxdLsFr(Mq{yEg);5qcD~@G65GXG|gwV6~i= z#cVm)d3jAP+q&xfJngPmvO6}y`VeW(H9Ac$A)<^B5XW1qQ`c78RHQ%`l0QB`>|oTz za|y|(0x7T6sbfiVrej>V!RL8=EKvjdI-MuoeV3SAYlqe|V+Pf7#Mv?~_4MQ=B;&e* z)@sjE`B}Pkb83t-Ui0$`?!!WSzNb&c4b$r#e6k6#$R3+_0g*S@$H7_>G9| zQZRm-gL&q9n?62Et1x$?b9EbeoSSrVb~HxJY?Njld;$*b&5t{{d1prbj=2z_|xSIk%Q9aYwKPW49oX>xLeS z(qlxPcc5Ho)o^cJ@Rt!F;*WQmhd4b zrCeFQo5)b5i#$fsECc%FLQFiTUK_7M1PIplDK}k;z8K$SU;s zZf8)BPMbX8x^4Pt1+yA&up_@NM`J!h1{({wIhSiaB{Pe$I5Jyr z1n#h-mE1OkCQEGVMvdQRo~XIly=f>k+udVZ7qDwNr;xUgu32s>s(4z}l{}nxQN-`?Pdc+nJKcmk#)RZH?#% z@v&*hQ}5`sG--wI+9R#(I%uIe)=0V?8c&qN3BK6{*pi(lZ7wxblRe^qp6t?SSz%>; zc=PoHcnZ5sTH10oC!gtwH=Ithz%3ecw7IcCHC1S;)5YYrDcXN}fRkt%7&g&k%S7hd z16{-@EsJ7E4{}jSh1{JQQ{D%=$Ybr<`n0ix;A@g+tcY6jx4Nk7==gViz7f2);EBtM zdk-Jt;%*4d`$Xqw9_k`)Om~K!h(eLjhq;)WlDR4sJqzWcvu+P}atEzTk8n}PyOSNd zR3lV}(W>;3F78CDODE6lX^lU6fE|96i+qDw$c}3z&}!q+25~A0&Ib3`U=i_sj6nyTHsvvSPt&0Q7(8og;@d7T13y)xc_t-35sZVU z>BIq#gQsgW_cX-T7BCk)L*x0TA1)Ea@1Cg6=Y zKvSOGqh+gnIv8YLl*?^Lw6=Lpk0y3@dUtRe8%i;W&+QS#8RJ+))PK**X;>vis(hhspq9QK* z7M(bo)VBGCDZf{N=lE8gD{293O{&D64%HA@Lf8!ZcJZ%7Vxd!t+581h4CJZMI}M01H&vF ziXFb!q>1~mjfEoH%7B>3`%K>EW(=aI??k5F`*mW{Oj`9CrIW3o>!JhO6;MCmqEb3; z1S%N$A2g^A9D7_KAL~OdUX+oKvgU3xsWI#uXw?rpc!uimTNUs=qVed^m#s8>9SqKUtFt$SRdC|A_5mU@r)0%#M%Sp1F`5&Yc$t!#F(;uMx(io*>GvdYx=B4Tb~*Ofo)e% zJmqs5Yomxs>7B-=p;_Vc8jY4N_7NgB580G27`%C7O5pa|FvvLjqRy(Yxx%4~~9$Jb111fL0wj<4%H z>##F-bRe7d4V`7W^=$1#a(z={ML5*}H1k^;D^hg~U}e6Y^EOtg)K;rPH(t084zt@6 ztswr_#f&o=Kqka@G-@WWeNdS%Cs+@D*G*j0sG1>D?#Mv%#`kP$l(t2C4Bz)LBgnec z)542ro&N*Kbsy$pw>8+q{GrCDrGA8)W>LKMM>?-QN2MBLX)>y8^<%`1(Z?Q(D5^^Q z#K(@K)t(*Wi;4VGOpYKoTL1hk&pp`KO6Ms@a(9HYt!O^|c~09@ZO$YP6yGj_wbm~r zD=+Xk<-l>rD4M;0nfKzRZnLtYx!X4RTo&rHUs-AB{#q)cU|;8F<+d_fQ~ssoj%V&igfWTo(*Ek= zg^x^+Pbv0}{^lmeXjfoY|87#FcsHoJ-9OyK2y!AD`%i^B=o=jVWwK((=82w(%>IAp ze$DvA>Sm|qa@g1w0Qoil$)y{g5VefPYvd*BfmZIQN38!!RQk3)NV8yt=ot-2vcE;_hVKCY%Xxsoi?A+cQ?iCW-?n)ysmSiTvzxmqnNLiU!{-7EaG1pn zKfj9BQg<f2)SFyaa`xc)k&09aI8W~n+^wtZNJdmaQBk7 zs@|?uTgEXcwq%~zfw)`exRPZToa9RdwBq=ZWR>1xO9VJ4l$?#B@g5WxJh9}6yAE{& z%x^i+MN)mX@r%9ycW*@%zp*(nNiz)1`DO(H4?Bwvi`$ zMj<2Rb!9grB{eF)IORH~!j}|yvS+%vabjeEdzQgn-P||wp6%wwkr()y=NMcUFs448 z>*TFyPDQZj$p1S}cfjPWDq72C^o!oF=9qoHwCEK-2$y`xZks$th4=La7xlVPmkyKW8t)djCDqG?;Jt>%XLPCX6WFF<2(MMfSq8$mJamY zN{!`O$gyd_R*#glO-VcHl&u*W<3R1Xs-#j3hYD8g&?g4AgrGfFYpfXUi6mR2(Kc4i zEA-fsfpK?D$;!&AjCZKGZQ!hjc6HX;ytEtYl>!fOH0Mpswy01I)uQWAGJq&d5vVJ` z55CqW(wZLYE=39Iv;aH)NM02>SOB9m`x_@7TCIA)xFNivoDm1DdT#ZX}J|_ z9*8+^aPf8-jmp;_k9|9ryzPxPQP|Y>?q+TEF5{}Wn37)a;O?v%(>_~LRKIGIN~~0C z+q?BvQlTsALMvr}`EguliqovZ4%tw?q`>k`Xw(|nKVoh(FP&xgCLnIsh*O!-3n!wr z#ug8;vZLAvK35KG{8o*d?5cMvoot5D4IjThfmOIcV@}hJK2bCX=m_zTUFC{fO)u}X-olXYu+XX>m-^7wky2RwzwUFWYq^ZTQ5=XwG^Hxq#Am+78==Y zsVSoOY(?Sr8j2Zpa;ao7l026nD|Ap9$<~T`gR;pUU+@z0Q@UO<8R~4ypYo7&Ji9-U zfd~1xJ@6f>$8Ueo`;SL_*O2GaLF+$Z5A;E| z{uB4WkJ9>{_2&7c{ZG>Pn@7eM)1^Br#z#g+W8^}jifK=FkwqACt~x(x_ETJJaCCt^ z-hl7^RKSiRwsK;i{?BTKFU*|)yp$n zPqBGo&816SXm-DQ;+mpL-!nbrLjzoSmw9$j7L&Zs22_7% zbDsd6#d?nG3AWNEq`jHLZ*QanFGndKEBvT&gUl`%x>#t z9`a>0c3$Emo3m5kGob!{sqY!Gxk(3ebsNlT~O2kVYkdinXh9OY~vm@i&s^IZo7`7(Pv0+AW{Y9DjJHtjV&ZXBBi zR#&g}k!k*@&xM}(LTBq<=OYi?n!esg-iOxo4ZdfHU`>%Vdn4cmTQguy-sI&*v?iXl z-Dxzk-)!?KCnYp$hfb)y#X)o&%H`WHk6$mUoxjz=q(h?-;|55#-sYye!jpWdfz^Jy zhufN}H-jx0;J(AnbzbgumG+sXBVh%XB{x%2GckvllR%Dw#Y;$RE zCbDhvM9oDdr;j-Jwn}j&Mx*DW9%7^346irl@#REy^^e)yiE6z;^+sxecYz`c^>GKa z*ai+8K`5i=c0hG5&iFRN69W+O%TH)@+V@(wa%4P8G#>dEpVX;Y>4D6Jq(r@S;pg>$ zUH+6#&SRKDX1#;iZM@X8G7vjXpY|~$#aNJi{)~%FE5K!e@*?JEb!NUch|tD}`8gLe zf}E({=;!m?TIr2D(rejTgkt_*$R*sGRJXN~X;Jslwd`SAe~;dZ73~*wBIRJyHB-An zvz1XM_LnT;rer!)Q^Ab-<-7;CwyN_~ab;D~uDQytaN88sV)%-bFeirJk$`F=d^Kl@ zf+QOgsu9|p8KJ9h_2y*D=4nk)QTS^Gud|v?um*BG-oZ)4`MTs})5ewvCv!dfBI2Hc zZ%CHdysS5pC^I8k3x3nZi*X}~#|IGgPrsFqg3797vO6PKde^b7*b<;4-hvq+AyA#eQtDMw_&f363tIGgUt+n2m0Gc8r#% zx_E4jL2dcdLStI#ElJZhDeSiNM1aK^?4L=w$lc4PyV2%!s*A>@A&>UwB~4CvhVf#z zBRZe?3zas%yH%f=4fGn2Z~4oTwt81m+el7yJv6F|D$oC_$ZelIjj)N@cUq96q#vc3)?Ow&y5hDg1`P z&fyCb-oBW__bYi(=WyhU?O!mvlRNS`d{dIgR`ltIJsQAVet^XspQS?aD`{8G+z5=S zKL-|ESsdFH_G8NlM*W@k&+d+@OjIXpvq^1Rgi-HlRdECHL6RmnE^HXPEm2nY!3C|I zj5Mn4HWdI(veMXX8yvGu50QPir5Y#*=DyXvTt`5vQ;+jrYhBy z_33rV?wx6CDsaYK>d}}>Nn;LEc$7WUPO{4h>5hs5T@l$z6S^VbOYE70MMl6~oKN7w zvULdfh=-e07mzI{I)`zDLfldvU|WMd@+0kMh$1)g{qHK7Vyx0p%!=@kb#-F*E3mgm zN!kdV{;O4@+zkL$_(w~cs488dYoubF4ntnuF)D9;5?tvS?X%oXvS?eNva*`*dQdFe z-e_cx60{e7Y(b^EycNL`H3zLCPi&0=mf-FxF)PPMw=O2Z@k38G-w9;#jw^_}YL4QD zT-ner#PJF#eB7Zp&Xrjb@V5ym*0kx$fEqSRn;oWwIj3ZLpEixzs;0Ywr{)@YlX z^AV&&yi**!Q2CIaoLcZ`<(5Ry6J$#kO4jJyJS{EO(mgTl7)0R9oTd@Q;GSB&tCKWE zBsOr)1GD<+HZ>0)>PWVoMq}^{i&+n(p={MNP1>&Ryr*HKN_m#fwM{6ShBEihHfZhf zTB|;9I7@sY(42F0;-*AMIA&dOz-NN__S}NmY`p z3mHpqz?i?(WQw4I*@b*5!QRDUix@>~JnbsH`pZ;ecvWMt#$BS3x^pY*oxlhY8V$oL zZM;5XI5PZR1ClM3tlWJW^!;1QEV53AJ;dEMVsF@( z8rkw8e|WW&ue`jNcG}13(#YUFOthX^)1!9in28w#j;Sx#7$nLhXoY&iXe_K%c$?>^ zs65l)^kuYQHR`ko6^<~)ed&*(`ht9^YYS#4yIyZPRsy>Ez8xEwp{XsM%sr z+nrXryHbmAJ_YS>Z!M_Vl}#=q#BEt*VQ(mC;@ThA_BPuhEb~O(me44i+ z`4W3(Q&GYBeom@5a5dSYlj#E_-``D6cP6bG-8ULYM*B(?CwYB$E@{<`a6#0zzRAg* zsCODk1c^}$sOltd7Kh|xkUh3U)Z(9XlDE!M;&q#Lxs7h-jwdvhYYy^6x^Kqvl$$-^ zv79)mWBXu4O*_ehA5k+-?!FjNvrclX5ruL^>pHn|gP4kqz$$wjd3JF`wVRuzFIf~S z5$Rb~+WO0ChuBvTvMnas>)a+~?Xl@9>Q-=_0c0r~29Z`m59SrV>K`ZL*8V?=l zU{is|+$vf&lTuQ5Br!5Kfd;h;Sywk2_4#(a?J8o#9w%rm)G6d#OY7-4SqNZnva8ZI zQbo<+bvrs^zN4V6t2SqXvnx<5?kxIkecBXNaJuFao!w{1JE)tN*jYg?gnwxlT5drLvQzM1T_55%xpXs&udp)H#dnit!Y#zo56EY{{m z7>!Lv5&H)gQjYHwmA0lf1o|InOgyMyP1I}K%%B-xDvfjWi~Jy}q^RJ@r6S zl(`U%`-c=V-k7w~DB~XW-9rl*Yn7?`bZF%_REO$eC8?PN#-$MF;U#B2-5KUXpq6`t w!fB`kC>zd5eaE>+XRw(!@W0cgS8@7 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 literal 0 HcmV?d00001 diff --git a/vscript/languages/python/python-2.5.1/win32release/python25v.zip b/vscript/languages/python/python-2.5.1/win32release/python25v.zip new file mode 100644 index 0000000000000000000000000000000000000000..45e569faad7cf0d184e079f6f2141a37ef4a6e8a GIT binary patch literal 4546978 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

Ded{+{@9z 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�QYI1W-kaFfF>jJd|)g5bwHF)BR=Geq$ za0dCN%2BB%YxzQOc#T`iK8&t`1+nma?q;t7LP+`4qVTIY#w{9&jD@c*e(TSJx z<4Tx~5(32^YJrg2q$HM|)K|5ilZOvqKc1c8BI2pZF&b%=ExyqFfz8sZB`Zvzzp7mT zGIdzJn2wzc$}uzBeZ>Sp1WNTd$x{f1u*+)Dh#eaa$I-|Qz8mwz=E zbLk+c#Vis=aiB_uZs1c-yVEfKCi?d4{qZ|CjTwPV=0-52^|`f3(S*KJoA>BDiL)5qP(?NzZW1z@&|7Nd9=%1C zG&W9;gSj-Y@Ha7WnSdg~>Q0DA)Dxfxt#1s2&)Jm;(bLT$CsI0St|c~k1-Q);3ub5@ z!Q&uowghYd`g{N{78%1q7`<;I!)gu%9cWuH)v9g`#^g3?@s8gWFX5g0^Ai3p`uesI zLbB!0nJfw=f{yxZv*=QiCaAm2IX$k$#~vo`oK!Qih*i$Fv ztvf}%d@}U5<`zXTBvb|8N&21Jddc+722nGxs^-li8`Wh*uwi{kTZ|M`U{%3p#hd(t zwa00R5}b%F;UxEnXpI*Y2VR$YWUJcGjfDQgR?dD)HHKktCP_S3xGWySPY7z{Z8naF!P~+>YGB8Lvyc5N-gF9F-b{a1pZ0CYq0qce>?n> zU}&C3mTZawO^OxAGg)Cnhqr7AF)SwbZMvm!s(6Gqosv|2Q+P^P?lmE)z1oCC%SOQ9 zbg^P}hwg7}GQ6WwZ-lEHWH6Y6oRdveO87{UrBluURG3x_KI-_B^>c8r=gt0>rFjI# zCX`iBcwOg64w4jmRkE-5hwH1W_*ZSiO!bYQG0Bm-z!w&FfjfF~gTW&W==F$`+APGH zV@jYh4YAaO$`;7b1mq(dtE^IaWo9pn+8k-Nk~+vFK7r}TeTk-ha(%OV9Ma*u>)+-) z8=*6l1bjJ+%rzBDC1F~6Q6`j1LvE$338fz7a3dRGXW=NGf~52saw(z ztNRnun5wrE=$nc?wO-w0tz~~k=M^$a5JX2?>O0;@y-o#vez5%JBn4 zl^~mi${UN!s<^&W+K#Jwp`Z8pP>#4a*ytvm0F^7+tKD|vP^QVrc9oYK?G@0+GK`F#@w zWNjpN4?gD%9Em}JNc(YmZTVDpOQ$Bv9`6|k+c<(0dfaMkC}6P^+!5+cqX2WGftHCj z557w+LrE$AGs7z(A-|V9+{c{jB}fzex{gr6FlVGu$LW2+Q1UwyYx zY^D9AX1CV9JRbJS!Dbye=@>f(&0!M7kexG+>655j0%yyo=G>XjOG%7DLiyI{jAScF z3o@iOByS`ypc$%RzKiB`II7(Qu%S5Z?T0mM-$7Zr?menl!#9Y=EA1TN{fVjNrP1Xq9E$ni#d98Lklw`p~??N%%3>Vcs zOrgkz#K+icBo>A+j&mdKtY1ydSLwGz&=$IM^h_Gt1kTp2(56I~+^%usGpA^D&qzbY zDP;O|PcOCVb~Z~q;hh_ul43iiRcbcYitK4s@m0;~qMXbLc3UW^jn`f-bu1Uf8uMU# zva|lf8Z5nu*ovE^?fn32&)ge#R9BIj4eAOL-K_F3A7n-8%~+%H*v1(yt|FIpflK`LV^_`3krH|w*jJu7a%%0rdFh{A`uIQlAIYDl&pu@c>Mq<~>)!Mv zL09>~&ZC)zx$DYTvMZGIc!XZ-k9$W3M4)t~PIOXSVjaHTq>Cv_MxG}tHArNx8aZUjw>P3yH+M7lHfgdy$?)=9NeHp z5oQ?kjDivipA32(&swxd0w1=Qla$5Y4GPVKyeCJOmIpU@ahrOCQg5#JEj3_xg%zOe zwbuEFTOlDVmlU5l-_skl;oa9*D8ByM3dGCeHdJ5a!b15HERy_0zlY z$2lAe+G24@H?Jr+LTF>`Mmx^9N}0el_&5wX7Ay(?@2BT1T6K0&CV=tcslUVRL_N@;p) zS`R8l}FMt8vSVH#bC1<6BxI?~yyBZCNhxn;ty*}9| zye;+^CP;r2a{tiSx>5om0h)8`t7wOE$1EGex_Vv1+F9!@-Ae5&-s�HMWJERv)C5 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

m|Ktx*`qHSBcj*t#Jj93OY688R_754Zm=8cvc@ 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

$zAt@> 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%0DQ`sD9naVm3 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

W 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 z zJ;N+e?8mMK@~~_jprx43Pi1aUPc&vZ@vETMRi~Gl#~#q29bmA*OM^)2Y;WKmrUlvc zbG}YAXvCMbzn~&V7V9vp(t1kqr6WD@Iu#og*Dt4=D`~1pltxe`oq~f+AG*%M8Azii z4IC?w^jmBl4Ouky^&ThLv36$@Ajj@XFJP+d109LWy8urkgFHdvEwo`^u#Wo0ISBoQ zQ?f^8?Z1TPog*YXTEoUrA&KI>h)YDd8OXFjqQH`(n)kH-;LuTZ4z}jxe95dsJg_jb zRRaLX0mj1VE8fl?Z)QnE^ReQ2Wzp_9a`Dt21J*p4I|6?fbSVfzYEZ%pt4Nd2o&-=G zcWZD05d_-L)Bn3Z%*(8-fJ^*7bNGT8;J0^nPFhO%CLc8`T;v4Wi@OUV9<1TzlUJB` z^iS@GKF7=Ip>pD5ODYG-B0yy#-Q4*!Se1Fe=upepVhWBgDKn61c=DUt4fEV#TCr;f z%(Y>Nro7-|YhJ$it^s@`hKpr`asj%<{w6kO@i;UK#jr)b(W=|N$}53vN|-R4;N z^kPjtgielAU~(Clh=>2|+ITHBoBds{4g8XwYz|jG`-~_ma-5 zC@vsl<*ix^e0vvh9ZBEifqTp*k@Vyyyyu_dd49B>N&iZgM4k*L4*@s8ex z&hlme)(~A1H&wlwQh=uN3Jq^-hI2J#Edj(JUg#m^i$@7_kr0D8MIRIU8xiTZj!gzo zQH0t5aID`Fp%9z*Tdx`1SKG9zbWOp1Eg{K+xd@1=@f0@LLR`1Ej7-M%-rNc&OyZ;~ zwtyE9+i{D9o*+amR;%F#ENXN>Rfb8^gC{6?C?K)JVT1=FajYX0jGTHIa-0h}5IMCe zDPce-OvPa^x#sXqjhA(h?_dFxd1(dTZHcr^VfkI1F!Z|47)e0n0h~J55t6~IcfAS6 zTDPPrDb2%h53!CML^!0{6wOz|D0Pt<85T!}-$`7&@aB?!pbmVu_QWiGAXL!wWouH7UQF*}y-H5}kKMV*)Nn zg~=O~%asqSK>`(~CruH?knJaUt=#+agV>wmNs}!J4owNddd{Ky=1CSx^V9sh$uTIQ z2suo+u-8%hP6|q?&_Q&JPBmBN@-G*Dl6)UV*EN}vbmNoK80qY%NjuSEpJ`O&r+Xaa zF?U=Y438jOXLKH;!zWHSO!is&27#}^(aCckiqkkjJ(8x@+T$wlt;43Z{hecf&cRj{ z*Z{kN#pM+-rC5#j2al&yqmvD9Sfns8A(RN@h->?Dc5i3C=RC1&9D^JR$Q-+Ze9H;u z5<~+(Nvsm#sJn?*2|sv)!RkiAAld#2M{`c~<30*ZXP5WUPElqW<)Suipv6PAO*~VQ zt3&FWIJ1zg!^C8!8n^%?8eHS);F1`=3?w)ckwXYEHo+DnPImYHdfqjsGdUZO`8dR# zn#<>=ao*hJ6@rUS(w?(~F@v~>8i0(3Ig#ZTqy`y5>!4d5vEyn5mSI&`;O6jB{7CC_ z8|%@UB^)sgy@P>)npLumJi40ZHiYSFvg(T0n6HsG_xYR^wlI&E{ zi_qiC6X(jziKr?U2C%SrZ5wqkc{?%kk9nl<(S*2nY)1SlIsE zYK9{Y*DXmoQl7dkilsC>DHI_Y)r^>;PrkT&Z=rN^&!>HU-!}n}@Rfq0DNs^seeR%> z5s;_>%GD2H7#kcHc1^%cD|;^LFv@6@c*sowg*kZ(t{Q+L&=y%B4)uLmYoR)=TP-i& zy3HzKs90j^^{-v7&*W&MGyCe+g}a=g(&ZCzO`uPZVMN*T=&g%ZAwwm@nTHB?IPx_7 z8|rELh+z;}UY@Y4@JWIZv}P@4DMp~1+`MN+T7FZYt@@&xQ@%H}pD;W{i+G||HA%G; zRHcV$wrvJx3*@E%I|{Z+C@F+$+PKC8vc@y@51|=)9EIt!)HqFeawjKx5$;Re-VErO zT|;9Kaxd$PvRA2c?@;fSbq?{mcDtggy>;87F4%tbP8LdW##Q^KuUXkD4V(_YBaF&E z;Jb5`)=sxT@Zr(wvKj>Uni^M56J=xT3`T6h5}%%!8md*Un01wH$4JjCN*u1uu0YskLNzxA;^g)KJe~WweTdw`KdPp; z$UW4(^!qA3Oe@zoDoX%sikRg6A($Y$7Fc!tLy#r^y&=jgYb*1#$KTUCNBO9=c~){s ztI?E79D)Wo%gRcMyg5XbrNzW5ggu>If!lC`xi+W`NJG$~fxf(~Iq;f&dyQ$KMDn$} zwB_7cBeDg;5Qug$80uUt%v@huBo@5i$!R(FqN+LB6cNkgljoj7@Y|IJX3gvD5K+T5 z;M!2n)oo{ivVWV3^KOtWJT;u_ItmAZx~8Jc(XAhztedJ%vNEELMo?-UDNnb_!fk7$ zAvbP#(slAGvQS`j_jI6ipuXu3(HltaOL_LLg4;$Eii$?JcHdBEmu2r8QUAVH{cDA1 zU)=?UXWtM!(KEGQ$F)2AWOlb}b+)`L>WZ2YSE)=UNnrqd4K!r>`nNu9_jAyf?37zo zHsuagJhFW^G{A}u^3ZCJtN|31o*?zO5_m%mz6K0Zk(Q@td2=cAgf#dy$QzMCLPj_q z%q^bjO>(Fnd=%F;d3$iGVA;1Cv7sLIWL^RAVqWN^j? zgc40b#@#li26|3N$-RZLlPS>(L7ko2T{z7azYVMic%h1H0LH98!b64 z3e1Za&^TH#7bvA6-Y;N3Zz+euwIbH;e=5D+xbfzs&6O~4m5u4_Y*LPj0!gVWHxWJ^ zK=NNn7L=x_0_GLYmiS%FCQUc%G|$1VZk`o2iG&9ac$k!q&b17=UW%-i73toMaIpIW z*@8tFZ)#9Z{i&>MVC$D07~hC zC#MVUXR=P3S2H)}pD4fPUOVa{Ll3?Kok&!7eVt} zvT4&kYNFSYVYrU*E+aiR*#=+d4MV5~*6>I0*SZM-?ocZV+vt+b{r^phY4o^D+f)}; zj&;MbMPeYQ9$`2@4zCELa}%;w-vcsY;s1?M>!htPQ|Z}rS9YZ}1gdHXu_O+!5mNoD zDCgR$(pGn`394rGAOJ=|HLNeZHdF&D!?mNQQ3e9YfG%*b9V#(QXiNHAT+jwXX&Mj% zqv@7e8~54JSny+IypYxQ8V1ZjdP5d8Oz}Kx%|C8PqB1fT<5O?P24;i*kaOXWNN-Gk z1WZ4Jr}pKmb@j#jY3}2dR+VjS)g&8-QILaXfF=o>2$b%R*f-Q|QFb7~uopc2N$M&x zwQ+P(g@{;ryJ^xe0uqTM>J?>2_hgeWO+95dIVy;yQ+D{Zyl>65;`Vy_z^&EV+X&faDl@8eqwQHz!+Yvjp zB~uM4EQsq;w}_&LszXsYs>TJ4!0SvrWpfP>8fqPqIRpa=%o2>KatIP_4@qyi8aS)W zL&F?@&2VYcYPJPj0mTr6`DoLDQK`|mdUp(r*Jkw9)WGSYb@x#GP?g|gRIO|2o`Ej8 z9vony1SP5+f+izpHIUZaMK=Un?xqsJ0+Jypi~b+zDa-Mr`Df;Y9<^--D(#l=H_Slw zBrERn+DS8V-MtZ4q3+>;Y!!g}!^8d>5R3oiPR%QxWB$H!UfowIGCSbl<{bir)w?-I zglJ=CxTAfR%?))kAlU`jptT2{7U?zEwU{8nq!03&Ocxfjl-c^Q{A|>bpoqKqaZBFK z$s^BxXiM1r^GkL8GSO;KNd?6zafT69tAcECsyJFyDX5+51IgOvdMSTdypsmXcS;NT z(Mmp{1bvX`0Ojb)Ma+n>+!DqM0bJ-@tA0+N_p9pYq@7iba&tyGo$GC2S55lEN;DQa zbMp$SCyg~4?ROPwh9Y#Hu0q*ijf+`B@|hb|NLe2eDyLymkSufUFF_R;@Aoc90X;wJ z^{mRqG}aLTo64kpZ`6>Z-u;+rv>d8cmB{#1Ju2%_j2xbpGCyLWMS!zo4uB?IF6O_i z((J!xE8tMuk18nl-!4?|SWtkt)OPD~kP_4gXSKqN#efD^7`7pa9lLLf- zO1wDYg|@fO(^3gLB4D2uOyVNTz3lokqRnDfIf}UZfiUF)Q3+mK>&4aD= z{y;rBPll_N_nP(8Gk|^fYc6MImf2*jsS)oT=5P`M3$eqt(QU#1?bkYQ)rG5=p|WLH zKU8)-5!TDTHk*v4x-Iu7M@k{bPZSF(Ric{f7-+FyBW&6XNwo20-+2YTWpg|)HVP7M zLy4|}4lQcY{^c-Ep_D~7RiGmo25}y@RQ{03md)XrPbAjGx&HjZf_%Ou@B4?I3&#;- zI4sSszlAZiUX`~3vX$E` z!h3}yLCSVb9Z96Ib7w%+&M^J#vvrmaILPFKE7&5A&bn{<`RAT*Wq$tjDw%grKl@yf z7b8asUoEdnexa57h1I~=y?46IyK26@(%=W1p9pb-A&`^WB;(Cl@VYMs z`&|EQPl4sQ4#bN?&mup4Ki&gZ%Jya3r>>L%(HB2jSv)sSs7dV#P9rGA3$>Nm&Ld@{ z{>6n;nsUghY28_OP3)d%3W=781^_kZ{?d@|j?T&SE~_0|V7APCIk(2;$|B7<&k>eQ zc`7rvl{QRm&#<1vnxn~PD`y$|IxqV^PfzT9ZkHl?y-*-ch3%NwPE6Kwnvl-m@%M2L zk5l>k889Cq;&_bg!ZEONoJPHyBptP*vc1*~#UWa1!6jeSQmlT7Tn7EUBk4)^} zKd~5=rZnt|Cv^rc8-wQkYR%!9 z@}45PW`mtYpDl#{YohrlCs32S^SNA^Q0CNY1Jsem-4!Aw78~Ow`bz9IBWF#+ulGrY zW{o4Tc>(f@hO~x3hD>|`%G(Y#KRGd(t6^-{MaWXzxd%ra1ATbB?O%Pk5oBTEa}2lB zr&}XGIt3^UTVo$9&Q-KEw==h(UR||@YCB)zEvZ`zwg*=;w|;tJk{}j-EzNRi9)7u* z?Dy0REiugiI&t^NfAYm}5DKxNG(fjAL~4p8gM&6s&ys=t)NWWd2mmw>mo@Fo%zo;~ z=nUKQ?40Ki&D___`uypfHD>NrGsondGkfN~X5JU3>bx;?ubR8asabo~d=03YwIf?G zKL>kGb6?@0qM0t(@94=p<1$lLEduUIlbro!qWcpCIS4CaUr~vWiLl$;0)Q9vH(h?^nf1F1gPyRnF4oya0Nl77!->WyE7Y`Ol^2_;)Mi6qRz#T zosY}PmSg(5R)RFkZcnys8jZLW66(?s9xN)$N2`{LQT4SIlt8gQIDdpuUp=ZiGxd+8HE{$mL9YE zQ3ta~J=e{7iYBGBJ<89*KN4!!6s-(>fcoQmd(fBTDN|4rN2M)@zVa^x$94S z`8WUOs?t}fR(SOGT)aB}M}Be3<{$V6rw+_JFPE)+U*+2$Utd+-s+!?CR?Uo6-SMis zt~xhfozUI->fE~O{Q7EUeKn@vxA^xh)yyr``3=>~hU)yS)y%E&Y(sT!V>PqUC2+r~ zn%R`^H&-*8^Zjkr%xzWo)~ZWRGLX*C+pF%Ds(VM(y|X&Qi~PK+njz)xs(Vk>y|?P# zr<5~POrHCznLDfA#%h5)WVp5J-BXXD@T*5I2nPveV*+t8-hc^AA=t4_0IEEpDsU_qJ6ZZLXHKRAc=09@2xw@oMb- ztJL^#&htns&%=?Y`$#qOXw`kRn)yQ2{X#YKSk-;3nwhA&6V=QYtL_)8neA0~do{D8 z>h7p!9ONh~?5?`ItC>AjcTY9*<*NJTYG$hHPE|8|tM1-vX1eN5S2O#n?!Ic~nX3CtHS=uM zeYTo;uIfHl%{*UqpRZb_FVe6{L+wVHXg>b_ddyjFEzt7cxWy02F=2deIYYUW_oJy^{gs=9}&nK!EL8`aF$ zs_xgSnK!HMo7K$Ws(ZMa`Fhp;dNuP_)qSg)IZ}0xR5Nc^-M6cmqgD54HS7CfRku^k9Itu@s@~gG?`YL~r#b_Do~U}aR}1e}XR2!b%r~pvdm@B` zAA-O4tKMzZ!ndj}FTG!VHeM~=R*m(@@_u#C;#f6y>938S{ATqTcPHN$Ii6-DoT%ww zrs}?{A2TPbvs^!@y5IEA4@I`h`d*#&`>O8yPWo1zG@FV3`>UC`sypLXPgUKMzM0Q7 z_Ca;7Tb=J!GdsQ`LnwwPS0^l2Zq*J&BBz+ z`4a=L5pYXZCN@(fMnjJk^x{IFcmb4?jYg~)SwZ`BA-SCsMWHMtI3Fi}a@=`;X@yhg z{dzJqLGhAK?-9thSMBv*-0T%dnvi^7&mWsNzkyYQK+W0m{717fFV^hhH zuOx+!pEa|T9t6tj2cC#%m0wEFHov{lpKp}W3BcJ|^rkYFnVt39poO3jInhbdVu4uH z3A6FEzj<^29(wrk4(8Z;_r-~QFFdnvdgAegU*d0)ey^5wc`|PA;5I8VXH5r_>y+hQ zE`^Ovwgp;N*~2D6%XbZCx7pIs<=aRNEZdBAc}xCH^CRU>QWEa#v|Dp7G%uT)=lo&< ztAzLEThdM6NkX@ibkpw({^>na{(o=%|K9X_I{m+IVVry#4E_^JUgz5vLVApUW*M&I zRp+=7)qjq3f~|!${3%XSP6q3uRVfi7B#5a|BpU*o$Y@U>bR+NQnSNPQb`zv)SuJMY zV`&~sNN%g<(tn7b^DlmI(E-DzpWXYx`Gr#-1kE$scZ7%+`SyjH4PzU|*505GdBa;C zHK@{TS}Dv<%2{0b&}FWKTxI?cw5m)};ld@*q0n;Ep$AD0z{E(C*yDD0gwKw;xg#2B zTIRd!HE#p2yuvq{xBf<&_XT?N+RX!Y1b=IDkz*M`7jkpefiylE{Ina>ho`YTotR_a z0UywX<*O68I}o>pE>7)jl*B;`HD1GNjNl5K8bV~ExdkDwOCeN~5X>#-jVux}MS)TR zeW!?eXS=?hw!7G1485f=Oo(@ru^w5PXzRf>uc4T~2UMOo#Se^CKft(P$X85T8lXpmXNl-z zU7&Z&0%X(F5pQY;>^iiyypi151LQdOeHB)XwW;<#5}QKTM73&Yhp$WAFcv_Y7ha7; z(c5zu&4VX>-Q(+&uX}x+_Vo>45BvIcU*Gceh_7$^deqlrzJ9~kj<3gkJ>l!SzJAl! z_kEr7^^~vkzIJ{6)YqP`XM8>D>w>Qz`Fh^h4}D$oHQI8?_m_R``?~DwE?-xC{hG(| z;iyP%uT~5BXd*(x3 zrgnd2_QR(huW3*e^SXNE9y&SE;KQOTiB;>g9uhsSmkg(yTeL9J&4#LXYqh}gWxaE< zrih=n_$LdR4bJ9Oj`Fjb+2|A&G?ZU|HdWt2a=pWX<((2emHDo!$A|UJ-PL|XOeNi; z<%yE+t@fv?Zg*ApRXsjDxW9g|#Sb2+dVF}WwSI7iA3Rv~`0!v`{oqbNct}#D9z0w> zxXTY7sd{{P@F))+)_;;9A4PQwR8tnNAk{Uzw7c^POGAAE_hefsL7+)CL(z7~ zRp5V55|b<}98NRCa(3YiQbt{jRDWv8g}HM?k%)-N5qnTDr?8LIopj%-l~WECXHo)L zT}&-yYF=+7h&{VP@KT#=Z0uFZ7o_6sDWKefoG=YWjohhpP>*7JPLsQ?=9+KqEhy%= zqbXjEw&#t&2IFZJgXDBxYe&rhu^8;%#XC_zTxPf z4W%r=K&t+uTw**o{pKbD5CP(z=q`i+rUjWLF4?bn+4tt*uf2Kb_=#CZdOPsW5if4O zDZl7g;)y{ya=TxX1@H1YlGyFCu;|Wo3PkTLQXGU7rbTEZvFx_Mmb<=@$gU&ibtJ$2 ze!l$&xKs~r8QVOj?-$1I8@qjM)7YK-n^)8F_ki+Bf`i9`8k+qX58=7TCnX^EA0y*| z^9tq|v}lv8%NUewSJSq)h(>9N9Ywq`dLP%!I#zm)vfhulk!i^>$i6b0J*(wMI$E{Q zF{$2YH?8%tJb-CgYvO}GQF{b+n9J4_6D2vGWe&L>TusXi;;>t&_IMM|=y80agGDpU z;Btd3=yGp&FuMeu)GMNH{T(%?I>My8cwXqT6x>mduDS0_Nq%`&c>JG)ehcZF>IDPy zUgaJ;!cFv;=H*+er7tkIy8D=QA+LDGl)9C#m0?O*uSJFuQr27igGu_h39$b>rM{;l z+9q;{R5_E|Ncu4i6Ml{QTL_X~;mxbS{glK%Pl| z9j{RMni1BKUg78X_BV2=#_xj6w~QHCDyl}-C4K}#mNo`$OB6vc32f-mc=ge()kXCE z0E(zG26&MSwh(r7Z+T?F;t7eyA`ix@)A87nP87Jm89t9t_3;SmpBLDkY{8xSc+b&E zttmTS<3h(#OE>69YJ}HpjDuVfj73diCpi$SA963y|E99eG49MWRPL;{oJk1cyAIE= zK1Oe$3;hM&>EEt5@7z4LaqLmp#RFrts90lEl?f;G*E1ICM1}mg$7rP`frzcgFTG-v zN`8#Q@oMXFV?V?`BXTRtkFCciRr=8daVC@f{sk{}HU~|;!NX-ySGZtw-qvp|G7Gl{ z6B+IgrY(EfH0YUDe%0WkIQV}}sOg*_#C*g@lFgrCqZi4(g4f_Kp3f_7`7~o$huyG^i$r1J*sM#p?qv= zfvv0HO#9<=wR5iF5&q&iM1 zv*u(6eAaW4-k!ja&3iONeYo8J0);%mT+Rkc-dRubr_|Q+FYr7CFNaF^aXF#1logQz zp&-9r$K7YDJI(U0KEB?Zc2eS%!7U>2E_AKH*Yq~4WV7-P8ojFX4P87XuGfo1x-hTK zTM=&N0*A_+vKg_TDb9tyF0&4LVV>t2!biR%LCzdJd3bcbs;WE%dotEc;^IS~Zc5BY zns<&XhghkL4OF{Riit&xl-R;nYhCHQq&HOYX|q%SpEqxgcRi6^{$eLqY~I=QtAlPpHf2AYTPvfN%S;N*Tf+^r^xuWTA*sG@w!G; z;!h{-}#}HKv`1+w^(of$jvQcc0%0-sVXJ!{&tEpYlZj0r(mTpBq{Jd19#MOYqbp~ zCEgCJGPBE-z~~!w6y;UscoVz^XWCFL!1__fC2%*FnJMM>1b)a+u+-VOB_9F0Nb z?t6@~GTU$ExZOFZCRKZP^fZ&ghIm)PIV}pH($hQATo!UX+S-AqcWQ!jy?WP^g&H7k z4-o63LV&xg&cyr2Cne+^?LW@dUhy`pN@IUlKHfvC^I)6(9b~kNe37xprlU`^Yi9Q9 zO)xqi3J^`O4cPkxCe7}H(?lyyo1N`H#l7k$0PBQHZZb;+*AM5PrHPz>YAyM-GWq1P z93ae1y_BES8aJ`o?0(fbPg+M@(hN7Zp&3QNMn6&p0nLh3E;!~A=F0Vvu^wO%oW-}{ z_22oX-V_6#JvFyHe|9!}U;4}1A52NO^|0Q$(Dzcwo;3~YHFFixeIs-@m%W8tzx-3< zZ4Gxhu=$tyR?`ZLZbYA1`xw7KY2VTq-_K2T%Uy8TEn|0$ZyMXQZr8(`;jQZ!^^f|x z8JT$V*d6cz{*A*6ZWTX>@8(#GiB;))fN!B{U;+`R*J53mef9J@ zi<9p3OFvizL*vng>Z>8|t9I}$85d55ObJI%O913pGDy6=}21RtTC4zeKaK5J|{+VqX8)_#*MKc=AiXG`I-Wv(6j3yw1h!fa#T(?t5e5 zrJjw1X>)+M_s}C#tiOc#MyB%m%Y-UjFZR95YagK|9*b)z5&x+AScVgIvF>U@PR(^pwDi5i~*{AYNzAY@xMq8M7oC z{i6cxZx+3ie?H@ZrU%g@N^kdw(rlS+3HJunD1ysDcC; zPJGu^5Qy8}pn^bCy_@gw?0>CcJZPUA##6WY$D3Bq43eHkeyEcYJ(=l@#lD#E* zP=M5evUtO!sPkxF(5@_>-u*(!gFo;*_QA^3)U)$J+I7OzoQ(j7qnW!rvu*c7@QQ*> zh-T@k6gS*l9lhcCx%r;&Q+o87fNJ%b*{};`i|YnEQ1Z8jOA2%Tj~a%t8LjK>W7}EJ z-oxtE3`6s^h|>(?d9p&{3uuMV0>NZKBQx($dD2{xE{TWc9_rTEc(14J0e-&IuiT#b zx>uXx-HET~f%c^_ucCrsuE-8CFV00A^7MB9TBLN``vsk;; zv}3K3XrxZ@bRVrqMQ&Epw?bes>8a>#%vxX}(4YEX@y_^VN~`C4OOO<{!RlIWZk5IrDwNm( zW&cK(lve)Vsm886sE$7P;a%1bK#gWAW0!uUdXFI)G{A!TBebJ{Ir|Ns)@4biH%AfJ|DZBEw4-50h1)**Z1^&57$l!?0oxML?_b2cWghOek0px_GKyrQ;wS5w2&mSn1Z9z#>?`B_;)Bu(050 z`mwYWJ%nC!mOD$jM5K$gtyQgk_LHU+@*vj1q9HOkdfcRls-SMk)B%EK!KQq3VazBL z(%6dBH50p+`sS~OAdQWW##p9)uw1}-B&6+e3HRO0=aZNMH zqHJz!tS8JXVEOdZ7A}ousgbNA#+ikzE0=Z5fXCnL>#vES3oQ411t*BXwjOs-7FaD1}*0AY}g059>)rKbn@fVBX`FCS@-dbIGJqFB+5(BPol@Jk&5e6oMR7igB(sx%GnBUdF{B8_P z3mFfD#vwCMFzJzJ(#l}S&Wo}KzzG^>ft zGex46)Y6G}AVV{It(syBN2?)zAn&rlzK8-DxizF&Y8aCt1(_kmeuu zz4%kh?yjKeMYfUNXU0$?*-isC=scPx;L|1;5Z>daX?_elo{$4)nFyLwHh9 zm(HiU9MI);T}(MZS#|!rF10i|d#=~JIE%05$33&Nn0D5Yhj{*UN>y3gVy`PpwBmBi zc-m$H0PmMzN}xxtv469Gr%^K26dmUXe4TIeqabDrCqGPD8^Z69=4pl<8EXJ?9iEx` z%ba9ANtO_5u4j8y%QM=P`cFmUo_v^kB$sZ&rcLyF_xOhK&E8|NoQk9q|4)o>8P{G6 z^i6(EMDs$2IIRj6YWvbes_R4U;Km{gv_WUdEJV6?x*H-5TmPEMdCs<~NH?}C$%}4* zMv|S^A#a{(`Em70D|~D6mt?bn{a4hxj2LJpGK&u`E6v6v!hHwr!sY~}pNWWGZ-H7TcM-{90sKTNY>*tbZM zvfD@PWc+CYV{?-p$bp~v#@&3MuFE=xO{i7g2{NaNL4_1~sut3xA5tKchJEOp_mx-9j!Z|$FsT|)#a2f^SWHn zrKiiUPt-8@Mk=rr*i0 z&N*Fvj~g{B0B$za%gHeoMN#0x$tkG>@u$;=gGeDPSA{{fNV@?WqOCjUa@|4pI?XRcQ*3M z@8#S7el8ovZ-0E#ZJTc0wDr!-cW&DB>ZbLZHm)1H=jeuUmLKDrZrMD3=L38<^VPln z=euS6&IjT7`!?UQY2BvVHm@i51ph+_r0&@CrOo5_OnOhg+45F@Ye4qj9T@ZVr*j18{7nl+In%>uUURjsTn}IrBDODV6x(WPv_jq zZ>VemjxAz~3tid0>rSu(jo4SRe(}qT3RR$>c=jyl$v;e#Oqm8ffZbOi2)Pk@74PFc)#JxpyNo8NLEZ<0ukA!FoG$EE9KCZS#XG zrz9J(DG-wJ!4Kc^vWJoo1yJZx5^@Am@ug$o5XhuRLFhf%`&8v2W4m$+Rpwi&v18=c z8}E@b*A}jLeoV&IUF=oS2{np znCQb3bB?20L_ta=N|H5;BWS|h0`V}CW5q|LhbBcGnZfA%6(#>wU4EL2)xDk1xN{Mz z-80zVR))W&%g=LJJMsKwaz7^Gd4!v4ljbCu7u-I6R~2g1FCnH%6Ed&o`Xh6=A0J_2 zVBUz}65rtlQVQQ=_qtNn+ez5li28{KG9P}f$Hf)5W0Hu1#OD^pMcR*OrX(Db`H-}k zq+6YIn}Xpe>2{K`Q*v*MlkOl1mtCh@5pIbONe_{P`!Pwl>GC1z5t48`Ch1Z68Y}4w zB;jRD(qnQYR?-AX;b9zJ#3bQG+}lwtJg#U_-@$+TiK@qk2RIKWkK>(Hj}J+cB;D^4 z!&jIj`3i^oF#$T>_d`OxiDg2K2Ry{r>O_StEQp8#6 z@geCMk{))A&sIG?Bt1vcBTjn0>hU4z1(F_h(pRb;ACg`q=?hMJsp|0|X+KGiIqBu9 z$A_d>NSbicSF0W$l3pe0i%xp2>hU4zb&|F_>44%(38M$A9v_|^;@RU)dZX&`A?a%* zJ>jG`s~#Vc4wLjHCw;x@@geCgl6E@jNY&#*(%U3WI*IU1d`NnSq+L!rR`vLh^bL}p zbP_S0p7PCc1+WrWM04UprgzD-+erj$;zQDVB<*n$k)8OE^evLU?4+5h$A_eoBuzQ# zgQ~}eqz_5j>!k0idVENlC2878-(U6kkTgfqJ|~^3dVENlC+Qg{b*mm9l6oXP>!j0F zj}J*_NP5mmXR96`k`_pM-bo)R`jV2)k@SL-&R0D?BwZlsD^6OhdVEM)BI!jZU95V1 zNV-JQOHR66_4ts~CuzTvma85gl2+`v{xY1!^OmH1eGl;MKfwiI1|g0a0|8d|7H4M1 zvXi+PPj+eKMTbhcruVqqW$n0needz?rCGY)N?1rP3OE;b@uBr$opUQhc0$c9Thpr% zI(W%)fJ6|NBeT~PAK}S+;k{e<8lIq7dFJjuzi_TzsWra2I;l1s85Q;(Nr&)(1Ae-7 zU8(Jh%xBBJGdTF>YE!s;zpK#XgYT1kX=Q<6Sx7o{S@~6+D)73zw-X52J~#y#oJ+pI z_PE6Nw{AyWP{?f)%#(Huc8~m{ZrNh2hjd2+4Rgg4YO_WV;D3VZEup5WhTs zsxslhiyZy1I;hyndlTwg`)qn2xnE|245Q53Wf?Y)@N6Nh7R00%Ll*ih2zpGh-$dCK zd0394tIw2W{MAlYFGdc&Za23L|9{aER2gE;zfu z#t-rrG3f1AzrdrkQV@lNNTg2jHdO3Bdi@>myI*upK+?W(d|OD&|CgcHMLV<+Ek_uR z)qVZc3I~pMaA&guxF|*3+WS*W$+y*?4{%f65a-D!<3%Zj_Af7kQ0W>|;$L5IMw zQs2>2-kODT(M$B*gY?{$32`!a9uhM0w{~z5oZ{)FCs?Xk{8h0>jht9C{NMcU{4-so zK`m^}ng>6t2Ylmlo#kpMJHT-7GHSW({iinGHMS#KCkod00AG6tLcRELbfv9QdWvMU zk=q=$>1G_H^}d3h&Gwc~F9{Siy&CI$!quZlzex``-sA>2gy_)P$B^KjAu(3fVN0|o z$ze3=X3xe8IT1Vt=%yT$mumsWQO+ziUlA$JWgE7(l!3OXms)BH6z#GF5 zD5wRXG6hUu#fm8Vt0ulfAY zr~^-2Ub!h?YRsV9?EPp97JfE<%HQQjJvuZp(1@8;JSM*bA|SyFv@3EH#%rrOEj27h0>|!C|DHjFS<~CU1re zYsSJ5r47GBZO}-o8i-Y?A)er-hB$$nSxF6T@I!Y?4QS_I@#al~D0v}s5kTDglOtfP zv8t}CVTASuu*$SGfLXOHVOC&6y83Gn+}R@f(F}AmsBOVL{kyIO_v2Jj!yQ0>7SoR? zq9A)A^{6AYdR8rf-6UW&3T_72ngeKj{GJx1s#D(seETnPSq@+aWduQOh5#)v&Z7|w zsTj1Q2t@dAXd`G^1X&)Hpn608lx0%qw{cnf@T{4vTDAB0Q&v6or|Cz<*95MKg{CF4 zvD5?DBAG@8$Xsc)=BdDPw7QKo9mNE8FFn<;A6vnHo`ya1N1BFhE29JHf^LF~OQRjQ-QN9=$tjIN|=SZeS2Fer1CkY*CHN zemhJJZXIYP?~_Cn2z$kPFpZ znV0N*@WYOWL}*z&nwPLlp^*|O{re(D1q>FNm}F>8p9s}{Sl`_CMan#O3G-&Y@74KL ztBnlg?QILm8co7&@C##o`%W*rSg|Qctu}BRYb+M44yqa{yL7@t4#9AwEeB1AVZcc- zCW&J5U<{Nqo(Fm(|1_>nu}*LCRyFLV`$oG+dAz5#{gt84QR{@r1AO~m=0fWNd^i>) z#3xM`t5BB;D76o@boBWM>pqG#@O>R2qtkDKyne1}!TmvA1O2m?*Mhu0^GdOvA%X>O zeT?>KFPjdcJ!93bu2dB5HvB)rgGknv_FhO9z3{U)rZMR!e#IWt41v zEcL1rhS-b;vDnP#V=m1?2NeD*!7AXiWS>`G-O9HX=zw$pTJV?_HVw?uI=`-^BO^)k z7;_h*E7x^MeUrA~AQiW`Z~>J;2Tk1;Hlj#(*aYv_76Z4#%@3j$Tntq+V5molof;8l zy7nIl-L)DJ>!qL7-ELieS{IG0&Og^h!hv|f+T@iQVd~;_RBquy2-|>OV_Wj|z=s1| z8hv`<0N?&U<+2w*> zwzH3DrV;&wUF|K3fDKY9<~{rw*P}bqMhylt{E;yBzRhp2S$&t6@6sGbbwB3!-@Ekp zcwwVoz;R%VZW-feXtOanN9x7E6nGRP4l_IK#HkoFi*4UtSMhEto7P|)9{v?wO^+g> zLigSI^TNkAF0zHuhK_6q*>Ka|+!KAY-hC!lIz+-@X9pb~(-mb^oqw#0NYQ3~#c|0t z2DjB+XNAMaFNB452P#d*j34VxrY<3^Uzz7zmeWfy2{v@{ca+P-@*QQBa3|40=bLl- zPuJvP>AiRP^4iHp#ZX;c&b^|XFOgVbmAM((*@%7S-R$^iR|I#1b(^rvl(tMBLr=$G z!7={ULM}&X=|b!np!r6-4l(0rh?)amE^|90K8@q##68=vNY^fj*fku zwW&~NpSnV0t=JR#d1d}vx(IV?$4EVpgq0_Sj*Yyph0I;J56^3quS?$p{O|K*>IT;e zh!DcWL!ipkWLg*FX0T~0vBfPq<7$vv)vU~-?{BOvg52Dn9mTzBiU_{KNtDp1s#XY9 zW84s_RiYt``Oj*;?_S%cCa^#2DvBvF z_^yr3)q+$+-cr2$)IWE!z)bz4X4UI5wXN=-8z)G*Z-@@vw0}amooCcf78X=zF!Z0- z-Axc)-L!~*_|>Lq1?h?XsCu=^bCr87-8v55Yu&Wu-2fqwpKXa@B8zqG>p@E?4jrL#9 z4RSA|8RTnf=Tq}w^CxY`r*O7r$h625q{*4-CEigpneUma6;IW&5+!B77ILannfBLv z{x+i!osL!e6J=WbDk#(OO;;B4S#cOjq;ubvG!b)T1N+V5T^(UBO!=)JQNu#5rI8p0 zqEaJveu0Z;!^MU35j9RS)tYI!BSLytxU}^HbDgY1Wgn_&68CY%DpZvZU^fv3?G)Bn zp~oz+4OR&(;+BDHqb}PIxJCb~U~a5kKN74ey3JAkw$lENp7LGOs5FZ@rIu{eE4W&1 z$-3tO*uTO6Nl@>4}vc_)CICl~xU( zs9|`B4~32U`%Twi?2utFAEy!uT{3763Eay%-|B4YC>=L!zF53*cw;RJFyh z*HUopySCh+iHZM9zFj)&w~;3@0yw-l$U#FW>n2&W=c_SM(DMhZBMPs)25)* zq%`W+G>s}$@O9s8r_vy3ajfW~0SX#oR;C^^CIkGrsfUvbeoQc`(FHrGA-oRtNX;jJ z3knL5jdF%4&%6>c${P}DTJSw1AzJd|4Yo&#aBCnT#JSP!5kd+QDjL<$(f6oPLv%#T zesj~ZL`MQhohCBqPjLx4(zsr2E{w$xBc_mJq9F}cdFj(yAGlpo?!YCOMbK~E#2}9t zBfm}U5ObAhrKZ98%uQ9a+oDU;7U&0lmFIQD5eCYGX>Jc;CDN<_(#9u0W2O>v%H0sR zLUWdPY%Q&Ii}jr!|1%zU-UOtzH&FTr&tcKP{!glfn@Nlo-jNp*YnEM7dy!s}90O}c zu;scATl|(xphh-p*0$`TKC^1h9Vb28O|&b8MgBd5?W+4u?b6qMcaEDi^xc&g?KBpe zI|-VelHes)Za!jhjh;*@O-XV7wQc{US5asdeY}qPk~&P7i0-UAy7M$W8QM#;AIsTI zKOfQ48=JD~efu0M`VR{$Qm*CReiXgsL*u4uk-5Ic%onMw!OX}JDjg*o^lmsK1=*cpBYKYYXm5f+Y60))1pPpFM}E9)>B_!B5dYn>&|{(A|I zu}6B#wY>b#G1JQ|32Y`Y$?8I)lGiaK80>VgMq5Mg9W6T|KFY7q-HzPfo&S-aVVQ9e z1H4}6%X;$DN|b(*QWZTsqGvT!@m)O^2vVe3wVA88LvsK8QUtIF#nyjI#L7kVNQ+_sJ#*G023d{S(?%2Eqw?0KY)Bh$ZTG255`}h$grE4tV zAdI|BGi$JDBd&HcB4(`~k!b$c1+vPlMl2d0t3gTJ3q?EBY?!_cJvLBj#1FMXc)a93SIiky$C}c%<>vXrQ zyY;&J5#4Rj-H+*RqwaoGcem^AH|g#U-Tm9TyHj^RuDiQ+_ZxM0kM4e}?(WmwZ_(ZT zy8Cx^w^eulzV806E)VMGHeG&)e(Egg2uG>Y-y%-sgzkQ~o{FhN0L$&V`w68zuDd^= zyC-z_`*imu?mQYCGjMNb=fLmjj)h5QB_pa`~t-EjP?)U5NJ>9*-T|=wByN>rpM+Ey4BcT8H zxgkuzU7NOTx-|tCSWkd~b?K{M1NnPRsLEGV<^IPWiu{ZQ4wj z1BEmg_?B;PArQibqSRbM&QsQ=a+Fu!jeH;F>*t+4;A)=c`j7i?N8ZQ{qY!sw&cM~9 zU;_1sy+OpPlD{VgAO^)*?W#wNUf%X9Otaa0UWx0grQgH^>P(-- z>ezEMGbukElxEyPY0?fJ^R##6wn{OX*UrqAau(7gzM*X3Z~?@w4r()Ko^;I1?+9reNvEt9)gvw zuU>in(;8VRAWyWtM9+2cKs)&$h!Crucmg02XKjfMw^R?_rvSwnD}rJaR^kjh+__tM z`N?uK(7&W(SzHu8-ZEiaye%g@#;>|()F09J>F606%X@6TViYO4DZI zS$&uF;Bg;V(*H{k)uBb}cIPIv#8&``xe5F{If8S3=>n%$*;n*D2m9g`iVfp}oF^9) z`6Rnr+P(7V5~n&kUdGfBozOWK-gX>$JU`dx)ZOsWw8QJ-gv~P2>pq8A5jQ91T#!QJ zXa77$*bm=8y~$p%P7zM-s;|8A%0vX*o)zGeQ%82WfSo)2U;FX&v(M%XA6z+o`hzP| zQ=>EPn|}Ve=LfSse|mJ*-P6xL*W{d+ZPj4sx+4dglV(xJS45`XC;5T4B7zhf&U(Gs>fhm=e^joxHX9PpDFJh0(DPaEF{zOnb}_I}FMz~&$t1>#!w)R=fnaXIfj3t7z4AiC@{ZfJ zr~d&RaS%sXov&KIU~&KPs6`Y&@W1+3o=` z$3rjC(g5geA|ak{)+5pJqK^dW%=7!k0{wUH<&`~=mWtd9^|8uFKdVnABziw5b zMhg)vV@7$3y)BQB?h;`v&{Igp)eSL^0$CSm@0yY2d1Y4bpDLm2{GXIMDRo}QU8PQ) zo&8u&!b=1}@>|QqX6u`96he!mLeKaF%n18u+^MaG4+R1zg`bZN(7%KHeRlK z`&?LCw2J=U4FMNze^XdK)18u(dBpO^6PZ@^|~C<K)KUr^IDa-+%U@9T zU)1F<>*8UgwVJ6Wi##1M{f?v!GiZ0heCEM1{=^15qQOw&Ea?TU6&o`Df2n)h=D3n8 z&rds=kv;S>!r}Eygd;W_HN|P8*iAqL$(DN9f?}y|wgxLU$!(%XlF1Hi0Vsl{1`1FC zXp%G5hj91{?0bI`zw|4A14sDvzF+_T=OJ(2TetAQrnEEAOcS^_@5z(rDNmj}dD4En zz@xE^ho5`|L|X{6ycBl^3SjTtEa#E;h&3o zKls6a{!cIN{^K7ybNr)+zNOPtc8(m6hScH=N%()%}qJ42)I3u~P8E zQim-{=|nlU>({Pdd-&#bGCR@5yy&XdK&)wYvhrIr&q55mq7JG*Ts@?W8}(eMRU#kk z6~YT4u89UNF8y68&FrYxmG@tTvt$Y1dLeE-&fLWWZrlbb3P$inVqP4KxQIDp?$ zVY>}g-n?aX2;*1sI~o1KFVU|;m*;)baw!dF}KMds!Sr43=;`D zfc)wu%;8{T@O*{FE4OSQjKzLde30#@-{`v=gC`VrQH{pQ_yl^~(4*DCgCMplB28aX z;N||ns`iwgjUklN+x?cphh#Cmq739I%mhE|t$+*$uO|lwtFpe6y%~iR;fiQ+6A_{O zkX+|euga*^?13utyk$HM0`sHOqurwep+@p=ATfC}J{0ql0)|J_Ct?NTC7ATp>`cWd z9g)$-hOtri^fCDi)}l}o(fon=E`#x*mgYU|R@Ivj4I#&L|iExbtK#o}3s{ ztkdz}>DODr1MxA1*fTIhE@nvUd@$Zs-;+IuMrBTzDjWvfSkLJ7zu|Dme^Q)=9=U-0 z`}6Uk;W-|BH=UoJp^%~TsotZfU)~x}>Dz{`uFf>*gSXQ6g9B3M(0WeLim)1Ue0Gy@ zY^r=R%0s0qD`SengaY4!N8opizyQDtlwQB)9kIb8I6xiGSqxLsXo@gjS=b)zL|=-uv!|1$nyWQBS@?gMVJe@Pxg!Sh0x2M z84n1djU;8{V@jw3#wVb1`bv_pYvRt6swCwBRv6y7F;pkluT9JxGr}WPah+fesJ{YpQWZ zem7;<__Fy<#axe0CZWfY)uU4;79a1J!fm@#D!WE3?D{oy0ZE3&OgV(wBv6Rq!NJjM zF<;mS0T&mUdp!xk^gAUP`=RK~3)mKNHBdFSh4H=g@}Wi|KG^~kh1bpw%2_wz~Foq7>lIw+U;)VEWa)@$Dvgc!)K)e^2h!A7HV+J*O z)l@9)k_u__|N1p5rAlH49-}lBf*Do{H{itRtizMZ{5vsEMp5d3E)G5LIhh{<45a37 zhfJBw=xWi0s_F1eGQ%KBamL?@8Aq^rK9!$w{hDf`O7d-{Pd<>RD9x8prm!G8E@lo( z)9OCUnjILM2@3B4 zlYssR)w3Pu`O~S$GoK=~VW{~{Duue6NAl6&iOadqe5Y^u)SnPCc3-E*L^(xI&US() zasUqDHg|xtiXxwMFltXZMtjV`^D&=(0|u0RHl~UztwQnwb^3a`J8|opNPIUvMG9?V zsic`1g~7;qg2YTQm`QPM}A+shr1Uka`7FD=5kH zIrFRJKZGWvAUPpe$47`%P+MMR&NDV~hOJ0>l<2||xGrNt1u>94Ju)gxyvFeypX8KY z%`V8lL}(PzcjxgV;WgVwGTniY>oi+A9eg`GdOeW6U|JH@%yVWG58a{gIlTT-U7Fw3 z`=v~Jm@m{-ZU{5efSL;jV`h2uLpuY=xlA6Spe6h*Xo}5)6p&b|EDuKP*?Kj38xDhb ztE%5Q{bG%=C_!F>r0U(yQ5y$FPe7v(bJqEmy3m6k-@@aNgM#-yU)`Hv2<3hZyri?R zazZf*4HP$F-yEp}+%C9EUw;p~kLFpw^H7u2WcF&zL}_af!7`M0CYXrBF@9J`LU16L zBsD*wEJk8y!o)L2%a~gyb92B!`^QMDoHz3%#=ECC2fsVo@fnP1E5!U4*sIs$x#;X+ z3-{SH>ci>o{Ae{CM_W`ehzBQV0N0#q^z_T@W!-gz&z-b=aC<$*JyhvxL`KE5`A=ZW z8`F6kf$=~TAg0IoXzMhCrP9&K{Pc*@q3*Psr}I0UehRd!Zv6h-r_dughVoe%T1Qt4 z>25<}BnE#X^+cAbc)#Im#iY+Fiz!*aL=Np(-Gs}zI9MNy_mC>oc|MWgfSzFKm(>Yd zD!Wq#;X)xjL2|4ffxsnvSLFinPC`^E){Ef@l1*<3ZZO)JfC6qq;&{hB!=oAMkn|2# z;bFUDDG&n1s`^_a-{ALW<2_xdwkt`Kwel5>hOjr?XRU(?71dO))u5Rjn3*;-=2#Yc z_{6-h!49cJr*gq%K~5Om8Aa2XEqzwPK|s%Vem2KxJbEc?UNfJ)6jpKWdqw6)6=1M{(v2MCG=h$5-{ zar07(;6{XQGtw;|&TC5e0;|E9C2C*{dQa1w-4-%jpMawxi_Gn=`vli)t$zJl6R|jE zc5?TQ-qR8nvQqGg6)$7@9Tp?x9@VxbFp-ocv|Ufy)?|%jiSq~xJf9|PzEAy1Hu(3f~|voM3xN||YEWd37Z zIqFNhyyg(ELE<{J`JZU@u-IAu$Zx>aC7af+x4)oPU5dlU`L z1PqFixPI-<&@?^;)7E_oyEbl_Xccy#<@ut|t0$*#nH8)k09JGK_~Ea)NYBv}5S$G2 z4T`k}R76pw;nf5(divFqtta{A7H-?BjsAqnbo^TM)-egqNOy;x<&OQ+`mK9^ND$9d z?Fs5q9bSrUR>GGCgOTNt()!M=yMOqD(R6k2d07!8yY-#!qVjQVef9OjTLT98#e+xB z9%e5x%tJ-;QCK9x&(nHTfl0_}Sul?h3^>yQCKkjtIht?4Y-}MW^OedNHBCbvMFj>U zE*UdSHL_-Lm{ADXRSzd1Q3N}~_*tZ{U}IAw`ipd$H#mvq%3#Fj^NGzL=5d$cMuJ_z z7-4X~-tzH2V4md*L+zNrvgU1fmTjeOzJS_~P*qsn2+4Ddek-|B?zNRsSIyG0Xt|~Nn!exo!WLphCg__3% zr`}>o@xfS3Y8?eG*2Df86BLUI3$6D9HqQsIlk=py9Sn(MC4Cur> z*O?UDyK)Vc{{vJ=gyt#uf~)0%$e92JsjcAc#y8&HR``o&GX1_6y=Kic5kyTCXC8N3 zv91YPh`VGJ3p($;|Sh3%?cwuUUS3uRchnQWk*Vgr<7M7nH3 zt(eyK>wap>!Wsq2xf4O(7Gzft{!5N1tj@W_h@kW5bzc^T(Ct`On!jaF5+_Izio#m* zhD(+$F(t=^94NzMyP{&edVtG*Hum*(ine7!*=0?F(SXJT9-ZO;GRy+amg9JXZ;#Hf zSn?n|0{ojVA2I#tUSs6Jqk{s5gJqir5G%JM1~jeiF7QjkOcZXs*B^CnVaBk>X{szx zz+9a^gjQsADB0Tu^97`F=%C|+=0oYN^fYf!*tHnTt&{|~rp*IwN!f%^nl3PffV1?vB1qyqj2HqgP(v& zL1O604e@e(r`~WoBl336v%y!y0nwXO_-4UtbTi3eZ#jvP{X?Y)?}$otE*x}A`J(Gf zKVLuH-g>glgz{+f@k649tLwfEdX>Hvx>zmU$54r?_!gap?;9HuU+F-BNN$RVIOs4T8~hS++^Iue*x|QGpij$4C}^Vmpsg=0#zw{io6gOR8%itq72|v71LX*eIFp)aLZlL7VZ|&l*Gzwau+@Jz{~Qy=~uP@(CqP`>JmK$3)a z$FzgY>4NI*?UAluB+7|^@L#8&LKb|N;wf2F8pWL83xNfktCJ(L!J(Vw{Z9N<$`EdNI zc9H;fx_t%*)<-Xs)pPTSL?)e62nf&2nruFC?DeAhG+(aeFQXMZZjdA(*V?}eZ%eRk zJA7mCa!qhX>p`q3c8-1Wu!(9H2`bpTk={hR`B-~^|1dr{n^@}LXlNn&+0hv>1Ots+ zKm%q_&Ex80V8a{&fGD3v48Pr8~Vp-+7To8 zvoU-!BUwe~Na{I9JM?RgT8A%p-kmRZM#+v2U+jFz0&iM8J?C4Fk>s~O`S|0z7jgDZ z!&&UT^Kd{?(Vayehis09Kl^)vRmN?099?qWmEm_9hTpjw!|yCI{7#3VU50nx8^gD7 zczPMGZNTc}(jxy6(tGd5e*5wq?n?qLkb>nP{8I ze5C6Q(D;^I+&fP$rtd{AG&C0r{dNhda4Vq39hsPI+-r+OEfH$perxjZ1-nEp5RK0% z{qKmwt-&3_9G*j^V8o($VBT;mW(OmtZa)aKA-dZHF+KkM8K>S(?8&2xVO57}nNs@MV4* z+kfAJDMk!-{xoVlt0VSn2AC_E$L@>M zy_MnMqrvdSY-O_25USJUd?Vs_bb1@?h+F{88fz@TP88n54VkT^OL1to9m&<2pOI#PlT^`V^KQb*3?EuyMgEs-D^sPJ4P2 z7@OjTWG#mhtg@v_*107v`B%`QVXHogpDoJ+$JF4hAJ1c-#y=sZso-0Qm4#KZJ)&M% zJIp5Ek}b%3-DiYgK=u{?vK%piC@Y~H*Y=ELF}pUWSrz$J_oBjfHmhb{n<@GykA_zT z>?N62&~0^u~ZQ!t_i(FSi zd)~yX;5l2=q=h1)u&x&5VPA$HoKVEx40ub{OV13zBSb|F z>Q|;u{n%br=#8pNB;SUAp7{I6m(~Gmey$=|kLPHEK`1IAPHQS$Y6U$<)jnGGpDo)6 z^X;d$f{;-mgIH_Ga>X$4#bPc|6Z#^F0*D7yY_}J&1vO%KiIt9}a9lxK3^u)T`~ym{ zhvVW$2%aDn!D~!6A#E2VAMFJrEZ^*~x%MqlNH$vuJx9b=36l;?gzp_#K3t;5@3<28 zPVe=EVkk&ZucU9^#_4ZVHT1LNSTBQfw}z#~!-VPu;Wubqb~R`g8VHDYJJ7z@T14B> ziO}r#ra)&+30q^Vy`bTH(h0}Ohe@e6z$4=0jEan zM))3$Kl;s@-K(bAkTZ5Iwdqr1lCh2r|HNV{*_6~^U zp8D*PE_yxHbbv3YWr}yvsU9!;eZSr z;;i+qS@8}mk)`SD6fou@cE-DCCT4UX)IS=msK#4~x(j1QOZfwb>U&yE4_AV2VdC`2 z-;WRd)5da>`&nDVKei9u?(C1{N=GkgtXk4^Y3I6)YTJ2OW^{+e`6eS}!Od<%M9MDA zAxQmqpS%72qEF$idp(Oq2izMkwT;U@D26e8@~&WG5VK8_U_^LcU_fdbF(jZA1w_swx>C2gzr21hc+ zgP)LA$`;bj(HlEJ;U^v<+4GfUZ#in(K-9Ek*>grC$|%&kO*VfGSuid}Dy+H7KRLh< zP*dIT_Igj#dgeQwzg>jI2uC8Bu<`?hgD0GMdiBUUpUB-S!B( zLAi|5ygyN&>*!gW6fikQ%pJdHlsnji;}Vya{Jox%;Xs1^4iQui|NDvaOiWd7``Ibi z(Ufq>7021uY16#K=!%d&{>e{2`McYK(EJAUw&`hJHNQP_0#r+^@2Bb7W_@REuNl;+ zy5u&NNR?npG+So;DwBQgxOPCi--S>I_&Y6x0*0)V)d|A8R+XP3aH7rPkFAQlNPn9ks)HN_iH87w}G zLt}$-j7od-rh9)%+-#p?tnyI(gwWG;CmQBTCa)xWz6NgtSSop!T!Gh4W*hP{u`6C? z&+_}7q|StHnYgKNK{>LU(!3DJt;mi~s0t=0)Ra4qAIXktqGDbfpT29{DnIU-m{!-< z?tEOERC`dFPhtN(jAxiQ!yqQ#z~*w&cXT09g>7%gBsSoq2a;s+cCw3KEMf5naufr6a z^5V?x_%Z)&os)6FBNK+w0u(W%99)zmdVMq}F`q&;91_CR>2tg~+`tnRNU|qZdZvpO zEusp>$j|=$nsY8kuXSKr$3aDGGnnp8}RD0{39=q^p7pTDs68b#ylP#PgV=ibS!#R_aD;Zcb|nQNk|M{Wul3 z=vQnpt0RFFF;*G?;SoZbI6K!fI_(M6%$&#qnjJ_W!UT?U z->Hwb`S9Vx)t`QR571|-RO5Ktfb9_8OyfA{0J9TvytakrODdK`bpjHlMKlqoA@*Pa zdRM2Pu;Sz!l?}l3*ynq15gAG+aeBN}0L;NdSYs@ZJDB+>oL@uICgDC6$Ti85H2Lc2 zcsMWrwbkPo45=yaww;%bq%hK?? z&+arAYJ^$Tl^RzEpj#{gfM2z7H4u3LM}V*^IIa#s7j7g3zna5gz`a~AFWDAv&k((- zB7eiVzj}svhqG(Oh}`)LKdus!JQ_!lR>{bD6NAkMR#miYX!i!2bBns34-9zdScoTbS_TINqJUrI!0ev%__O~YN(*B!)OvR z%*bf5Y4wTCjvaa;S$ngHBQ>kdks2#L7y7yxhxqAD=IOS&v_e%XPm7hYq_il|Vh)pR zl*T-`{U|`BrnmI<>N{*2rRn~%WG@u2P8{?5qKfz~QNk+#yNp6!65J(~^9sEoZSIPm| zNOU+~i@%W^FGbb}a#&d)529K16DQfv2HX*s4og}uDuBG#A5|22;x(C@3Kmi97B5^U z{>&Hj`XdqFg9m<5#VcwIGBk}*E zxyda9f>9wtolZ7(@I@u#hzSdGax3`Ky?oWGP}xYU+bckUip>sMY8y(&#}xa_c%>m> zBI}huo@tCuf%j1IBi8EF*Q6w>b6x7)TiioPH#l2d!Rm?WnZI+o;@(D)QHiRL(8ngw z`l0-eL6R)lm%g0x%EjR~sol!aj$Uh>+2D3#aBlsItj}R|i{8I~6$?j%4a7fw35)DX zBc}$Yve`?4jPgz;o-0BTL0Hc%h}^$p&HW2)Br0izAhq4^%{2!nleOpz8}b!w8iS?x7cHzdS4>*KfP+?|I~ z;G}k4q=KLuHkq{tl6V>T4qArmMR+k%p}S2zHr4t&mugN4|8JpSez|~j)jFt3saK*m zHVPsHM+Y}MG_JnLamChmV42or?bBnG@( zV=u}mzPmZj9xyR+Xbn)9uA{3&aFBT{wxeR_(^I;ESj@fXyBGDA66@@M=8B{TJ zN2M&D1h)LRKdfbu0=i9sV6K#kTVkriGY)8B+X!Gym39x0+j(8{&HZRqufxr-!Wh6KB2bkCByyG=efe^IGgdOc%c$x78Q2s6b!8WR>gQ2ZZ z6@f10vAO;Zn1HYvD2{RuQiZbxc>a>BI2+gr*WX=W74@B4#^#IfFOUz|Rq!QWS>Y?} zKQ=#hx__n>l_RH>Nb;dyQY}yzjMj1%m-csl!Iu{W5Rtqyd|XxfiaMC$P#@{44sosP zlA|@*gTn1wIC{Vd`KM2wZr4&77cw*hGvP?@I5}1ReNIUmE;X!%(XgVYE(U|_!9&ml z$Sx)>k*<3hh0sfv`27nG#BXGHuM zsvJ**(UgJztnjwWHM=`QSeq4LxpnkyTn!b0GE0aF?B;BL)ffy)7yP+_C`Yw>Am&pD+QTg_e(6wMI4iKughwQ>-1F%AxrNyjRS2TC zkCoW^&g|y+!0t~Y+gaK{*@;fNbwOR*X1f0-X4kwh!1j{dEo$!FYbVy%%~;dBC1NqF7^;4F|xf%yZ`zonIDc7o_MU? zSL0R_-3ua7h`ns%KN^W+Os%^8oyItoSm98Pl&VRkbRXn;V!fs!> z3?tVY#yKZ{)jSX1=8=JI#_TP3VGfVy`uorlf|U3NiH+{P}XK8Ly$Y zGvHD4pzY4s9$gOQlAO>tUCXn?h4ECkJ_%)^si=le65K;%_eYu|;1)M7jknscmcPxB zV4q#wBT1ao>|?Zar%B~A_;i5<&$TqSJ(1mK88Ae7=i1fPN0_1nR-dq}^r^%Y!kZwq zkM6j+?cy6_ZPHKhfvcuIE+j)i`MUqUkRh}8oR}DErXoJr_WjfJO(Q>z~y-QHEaEjfGETMFn?uB)3Dunb+ZbM5g zY68D5Y*gkLx8+R|)67lZL(Ceh5uWlRAm?mEL`S487Lqk7m()~zeBieWm+R+R2mM>J z^QjA=&@PRVW+z%y;0_ZgURz3(lJJ%b3W&0^NR%s2`hB{08KPKeW;crOg)H|jPnPa7 z%vT}YHOMiLDQ>ZLGGdojv%Zr#y{BheUu`a$vuABeI>gyQnXxV@VgB7^O<9;0|7dZS zYzvR3y&}_|LQjF(g?h8PSuih=O(ByW#yy`Ul*U& zKFhN5?C+m^wY9yJMPK)+MMK-~r4a*fAH{9&4nRv|wlqM2 z3rCqs&GE7r6=4XjXP-=LNv|b@b_C6bA(r6-CO=kv#dbk{)ivl`1E>pT8v+!cp*m*x zu0#?3U7{?^jtXOxc?SPUu{H~Bpn+MhpYVF`+`f|6;`ZSGcg?duIsP7TId1@6R=4w_ z7Gt7cKi>T8$>$4v`iJ%)BMZxI*wrWC_`J(9PSLPwXVRsxq*hCK#6&jV=u9Y!BfBAi z?I*4WAWjr_n5UiSwNLHgUTXFpzg`XeR-)9`94 zv)Xls;<5OqpcayS*bK<FElSLsL-td8uwNH{8ln&qewJANW?6Of1*O)3QrU}}Z+EgjHq~B#jdc5o_dRG%W>lp+w9ThrVG0bUwsaxO6>%lt&$;BeY`|%3)OKS*ye> z`=VL`&BjD)h1OVdZPo2rX3U}?fB5Cot>11x+I+TP&A(}c^BGmLHwd}*bV7RPtXVh%11e%@)%2t14aT`_AxkBXQ3gDeGtN-Dw`PZ{ zRx!A{O^Q`ZG}>gXLRU^#%b)Y@_zO6nbglC!ji8njdnF<-7_5hHh(4(HhFHQ58o!lH zTk9i;-^et}!KE~BFw|Od_ge#XG5zbd+4{YazfbF`lRg*Fz8O(uUtOK%3xfR%vlKyc zUCM)jlU2{mR;RmlgfhLs!1`6pP!^`F)0&UrD!y64UA{j zr>;zHrI;?eTNH0hMnW0!>m>Tj1z_O=NY*+2cCBu`d-&X6$f0>NKIF7x z2~KncOgdeCyUw1+T~Zm#Ej8IbHCyeUbMXTkYGhDY!;%->QqZpLwqr7lpr`)2@!tCS z>7#{J@y*6qULZ$HwbVLo-dgyix+&Tm@wWN4FZ%3vFN&v^MzNvsr9{0K@ujkEtyP@# zpQo@JdbtP)X%Cdk!GwRt;y!ANdr3%aiF?YkiOE7b1N&4TUs_a}`LcvROzAx}Rhe(S z(yOCGmyyPD)|?gWh+7-l8>Z(cXvAKLB2q-goYc;LlqW=h@AEE8Y_8 zyA65W%Yx)TZJu3Vq>ETrB(HvLtn?pC*iT>03AMj7{qMdX`rqxLKhKuXzdMWS+~u-K z^z+Tn7FIxixHNl~(qCORFE25L>Vv)+v=6_%OXGLN3A7LErSqp6|MQ(bgRJWA&}3&6Mi}hkSr`er!jH-IVDh4#R4jj5*f!`s6v# zHANVnpyR9P^XR>>`aZid!QX>+FRZ?e>d=DY{9%!`W<) z6>R@X5Vd?rF#oMZoCkzX1>Kjte2^&R!nk39JUQIM;|aHEk)*8)9j%AMvr{_dNFP!n zaM5c5s)=(cF|K-K@Z0M?a{iS?(UVy`nPnI6Th6zqMbfvY7NVb4NvQ7kgAD0Z@>J~9 zg<_y&L__s{-MA4E9MU7E9HF=L;6jabr#PtFsE8Y>+s%W^I#P|%F@enWLG!rR7JWYD zGWEIFqlWkHhnok_%JdayS*Wbw{B|)XY?Us4@2vjy!cZ#L{Cf`Nd^_AbJX_9(WL9Hi z453Lrs_{M{aWd*zcu;-Z%rEPdDvKjorNiV6Yn)f3=D`I6Y`IIk>)=@8T}$9w6( zimD&YutrLCX@;^!_{G}W2E(2RW>epKu23;5CWeu*&5#k@g%6rq#2 zxmbDp4)TYw-8mw;J*2Uek?=+p>wc{>ObW%@(YwgF?Im-&7x=8~pb{oX`pAIio+$UH zIS#f~H#M%#h;e9iAn8fLO9aAh8>_TDsN_8Te{g@KrJrwQ4uVdv@ zsUS<6;K{BngpgYYCT~)4?Zakw$3JHil#)%ix)EPuaTIiKeoBbBm5zR_cL zJt3PRrCfF8PTJq_)6T}M#@Uz#SmYFl{O9Pm!|7`GtLA~&@eXH!mNH?%XZ)|igie-b zk|+*%G=Ap!#H%>b5X|l4@0tgqAb_u!ko3=-fRTypxyMPqc3$!oiTU*F1*>q}CgS(9 z3KtrKXG(IY<`p?=+E21aQf#zP3h(m)=3bdF?z0yQ=PedZ!oiUo9$69QW^TH((^vQb zOH4!3lXyT_h&)0=?>hQi38K3H#!z#aB0)f!;{~)dGZdXq05N{i}25Y z6K)@p58We*75TGC?_xdeLk}6}Z8BcnKKx6dq8o`MQJhnFCnIrV@L*TBPnt4XzJgti zA-5TgAWe>h8VZtdXp90(?s4f%*#j0<(mA<chrijX+*-He z#M?V-t9Ow2rM7%w1If}CY-sAfU?{tSvCuQqbB%`schdvPE`v3P=5SW{<(~XA659O$ znT`lLeUb&NFR)lFk+Tq-2r9=J%a;c^aZ_|U|CSE!vrbcyZ7bwFX*`Kdl8a6_IQ5-f zP-2d%#U{8FgfiWncR%1d#{=?w_m55qn#k~hU?LGn`E!GzvHvKIkZ{l$kKTmCWiP%23kFP&t6_buSi{9Y8l$&ycgqaDkWTQpj^+RwGJf;4=4{55@KbF<65bgXB6{5 zlX+H&2ip@wu~oLrn>i7^O1<>4$adP;Up{*BiwD&yZkL%-U5Yd{yyZNGu|1=##_srd zvaQ&CS#y6s30l}Eh=GUE3f&m_c-B-#pQ7f~kjs!T%B-BLPA#=&?umuie@VOQVGtY6m%wPwQmkGf#FgKh`4qmP?(e7;<+@RAfmm3Odbh=4M#xnvyM_HLfUhK)) zjsXdSPtase1w}dGfU&f1CM;EOJ3EHzJ$9(OSL*{ud|&3A71LTdJOAyB>2bWH#GNed z;gD|(Mi|ujYI+fYm{md0od~vj1YFe7iWPap7Cal$B_J_O#c1Xef=sHf^Hvw7y*)b1 zgi9-ihq)#S<3Zt=lx(ia3^v>psN4j*qK>OwfL3HM)#|Hc9}q z+A6oNYDW~@zd1OZkfotJW>aLIwRZKi(@}bl#GZD`+|;XEjy{a0W>6H4S|OF+`W*4nzwnn&TNy?mjVj zoSN(tBPDfS>M={q8p@dabgVLT#!HRNaauWn2KarTaSAhw$KvMKg*?GELg8^TH&3BL zgI#nB_bOolIJ>Wamhk&8zTSNFd5Rgd#oE=f;4@98 zTfDk8aO90P2X-{zY!(M0$}&AaZ}y7a@8nd#o*!W~88|wAi@5K{B(c(Pe*AK>%@o1( zLxEsba@DS(vAHEXeuFS4Tc%uD;YM`@s_ScPt}gD3ffwP(-C!=V{owFS zY5qJ2VQ*}Szw)}XXtF387A2uoZRyOZZD|<|fx0L=lr?YLhqbNKMMgVWH26wKUk@h_ z=X01!EMh*9bGWO`oynUCr*yP7#!utAF3U_$)To|kD|vG-Ebehs#=uCuCfUtT1=1Gq z@(SDnJ3kUmHLfhcWQCgYy~d~I=(mWWfF)hmY?d0;H`l0X#lPp@+CF{)>QzLQ;OOe% zw0S^hS9A5Rw3S#Sts5y@SODbt1#|hJ0<#a57%Tg3OofyZ81r>@xp(GvhEe5&l&9;= zG*5o<@6*#y@`w_e4eO~&&cO23!!7L^nWab=u_!R_(iUmHJoue7z%OpxjU*djbNymva**0%1ds!=}MoC1NAz;#_hUU z!=HH$UX(na^lyzkiG``5H{to*uH0?jeKgoSmAAwEa7>f&n6www{!^J$$wv)Ke#on_9a~ zXWtzuX(q?52*mbw6r;{108wGP+1e(j*W;HjnM`~skLYT#X=3)4I%5<82loV~X-Aq@ z0ptS~$W&;>6Pcdu9Ua=bF#Q-azMx&uY%=#-gV{SfJd9|njDe4rjIUTb7%>#hwxuB( z>j?L0aqqT$!ClkReNr;jCMQe@EIO;$jSHpuS)75k6RahGA_>6qRQP&cD>(JU2pqrH zlNDrIxetOoOIj_T&`=ababJ>Rf-X{Lc7Jv#`Z2g>D2=$~j5pbfQ}yXv;>aroZN8(O zWq*Zt&bnI6n`vQ9M^@!MQHm4Ytd=ydTH!sy$jMZVy{3~bIb3k$oKPgVkV&Dfmmv#g zWt?trG_ZEqR&I&u71CamTiRd>PHkzar2cM+Lybo16vNy_(S7NQ6brK1hYUI?5fLV0 z5GUw|ISLD~3)tQTKtd|Z0GR*v%qUzYgKo@ucoo($Qk|u7J#Nu#N?Z5%ig(dlt&+?n!{Knx5G#>c=r-ROw_vL81 zsMGY0q~ckschh#=>US=YvOc4Ad<#0|LMq%p4&3Uvc^#TCht?#g7KRSPdpk8eGe5@* zg|$F%gAz+CjDlsgm?y^YBg$g?2U_GR51C;y?xbds;5GnJ#%7^nt>nv|9e5gFx!}U= zNP_A&C)EV-_{r8ojxL*+Sio-?g_$L=9AlJI(i8_eshk*SS}s-0m>40sKwXf&^6 znMDAL1tB-E*raL~7bhx0prz5vXkX{1^GATc%Jf zJ8bpg7bU2Pwhm{fUPE@OGwpKVY~Q}<-Ya%6_DFA>?`x{Tn6MpUXrRr=^$Fp~^Nlox z=z8olX%|&0#s#LjnB2-zH`dn#D--og)8@TzUM%dlhIP&`T`^77^tA-}4!=hGF^%-VZFY%Ig z53~kk`-tV2ahLN;5|LOOx6OBg(FcNUE*9)lh#$7HHvu>Tc2e=}5x?IWd?>*6cApNz zCY*NSe?R}pP>ws!MV)zdDM;>VJ^kv*){|zw_6Z!p=p5U4hkTq1ng2AeV9L1`Q>C^3 zkxroGD8E43OWem(aLjxmg}Li!(MdQp*Rt{S6~x7eyWKBTkrWk%%f|C}0UP~Gu%(Tf zdZJD{^&pzd>z6n{&$bp1y{t79rPuR3pdMXm=~9=93vo5__>OHj&6WZlhh1!6kxsBd!E!!vw4E8J?uIh*b0 zJr=3XVu~GWxg~#f^Yg}r7omRm)w9ionncxk9x=re2)Lvt^B>BjYN=;wEf7|SSprDWFxc^LCIYD`0hEYFm05n@N+{8+&@aiLGY(ef-;5F!ry!S z59EkI)`*GPT{O&6RFPKU?PM6G;dZ}O+-aXW@wz~-sYrbjCM$I|kM({yJ^64jG-a!? zY%X`vAVW~_Qf#+Ua)f+2Ao;l#Cv8T#O|`VWku34AA%J|^L@Z?2eCymgm8AA0T$!+I zGB>}mJ?$27M4SuO(W`8OuZ)oQf;h`7T=Lu{(dMwN`NZB?LMx3+LPo#1rwnsuAb42h z(v9e2?px{ww16%YC*OkL{P^3|~^J~LBv$fT^1 zQn(@^3uoVoZkod{DKR}N9VR=X-?Ba4FJx}sq-c_}*i59W=EBGeBpkmeDYm zb=G$90Y0fFP9|`cVjt+h&mR8_2Ol&r5?1+l4DIeA4 zkg{*y6)Am8u9XoHr1VQ7<)dli3(=?ky#0wkcc%Im36v4S4&(ECy=7K%Qvx1BAJ;&e zsm-Ncp&^aMmVtdzZpLH!-X)z^0!1?T0f}V9fR#@`V45W(nZ~APb{Wgb=^3?kaJ+qz zT017Ww`A#}jRJu;H9yh?Tebyjl^4-=35h3$8^J)*#a41^LK>nOtd2&>2^vE>X^K%$ zH)Nv4Ai3>`Sayav2fJ@aXzdOM1UIbYbrJPLtEKAADNhNi$-m>bfR7Gg{PEjSNTP5P z6Qx5j;O%Wz0^8e_Kq9V+KhGy?L`rvGjfT%3tp2ax=s&kt|8D!6kN%bud;*e)q$coP zAX)*-mn1Rc<_vWS-LdA}59aqZ+oUs~sJsW9@Lq$x>I2oYzS{byWx#ZHRsxZO7>tI@ z$XT{3G87>xtirOiObFR8R0YJ}h4*q6iu-+NhB?dfdkJwjBXmroG z(@h#Sm?rV!-=Q!OMeGj8xa|v32fg5Ley~U&aBW5@_Dd|TKAxckV8uWaBS!N2$0ljA zosuqkc0X?Stzo)sF#5bTf_B3_6X4^w&l{vm2_zpR0}4wIX9TS?7`5`mirU@_MF*K! zClYAB_NYB?P@`GShomw~DU|{C?Jhq@5md3EH>elir}^?~zZtdK6uKG!wRUoKMdgMH z5qh8pqvm^d4`x(KoxCI_A%7u+MN^~P6RVktF~w(}ACZ<>4wE}ZH!P4*0>!5T_FkJL zL2o0oC;98=?u4zI4l@@S>BJS&w8h7^tfqk2pb7?u8L`#$Ma&!q<7~#4Mj-*7jmD-k zJDDq|u=D~3EY(UxwWDo^C%V4(`4Hfae!;$lyA}~py%}qo4Gr}Eu+j)uJ=rgtdeq&L zyd1h-vt7}>(NNsTfg71(#7(UcqtWEc6H4xd#m||I75p#pTIFaq*(l~_SY$tAH~1MY8Y|AJ6)gtX51t-O zR&5i-mvok1nJY_KXrkJ(q*AJ2aRPd%BlLkQ>esXokO59^*}+I@(2xZg2DM;ndsNBBSO07blWtrb1mEodMDB*+iz$kT`E3;Xc z*J4s^5ITogXSI8(^-TlF_=Car0n&jIM7yX4BRqkYT0jRS+uX=w;d8OoJpvX*Apzdh zK}V>V*m&7y>d>d)8{L6SSyqP71(u3zy`D?)%|IXmw)ot9QgTZ(qDxU6&buiP=2%B8 zEO%Cv#|535-RS7LO{(}9Ik1*7xSrP!jZ?1Q|1cEuLQB@JVGXvWkChvL!9(3O6`^8xy$U1rRYE0Up_68{(0b2}#I$qn^OviR+HiI>zb2vT!tt8Au zb@;OY@bjS-0ldD9@7A3n3o+L)7%9OWqUp^>usjj#8NWC4@d?_RxI4+UO+~-A(+M^B zy`h<>FvAJEV&KZ!N*5WQJe7QfdYTd5CD-X888QSm8N zQi)z*c8HhhyD6Hfc~~@={6627u!Mp5ReQy=(*t5%2OIZNGcg=b1bH+M}3uWsLJ@{efIQVS%B(-Szj3|HK$^O9FnmF zQobZx*+hsyURh3Zo}Ag?zsF_uta(r#vxHvWM>sfU-kim>@BCpTd6lGiGH3c9&nZJ- z2Lo+2LJ9@Fif2c2rq4{to;JHkEf!QNA#)_cHRTp}4#u-@xw8Ci3IGSsOobdb+h-Z5 z&>Cw(bV^QATLA7AzHdUTxSCAJnaCu?E1A;aPR4ga$tiN0Bd1GS&WG4GOp|x~5wW|2 zCOYoCEH2o|V0cKz4AaT%WTLH@{OI8u6^$ddWUdFP2=)iDd89$EJnEoZ-w6c9AtFCz z*L!aFBX(yb03{}+Jr==(7xT$Wg4P1T!r=n zV>dV{t9N?hHx|(YO5Mzz=1HM@%GRsC-GZMD3h^~gzvsMLccxYik$QV;083jcSBnk! zBa&3GkdmBN9Izf_6jTe(79Znkq-YNtkT(fyI^R0*t<+f&j_ehJs!GI!#?4Ol?E$6I zEO|`stVv!g3BftdDO@*L^7_d>XgU&Tmtg;RhnhMFI5FWk3{yyFOwdaF8;#h1ZlI=T z$_7T6z3>F%uJ*l@2;~@Hg3N-1i(1X8_E_QIi(wLAQEP{IIDTV$SD>`IUcTjNL!8iC zyr@}zGyk?bjvHt*q*WXv{UqCYaay`jj4_y|@4mwAq0<%q_hHb^l-(O~)|y+KEM_6s z&>xEPU3WvVqTZFX#say*-BNhD$H(*-@y~y*V$WP;^ufn__vOdA6Xu-?j_&&g*Wm}N z_t>O4`QXHyJsn_;-5}fRxcPkjKIQ8#bl+T1oB$tM)K{8h1Z`4g)otHTMf zac=LvH3AByvgMa4(xHVV>j9oquM+_C=Np7XPIYjG+vf2&Q zgx>eB%ly@v+l2FdrE1A+i3DEYs2cEE(s%_XftkoJEtCx(~bwCQm>`}^WD45RR;mFJgE^e%q zLTZ^GUUG=~W>2iOXJK<5+z<9{N~dEOZKCTtDv%(%+RR>3J((Hcc(I^ocA5YB8r#T| z1eaxMc;7=>eS0oJ&wZ)#!(h(5g4s9oY#zU~$=swP>Tr^JUFlWgidV1%n@X2mc-Can zWOULesSHhmi=@wHYh(%Vkjl!=Sp-0uy2us*udun@Zm~oLs=1{SF_L#o$l_oIK9kY4 z1b@`kjlpMjXhaiH%kGj>jeE)6<}+HbJSB%K}#rk zGckL$hes#&o-?{k=RM@C20AqVfEwD`XBr=9Nv~91bL%Ad0BQp#KI@yZMuiK2TN@$j zIcXew@(VD{A;bjZ9jX5g1FZ}DG=PaaHx9Ao}4n!!d zs%6aq=kS{KRs&qaHz(|)^cY9$w+E}{JXPH3?ldmq)Ip>R_aoL=xL1D? zglN|w-*z%Jj9S8goO;?p?gkz!+d#GR!T2o;vn)&@^WEHC%}mHPsh&AKn(l?+ z4U7I~Jf;0^A=a7bbiA{NwmK0$EP?H828?4dr2v5X&<}%=7~AWcgP#@K+!@(ImqWG& zRFQ)PJd@Q23gGKpgiTf6*X8z9?X+EfE+HM|?4X+q60urLz&M+9kkqE3_5FOcw5aw! zLn0z~GTpTfj8N^$M9GxX*yqiLa3Y>sS%ii_0Zfxoocd3#|hQj*#-HheYRC()je zb*74s4|Uw!MFTGl>y;}6$AQrp^a}q)CRq!cjNHz<+pl=weWn$W+gcdTw#l#bhBV5Q zrsDD#R#}vWRQ($5h3T#nyN=L9p?;u9Lg4!tB;?td;q8asDv)E^!V8Y$)XG1MYiMf2 zYiWtT(-k+Dh*H$qIN25!nESa!8-C8(FSd2O)9cst=nW0xR>RTVTZ4N<|NhDDHoQML z8`A&q4@iO<9)Ej4)4-P#)NJU!xiz>A3G`NhLt5~c_l>9c2BUs1{205n%%-tGC$DR7VP{z0w3 ze!ThFlg}UO*RvJGWyMHv4_vz)I&tp7tP{143yZut-0BYZV|pMOD$Jfdy?*T?H6I`) z*RO3UT&wFXJlH!Xhe**~vZaciohQuN*XtE#^FEr(mJMk#)&{>9f)NhauOX@n;xvGt zzfuGJ&>k7K2vi6#eC&JcEE+&DcLmC@NltT0Y@u5l) ze&ZmFyeX8GMBZHjz$tMT049}&gK6|(|_Lpn^k1VruPR4jwLx_?y`gO${ zvH2@_uCwbsI_vVhe#OC=Dhg{~e;bacM@O85i(%v}=L4}BC?AdP-MRSmDsN|6Iz;HXxFubt}}N*w%yfTrlxc4 z`Q1o7xQpU;frdQ?+XZ`W&cSlS92Ol!yYuTk2l_F1E!gaj!C^bh|}f{bT~?&`d255_*1qKfFp(04~KUBo$g*#$11l?p;OB%v{U4u!CxZ zWR7Mk$v$KaO=8sv`F*RgI+DxHD$%XiBl*_hK5y~+BQ{KA)gI-tXA2hEgXg!uQBa8) zQ&~y=a4Q}@svkb$Vc&B#j^`~P3ySfmJu|c|&>zcyngtNol3n~7z7mpNe2_l>Bkbrp zob8%C*A;m&T{|LgAPa_L067)0~W47IB;2<^x@S#PTavb??9 zdZr%;?XEiVS3mT(gT|?eRk~dI{z+YH->b;la>avhwc;)E&8Bo=*j<+`nT~=Z(4&VV zP~%mOR{vHrOMJ(WFXTwf$Xc=WO^Cq}NMtIierk@u$8|l^4;QOYt@Jc1gB5g5%2%UlC{8aQyX^Z2 z3uP-f9jbOHdKG#w2A_HRjL5&l!J94@<$iB+1Dzs&X|Y8rpqzXxz7mQJT>=zJ|YHsC*D@E%ext+T+?EB^d`S=|M_x_)Shog8MGAkbfELl zx!44{o^I$rZeO*2exK6bv1FLsKKHnh_rABTZJH(e-n##;KaC%ng<`uPMIkDt; z^%F}WqORF;MZaozp%On6Jt}d+!S4qj3Wvsr&Q;VL|?zg<^$z>$Uha*q*-lmtNhmXc4qwt^y}B2 z{_2N+e(eYP`Op99#odqozyIg|`f&7vAL#%8Tb>fmgwZp zjySN?=+a@8$Xh^}EU%z%nAp|=x0Q6@{gN?Mx3cN$J z(%_TdpHZ*X$H{2OyqwOsZ51{tHxhxO6f!48$Sl)XmDyzZ(so}4BT{OC_JL-5x>VXe z{j^*M24SvWbD(700Tqn4;Dj|3J$R>tR3T7dr!FY3X%#O8pVAB}+gD+uy=H%=#95L% z9YwIH`?fVtbVULQhH>!(`y6-2Q34Z;q%pOqT9%b z+>27LsGtnp*z=Fe-_b&p2xr~<_^DMT=T^mPd zbCsl^xn99{HhZnaFz4qu3h!CX!9D>uq+yH>5lNS${keUoB_<7dk>(-9GYPU93lNpFjpAmW-7=@|`nAuk zoV_x*+h)R0g^q}$j%pTEVvkZgj9X!F+{kT_-mpj7enooJWI_!prE}+q{qxfdg|OGp zs5o}1BhA=KvLhjg{!n0~Ie3SVP_MnIPJvqv&+`ta!OAL!Axw~DQw*f(sh?DAE2}hV z<)yX9o|NLVez?@C?P1nP^aTZ-G^OCQ*)!`fb$W}=v!AT)Lu`yC>W|ra`tivtK)mJn z#2YCG2j*m7)USVUy6dcu?jZo>O?SAoaHd1F$tf;U!rtt0x~Z=8wwt?w{NJ^mcFiEBU8@qSh<>HKzwlk?} zRypW^q8Tb?MLB~)&-yhdua=G^9H;k7`M#%X0yc8WV82Bc*9`rkajwi)#BUp}=;BQ! z*{|(ITyuM>3f)#-U!v>_grwXLAZCbbuh-k8m>#1+P3WMyDN6`_ z9`sSF!qmbzc7TQ}DDBGaa^&&!jx(Gq0VZxNzMzvPI|5FU8ExZ;d+z8${#IQeAvmCs zLUMc{UxHrn-x~wAK=i-dOS9ah_(Nx^<5vwypvwc7F?|{3To}Uh;Z~SD6$;P+yU!X2 z#%!G|7eKFH`(pFa!_CLr`UmCZ+m)BtoW&o`f#?PaW90u5w-fWnf!hciwXM%9FoLss z9vtVpt{x2#1rq=X5yJ#)x%g9K(gNTp-D$Hplj zJa2RA7MTYX#cvJbwGThv=3g(|_bw)PkHc``J-$+3Wloo4vtbo zxzw<=SaPd}g|whLABc9@2WpeW$1q2Lf3*y5;%&)9mUWNq*BRP~#pu1g6OO2(Xs2h6 ziEyVNsTy=JIi*@@yroDfs}d6fS!Z$&xiP~AB|!QK)4TGs#GmO>)_a$E&OFVH59U8# z8IbB`sMw=hEmR!4UOWPEIbU#TA4h*S$9t+Hex^GH9Yw2foeBNKx9Iprj&R#GGY>+(qZA3m7G0TS*Zu8 zo;-z6SIj-sd9GW7u0c?v!AeSYc)e^NAMTZ^km=<5R=s@y2Ic}sE~T(Fb5)H|?Yaq! zm+pRt6|8me0d53}rQfAe);a&l{)tt%MSEWz$2_1Fj%Bi9pu@eK?6t?=$f|k3&7Vr8 zf4)vWJGfzG-xp?iWS}X5E9h;UL?-RF(zO;4^325{s=A#}E{U>k^OYC4>@T?NP8{wR zmVYRv5--iJ!>J##)^Y%!4bVM!IZ2k|#pM6TLrk8<0%i@*a6bBS@0PG`FY z%rd1WR5CmLlc{y!^%Dw@@>@Eqggp+$-{52w*BG+^``~1TqloRtJq$wCDRpKFckCGX5{DHqAuYC znPn3W+iXnHL3`?qk6&N-@$2r#mzdBSUqb!gAJAC_pkA!ZU#y5yFIHZ^U<%UQ6chaX zb=zYO+#8nkvLi=lGo8mIwgczJt8cu9R@8z31*>;R-G2I-r}*Ml_|?KMEjJs#Lr5EW z%}?#x0pDX0_7NOWHw^}S-+cR?9R(*DNf#M14^LrF7NzYfFg>NWtz%&MMWS3|90FD1 zEjF|Hpc*&Zx_+I0w&bm%%RA5vCM=`bd$z-lc}28y?eH?Xtsu-DHS4FF4XmM?N;U@7 zx?#qOfDI_B?y&CmWoCvRxKX6;QSD z15$u*SgXh0-wMn3!Rnh&sYUUT9yM)Z^!7}vEG=pKvC|^5K`eT2%1R$lS=r}T1rTi? zBqGM8>2r^RihX;G?bo6I!TlD!wfAy233cjCf^r zRsUV=cdOn&)0E{DlO2sXwyaL8=jUbII^(Mzl@q#tU#Sry4VW!ix47JO(QRgPqtgJ@rO~yCzCWJtXrH?+fm2Byhb#6cqjf)yDKg!xt@VL;k$jp8*E>}t zX5M<+eg_}zHTj@P46U!H8GzTsLI#>^72-B=%NDNIZeW z_B2S`^^SRMyRtJgR~2A=tDoTMKjj?eocu$zj*C`-e~v_y{oh{97G}PlS^@b9Wj%uo zeBAjo=mff<78R=V!$5L=IAEKmp|@x!-IK&GekQ#0Q~y^uH_X$Ql{B1Eb2j?XuT{hH z@u#|e^%P%QfYt|h26qSR{NKI7`o|SkIY?AAK-R-GGL{Dh+6NRAXgmkCl<%Mov9HJ{ zAyejU+yIopO*;)urpjy|B2ayRyGAg=B1_pYXQNG5t!j_og4MRiyEZ=Aoldt&ULgz%xKlHNZ3;H)op-&e_|9xib8ZfBS+p z((<1h+#4$_VAKf_`N5EVC+)2pyc4UHA`i(8it#1buc7RUy?R)Q1ah)#iyB@v5pdzSQK!%1VOl^cKyn#YZl2;^0a!ot2l&V*GV3%0joHT?gM?K@lNw zCL1Al==yJYocIjY)ZeTO>E31K8JmS94Y4(&Ott;_n2aaPWE`1S8`0W#f&&Bha#;i` zMQ5LjFJmlyn;*sDTOm~mx+#3BObWSPY{rI0HLYl)qTYw$pe?-Tl>_>DLP5tDS}95E zyxx3EB+n6OcTvRr@!84z$JEptAN<%d=uUn--{1K$L^+$B{CNLtx_7k3gB+}A?5v57^ z{V;vb8)P3s@>i1s3U!M3UN=&P%1_{k=vrtzefV^6_x7EtMB`}`P^5TcR(YgO9)ZLv}v6RZ9|-5n_zCJ9Ge$`*lS zuFa=hMSl>J*D4YU^~rjTuSyC{iDb>mprR*T7^EC?AtM%fsrdQG?(XCY&kw(C1woH? zXwS@ef;aCU=|jMDZ7&C^S=;Qe#cstzwzr$sQG)CNH}yz|d{eUbd)v=E+G%+e-JTBT zN|X1yNBRA#9WA1+0eQg_fcizI9?wmpt3myvRJdkz`DOtxd7|xRL5Q+3+o6FVITY{z z7JpN+Nr^b@NU}Nk@C}J#%C7b-4Rpk->nhuMaDUWvX6hqt0$isP#M>(2q&Re53x|;H zZ1Mc`o0fDm-E_Qy>RZWd&qr8b9qqOn>CbkXM2_C` zS8ou#M~{ttYRw)aS^X%;&MwW%>6;BjvY6_Xd(a{rw&=GiUQhnKPc<zVOW^_K~!f8^rZN?8MHa|-=R@8ch>Hg@9 zOl|~V!tNWhkl3i$#n=}A+KW*`lM=hL44rbSBwABl0PBxdeBe>~94o6m9~>6e!j@v| zhgNO(SAeaaWjZR7K8K>z6VJ|1xQ|OAGP`3`d^Q)vY(h+J8t#WVm47%G;R=ZaEnNSG z6iUazQy`ssWwr%VCz#E-+cuA1CUlL8-|MPE5__ ze~Hp%wWW)!9a#^kTE29;cu}ZaSCIQ%nm*`>QeY^9W;Mh+-%Mde0ybAc?AhIlJs*WK~i{;Q}uzCTm#ZM#2~4#f-G&T|+A zH~)^+#4!bds0**~*Zk13`7QsJ(5IA)Z%7sKpPje%dD(F-Ff zrM?j^Ge#Xe+w+$i>W89eCL&}V3Z=@p>uttQ9wx|eMPV!+uaE_fn9NmtxZ8ps?M{eGb^!( zRVx@@><}}Hc&1Sn`}Hqlk`>h}%hmBDD&0wYp*2o>xt-e;9Zje|I2<33w1~`Sm?cP6 z470JDnXy@xnIxG-i^aF5fs_!v>@$1`eLF26SN1NNKS5!b0+6w~=)dYByNWlih2R&* zfb+Hf4Owm3Vwc(*|E{%)t;Bc{(->wVjQ^P8EL<^$c^6lHno*A!YiTZ&VlI(+sQ%0^ zbywoN&?pEbj9YBY1`N72icxPXV`Zk)Z#FTLASn`-VGLecG{txEcSS1!X~R?U zzEP(CyC7QoyNI#Dcc5pU_M+c3>#C)G7X2`V{5&1UDL*+?d=EufYw^cN zUo5agyM&JxMx{NBc!;QaSd>UzGQJ0$V(=w2Ei2^NIc|$8+b872u`Y$BIWme#s_6;p zT+yjx$sNm-SOHy}ajYw|O-wtM23NP&U_@1m@SUt_U#;C^!gXb`nnN#@7S%)^lD`BAMvo^+hD>uUF3*yO91KtBlAEe>9G`aPWej1}wlYL1q z_CXM+y&5!F)qkqZ$?EBOE0ScOn%^+eaq7xO|A)FZKQKdXc{I|7wQ zxgEh&g1tKvLR74M@i4qv3LY8*I#WpO2vQxzwPxx@nxNycpAM#LlQo2jd7S^V)7j(P z9WrxK&aOih?ZO^%bv2hN%p)i(U@;@oSIrwOepDkP7$YkqQq_!!4~;MRo~v5sJHwm4 zJIClN;S3InL^YI}qK#K0`Z^8wI%EdVZH2Vpv{4(bwG!VnBw%K*@Nc0QFQXzlP{mLmHs)lfnGn`e)yZMhmW6aK6zY^ z*kN3z;~jNek&rmOZM&SKEet&cKBMa$0+!c7!2G+>SQ}nG9^iF4MMASX;QXM$riquu zTSvpNb(*dqk|g*8#gb>fDzt6i&h<7)lIGuG`EoeO^SX(Wws+iV%X)J9F2pfk)r8|F zgP1hVps5W$Or} zI<*da=8QyWaqh@BHL6u6M9v&NgX^CtTJRccmZ7J7-LfP-BD8F5=?Vz1ZL`%BNYFOL z=%yt+Udds?zmh-uk5u!s-~1y>%q!0_CR-j%$OdSbW$~QyF2l!irt|z1G5ThWD+Rf_ycu4Aim*%bd^?t!ww5tmxRO>$ z8ch@Gpv=%}{yU1+72M0kiZmGgG*N}Xr!(guT5{Z8&Zze>o}Zp58=!RBX)AcSWKUA- znSO{|D6H{ZsNer4;+@#ElgV+>A#Z68yoN>`W@F=ytqS;XosSv}iUyK%+S*H~VDJ$~ z1cd#$Q6hbjkpTN-NgSZG(=cwc$60T4SKS8cf3vZE1@fTbGBeOTpUcxYoOA!weKjUPWyu$|lnGPlcpn#$_CIDuiTIk zHO)@6HZwD!qda9Rw&36<#MK=hv8$kL8p_SEjpF6g$bzEAp9eBu5gaJnF`Jf);|C4N zmB|iCu_}Rq@%-ovwhHH+@d-(_-pIQv5dxu@c&`mC_cxNt^v3VHL{vGiuW@m2sedo1 z*{Kha^d@#7^ikEERK4+@mxPlfi%3Qf?wy`9Doi_RF4NPSS~n6KA=#5;8-<<6vopnI zB>Q9Uk;4F1FM_apY-w+cA{G)UWkBnFBz4%#B>Jl$jN_Lu@>!U3ML0|sOPv zw(6}kUGiY9g++_KhE~;b5fMGnPj-$uD4;6A^nrU*|8Gxdb*b#v-?j5%dp3D0Oxims zO9+KMKSia+X9uSZ!sZ9qOjb<2#5!hLiH2ZTlxed^2$#kit=-SUmdZ3*o}+&Ewu6%LW1&*>3;Eo*+6X{tGETiB9L zYF$#r5faHzg|s&%4leSc^kVACr#K*El8K(%6w^$7f#q!w{>;eUz zIp3-(n21hhE*29APYWjwbqZ`YJt39I>pzR8za}N}=(Wt7r`O-KlDe{}y!FnO22M*# zrQB7SG!h7ze^lg`=|Sgil^-_x4{tbA~sy0x4-?x!!MqE^{{+wj;l^4i$clCAmL2Y7$j3kXbx9E1t;U=uu$&{ zo6evsVP_9Xj|bmPJuf$_6KkhiW|?~5Q{qA5q0Y7|#nn4POxgH$X*Y9dy!IRx<2UfD zd|z#o?;x!mbZsk58NQxhI;;39>Z`Sqw;CR=aVFb^Vs}h&TgOElFPA*K5@>%}I7^of z$s>*e=$R6#H*KC_MLB;}t z=Qln0(R@Mw`Y7C0vu`GebxM{XS2>`{VQ&CvQeo!BD_qEKq~UqVjRM=5L}jki;)*7Q zPo{)agwdz&8fWVTgxbn%fF=I`6~+}Thtu+E&7pOO!JnW{5_IA7%_CvK;D$(R8SAoUQkl-K+JFfu9G!5V=*+{e{JzxjkB5uo`B;;BlS{1YQuBqF$nR%3x$G zB|{~i(7dC4S8h-8F{d^q$A3@Li<>ILeZMY* zN<=M#p*nHD2_f|T7#hpSeIQEvU}O;6oS}jEDy|2}V`qbqL57&)<~mK8t?MPDAz}V} z#TAT93ixYF#bNl^>!trv@xmT+y~NPH4_hj|M5m|C5x)6k4pS~uI@-|syvWC0(@#HN zVVZiM!?e<@)|k7Lm2F238$l#B#0D~xY$K)SQpGH2IwZ_C#rYnqEjTK9Q3!i=+_%(F zOT~qmRy^-pnvB^+;ZEcVED{E(!FrrzOUG}{ZUys6Ss5f(Swro_i z>r*7r>76U?%Cxu|B9T3g zCXqLb3!krziBoe?>N?Vx9T&k)Fi8`yq3mIIG(FZz7yP`o=yDr7w8XI@imye-aQtpB z&(rNrNy#vAUNWW_C>Lvh0UilbK~NI7FtU;Mn+9riSn>nwc9q&q=`7l2`{0J1jtvLo zGOmh37i`w8BLguB5owojY%c8>2+r#>hQsC)J@PYgSfgPeH}U;NZd?SzA@k`_AD7Zh zO=oj8t3)y-bA~#6*2E#ueif&~$fY(|fDy>qB=GY<%yQ`KLBgv^Pe8Gu$>_xZLjt`! zK*!Q#opLtDBZwIeCY>=czQe7-!1Klsvfw7{LtpV2kB#%#53n!hAMFT0OLbM!`HjVv zjirQ2ZN1ED@ciH)Sc%2fJMchZfst7;`BZHzjWVW8@)Cs11v`e0^-{tjvuq5HS_{I+ zC#QPf?GjK%!XZf_zpYxB`JDE|;ZQhSg?bQ6QwpW`YE-*m)7a#QU!Ac5Fy1|#2LUBxEmo95{yQuDEPs+{SC$Z4V!^ie-n3yW?X)hYa1iJjg0LOcRuP<Hi(uWh$Cyb z!0e@Y6Mv|{090=1g(9IA*uUgsg&^xN>sA%|SC@NxYs?bQ2?4?4TE^Ga(opQ{DIjfBH8g+ndh-9XdlvK`j#}uw{v06AEB1 zM-E-3WgP6*c|lsVVvL5b5!)@OsT0BOlZ{mQv{5_70lJH~p7i77vUkX=0vk-wnkUq} zyK?1<(_)>Q#^?ot+=?hUA!C+@fh2BPRuRNAp~W12!?7EX7byUZ;22^J7***6ZGGr% zleZMfkMDDkrmA58D0IWtj|=#wjI98o5?PsEbT3%c))-~aOUg?3Zchngv#f*&*W211 z%_C$^Lr0cC)VnNJB3S+u*GQH3e$_?-AQH$jk@9d}ktSiQJQ&l9IA+d%JoN*F4UWxU z&E>46z@ewZp@iQ4ZZ#MP@H!FH{ZqZ(tYm$ThJuS`!eQ%kHyl-^kLgEvmfaIz)iFCm zrg3m$es!3ssmRf(by$6tDHLAQ1sFN&-l11443PN%d`5H zajGmRA}&gMZ&4rSZ_mS#DvFhK+)0`ozciJx#cb$@?_=2*X)`v;Pe`*7m1YQYIVM(L ztFd9;h`cg}Mrv1U%>6<@c3#AZsM+I+I_tz# zy|msj-PI)pSd}pW?hb}ZnO4L-AEYL=?4Vi_ikT*S$Eos?SAJ_zhYn`l%%YN!KU8^a z?9DM9d>xCJF*4%eu^@WZM}!&e8jO1&wWyKdCnnS9{L6)z!)GqelnpQc%$4$eR&ppN zPdC2OzA^7qfi8iyt>Vqqq>)dP7 z?B4}#5rutPMTi3m5?P4b!&u$9$yu9<4+f+utDibBRBXrqlN>k=Ck4&4_QIwlH!~j! zxyQ=Na)KalGPRv8FV8QxZ~z!B&tP}LX12b{!Jeb#Su(+;URbyQ`PS#tAm%gk>#K{) z%Sd|$xU&2q_QUe@{H8ocCYCv(vz%C;zr#RK!W2s3@?(C_V=G*}adUoUwEQ7GLedVo zPouHtVA#!djsR;imDK5Tg!ofwAJV?^(&h$rQ`QeVH&@vxwhsTdOxqC2QXyIno3}_J zE>KlA!62K|HG8wO!iqab78S_axm7mDSU8+>+U?LIy-CHKn_pSsOiB7Fc4c;RgEpO; zHy!nzd5ZstJtUtfln$KxMTpeL7iQwblk^*UG|>S+mmhX?`r)jdR(gTMT4}LD1ZJ%x zL&$TE>A?QuY;fL{U_J5ijLpHBkEb2UQ!E<~yNdQ__@4EneBZB1IyQEc7*B_T9P5hw z_D>yS!c|7?7L-@^4WXXU1Z6y)GTM?#i9OI@mhcz}5w#2#3nMaDg{6`87a$Sraa>zt zAB=%R4BeY?&l>+4D5*Iza4tbA`y=8e_C>OVo&Qm6W9m`Th+@4>@QYych zJ1O!@7zm-#vJ^!q8*8?)d@d9qU3_>G+~(Ky3inIN=9c~F*e@7B@D9|fldItddKdH| zY~-Z1QigTgKV9rBHP$+`e{p>zs84W!*kN+h7Zr3_Ueh_8eAWnn{bfQ z#NwIJVZl=!pnLnx(YN0kou0K>!}IZ5@ATBz0`(clr0)uy_{~OE^X*({gB405ZxT(}G>MfWDkvtD`(( zwQ)8GuFXu#h@kMB`U+MJ5ptd2Z*4qG(r%6 zqIa%~DTq+gUs|}(VSbm)N(AD~U>%joSDlrn%qn8WBCk%l> z|23aJul24-pNKyJqx#Hx2Regtsy5lMHxT_3&b+6Qs=XoaPOmRaO_re$l97x+47wva zfmirEOuC+e!mLxg?qCSfsP~{8Q@@8<2dk}sd(uMJ2hs6>(@mh4K=(#Q=JIkiL!*k; zAR0%Sg%P6ZX-3pR#S3R7wVwA*ry6K$8&0^tqUl16lzy6$=6BD8PwQf?GSRaX7pQFG(=N23ckX^ z2}QYSvAnU|xz4-{1*uQ^fqTV#Vsvia7x9L8H{v_fJfXCXd?Ar)gcw3eZkkCgf~m8y zLL&m=G>MLH;q#9>n@HXA-n%n@uPa|4o4SlRD#*lin2NKKa_4oxL@dGE$@S*O#@eYP zNABFYGge8rM>H>yRgIxL5@845SrvfXYf9*kn&%^lT>{hLO-ICEsae$VfW7B8!Fldt zMzmhEucooHAfcvjS7RpPYfeuaDUZGV_S=V#A3e%pYFlM-VJOb+?wpcH9;9H&!XNFIF;;C;MsJ+? zFj_h4UOl%Zq+9Sa5f;4#dm&-1YUJykrLR(e07X*-vB{Cmnohfw*imrsKMkF;w%lW? zOYi|@cnybjNvuN35FlcULFT|oxO1STzO_{X5#$#6!PNu`ST_3o8!~7QsF%`@ffMK5Lc+|*3Uj|@FMasDIDyFP1qr!HJNKQ(zKFXQ3|<%P-S#5sx_ zKRtDRYWBzF`1Bbs>w~G;>B*THl|o$ja`NLzIN+IcYQ^li$#VRo*>e}0<>|@t{M7jA z^OGeGuVnslIdf@pVru++=OEk0g8H$FRa zk=mMcZsw!&vot?6s0nb+Uz{P!2jxdIljt1AXUCQQQu89MrKy+CP13fenmo?`iCOmf zD>XIGHhBz*|n^T1IV48m}^`;did?JPhTJTnx&~#jk#-gULSe?8k_DK@1MFh*0{zwyej>*k&*XD zq%n7Q6zhQ`HSI^=lxyAMdw>bcT6`QOiJ~S4(CSv1YaLv;3I8wg`@Q2w-*`)EEl*%t zXtVKy4#lP_u&mIYd=9QJB=VC`k{L~^x~pm$95P})6tmbIwYeGm98sxa`vP-ffkOGWdIPzHHpOmAd(cJ@4iyTWQ(x7dxCx3AI8>`i zU1sdGzF{mvG7yogwBM?HI*XZHF$)SIs4j4f1twL=QRv9g#w9R-+Xru^!{k!a^*zbGP_ysb=iZ~L)T>aWf3E{qpQ~0|itt!ZSJfX= ze?R8yY0#sT=o`KJ973R$%2nZEUFm_2>eLUws0QId4OHUT5&RnBz}5R4N({qmLl*K} zCD`pM$`l*-5u6ujb9m|lje2FV+Sg-_s#2ehD`V(l;x6vYTB%}!U`_WUx{Tz6-QnGh zIr#cHj2UvC*RvEDG2v+24te+5D)QiGMaY#J^%v-P!A&kvT1hOkiRo&BesYtb(2dM! zLcbAbgPCsS1-18 zD}rNAL<7H>g}aU6Bk0PH%(qsKNK`zGEXvJNr)HDJ8zr>}GKFQ$HqazvRWAsPjtV7L z?NphpWYZenw@M3n0nuEnVTw3*LIi3@h6qF{lwN3FHT2B4joajLvKqXHlsH4OHhdr= z&EMM`wfJ6nyr&4I*qFaDYC1zo+qhlzN#E|{MX(iZDlyQfEIXk3!qha8i)Lo$V1^a3 zsvo9`i=*lT5MOIpQ+hgKI3$*B@Bp;m{1iU=U; zx>k|ur(iUfE8SB0zP7&H!=bf4IW^~8*XSx?DPS;Gn&n>@Djq4-Dlw53TdJq7E+n7C|AWy~$d&4`-~DjAfp zC(`PciYrKHL@i9JAMmO{iDir&=D1h?&F7)I&+x@mS64s1dg|C4M%ac;RexBm2E!ii zH+C(CCd*niBrCE9%f#ecVw0#PaeXoGymskos0X%+)`WwCHD?NP8J~#zY zzD%>1;_gsoT^yCbclGexr;U*E^UyYv_EPq$!S&o%ueBt4Uj4{w3Y&6DRAGwCG z=(1u6>o|pR!qvEoEu-~1`-FX;n%#Er@9@%MtFt~o%xi|9@X^>KQ5&Jx6$+6~@&iji z+x7l%Xsdf3v!HKD((*FmHzTInlc(`W3`LJf+HP$TOnVyoUc-qPo02$Cu#IaQccHZk z59RITPL`;3)JVg246)Cmic{Gl$cnp>jH7jZ-rPyBD5|N^qr{9Zi6hXYF~KRGm$THC z-Zu9ytYwY>azP6SssQ~Q0j(Npqhiib*10{tvtbJlhC6!Tj#fkP3gz!^vaL-HTfV4e z16z_Keyyd=9%(s&KchJh6P0yBTZjw5B)|tIh|H;?Bn8%;8`VGaM~)$Yht=gsCxcHT zOqIETXX_e$P7rg=Ts<$3^1H$8RDth7t4-h$@(M7QBSKcbNt3;+am@B`G?XJlnIN8C zInqYQIO5jk%8J~S`w3}k0hv=`jbP7w&RV3@`pFPh%31Z;)6^u;9wsWlWXlAK<>rI# zjD6hdmJU3+@jO;(`9!(+()da0XE>ND5|G|0(5&I8x?<}bH+3E1F66n z3he=1g%V?e3TVpJ?v2fAb@1Ag^#D=l;og$31T%<9AybxHbWB^KwZ3tuBTtBUD!s;K z8Ti!r<@jKXXVv-o+*-bGN0woBs!pf|IwAtR3{O<%x)FWTkM(I8F2l1uXnDji&~s*= zqz#@$IP!ye!iHg{Kz(nxrI7`V7;)bPZ7{P z6jnqGcCB7q-&~SPm6_o?2=xxzhhDJ2BGg3~mw+)@-%^A&1BnCO}TJ&V0>MP4kBsA^kS z#$f0(BfeHU{l~5E?*ZG*Rr1~%HDan~yXoIH0k*d>c4Dn!lImmS+aBxb!I65st}Msj ze6xaf?0Xojo+|3hK`huiVBH(rIuDd8Fbcg~LM)&j7%BjD9TyvK*P(J;&I|s)F_w$V zW?M3#Dvid|mxh*|tteY}arO2rJmJVo5jjTpj^xk=nozS6l7LzEZRJ8_!Zwzp2Z73g zCT_FChvLL>8v#ohyI`(L5qp;QVI(vKR&Tf0!O&>o8p9W7hDSO3$Rucx zqP#xl>Uxet<;B$!b7pEpH1@0Y@5p_Dd~e^C&k5QCc*52u`a0Yj%zq`0#~~qS@zNM) zCroF|;M&uN(J*paiav9thI{?du{V#t{pQJR@o$|d0S~2ydAC(#+!4G2c9vaaz_5YIX{C=sW9xu; zxuJgzrd7RB`h0)>K4#Y62%vmA>-_@;Do;w!BK8N-_8{4S3#4>i^lXNjNSYlBIas~7803E6gH$LQ5|x(cjY*wokwg(vcQ4W#raTSv=rgPzq9 z($yygC{TJO9Y@FQ=yC+JofTPDd`MQRcS^aIz2=@VslKaJo<>zkC^$kUaov724%{|~ z>FTKypN>{N3g8V{g!DCrbHU@UR}1t0sm9f7cS=+#rEa8CDKnNxP^|q7kG=N5&ma3V zQDLT_$!zzzm#?!%(t!lYv`0S@=~-5H;!fw{%I=~g@r6CAzsF93@>`uQ*G~8NebpiE zbuJG`o2zI)B6Q7bx|*RGT8Y;8hPOL5ItrLoz)ZDwYD2zt<_lCFr0jzb7CZxGo;I&x ziR$J_i{C-MwdW@gzRv1p`~iv#hD|=$NHeLD*se6E>X6blPnTkii8?9 z8n%<&JDv5FrLQQF{f$C3#44EqY~5#IvUwk-V}HQKVP>N__Hy^02TI_0G0kB~c*g`a zy`;j%Fi>TbBS4RsXNF$zJv<0K#mQ4&yLuaV?Sw1CGK(34J-|2<(; z-~vhHORJ`8G%#jVZBqs(O6O2ZO7T7=fMPkroMF?(I6=lyu>t*zK5ci!m$!D4fcW&mf?5qX0kFgw{2vhV`pErvw?V^>;Vg!YJJ%HG1zKR@5*t`43TGev5 zm#@#f6?)L?BTmCh+8Shd!SSWTILrs1k7N2HyuZ{5&@e?1Q!?P#pj*olKxA^gTK}~m zdeX=LK|B1Z4=XcMM+8wJmwYxvyyYk>IMQl3^+TNjwMxTpOwiaCvDtO>)EtxQyn+f|5Q(1Je&X z2b?RFj5n6hD-ky)@yd#}R?e@rW89Qtaj&?|eCH)7Pgv+qwyFp zwoe6%Jbr(}Cd@(0-1D$1WQE;t&irH*8ADVr79VMylI9!zlB>2>i0$hH0P8o*r5xVJ zEVBH?vN5K(NZGdB`cO>UHgV&w;@$=z9=7sf(p$1EyKKv~t-1uIv-w;#K8DO4VxJ7aiG!*Jn-`!(`t^oGsgDm z8|;t3H%ZEGjSo95?2k<`q?I*EA@C*}cXS>+h;J--ff(chX$gC|#Nk{Irn^{-{QpnI z?HViH)+#dI0*IcC2J&A%g5%aY{*;7_IK0_C0`(NaIHIUDM>^fGvh`{Xd^E#fkCra~H-Z&P`2Ej^Zvfcj^52tUS@@ zE>BIf!F76e^qMzH-QV)lCkOe?T)aF}!PE46aegw;iNe`P8~;um2{t90XM=flYG8tN zf&4xSfp-ElI+EYyVz4GYY5BLd$j5SV~IAWY| zu4iU({kHarTw?2FnR7s1^YF~2Vbt@=a_mI(f}jjFPF&Od!BV4@Hz4zBY23JR?Hb$m zeGXr{7HHYEYr&H*jAA266A<0KQpQmhmv(okRl#DZtBgBZZ-3B@=1;A@|E zS$jMnJ2C!c)D$tc7#Uqf)Rc-{JaoFCIf+SO^d2v0N&hL+mjvxBSvJQJEI&lkH8{Z!quP~(Uw!BGgSG(RNzUZqKq}0Vl=iQLtJ$Xp@O}zMyNhDJr6?{ z_|Qg^;4K8*FvH)dhus*nhg{p4l^Hr;2PWo+0JQ51t>duF4gOZvoB;Bhi+An))#Kuc zJVO9-AIV=#9?E!Bu=+nT8l=#^3IKy?6v%6`eN#XgL|e|GL&*+s2?wh%#xPpyK?n zHC{W`Jt)8V4zk-WNJCY%TlVS=507EEXDf;A@x#~1HX&MZZsSQpqyDfqaS#xH>y+?(yu4g z(I{vMfRTbqM(buW+FZmf)*29ksvEW9LWjKJn|&Hi_cj`8{bp)C%>2>w)`jD5g#4;K zcEbAVsnrYpc;c|dQfbj>5gsJ;C8qVnmiE}ms@sMVNLnkGk}0|uj-U--&|54GNb;yE zuSn#hfXSPh^)pqH!0KE_FUb{JepYJF6 zj!Nf#pWos$+N$~G;V;bL#<6J4H6q8vOtkRGj&|YOS_gbC%-80E;dJ0ihmM^phfltB zt8YVzv~u@2-!FCUEUsUgxNn+y(zH*!buu=WB`8YeW8R<5sITilGcB4BMgo*`YmMAK zP*G50E|ktxXA#HD82jz@)sa)E-4h6ymna(t(0f*XXyW~N^&a(n3U(A0rfcVMe_FRY z7EGN`cTAU-k?yJ+a_jgwSo2wtY!^}Bd=Y^kMrB~NVw$~<_mO53yp767Z(GfTF;D{{ zrM7oYq^puDYQ18IGmtgXW!-vtBd(LR(jt|wiU@2&r|SjqH_kn7wUfF|*v)hjBgs7q zT@NtNdd?zr5RzN4B;ONu<0EUY6Zl zZK4lbb^cMI6;wc4J7##iZx-_!N^Tw@69Z{$r{CC8lFt_JSx9=n@>j-G5N+}jtMVV* zlNEwNsuPy6)}N|L_pdTcC(9frda76x+`4f89(u>_KRwCr3neAgq`gmb;Gpz%n6>3| zJ7p4J?w`rQ78(&+&r|5y{qv>1SBX>Z(DzWNTGX@f;xyZWaQn|l1v_!HXx0M{%mr&3 z1rm4!9IWRsF3;nfY!6#pb08`X5#h6lrtX*6Yrq)7O2zVkBZ}u04PPPF>!LZ)3v?Ee z87qoJz7BBq+AF6S<-lxa1~c29X{m?}q;2Nn&chZgfh-24mM@LU($4S-B9bgGpxom4f!YfW!0g;*in?zRac3Ssx9XR%&HMoBaVW%;Ks%gZ+BVc~j z?YeUc`{t6oW7w*KN>~V`TUMjpNpJ|GJ?xU-l`^Ob#Rt>2*DF$CxFU|1=`KBqHGgJv z6{p^eN6>EbRazb;bX7%{k0hu_ST>$48D(21QPjSZr8gZ=bA#jKX9_sSHS-+z8p zNe}5XGNNY1!Z9MJ857&|o|=qVG(I0LPlUyzinh2bhGdy@pOVqX-kmgchC+$-6D0xh z)7oK^Ri)2?X1M2o&L+uVtMB@$`xEO;k6(>m=_l6Zf9Y2R7*9a=Y)7-ax_}IxoITA^ zvIv*DpX2gY0K|k0^2y#oj&lZMOo!Oj?QW)&?$dgo;FqyLYfoYz!FR$yRYPdlv@K`l zde8dR<|%q7@Kkf^%E>qK)?%RK9lf>y>h^H*4cTv#@z`}5C*ROPHPO-T9d>Y|waVh_ z;Dl~FS`@Pujd5Vwq)w5JVxEn5AtX;Kcr*m^J8@hkS3No;b(Bo+$nH84D*5*1-LAT< z=4a4lW`@dprc!KDauTu)F^!XNPX`gAG z+dgM$MSGkk*j$Vmf;Xh}idE$Qs@<9ALC9=7#}0ab(mwQ{rch*kt+zxe*t+39)>1F@ zROw06%lg`^S`gfpp>6IV*Arua?PJIg4L0?STF>KwUuuSjlklQY`M^*rezMU*?0%Dgb5I@18!0M;l-AQhxd)xm(k&p`7#&9!1$Viwx&En$`tkD zfhn(Dd*r029y#SZkDT)0Bd2UUa>|jIGLF%7$M?@OR{<3}glZv`6HAk@&VJN&ShF91LRJlPi7@iU_3k_htN7Mpv!^HI)M#{^^QIij(l`?R!Qi!eB zgTOM!Qss%Ms3PRe+Y-Mfr^#CQhxnDe@iw?jdKm%F#BT|6tfKvE1W9s>V!c8gb@oh| zoUt*i2bl;MpcetuIf$Sa^}x>FtOrV%a`I%oDhzbBECs00nWUxAyLwd-t@eo_U8^_* znKp0eY;fcrtK$|#=)$(MH0k;^Kp`EpJ!xL&FkSEJuZXAO|ASdWd_Ie5PbEwZm0N9m zvV5b%A!D`&h7Oi<;kBQW8Of9yk$&1;(rCM))o)Lu+RBk$>0uNV(88UT-uYb*CbiOJ zX;UF7XM9nS6r~G2u$ru0IayQ!1HgNw?I-ct>~sT4&e*dsMzIPnNF5CH+6OB3pNSoN z7$B17aBm!GA$7H&YP6)ZNUY;mQ|}{TS@7vmh@*~f*OoDv!*Ja6>eU;Z^_N2!1Y?Ns zB#dW1CsLP6MadCIEWQhUc9ar3(eBE2VzClpTUD2SV!o`)2}o6|lrk1(fR5RakYjM6 zto*3*4^WSZ6A&TkY;>6OaO0gd?MhE(PSi`xTd&$d85MV6YSDJ*2f(SdNcO$hfN4X* zY6~4pqY<{&)VZv%)uy%}@4v(D;n=_eG*B@L(A7pb^MTC>$G=}5L8X0Um17y?1LnOB zqZKeyV|)YZ@UJ_>9NS>!XmUjy9HpAihqgZ`{FLgdCY7TW#W6IL#)t&kr@z}^Qm1@sQDhP}brek{tbFuKZZ8VpD$gImo-! zfLu^OIl=vBFYKB7>aEX?xNYu(XLQS#fzxTy2qKOl55(r{OH8qph!WLvmAxppbK zxfY9?9IE)UW#kR{?5KWgu;FUSc)ZsU8=80qQr<|`SH;BV_@mit=uw+vgJWnVZ3~;n ze?Bio;oCPeO@sPCUQ`X$#4tu*9|8c>JYv!aPr0hqCWpwWeyYBYm8X&BlhZlM3r82^ z!Y1Q*y{?)KHXjQScwduGUWkJmANg7nQgkRqHNf*jxQad6LW3}s$tuK<+L-m6_*4yt z_A!T#Iz@r=IT9}#^&jv0NlO+>X3L&UR24d@no@w6R~5safq_jKVdW=mDEQ3+=;-SK zz?SV0bN6gaTtd$=9?UEbA*+Fa!w@!My2N{H&k5b;e{#l9M-&|=GNQ7EDZW+J^(f~6 zx{E>oE$m=Hu+q11HWn3^^%hm-n37%Gx_L#WnN&>@wJUSZdHCw6aFAJa`{NvG$}}7a zvWd=|~=$w}Yi%xtoYbc=3_OT3XFOOG-!|4a z7xE=%hr}sc{0RYjSRo`FJ`A00-somM;o@xSfC`G3#~&y zP)Tw=H~Zi;u`{cN^4+ic<-B?WjB#fTrGM?M5h)LOn>2IoZewSF+DK`d;GBS2Be1)X zvv8ON1_cHnaMDVeVdY#6QRnf*oK#yVvZ;mBz4+zoO*R;ZdZsMeSl7!sdSRwwPG`j5 zAt>Q6%LB$k7#s%!oqthH@I%4Sw8)vp+F+C@B;8%D$-FeW?_?cAke$QtQr54;+vn`D z#^m~_%n*I^U(NGn+eDR(I(uVsTWLat@0Hi9ZiK|W77V?PSU-hG(8~ZN&4Nf~B0WO( zHwvur4ucA+@@xLq^i%=^mba=)_TGMA(1Z%HPUPk!|eLG zPaX??GqsLGlvZffrdSqnd3pjMD?o&iH`ol`(S-c;x zZqm+d?RvEZz_z=Ah{YU%=$&z>`XwMng?|5{1huRQ71LN1(j&h0w|tAw3Jl>yVnFHx8dGCsK)H$#5UMgFL4O zAY0_os4tyouNy%0NFGg_Dl_#~ev-7nX5d-2gQX(}lE}O2oKDALC<>WQzY+pcOfq>~ zB$mo1qCwrkm=V7u6{qIZS!Job^PSR_UvPad`Q!N{<7J!y-C^jbe3h)B1A0^u(X>3d|Uwy2jVmd>ykG#2PXmi1@Awo;O+>0 z?H%-v1+Jy86slq8b1NM2%Q43`Y}6j;uc?txV5ps}Zyc^TErslNvYM!tq>$aE}1L}mFtL(}2O zH%BJ{66#xF*pe|Ko2JZw*gq<y}q6Xg_+pXWBQrFJK&%Uxu_d?42(F9 zh^dOpK@KD4q5@^WFmJ&ZUPvRah+~BDU^8JqEI}=-;PqyR2r)w^685yEKBj4tsIJtD)pj-O(D8n-7Q#<#2I?Us=ALdp}j} z1z+^Wd+KFgNh}m~{|Qx<2Fu=mMytpA3596c<;;+O^lKl6Ab!qrA3IsGQt|VHL7I7v zTs=iRd9_s@n7xBjO~tMLbF|xBIB7_ZOw@p?@*k?uY83RbYPd7cV`i}k{=14nzI8r5 z801xfJ~{KbV;u!|+k90o!FBiRWPb*aTJ7lM6!+d1`xa3<-hFYAK)nzXBPxAx9$Of6K=>vx3k3Z56XtQu zAlpI=)kC#Mdn;77lpu~^y+kFcMj|I9`r?$jA}N{nuU<@@HY=-sg1#Y~@mqyU~0tiqax6Kmu&MAG*Jj#ox<^Om*ca`ds>j8sMg~f3mGt9w2>FRCDD~$xhay5oI zJv~=$9Lk+GoVk+$RZe7tByoi82O+o!!BU7y3N*aTrl4EG{mk~famKd$yu&Hl;p1`) zQCw|rU>)~Hr;m)t#+8-$99st11cVv-qz?>JoXn(7i=cmo^f|8~t&0A6(&s!+V#)gF zNuTpP*|_x2l_f~|a<&>2=MZ`zGh9hH4)y!+=Mv%0wAa}sTM2H4sf=AWXOVQGb>K(R zHb$4@ye*Boy}2381L8$I!4ceDh2BFb^IF3!Nl6UoZDs=I=Cc_=AB@PtzlAL$6~%pfE%>j z?oJbScdQV%N90c-ZLm#env~DbibF;gTOgrof&TIKO0nC#S7D|M0~*}GM8Fp7l(e>{=T};{PJT^DSEH0X*ji(mss+yg4r&PAc^FV| zKxEy~9%;!z2ko3otBjYL$X)o8BvrXAFGY=6r$yhOZc)g_`KfA%dC->AiyO8#LT7BL znup?+Hw~~tu+bY>L8q)1SjzQqdU(cSIdunJvMDKTfe`7A+h^vmGj>gwubG-HVDIZh z?7h}~U{Kz~k_=yK9D2WT^%qCUGfJiy`ZwL5Qelr#+*Jy@_Ng*`Y6maX8r@I%mnXQ- zY@64aJ2Lo2$_p`aV;#sU1CmD0^kUV3B@w}+P7`9vZ!it9%7n^M_OJJZ1{5Xn@~eVE z)ggP>(h{Fk+7ZQJPzzj0f??8m3-_OV4lqS>n7wx z18w$J)o2b^JxQ>;Bj3pRWx~tJ7{9Q*=^hqx`wKy{%SP_jQyG=mst6tEvsp1}4D~kuhtT)BiQ3%kQ!FHr4@TwK9 zai+lPUWa%nR#>Xo!M|nOPHJ@(lpC1fC8gtR;AQh@N-=^+1F0?(SK{0^yQf^*O$tYS zQWe<;#@R0G2d@Bcc;Jb)78JRNHQVSLvCw_iYoA$HtqTPDDrS2%>1wp%=Q95vZK7vJ z(@uG`&*bg{l19!g)*&)y_~)_U680t=SO{HWVG**`m`#DovhnlB7C&ET1x1m0JeiKN znlWtoigVT((*QtQLiYh&+5v8fYKwjZ{0Saq`(!oiDjaC($GTxtZ=PQ8W zK1M+Oo+S`z$9S2DdsaD5n}=TP4e&%igH|^M!8pJ>1my}P3*-i1n1%!N2Onw zzkxbLwy?+`1v=9$PaQV-BgM>5Cb?hwB6Tq^RUCfBKHA0Bdq*KPFd~cZ9qljN#giK% z@$2n$ANyG~NEW1rFa3Y|orTiMWBT${r!@yHm{8 z2Z@XANQ0@SPA!!O18fgUjuk8I)I8Y=Z9xK!umRb)#j398p;y&uj%#7(4RlOfd?jSZ zCO$B_DG#qG*oSS`_z=dUA?X@j zurUzFZHK1i)n~l3mAM#vGBnrBX%V>KHAETWv~x?Ub{ScCKJzEyTU9JB{GDYabm7wW z3acQWOd;qilOoPhD>%Y2jZ(Jcxh~-di*XVcNLU^tqh<>YC>sio3!pMTkkj!r zT6zM3tNdK2m$y5xlh}aSon47NWztPAbh;cD-d+eo&mn=Yt;74gT%Qt;s3)SgK`r8$ z=}BB0Fe^#o%M^9#9a%H&TbScn!qASWV#v4}o3jtzxgUW7&_wgaUE{s$pzZoY{ex z)>yxS@+>!dnUBrp-BRI@IWoiGn!zBQg{hm!nCjjRP}B`R(pl>PLCj)8jfCv42$N`< zsWg(AY_0C~{lO@=K{ShMf%i?Nm$99rx~X?9>rkKJz?}O_X1K6~;xBfw|A{KMK_2bgB=w#%#;aaEGIr zA0gcX01+`=FT^jH!LkN&d({u-Uma>+A6j9KQjo);2k4@51O>;W3IoGOtajx)4X3R2hObb8rnyh99x%UUR{Dh4-0X%mwmvlpQ>|+1STi8LEsdhKN0pt z;r^%Cf1qQ9;?h^ZH)nB%bjl-3bdH#U?bW%tXdte(;)v~(Q!&|%1q!rU8kXw>n@f8RVs$LR;luYy5(@OT zN7y7_S_487N4D*ahAh9AJ{;P%r_j%z{|m?8`MqO9qknO;DD=CRcd;B!Hdy#8|7hQy zzj1i-%z~xnq69zSxBJdeQM8KU6RrcrCj&)mu=r%KXblyuZN;sj;uCKCep~U$ws^n2 z_+)#$-%)(BqgdQgw09P*?ZuZAva47eD%!h?)(-p6`(4G)$iAm&?Jj;sT~EaHdo2Cl z`1pi9?u!}8K3TM$w!Hg`)-y%xgQ9gnC45;FKmO#&qV=p=*?O+{8I6A0vOQn?j21i- zOMJmfJdl-mwrG9JN+d58eB07LmnGokcPzp4R`|=7;Dw@9TGL;&l;`aFO7SxQ^it6} zXrI0j3z;ffKP*~@tdMUOt?$~`ZxyXq?dIE-?0Z)1cZ$WAi^c6lyDVD6#g~J{+E_8* z&+S*jhxS3cITRniTeKQh^sB|{zLffV#V4;8tr4qX*lKvqYG~N~>vlg<+$@T1tq+UA z){Div+gj(jc}X`HxcNr$?kBHBupJTD+OHR%jMj(psP*`;05d;Uw2oPIM~c>QyE$64 zPT0+{qVm9o} zRkYrzMfBD{Q6M*hfkL!a zcrHnJCe(3DREMY!h^z8&6xXEcL5nj_3KN*3Y9Pq!w}MTkCiKCSw3kipzuhKON|a7z zgc;jorA!g>0Y3-$<+NW!VzE$>a4aX&$g%{gbU8G(%JSx78eR~n_1XQZ^HZc}qPgtM z2)ZCT$XRUYC|qiGWrdXyJhH`Xb{DOs(t2=2tW-EvbQfCN-M+0TEYCz|?cRF(#?1}< zS4PTXZ@>NaVFmmj)qyq(hsRf2Y(zT0xN?1Sot-2K0ld*Ug*V|35X1FOI~4nrqasw! z2~+_P>GoZvL)u^3xTBp-XIHMDOQosjKUm~^4^QQwytKH!(k4U;N)q}@cchG8yJtrW z6AWwAgowmvyP=MaETMcs97=5sYi$WOY!<)Gb;g_-LP|*nK(SoXDMh$Mb?y;O>nS~vpN#y>)Jj6cEinPjR-?qM8F{1mo+|H| zwd7uBlVQHK7^d{(*~#gtD`OKEFO=~JlJe|@)91=FQ!^9i$ET2x$IqWHFON5yHO5>nY@ULACwm+ zn-k|Kas2eu`Kj3-m*dlCtf&vBW~V1-W>iQyeX*SUcyfBSoH?g9%$}Pp$3L1qcd=QX zo-EH#jh{Y0S#nMdd4F8aT$-Gi8b9wH<@lMY=H$d|$;XL{(=(Gl`iNrqT%H-fFn*R! zgk16Q^11QZnTu4`q-Qf9ou8%g-kc_YIe&4693PY)%}jEf=J@QmvR`Umq^&gc^0`S` z)>MPX`9Co`b#Yp$sd%=@qc>@K^6dF3U_CLZ%oi=k?8PRDKLWy*X|x<~PR$5x+I>L@ zB&1NvnWit4YArJG3ly}*+A-PGSv})c@&^DZ8;bH3VFGaJv9Y6LZ?yk8Khxa_o*Q#> zCTXJj+8Ft~LDNo8%r&kaJ^Z!~a^;P_Hs-F~d41&lYh&F`Jy?X=9&G*lZ{Q=E?v90)gThSgUJ|8N;^IyQ`@N!3ScXVK5 zuxJkzpKmWd-ywqV#m?gMoyA(C80g7BinZ;cLJuTwZxiowZAbCNuHuW` z#TR>uFP?P+ZzF;sF-HY zcJIn4RcdY}fjc<!O=C@itF-`c!oeHL!Y1DzcU99X3IE8#CAioR2+4=zP6%9m;$!6=a&{ zNUmjVuS7_;y1Hutj=W+4${Py{Sx;uA%GNMZtV|MCPgibhfLxHciOPux2rwmfr;{?T z-`gO-nUh$SR#B{9Z*wg+v_{n@W?xa5KB~de_4f*zVhL2shJ+Z$4)7T4Y~0YY&Ten4 zcQ)6$8$-OsG;Mz|p;);K%aGiLP{D>IsH&%)x_y0PC$EE!WMen?spT7>jAF^^@)!e_ z1rlx_RyNdFwO<&ksk*J5){$7Ay4&qo6&p9zm9ACMRfq^N8V$Y|cIkeLyME(gv?dyWtEYJ!t6a03!(O!@wSh0<0I3SGB`JG~be*1%CwJ&%C-4(^%KP&8c z=F?vnHU--49l{5WP3bfEk$do)cyw?X&({o1f>Bqu6$76g7lswCK*w} zts|kD-G%zHJN9L}BTb~1dxkpPJyUEvVHKIEOgS&M_7?pAQULy*sE1Jh6I8jcC|mmtNk0LA?B#o({RSBN zHwG^A*g0Zv+hheRx1Q8M@tUHP^<`0$97do0(}36WmyM@18~z@bfWgg^)+{!}M?mIT zV3C7#24ar+=^{sx5wU_lZ+1MgO+*hu)8TL-Ohtjs1fAH9{FzO-3$q%G zmJ{=OHE-uv*()KURPziW6mJ>R@89y~#j3i`)4L;BBah6tR*r~N9A56+;AW{~ct^Fd z2v`q-#f7QqIk?Z+IoPoo*dD_r_G0P`Y@8v4!`&xUBmvKkjD_d{i!H}=LMz%}Va;K6 z0bF6EBb(iIod|h^SPq+O#tXIe-adBKi4^S8(MIf7V;`vumx7FhMitD<5S5>!)zmx7 zBAl~~9N2Y~$1vwJI{45^lYb=T2);b{D!cGAtZrT zHiM>NSi!5^vSbO6s@Bc!1F70iloh=d0IR;##l%V&l`-#HcnJWAa8E zdB3UL)@x3XZ6o4|k}WL~zJ1%28Jb>W2HiUlFtuZ55b)*I zL&Y|sJ6Ju?z_Y~wKee^KI#>)`xqDqm`pl<46wk|ufCL>;!_a|lJ1D03(*}1JhOT#t zg$3z?>CvrpgmZXR6qi2xGa$Gh*zaZ9o@xSP%`kr;5tRD^_*p!(VMnk#g@WzCl&B4b zpIAt3Lv6zO-T<+{c>|1Z7IQ0(mj{?-@z^l0dI3uf_Fn*rU8JN0}-X z?suP~MKq4vAQuD0#*=!-M^P7;X|cO}-0rkQrKySQNfEX8@XQL5TSXA6c;`?{ zSJ+A&F}ctXs3FvKL!O2%jUY8k(lx~`83M8BEgMhs7!TE$6VA{u*mv0Kg_})rP0f?K z7*5n<#EH!(crf&y3J9yXDW0(TU0q()<$Jnl`57bGd|i)1c+F8R%q7rEj8SB8cVtG7 z3>B(X%>zoQA}m2_WNUL}XJ9#0PEVbH^Q1IAv4X6u3w*isl5L z5j<<+@?a0A$80ol5(QWl0%{apU0OSe(zH74p<1Oeoo{LJwQ*etzDN{^hsWDj%CjF$ zNeDxw#|}zGSx9BL3`;600jJKKpUhf$dA;rKfgS>Ft<7QXG`vzfYbOOM9KZ1`(K zANI{XOB^9=Q*!{VrM$kmq_|ABYE`|p+n(6Uy=2RfaHY)|@-zkM<^^3Ya(SFZX-j)f zQsdm*EA*(V$)qSEr7bSc%~jp7yN7Bnnjez)Y4zn< zZg%Y10Vi$$2A_Ol_qN?TpWE*UOCVKK)b$B|yZ?*}$b}(;^7&L_1VLG#8_<;`?-LB- zQ^HB4yR}WY>+`jo^P8ILMeg~bY>avtT zSH|s~R?#skf~h1U)!S709jYPe9;*p#$`2wuHGGE3)hTOh0kZBn|ZL6`)XsC`zO$`c8})F|iqTamLWUO@!cEI5$1(I(B1;EVJF2 z>!68oJ}pWru^F?tdb_<&%u5Xh;=OStme`P_h9=wo-kguwLR@jnCiJ?C4^esLvq+P` zG{eo0xXW;;%4ja?E5DD5u$1ZS0CPmFS+Qfsz_*5m2A*PRY&Sgm)WGhcr&uieSuO_# zr2u<+a6yYu^Gj3N=GU)s0}TY7f)XT0A*evMPj}z0H2tG8qX_A3wd<$2lW{BKpvT>gGCwYGHf+tsHFR^&=!1f6*WalQwb4)88!Ca z_XD^!7FGjGU2w3O50=`*Qp8-ra_d@L(>r?vw|p0im#T=J)qa+dFrff$F$QvHNHmxg zH*CmFhDJ23`pjV&_7_!l^E}V?K<$S4ZLg2v7gG@E&MIwADWwpmOw%^=LgyZ17Ho(l z5@TpxXX%+f^`@qTuuQRC`p~DD0tc7`Paw%ZKhRatNaJy8U5!1`D*FN_AdS#OP zNb@?0<5D?x(mF*jUHjYV9yjhv?0lL`6I2~06Q~I{1I-~u*v%rWXw9L!e@6J^%%_{0 zCimVJVMrQNI4P&4l7qQ73zGDvv;u?#jtiXH<<;Xh?RY69w-?ldMs?t`M#2AqZ2+^+ z>noS|SXYlaenZw~hErz{#r@HAtDOb901`A+;x*Vngm;qKssKN|1kMx=mhcP$-CmSY zHaAR{f3_DTIRylUO-sm1GQ^le$$9+a0JD;_m)bXUR=n)xn#hRNagt-ia2tfL2DiRT zi#Q(-Ty|csH-;LMJS~_h3(9K->+&E4A1u2B@R9XAhVa&Q3pno-5JI+^N(4vPb*-B= zY6rB7O_o+_nO>YZa(t}pjU%7cp3FzopeWy6-%hc`&Lr8~yIb`#n#4kHY;p=TT5GZS zN8HjTrWxL~43BvV)rzK4rr73BNanoF9qt}pkPE~&N!x@mEsP*IKOs_K{DgBrS|?K% zjahe8BE$`GWC7FSIrk`OeqWgk-E_HYXn{2^aWMoDbRe#3Jiyx|{3Q3pt`isIh7T*B z5Y(NU_e}hL9L!=3WA5m50@}yKF1p7ltJwe4z|%w05e~tu?}e~DJ9J=hCz`}vgOHvf zSz~shB@~y&FGMJ@sR>h@pcv<4ZXwRI42GN&%~^uWt0>w~--$aID6YWm%rt~8yCRgB zGG%%TyS`<>Gu=~i09s$Xfy__rRRW~u6TQz=iy9jypD!W8|N7*#`CzQNDL6RVULm{h zxy*If#SSC$#vRPBwVQu}rdcBm>eOxc-Bcawd#K8j@%)IS-fEw-O6FilOj-PwH5{7J z#ZFOqp?O2dniLYICiw0Co6vjlhQ=`hY2yv0B1QfMZN6X}Tf)!~>LuK~Ohu|JLxlzh za=yJ-2J`JGmfZjWsAqhaYyk3j6}~fuNY!TLWwm=xD>|#S(5DC%d)*2f<#;Sgnj;k&-em7C38Kt zBjrHtDb*!rdmhk;V&nl&e|Db9!)pvh;k6lp;_Ii<>!)LC+%A=G`=E5HcwfeR&&JoQ zf0deO2@EeqswK~5ErDrL<Pj({f+p#_03rJ>L@LN zzeL52kEa6_$Ajl-e~q4mF}+txv5n68^QVl(L+C@3fg9gk3)rZjq@{?b?SDY zV5LHPa0Vnh!rDjNF)-yx`=@e}Iu46k5(s+ZR7uzy@&@u;4igJK4Evncm?GYD4usm0)e#+NhM<{T7Ek{rch(kcnOs89Q-(k%pvFmS~<7 z`dDfgBPrF?+MKg7T3=vlI>@!}fAIIpvH? z@*6cRn*#sf7qTR8%Uk8Sc^wVgA|8dI*wpYftdB%Hmc}s|Gi^F_uHSBVHoNE_t+e$` z`sa+#iQ_4^oJdgYDYkc%0;A#8#ZjXZMheVng6S;#=!c85iaZt%tuutq-i z**tmI_>&FkMb3RV`Qy3s7bnKg&s`XwI5#ytx$zvYG1AUmIzK)uC$zcCQ-qF24Bn9C ztrYo-F)%KYEr;P|Ek}kTs=#W==S6%`prAgW|mrRct-4m~+*pt`70=*W@ z*rCxd^AyOhtAgHs6SYCSf2;jTyuaYOOSza_SVY}Q5@nQUYgeX*``1@a&-PSl?L_*A zRC=XXE+NlyubSm1>qpnRq)vr;WtvulfTfzT9eB-7XTzW!x^$X=x2@^TmFtV^u5J*o z6u!-}*j*vXI|fZdRE+$J3aktQQFCW7)UP+(wdx|vn1TonEf~CZrm{f{JUGUbF4Jy1FVq?UH@|Qj` zoXs_!9*31wZf9S>w|`xni{Mav%k>q{4ICW!*0vW1UVw`+Q;g{^q_MDH(_QT6X-9Yy z-s@>_|KQHSX9u1_^YJ7M=g`2jyTq0%En@G`lS6w3Oy{BQsS(B%K_e@cXc?{u3MhWZ zRsTc94P%s~Ei>Nd?uXKiocVM@EYQ7YjdCLYnUE;O$Yq>vwgE^;A#)s3DAo$eSG=p4 z3zUd7D8%HQBS(6T8%k7uoV!%>ZeZ%ig5&z3f0q{~dD{lDCVZHCRyB1-+DcIPYjKz~ z(NKOHB6Re`fa|Pxo4?Adriy9)mM&AeSTS1UG1=pcp-g=2N3wm8bMEE$T^5r$kw_Q4 z7ntuh*8xU>u{==e@3rO(@-}G^b=lPdya$Sxqdr+F925f0&BeRb!}SIBfatR>4^_0< zI+`QTak&3uYM+Wmov(7$g)|F(lWBO5ohmeBP>e1jNVrEFkq)(FR3Gd|z@W1qhOS&Q z`w-JZj+%{ni5W z1R&8(?V35j9+_vgS>`!zp4ZI_+}J*vm$+g340;!Fx8F1#k4jJr8(&ZBqXGo=&#_{_ z%KH|XzO7=u!_CXODY<#Yi@_G^#RNvbrU^O3h;_fo5E_SQi=i)bn6Z93ga~$H6T@d2 zT~plITf7ALNBp1|OExtS&mPwtO!sU>$UhNuLcGp=EGFctisAISIhN~GE!XlcB! za7I>c%r2%<`ww*yeQOIBIK$I*h6fSX ze*Oe#{6(cGia#vcQlxVCWYLyTZFVnX&X@p;%bhjxqwSI}hOFlmQ?~sBJ*tlDiyWKv zFX>5`da11)lfTTJvka>4#&w@w<9CXL5(T?oS zH0Q=GASEod@7haS9`=$Ig5JtFmIlQ zzKy==S-aQMOQw_B4KWfClK=1Sfp0n+AeisqcY@#U79A99fUKcz^e_@N6LnAnK?fz1 zvkJ+Hw+eJN(YbO_n4d7Q$Cl?;Z#4fpPX=uiH<#9N%2?mHXX%>1!WSpgO7l375ko$w zDx?iU5?q7n2+AM`ai$DtlkO&S`n?(mI!EyMnS!e(zORl23Rx!kfKVu{iOjU-uL%1k6i?+7dsh@sG3EwSLtGm4j-w=pN)nu`h^DSoQk;bB0%R zC*iwaVD7UjU~;9rl)pX;&bX}?Si&s8nbqBhETnM1g8v967Ur0}2}OTPUNH5M#uvMZ zK%Gy(qR(n^N;SBncu5RvbV;D#$|d1%xJv@);6)MuYc~UWws%!HXoNDn@Zj=FWoU_M zkTk6*n^D)kHW2Pse`q>USZj6gRTAKMVE8HQ<${N{y(oSV7rDlqc9M&7%-qODvLaE$~=B z*+RxDXX-UO3(?ZBn^ex+Dk6B<<{DC5=q%L&v4biD*&S^{)fVVGrm$o0>*D$yT=dwo zg%XZ7t}bC9@2rN3O@M0NoL}p9TK8;mI@f)r49XJCDGM=%5dr@kGnc_3FdMJCY(44L7_YKn$BT^^w_vwsaBed4ZtMzrBvYoCTEAbm-XNnzq*@PDkY{5~opA{++eg)^N;xcb+%3XiLR-TQ`~8{Ee~ z^Cp%00WM@a3X7+(wWFRG+B3LsoAx5@ALNeT1?3X|rd4^C-|h%d^o7Kd(T(|6023A> zgpL0!SW!6WE?*HbSy}uyv6YpI-rX%IzE+hue}kmi^9Fga=M55A&l}uQd*0v#)bj@6 zwdc(f5>mbPyN6>Vkvlz^VFwziwHddJvb<^hXMd--TUw9yV^H@L!JxjsD3xIQ0Q-92 z!Hj|Jeg@p6?S+@pDq{udR9TtDqoOtL*=I#m`|lHZ%QUkguZ4y_=wqDrn*?_FpgV&! zzfG++yGy&y+4V?Qi{P5wpR(&ac0FjSLK3NMF4%DrLbQ%55jMks`gl6O;(*j*>~^qS zY#5sm+4Y;KgjIl9?_H()tE6oHuUsAne+XmRF<^fn$V!eZwi)>z+zraWNIq!eM(9KB zVOmgf{R*8<@Y_Ai1!xE%3>0h6L$Zvx0x8E4kzzSdu4SUZnD!>Bq~Wrxvv_)8& zj8QPf@-o|sp@mYTV%ke60dMQ&u(8B;^lri%RbNMUAuWn{>BwEau) zZlLkKYq(#*z@-{N@w}da0}MW#W3-I{iXs$VI9+MPg97mxS+di z8jJBgrL~15*})hKTRxpN*{fZK*O>Xs%?*wiX$t*4&X}7_4>aU$WBq$h1O7av6x;Bu z0a3ibzumaT?*%3As$4nK;QyLhkS#C`xGf?`YVUx5D3`=8-0XRk=vZRO4hgwoGv1An#=4Qkq0jubY_>E-TkD_sVH5Fk9 zDbL>}>dmrm`VIXycTMZjmN_lT-26jbN?kNpoByXS@9Ofv*|`C407WyBrPsA*(en)x=><%V&96?Ag0zQkpOv*!D}4&A&q`BRh7yt*ynY*Se#hnlVN_6H8-= z>u)nxKvZi4?_jnjgAD%0AQ7Q67+uhgR!&)fFOpI^ELJMOj~ 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�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

A6c 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�v#Z5o$Q9U6L{|QW5V;0cOvlhowHNwJo_kI zvjbT?yk~YO>Jd0*hq5;9mz}|r+tc9Z+gZ-3RuDj;CH4srJ)}=|C?~klx9E}`GKzs2 zKQ`*s@Tk$!&az%@j1)6#_@jSxW}qZf(f3XV3u>ekL))5$l4Q266P&Dv*LhN*=5?JNJ$p z)f{?CreN4Qyi;>ZlWt^r7?w>pV7Lv`Her zV0?i}m5X8ud}%+tffb0V4SBHk8EDS0UCL+2X@x|Yi}}TAz-lzpo$o$ALXdP#Z{`&ovk713P>~>9>B=0wi=b=Neb)3DULj_WAhk^} zw&Bh>A1Amq8^2%MvAKRPUT5qW>U{KZJ5*0r@{3%*gL^w4u#XcG{>KA4c@@c1bK>tj z)A3xRW|E)Vu0y(YU@PN#!p@0cZ!XTKH)nb~CrG)=tLxp8&By_s!Q}X)DL&hDOt&+$ z;e29fH+ne01HGy1;3|8loe*o;A<++KvQsJ3hlBetBd2hu5@vU4fz+TZJNRMK$+r!+d=SVN7$-$n;qU)zT}C35i72J_=l4a|{r06PSdR3rnM4sO;d zI2JyQb4H5>ruj10YK#m?;Th>nO~MW*r)REYF&%_8_P0ZtBsHy={yi3W5|^lJ07sIW zQMd~$<6(Aoi9VAIzxV0;# zKT^s3uIM_1w6n)Oi3SC1d!N|Um$fCw*;FRL#H`q!E-b~S{ASbAR=Ulmo&QLjWvkPwA%q*NFVj@ubLc(e|F)w#c2VO8(x%*YLpiIg4aRM(3x;x_lVsNiseYNrrCd_v&x|M~QMYToPZ(QU$2yYnqCT@K zjusRildrt@m=*xxJqCCEnbO3B7WyV8rmB+@6A2gH?8tJ3$~?eF`VJ^crkz;)EFX{X zLLJ=>Fn)=5WdDRqcggF#5S*0Rb+@5Y0FOC}j^bB~ap~@Z-rd*Jfsl>cdbS~CV^{ya z{-^r)_CMD1EKUdRnnaq2N;~DmdHiZW3+@HWPeswkknY~@2o2yFZ%V;O9D_{_WE(V< z4zAgmo&tLe^b}ZCzNvAc;UzxdB^G3Hq&#jgaeRg&J`6YUg@@?7X^kfoF4HuDJsZ^JBCBNuFaej`mbgPAUogB~r1sp~Q2= z*6NR;4YdzYR0LbYj@)jXg3hqFJ-I$;I=k`TUMRKwcs_vp0esnsr=56u3{L|%W}X&` zr*O4N+fJq54W*cA26FNb^De`q2B2EX(8g*)iNP6do=L*ItSF7zR^UbmY;wg2LG?vq zI=RHVH*iUt+nSVb2>(kmke#JF*8wx$j$B{9C*RY#_kZmf9>@gd{j;CH`SLgZ+Bg2i zpPs;p>iDsDZHPy#Y`Bvh;d&;mQk*DZw4Wuz3u z7~-By`kP~;*?GnxK)5}tAB`!`EzT$;YE4P5F5X7SV2}AviVI~SS5qznYrxf-l%{%b_v-d8~ab`!pSb_bJR1&4pNb|b$ssW>iMT!K00;@o> z#kSZWC~?FlIRIPiA=yz=s44)}1gfAafDcV;Vb4TdFYdhyhaVAMd2`pZn25V_c;THL zH^LFNx8C?a@GKqS$M5&cljl3%S6|^l_Gq5yCQ$W#=aHEwPiCGxdGb_a%JS1UlT{6w z%Fk9~GV;^6mQ{_dg%781E4EH~xonmt__4?_X zL)8SXkO!75xG};(L1QIkoIz|)m-*E%PYzyV*2b+191>(k(=FsoH_~PZO*S|o?Z17O>*2k;2*Y5oI zCwKqkr}sX&|KQ=Du5Ud0^k ze6`tHxpp1(vJto$Mg?cN15oGr(RxM6jJQb~cupd%q6=m;d4bfw6k5o;jgB$E?Llv^ zv(H{plGGb8z0R1a9qNr{>%xs%ED=8Z07M(=S2_{K5-~CSiL}`}E<%we{NSt&KHU56DS2 z)`4UV0>qankE65tj`Q*1&dZ$dyMxZ5;)uH(r8=NP5i~}wIOV}?9If*4P%bW}tgLZLbdEqYg66n_7l15`RHfko zhH>YYcmJqiWuHa=Jeo?z*v}&yp1cvJWgQ!$nRY|?#@^^flJaYs=?tn;luEJKokk-* zdMi9m1$F2$2lmm_hp;Y^KR$XRxMO!2;70!AX&yQj^wL~7tcAnwZo**8krzAYToH}R z{Z6-k1%q)p_(mB%Ga6&fW^BdExX+26Q)M2aRrpF*eB6x5uQ2XUjM2VxQY} zT(Lh8YPgNo3qsD{(}Ab{J^vah%d8BSLN+Y`!c2`QXDvWI43GtqXH-=Zwk$RVy>~Ma zhrj5LN5Fx|DE~sdQ^4AYrLAYwXD?yPF7B{hQpSL6K%%_n{6}Gs*xkzj;*&t8TsEY| zC;^boM8krKtxtA2icIUtYh>?xy*E0{(uJ1HEE||U>|uu4C6NunC z+=CHP3}!p+4zmq7g9qy(gT@>h?|d!h{stI&ufckH3FxMGtxb(-7&|E1ov4Cu`pDVQMhF1bTQ`|XjcK$wCGWsI;f?M_ zARH-ICjV%^c&_v;d1c= zUa-c(WeV(clGsKT_rnPoLGw8vNFqgx+-NA)Ckp}w(}W-$?B0Fg9>}CAy)Ue@IF3vJ^;|pN>6f=^;J7aW{DB9uS z-X;Vhm@s6sjMK=w<#15K8V82i^Hj~>An#zZJ=o_G2CE?q=b_#8W89ToaBmfr?FB(@ z!56@0v9MN3Z!Lq4XB?rKqvF&QF>CnpQpw~XOP3MPpU>tLpBV}5XkUU|#ekv^rv)4y zXe7upk&a6a%+8Q}e!|;VEEOKT_qBBL@g7Cy=;B3yC2T=+hJ# z#(!;fhmr-+Y`& zM$S@Pcx2L?E{1whQR^XZspa8CGn+JcQzQ*dVRbc=h?Gmz)4B)88epq_4QViuc@6AcWVF!SIPVfbC860lo z!lPZrpYqZrvBD|lwQS=$Wm*)3Y~t@}f~Ov`Oj1(1N*ky1e79_#@7DA4+~l%RC6S$J zgD05nR$o(IGw<}X-CCekh)}3En(bj^!<0Y$Y!475Q@(b}*={W)Q$C#5=e-WtF^hha zdqfb9r{`y=hy zo)-r7%gfo*%Ztm{R)x)o`_*~?y0(R^6~N<$Y&tg$VJPCRxO_@-?~JwUpTe4lSdqa8 zTJ*U7kbUuM2IAcq+G4LphU!6N&bSE)L%`Dy~2xW_ItIv;SvD`!`?Ovrc~w2;MO@OU}y)WyoxXcHU}SZW}O2(dnh7s~vkrW7xc>EZq) zz81;kr@5>N#A6-qf%dj8LYiqqD&9$5yOv#H78NDs36q}c;u0TYMUasC3^(GS@&^Oo zRdUQ{2c8zwUSNBf`~fLa_b!t(skILrkVF`T{`3d26lI+Zi=7yx{Ea;RfH$i|FbWt1 zR!d83-2^u2;0j0D4xQn|;;kT4##$lb%FySRc>{U4W14*8<=_Dln=rdEHud_7HM==K zpD;{XR84?uRJ1SdJT>QV2}R#-A(qRW=3oLN07i*x?5T z24sY^Vd;~VaV#)>&F zV(#&@#9ueFa7LJmrnU~HbLVzT!NM{0!swf|Ut*<3w6jvoGAmAv;A(i|uB6*ij&#kj zu4QQ7&S9;p~3_!o}HLkZS-7wwIRxn3CvKBlcqp%Nts2j4im&;q+X#7JK1vfBJA&51#5t%7I5zjM4~JonE*k0LW~|F<`e9d?0m-|z){t3 zsRGCb9-rEMO~fFRb7;@B4xX=P0D*1`LJxNe>|cP5g+E-qL*DsN`DNhXNatV92se5y zX6znhB+u`g`q{&++$vkArwk=&E#OZgPSPTKd<`pWW)xQ1ugRXea|(%rNf%OQa%ma_ z@dU}^by$w#o;P??;9Hb}H`g~mU3d%@AMcrZ3AZizJa?mpcSzVgpPu8;A9N%Je3f*a z-*aeFlAEJE3yQ;~K#>%Y1t;bxmY|wsz2X*mHnF`s+QimiAiO<8_dMbpo+WxM8y*fk zhv-r$73jo~3x%G#DHE{38&(2`Bb&MnWT-@%CSimr=03)R^xo4@?djn2&(WHwfzJkW zkPq79zXv+-4kQYPjkwzvrU5rVYjr~#WvIBq8%}&gabJQt`7#T}$VJD5lDKS_Z0Lot zpX;F;C(>NTIph?xhpDw@?e7|P=*gj!^Bxe!dnBjTnFAAj0MbK%mpMTwLrna}Vrk!| z{>Js;Sbc=sv%THH=D0I{?fMkuCMZ&8<`KoVgmqdx{xpgr#hn~bRJ)spUfMhOrqQwq3z0bAz^GnNF4 z;hk(jo!DhJKUC!O!p=uHn5hOe&K8oN(a$M^@d#9jA}Z+!L17-+tbs%pdB(FD_j?@f z%vfmO?#a%Igkj<38jf_cz`%EGaWf#Sg2765!emQribXewti=|hFI{cnz@h6BnCqqyd2e@BR)Xd zUy2Mjo=tGsDnzjjJvOIst88D0;-=3WwcZd%4|cFVc&dyk{K@T_1BOdAfkltlf6sDeoUxUT7>V!fRrp95)dN zzjkM-&Z9G~Kro@whUg919*tjH8D45~eif@I%rV(E;XZkC4cBYXSynKr$HiB7Zr{c= zlJFq$=2d*VletNg+M&IAxAw;@g`W!&br`w2zOQk^RL_aQ+3My}8{>jL@w@(XX=V9R z?b_9qOSRTg6PvU6-PCVvoZ>T{Uu!I~NMrG;e&g-6#P;6KRaAp-t5B7vG}UD zh3}JzJ})gV;>&<<7gy}b)$3NgvDw9)wrpT&MK$d87At(A3f3H0+A1t>URROjl@1=% z)FYm-h2`t4WlvP~ntm@?`AvV>ZBD=JHbTwrvX$<6>CHxHytm|yUkgQIoo0Bj?2YiU z5x~>C>JK)(5yzt23PoC8WYHc7bK%el54_(l5D}VNvEu;jmbbcTkTkEYSgXwzacy1$ z4uEH=f1SPUu=VB87@o20fsw?EUBjc7dSpPL6vyjz{t*YDgGY_czCng!n|Su@aH-!i zsxNIdosdTMB?B4HBN7^prDe5kM8Mlfx%92Wyw!|UOI}|MSZ-ajE|<0z7ujfFn5C_2 zMoBzh%0D+y@Vw#A#gJRqY(Vis&}9u7ba;N%E0DZf*K8c{TwrD84O~2LdHK+RjT2t1 z_zP=@0{}8kVPLZc&kGoEC{(_PK^TuI47y&SfI-in7cl7i^CAYEwCXvJL70k5TaEk} zT=y|(*t4W6<$=&?;cyV^GAv$DoLTkHHiMJ_bb$d<=>h_!ty1@G+Re zz{j9~!KTx6B|iq6t}8b4W3cIhuhVsjV4`BvMV?iN!frE&`elFa)g(wZ4L=CMLN|to z2}kQ7sKBMImHc3KBc%DU=|)KVxh}gAP?aa3p@Rr%c#*FbA;J<*G>=yfDoFM^U(i*NhhWzJIYF8khP?rrR{?_}wU;!)rA9TcmUb>^U?&BeDt z)niZ!?64J~5C&1zY{l;Lqp}sd&r@P6b|0SmpxBsg`KWZ$ZW@anPRy}cca5b*63py0 zd=X@?HW%@Ljo?Y>qtS#J1h&Kz&0mz+@&}xsJN|{8;!CK_spzkkDAER@+!Ezj{6ZLZ zz0wjT5DZK8wnW^ABmc&}_x%e6#?NCdLNWGNgd%<+5dNh>ASQcWt3fc3hC0-15Re1B zRo@Mc$1nT~sfI6xSc4rnMH=kDNhos}HkDdfX7iwvRaz!>z47HZi_NNPEG?TDT3qfL zyEc|&H^Uxf_2uOiHny`LOv~jJw$?dRPk2e9jb4OrvZ7ehYRY&Tdc|u#MK-(fksyoT zi1+iXHk*EK$SyBmCj7AMiy{4$08i1mBz;H@p5whQ^LjczIdo#dCf& zsAX2{Wv>b2cJ`G(9>lL5aYlr>Lr9)ST6G8sjw%Q8bO_3J{3^M<587G3S`7`Il$q@A z#z#bYFMcCqJkM$qknE)>@-piL*>F=U2@fVb5nl#3)^ zCgnhKa2_ja+Qe@pT+oGhd6nEBNq&`-Gu6m|^IuMo#b@fG5jF}XZmk;zwxV`TCb;utBuLL4(DUm=c>O$W+IKRlT?w$T04S_VH~vrjNGYpUnG^(Y-B)bSy00(601lKDcMMl4*QSz zci4Z%a&qrQ0&J4WBg<(K7V+28D`Pon?nnSB?#OcT0!IAh0nAuVE0ahLtwbU@yZH>%Sq#9EZ57))gDO|Sx)LNvYgak#&SJUF0!0lvysMqGI^wN zKQC9c6pAF*(kHT?|rgTRnm2^iWm6Qb-FjSPbh?JAI@QK`%wupq2vH;<{Vk+gD68e!G68g?Z&8tCl zdBq^RBv+ePQ_VZlSQL*< zDV9ibDV8{`rB@=wrB|XxZc4F4l1s5fww7Lr6qjC!8o8+zVI;YHc#*9)Q}Ni`%!@}U zmPm3bmdNDNE0N;TD;bkZu|$$fu|y`9UWpW!UdfnTiY1a6MJhrC1`# zrC1`9ORq$VORr>1F2xc_F2xd=TzVx^TzVyAaw(Qbaw(R`yd^CYnY<-6<0NlsrQ=NA(n`lE-jWK6Ox}_Xa+0^Cf}F`)iIZ!o*OCf~Ox}_X za+0^Cf}F`)QbA5}><*_)-jYUglDDLhoXJ~KNKWyV6jEgJmNb%+yd{m~Ox}`0a*DT> za%N|1DV5!=rBrse3at4MNbD`)bSv{j_I{9TdBTT)(;$mH0;$FN3{H&a6wTmE?GVx`sOYA#ChmiAO5$(!Vk$mCLik>XN;8Iwx~ zMv_YhMkbdEj1-p&%$Qs{Fp^w4FfzGTI+5a1ffN+(iWDlkg&mULhw zxpZJ;a;d;bajC$J$)y7$$)y7$lS>6gic1AXN#2q#Gm=~z?=Hz(*HTH|x|WmVEvYiN zcd#`RR8~v+OphAz5yh4sEyqWcU3zrY?Shuno1QgeF-}H3YQ;yKkb1NdA8}Ud(Y4rE zjFj+Qg_>Mj07bZ zjD?Va*phy91i~YySqSEU5S7n{m*k1%)OMFf`+iQi%FsMXs|{3S%B4uvltfBjWo-)!Qz-_J75{jwj!TJnr(6R3bIJEEvFg1=OW{Z zw7g0I3ZvPIbfgI62&_m^>XA?M6)8(Sa`;!IG4&`i?TYlKo;d<5Ql5I`6MaQ{P zuQaF(^eED7MVnK477=JrE$ER?^pyrza(d)rzS4+%7AN{j!)X==eWl?v2vuV`e>EYeISfgZ)7ivdb;qOUX~%`oNxvSy@NRx{GfnRcZaX%^vcI?XmC z)2=k*+>8h`U7m5G*Z?%0W^tmgG@WLfaiXuZXk`$mDBV|DJ~u;z-%@X-w{DAG($VLi%dCZB9CMiudX!D{Ec`G|^bqa@GRBD>BAxIkj(Lc2!lR67LwpmSMFc`< z6COpT4N*;a6yXo?On8*h?0V$0h=2n6hyVxOSmS!+vpCU1JReGB6J1VW)pU)%ay{}{ zoak~Et5h6wd5lG~sL@wKj8Zz$LwJ%QV338#B$SFY3o%J}l+i52BjH)3SqMeKqe!z5 zg@i|uW+DCvk20D?`z(|0nH51We(4d%2#XFO$D7N!kmE6eV>i=a*#+F0$MY{%3Sqd6 zFGgT8PQO@k6CS9EG05Q{eF(>8EOVOq*^frWz8m$9$2#LUkIvd;V0A)gn|P6iLE9w) zyr^&f{+*w$&f}=rt`}t^hx7B6HS=j6%bg2~8%NMMgM&X0RTwILbnBbmIZllrGsd^j+ z!Jvg$bH&BzY8Rmlm5<>gbj*{H&y3kA2=J2)Xi3L~sQqq1*qn%aS4X8Y;pz#= z%ySO6OV2rg(j^BWrYM?8zvMgwa4kOzk)Kn|9FQlZ@+9EfZ6(Jl{78f|HOLp^pLhsciMDzts_p|`uzI*rTJU;>?mjf`CeYOl<-qotCSh{z*E^_u+dN7Y5q6g z`kyZSKe()j|9F`ZPIw)54{#7nXQuDO>vnL8G2AYIbA|^mnKU5W(i6_%@tD;rj}f9e z&(Vdqc4Ew~>%s9x9f#cEF+-mI(s3%B{X+f*oNVO*Lq7FZ?C6%x{NaQZ4twF~UO1M?q>IyxcIs`ngNufgO480~+3_-O%FmQ#2N>-bX=s!u$wBp=G70iDInJPC#`JMc zmia=Yosf)Rd&mR0RQo@=fh#`_21uWf7W-qEAfZsq#zFhy=2YneB#KkZNfi|Q;SHP! zW%};R%>U70f|VI1Ke|!d9Bdz3?2m9%j>o1!zmLeCI97*qVtYsmOkyivMZ{Yf9(BsD zgCvl`S?9j(z$9+C=^pI9{t(AYkrOLyF`-U>GE5A-P`NU@|77 zYki0#oKW!>K7<8D2tKTB-e5Kv@CFJ0VeR7^IP0H0Km$8BkojkP@L}yI*}L#$a06)y zKCIo%Uhq5W?B3uZ_z!FMvN!f%>xMG8epu_>=#6mw5)%|}Fi#JRPu|ussnrcF(#TN~ zE|FG~aQt0n>*R(pd9B_VkCEO8r{swj5Zou;6I>h>*tUj5I0rjM7a_|`Eos-ay3RRw zULbR_&g?@J1V%GfRfi96fcU_Y$zCllr%txQ5=WjLgn0);~m_FpkuI6 zTo?k#-h=v129(0k>f;o%-BCe9!ygLBr zVe4Ca2fj|hab%JdnaOWpIQ2RJj}hn1J40|FeqdZMCxEqjp@!s3vBzZjV6PXtNZdMR zW)Rk-ackhJUwdc;p8^nO5h&!eBR%^Y3W7T{-0{jU!RyLf4{%Qa98V4w$ zkQGnH!72pRH(DS*jz11xKPT?f_Y_zqCxIR0hgM^fbk6ml$zCj7s=dI9VPSze~%_#B2|Yqgdr>A$~=*+i>Jo1H;_C9!u=m3y^XvHA436U zYlOdkG5X>E@n7EiAAk1kN`?P;?`u#2`>(ry^S5WKe|zqKz1_uA{k((UKf=GsbNs@M zy-#$R^b=hf-Fv6<{7hx{oywDUD!cDip1g}YeevhL$_~om(%|nt>9i}zQUct`25YvU(HpXe5=y?7A^)>B8&h0T>$vTYnHEI$)aQvU(Jf8 zDq}q+TzQN2%BhwsCta;`^k_Wj;bE7TZ?g#Ntm5C~L;O0x|GKRH;7sL<_bQ`rSLX12pv&LqhPb637hiv= zyXk*9SNU>|h4J-=__R@HgZJyaR{MZ$!YEMhW^o_T(G%Apf<;RY-CS*;vJ$kQF6y3S zms9KR^X`pj`?{dH(Oi0l3|7ygKCm0I!+Pi(n$TtDl{4SNoz%QrJK{;egy#xAy#6*( z1?ay6JRT4Ku<|at{i0eKeXlZyA7CG`9O4rB&wwC^U^q@tv!Zo|TlMtUoMK_~2J0GC zsYBIN)=4HI?Ms&Ruk#7tX$8hHUFWcikfYNP(v689ur=!4%6spCkhs{~2+7V#$RFe1 zogTw_*bN<)AMV1Cz`I}LqgMckEH3lfu`>UntlnkeW&to&NyZN0~!-S z9-e+xrFw6@sQOBWg9F3iuvHM*(8h#Bge@s)W2W&stj5YIhv++~atr@#h~AHE?=mvV zkGEp`zjR4C`D^qg^1SV;%tq=oi?XkDR48h~Dk@Hsb@KBm>Hq7f@(KPG=s&=tN|!Bj z>ajCUk;#wnE14(n963+k3G?KgY@YmOoFxAdEfvS%O_y?N=PO#teWim$X_c;QrAbK4 z^|*=45A^ywJ6J7HTtgqQhnxBt=a;`8MD`1StW`)7Xh41a&)>)-e${`=N9 zzLl*$8~?>$wf_Bo|9}0@k1#>`PpiDcO=S1Om8=t`E5yBi;VbR{LB`bZ1x_c+$c{^Q zCcHtcU%Pwd0lk;~&K?}6O6PfpNjBk$hL78Pm(1te+2lr&vJV@u%mv)9JzRTOTW&Br zp{goNqP_Q932eP0cW}5CUJ!(hu*L#hir!G;`jR)aii_2CK}fCMy-;f`E-qijuO_w! zY7cRl<+yeWFmrS5haLOyqutjN+~YQ0*c}`$O#0Z@5kU8F+2t^7usz(k1K$buuWFsz zDx6Bn`3YQaZIAnX?qRWWd2@FT4)$+cx$^SmOAzy5XEaKfMME>}wzl{Za zf^CefuDuCApRL}VV!NHuOLGZEMs^~F4L9FIb$|iq1YXxt5Pg%*GH!Z$Say82`l%9n z)22v<&{{cLy*c|QKXP!=DHkj6^6KKgPF%c)!Gy#7Au$(m?6JOMe~c+OA<$_Y-$YW# z{;PiXP!3_c*W280+#lc%Ha`c$aN##TW4yC381=F$*tlbx?Jcj@-9--4_Ev9lQ^7Tu zf;;`)-S8#fUH4@#wBH}T2%oT3&xD~l8*6Djqz=3Q zeK4$jdjIZc*bv}eXF~35Py7aU&j19bBKKRBFWET8nCNU(iI6d^*vE_g`UTE?M~!`V zcLoR{2zY}GDG?oSBqRlvfZHgDQnx7nDaBs$x)ufwaFDpYgSj0G8r+&0D$Q)JqFA^A z03@vQ?KIWx-iL$tv2R4Vg-C!Z$$j3k`-)KM< z@yje@PD72lLgsKkjiD06Py~WvQ#UyFdLiL8;ObLPmXRteq|uGTZ)ySfKSnGCB)VPw zqp2UHgT{4LRDWm!e#Y2BW*WD9YHY|8<{{SAJ2r|G=jF(grU7nJbBGztQ3fHM>1e#kpCb$K+yOFFn%l+Gw7JO53>m>R*A|yukt|+u0;^RG z7s4<=&Ccr^x&bKHEBFE0$s!(LhveJMCLAL<&Q`}TpTIvhjsRwrS0fw@_UxMFAX~v! zTXuuTCEW61Wfcgr*Y9YnGd#ntCSq^)M|Rtc3l=bsR4pX+VE5oM1O}x!M#`1njoKm- zE+acStPC^Hk!cwhj@mQgjLD}BK0YU7NuMGRf%()CHKPqhZvu4gP$_UfaI|%{TG#D3 zuLcM_>F>VA+-GiZY79-`VSn2qZvv{J6+jH;675|VLpgO0cd@&P^xz2hJ)9h3{9cFh zTZjDYK%(VGm@lD501rbUG}txg>|(8+p=)zp8VWi^%1OotK0-BxDQy|+gW!ttYH}VG zFylI7q-~ce!xroT6S~8w2~CA(X5lC$Hxj`2F#eZd*KkIYn7h2|^k;}X!o7T*-9s`5 zEZT>6A0j`q;wQl16nd&}+x+`59}%q*$HPn^M3dm&i>WG>>E28$MtO5~pmFFCkC)N_ zbudMcke+r}u+)N-&UBk}qVD>8Ox0j_Fd!TVp&%Xu7X*&7`hRFMiJ~4^+Ees>b^`{O zX^>RCa1-qg7;hiw!@`BQk8)}k8TP}#1jV-T==Ot8A319jP{DkqHq<~WnoOZ2oWH7$50B8XTY_OgF+$8Ess}7Q2TK zZn!YRm4ycL4>Z;%V(Ot3i?84%1s1kBZ`9rRz});$C&$;QSt&@#=# zg?m^@?%`H|kjY;nd8>B*nGPVcvrmVESHPind9-y|N=teZie-c-#PiR_I5xs!pLDw9 z@d<<2pjY)Cmg?Cmim)*i3hF;8!r2I}f)R^GAf^GSf~PR`F$Ea>X>$s;78n+*WGurG zg@zVsbF$;GiVju*+Pja7f~ZR|?BS+CQjazo8p-14w!9`@N}YiTAbTS1IWod`f=e8D z?*(l;#Zggr@B-^wxOBqs@+ANQRcuKuvz*YC3>8c;j2R{;XG;(!M2i z;Qg8kso09H8nud@N#tyB+=7rEf>vB zBwVNgwmanQ3a|qq`4F7e2}=>;%qUV2la`(U!*zDp&N_H4F~L6_(p6VC1qNXv8*rkilU-FZO=B*#%?I&?@o^v5bl5s%XbZa#SVlDLqYll)ahLSu5*2jI%wH*9R`HlycEs<& z1ojK0;Jc~S)?Rhkt#D#X=tg}gh-A0^bbfb&GfnfCcjtLV33%`H;cfrB!yX_(kOEpG z0Pb&L053v9Ut%Wm)=Rz{25Mk+if`kW1I%Sz^0yMxZlJZR%( zx4(%^9msLBnK3=%k_iIe10`cY7(C!{80zRU+?0Z0G{X;Qf;DHwrQA)9fDIBN$o4U_31nj(T6PBcp1j4|Qg8`3>#*Dd+t zi-5b#2SsI6;xe0Exr8-_2Blp|OZ?7OuWSy6SD@}$&OAYy(v;g;0GjO&R%OV$-75)X zhTYvmh0DrHgL|@nfUxSU0Il#zXA5f=vUsMkqF;x05*)UqBBIem@?Z%SypwdIa`A); z!Mt#3D|e(z77R0;%w(5vOP2)iKAw8O^(qA{M>q$BEuW+D1mxGlkYqB+gkN4cyo93h zmNTW}ZY$a7Tq=0OrR`=jRfI^*1T7ooY7F7xcNvZj`Wrt6)B6T|{IEW>hCy$#N7NGz zV`K{(Gc5xW(OAK)R9>50y@qSD){1M z&H!>VC?Fbz`GsWYN1jo$@-bN9G)dA}sA%{^X(S3#&!$wo5Y(Bh=R-^cUXDjQ+n0;k zO}cJw#zRXWA;{ql1h7093wudiY2tv3-3n(O3BS$W7>^uAs6>BvE$l*YfKa%f5z}^$ z3tGWT>Sc@@84Tb;a9Nn4Te@Or4X`18*Lu;DjO2jW90QvBu|ZL>kFyb9CzDbN*P>mVXG7Z7*p$}Yd2nk!a^D|?d z6q-yffEtLUnS(lY=zHBw-tf_T1?Mt_9gp>;fB16yp);$Wy9#^ggJm{ zYySKY3;E1)iI#Qo1AHBFjo$q8z1MKp*Y;jRX8t*?0qlT>Id;=@KNe3a!}XJj&GUkK z+d!nCxv-E^0=U1v2&RE2U#5Api_paH-uKNv@9p&`+qExi*kj+X?esbh+x`-cI?03q zTq;xq2cDruQicr>bhHslVi$COX~8haW8&ST`hMeBwBklJEt7~s`hjZ^o;=G+22vvL z0p4UD!)F-(?fVZN-@5zAi7xtrZvvCD>MpKk zo-BAlkVH}@5dn}FoKOY!RU1Ari&e_-`(%$ zJD37AM`euk@I|5LsTv}(O5Xg7`G>b2{RA0J=C2%1#-zdgF9T#bUfJhb@M5X-qL{(v zlZHdZ>VOEBJHv@}Q&%8`9YcpIls2-cXeP551z}Mt;cs5-23btX9nt4Y_)*@vPso1L zS(xyHp^a5trWDRL;|b!UC;<2cTJS=GKC(nO{?l+o*?lbHnfURD95dFfLjeaEVwg>k z_(y{X(I0@<2LfJ#8G24}gGW944%wIDii|S9GF$;UdOs23Da1gs41;M>T&jsE#IS@Y z841u}8=DIp`2sbN6z5k>4c|~b1tS!IpC-iA{MW2j9No042o^+eV%I=`YzYSgz^bOE zIG4O0@M^1AGR)k7%k=H8mC<^3Squ ziRq&~xmw$VHA)?iedy8nIoOZeYaXv`g#dD}u;@;Ze!nw;$N-jL=w3=fk6J|rgyXA&uSPCoFQC!Z>z}aKd;S9iR@p<~ z61PiId_U;T*FFFv5FYdaVVQ?4h%U^f$T(qr6Ziw_px@!fhJhWP?oD2F$HDoBy2vtj zuJ*&rmoY*NGrm=n^_n&4bs7a?f7L z@1h1f`vcE$^W*-(#zF5VP-VLq3h3qb-TMzeeboNRt^2p{tz9bQ?TZ33eqas6Mx|Bw zXl;G{!Fp)qcnDT4_U56n?4{amc-Ix+;Be)$2gc6h2Vn7uj*8rY+_;a($4fOl`Wa%e zG3(0u$M&RC;P$5v@7-O!^=PfVaqE+{_N~>`wT%ss;&J;YcWmD>ZVb{prRU=x(D1=#L{9TT5#G z|ckkbR@c2?~b$yMrxWD$ez53w(#)EsMB*4K3_!a_M+_Abd8gGEpcl!^tQ-7%j ztnS{w`v@$=^=TsO}VhMCRu`SA6O9Otk-Mu%a^@d?@rt`5-^9T!Q$Ou4UbT37&4B8CtF>3esg8^2i@npa+kh~ z23;Cd$@~jW!JOqMS{V8p<3;#wS_RF^>6tmIkO=F}ZJps3~&tj&8B=Vsq>A@mBG(%{u6qDirX8#=-1gWsO4|@H=vmX79^l}xpUaz zfui8{!VaUYAkJXZArQ)x4&Eqko}mDUvlRyj2kw2t)bM8fFEW(T1&U4gJ?<-@6}UgK za-pNJvr9Gh8rqToQxA?pPPUSUxI0h6%lf-nyNppVZo?2rJ!Vkn7k~28O_b+WWHOqeJ%~xak(u5A!~256K&G6_ZNBXXB#TCD}p%o0p; z$F+t-gpghK2HCuCVNIi>UK1FiNJEOW;#zSk-)D_`ju!8<*WpUsBQ!W{jH5wp7{l=> zDX|?(8z`=sxzO3h$qmU=Snmm>5v&j?hZeX!Iv8U1-BO=;62Jhb&?Br%xl6yGT0j7e#Bftpwj_$E}f$p`413EoLE1A28XL!+R zXTbAB`R2sR`2h}i#L1LGA&7K%@r~?-uuM#U_S`HF7y{+Z!cY)YIpmtG-ZLRYQ7aN6cGr$s-%G#S6zGu%w$FxMU zgi0TugFZ#X@h-h9iI>ES09%8pgu*NnFyR4|VXq#*pGKHP?d6H!C)Kk?jOVlTbs1?D z=ZnKP35jO`JOj|I7gRikMUO(VFro<;2Q%XQ`GqeKzYRl!lTY}$Khum`i^p|iqQoPJ zX@!^~cgi1o+MgtcdW3f^9HGZ&y6I^?Y4;V&W&4uRKy~;F8iua#H#+yPM&9D^zv^T8 zI6gQo1At267eu*vnJ|J=OSx#4v2;7GY*Pl4+p=wYqqZuf*EEsRtV;gC5_|vy2EbvF zSdUvOSfXMNiaEY7`1r8~f6U-~1V5wJ~n06bwm2j;}YE!0(tgRdA9l9=SB_X56KCB)$UNk!iZ%azbM zR}H-LRf3q2QZq`z2NQ|Zn|=jZH1i!qQ~5g!R4QrEq-^q@$}Cs zBT&+kwmm;xu%;Jj$^AxGiNjGA?=%AV`w=91gB+7x^Da6$y>OI23!A^7eK&9=lVzDy{yiFYEi8nHwtQqo`9hsu!wY56kd8kboq(~eD z0i0*Zb6MSZRDZY)8zuv{9)=6CD`7yh<(S5YV*zJH7^w7R7$}5+g@Iu}glV|#{y{sC ziw83p>|~?v_CU_;vN|E^!n9-EY!G|K6WM?-S_%NiH9C#yZ#(y1(iVM)J^$hm&UI%7 zaHS5f&{-XZ>qhO*Mu!=DU^<%b#&`H*RfY!8!L0^{XlTJBc(N_gv>j}sj&&wWdcd2J zDNuyL;@Nph-tj(H>l_}8cwEuqFl;<#54UUQmX;bJ79NFx~&G`e%WyVwOpM;LCg^H98`Z*QomVY9Bmjk&G^cb*jQP`spT zZ^*mOjfK-B(R&0bXA=OutsZ^0k+?{U@RHY!1_L?il-7=^szQr+F)cs}WzwF_l!a*5@5!Zv4O6R1~!^t9NZ6>wdKO=$J4usNd5JT@-Xv`$4dk2$=faTS7C zcqlJj5$TZLO`X-l?w%s0;5|a73+^7^cQWWRicS{{>uZ)LP{xV2e1;FaB+vzP=DaiY zmRs}{2IL%NR&UUw7YVA9o+IRM;8|14b|i5}C%-BDAhi--1o_0k%jO5IN^D9(-cdAK z&2SoQlX*J0nc_qTeFhDSA`Q3ITeP!0X$nAovW?NY(oj8 zK7xWl#1yk$U8+6r<800$H$b_CYzJK7XQMZsc+k8W6n$*IyBj=>1P#NU4ji{dFt3%r zgRgl28rHWR&rQY%EBm`|d`vf^kC{Loh=&<);-k7*8?LdyBJnU@ut-mETsLbcY-gYu zhLLe~z!oE;gl?V!GgTPZQvcN2#>85_0?LiY9szmN&0 zY(Iw)w*RHatrDiwJsK(1Q@aot_`4 zx1Ol#lD2?&d0R#iZwuc_+tPdAn)eR)H^}QEd$|Beil_;16_U;2;4HoK7uSVR`NfsQw z^v+gv84jdY&cVqC97L|}a;9Hkf>iS35yvt-DuBj@e5lC%mt;QA`Yj30D*iKtSul{T zfjk1y48sRah9k-XU|ag)Ls{8;%SB3*;1~c!mxvwQ@IcQxLp0Mk&%&%j!(I{OJHm{& zXdkBv|Jo$WjSs|~4H$N_xOAEgX66q7z^h#T_8&sLO1Rm{&$KIk#x|Ieg@`qgRZs3_ zB-BqlL0$zIIZ6HFf>kaG3fAx<0K@`z7iiA6N0TjEvnGZ;Po#P${3{Y9j&vbUEg$cL zOiMeVV?UgzSvRUY)j3lV{P6Po>b&6w{)5VSr|=G*88~C+m0? z-zK$ZFs_%F!MR84lSF1uac&w9U!V&ZH`aVp#!UbVjLRpp6x#ZaYG+q-0Gj4>plyNanQGn=LsA-8*!F%UeALG1eDiPYKGjj$c?ai72C{h^duVMzAtm9cT zAgMiL26&078Q|7Z5dN8}p5c-PnT^Gq-ZRRf!#pdh=WK9fyiREtLeFH?+#E?=FjP~p z7}xFIVnmSnNfO3(S@9%9Fwt34W@f;*a1^DEnVmnaQb!i#&~OHHsx1qjOB-OK+!^#K zR4+ZPQbsadwa{z7y#7j|qjFf4(CH2erB;1sb28e6Lzk!ixi1bIj3bD;_XSar$TO%oOW0BQ?yLdiBtMi-0Il$X761`^Lc1gSbadVq z;chq@pcoU(f~~=;>6RSKb3pD2VQw5F{yDn^g!SV(=bEEHzD z15U#=8#0L?+ZF7GokEj8U&(&qn{OAs3?iN&igC^@3W4JXur9 z7x>UZs;YW&T>>{w5dd;QVkh5IVB2JgWdot}jtd(Kj&oZW|$@GN*BK@ zzs@v>K%MF{9At&-7`KKmzPh$(KldQgrt7dD{3S_>P25Sm%Z$7 zUcvQgOG`_O&Bbe17Z)3dch?nXA*!tqA|IY!dA@lC@tXrgTTZU9>nqom>iips59HYl^ zj6WPJP21q-bJ*(QF?3!iH`-HLF5FwepgO2wFa)-MHtZe-3y{c;+T>a~hh4_b?r0m? znh@pzB^;!EN1Kh%@<@g1*Do-U;c(V45*8dweD&(pyo}aPZ3j*{>{ensZfqCTgxmOL zG7se2<^X3naL3FRBUIqz(OqmnWtEwxu>fB^81MdI6})({--DRB{m$LbK3ThwgivAXAn{FE6EPNp zCJ;E&)KMFgxQz!i>Tu;eCiP%%chKPlMMxG?)(&q@DpK$%kr?-P%0QcKk!goZ|erzXCA~6`_+V#b&^1^a6o}um`WUF#NG?3nMTW zACs7aztBsu4LGG4=WN^bXoi=PaGXF`4Hl%oj~1AS?z*y8R9(q%XrXJ{+CpA4yu1~r zlR^9l04jlI9edPw;D>-Rg*pK$43bSp2iBi&wH)IZw&>?jd zkiqhKa+YK!ayoH|!I+Ay>JbY$6n;FN@x<~3g#cu3R?@tFoTff0p*Z_5cC4-1LYkLc z;{{=EFc+I4#WVCtb44q#vl0>$A30m{BxZDuQ}|a%VC-2!jvY^9Pcc&<$gh&9ZThZp zVWcuWg|NUaWKu<#CoU)~Qre#S;mfU^5LzPPn;)!PT!>8+iw-F;k#A9&$KYI;16f<5 zMH=P1*R?mE6)Zx+gcDaNfV$#c@qhFyoo#<*!_m?S2Qq;a@qj8EhV$KY0@eU z0WV}>j*8-eYl2~M3P&sDPzW9fl~x*i9|Qiib^!1(1A*!+q;~Kjq{B~JN*4?`v8sy& zv60F&<;WI-Om?~tMsc(>MsS%Lts`y86p3TeE3nR0!i|5dsu7T>#X6l^I@k%Y2Do_7 zFQO_o#Ee^dOhk-q! zX_Sz*Vg>)vw3KyG=rvd-vtl6&+u=#TVmQ0%moH`1PReLg1}Y^x@&&LZ+)5696;P&8 z`420oacVCH6D)I`WCS41VWv~LX8Qq0l*M>iS$r_lJ>PD=Ws?C}Xk~$H?EJ`xzu5sN zW%$uS&FH=Y*OWwJa72#{pQ8jQxDE>(M)>)2s*odJfl1&&^LR{Lnf(;y@Qel4Y~snX zI#rz6$*G67XOhpCd?wFPGS3iS1p%kJIEI82LQrL=CL!z1X27zEa1;q$&Heqv6j|?I z{a7SYz`B?@7B0J|ChiP-eM%_JC^t0@QYRUv66-M1k;-C3zjd1#0DNJU%M;9*T<#E0 ztAeqWCUfD=?e^-u2Wy|Lt!ACEiQo&p<(KrX(GyxC_zI0GyCm!T53ZbweW}O#7DROD zyZz&}M|W-)1f9K`F1x|9*la_CU(&r4$xucryr1;jTfIr35xk2-d5*VTQ(GNlY)UhIC3_ zQ^9bv-!xr#K)!$%UxvEjuAIq^ayfSA{Z^ZlxmX-6WgBKkXriRhP4!W_6yk2StaP}8 zlwvThLs;MURBh|QoNrj4Sel2toMOUPE|SLB;$Si>+mzcHgnV%}i?A|MD*79>MZ1Qs z*hbiNLAYVKrjD0KSQa%h39ewy*T6H{X!6+TgpR(sB{@TZYC+JR65`&LYEKQID%my# znuW}IUNj7?+2i*^$O>G-sIl_QF=2Njk1Gd%whTiRirO$X*!j>l0QMSYY%2l^=uY8U z!jtTaKT$Gz*%ATCa%e4R*poCCiq38eL&0UiN!kiUXS5aJ_rYbeQ)5dE_=D3rhx<63 zGs%3-(?h_5M!e%eM0jr_i;pS>hqERA81YUp6l%`xRm_nYNTWTVd(!s2=%pId-j(AU znG17`^ntVelepQ1@KS6~;*_>@s5~LOGJaM|TL`E?_zcQne{+OPUW(hnX7I3wOr&bP zylO^txh;I*Lmv%{hx+2BGK0Y=oM+^~1O6)gn+%0Iabjy*ioHa8bLm9AdHv%@O5OQb zOn2uEagbw@xFq+vAwV6olwNq975 z9D|q2HGITgprgSFzJo~aI;zZMUvf@Nlyd~kI26D8x}Ft1szJm?9HD#@@Tf;|on5Am zkBp6)VP8zO*Pm)oIekhYKGK54%Qhn>P#vFi?Jbf$ZF0e_5b-Wf&TZk0T{$x#B&dVj z1N4u=is<&498#PNk0P$tX0SOo>F_!;0A?NeBaVbY4q5ac8>F^HnwxfP0=NgD%b{{= z9rKs17{YJW%)#ai;>7mBqP)~DA_U|-AtlQQ;Tdg!zcpLxxw*q&D&C~9&^z4QpNJen zgqtSQxP)B%-0WA1HiV8rS|h3iNkB$p=DWZck@uPO0VW#608{7}d@UsAIaFcj3j}^& zS14mxm^SDoV<(^oY*k*c(O3~^VEAx}e52W%g3)ua*5&SdMdu+%>@^nj4j5D$VUyf_Z%a>3l?tIG}$2jSdWrh$j7fQePVRkZv0YKat z0880*PI-EUlr8|D;6#4n7nl-@SFbf!S{E?FYhIn{^mKbW*<-2p$;bKjA|0GF+0ryE z)GZPu&d-+*3LW#Xgl)GJAIi^B+XRZ3VFHB-usgzK7j<@0=$ag2AyI|8oFN$|TCQ7| zju;en2yV&^&I)X86_qXc1c*PrduQYBkMG~Qw{{!52UCUExAdRQhmaTXGAlk>TmJ-A zRV#yn735d8w%0zx#WbgAnYCC4LHmzB-6(B)#))j)5W`DMbN&ugI$Ypx&Hu{9{sq4IZ0WHF9yUy z*@hKi$s}Px{+LBo!mD7w=|Qu(LJ%-NOFf2c698lZPRH!5vOIsLIXi124@Yp)7Aj1$ zhc@R}syN%=_K5<}IL#y1XjS|@g#H{i;$=&`laJd;>2=cR8%kvQIUp{JK`~O3Gv2}V zuKk{`G-#(ZxZ+&x&h8tR$`n`N^!yIG4^q(51`;G8a02OM4mqg4WpkA4vllrA*IZsVXAIVI@_lH?Tq zpmcdZco8@EL*rJ4WSc=MRlZjS~8Nl3@Ex{5pQ9CUhxn51i=tXfyg0c zy7IPA3~bZqY`BDp0-*D7kvs_%jH%ReNyjXV14%nzM(YM@l>st6WmIFJElg$dGB;`| zaoM-dK1_FNZH42zg0Tkw6nL9yYT6%vdI#5}9KgZKI1$d+@nG_NRx6rFm>QT~<~WDt zgBX)Z))vlgHJ5M&7JDuJsGl}Lz)b@nB-D!FF|#eq7$C%KEFN8G;ZNM!MNo4X)=TW7 zEVPRqrUh$1z$Oooi=CDO=Cje+21o#k5P3CYc-WUu9qgFf)=vqmvK)VeDY*ldv+hL8 zDj&xy92M}3BL8PVQ?SduZPbjLpR~^#S7$&73Rn{}Y;40J!pi?UCRBF3mZ0}PWN zE^C58K0Rj1JfawQGuoi$-wkcp@Eg+xm1on2Er*KsmjT^||s=Jd9vDVw{!3Z-$8&i+!CVKf=FP+fqa+8BE@Qv(SKo2V1Z zD--kwF8clHJMUI2{Q2t_qaXg?mH+lX{Kwao3jci@&oa5Tu>ZRIH-CG!x_JNlce*N% zU*E;QAK~BRf0?UPdX>r({GO}y&QzYyRi4aM`g4`RnM&`S$`@xUPu}rY?^d3?>!07N zJbBMQzh8Osex>(rrT?|c78-f4@>iA0UsfuA_T=l8{yUY?y~H>zZ$GYFD^uD1-)%fUaWw;dE`gY~Xx4o_JRGxgtKmS_g$*=k6?^d3C zx6=D&rH97OR(dFpV((VA0r0O^UVpFBf44IDUZwYImA?em->*C#o~_Ky&Gk_2`<3Bb z<+Im7;5RCBkB5I)dAI+Yl`pE5(f3$luJ`MeC%;kYeXsK5w<^OkmATKhLBijz^uAA6 zpZpH{fAX&?z2B%j`Q1wIH}&xMD!t#*hu^RCep?^@fS~pNP&E4;J`v4omEOP7>p!aW zepesnEB$ko-tTcNM!#Q~BT2uBKl3aSf zx?|}-7+1B_y<)QBiu8@*bx@RBMx#wXosCOBgHw>32zEaX4DvnoidJ~I0qc!wm9~PCOz0CqzsOJfJn($6sy~f|i`9@*WrB~@ zyVw%umMpbpM>#EcV4Yr#Y(j-zb&MT*jd0y*pV0wD;Yq(*3Yk~2+-IA8kanSppHH>D zRoYAS=Io!`K)Kh0=jrXJKXZcsH0fth!ycNpW@KKx660pcoqsuBiAiTW6%k~7{DL92 z+x~Jj62r|(#=wf3y8h19gMG5qr)2_aeymiU*K&Kc72wZ!nmdic1EHZ%b|zpjtiXHjutzPyA@QQ zpg>AL$GK{R4A`O2tw2@4g{U07rKrj7Zgw&VYIb78sD_)VmAgR1tMlbFy)Vo_oz{nL z5D<_MFWKmFThCJHSRAKI0S7dPHLj-KMp{M!Mv?-dyIY31wHe^QRArH5taCjuhZQqE zMF!(%Tryhg^m_2^kA_%{5Xnikj7V7-fe;6MVyK7g7&ioDGMto7$gCr3KMYxE%7@h1 z*pKo-Nb>$)B^|QippY)do6#@v@7*C9i9@|CgGpHfN5EEU(fe>dtCNo*Y8;!&R-kqZ0 znNS+6fC*s5k*A|t2j=6^s{zyAoKuj}ELQCP9St{DOuzhH#M-CUg1usCIh3e068BNbXh8%&T zgIg7(Iiw?4nuDt9*`0&6dWSJA8VFf5xQrEh2vapIY|IQKYD-QBv<()wtrhYQMy6Bc zEwl=L4oqXBIMZDrR}Jbv=J{IFyjVi}^=ptZCR;{bq?7tkgQzwTRGp&ka~TjQwLB-v z7g*$}2w=dJw}?AU z%>-av%&wV?Rx!3<8Az$j0wGgTeWEh1R03~GX*$uBhbWwOcDZYY6NW6KklVa9-KZB_ zU7Q3q2I#^$(7KQI4tqa<8p7~GniV*NwHVS=V;W*HWW#9>a}7c7(W{nq1qSD(HEcKO z5;Dm2LhOz;T>tcJFq+#!2|T9F=|5n zV^W)tm_eTqWa@FS5TXYZ3);6M$Jm8qwAoDFI0@W4iVC0@Q5Hq^7 zg6M9etR!Y&lQ91!NidzO6uiIytc072a3#0u$VkRXdBL^Ufg}S~9-V=~Vb)@0VLJb8 zc;3|ir^CT3fZw}3+QLN;G{&hAadc}01#$k_7~T#-^hpPY-4EdAN#0}Yw~7*MN@apl zPfBp!fsHK562vgC4o9wMT%85?AeJ3Ss-z_ltXhmd;|72aVI!#Q){<e4s z!8cnl$(Z8_A8Bz_J1;r|n=Ih2P!aE>sxb19Fp=yW5g{8AHP&dT(Oo5zQ&3NkB!Ce3 zDSRXpgrN;<7pGv9GpcNmE}8T%jFp1O5BDKGI6(}toP!&>3Vy#Hc;gXzOx6WzD7Pv| z)wfR$o_#ZBCKiW7@W`&5qD4E(wKNb!N3XTKvpGkgpc24rhw#95CRJ{cb#M%@8_}g- z2xO!mPhi0jIKnpcYl*TzDHl5n)w(kShvov-G5JM0!dm0>!S$Yyp5ucqnA{s_U2tB4CR@S(bDJ#fo3Zk6fgBk1j0&qmC=G!E|hV7t>5P~S&p3d)1bjEBK zE@$A&^i}P@Gpqp(^b7zMC<+u5FfW0^FZyGtDr}G|Cl*$dC^&vOz?@akq3Wz+K>EFh zCdk%w2+U|R{UTf^V*=N1XAK<(imU6Ov3>=VPiR}9`dW;#t>PZ%@Kep68vY^go9oXY z%;A#AG>5F6kg*hoH6#Ht0@<_-+KbCvNJGfvasRT&8k;RQQ?x!al}iUts`f1t9>g_7 z>bR2#C-P6fS3NI9mPNWlM0?7UxT>U}rhkjJVBAiC*%Dn!)oAOeH5_FdK?zX)y%_ZA z3VH;#-(xydiZei%!RqKulJt!d0kY*VnQ2D%Z4;58LG)v@Mv!Fd_YNfI@UrYxDpqPm zaPh4qKpr-L;%1>uNJ7b?utP&td#eUB_^>Zt&4`ciY>W$)1Z4~LhY<}WAVmg4EJ9#9 zXVN4$H7{5@7K%H~_>#|*2BFEoDOKZfDr=&o`IgKCfLh%MIa4DWRzDr;W~SuirG#N7 zB&neQz4l*edYB(jOlE<^1fqHcDQvDlakH4YXFx;~$6E84wGPJQY0*v>8XCicyWDpV zwe*vfRfUGaF_P>(E$2yR3rh|1bEbjJehOH_PYT40%E6k+`v>8_G$`7fdd_ao#^wPo=#AV6D|mgJ{1kpd`<+TU4Oqy5wb=OE8;@ zKt5ITay84-XC2&q<4Zfae1S=5(91(Zv+%_Cb-I=YE@~oLh~f(AIS@Lq(_D3(hej<8H250i9tovq{Db~H-Wv=BLD!jLq-o3nzXGnvl}sGhi(DE+zIEw0Fw|* zrADxYpn4Hz4DE+48}TiEl~5H^vdUC-vM^<~%xj7z#M2&_NH=zbJl#At)3^D4oWjS3Z`jHY6Oa-3yw$!#ci z@e~~XAi|?iCS<^2s8S7aN(NLC?(uZKG}@_}M0h-%KTV)hhH*)RQx2QBrCYyHPGLx2 z<}1m{1>)hR53o9EJbyt%&Z5nxOF)rj(JR&RqcQtTbHOuxVLnu=7ZGo@3mU`tHyI|L zP8@8Ri_V?opsmsv#QXn83iez*dK z@rOfxXz3Pa4a|4w>fOsPM`KtSVLsq`1=<{HSk^G77?da@yClQVO}eH&jySX`px3?D z4{M9o44;>VHmypF&XSQ}^2?zuL8I6zeLAK=qfWnv2E4wB2bUIz!ZOH8p<2_0NL&>1 z7;3+F1MT#uIL|@|e8MDus}I}vA28>%lbHrJ&%cQgS#5W}4xaR4n97nH$;5^X$Yyw8 zQMDioz8;e3Bo)ZYh^(XD#G0U8=-mfo8UhwPS^rrZT=&cb0p0%$Y6W6G@EDNi{3F`f zLC&Gg@Ibi2>2%U849M}Zrv-Ytbc5cT>RRFgo^E&-`3rL`A5Bn<=I}+X%c=6Br^?;@ zi}{DQ9{pq<_oiGqoQyeA^S>lWiN20uBncPzM+`l(iHP$1+Rww-UZNW7-#kzMZ`e`u zK~`BKgbHS|Cl**R^Q*$4sRgyt8( zh1~1pcwybBN3l{~rBu51R;Hfw)+VB|g>idQVqKo-~Ko?P}=5V@{ ze1(~tqPYC4LJ@$XYYoFO_$I&twG!B;@ehcceZqbwzi6?QOp&l2lh~hbNvk}R$?5-Scg zkL@s&=_v1-?VE(Ed~Ew~*rD+@pzyOf$zjjNZ7?Lm29)eieV!gL0}CoAiWUl};skw~ zmgS*>XcxtbE}PzNs+K`*1En`%(&ibotWF-&GSm4Oe2W@(3Qx?b_=DMSTA5S^bSa{b zXhc$dG!`E6&$8_j>7zZlT0<6YoW5j;1&qAsU>I&VZHDEu6}l9bNi-D?pqVdDl}J`r zaYg068sjjxizcWoHnuH!lLgrn0BeTjVlP?1TCfJRtAgeh2tcHoP{LObMZ(Q)pThbt z?p(9HQNiRqaOAp^Hd=qu9S`JZTtLYO&3q~gAnS<$M`p?;a494zzBlIZv;@!DS#IN z)MxbJ-OBn#{T-J4@9;}5ivZh7 zN}d2=+bx-ZW^~y5%E518mE9lxV+&nE%716@Zx#P0zlmR8&Q-pwRNDA(MjwRhMx8Xc zUuVe!2Bn)h&IS+I0wksIK6n>jco1}*CD-|?j(_%R@(1|Tz42`SH8yXDjpov`-NELw zWPtGE>nPGj;-HUpwELi^dIDL%3*&Wme>x1lh8k_C(Q&&yCITcxWv)(U3)tD| z0g(}>2NV$9ZXZ~^-l*Gdue0#_`}mc0txqSQ;5upaoE@|N`|rFz_l^uNZ0)Y3wMouScpgkFb2wwP{PsW&&-ikUjz&S5+#LD_WFVgZnq(lizCY*xsoU&&wrTWvw!+Zw z>u3bf#FI*$j8H)E?gImsqXnA@w>7I|{B@GiqU8Cv1e3IUe@-$<+CXHZS$@EAG@D4z zs1AfhCNFGISKALBuHA1V1Mz?pMFWF5fhmW7nmQaGO`Xs2;nmM72bIbn-2VKN$}fHX zU^*R~sSMu1aRZ(-_~O0F=m(X#*WYEy!MmJfI7l(~_~)Ni-UXyQF7Y)Tm%xL$&wh@R z3i$UJ>|sLizOi@@`w0|TeL++wI>zkSIz#N8kmBZ)1PSB$Sz@pA3OlFzXh+x8R<=25 zEX_d~U`H$?{0V4ovk+H|c7})h|DLqxm{;b$4*LJz+&gpMo%{AXgZ~#ALUiM}yn}xa z@Ne=x`~oRJ2S~|(hrZ`{FvEo7_6`y5%P_= zg{%=Y1P4{4t$B_!!s}=GgaXQh>j(Tw?IY^Hsph`ld%yC1mW|+Ya(peT{%&Oi2nj!?fk9wJHA93}*4ty0 zaDZcRpGtpFXeQ9a+Wa{t8vZ@TT%@kh?A(xHF!`@An>9%u`L#N=4tA1oX;Fxm^VI`) zWUO;|fWI~~fFCO%R$IDIyXD7uu#jPFy5|Oj$&CmfgeSt0$y~lM z+^3JI7P#j-YJgqyJ-4tsHRQX&0)h=U&~N|>3odAXh7l@S5sMw3+Tkvd#h2`LxO59! z<){i2?PvqaV?hT>U{4`A=R*(oHUimoYZ79I5-1&{5Qu~ZxR-@gFxSoztnTRs(yoQh;h-h^O6Y0TmSExfR-AWyqDeW7Fl88W85HG=v~3 z(2%K|9*`#K&gATPflC=a-q$QYd*D>H27z;a+B-Zv(SAHYVUuX_E z%gf|VN&kDK1@!FcI?(+dbHRabJ@@vk9Vmqs~ zg?hIoV*m6WyJ3g3ZJeHEpEKEdEgKu2ZR@nQNk4DN*!;ZDZuTe3+LYaI4;1%;-LO^q zMZ0-PTcUrC7DsUh?1oL!l>1UF_n^I`T;K1!U&@|r12&Z}yvUv8LG3Xg<+uGu&$T%J!;EOdXtvY05BQ4Qb`Tu zgx3gg_WJ(cNxGK5M?S+rE}zXrQNja$CRKJ*huph!g;Jg11jBvC2{jd`P zp30(fblzXNJGUlp;CA~1GNtxN8TGf3=agWT7xemyoQjppw#IHNR9Du5N53ZZfp6r zvG^Inv%8I?mjcqb7%ut0t%5b9n7P=PzgvpqEjAS^mKAWb$eEco-I9_ls8n$|CZ8i1es6g7oB~XJk(hJfCrJ5#znpj?KOetkr$_T?+ zoOZdlOsgr@26j!^UskDW7nRrOGVAL#DMN++GdM!XZ!=kNZ}I%>10lTSr)eKzIB)v^ z($Wvyd#pps-nI$WjE}EC742KfwtG)^Z`Uhb`)y9t_0X<vfw=v+E1we3N;XYj^y+Akx!s55K}{TNA!?3Y$1J37|s3Mg5Ig+0!?!yib~V z(%)wSi(mWQG^Ab(ixqCcPzM`z$~|>wl7-AZ9Zm$jFCw%I7*hLNgkLFQ5|_`!f4(0rUF!uwP~{U1~s_t z^;7O@3Jg+{mA&?sF2b#kwKsJ)#N}7BYNI^W>krjz3ry41*S)vagU>_$jtLlq zn;gIklB0ksIpl)&YwG;6G*(`@8OZO#$6z4h<6bL=If&^RQ6=ppW|W}Bs#$G9-y{>? z*aba`;^>S>>-pV@+jc`wi--$H@>|Zi*3Y0YY{L~jEyh)9cS%PZXTyjJq!45DXjZlX zv!gqDRz~XLzM+7i=}85VHV@-ozzEFVcVCE+;>$#bE>b?mcE}Wu$*O3q%yNx^qiehM z$e66LxY`d%Y{OgJulA0fq!1JWPK!cqMaS})?{~({cg7OLzH_bmJ&lPsd6zt2wY7#m zINc#k$$eOz{P%_K1=X)ciD!)R+x~CK28}`b8u$ayDr<`VKv*J~k^Dj2qsIxeu`9X7 zNZBQ`5#p`x5kZlkcia8mGC6OdRM-YkDYHpDcF=~XtfzLE<0*T#~7c!ebKRr7fj z<m zlM<)|h^!T`@w64jsMQLyzmYEM#L$Wttbkr`g{eBRFaE7ums=}(w&)A*=)JKOdt)p1 z#=h8_EMKz%*Iu;#lwERdiP9voiEXEWo;S3ZKd zPzKY87A7^;ChfTo+%X+K5SQJ7IzkMi68eJ)@|auBHS8wNYf z+*mL}7ZkypebGb7qI9+LIjnhOPUG@hWfNBjYWsF|IZ5xjvjzN%oR8HgZSA;A*ZSZPsJ{|5>CVwv}{$ z7j^7l&l|dS9qL&SscNZJe8-67pF%ctwGSNV1bQ$79U{0-)M1&FZry9r3Bmzl)6baq znOUTTFw0}o!kD!`SwdvMay3Mk?@e|!nNs&8Q{DC5mSS&GCn@Q;VamYh#Z8~je|Ql5 zahBZs7Oy5| zH9q^=+A(T^xL>wLU;_m_Y;W#0BsH@)S$id!Vp_XjaeLR}50kaSl0!&DbM>DIoi>n@ zA%ot~o7_SYGo#l;!VH@&nGfOoWj*G>PHpZkuBmdEE>tmMs0iyX}F>yKQ5plhwCLXcM6c;X1&t?fxqkmQNO=c1>1$S6o$I zO?+VO5EpY?x>&zHJ1t32MpM)9v$>rC{$p=_jWObWTexBpSA(%G6@=Z@i>tNY)i-(YjMm1*>nF!=)JLZ# zr>Cxr+XNp(1fLgbN?21Xj2i@t;kf*UYDe`}{96I-YM<&!aMgp@Fs>J>c2u75RgGht zMl4_LsvakGnbPG)y3};JsLQl2GrC;UWy`tWDpjxHQCa&PlAGD=&Wit8s~H^X?6qct z=@!K8h+)+(ljZ*rixRZS-hBWtRzwgbgxk?yZS#B-b2B$go9kRq%`7%+vN>r-{l(Vmv@H)$&Hsc= zIJH0Ey%CqT`P8Q_{BV49rhd|>5UL$#kJuouggRN6@K{Cz$KJa^edQO)5Q42x^Sr#B$j_*6iy#Fw_H_nXELC`kSpYRg!y{T1qP z6sl1ZlNTo@Ik2wwhdgAsGD9ul7j{P6Vy82CbiD*&Z*;MhXwHm6r!%R*5`X4)y@qUh z8d9#9n60ihC$NNQ7aE17r8_2TV4o%?;En(^qOs$~iQafeR+6s-tqM(Cyp|B7-%)6QkMCyN;g7*$%+a?4w4!o%bd zibFazTPVY_P#kiDndE*(aS)JM9%#Q6$Aek<(&CsS-9H9^HDLzhVQ*%9$R%~9Hhn?M zG`|AkKAUzUaRQ>=Q&;Z2p(IYpJoMmh*6s2PoW(0wE*|tLGc@)mt;-CK7o<%fvM@4i z@iQ|{A{)7VAuTT2H2GrEHKpDEH^XWi_%`XMOA?BkE^V29(ny50h1)n;X=*VJV@m}w zI9JssBMF117uwQ=69v4+vd+o?DOsLEQyA`9g*|4I zQiYhByuwWlOGb5Yh<~PrrPOpJ)|nZSG@-c6Dicvojl@Ef8GdSa_3<}qpZP;k{W+>l zc17FFE|a?UclGtiQq$?l?JxSCT3>cif*PqoYWAMTXlTas;eI!kUqkOf&_bi5FBL)` z8ikFSreiEf6wD253>t$3@-HD?rkL*J0?q`v^(|8wGS{P}1)@usfPQhTK6+(p{EP8X z(}G80s6i8_O^m%*zcfB`aV*?V>)zc=)eHb-Ds7k`&Wf#R>RL4Sng4EMN36xob@0b} zzNmj7tV?l8kX*$m=}Z_d?j zLq3=wc%W1GPIINBLtf15;0jiI+Z1zI0c^TvCU%b&&AlYZrezxLoJ9=T{B$H`z}8+e zEb6nZ0rD0L1q7xWY#SuPK<~>TuXlGn{+s64q9s`q2yk*yCs^f7?b&-2 z$P_K_A`CO6+a;+@Hk>S}EmWjc!MbI-F^dmX1&dFX+C7pC7dQ|H*$aTp$ij9KFUZ}L z5Y9qIoS*IM3sjh6Os5+kb8` z$3ze!Q%>h3;YJF4Q8DthMrdh3bvQ}tD2xN;Xoi*ZZO-(JyPt9~@lgJoK8a4~{lBBjpT&<@ zbH6qlgo&VLCdrn4G3=kJ{aqy$ms_}lz1HqG;BZiXswZk253)BNh(J=E}AC^rbxV z+qGM2YlegrJ3E>;%pmmNX|{k!%^=j@y-zMi2qiB(hhW|a|o?gWK@9a8YqCES%NY8JNME`z7`WLh1 zB?$&LGf790hyp{f$wyl#^z6K+D|sG}>!^0JD)HI`bOx2l@I0ffTDFi%)0nR>oBwJy zQJe4K=10=oQmV_6vV`84xHvs=X>#Ps_?W44H?Un?<&C??^?Hi&FEDA0nN9VE?lGFq zT%WEz=4;8u!E(ip`pc|L!6<3utZjYk?Q_T(!69gW*I`U|ukW!w{F!7TVjQW97FpDdK~9sJmALU6h`bz zwf{agf#023?#9$9((+}w>*@L~-SRSIFKg?9_%Nd`^VSl@ht6?Z zsb&usG!6Zrli5SvVnV%=Lf|fg=FzD_e;sx_s0LNbtp%H5)UcR|v)>eV?@*JtaBB5@ z1FRW2i;Je@{NDh^Z8MMQYGxla@CNs8=!6sC2_rS0WdezZ>+S8-)VIeHjnY09m>;HfhE~gzez=$hLq|nYk~qwEKUrJ0&n%8akak&?YmF7*$gl6Xp+m)-SzezH&$!CC1=3XNFfk}mMkXp z<+pXYtIHqh@_{ZDUFLKd*5#rue_fY9)g`kMYUE{BLYw(yzt+L#CYG28qo-W`%3~gW z;e2%i*G@CHJ5Dobui4!ryHm3Yr?#7fvop3kPZ>8sS^KxRF%zSk8Id|9)5sYRlZ#(5 zs~qV1Zufp%X5=2&-}P$u{;oGn9+BxWyMKk;`hKurew?goy2#=Y_!M(O?@?gT~+ zx=Lyzx?Ixbo-SIqG}+4?hTqYn483L~HF?`4Y3HcC-{JHl2bhREd!ctv@BZFv`+E7=)qkq@L~kGemU{d4z0ljcpc>VRl-Uk3VIgF}%&-c; za%3mz>XOrfjnmiAAsAGbE;CFnUB+DCUwxoxn4QirZXe~V9H_NGK>)6XLIs;gkG5;#6`ea} z*lb&)7UnWl{>~X>W`4BKBf~rheORX0!!`%@Y)QmA%Nj@9R!vL{@%gO= zv^E?BH8T9TAy2j7w%KwUfQgmgmd&E5l9=r)vM2(($`(dD2vg+~Kr;s%|=_ z5_Y}S^<39;&mHV~6@BeF1kAU)UVg5NcRjqpeNSI;20Y+fDSOC~j%iH=3}_#5wulC> zjAEetSywkBTBC+(5orPfw57B#+^`jzwk2JGG<%ZQY`EoyFVBoxAEp}J(Cf6hLr%8e zrP=~vZFUHuQ;DOCiIO?Nos$t1WG!d8bqW{)c!=5ranqht!Gi4YUaXY>y3Y*G{4a0-__;s zb1?$1*NJHpLLd>cO8B* zJ+{;W?Z1i*;vnOp4;PlbSRHn=5U{(uw~u+Tr}z2ZgS}&~{4)7v@-O!e_8yR&@O*c6 z?(_for?*aj{`jRo`wDqWzv{F0`tsa5M?Mb>3{0=#1t8BxPV#7TC>vqKIm?tXcI+STgcgEef1ol-#orW^bH*cRHzCe@Bxhf3r zT?p6cTU45-5A*{?P1L!a9w)(^6@+ND$w=E?Ix!Rg-;l)CZSe*UI>sLb0huvklZnCbs-k!U?Xm>TLG#FA& z)jpT;h9%;hI`^|(yAsqmaBubKV1FM06(J)N-RQ*-zeSxXhfM(;&jBHZ3yok?h9|b; znT&!&KO5frW^ju$NiTEYoZ?^3HL4u)$=Q2f>#rEDEqqo7X~GRVmWiSe95@-2y>9xx zx=55sa>c`VjOMi+T&FO2oDVOqU#A99P24WdW_2BbIJf%P&|~o=)6H|*pAJ#S06IW1 z#}Pn=apW3ozhSWfj>r<8b&9`O<4 zD8N%n2W`~c?7rQ9rv{5DI+9{_9XGyX487hwp*_M4Y zD$|yY^kjvsIK!@JNyPHz@T2#f$0+~kioRE>M<=Hy$B$}1!O`niMsA2Ib8S|7(PFur z(ohQvY*1{LJC>6B+o5)mQ+&PHILZvWMtnfdhBUB>z!=vOaq1`6sJXBoGjItZR6_@D z?!$gdnC9kN97hZX6Y=?japx=(U9U(;Fv|@+VTZU>MKEduF%0ILM9MoNO{@DV(2S(&MXl`TN6 zbOuL!Bak5hn~P{)1A2~xgD3f{A*71~W`Lv|B(&W+O-v>3*qvXz-CVYF>Ab6gum@{j zoV%Bm6W9{0DMgAnPb?)3%1cCE9c$cL&a!fZ^xZ%*21H6XhQKhzbjTN&W7=utvsaca zX^QV3?sV(gr5 z*72Q6%z0Lk%qm2rFIhK`JeMYyav51(Y6)|KZO9)CSQh8cNw^$S(}H1U z**0ehWpfuIL=uo*)sE5azt5w$w^uqt7EYlK*asLDFK)aX@21?|_Ga8uo;n0^{;;&`Z!%8Ia-(I~2aY0t=q7a}(y_psLK_SJ6dU z<;07{)jM-5I)K%*B|AeJR#g()Tz-dIP`uRQB4K%`$s8)c4j`D2ulfQCY(kmWS=>rW z{5y80djv^M1$pdNj~*Q~^hO$>35C9wVr&|+W)8>6uV>o9dL*mR5kF_}(|g3^V{0mk z^#>+-)HOivG**Z1e1_@h`q;!&{o=%xabinfnixe5JNf9;;>V}YES~wW@OgZ4bZTs3 z@>2b(MBw^aQVw@caAjh0e57V6PHmZD_zZ=d-ZIIl4@t5KAfcYqr%3Wq=Ta_SnHrhl z^O??{$EL1dxH8W7k2`-K8M`)mwSMX2Q^TY=wF#tYBEfNL6Ijzkr|YMcY!i5M$v#rD zP2e7hJ#Y%Zx9I6&FJGVhoO7-w>(djnYV*lQ7sJn$$gYl5s?}(t8La;Fg%UZRW&$cibv|DD~?U+Pfbm==IvemFs2cP&0KcgW~3pr zVGQTy*(SkEWllSPzH;o!&V=-8=`&T#M^ie6O(gd$!3t2{~} zHx`{g+5~P*;#=aF zp7VaoEKovnIC`>9=+h>gc)4EB5N(K|3Av9$ZUB?@Yd&viQ1wGPJ7a03x&#LD5L)Oi z12A7X&{-y9_$8q1Lzt=ZWrYetTXVE1NVC!aSt!jK;-A_Il+3Km=abntUl2GC@vc=% zgr4h3p!I}rpReRNh0RJO-~-u8&j(HOoM`MhU28a+)$CBg1z};VD{KRVQjSky=v!7E zWE(4ft%Y`a53wKzLD~l?5T8|sPoCU%nX66Cs$IX^T5qFw+HuRd!W~$Rj@Z5udNWL< zaAc`dJm=?y5?~u^P$!n&<~q^8#ED}22v2j!)CH5=wRCf#ET zNO}3h3r#bgfXn8Xh)`FO7Koe`xQ@yiERQthNa0ZmCUz5eZk;TPJW8q`2O&U~J={Fk z4DyO6%dYcCR$ph$x3g`t#|=dur62vXgb2*zOxvm^4|T6Qyizi&a7;lrWRb_zhfZh6pwn?%2nB!6%MnXW5uTOPow5^u?ni@Si zIx#a-xis|g@Ni}Q#ND}v1yDEA$R?QG5(D`Q8_D6Qj_5EHDlWwhj(L~&79 zrh1rjan<#Bcs(djU`+ggeCYeG}nou^fpB$JG+u|b3y@qnr zy<90T&2SxtjSAQ#bA%yI$eGX>-=woZsh*9kPTR2^ULu%+25Z*C*2+fm3NVN7LwLhH zJjG5zQ?Ub)*3((01YRI-6_FJjUfRmB0Ej<<#hQ{JXRLd~HO6?1#Gfanu%KEdJnxUr zDr&B;%v-~sqksa)4x6TOTNo*qogbw2SVcY;W^DB0K;7Jx=u$fKrBvrp zW{J*p0#@0FXUIwIX_Fo>HH^38KgLK!Prwd9Bc zKDD%%IfiCssEucX1~e69CCK>KXli-*FPy0*W#phXXKQhkr@Wxk$8;oi`j}Ber(*pp z`8M*wZ14sUJZ)Gt=~R`5{4+iy_TR=yqys2HaF>)_q|rD>k;&zs%8_`wuspA>YqrkQ z90N1OR-n7|xim;SHEhdaiHD#~`FMZc)>4;bN%JS1TjCG?Q@B|MM+F-UxyESPiA&#c zR9A;Fj2^EPOuuS;kr&vZBAya%Vh*0}d)mn)vXNZUTJuOM$Q{a4!i-v3Dr!r_Y+T;= z6I2%0awsV9)Q(`$cPTN4zDu7=5dMbyE(K#}eJ4|kuRdFU8$$i z_lA-Z9lAm@O&F9O4~(xloHB@dH@q zP(&RVoTI7&A<#9Um3d5vFXb?iM?irlL!vO-dFhTI?@;hOy zV0*N_)^Lndbyjpv&55bfx~l12hg2yT)%31Isz~I= zI9k^6_4^s47CY3Brz^_)8{fU3VJc6bxlY-tM{>zJI2)$uEwzC)&_W}mfNxI4bu}UA zBx%lEvq~JzOEw=crxVdf#>2PLnV(5s|NJz_yEt~T(U1j>$PWg`guX#F(GZ}FM;skT zIFG9NKpX4AMwak8k1pJgIt@7$ogbbcCX;cCy(DONj(zaegjt=(D;yh{VcQ zs32vO&#XWxqXMw0$i1Qbl)XN)d`p>=J~x5h`^<(_U~@(CHKrFi;07TirOyICv;8V1 z0MnEyhQ#`YOR3b}Y%yfZRq%{$DU*Hz`DuO+>zuh|ZzagBj1-_Kul-uuxOp^ML5fz? zuogdz=blpMe>Q@VTMJjh&A=$Tpjg^%fpNN2gK};JBez^_Mc>`9f}z*NVW1tH9GY_1 zx7*~z_FN+hecwrjd`6E3PtzhMH-ew*%x6m1n}WTu*z%ibFinNM46ZO1`Upq6(i(SGdNFM^|M-68

%m7n4UsxH#cCa~mk<-kY>Un;Id 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

P5* z(753{WG^i4P1HY9Qv39Vi3y0JU=kKs$%LIgWzP`ZCXM{lKGC<>J^^}+6TR0zuFUv} z_PFiM^n2gFKox_>8L^GNjYET2vmOzi!_+r!Lle*Eb`44?GD7WH8tY8WrnBGD&q*$> z>v0b1hAmj%xX1eXpHm{Oz3Nq61X35FY)gDXKP5WW|2!AVdo>U5WKvdLifB7V?~-6) zQC5}&@jPR3X6pA;&@NppH(C)?)-hIS$h z9^{_u&@kJj`-YBGhKCO9*vS_AQ#&3b^-fE>(*%T_{NBUeVNyOdvTyhZ3pM2$E@l-8 zZkPDBzsE(S&wp2z^w*SxB*~rvO^r&DHEw-N<%ha6acH|r5=jvr6XX98Py~AENwjlf z^Ny<5L+gYpqt?)ahi_%DEBfI&w2RkTr`e)+dtT1c@L|2lB+SYAFL&C`|1UTg{(<;D zJNMU^Z&a4gOrP`14+yv4p^`cwR&a6F?bnEyOYphoCL&%KhBcCK7Kk-L)$m&?Uu0MR z3%dL^7sL1HAK%E!a5=bQ-;O3npp)A@dCIGR41Om5ap8&K7npXyl{!Ly4TfV2V0ToA zl4N17fMQ2mv8Cy+_%dz~;a4vU_B4X;omCO;ma?vU-`7v zPwrsfKuSCPRJrq8VH1+_@+rHuZ1eTkv|6X5hO+xVjrlK86C-Ww?Z^G#2ot)_KZRpw zlw-%4)Gj|R`Gfk$~ein z-F@NZvDg25TU!}Sn=xfRVVh%g7z5aGq$>&MjT#DA?I*yygl}PsGl8n^3htm%e6RIG z-D&nH%n9mO_-P0qJ)hU>O2F4In^02;SJjOPVYKCB$#kUhB>e9Pj6;W!_ObzcWJrJc zhs3?3@)-OvXDK;f)EZ=cOpjYNPm{{m2kDx#SmpROQvsirIwRIK@S?${%D2@oby7>g zIkh!@jXH%r{n{*+ZfaIuq5^MdfuM{VBcu;c(f-@y>RQ^?AM$LVQQAp{;LYN4sY3#c zzG|Cw=)2tX>yVzIOW5ViVmRBg)&7{g1GnGepcpp}PC!3+bXR^k__Vs^rq_RitRI!y zEU?F~f&UdAtPlQfWrA&ED1XFUSH10$m2PSy(joRoJXqYa)xK&>uBw5U8B z2r0)Xf+o0|-A@G@{wm@Qo@(h9B1PyM;)+!9pg7AKEc+gBjm3D4#zNi){Zb zE|<_XRR?qjKWed+eQ!UB}wvo%JO= z;qZgQ;fRg!gZ(moSYN^uzJy=wjS1iF@$Y|5=66E@1SEO9u|=ZlyJVg`dGh4RlP6D} zT*P%dYrUrdXuRQm5xR}B-;IG|nD?9=TWS0qc2mV{&)h}p|BArR zgeXqEUS>w{?Xi+GNPS6Vnuz;DUHuMUHU4s6JCId>Kn6Otm$YvmzOGO2f5NQ-S)kCS z!0ICcf5@L%d)iSj{I-FRRN#U!C`tuZ_|zIHKRv?NHwRz(KM{*wz~G!dVmdSzo~Nhqfx9pU5X+`;4T-=`_N6(LVmOi!~`p>|C~g72OWS!)=>$@nGbbuAhwAXy=<{XkY1r3mrl zU7%?w9?A`DtEl^K=(2HIBX+j9V-AQJ+drP;&32TAy`}nbeMhT(Phr~8GQe|8P8_p0 zD6L-ASEfw-En&c4?(6a8*8c_>9;mo|T;O^56pM)hB4*gj-v#~#@A38UE%6F1cJa<+ z@})PVwcxXHc1(9+A;LBA>z_06=TCFr$X{Z&x-@;)VoaZTg3IHhcb9SEla% zrmkl6^}G7|J$;?x>nrwRG1R{#vibmg_(_;z7xF`ReZ`Wsn*6s_vKk8cp`Z9?Wd9Zq zAbYeaxt+-vOv&apnLiqZ*y!FnKO&{A)8;y>#^hbGo_hQrQD(rj>=2pjl;Uqw&I|AEn-KSrNcw=0 zcBhC7XVVjHfnbm=m{^CgH@>p6t4c_s{)gpCco%$$R~c*%NA7Q=J6j7$zzBkMFzrx4 z@u86vkkJ$-n(9|+mlhHY-wK|Z^OZg22Jz-k%>m1vA_||nP+IqTQ-cPip?~P-( z=?Y{1Q^~_ivc|jB)Hc-NNq{DRgMoPxe2GPMzo@GfP8M9BNnW*8RCb-pH`^t^UDLt!>Tr}UcB?|BtUU~g1mTp!DcMQl8^OZfBuklQzd^PCU?#H^Z(To z<@9V@(zM|vAKbMG@$4g(`H;WeX`y1W_;+2of6ABl5~wD0p%aAFU=l|aah*^2puf)& z(kBqZUp=KMTF7Y8#$s>MaG3@3s_WL=w+O@S&Qd4zL^wTYnqPuNKCkc9Q;mQY!Z{~B z{|?V~#jqM-{%hc;Q@m&KVZw_kllUsei1ANzLCvu^hbi8}_l$42k2QuL*zy&91F+DW zLMa7O8Pmb{^B01$$WplRnnI!4|3p`68Q(y7imR**U;?nijdM5cV2uv) z|AU%Bl0viX?=q)*iNF2k>EDcEFl~_EB3ZFPCheY;9_>jt0@4DJxao{3B|i=xW`_vw zU#4w|`nIm(li^7Hr{g+KC@?gICizZ%A#HJ<3*p|)jVL@Wg=2ShDkHg3y8;xa>`kuB zejDPw`wmiTgKVRdI))h*>wlN4T@xI{{ya}`TYg}`{H`rOjMVP`EtUB16biFqcQC;H z8|3;gRh))U6uGDOKV#8MilL>OytGd$!en)9Z!wW({wx|a)du<#?_KB5EVrrT%I42O z9?{A8Z&EDlKt4}?n%og1x9CdLx)!A-3Sx)I@VPxY)^`6MZ+FuK26GIogDF>YV`Fkv zBxUk7ZXAE~?Nytjjxhjgt?*i?1>)#4COZV|rB;lIT1XU|nkTR?Hu^M_*U<%tYCwx$ z0(&20l?I~2$Rs0%M&LP%w3`jr9{nBB2Us=CK=`pJcciuQKi~at{_5ZT-~Q~J+g|>J z=XFt{ZZt7=F|+ZHd6uJ?(iwY42XOA4dOP5x-y!Wj5zeOtFPJaEfw9V%H`p7z&P_;_ zI%}7ma_hfKuD=ksilyMzCyiH$$dU_j-{h5j{(t1vh|wrswb*AlqFa-^1;!aUc0g?n zkuQqc>bKf;71&fAPk+|mKH%cvkAgUcUq8b~w&p_EwmidWZe98K6R{?IN9;hZ78%3Y zB>Y5z|}{IxkW{eW#53D!ph#Y_1{uf zH3exnbZOZ3cwC~Fm6SP~{hl7Fh1>l;=gg^DeAV5N{)qd!*$Y&&-qL5_;SK$Y-i+(( zh`!7tO}N+|0n>)-Kh&*Y*WcHdHTi8_N%qx$p)b+Y_5{`?pl#cO&rp9?w|_-nHikW? zt3S}!-_Y0J)R!jN9{W;k>J~AnGWEa3mm31($yoJ&UC&?CbKzJ%TB`mZ^H9XeeLY^f zSYJHj9z)t{nGE`T!AN^NnAia#86A?h&)(<7RG5GK-`@TEo;dWHSdJA!Z1Vf}9=gom z=lo6a_bh)u*f&PlJ+bAJhyIlN?;Se4|M^3&VO1m;-wXSmebPg_eCx^m^@C&Ae!TYy z%|4Rk&;Q!(Q~Q(u;`hfVlSF^}d8Pn1ogwE;j=xbkwlU}*Tk3R=wY&E#9;IAoZE&RT zjb3ln%(-jr#=y>$#)R8$ZrJI{0%4~*uW8Ls2W?db-Of6mdILLv?1oMtbUJXPS+B$C znvL9H(9Ir47;;Kxzp*~pstk?}qmY5lMr^n7S|9XuUUcP}4niAD5HezDXYe>WJ@W`V zzq-=vb70vT$7bGbtdo#rz`Zc-e9OKoAdb_i_`p9s< z(pl;^I8k$Bz_Gpf!&AB-P&n``II$(WKpk{)o7^5lT0f%0sc6S`8cK*n8A7Dg6=1jWENMPZeYODhKDWu9N2QUBt zYxf)LmFu=yz_At{oNwtIB6lTLWn);6)khhSiS@={FyWAfKvEgAIu_GPo6#+&@RdJ zbq+A<4&S38TKrO?ppu9Rasce0vxGA@z}j8NI1sD`6^+@*Wk*%nnWrt9V z96NEGq^fC5SpbGKa-m6j0IzMp7skxa#cf*aD#r!;iH_QqDmU;cBUYi#9BUblO$Uex ze;s5jIWJ_4E;{L0Cr7p`7p~p3CjfV$-)?kuFlB=-;0uB58c^x^-f!t6%BJpUKQzl4; ztc4=IRWy}fg0t1f?96xi)LL%TxH&uDm+kn@*CJSS$Q^(i4H`0a2GBMGCfP|@LU4xdxa;)&{Emcf&S>J8B9S50Ga zH~T@qX*)l7TRkJBJHu(7oui7Omn;Sme->$NpX^QOqIL`%HD9hkfte_$bY5BYL8p7_ zWHqfA(k#kh>xgO3Men26s|$yo>yiRJ6j^(N;dMp6^3lnPzJ*_M9?^GT}bn89M)mA5V$}MDF&rl!0Hm)U{Mml z!fE#7v3f_~AQZw$aO2=QULGf#Cy8W{Vzp>z@{vE#S!u}%E?LeKn{vjps)r{k(*m9L z7@?FB2PWe{P*ZavR^a^!${H4T)I~$GJ+-wRrRM!dD8gosCJVJBPxEj(0GUe5Nk%=WHO|Iwq2oavf4rl#)s`9SQ#zG34J?4|>!Bpj~d>T6iJC#C5D!kZ}z))%8K4Sjz=&wi9;GL=W?r>?EDzqMwimP;bD(YlY4rdhbOU&E7**=;rYtsG@EXe&J4ptsS-MqwQ^gG0-y zet{Fn7stT|*oP!@1Mjq3MRJnICkfEh_DH9*=vD_C0;U9JDrm?~ykOKtEM+ARe5TI6 z44;33X3sPr4~i0mfC!O}Rk{h9psLZt5YR@`jZBciPT$U0nuQ{7-+>it>EY}!|0L5| z!QSCVthu`!CO;@>hJFZJXlUJKnZ+991V>u?9H&?Z(pSnd>Skf&5H9r5jkTqAKNXUG zTk3B&G$>8@tBGu|GSh?FRcGmDLqU;0Y`hNha80@4LLcoIW|Y^&Se6+zu1Qncj6Svk z$vDv%ao4vAwh#ZP=s`VzTLMG_SVSgk&%7B{6d2gx#9Vl_N2f^VW~xcBl9)b{0}!lA zrecG6(C0N++n~u>hs|_VD;aU7B11EzWl+EtuEAiky2>;yjM_z<-7--oOqnDlRYskL zUTRv8nYkDck$*fDJ~^do%l@P(Y?$?w1Q4V?o4t(E%eX&KA;*Wg`9y3$%fF!XcQ|+4 z>6TGsrO6zU0#=$cgiz?p9M+23vmo#s*`vq#r_fxgLO501HFPQH*$AD(i7AzpQmPk_ zy}Uf&p!YcZC~4Jgg3$JE<2Pxy@!OsCrVFwtiDgWC%Nb*e9Y;Nd|Cl&(+FMjyX;hfj zrbX7i5nM)9$Ee*}eKZyNj>xrHn{%bxRm~{6GbnCt?a)^@Ti;cBT8})li|J0imjUr^ zPBl=#V;{-@>#fl5r!Vuca!`sLC$@|@#H~V|AvQ)0Tjq}s4j||TRP}DA3Y4D?i>>y3 zY(v4mEf|$bsyVo#Te;8Z#b~W;5R(N#QF$W3U$nQ+bY3Ej2_tmKcf(^)b`08LjSP)NL$v7`bGz4Avru zZgV@gj$x@b<7b9NW(AE#PBEgHqu_w3Rw`{_hdB}R5TNmm<&XYCGfy=i<;K+ z5L+0>u*8bYbWI-(nKyNsaS|gAE9ft>!z^Gy(hGgm&SobtZ-JWk-~2$VL=wcQghPIK zjdPMtiTX3{9#|XZUIekme8p`V8ggoM$3a2C2E$J^m`aRWktv-L)~2Id@!qbk!I}sWJC*T20T*71aet^zw7W?h1_im+VTo$PR-ObQ z)yiE@HwiWg)zL;Q=Gn%|UA2t3AZ0cNKee;)Q^j**pgo46a`g7R(I(qgv>JbunP3H+ z$I_n!mVw)n&G?V;6qCm8>|nM(J8a&+Tiuz8yij#!J}Z-xDL;1Q{eVkHLxpemsfu=j zVD?X4AdZ(d2vQ1m26BoAm&DvZ)J$ z9D03JUYur3MV8CgYOobxis<$4VW8FO3S+g`a9j$utd>3>O<}kd7NP0m9a?m5c+Zs@ zp`;lDYX=$H3xYfriVbYQEUR{Ws?rj?Dbzrar4W>Y|t@0$q+u4y!_WCLO15 z2N@7kL=tG>AC}I!1)QmzoCyS1+mEmx;nG%OShPCPPmFf{3LCn2k`dsD6%u&2K+RZ_=a-3ssT9C{U=m@x(*P^?n>L1Dr_0DP{6z4LzDM zQO0M(>uBXf`|ZlHkif}816h(Ywg8$VVSsEI(ejV9X1#GNwU)8eW`<)VUk+C#ige6Y zGSzBpj*me(W@Tn<3oiD06E4cQ6+V{Zarh`vj?YI}LmVvwRz_>P(v|ITg=b|4UXj8l zji351+WPe3qOB)K-`%*RoGQyUEtsSNMNi7{5B}ocd=FPu{h23auYv0jo|I^r7i6Dc zc3f@rmpWJ>`;V%!F>C6I<{ZLKl%rLoIh zTw-h`2~(C-TxNTy^Jug;yVID{EuK)CBQJ8 zCI`%Pgsue#6iu#@ndxQ$@*uMShJ^BSvx>zv&vYF*H$sI=!4iI{`^9=^T{DsJdeCj% zZP^Sm?+an7vxLgfn8KHI+^fx(iC9!eE*Pkp81nx68qkG_#>Rv!_vo)$%KzEVerD^&%RT(N@snWbAJ%FPH=rW! zf*VWInw_%f48^k4pIo^5sr;}o!;`~&sDhWy$&)zA@^$Q_|D2Ngt^2o90JmT~H4d!H zLW+pX5|KE!2vB|B-ooyv9$NVH)i*~&ghsm%4)7A~dwS;dJr(xO%&AkS?qRlZGZP@F zkxW?9P)KJPV`XyrPn^JT0khz27M#F3P@w&A9rm|QzeM#fIY~k+Gi7Mv-P7W; zah1w2epip#Ve{PuVzB{Fo;-efR0}F))`mL-f1h>q0(+b|as1@z5&S{IT?2p6xSt2U ziRXB~Ynbm2?!(r3hCcE3XpUCOU4y4L4tEA#DZdK%{*J--Gw_I+Ah<_%`s{Vu`?E(G z+10mwDc;0O?NXH3Q8AUFC)%=H@YKY!62~!#q?zm!(aOe{$ej;~8fi;)j0P5^ctZ>SBh}rJYsbpU3}K^-gt}J~gq&KT zm-_fXrgTQ8QpuhMg~n(V@8Ykai(;x+vw8SIb>Jt`cPpZV;;3LG{lfIgS!DCs%EZk4 zL=KzUGVVId);N;fR7N>w*6v}BU0W}hd6^X9liemquD*_IFl#!TOqm-X!_Ff0BHzt4 zd+U!A{yQIqXCc(*k7w>0#H8)xqrvPm2sPMtIO}O*pKQZf9tLNX+bsicGd_ zS_>vO8%bv#AkG<4Yvme=qDoo9G3K`4h2wWH|D0zH=0SS`sb4T}2L!FtR4!k=K`)%hy_=YbeKUff z3`oW|>9PU}sL^i>*jAaD6!Z<(EdMr*IYFCJoTrU+Hjb6nk>}aa53FrU$r+E$hD_&| zp6Kl&37}QV9El5fOeh%C2KwB(7LzpOyZ#$T+RBmsgr=gAe_%t^JM;qULFxujddm(Z zi$byU6grM&_o{fGafQl?xf6Pg`lt)NP%tzq_Lf4WBC_67Y^l=xk7ZsrHLlQO0!f8O zd4}=MpZ>~!|9`SAPJd5puU79~yZiX9S|pPFM(cV=fts!1p@=H)-Rh(}Z%I``MWoS$ zt*M6?O__9PO%4rdrHy;19L3*5Kf~=GUl&u>*hg?rO83V48-Q>qJ?>gsGLY6cc(k^J z53+-Yjx+Lu!79ak!hq;SaHI~tIBXeVVr1)4OB_tv} zlHxwSJm=RGcm0MHae~sWUpasM6D6U%pML0%De(NK*Q^33DDujs>jH9;B0sKQI)B4! zMxmE}a`XHZy`j*HS5=jhD)UnPf>-P$#eR7H!jFG)^Xd&%`XohP`LKTeg56MfJ-wmy zOFv2BfxsMDBKUwqyg!v8l0E{P8<($K6yQ@}bK!FR!p%=Vx^n4fdH_;aE`4<4`X`q^ z5|XDttA6?8PqGJUfvYz^q@qrkQ{X1jrQksi`lYwvrfvc<>9@c>_ase7CC(c=g8bEM(CM_A zxL&_nzj5`)m&9nNL3wV`?!*wM!FcY*;?<8nVn+h^Cr^XH`1G_q$5Z*Ce!^_0cQ3l~ z%gIq1p55d89abK5PL4D9%&g(;7=(TtxICrpMzXQ1U{8$&EO;u-Wvu`e?u)aRufw=B z;`uAJhY@s;oewK#DrrTs^mA9|w#kCkazvg>S3ep79!(&X6&Xfu7mBsCt=wp{VOaEA zY)F2;^|E63BLwiAEGB1t@lZld$)(Id=W4L(2YGfE|9dG4%&v18t9gMJQb2cUEWTWJ zu5uzb1{X71VNum6>1OL-)nk>HHP={N7z2ZvohnkOiMbMFJY%Jof@U7D>kYs8%g3&| zDv2d?AouwrjG_G+*<@Oax=(6!I}skrTT!a)@;YjH11G4wo1o|8m5=Ztix%q1(PzU) z@ZrtiSI1fJ1LQ*G_VA8<9jz^#pPoNH{i8eKck#~A$---Ur>~=v`6XB2U;cRRYW>oM z^VcthqHW9(y3rL_Jw;W}cxYA0(TLHOO?g;>z<0)OYD$u$22E(sbD2aa*GK4hWVZJ+ zcF766HzzcOZ0aXtFj6*&wn2h@@nLKd6nnCdQS;KSJDSEH{ zNR@R!GrEh@7G2LMLwqof#hM*x8t0>7=$_8Nz>gqxGV&w+LS?sN#2oL2`s|1k;j^#E ziIJoyI{p)C0qpofI(u_tJQv3t0HkX=_b`llt;vOYz~R!5&24zIy$5Wg8a0x zy3w|2PL6*<$IOw#sg8a}KQoVsuwfz8cdgOC2O~t-!YJ*ez6-qKoDG7}svxcx=fU)1 zgk15~2cngudPLlFq-Ecc-5ddb&3>TPUTgOO;A4{_%8F* zIIz9c$`NOmQY-FSfJK7XOWhW{9%-#|GD{;0J$>872p?GS8{7FW7moFWOkaDTS@CsGS7LbuO{=aCau?! z`PY)x;bi`B()xBX|Lvspon-zyN$b1G{CAVq_mcVVC9Ur#^WRTeuP5`bC#^~{UrAbT zB=c`1t!gq~Oa6G^L<%-53EWHLXQw2mh8 zN0Zi@$^4s1Ybu$aN?Oy&{B+WqN#%)g_k`19{392?jEk>XBuX7zpX&Z*=!#CJ#BGA+wUdqclGYf=gVVb{M~B3n-B|U{#?@fkzKr>v}Wz%gQWGI zU7SzaA119c2?5Z1&m?2*^D52{AUsRZwsUIcH~6}tDPN|^ZJr5sNaR7U2&l!?UVVvE zET#_uLT%F`Ws0 z)$}!~ucP{UQ(sg1n%38hzK-eZxV}#4>!iLE-LIn{Or6vEQZQzVQpRrgcj=@YkCJ4?4s(lL#UZg~gKvEb3O6(pt2j9ha?^yL>&TB46dfPKwv5Tq-U{gj6@S7rVnl@qaE~N9|Tc zV)Y zClw}@U`)KB_mNs*ymZv9Wj)MGoq+Y|1&j2#S7`{SdaHYeAiqyqkl*73`6aHZMM$@B zmqjX-8jv$;q70sgDYiP;ZM5yiL71>6+1Ci+X#sSPOqV zqTb-2*89;9lP{i^P$29qRiX;7e)&RtMDR~)`69GG4($&a?SEhamPKF3zyr(%dRtwc z-Yd|Kptr=zd=B~hhNz)Xwu~@T*645;TEswspC8|Ii`Ss?1*N~3y!q&5YyBrQjHxlU zW`J!8!8zfuQc4IY1`dS31*nOB9b6tb0EWI^lfd+-gcdfYD{95dfy%}skH~1mRg*}pv+ldXP1?t!S~Lfx`_b_$%No`))XT672%A6V9G3T|=OavHADYkA%9iA9=@YydRBw8C7) zwr6@ywB)X_8vdqzJNPcz6d(I~%=jkkrMUi--vM$BLGvvC4vxKM zVJ&qmCgIOG+~g%<>K)*jAD*drde3vL=4+&ViN6CDFfB{Bm*{&sU{fJ<_gVD4*MX_0 zp5{<77T;V=Lx?qPaJQ@rF{`*tzE)Sa_}Zl#d@X&j_u6AO_u8dfdkuh$y>=m6uRp=S z>rZr{;mz#4;R-9Sy_AjDE@Y;(cV^%9cbF#ak=Z2ekqnLY$V`y-NLF1#GT3zOwHX7g zov`QH+hE4Dcz3BS*J|OGT)T8TuB8uFT#IHHZMc?MYnf9!tsMfIA?WB!iWY6O zmMlZnlSv|H`1&(x!Z};4MGwr~dm`!9=Wkday?V{i%dE0a=U|gHUCy4+Q_cKoO%isG zTLYVE)vo-#bo6i#t}!)>V;&t+qSJ#bO8qsUae|rk-yL+~LKH)j$G;7{eFrQkrXmpj zW&GQ_Z|sHS*|Ec8FYVp0e^2axJ0I8ZuU&uf^eg|@9}j>0c9Q5%tzxnc4>kA4yP>I2 z=htj+NJakGvcbgAK4D{zym|=f6c)Z%-zUp}Jx7g}gr(W78*yEX%;t7v9P_SV|k=PdI~ zu%+1QoFor-+Ms3vfk>(S{KS`PZ33j z?P^939;} zmq)xx59nU=B}Ky;hU(*Bf-9Z&kh-0X7MBMai=r@6YeN;)YMz$RyydM?FhvK?GE8~e znTX?>h|EfjSdr!?L>j)V4OT^IE|zdCh!iRgi=^wEtU3%U2@wxMw)WOj_GEcl4W%f1 z(epVb9GT{VmqPHXAI0u>H$p|)s-^7W^`5I@BWRe8(u zrHw1uI9_fL?xin3-pa&}8`IZ>=&!PTd}f`i4_22S%=G#z=WtP3Tx|B+M8_Fe+Tgx1 z@$vooROQljzHX#JMY+DqdibDn3q6ZYGFADAoRy1x!tYE~uHWmdS3Z@YwA<+S0G#=Q z8jopzF_f^=snsqqGQ-haN~54qqU{Zxg@?up=3>qQdCgl#zETgh7KG2o#3DXrZxU-O zFqnIo0w2E2FHK;ht;W6|1eub~UC}pD5rvYn;9kN()Rl++6A<#nXkP)2tA*JL;6f-` zX4r{vP5tMzjvQ0F?HX`4MlH-;vBYy%lrAnmvT26ZNMG9X)r+IeyFH1C$ytb}zy_6x znmkh`zL@ZhU-7-3O#(|B(20Fo+nlikP#KPf3~YB?YVRz|`(!zI;MQHnT#Il?4f_+U z3@x*CBybnJOWWh|g`eN<-|pJ;%PU<)4Lw`QWqs2y?N8jkeY^ku?XK#Ty_K=w@d_a6 zl3_)V0vpr6#sbyio!bvo=)nV@v>&EBPx=$b7asoX&cf|hV|w}g^hbA&F05X;BgC&Z zhlNzfr{Bq5UTimWFBeX*wspIeX1(0avN|QxBBv@T+^I?m1#~YxT*s}R{Uk=C_N6-u z({J8+|90z5P`M`Qm!W_&MCbwEX?q+qY-J&E(MuR&R^B**Oq%U+fX6 z*m6%S{JfgaZ8wugtB|{xdtzc!>8DD?I|g4&)ZTvsf3nF8m5C9^pktKKF>pD20=O#R zs#SrDxK)MS4K_+!6}+*k3mZ4@yuZ+|!?YB~Qcd=NeH3Z|qBa@PJPPiFt%+wiTsPWK zqrg~sfb_|3fyUuhR4#3~Lt@hADK0b)3paTJhg*?2wD5;90Ib&8mxqcGIL%1comOx! z1u}4rV$f!rw>G^K41f{Vb}saYIBlAoY8R8Iqdz01f}GXbGb=O1v0J8cO)btYwb2x4 z{j*c@&3mA5o6-mcBex+#QNak-=n5|K2Wzasb_M5k-j~+Yn!!Le*_RP6ETPFJrEh^$-M2w<) z=4m{!aA%=5`RiZafl;on6K&a+xKoi~l2h_xVfMY5sb73x9rPny`yZusij|zI1gMPF z4#*Ba|JuVdyGGF7P=N>ddtKHRvpImP(q5VT~AAQx2C_t&cv zRcR=xbBU)Xv>UW4yzux4wzEKBey%B6l)?T^aUe{8mmQQ0;gpKWAu z8;>uqKB~O>W6QfaD%;J+X4@E9+{O;d8(F`bkFVd&ktN=IY>5+nnpf`8a7jJ8+{i9( zhD*Hb;BV_Vi=S^0+F6bt(dSNf1)>UwT4Fbtrobo8CA_hUpz0g8DsppD;|yLIGmzAp zfP15Q5$c9fOKBtAoAHU0tdu;K>J1^-@re^EdhZo#xxfhscoGrJ-8#nBb+?*ts<)o@ zC99~juIpveY}n%sOLEh$Z*EG`_cRWNItmaqEENXV=>@e@an#L{aaV~ID^ww^7|q&P z8Zhmmp15$vy*ws$E@?ADenU^#pAr-4kabJg`8CKhGNEQe*`&TE<3gCFBj*NYj~QT) zK~CXwC+iG*ICW>nty#8B$PB?uN0FjjQieUhM_N-yTAb;__w4NOF zRxXP%Cj*>%KSIj&x3p+g+l`1*zDE*0kPv1}`?WQq;-}^WQ;C-uBi(?Y*<@rMYxkFl6d8iX zrVz8Jw#+l+CqJAs%ed3Ca6$RJE&z;ZD(W)jR7y+)=BeFJu#tMeMH(Rw^lCeWQWWygk7;uBQoLi zO#xOPr+%<;M%#x)=!!SdqN}!2OQn2NbRmlz^;r8_Fq0L#X3o_u?#3gsHu^0g@iBg3 z1tiLb9kr1*X|WeS&{n;6sKtKZ0qLt9FAA6 zdgnIFy~TDlC=%7`DOT0cYphE+Vn$VkC|@A;!tBXAQ6y-PE;q@tc`uu+&F$&JrWv9Q z=cqr7uFonUHYLS~UbT?JouCD7P&+X>Iim%E99AbsU^N1%2z)Y!l46A^tREF)IL1UL zEUc^erJ49uFhzVs|Bn9d7HwVnar6O&DCOHl->gU?y$oKU4mL2gNEi7c*Of?)>Bfc= zTGsQ6;!)@dN9M_%OfYI%*k!_C`*q}gk)@AhVdoh(5%`w@MRF-WIzQ0zo7cvI8H^gbN&|JeZUW7UW3+|bh@kud9+hkKpapLeWqBoR2d)-(Q_E0P>)RVYIwWMQ(HRC z@k6W^oe{$o8)F|y>2OJ;rXI)kYGE8?0BuBEQh64;U9QDwAG9A|K-+G$(kKpxgk?%Q zhQRCP4^iX5{yheVxW1TEPl=l4i;W7<+3YOap;;30D6QH~7zktwm$Y;mrQ3>IYO|Uc zwl->Ggkpvl%E?q;mE*8r3yTIiqOh<)x~Uwj4dqfCmJM(qYx0+!6UMJOdOSc^^QAG< zLoHc|{>Y*k)pRhcy%h_+s`u}Kgvl#wV1talXM3kDn3#g9s6Ep@wu&UC(NX)_-PQJe zE~CKHOqIQ7N-c*X6lE=&k=(9$=`AzU7&JSbMfQHcRs&2xtZFfzI)38hskctQ{m#2T zLM97_z>)(9oRXm%AWV=l6rm?!9LmBM1gS(yR?H%gK_%4e6SD&Pn2)TnY)`e2@d9qm z;PV1UO8JZWqMigiVxPzh@SK)7svG5UPlS5gBPX)ay08(1liJX&8ww;wv^4GSQrRXe zl}{hWnn1d3YwR)JG*Br7u)0iE!vIFRK?FY6?X3j9e8ck%bqkxjGOMiOcc8JiaHNXh zGC!sO8x~4K1&r=S^0Qhhk%evaKB$0COg;i1=mJSd;NJ$7K-R6=@lufj^++qxm6|(x z$xXo+4Ng>L7i^PB!K9%)g-@&wwN?``=k2zbN~bL8kVcdoirR{&^M$0q^5HpR0@Enc zej%}7s9U57trKGuW{oj>eu@Yb;W?|6`5pZcVxURpnN+6BE-8|-W{xgf6NFaFvwuWt zTN)^l5)^eUJuL;H&?9{U@hK}_c{>&PKBg2wLsGlkF0G@G!LjDaBqV*++9K|*vQ9_m z95<&1ItKe?(L}QR!hvp__Pbuih9kjjzz;5P$rLto6U%f z0!MU;3|xs4Lc>^L6#4Yhg@(R2p--jltyT`8VW58zrvhORd=ukx0RW-wGhP|UQ-o>1 zJO7~LEUh-W_l%;!p(jh7N~YS}l~k9XTqsg-d;&XKd^CG!`)(P;6IGGj&t+AHLX#SYwmTQ62$}#CYi!5f$Jbh|CD4{8O-14vxZ-TeL61Nu$R?kWh04!TCkPSh zbUdq`*L6h2yki9X&qM?b{}HIAHB~31aYxUHV%zy}c-iV>ij*64H^Yq?@WOG3*}h93 z33ZsSc^rijgIdOB+|`kbtpQ+-6ZSM1W3$k*t+zC!aB9U}hp}}1W~x%ST9~CNH)9-# z?~_*aG&HbLTvZ@@2F3edzTA=5MP=l%@-TxRq3u*337{cS$~h&5i$hA#X0xKof;D?1 zBzzq*YBSlYWKN-Bv66mR%qBTwE0~ru-;rX?3ctt`P2N%y;D}CTdX{MR^1C|a63ZT>dU?KP z&>?1~v!!zeq(^R$!)M`YAPZ`{J3{z`?g3#T98wFzvXKO-_(05g4xwjP-TGfX}3kz=u zGttAMyUcXz4w9*uX$!uF->k)?QkbG#QU(Lnieug8iFYKfez$6^ttl6}h?+NC4i4woiDe5F+B=7 z!3lJ{dTplz{uVU~aPp=TV|B^;?ML&1OwVrKJi&Bk3uf{mNZ&>qZyD)>VLE}Viuyc9 z1&!h`R+uouYhNbp9;48QW+rOV&?&xkXjKW&PPdD(Mj5m;{j;h$Y>^4va(bnyXygTKy3z1FA*EJP}} z=W$qwSHQJLW3ku;_nu5{5YRwREjkMu-Jc*lOZ%y${ba(f@{4x}gYtCJCQ8e`Zv*(g`6awb?gq?tj`SOBY5ccIoyC5b3F<)M^m@h9S?H7|a zuU^r`t6=(S`-P-U00OQQ5r$YWM1&z048Z`11w%v_V!^zcw4Y1b-%8qtlJ={~FQG|{ z4#RT-#1I{Z?fC+9*a7kAySjOmpfSq&?WAo4iZmdv8bDA$B; z+eeZ%&nK+(nmze`(&hq~uOz>u-6xaw%Sn5Z3LUllC+(XEG`uES0)c3R8c}HcUXb6k zN6;CXj~nDEBR<7(;qXaA2DSNg(w<4$Pbe-*nD$@d@#7JlEOy>eF^RJ5T0A1 zV-d^foutkGxAlGI^S`i{zpmcPST!DmI-k2b9Ibg zCdsc74XCvkpZ+3!dM0T#bTfa}0t783zddFVfSUG@2tX~nAOcX^F3wv7pk<2ybb}Bl zE*UN)^B0o##iV^9>0DB?(0di-m}N|EiGO<$N< zM1%2H+culRK|}urpp4!$d*GYgGW!kfn9VlK9vHD**2xl#qT9ID71BM{3H6)YD|;Yw zyZD-0WgoXwb|CFz>z%O!DJEZc7i{M*_=KoXib8YL0@+w-mqm+X5R6MPz=0X7Ez&~C zWyc~V%w4fa37KD<$Hq}C1yiY10)i>|n7@I-izz(R9)fr&m=c2RRfOWJ*K1GkX3lV^ z+4mRrJ?YW9^wOfP2$-Q5wwPL61p69%msg`Bc%dXJh?jz2*d`W~z+}K*hM$l%{1jn= z0AgVFj~k*Orgw7|@WF#-Nq_V!MK9P50-^$|1`2hy%i@g|?|OiXh!gBW;pw*6m^tuwgTGTDnrT$Wt+{CUd3#a*u+HX z2`)JnbZJK$$tFrkx7*=3P*f4$8)%f#-axz1-aw1dcIKS@ym8hZYbW49vH!~Z{*1wX z!`UJ1?DK}uPCkDecJet{vdV6~BhFw>l+tfg8%tlcR%hRg{fcmEaqVL9i}*ylV(f{w z#Tcr#`6XP%RNBsBskE=gF0^~bFVcLLNL**zU<`t7n+aDjo$ZbBXM$$f_U*fF-y8OQ z)5zVQ@Sm#v)cvmRcN>1U;deLv?xxq9I#|8gzhl4P5q`saK&e-NsXq_*Y}c{Sk0yz4 zq`p2)lG;aN^F#iuCEKX4V@dtGi!O<`LeLq5!2}-%zt#5QVkY2rCT8pEe7{s#{3SyP z)S~14PLZlB_N2wQ+BFIqLw|=qm$GVFiMFTtyP&7%`68O2;_wk{a9{GpUb}uuLH!t< z2>M2>K*gJTI*bK}XG6MzjkT#p zs90Pm?XOJ`2{&nZhF!;)QSQ;=VU-S!}Wb}FbAgCaj+2*6)6FG$0 zYeeO0sz&;gP%%Qi$;G1=0}(`kJ;~Uu?#o2`BP{BHr1z9X`?L6Y(9KCQm<5DsYVsJ3 zh8CP^Qxz&k*4fFf9|QCaZ2EESUl@G@TYg**1(u?)V3)%?@+tG2Lp zHG!xLqxvLY8K$>yG1nkwvR{?fkszjK4;`sG-%!uKBgCWz`@ zg$*WV>cjs;O6|ov|B+-K5{~{_kpSFhfldh&x<@fr3Ap*$K99CaFw8y4I|S*JjRARx zv{4x2SGYlWr}h>lb?ozM(rtSJqOX$RMNdGmRndmGAN$*Z+uE~YJ1SG_dTV#x7zlUCW!rzLbMxbyIoIdp5d-HJ*8Po zd!FpM#XvRPt6~#d7zRn9S(**5w)M$kC;FZy8#PBoliVCOQXQBz7@KbfpAQe&CvG!1 z+MZL_kXln;v;kja(3U(4XK3~!8^)jFeOT_XoXD(!1qand*s5dUAh|be`Na<=Ua}2p zHxffq;Scy5O!1XG@1g(pTLjJ*_7IVC&q3mFKE>Ywz7O&J9RKufaz%k%MZYG0gZ~^@ z2#Y7^s!t$Rh|mmy>HmraOds8YY(b)6xlg4D7JgTxR**adNd92oBcl77Qb>s8TiwIx z4+sJDhl8d+(35%YQFwui(VMa;5;}P#J6MwLu2M6rIJ0M6HW5XsCkXFZw@gk@?OFc%g z&p${EzUPrz>bO8lUUmPcF$rGCA|d-H-0V%B?fo&okmJc@?3$T^Egtj3-%#Lb0!kAG zy|-?daetVlA!Su0ZI*mQcXjWZ%n@VW}n=;u}=-3YG90 z;0@q2$>)DGHg+qNPO^xYNG%keGueL$;yjZO4^)&0Z=M&}!+!U=n&TOJo8tmcY-AHX zG%684n=sxlB!^`@Kg|O|X49B2n!TKF z3`e3Kck=prY_{R!F(D&;P4EsLvYjXtTr4!Y?bmV+VqP zkwx0Q$-^i121>?09Kuuh3&|Uz(#y%=JzpM5zI-+Lg8z)<`;zrDePp6T z$muXyZU=Vy{PsH=p4m$9jxKBOLze2PqN*#sp_OTlvKh4sX%sOMtIPBHdP_B}o{k7__XNc)-~+;0bv88!3YD}vwHm?AN79vcKAd)JCdGS`P)8PVqee($ zN@^f$zYF^0_)hWFYkDP(?eK^~9_=-ONCl7ss(b9;TnKEgcZVmm*XQKAMQ49_()#C< z$?F&I{4n|QwXCP5{n{_+e$I)%zwg$NwPx#$TckniUa#r!iotaTdQ&AdKa7){4c9rO+9_%7)Zzq8plu zhWX0dQ4J|nEw-q-S6N|~Xf7DbV|JrDZN8Dss0Qkr*^6qRzV=pBgR;Aws9p#9mY;QE zbKh*+XkA*Vtr87n)FG-55xl&vs}GbmGk@1jF_OD{;n<#7j!XGe0sx({n%K;kF@%iKg~DLk?vMDQv{G`Ga=S+N;90Z<|5jTV+OAoBo(nwLNCd*}#UV`Ko8; z2xoJgu%D~0>5Wfxv`|#nF+3J8{c>s7O#P(Z2vD|*!jRJjhPsaMslTNZX3WV4%Cd=4 z^is9g1y|p?jsP-4C{fsDF3pau(bU9jDprm*&ls%ek!Yz?Z%4aJeK;*)+^^tki0=C8 zFT&PkyNPbC^>l;E2lDYfL=94fKO!uX3;BB{T)q+vmCZ z{vMUOZ|q5~U$lSElKMHWc(zArE&ZPFQ1)wJ^nFTy24mO{ipNOQbTo(cHm&uj;o{=Y z=4GVK3q-|*B~fq0l92&YH({YBEI*A}G9myO7+5-6fYMcI8Oe~X>tLC>p)C=@qL2Oj zC9WRTE>o^?TR3^cx^)(>+c-BDle>Oi=?%-abE+t{h_|No5Q1WxWPBJvTHtK!8ZoT2 z%NNNy7dNsu)FmkDI=#V4zm;xvH7FrirF8=j@@aiV;XkdTr=gGSE{%R{cWD4*ySp4C z02@XzMzNKdg(QyeEGn^8KNon|(q<8c4W~KVwPcsqaqhtaq>k^QC9MMf^pstPh?SP) zhKWYcXrAp>bc~N`$v^bKs}9Daq`GlSp->(1G+wH`xFMCsl3zf`UFTRG5%^jzAgEQz zA9!MQ6oPMBCPlwubFxv(v?FZ;s$WsdJj0huYm3-v_qlMG^$WbOU)9%~l4~Fw*01UQ zS9EFO{GpCk==6M;GRuDbhe{z7>aup%MLM&h+bW>(6mGutOFXt#m*22mNQ3kNL7mIo zfHUc6SC3s2vju=NzTSCGtCxd6;cMR>{d_W%At1oT^Dne+3>fAY8A{-^%O8-Mn@813}; zvb9oJdHTuJXIVAcIL#|aPxp|`wD z$QC=#K|Xow#8d4wD@6a|*akhoin~}7qrKW__Iq7I<&RhH4u|Wr$BzA)-YN|2F+Ieges$QJwTB<1uXv-E7xEP*aL1>; z&p0jQQ;s5NY_4Ehr2;O+BL_CYJ@KO-{fMB)9U??G2EFc1p`P!y`W&oqv9WrO-6kbm zfq8nGuXntKP(J#dhdYJ*czjO?_GyJ&ChC$!9Qw3DBT-CeK(N9Kh?>5FYh+DdpiDsb znj#hr2JjWj!j+9dTY)RqiR4VzBfbyW;fq#B+_c0=4zK~Ca6-Eeddous^R<;m&BVbF z1XvvO2t2L8tF2zsj-v2A*xF>F-P!9KeH1B<3F*Kjgz;YHpb0=KR?yNTL0KVI9@*JU zYXKz1jyfPj{O3nrWbDu8a@ek-H3Wj?u;^=*<-Isxu!OvyG}9a2^{dUfEe$9T;5(9{ z02sJ}HP~3U9*Co9p=M5^6i2DHnwNIlRFHn7&Ka6sP*N7te!CnWYyJ-P6+5ibXmNHl zttf9)&7-Xwc81W7$6@2iuqS9~!>IizR76T!B~sW!HFcVVgXApnA+u_H4For>uX@VC z11L=zQHc0?%;l~)!sJqH@bFqlrH%vbhwbKuy0(UVWqvYV*6^c%){MhA$TG27PWM) zSWGbA!WFYhh|r+HBkAXygnq-oR%he6O+sg{edwqmtSBPFN3Bj#XTkf`#W;pdqML(WwqtKtG1 z{2Ux_>0JJBsqSRQY8t2@|G+D%xhO->%)(O$?p9!eaE@3jZiE5!=M$U}MUciO2Vp%j z0kRp7O65A_wCKXWP-VR%5t)QLF^OMwd(+;5C!iJ$A?mD(I;&^{690n$`N!?{x`~B* z8iI)P0ZHQU;KA@Bs+AascB`sc5aS}5f(R(JUt<|vRJGm;QXHzps0!jdeIqhS7zYgb zBI@Q_)jt+otkxTdSJNQUHruMO$KWVUM#HN08bgM#eA9utS@V1x&dy6EXT?syYQ&LJ zP4k|{4aL+6B;5)lX<8ObxRN%i_nQ#6(HJJ8Ex^!sD_D|==nmGdwuExGK|txHHe$es zLRVU-W&3_dlMqIPtzel;jxn8jl(XB}k1k)iG(j63Jn*TM&W^&3(_+gal5jg4M3+eQ zk>jc;AbN})F@;|h^1ZP2n9;4%1j z)QQTGE+(R3>~hSjkY#IXp%Ws^D*Q;O;7FcwF8RL*x{ zN;QV_rA20!SX9_dI{gFHEXTGZV&FI^@oKXzn!FSn?;io#Z8qwe{b|tOgtY zt(6szJ+DJYzT&)0FHWtU#zS=-E*&5$wHT{pD;mY5%&3TeZ_A9@^FyVHL*7I4WX?Hg zuL}$GugVb{WMv2v#%GRBzW)P1Vyd~y zTr?1YCJ`Z}KrQ0w*%{(OKWMKaVFJOy%g+~~z6#-_n|ugpC7zM{yGH{YQau<&@*=%gGEl_u6Yg1sZ~MDFvM;($I_4(WvHpfpvRoM zDN6*C6{ciHC{yDN5yPe0WR{>YPzVvgkw6dXA5t&%%BBic&VZnIh36Uh$1BzAOdBmb zhtRHqc?p7E&s<`zTFprtnLMbL^fRXyHyYU@Qu?L#N9*opDVWkvndG}If^ z$mI-B1Rx+=wFay*BC<$m!qOY&wRhV(l%UWYG#Qenk3qMei6^OfA~`K83q`kx5OF3D zaE_|AR`GQgq!eg^>gE_+wHU9|?DPPQ6B<7;@;`_T>PY!E0n`p+BXfwX;vcKgH>rUb zYanB={xI<92G+I_sIe-22HAxI!8sUcHe`1NTBpktksVi6tIA*17`kFJe>=QbIT+aV znwn_(sVce$2u_q$i1A#ltaMXHY^2J7sB`AJrUdS$n%#gb6K`smV~Cp&0gyPD zx$P7}H9r8XgD9FecTtrq8C$SJhOP>>M`H?18VCOBb9HU$R23nu& zy5d<|v4Hju8jn!S5X`V$t0x&BB#;d|-sQ5!-v*0Z6x>icPu%tb6p4bGI4RZ*rKj%4 z?II^v8(7P9D3O=vf=7%dT*=kE8xLJp<(A+A8at{0y3N2luCedQKB55bF)cP36yS%$ znlc616R?e0BGSxLR=+ml1-$8gQ5;j%2~orP2L2u<5L4AOCt4#`E_u9iEJAgA8!Oo5 zS$ODnIJE{%yko=OG8Y=S(P%M6{6ecHX!~S(!pX$Mk>Yh=+q> zeQMfZ<#tgZ-)c|j%y0*RqR2`GWzeOqAe}#|-fqoiYPPi{W4mY3QY?Mm%F0?rN}Rg3 zGl-{*7|>Zm|1`matviQrP6{AHa_yW#gEtvS$v!$l@TA_7(Lt=SOhuoM+6m&FMf9_R-f zu}sOBKTRNWeB4YNcqyKT9F&2e-i$ywv!~1FkNo)+JDSfmE=X%(;$3%BcEDrAq{A&1 zXMM)u<|Z?!g(nzH8K(Wli4aL|zm@^Zzh@7&U%Sh&C2%TgEM4bUy#6Aawvo$p9%9R?bF)EME4?`Pd?+eJ0u=?SolThZD0$@5??FG-bYkDU#_=^J{*7TGIy=r#~OzD)Q&U^3}m`NZib^A*?NcW z;>Q_|Wtxo4;l`@BMWj*X_Vtb#jwWw~sB>x?N0z8~{Ur|B&MFhjGm>nqx3I_9+;;}Q zC>a2l=x>Kg8B|z|sa?Jr&gH<(G+g~uhoadvar@f+eu;2~x~(~!I~P|PNJaSPs@C$? zHC1vkU0BAo0Qps##D69Kag~h{mKQ9eXQ$Do@Wz^BA z2Axoz`@J;=3rmcTML~FxAwwHAN&ASyETKkaEFT(`LlIW+49{4TEVZ>GwZJ=u)X=IkoF!i4 z2`B7KN&^;7p)!_m`@*vNY*AvCAQsE~eLM8M%G*He4>my(AK79@w(ttip;m8RehoI) zv$m5nw;C&HoF`X-k3K+YVi_cwz%%pb zR3^MKmj*f&VOrvu0c+U#BZ&k?+>#A#uI)>ApR$E7U5Sw_e+hNvc3f-K2tk4%Z=v&h zRYj1t7Zb>Z2qq6ALnM8h$og7tCavIXP2o%O-viObmK9cZV7MP%E` zHch0} zSmw~F7nbz#h-{H85I|@h8O$8PvFDs$Xi=b+YolV*F#Wsw0>msLnQLO4wqaQn6@+YLp=G!+01?R&vy>*%%C3(i z5wR^+L+`~2GPt|t1n)5v{(+ebMi5*XNGbm=;CiynAPZRM?N2$(i@D6C)M^hfpd!lA zr0A_$=!v#zb%byN2@8VeiGVEt{{_shWk|UdXz_;(vxKD#hbP-<+^tR%zf*>gB|Ah> zhZf%3Sl5x3?edxg)X6J9BS^9e^%_ewkCrSKv%(i$U<|VMEh4%_bEV*l{ZNDtM@0MK z54K(<`C&3*t3s^VOI9ii*+}c<)ddvRs;}@zgNh2&rz<&zcG9)_q^eUvOElrhG>Zv@ z%90sYXM2{c;0|vm-%bN5mFWI(d695xlCa>f(Jml1qGb?L_@qk+Gep!*96w$;8mdz{ z7PFQ5kg$^+%r9w@Ka|11?jZA|L(@VFQOC?9T0&AVOBm8gjGDX|sUzwANZm6GwASvR z3)zqG<9&_`H$Ils4l(u}qDth2#uO24BdHHctd2Lu+Gg zz2*~Z*Erx^L6W)~tWo(VtjRxyscr9c9vLha53pEpU`L77qT6RQH0;8nP{nUWtLk#Y z3W}0=kW=OHc*XY`x{KgIj4ZinV&`2}h{Dv?XN{k9^qIt&pPyhlOn#VTnwBnhSa)}a zDRbPlZeY3r;PT5HqZ=V-pVIlqjzjf9Ui>_sLe6xX>@DV^Jc~tRgL6u4aHELI5%;W= z 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

}_i4I=nLa}L*Ld%OK2C;f(9ipA zZXAEw;11fyM?V?;O|*}2kIOR;&y1TlZ@$cDPk-fX*v{#1rLS^FgLS-XJmDd{+(*Fi z6Md~dF4{9`i{h9(uX6u?#~pXbH(wl)$0}!NzYzTq3>ml|kb27Mw@v^K^t{k$QFKfZ!Ya{QTo9@-X3+IiNa{Ut0cOrK2-9y};7Z!FX{Nc#Ng6EVgo4s(G6 z{m#6l?gy%a3`a9{PqQ91Y!sqWV`9+`Ysh>njkHO~*9C)9KYl1#=hUWCo9o0koGbnQ$ zo8$6~$+JBJ{TuZ4(Z@tzCH;J~N7GM9A0K^7^ik5kw>Z-Z_bty8;-KXbesAOM0sCt{ ze(LC(wLgOM&9P}uFl<4b|6O;6X@BFhz=1Yp`X*=-r##ZnNdFdnz1qiU8y|n`!lCq< zFyt{5d_cHt{?mfIv`@o0Uvq5wu4rdHdi1D#P?M+qw)7X$cTS%zegD6=`D?i*=%1pm zwgNsvg9jYUUPse+j&Pa$rw4m!xhL)9IqfTkPjJhYE%JT+VR?H)y!O-3KR|ip9SZse zj5R?&AAPO#Q!cgPz`^2=S?^J#VCTbp zdrRc>$)mDq)28d9KRet<&%YTq_}Oz)#Z*)*OE+$oEckC0th!6eVW(bDy+%@DOPoHh zP>SJuc;wj~dTn0juleaG?PprCVuhZo>*0SkD3=xJa_$zo34Y4O?Lr?4n$|Q(!lr0J|J*di-|N-@!dhZAsuY z(A)c>WLYN(-x3c`EI{D>a1c9IwDTP~OA+~)G19pa^J<&$EfW#+^PnG+W#nQTUya{qnb!=C4%kEizI8t=z8=E##VE#!}}j`Ccble{#gmF!AzmbYfMk@u6^ z$-z_?IRbm!(aa8F*uV^1+)3Et2q$2NqYdud?#Ja@^mpckd*#RXcFJ4ZUzS&&J1OtY zaM@yv*E~M;Sowu3^-VjUec#%?m)Ti9v)T5J%yAdmuMWVLb}+T89Ln{PQ%~F}CpKjL zaQwc!11C0>?EG}aw1+;sE2-pflUnlJa>ekEoxl5Q{fe>LcKBI_)oysPZ`kV6JmnDV zVn=TEmru&a{Pf9fk;jiNpR@}$sO_KMo44}h!;1@H2b*~Op#{S}TW{i-?}oyu$18fA zdit)N$Jb|^J6aL@HSAk&1Lr?|e&4+HUp!J_`Qp*a8DBiIEU@mLe4gw6zX|v;oiM4u zAJP&&S4($YP+=ALyIl}yfMYGr@7DpW=XQPID7CHiXQA2euy`wmaGr3lFYxR{J3ucR zcp~O`<`+XLhrs7YG^7pTN`ZLMrqGKx>wQ1^ z;Q5PZFP{AvP#z5M2GCBS`El&nG19x+pqKTGefz7{{SdR7g24~ySIrO5`{KTr9+6e~ zCv#u)-QQ2iW}K1j``{Uh z=Sbe0<{35|`&1i01`;vu^Y~ro9YG`#mc6$xm&m686Ent5c3)&j>uo2ec=@pFg_$Vfo|YFumvIew+J!?(d9! z?h?~@RI}YfhAcdVo!;rwr}v^gZDR^WI{}w*`>j`>Y3hUR8DPKp0e^?H^R?Gr^I_ZO zfpxgo<6R`~b(h%o`^-n(fz9hTPovrokCulE{(fDb8+c||njPCjZ}a-i(`f(vq1qbR zz9iOqN3d*??0sSTCG<9L(>#qnn)qR(_r`D1JpXD7~!E zcmA;6-uUg$ylhjMc?Nvo_<7LK-ot$TdXI5w>+KzqWhyZhW#NZa%XQi=#~fiB$5wzM zW8_#gFz1=ez4@!Fp}iOI=YxBD7o`^>G0DKdcSam_n2=kVBV^EUi$T_ python development environment. + +Running Python Scripts From Your Game +------------------------------------- +1. You must install the python 2.5.1 interpreter onto you machine. We only support python version 2.5.1. It can be found online from python.org http://python.org/download/releases/2.5.1/. Install python-2.5.1.msi. + +2. You must at minimum modify your system PATH (my computer->properties->advanced->environment variables) to point to the python.exe in the python installation. Mine points to c:\python25, which is where I installed python. + +3. You should also create a new system variable called PYTHONPATH. This is where python looks for new 'import' modules as it runs. For now, it can be empty. Later, you may want to point it at directories containing your python script files. + +4. Run hl2.exe with '-scriptlang python' to invoke python as the default vscript language. + +Debugging Python +---------------- + +Using: Wing IDE +--------------- +I recommend installing Wing IDE Professional. It's far easier to set up than Eclipse+PyDev as an IDE. +Wing's project view is trivial to set up over an existing directory structure. The debugger integrates easily with any python code that is launched from an exe running in Visual Studio (our vscript scenario). Just follow the setup instructions after downloading Wing IDE 3.1.8 from WINGWARE.COM. Look in Wing's help documentation, under 'advanced debugging', to find instructions on how to debug a python module which is launched from outside the IDE. It's about 3 steps. + +Using: PyDev & Eclipse +---------------------- +Eclipse is a free IDE originally developed by IBM to be a general purpose IDE. It requires you to install a java runtime version 1.4 to run it. Pydev and Pydev Extensions are also both needed if you want to debug python in Eclipse. When the Pydev plugins are installed in Eclipse, they allow excellent - and free - python development and debugging support. This configuration is quite tricky to set up, but very nice to use once you get it running. It has a somewhat obscure 'Workspace' project structure that imposes itself on your directory structure, which can be messy. + +You can download eclipse from eclipse.org - you'll need an older version - no newer than 3.4 + +You can download pydev and pydev extensions from pydev.org. You must follow the extensive installation instructions carefully. You MUST install pydev extensions in addition to basic pydev, or you will not be able to debug from VC using remote debugging. + +Follow the complete instructions for remote debugging here: + +http://fabioz.com/pydev/manual_adv_remote_debugger.html + diff --git a/vscript/languages/python/vpython/init.py b/vscript/languages/python/vpython/init.py new file mode 100644 index 00000000..a2705f89 --- /dev/null +++ b/vscript/languages/python/vpython/init.py @@ -0,0 +1,25 @@ +# Main python module - establishes the root scope for all python vscripts + +# hook up to the eclipse pydev debug server +#import pydevd #path to pydevd.py must be on the PYTHONPATH environment variable +#pydevd.settrace() + +#import os +#print("working directory: %s", os.getcwd()) # print working directory +# +#import sys +#print("module search path: %s",sys.path) # print module search path + +#sys.path.append('u:/projects/sob/src/vscript/languages/python/vpython') +#U:\projects\sob\src\vscript\languages\python\vpython +#print "modified module search path: " sys.path + +#import ctypes + +print "init.py just ran!" + +def sayhowdy(): + print "howdy" + +if __name__ == '__main__': + print "hello world" \ No newline at end of file diff --git a/vscript/languages/python/vpython/vpython.cpp b/vscript/languages/python/vpython/vpython.cpp new file mode 100644 index 00000000..a05deaf2 --- /dev/null +++ b/vscript/languages/python/vpython/vpython.cpp @@ -0,0 +1,4968 @@ +//========== Copyright © 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: +// +//============================================================================= + +#ifdef PLATFORM +#define __PLATFORM PLATFORM +#undef PLATFORM +#endif + +#ifdef _DEBUG + +#undef _DEBUG // don't want a debug python header! +#include "Python.h" // include python before any standard headers +#define _DEBUG + +#else + +#include "Python.h" + +#endif // _DEBUG + +#ifdef __PLATFORM +#undef PLATFORM +#define PLATFORM __PLATFORM +#undef __PLATFORM +#endif + +#include +#include +#include +#include + +#define _HAS_EXCEPTIONS 0 +#include + +#include "platform.h" + +#include "tier1/utlmap.h" + +#include "datamap.h" +#include "tier1/functors.h" +#include "tier1/utlvector.h" +#include "tier1/utlhash.h" +#include "tier1/utlbuffer.h" +#include "tier1/fmtstr.h" +#include "tier1/convar.h" +#include "mathlib/vector.h" +#include "vstdlib/random.h" + +#include "vscript/ivscript.h" + +// #include // DEBUG: memory overwrites +#include "memdbgon.h" + + + +/* +Implementation of the IVSCRIPT interface for Python 2.5 +------------------------------------------------------- + +The IVSCRIPT interface bridges the Python virtual machine (python25.dll), and a +set of server-side systems and objects, such as CBaseEntity. Although the ivscript +interface is not changed for python, the python implementation works quite differently +from the Squirrel implementation from a programming standpoint. + +Squirrel ivscript associates instance data with an entity's +code file, and each entity has its own copy of the code: +----------------------------------------------------- +The current implementation of ivscript that interfaces with the Squirrel virtual machine +assumes that every map that spawns may cause one or more script files to load, compile and +execute. In addition, every entity spawned within a map may also cause one or more +script files to load, compile and execute. An entity's script code and data is fully isolated from other entities. +Within an entity's code file, script variables such as 'self' and 'player'are auto- +defined, and they refer to the entity that invokes the code, the player etc. + +This scheme creates an execution model with per-entity scope, and a global scope common +to all entities. It also means that every entity keeps a unique, compiled copy of its code in memory. +When a map is re/loaded, all code is flushed, and the Squirrel interpreter shuts down and restarts. No code or data persists +beyond a level load or restart, and all code associated with a new map must be newly loaded and compiled. + + +Python ivscript associates instance data with the entity itself, +and all entities share the same compiled code: +------------------------------------------------------- +Python has a global scope, which contains a single compiled instance of each loaded code module. +When a code module is loaded, it is compiled and executed exactly once. (Note that 'execution' of a +loaded module creates module-global variables, and creates functions and classes). +Any variables defined within a module are global to functions/classes defined in the module, but not to other modules. +In other words, code defined within the module shares only the module's data scope. However, code can call +into another module, and must simply refer to any 'foreign' module data through explicit use of the module name. +Within a module, a class definition also creates a scope, as do method definitions with classes. + +Since all module-defined data is shared by all code within the module, we must associate instance +data with the entity instance, instead of the module (as is done in the Squirrel implementation). +This means that to preserve data associated with an entity, we pass the entity pointer as 'self' to all +module functions that need to access instance data as the first parameter. In python, we have very +simple ways to get and set data on an instance, including defining new data at runtime. + +Unlike Squirrel ivscript, the Python interpreter is not shut down when a new map is loaded or +when the game is restarted. This means that more compiled code is shared between maps +as new modules are imported. (NOTE: It also means that by the end of a game, +all unique script code modules could be simultaneously loaded in memory. Compiled code is +relatively small for full-featured modules- perhaps 10-20k. 20 modules would be a lot of +script code for a game - so perhaps 200-400k total. To manage large amounts of in-memory code, +we may need a mechanism for manually discarding +modules from memory that we know to be unique to a particulary map or entity instance.) + + +Hammer entity interface: +----------------------- +Rule 1: A python module should contain functionality corresponding to a particular type of entity. For instance, +you might have a CameraMan.py module, a SpaceMarine.py module and a Medic.py module, each assigned as the ActivateScript +for a camera, spacemarine and medic entity types you've placed in hammer. + +The 'ActivateScript' field of an entity may contain only one python module name, such as 'SpaceMarine.py'. +This module will be loaded and run the first time an entity is spawned with this module listed as +its ActivateScript. This module may contain definitions of various Valve callbacks. Each callback +will be passed the entity instance as the first parameter, such as: + + ScriptThinkFunction( entity ) - called every tenth of a second during entity think + OnDeath( entity ) - called when entity dies + etc. + + These are identical to the regular vscript callbacks (see wiki), except that under the python + system, they all take 'entity' as the first parameter. + +*/ +static int GetNewProxyId( void ); +static void SetProxyBinding( int proxyId, ScriptFunctionBinding_t *pBinding ); +static PyCFunction GetProxyFunction( int proxyId ); +static ScriptFunctionBinding_t *GetProxyBinding( int proxyId ); +static void InitProxyTable( void ); +inline PyObject *CreatePyVector( Vector *pVector ); +inline bool IsPyVector( PyObject *pobj ); +inline bool VMInitFinalized( void ); + +//------------------------------------------------------------------------------ +// python interpreter singleton +//------------------------------------------------------------------------------ +static void *g_pVm = NULL; + +// object tags, largely used for memory validity checking on pointer casts +#define TYPETAG_INSTANCE 71717171 +#define TYPETAG_SCOPE 81818181 +#define TYPETAG_VECTOR 91919191 + +// NOTE: increase MAX_VALVE_FUNCTIONS_EXPORTED and the DPX(n) & SPX(n) entries at the end of this file if more than 260 +// functions/methods are exported from valve dlls to vscript. +#define MAX_VALVE_FUNCTIONS_EXPORTED 260 + +// NOTE: increase this if we export more than N classes to python. +#define MAX_VALVE_CLASSES_EXPORTED 260 + + +//------------------------------------------------------------------------------ +// Module structs +//------------------------------------------------------------------------------ + +// a single python method definition followed by a null sentinel +typedef struct +{ + PyMethodDef defs[2]; +} pymethoddef_t; + +// valve server object instance data +typedef struct +{ + void *pInstance; // instance of the valve object + ScriptClassDesc_t *pClassDesc; // binding descriptors for methods + PyObject *pPyName; // name +} InstanceContext_t; + +// python object with data for valve server object instances +typedef struct +{ + PyObject_HEAD; + + /* instance data */ + PyObject *pDict; // mapped to __dict__ of python instance object + int typeTag; + InstanceContext_t instanceContext; + +} scriptClassInstance_t; + + +typedef struct +{ + PyCFunction pfn; + ScriptFunctionBinding_t *pBinding; // binding to valve function +} proxybinding_t; + +// global array mapping from proxy function id to function binding data +static proxybinding_t g_proxies[MAX_VALVE_FUNCTIONS_EXPORTED]; + + +//------------------------------------------------------------------------------ +// inline debug helpers +//------------------------------------------------------------------------------ + +// define this to always sanity check the object's ref counts +// NOTE: failing this can imply a reference count bug (i.e. too many frees) +// or possible memory corruption bug. +#define DEBUG_PY 1 + + +inline void AssertIsPyObject( HSCRIPT hscript, int minRefCount = 0 ) +{ +#ifdef DEBUG_PY + Assert( ((PyObject*)hscript == Py_None) || ((PyObject *)hscript)->ob_refcnt < 5000 && ((PyObject *)hscript)->ob_refcnt >= minRefCount); +#endif // DEBUG_PY +} + +// object must be a python object and an instance object +inline void AssertIsInstance( HSCRIPT hscript ) +{ +#ifdef DEBUG_PY + AssertIsPyObject( hscript, 0 ); + + Assert ( ((scriptClassInstance_t *)hscript)->typeTag == TYPETAG_INSTANCE ); +#endif // DEBUG_PY +} + + +//------------------------------------------------------------------------- +// Vector class +//------------------------------------------------------------------------- + +// python vector instance with data for valve object instance +typedef struct +{ + PyObject_HEAD; + + /* instance data goes here*/ + int typeTag; + Vector *pVector; +} PyVectorInstance_t; + +inline void AssertIsVector( HSCRIPT hscope ) +{ + Assert( ((PyVectorInstance_t *)hscope)->typeTag == TYPETAG_VECTOR ); +} + +static int DEBUG_VECCOUNT = 0; // count the vector allocations vs frees (test for mem leaks) +static int DEBUG_VARIANTCOUNT = 0; // count the variant allocations vs frees (test for mem leaks) +static int DEBUG_FUNCCOUNT = 0; // count the function handle allocs vs frees (test for mem leaks) + +//------------------------------------------------------------- +// called from python directly during object destruction. +//------------------------------------------------------------- +static void VectorRelease( PyObject *pSelf ) +{ + AssertIsVector( (HSCRIPT)pSelf ); + + // free the game vector + if ( ((PyVectorInstance_t *)pSelf)->pVector ) + { + delete ((PyVectorInstance_t *)pSelf)->pVector; + + DEBUG_VECCOUNT--; + + } + // free the python object + pSelf->ob_type->tp_free( pSelf ); +} + +//------------------------------------------------------------- +// called from python directly during object construction. +// same as class __init__ function - init the member data for valve instance +// Allocates a NEW Vector. The new Vector object will be deleted +// when the python object is deleted via VectorRelease. +//------------------------------------------------------------- +static int VectorConstructNew( PyObject *pSelf, PyObject *pArgs, PyObject *pkwds ) +{ + float x = 0.0; + float y = 0.0; + float z = 0.0; + + if ( pArgs ) + { + PyArg_ParseTuple( pArgs, "|fff", &x, &y, &z ); + } + + Vector *pVector = new Vector(x, y, z); + + DEBUG_VECCOUNT++; + Assert( DEBUG_VECCOUNT < 1000 ); // if this fails, we're likely leaking new vectors each frame. + + ((PyVectorInstance_t *)pSelf)->pVector = pVector; + ((PyVectorInstance_t *)pSelf)->typeTag = TYPETAG_VECTOR; + return 0; +} +//-------------------------------------------------------------------- +// creates a new python vector object which references the given Vector. +// (i.e. does NOT create a new Vector object). The referenced vector will +// be deleted when the python object is deleted via VectorRelease. +//-------------------------------------------------------------------- +void VectorBuildCopy( PyObject *pSelf, Vector *pVector) +{ + ((PyVectorInstance_t *)pSelf)->pVector = pVector; + ((PyVectorInstance_t *)pSelf)->typeTag = TYPETAG_VECTOR; +} + +//------------------------------------------------------------- +// called from python directly on object attribute x,y,z access +//------------------------------------------------------------- +static PyObject * VectorGet( PyObject *pSelf, PyObject *pname ) +{ + AssertIsVector( (HSCRIPT)pSelf ); + + if (!PyString_Check( pname )) + return NULL; + + Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector; + + if ( !pVector ) + { + PyErr_SetString(PyExc_ValueError, "null vector"); + return NULL; + } + + const char *pszKey = PyString_AsString( pname ); + + if ( pszKey && *pszKey && !*(pszKey + 1) ) + { + int index = *pszKey - 'x'; + if ( index >=0 && index <= 2) + { + float fret = (*pVector)[index]; + return PyFloat_FromDouble( (double)fret ); + } + } + return PyObject_GenericGetAttr( pSelf, pname ); +} + +//------------------------------------------------------------- +// called from python directly on object attribute x,y,z access +//------------------------------------------------------------- +static int VectorSet( PyObject *pSelf, PyObject *pname, PyObject *pval ) +{ + AssertIsVector( (HSCRIPT)pSelf ); + + if (!PyString_Check( pname )) + return -1; + + Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector; + if ( !pVector ) + { + PyErr_SetString(PyExc_ValueError, "null vector"); + return -1; + } + + const char *pszKey = PyString_AsString( pname ); + + if ( pszKey && *pszKey && !*(pszKey + 1) ) + { + int index = *pszKey - 'x'; + if ( index >=0 && index <= 2) + { + (*pVector)[index] = (float)PyFloat_AsDouble( pval ); + return 0; + } + } + return -1; + // no dictionary on vector object! return PyObject_GenericSetAttr( pSelf, pname, pval); +} + + +// repr function for vector +static PyObject * VectorToString( PyObject *pSelf ) +{ + AssertIsVector( (HSCRIPT)pSelf ); + + Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector; + if ( !pVector ) + { + return PyString_FromString(""); + } + return PyString_FromString( (static_cast(CFmtStr("", pVector->x, pVector->y, pVector->z))) ); +} + +// repr function for instance +static PyObject * InstanceToString( PyObject *pSelf ) +{ + AssertIsPyObject( (HSCRIPT)pSelf ); + + return PyString_FromFormat("<%s at %p>", pSelf->ob_type->tp_name, (void*)pSelf ); + + // UNDONE: + // StackHandler sa(hVM); + // InstanceContext_t *pContext = (InstanceContext_t *)sa.GetInstanceUp(1,0); + // char szBuf[64]; + // + // if ( pContext && pContext->pInstance && pContext->pClassDesc->pHelper && pContext->pClassDesc->pHelper->ToString( pContext->pInstance, szBuf, ARRAYSIZE(szBuf) ) ) + // { + // sa.Return( szBuf ); + // } + // else + // { + // HPYOBJECT hInstance = sa.GetObjectHandle( 1 ); + // sq_pushstring( hVM, CFmtStr( "(instance : 0x%p)", (void*)_rawval(hInstance) ), -1 ); + // } + // return 1; + +} + +static PyObject * VectorToKeyValueString( PyObject *pSelf, PyObject *pArgs ) +{ + AssertIsVector( (HSCRIPT)pSelf ); + + Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector; + if ( !pVector ) + { + PyErr_SetString(PyExc_ValueError, "null vector"); + return NULL; + } + + return PyString_FromString( (static_cast(CFmtStr("%f %f %f", pVector->x, pVector->y, pVector->z))) ); +} + +static PyObject * VectorAdd( PyObject *pSelf, PyObject *pOther ) +{ + AssertIsVector( (HSCRIPT)pSelf ); + + Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector; + Vector *pVectorOther = ((PyVectorInstance_t *)pOther)->pVector; + + if ( !pVectorOther || !pVector ) + { + PyErr_SetString(PyExc_ValueError, "null vector"); + return NULL; + } + + if ( !IsPyVector( pOther ) ) + { + PyErr_SetString(PyExc_ValueError, "can't add vector to non vector type"); + return NULL; + } + + // create new PyTypeVector object - explicitly calls VectorConstructNew + PyObject *pretObj = CreatePyVector( NULL ); + + *( ((PyVectorInstance_t *)pretObj)->pVector ) = *pVector + *pVectorOther; + + return pretObj; +} + +static PyObject * VectorSubtract( PyObject *pSelf, PyObject *pOther ) +{ + AssertIsVector( (HSCRIPT)pSelf ); + + Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector; + Vector *pVectorOther = ((PyVectorInstance_t *)pOther)->pVector; + + if ( !pVectorOther || !pVector ) + { + PyErr_SetString(PyExc_ValueError, "null vector"); + return NULL; + } + + if ( !IsPyVector( pOther ) ) + { + PyErr_SetString(PyExc_ValueError, "can't sub non vector type from vector"); + return NULL; + } + + // create new PyTypeVector object + PyObject *pretObj = CreatePyVector( NULL ); + + *( ((PyVectorInstance_t *)pretObj)->pVector ) = *pVector - *pVectorOther; + + return pretObj; +} + +static PyObject * VectorScale( PyObject *pSelf, PyObject *pScale ) +{ + PyObject *pPyVec; + PyObject *pPyScale; + + if ( ((PyVectorInstance_t *)pSelf)->typeTag == TYPETAG_VECTOR ) + { + pPyVec = pSelf; + pPyScale = pScale; + } + else + { + pPyVec = pScale; + pPyScale = pSelf; + } + + Vector *pVector = ((PyVectorInstance_t *)pPyVec)->pVector; + + if ( !pVector ) + { + PyErr_SetString(PyExc_ValueError, "null vector"); + return NULL; + } + + if ( !PyFloat_Check( pPyScale ) ) + { + PyErr_SetString(PyExc_ValueError, "can't scale vector by non float type"); + return NULL; + } + + float scale = (float)PyFloat_AsDouble( pPyScale ); + + PyObject *pretObj = CreatePyVector( NULL ); + + *( ((PyVectorInstance_t *)pretObj)->pVector ) = *pVector * scale; + + return pretObj; +} + +static int VectorCoerce(PyObject **pv, PyObject **pw) +{ + + if ( PyFloat_Check(*pw) ) + return 0; // NOTE: we don't actually coerce - vector multiply handles a float scalar + // and all other math functions explicitly check 2nd arg type. + else + return 1; // can't coerce anything else +} + +static PyObject * VectorLength( PyObject *pSelf, PyObject *pArgs ) +{ + AssertIsVector( (HSCRIPT)pSelf ); + + Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector; + + if ( !pVector ) + { + PyErr_SetString(PyExc_ValueError, "null vector"); + return NULL; + } + + float flLength = pVector->Length(); + + return PyFloat_FromDouble( (double)flLength ); +} + +static PyObject * VectorLengthSqr( PyObject *pSelf, PyObject *pArgs ) +{ + + AssertIsVector( (HSCRIPT)pSelf ); + + Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector; + + if ( !pVector ) + { + PyErr_SetString(PyExc_ValueError, "null vector"); + return NULL; + } + + float flLength = pVector->LengthSqr(); + return PyFloat_FromDouble( (double)flLength ); +} + +static PyObject * VectorLength2D( PyObject *pSelf, PyObject *pArgs ) +{ + AssertIsVector( (HSCRIPT)pSelf ); + + Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector; + + if ( !pVector ) + { + PyErr_SetString(PyExc_ValueError, "null vector"); + return NULL; + } + + float flLength = pVector->Length2D(); + return PyFloat_FromDouble( (double)flLength ); +} + +static PyObject * VectorLength2DSqr( PyObject *pSelf, PyObject *pArgs ) +{ + AssertIsVector( (HSCRIPT)pSelf ); + + Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector; + + if ( !pVector ) + { + PyErr_SetString(PyExc_ValueError, "null vector"); + return NULL; + } + + float flLength = pVector->Length2DSqr(); + return PyFloat_FromDouble( (double)flLength ); +} + +static PyObject * VectorCross( PyObject *pSelf, PyObject *pOther ) +{ + AssertIsVector( (HSCRIPT)pSelf ); + + Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector; + Vector *pVectorOther = ((PyVectorInstance_t *)pOther)->pVector; + + if ( !pVectorOther || !pVector ) + { + PyErr_SetString(PyExc_ValueError, "null vector"); + return NULL; + } + + // create new PyTypeVector object + PyObject *pretObj = CreatePyVector( NULL ); + + *( ((PyVectorInstance_t *)pretObj)->pVector ) = (*pVector).Cross( *pVectorOther ); + + return pretObj; +} + +static PyObject * VectorDot( PyObject *pSelf, PyObject *pOther ) +{ + AssertIsVector( (HSCRIPT)pSelf ); + + Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector; + Vector *pVectorOther = ((PyVectorInstance_t *)pOther)->pVector; + + if ( !pVectorOther || !pVector ) + { + PyErr_SetString(PyExc_ValueError, "null vector"); + return NULL; + } + + float flResult = (*pVector).Dot( *pVectorOther ); + return PyFloat_FromDouble( (double)flResult ); +} + +static PyObject * VectorNorm( PyObject *pSelf, PyObject *pArgs ) +{ + AssertIsVector( (HSCRIPT)pSelf ); + + Vector *pVector = ((PyVectorInstance_t *)pSelf)->pVector; + + if ( !pVector ) + { + PyErr_SetString(PyExc_ValueError, "null vector"); + return NULL; + } + + float flLength = pVector->NormalizeInPlace(); + return PyFloat_FromDouble( (double)flLength ); +} + +// python vector class methods + +static PyMethodDef g_VectorFuncs[] = +{ + { "ToKVString", VectorToKeyValueString, METH_NOARGS, "Get x,y,z as string of space-separated floats." }, + { "Length", VectorLength, METH_NOARGS, "Get the vector's magnitude." }, + { "LengthSqr", VectorLengthSqr, METH_NOARGS, "Get the vector's magnitude squared." }, + { "Length2D", VectorLength2D, METH_NOARGS, "2d x,y length." }, + { "Length2DSqr", VectorLength2DSqr, METH_NOARGS, "Square of x,y length." }, + { "Dot", VectorDot, METH_O, "Dot product of vectors." }, + { "Cross", VectorCross, METH_O, "Cross product of vectors."}, + { "Norm", VectorNorm, METH_NOARGS, "Normalize vector in place." }, + { NULL, NULL, 0, NULL } +}; + +static PyNumberMethods g_VectorAsNumber = { + (binaryfunc)VectorAdd, /* nb_add */ + (binaryfunc)VectorSubtract, /* nb_subtract */ + (binaryfunc)VectorScale, /* nb_multiply */ + 0, /* nb_divide */ + 0, /* nb_remainder */ + 0, /* nb_divmod */ + 0, /* nb_power */ + 0, /* nb_negative */ + 0, /* nb_positive */ + 0, /* nb_absolute */ + 0, /* nb_nonzero */ + 0, /*nb_invert*/ + 0, /*nb_lshift*/ + 0, /*nb_rshift*/ + 0, /*nb_and*/ + 0, /*nb_xor*/ + 0, /*nb_or*/ + 0, // (coercion)VectorCoerce, /*nb_coerce*/ + 0, /*nb_int*/ + 0, /*nb_long*/ + 0, /*nb_float*/ + 0, /*nb_oct*/ + 0, /*nb_hex*/ + 0, /*nb_inplace_add*/ + 0, /*nb_inplace_subtract*/ + 0, /*nb_inplace_multiply*/ + 0, /*nb_inplace_divide*/ + 0, /*nb_inplace_remainder*/ + 0, /*nb_inplace_power*/ + 0, /*nb_inplace_lshift*/ + 0, /*nb_inplace_rshift*/ + 0, /*nb_inplace_and*/ + 0, /*nb_inplace_xor*/ + 0, /*nb_inplace_or*/ + 0, /* nb_floor_divide */ + 0, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + 0, /* nb_inplace_true_divide */ +}; + +// python vector class template +static PyTypeObject PyTypeVector = { + PyObject_HEAD_INIT(NULL) /* type type */ // set up by PyType_Ready() call later. + 0, /*ob_size*/ + "Vector", /*tp_name*/ + sizeof(PyVectorInstance_t),/*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)VectorRelease, /*tp_dealloc*/ // consider + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + (reprfunc )VectorToString, /*tp_repr*/ // consider + &g_VectorAsNumber, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + (getattrofunc)VectorGet, /*tp_getattro*/ + (setattrofunc)VectorSet, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/ // don't coerce, all number functions check types + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + g_VectorFuncs, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ // base class type object + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)VectorConstructNew, /* tp_init */ // consider + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ // consider // BUG: doesn't call tp_init? + PyObject_Del, /* tp_free */ + +}; + +//----------------------------------------------------------------------------------- +// create a new python vector object from the PyTypeVector type +// if pVector is null, allocs a new vector object, otherwise just references pVector +//----------------------------------------------------------------------------------- +inline PyObject *CreatePyVector( Vector *pVector ) +{ + PyObject *pretObj = PyType_GenericNew( &PyTypeVector, NULL, NULL ); // calls tp_alloc(type,0) -> calls PyType_GenericAlloc -> calls PyObject_MALLOC + if ( pVector ) + { + VectorBuildCopy( pretObj, pVector ); // use the provided vector to build the python object + } + else + { + VectorConstructNew( pretObj, NULL, NULL ); // allocate a new vector object within the python object + } + + return pretObj; +} + +inline bool IsPyVector( PyObject *pobj ) +{ + return ( pobj->ob_type == &PyTypeVector ); +} + +// ----------------------------------------------------------- +// register custom vector class into the 'valve' module scope +// ----------------------------------------------------------- +bool RegisterVector( PyObject *pmodule ) +{ + // finalize the new python vector type + if (PyType_Ready( &PyTypeVector ) < 0) + return false; + + // add the new class type to the 'valve' module + Py_INCREF( &PyTypeVector ); + + PyModule_AddObject( pmodule, "Vector", (PyObject *)&PyTypeVector ); + + return true; +} + +// ------------------------------------------------------- +// Scope wrapper class. Python scope represents +// a python module's dictionary, or an instance object's dictionary. +// ------------------------------------------------------- + +class CPyScope +{ +public: + CPyScope( ) + { + m_pPyModule = NULL; // a python module object + m_pPySelf = NULL; // an instance object + m_pTempDict = PyDict_New(); // holding location for data until 'self' is set in scope + m_typeTag = TYPETAG_SCOPE; + } + + //------------------------------------------------------- + // release all python objects on delete + //------------------------------------------------------- + ~CPyScope() + { + Py_XDECREF( m_pTempDict ); + Py_XDECREF( m_pPyModule ); + Py_XDECREF( m_pPySelf ); + } + + void SetInstanceObject( PyObject *pSelf ) + { + m_pPySelf = (scriptClassInstance_t *)pSelf; + Py_XINCREF( m_pPySelf ); + } + + void SetModuleObject( PyObject *pModule ) + { + m_pPyModule = pModule; + Py_XINCREF( m_pPyModule ); + } + + PyObject *GetInstanceObject () + { + return (PyObject *)m_pPySelf; // return borrowed ref + } + + PyObject * GetInstanceDict() + { + if ( !m_pPySelf ) + return NULL; + + return m_pPySelf->pDict; // return borrowed ref + } + + PyObject * GetModuleDict() + { + if ( !m_pPyModule ) + return NULL; + + return PyModule_GetDict( m_pPyModule ); // return borrowed ref + } + + PyObject *GetModule() + { + return m_pPyModule; + } + + void TransferTempDictToInstance() + { + // move contents of temp dict into instance dict. + // don't overwrite values in instance dict. + Assert ( m_pPySelf ); + PyDict_Merge( m_pPySelf->pDict, m_pTempDict, false ); + } + + void SetTempDictValue( const char *pszKey, PyObject *pyobj ) + { + // set python key:value in temp dict + PyDict_SetItemString( m_pTempDict, pszKey, pyobj ); + } + + scriptClassInstance_t *m_pPySelf; // pointer to invoking entity instance - entity data lives here + PyObject *m_pPyModule; // pointer to module - entity code lives here + PyObject *m_pTempDict; + + int m_typeTag; +}; + +inline void AssertIsScope( HSCRIPT hScope ) +{ + // validate hscope handle as a CPyScope object + Assert ( !hScope || ((CPyScope *)hScope)->m_typeTag == TYPETAG_SCOPE ); +} + +//-------------------------------------------------------------------------------- +// utility callback: display a string at the console +// python sys.stdio and sys.stderr are redirected here +//-------------------------------------------------------------------------------- +static PyObject *vprint(PyObject *self, PyObject *args) +{ + const char *psz; + + int ret = PyArg_ParseTuple(args, "s", &psz); + + if ( ret ) + //DevMsg( (const tchar *)psz); + Msg( (const tchar *)psz ); + else + DevMsg("vpython.cpp, vprint error: bad argument?"); + + return Py_BuildValue("i", 0); +}; + +//-------------------------------------------------------------------------------- +// Reload the named module & fixes up the internal module pointer saved in the hScope. +// params: (PyObject *pSelf, PyObject *moduleName, PyObject *hScope ) +// ignores first param 'self'. +//-------------------------------------------------------------------------------- +static PyObject *ReplaceClosures( PyObject *self, PyObject *args ) +{ + PyObject *pSelf; // this is called through ExecuteFunction, which adds the self param + const char *pszModuleName; + PyObject *hScope; + + int ret = PyArg_ParseTuple(args, "OsO", &pSelf, &pszModuleName, &hScope); + + if ( !ret ) + { + DevMsg("vpython.cpp, ReplaceClosures argument error!"); + return Py_BuildValue("i", 0); + } + + // get the previously imported module handle + PyObject *pOldModule = PyImport_AddModule( pszModuleName ); + + if ( !pOldModule ) + { + DevMsg("vpython.cpp, ReplaceClosures error: module was never previously loaded!" ); + return Py_BuildValue("i", 0); + } + + + PyObject *pNewModule = PyImport_ReloadModule( pOldModule ); + + if ( !pNewModule ) + { + DevMsg("vpython.cpp, ReplaceClosures error: module failed to reload!" ); + return Py_BuildValue("i", 0); + } + + // fixup refs to old module object in hScope + if ( hScope ) + { + if ( pOldModule != pNewModule ) + { + Assert( pOldModule == ((CPyScope *)hScope)->GetModule() ); + Py_XDECREF( pOldModule ); // release the ref count that the hScope is holding on the old module + + ((CPyScope *)hScope)->SetModuleObject( pNewModule ); + } + } + + return Py_BuildValue("i", 0); +} + +//--------------------------------------------------------------------------------- +// given euler angles Pitch, Yaw, Roll, get forward vector +//--------------------------------------------------------------------------------- +static PyObject *VectorFromAngles( PyObject *self, PyObject *args ) +{ + float fpitch, fyaw, froll; + + int ret = PyArg_ParseTuple(args, "|fff", &fpitch, &fyaw, &froll ); + if ( !ret ) + { + DevMsg("vpython.cpp: invalid params to VectorFromAngles, expected 3 floats!"); + return Py_BuildValue("i",0); + } + + // create new PyTypeVector object - explicitly calls VectorConstructNew + PyObject *pretObj = CreatePyVector( NULL ); + + QAngle angles(fpitch, fyaw, froll); // QAngle(pitch, yaw, roll); + Vector forward; + + AngleVectors( angles, &forward ); + + *( ((PyVectorInstance_t *)pretObj)->pVector ) = forward; // copy + + return pretObj; +} + +//--------------------------------------------------------------------------------- +// given forward vector, get euler angles Pitch, Yaw, Roll. Roll is always 0. +//--------------------------------------------------------------------------------- +static PyObject *AnglesFromVector( PyObject *self, PyObject *args ) +{ + PyObject *pyVector; + + int ret = PyArg_ParseTuple(args, "|O",&pyVector ); + if ( !ret ) + { + DevMsg("vpython.cpp: invalid params to AnglesFromVector, expected 1 vector"); + return Py_BuildValue("i",0); + } + + QAngle angles; + Vector forward = *((PyVectorInstance_t *)pyVector)->pVector; // copy + + VectorAngles( forward, angles); // returns pitch (x), yaw (y), roll (z) + + PyObject *pretObj1 = PyFloat_FromDouble(angles[PITCH]); + PyObject *pretObj2 = PyFloat_FromDouble(angles[YAW]); + PyObject *pretObj3 = PyFloat_FromDouble(angles[ROLL]); + + PyObject *pretObj = PyTuple_Pack(3, pretObj1, pretObj2, pretObj3); + + Py_XDECREF(pretObj1); + Py_XDECREF(pretObj2); + Py_XDECREF(pretObj3); + + return pretObj; +} + +// ---------------------------------------------------------------------------- +// given euler angles Pitch, Yaw, Roll, return tuple of vforward, vright, vup +// ---------------------------------------------------------------------------- +static PyObject *VectorsFromAngles( PyObject *self, PyObject *args ) +{ + float fpitch, fyaw, froll; + + int ret = PyArg_ParseTuple(args, "|fff", &fpitch, &fyaw, &froll ); + if ( !ret ) + { + DevMsg("vpython.cpp: invalid params to VectorFromAngles, expected 3 floats!"); + return Py_BuildValue("i",0); + } + + // create new PyTypeVector object - explicitly calls VectorConstructNew + PyObject *pretObj1 = CreatePyVector( NULL ); + PyObject *pretObj2 = CreatePyVector( NULL ); + PyObject *pretObj3 = CreatePyVector( NULL ); + + + QAngle angles(fpitch, fyaw, froll); // QAngle(pitch, yaw, roll); + Vector forward; + Vector right; + Vector up; + + AngleVectors( angles, &forward, &right, &up ); + + *( ((PyVectorInstance_t *)pretObj1)->pVector ) = forward; // copy + *( ((PyVectorInstance_t *)pretObj2)->pVector ) = right; // copy + *( ((PyVectorInstance_t *)pretObj3)->pVector ) = up; // copy + + PyObject *pretObj = PyTuple_Pack(3, pretObj1, pretObj2, pretObj3); + + Py_XDECREF(pretObj1); + Py_XDECREF(pretObj2); + Py_XDECREF(pretObj3); + + return pretObj; +} + +//----------------------------------------------------------------------------- +// Interpolate a Catmull-Rom spline. +// t is a [0,1] value and interpolates a curve between p2 and p3. +// takes p1,p2,p3,p4 vectors and float t, returns output vector. +//----------------------------------------------------------------------------- +static PyObject *CatmullRomSpline( PyObject *self, PyObject *args ) +{ + // UNDONE: use interpolatortypes.cpp types instead of a single interpolator here + + PyObject *pyv1,*pyv2,*pyv3,*pyv4; + Vector p1,p2,p3,p4; + float t; + + int ret = PyArg_ParseTuple(args, "|OOOOf", &pyv1, &pyv2, &pyv3, &pyv4, &t ); + if ( !ret ) + { + DevMsg("vpython.cpp: invalid params to Catmull_Rom_Spline, expected 4 vectors and 1 float!"); + return Py_BuildValue("i",0); + } + + p1 = *((PyVectorInstance_t *)pyv1)->pVector; + p2 = *((PyVectorInstance_t *)pyv2)->pVector; + p3 = *((PyVectorInstance_t *)pyv3)->pVector; + p4 = *((PyVectorInstance_t *)pyv4)->pVector; + + // create new PyTypeVector object - explicitly calls VectorConstructNew + PyObject *pretObj = CreatePyVector( NULL ); + + Vector output(0,0,0); + + Catmull_Rom_Spline(p1,p2,p3,p4,t,output); + + *( ((PyVectorInstance_t *)pretObj)->pVector ) = output; // copy + + return pretObj; +} + +//----------------------------------------------------------------------------- +// Purpose: basic hermite spline. t = 0 returns p1, t = 1 returns p2, +// d1 and d2 are used to entry and exit slope of curve +// Input : p1,p2,d1,d2, t, +//----------------------------------------------------------------------------- +static PyObject *HermiteSpline( PyObject *self, PyObject *args ) +{ + // UNDONE: use interpolatortypes.cpp types instead of a single interpolator here + + PyObject *pyv1,*pyv2,*pyv3,*pyv4; + Vector p1,p2,d1,d2; + float t; + + int ret = PyArg_ParseTuple(args, "|OOOOf", &pyv1, &pyv2, &pyv3, &pyv4, &t ); + if ( !ret ) + { + DevMsg("vpython.cpp: invalid params to HermiteSpline, expected 4 vectors and 1 float!"); + return Py_BuildValue("i",0); + } + + p1 = *((PyVectorInstance_t *)pyv1)->pVector; + p2 = *((PyVectorInstance_t *)pyv2)->pVector; + d1 = *((PyVectorInstance_t *)pyv3)->pVector; + d2 = *((PyVectorInstance_t *)pyv4)->pVector; + + // create new PyTypeVector object - explicitly calls VectorConstructNew + PyObject *pretObj = CreatePyVector( NULL ); + + Vector output(0,0,0); + + Hermite_Spline(p1,p2,d1,d2,t,output); + + *( ((PyVectorInstance_t *)pretObj)->pVector ) = output; // copy + + return pretObj; +} + +static PyObject *HermiteSplineFloat( PyObject *self, PyObject *args ) +{ + float p1,p2,d1,d2; + float t; + + int ret = PyArg_ParseTuple(args, "|fffff", &p1,&p2,&d1,&d2, &t ); + if ( !ret ) + { + DevMsg("vpython.cpp: invalid params to HermiteSplineFloat, expected 5 floats!"); + return 0; + } + + float output = Hermite_Spline(p1,p2,d1,d2,t); + + return Py_BuildValue("f", output); +} + +//--------------------------------------------------------------------------------- +// +//--------------------------------------------------------------------------------- +static PyObject *ExactTime( PyObject *self, PyObject *args ) +{ + return PyFloat_FromDouble( Plat_FloatTime() ); +} + + +static PyMethodDef valvemethods[] = +{ + {"vprint",(PyCFunction) vprint, METH_VARARGS, "Display a string on the Valve console."}, + {"__ReplaceClosures",(PyCFunction) ReplaceClosures, METH_VARARGS, "Reload a module."}, + + {"VectorFromAngles",(PyCFunction) VectorFromAngles, METH_VARARGS, "Convert from Roll, Pitch, Yaw to Vector"}, + {"VectorsFromAngles",(PyCFunction) VectorsFromAngles, METH_VARARGS, "Convert from Roll, Pitch, Yaw to forward, right, up Vectors"}, + {"AnglesFromVector",(PyCFunction) AnglesFromVector, METH_VARARGS, "Convert Vector to Roll, Pitch, Yaw angles (Yaw always 0)"}, + {"ExactTime",(PyCFunction) ExactTime, METH_VARARGS, "Get accurate sub-frame time in seconds"}, + {"CatmullRomSpline",(PyCFunction) CatmullRomSpline, METH_VARARGS, "Interpolate along a Catmull Rom Spline. Takes p1,p2,p3,p4 vectors and t float fraction."}, + {"HermiteSpline", (PyCFunction) HermiteSpline, METH_VARARGS, "Interpolate along a Hermite Spline. Takes p1,p2,d1,d2 vectors and t float fraction."}, + {"HermiteSplineFloat",(PyCFunction) HermiteSplineFloat, METH_VARARGS, "Interpolate along a Hermite Spline. Takes f1,f2,d1,d2 floats, and t float fraction."}, + + {NULL, NULL, 0, NULL} // sentinel + +}; + +//------------------------------------------------------------------------------ +// UNUSED: Purpose: remove old module from sys.modules and decrement ref to module object. +// may provide either module object, or module name +//------------------------------------------------------------------------------ +void UnloadModule( PyObject *pmodule, const char *pszModuleName ) +{ + + return; // BUG: the name of the last module to run becomes '__main__' - must not unload main! + + const char *pszName = NULL; + + PyObject *pSysModules = PyImport_GetModuleDict( ); // borrowed ref + + if ( pmodule ) + { + pszName = PyModule_GetFilename( pmodule ); + pszName = PyModule_GetName( pmodule ); + + } + else + { + Assert ( pszModuleName ); + pszName = pszModuleName; + } + + if ( !pszName ) + return; // scope module has no name + + PyObject *pPyKey = PyString_FromString( pszName ); + + if ( PyDict_Contains( pSysModules, pPyKey) ) + { + // remove module from dict + PyObject *pOldModule = PyDict_GetItemString( pSysModules, pszName ); + PyDict_DelItemString( pSysModules, pszName ); + Py_XDECREF( pOldModule ); + } + Py_XDECREF( pPyKey ); + +} + + +//------------------------------------------------------------------ +// SINGLETON python interpreter - do not instantiate more than one +// (this module keeps a static global pointer to the interpreter instance.) +//------------------------------------------------------------------ + +class CPythonVM : public IScriptVM +{ +public: + CPythonVM( ) + : m_iUniqueIdSerialNumber( 0 ) +#ifndef VPYTHON_TEST + , developer( "developer" ) +#else + , developer( "developer", "1" ) +#endif + { + m_bInitialized = false; // becomes true on all subsequent attempts to kill/restart the interpreter + m_pRootScope = NULL; + m_pValveScope = NULL; + m_iMethodDef = 0; + m_iClassDef = 0; + + m_debugObjCount = 0; + + } + + + //------------------------------------------------------------- + // Init the interpreter class - NOP if interp already active + //------------------------------------------------------------- + bool Init() + { + // g_pMemAlloc->CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_CHECK_CRT_DF ); + if ( VMInitFinalized() ) + return true; + + // Python makes use of mathlib, so we have to init it: + MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f ); + + // init static proxy table + InitProxyTable(); + + // start python interpreter installed on users machine. + // i.e. python25.dll should be in c:\windows\system32 or on dll search path. + + Py_Initialize(); // this is a NOP if already initialized + + if ( !Py_IsInitialized() ) + { + DevWarning("CPythonVM.Init(): python interperter failed to initialize!"); + return false; + } + + + const char *pszVersion = Py_GetVersion(); + char buffer[64]; + V_strncpy(buffer,pszVersion, 6); + buffer[5] = '\0'; + + if ( V_strncmp(pszVersion, buffer, 5) ) + { + // we link with python25.lib from version 2.5.1 + DevWarning("Python25.dll version mismatch: version %s loaded. Should be 2.5.1!\n", buffer); + } + + // modify python's module search path in sys.path to point to current working directory + /scripts/vscripts + + int ret; + + ret = PyRun_SimpleString( + "import sys\n" + "import os\n" + "a,b = os.path.split(os.getcwd())\n" + "c,gamename = os.path.split(a)\n" + "p = os.path.join (os.getcwd(),gamename,'scripts','vscripts')\n" + "sys.path.append( p )\n" + ); + + Assert ( ret == 0 ); // make sure we could set up the python sys.path to the vscripts directory + + + // save off the vscript directory - ex: U:\projects\sob\game\sob\scripts\vscripts + + char szScriptPathTemp[MAX_PATH]; + char szScriptPathTemp2[MAX_PATH]; + char szDirectoryTemp[MAX_PATH]; + char szGamename[MAX_PATH]; + + // get current working directory + + V_GetCurrentDirectory( szDirectoryTemp, sizeof( szDirectoryTemp ) ); // U:\projects\sob\game + + // get game name from current working directory + + V_ExtractFilePath( szDirectoryTemp, szGamename, sizeof(szGamename) ); // U:\projects\sob + const char *pszGamename = V_UnqualifiedFileName( szGamename ); + + V_ComposeFileName( szDirectoryTemp, pszGamename, szScriptPathTemp, sizeof( szScriptPathTemp ) ); + V_ComposeFileName( szScriptPathTemp, "scripts", szScriptPathTemp2, sizeof( szScriptPathTemp2 ) ); + V_ComposeFileName( szScriptPathTemp2, "vscripts", m_szScriptPath, sizeof( m_szScriptPath ) ); + + + // create a new global scope 'valve' module - all valve classes, functions, instances are registered in this module. + // NOTE: 'valve' must be imported by python modules that wish to access these c functions. + + PyObject *pPyValve; + + pPyValve = PyImport_AddModule("valve"); + PyModule_AddStringConstant(pPyValve, "__file__", ""); + + PyObject *pmod = Py_InitModule("valve", valvemethods); + Assert ( pmod == pPyValve ); + + // Redirect python stdout & stderr to Valve console + ret = PyRun_SimpleString( + "import valve\n" + "import sys\n" + "class StdoutCatcher:\n" + "\tdef write(self, str):\n" + "\t\tvalve.vprint(str)\n" + "class StderrCatcher:\n" + "\tdef write(self, str):\n" + "\t\tvalve.vprint(str)\n" + "sys.stdout = StdoutCatcher()\n" + "sys.stderr = StderrCatcher()\n" ); + + Assert ( ret == 0 ); + + // create new valve module scope + m_pValveScope = new CPyScope( ); + m_pValveScope->SetModuleObject( pPyValve ); + + // get the main module object + PyObject* pPyMain = PyImport_AddModule("__main__"); + + // create new root scope from main's dictionary + m_pRootScope = new CPyScope( ); + m_pRootScope->SetModuleObject( pPyMain ); + + + // load and run the init.py module in the global scope + PyObject *pPyModule; + PyObject *pystr = PyString_FromString( "init" ); + pPyModule = PyImport_Import( pystr ); + Py_XDECREF( pystr ); + + PyPrintError(); + + if ( !pPyModule ) + { + DevWarning("CPythonVM.Init(): unable to load main module init.py - module not on PYTHONPATH (sys.path)?"); + return false; + } + + m_TypeMap.Init( 256 ); // must be power of 2 + m_ClassMap.Init( 256 ); // must be power of 2 + + RegisterVector( m_pValveScope->GetModule() ); + + PyPrintError(); + + return true; + + } + + //------------------------------------------------------------- + // Called every frame with frame time + //------------------------------------------------------------- + bool Frame( float simTime ) + { + // UNDONE: garbage collect periodically? + // UNDONE: invoke a per-frame global function? ex: to run generators +#ifdef DEBUG_PY + if (1) + { + // validate every instance object we've allocated + for (int i=0; i < m_debugObjCount; i++) + { + if ( m_debugObjects[i] ) + AssertIsPyObject( (HSCRIPT) (m_debugObjects[i]) ); + } + + } +#endif // DEBUG_PY + return false; + } + + //------------------------------------------------------------- + // Called on level load + //------------------------------------------------------------- + void Shutdown() + { + bool bGameExit = false; // UNDONE: need flag passed in - only kill interpreter data on game exit, not restart or level load + + if ( bGameExit ) + { + if(1) + Py_Finalize(); // interpreter shutdown - reliable only ONCE per game session. + + // shut down the vm. called on restart, or game exit + + if (1) + { + ReleaseScope( (HSCRIPT)m_pRootScope ); + ReleaseScope( (HSCRIPT)m_pValveScope ); + m_TypeMap.Purge(); + m_ClassMap.Purge(); + + } + + } + + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + ScriptLanguage_t GetLanguage() + { + return SL_PYTHON; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + virtual const char *GetLanguageName() + { + return "Python"; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + virtual void AddSearchPath( const char *pszSearchPath ) + { + + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + bool ConnectDebugger() + { + // for debugging from visual studio into python, running pydev in eclipse, + // first launch the pydev debug server in eclipse, then + // run python code containing the following line: + // + // import pydevd; pydevd.settrace() + + // for debuggin in Wing IDE, place 'import wingdbstub.py' in + // the code module you wish to debug. + + return false; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void DisconnectDebugger() + { + + } + + //------------------------------------------------------------- + // run script text in the root scope + //------------------------------------------------------------- + ScriptStatus_t Run( const char *pszScript, bool bWait = true ) + { + Assert( bWait ); + + PyObject* pyret = PyRun_String( pszScript, Py_file_input, m_pRootScope->GetModuleDict(), m_pRootScope->GetModuleDict() ) ; + + PyPrintError(); + + if ( pyret == NULL ) + return SCRIPT_ERROR; + + Py_XDECREF(pyret); + return SCRIPT_DONE; + + } + + //------------------------------------------------------------- + // run the compiled script in the given scope + //------------------------------------------------------------- + ScriptStatus_t Run( HSCRIPT hScript, HSCRIPT hScope = NULL, bool bWait = true ) + { + return CPythonVM::ExecuteFunction( hScript, NULL, 0, NULL, hScope, bWait ); + } + + //------------------------------------------------------------- + // run the compiled script in the root scope + //------------------------------------------------------------- + ScriptStatus_t Run( HSCRIPT hScript, bool bWait ) + { + Assert( bWait ); + return CPythonVM::Run( hScript, (HSCRIPT)NULL, bWait ); + } + + //------------------------------------------------------------- + // python auto-compiles modules, so just return a python string containing the module name, + // or a python function object + // + // pyszScript - script file contents - module content - ignored if pszId is given + // pszId - module name with extension - modules live in scripts/vscripts + // + //------------------------------------------------------------- + HSCRIPT CompileScript( const char *pszScript, const char *pszId = NULL ) + { + + if ( pszId ) + { + // pszId is the module name with extension - required for python + Assert(pszId != NULL); + + PyObject *pName; + + // strip module extension + char buffer[1024]; + V_StripExtension( pszId, buffer, sizeof(buffer) ); + + pName = PyString_FromString(buffer); // new ref + + return (HSCRIPT)pName; // return the name of the module to later import (and run). compilation is automatic. + } + else + { + // code string fixup: + /* Replace any occurances of "\r\n?" in the input string with "\n". + This converts DOS and Mac line endings to Unix line endings. + Also append a trailing "\n" to be compatible with + PyParser_SimpleParseFile(). Returns a new reference. */ + + if ( !pszScript || !*pszScript ) + { + DevWarning ( "Vscript: no script text passed to CompileScript - ignoring compilation!"); + return NULL; + } + + char *buf; + + { + char *q; + const char *p = pszScript; + + if (!p) + return NULL; + + /* one char extra for trailing \n and one for terminating \0 */ + buf = (char *)PyMem_Malloc( strlen(pszScript) + 2); + if (buf == NULL) { + PyErr_SetString(PyExc_MemoryError, + "Python Source Compile - no memory to allocate conversion buffer!"); + return NULL; + } + /* replace "\r\n?" by "\n" */ + for (q = buf; *p != '\0'; p++) { + if (*p == '\r') { + *q++ = '\n'; + if (*(p + 1) == '\n') + p++; + } + else + *q++ = *p; + } + *q++ = '\n'; /* add trailing \n */ + *q = '\0'; + + } + + // create a new python code object - we own the reference which we must release later + // NOTE: must pass full path to source file to enable debugging in external IDE (such as Wing IDE Professional). + char szFullPath[MAX_PATH]; + + if ( pszId ) + { + V_ComposeFileName( m_szScriptPath, pszId, szFullPath, sizeof(szFullPath) ); + } + + + PyObject *pyCodeObject = Py_CompileString(buf, (pszId) ? szFullPath : "unnamed", Py_file_input); + // PyObject *pyCodeObject = Py_CompileString(buf, "U:\\projects\\sob\\game\\sob\\scripts\\vscripts\\mapspawn.py", Py_file_input); + + PyPrintError(); + + PyMem_Free(buf); + + return (HSCRIPT)pyCodeObject; // return a code object - NULL on compile error + } + + } + + //------------------------------------------------------------- + // release code object, string object (module) or instance object + //------------------------------------------------------------- + void ReleaseScript( HSCRIPT hScript ) + { + Assert( hScript ); + AssertIsPyObject( hScript ); + + if ( !PyString_Check( (PyObject *)hScript ) && !PyCode_Check( (PyObject *)hScript ) ) + { + AssertIsInstance( hScript ); + } + + Py_XDECREF((PyObject *)hScript); + } + + + //------------------------------------------------------------- + // create an empty scope object - use SetModule and SetInstance + // to create actual references to dictionaries. + //------------------------------------------------------------- + HSCRIPT CreateScope( const char *pszScope, HSCRIPT hParent = NULL ) + { + CPyScope *pPyScope = new CPyScope(); + + if ( hParent ) + { + DevMsg( "Warning, Python script language ignoring hParent parameter for CreateScope!" ); + } + + return (HSCRIPT)pPyScope; + } + + //------------------------------------------------------------- + // delete the CPyScope object + //------------------------------------------------------------- + void ReleaseScope( HSCRIPT hScript ) + { + AssertIsScope( hScript ); + + if ( hScript ) + delete (CPyScope *)hScript; + + } + + //------------------------------------------------------------- + // return a python PyObject* given a named variable in the given scope's instance object. + // python object is a new reference if bAddRef is true, otherwise borrowed reference. + //------------------------------------------------------------- + PyObject* LookupObject( const char *pszObject, HSCRIPT hScope = NULL, bool bAddRef = true ) + { + if ( hScope == INVALID_HSCRIPT ) + return NULL; + + PyObject *pGlobals = InstanceDictFromScope( hScope ); + + // Return the object from globals dict using key. Return NULL if the key is not present. + PyObject *pyobj; + + pyobj = PyDict_GetItemString( pGlobals, pszObject); // returns borrowed reference - we don't own this obj unless we increment the reference. + + PyPrintError(); + + if ( pyobj == NULL) + // key not in dict + return NULL; + + if ( bAddRef ) + Py_XINCREF(pyobj); + + return pyobj; + } + + //------------------------------------------------------------- + // return a python function object - lookup function in MODULE scope dict - + // NOTE: this will only work correctly AFTER CompileScript and + // Run or ExecuteFunction is called on the script which holds the function. + // NOTE: caller must call ReleaseFunction when finished with function! + //------------------------------------------------------------- + HSCRIPT LookupFunction( const char *pszFunction, HSCRIPT hScope = NULL ) + { + // UNDONE: CBaseEntity calls this for EVERY think cycle - + // UNDONE: rewrite CBaseEntity to remember the think function handle! + + if ( hScope == INVALID_HSCRIPT ) + return NULL; + + PyObject *pGlobals; + + if ( hScope ) + { + pGlobals = ((CPyScope *)hScope)->GetModuleDict(); + } + else + { + pGlobals = m_pValveScope->GetModuleDict(); // lookup function in valve scope + } + + if ( !pGlobals ) + { + DevWarning("Vscript, vpython.cpp: LookupFunction - must first compile and run the script before you can lookup a function!"); + return NULL; + } + + PyObject *pFunc = PyDict_GetItemString(pGlobals, pszFunction); // borrowed reference + + // set up function object with scope + + PyPrintError(); + + if (pFunc != NULL && PyCallable_Check(pFunc) ) + { + Py_INCREF( pFunc ); // inc ref so obj can be released later + DEBUG_FUNCCOUNT++; + Assert(DEBUG_FUNCCOUNT < 1000); // if this fails, server is likely not freeing function handles (leaking each frame) + return (HSCRIPT )pFunc; + } + else + { + return NULL; + } + } + + //------------------------------------------------------------- + // decrement our reference to the function handle + //------------------------------------------------------------- + void ReleaseFunction( HSCRIPT hScript ) + { + AssertIsPyObject( hScript ); + Py_XDECREF((PyObject *)hScript); + DEBUG_FUNCCOUNT--; + //ReleaseScriptObject( hScript ); + } + + //------------------------------------------------------------- + // given a handle to a python function, a compiled code object, + // or a module name, execute the object. If given a module name, + // also sets the module object in the hScope for subsequent + // execution of functions in module scope. Caller must free + // variant args & any newly returned variant. + //------------------------------------------------------------- + ScriptStatus_t ExecuteFunction( HSCRIPT hFunction, ScriptVariant_t *pArgs, int nArgs, ScriptVariant_t *pReturn, HSCRIPT hScope = NULL, bool bWait = true ) + { + if ( hScope == INVALID_HSCRIPT || !hFunction) + { + // DevWarning( "Invalid scope handed to script VM\n" ); + return SCRIPT_ERROR; + } + + AssertIsScope( hScope ); + AssertIsPyObject( hFunction ); + Assert ( bWait ); + + PyObject *pGlobals = ModuleDictFromScope( hScope ); + + // get type of hfunction - may be string (module), function, or compiled code object + + if ( PyString_Check( (PyObject *)hFunction) ) + { + // Import a module and set the hScope module variable. + // NOTE: this is required before lookup/executeFunction calls into the module. + // hFunction is a module name - may be returned by CompileScript + // equivalent to python "import modulename" + // note: python auto compiles the module if it is out of date, and saves the + // binary image to disk for faster load times (no compile) on future import calls. + + ScriptStatus_t result = SCRIPT_DONE; + PyObject *pModule; + + // char *pszModuleName = PyString_AsString( (PyObject *)hFunction ); // internal pointer + + // import and run module - always runs in global scope + // PyObject *pystr = PyString_FromString( pszModuleName ); + pModule = PyImport_Import( (PyObject *)hFunction ); + // Py_XDECREF( pystr ); + + // set the module object in the scope. + if ( hScope ) + ( (CPyScope *)hScope )->SetModuleObject( pModule ); + + Py_XDECREF(pModule); + + + PyPrintError(); + + if ( !pModule ) + result = SCRIPT_ERROR; + + return result; + } + else if ( PyFunction_Check( (PyObject *)hFunction) || PyCallable_Check((PyObject *)hFunction) ) + { + // Run a function in a module: + // hFunction is a python function object. + // NOTE: hScope is ignored - it was associated with the function object during function lookup (function's module) + // NOTE: first argument is always 'self' of the calling entity, even if NULL + + PyObject *pPyArgs = PyTuple_New(nArgs+1); + PyObject *pValue; + int i; + + // first argument is always 'self' ,even if NULL + PyObject *pSelf = NULL; + if ( hScope ) + { + pSelf = ((CPyScope *)hScope)->GetInstanceObject(); + } + + if ( !pSelf ) + pSelf = Py_None; + Py_XINCREF( pSelf ); + PyTuple_SetItem(pPyArgs, 0, pSelf); // steals ref to pSelf + + for (i = 0; i < nArgs; ++i) + { + pValue = ConvertToPyObject( pArgs[i], true ); // new ref + + // pValue reference stolen here: tuple owns the objects now + PyTuple_SetItem(pPyArgs, i+1, pValue); + } + + PyObject *pPyReturn = PyObject_CallObject((PyObject *)hFunction, pPyArgs); + Py_DECREF(pPyArgs); // release tuple and contents + + PyPrintError(); + + if ( pPyReturn == NULL ) + { + // call failed + return SCRIPT_ERROR; + } + + bool bFreeobj = false; + + if ( pReturn ) + { + bFreeobj = ConvertToVariant( pPyReturn, pReturn ); // caller must free this + } + + Py_XDECREF(pPyReturn); + + return SCRIPT_DONE; + } + else + { + // Run compiled code in a module: + // assume hFunction is a compiled code object + + PyObject *pValue; + PyObject *rgpyArgs[31]; + PyObject *pPyReturn; + + Assert ( nArgs < 32 ); + + // first argument is always 'self' ,even if NULL + PyObject *pSelf = ((CPyScope *)hScope)->GetInstanceObject(); + if ( !pSelf ) + pSelf = Py_None; + Py_XINCREF( pSelf ); + rgpyArgs[0] = pSelf; // arg steals ref to pSelf + + int i; + + for (i = 0; i < nArgs; i++) + { + pValue = ConvertToPyObject( pArgs[i], true ); // create new python objects with new refs + rgpyArgs[i+1] = pValue; + } + + if (0) + { + char *pszdebug = PyString_AsString( ((PyCodeObject *)hFunction)->co_filename ); + char buffer[1024]; + V_StripExtension( pszdebug, buffer, sizeof(buffer) ); + + //Py_XDECREF( ((PyCodeObject *)hFunction)->co_filename ); + + //((PyCodeObject *)hFunction)->co_filename = PyString_FromString( buffer ); + + PyObject *pystr = PyString_FromString( buffer ); + PyObject *pmodule = PyImport_Import( pystr ); + Py_XDECREF( pystr ); + + // BUG: this executes in the module's scope, which is not per-instance. + + // PyObject *pmodule = PyImport_ExecCodeModule( buffer, (PyObject *)hFunction ); + Py_XDECREF( pmodule ); + + pPyReturn = Py_None; + Py_INCREF( pPyReturn ); + } + else + { + // NOTE: This function will actually + // run the code within the given scope dictionary - must be a module-level dictionary. + pPyReturn = PyEval_EvalCodeEx((PyCodeObject *)hFunction, + pGlobals, //PyObject *globals, + pGlobals, //PyObject *locals, + rgpyArgs, nArgs, //PyObject **args, int argc, + NULL, 0, //PyObject **kwds, int kwdc, + NULL, 0, //PyObject **defs, int defc, + NULL); //PyObject *closure + + } + + // release arg objects + for (i = 0; i < nArgs; i++) + Py_XDECREF(rgpyArgs[i]); + + if ( pPyReturn == NULL ) + { + // call failed + PyPrintError(); + return SCRIPT_ERROR; + } + bool bFreeobj = false; + + if ( pReturn ) + { + bFreeobj = ConvertToVariant( pPyReturn, pReturn ); // caller must free this + } + + Py_XDECREF(pPyReturn); + + return SCRIPT_DONE; + } + + // invalid hFunction + return SCRIPT_ERROR; + } + + //------------------------------------------------------------- + // register a new function so python code can call it + //------------------------------------------------------------- + void RegisterFunction( ScriptFunctionBinding_t *pScriptFunction ) + { + // if ( VMInitFinalized() ) + // return; + + RegisterFunctionGuts( pScriptFunction ); + + // NOTE: DEFINE_SCRIPTFUNC and ScripRegisterFunction macros eventually call RegisterFunction. + // Templates automatically create the ScriptFunctionBinding_t. + + // Following is a summary of the Template expansion for ScriptRegisterFunction(Named) which + // builds the ScriptFunctionBinding_t in place and then calls ResisterFunction with it. + // This scheme effectively uses C++ compile-time templates to implement function introspection: +/* + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCreateSceneEntity, "CreateSceneEntity", "Create a scene entity to play the specified scene." ); + + #define ScriptRegisterFunctionNamed( pVM, func, scriptName, description ) + + static ScriptFunctionBinding_t binding; + binding.m_desc.m_pszDescription = description; + binding.m_desc.m_Parameters.RemoveAll(); + + ScriptInitFunctionBindingNamed( &binding, func, scriptName ); + + #define ScriptInitFunctionBindingNamed( pScriptFunction, func, scriptName ) + + ScriptInitFuncDescriptorNamed( (&(pScriptFunction)->m_desc), func, scriptName ); + + #define ScriptInitFuncDescriptorNamed( pDesc, func, scriptName ) + (pDesc)->m_pszScriptName = scriptName; + (pDesc)->m_pszFunction = #func; + ScriptDeduceFunctionSignature( pDesc, &func ); + // this is a complex macro which, at compile time, + // inlines the code to fill out the remaing fields in the + // pDesc structure with the appropriate arg types and return types + // for the given function. + + (pScriptFunction)->m_pfnBinding = ScriptCreateBinding( &func ); // uses functors to create the binding function + (pScriptFunction)->m_pFunction = (void *)&func; + + pVM->RegisterFunction( &binding ); + } +*/ + + } + + //------------------------------------------------------------- + // create a new python type object encapsulating the class - + // NOTE: must subsequently call PyType_Ready to finalize the class + //------------------------------------------------------------- + PyTypeObject *CreateClass( ScriptClassDesc_t *pDesc ) + { + // python class template + static PyTypeObject scriptClassType = { + PyObject_HEAD_INIT(NULL) /* type type */ // set up by PyType_Ready() call later + 0, /*ob_size*/ + 0, /*tp_name*/ + sizeof(scriptClassInstance_t), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + 0, /*tp_dealloc*/ // consider + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + (reprfunc)InstanceToString, /*tp_repr*/ // consider + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + PyObject_GenericGetAttr, /*tp_getattro*/ + PyObject_GenericSetAttr, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, // | Py_TPFLAGS_BASETYPE, /*tp_flags*/ // allow subclassing + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ // base class type object + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(scriptClassInstance_t, pDict), // tp_dictoffset - used by generic getattr,setattr + 0, /* tp_init */ // consider + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ // consider + PyObject_Del, /* tp_free */ + + }; + + // build a new scriptClassType for each 'CreateClass' call + PyTypeObject *pnewtype = (PyTypeObject *) PyMem_Malloc( sizeof(PyTypeObject) ); //new PyTypeObject; + + if ( !pnewtype ) + { + // interperter out of memory + Assert( false ); + return NULL; + } + // track it so we can free it later + Assert (m_iClassDef < MAX_VALVE_CLASSES_EXPORTED ); + m_rgpClassDefs[m_iClassDef++] = pnewtype; + + // allow mapping between PyTypeObject (accessed from pSelf->ob_type ptr) to ScriptClassDesc_t pDesc. + + // init the pnewtype with the static template + V_memcpy( pnewtype, &scriptClassType, sizeof(PyTypeObject) ); + + pnewtype->tp_doc = pDesc->m_pszDescription; + pnewtype->tp_name = pDesc->m_pszScriptName; // BUG: prepend "valve." or pickling is impossible + + // if base class given, make sure base class type already defined in root scope + // then hook it up to our type + if ( pDesc->m_pBaseDesc ) + { + PyObject *pdict = m_pValveScope->GetModuleDict(); + if ( PyDict_GetItemString( pdict, pDesc->m_pBaseDesc->m_pszScriptName ) == NULL ) + { + Assert( false ); // base class should have been pre registered in 'valve' module + return NULL; + } + + // lookup the corresponding type object + PyTypeObject *pbasetype = PyTypeFromDesc( pDesc->m_pBaseDesc ); + if ( !pbasetype ) + { + Assert ( false ); + return NULL; + } + + pnewtype->tp_base = pbasetype; + } + + // set up constructor and destructor + + // DEALLOCATION CHAIN: Py_XDECREF -> tp_dealloc (free any local allocations) -> tp_free (free python object allocation) + + // ALLOCATION CHAIN: tp_new, tp_alloc (create empty python object) -> tp_init (set up local data) + + + pnewtype->tp_new = PyType_GenericNew; // create new uninitialized object (just calls tp_alloc) // BUG: doesn't call tp_init! + pnewtype->tp_init = (initproc)CPythonVM::InitInstance; // same as __init__ for class - init the context associated with the object + pnewtype->tp_alloc = PyType_GenericAlloc; // alloc space for a python object + + pnewtype->tp_free = PyObject_Del; // delete the python object + pnewtype->tp_dealloc = (destructor)CPythonVM::FreeInstance; // called when ref count drops to 0 - release any memory held by object + // (ie: call destructor on underlaying valve object if object was allocated from python ) + + // UNDONE: implement these additional callbacks + //sq_pushstring( m_hVM, "_tostring", -1 ); + //sq_newclosure( m_hVM, &InstanceToString, 0 ); + //sq_createslot( m_hVM, -3 ); + + //sq_pushstring( m_hVM, "IsValid", -1 ); + //sq_newclosure( m_hVM, &InstanceIsValid, 0 ); + //sq_createslot( m_hVM, -3 ); + + + // register all methods - create tp_methods table of pnewtype + + int count = pDesc->m_FunctionBindings.Count(); + + if ( count ) + { + // create an array large enough for all method defs + null semaphore + PyMethodDef *pmethods = (PyMethodDef *) PyMem_Malloc( sizeof(PyMethodDef) * (count + 1) ); // new PyMethodDef[count+1]; + PyMethodDef *pm; + + if ( !pmethods ) + { + // interperter out of memory + Assert ( false ); + return NULL; + } + Assert (m_iMethodDef < MAX_VALVE_FUNCTIONS_EXPORTED ); + m_rgpMethodDefs[m_iMethodDef++] = pmethods; + + // TEST1:m_pMethodDefs.AddToTail( pmethods ); + int i; + for ( i = 0; i < count; i++ ) + { + ScriptFunctionBinding_t *pScriptFunction = &(pDesc->m_FunctionBindings[i]); + + pm = &(pmethods[i]); + + // fill python method def + + pm->ml_name = pScriptFunction->m_desc.m_pszScriptName; + pm->ml_flags = METH_VARARGS; + pm->ml_doc = pScriptFunction->m_desc.m_pszDescription; + + int proxyId = GetNewProxyId(); + SetProxyBinding( proxyId, pScriptFunction ); + + // the function/method callback chain - python calls Translate_XXX -> calls TranslateCall -> calls binding function -> actual function. + pm->ml_meth = GetProxyFunction( proxyId ); + } + + // set null semaphore at end of methods + pm = &(pmethods[i]); + pm->ml_name = NULL; + pm->ml_meth = NULL; + pm->ml_flags = 0; + pm->ml_doc = NULL; + + pnewtype->tp_methods = pmethods; + } + + return pnewtype; + + } + //------------------------------------------------------------- + // create new python type object for this class and include + // ScriptClassDesc_t in the user type data. + //------------------------------------------------------------- + bool RegisterClass( ScriptClassDesc_t *pClassDesc ) + { + // if ( VMInitFinalized() ) + // return true; + + PyObject *valveModule = m_pValveScope->GetModule(); + PyObject *pdict = m_pValveScope->GetModuleDict(); + + if ( PyDict_GetItemString( pdict, pClassDesc->m_pszScriptName ) != NULL ) + return true; // already registered + + COMPILE_TIME_ASSERT( sizeof(pClassDesc) == sizeof(int) ); + if ( PyTypeFromDesc( pClassDesc ) ) + { + return true; + } + + // register base class first + if ( pClassDesc->m_pBaseDesc ) + { + CPythonVM::RegisterClass( pClassDesc->m_pBaseDesc ); + } + + PyTypeObject *pnewtype = CreateClass( pClassDesc ); + + if ( pnewtype == NULL ) + return false; + + // finalize the new python type + if (PyType_Ready( pnewtype ) < 0) + return false; + + // add the new class type to the 'valve' module + Py_INCREF( pnewtype ); + + PyModule_AddObject( valveModule, pClassDesc->m_pszScriptName, (PyObject *)pnewtype ); + + m_TypeMap.Insert( (int)pClassDesc, pnewtype ); // mapping from pClassDesc to PyTypeObject needed for RegisterInstance + + m_ClassMap.Insert( (int)pnewtype, pClassDesc ); // mapping from PyTypeObject to pClassDesc needed for InitInstance constructor callback + + if ( PyDict_GetItemString( pdict, pClassDesc->m_pszScriptName ) == NULL ) + { + Assert ( false ); + return false; // class wasn't added to valve module! + } + + PyPrintError(); + + return true; + + } + + + //------------------------------------------------------------- + // auto-register instance class, and return script instance obj: + // such as a cbaseentity instance, Entities iterator list etc + //------------------------------------------------------------- + HSCRIPT RegisterInstance( ScriptClassDesc_t *pDesc, void *pInstance ) + { + + // auto-create the instance's class if not already created + if ( !CPythonVM::RegisterClass( pDesc ) ) + { + return NULL; + } + + // create a new python instance - this winds up calling InitInstance to set up the instanceContext + + // x = CEntity( pInstance ) # python code + + PyObject *pcallable = PyDict_GetItemString( m_pValveScope->GetModuleDict(), pDesc->m_pszScriptName ); // borrowed ref + scriptClassInstance_t *ppyobj = NULL; + + if ( pcallable && PyCallable_Check( pcallable ) ) + { + // create new script object + ppyobj = (scriptClassInstance_t *)PyObject_CallObject( pcallable, NULL); // new ref + ppyobj->typeTag = TYPETAG_INSTANCE; + + // make sure type name matches + if ( ppyobj->ob_type->tp_name != pDesc->m_pszScriptName ) + { + Assert ( false ); + return NULL; + } + + // fill in the instance context for the new object + + ppyobj->instanceContext.pInstance = pInstance; + ppyobj->instanceContext.pPyName = NULL; + ppyobj->instanceContext.pClassDesc = pDesc; + ppyobj->pDict = PyDict_New(); + } + + PyPrintError(); + + return (HSCRIPT)ppyobj; + + } + + //------------------------------------------------------------- + // set a unique string in the instance object. + //------------------------------------------------------------- + void SetInstanceUniqeId( HSCRIPT hInstance, const char *pszId ) + { + AssertIsInstance( hInstance ); + + // make sure this is an object type we have defined + if ( pszId && pDescFromPyObj( (PyObject *)hInstance ) ) + { + ((scriptClassInstance_t *)hInstance)->instanceContext.pPyName = PyString_FromString( pszId ); + } + + } + + //------------------------------------------------------------- + // set instance pointer to valve server object to null + // and release the python object + //------------------------------------------------------------- + void RemoveInstance( HSCRIPT hInstance ) + { + AssertIsInstance( hInstance ); + + // make sure this is an object type we have defined + if ( pDescFromPyObj( (PyObject *)hInstance ) ) + { + ReleaseScriptObject( hInstance ); + debugRemoveTrackedObject( (PyObject *) hInstance ); + } + } + + //------------------------------------------------------------- + // Return server-side object from python object + //------------------------------------------------------------- + void *GetInstanceValue( HSCRIPT hInstance, ScriptClassDesc_t *pExpectedType ) + { + AssertIsInstance( hInstance ); + + // make sure this is an object type we have defined + if ( pDescFromPyObj( (PyObject *)hInstance ) ) + { + InstanceContext_t *pContext = &( ((scriptClassInstance_t *)hInstance)->instanceContext ); + + if ( !pExpectedType || pContext->pClassDesc == pExpectedType || IsClassDerivedFrom( pContext->pClassDesc, pExpectedType ) ) + return pContext->pInstance; + } + return NULL; + } + + //------------------------------------------------------------- + // return true if derived class derives from base class. + //------------------------------------------------------------- + bool IsClassDerivedFrom( const ScriptClassDesc_t *pDerivedClass, const ScriptClassDesc_t *pBaseClass ) + { + const ScriptClassDesc_t* pType = pDerivedClass->m_pBaseDesc; + while ( pType ) + { + if ( pType == pBaseClass ) + return true; + + pType = pType->m_pBaseDesc; + } + + return false; + } + + bool GenerateUniqueKey( const char *pszRoot, char *pBuf, int nBufSize ) + { + Assert( V_strlen(pszRoot) + 32 <= nBufSize ); + Q_snprintf( pBuf, nBufSize, "%x%I64x%s", RandomInt(0, 0xfff), m_iUniqueIdSerialNumber++, pszRoot ); // random to limit key compare when serial number gets large + return true; + } + + //------------------------------------------------------------- + // return true if key has a value in scope's instance object. + // CONSIDER: if no instance object, try module object, if no module + // object, try global scope. + //------------------------------------------------------------- + virtual bool ValueExists( HSCRIPT hScope, const char *pszKey ) + { + if ( hScope == INVALID_HSCRIPT ) + return false; + + AssertIsScope( hScope ); + PyObject *pGlobals = InstanceDictFromScope( hScope ); + + if ( !pGlobals ) + // pGlobals = ModuleDictFromScope( hScope ); + return false; + + Assert ( pGlobals ); + if ( PyObject_HasAttrString( pGlobals, pszKey ) ) + return true; + + return false; + } + + bool SetValue( HSCRIPT hScope, const char *pszKey, const char *pszValue ) + { + return SetValueInternal( hScope, pszKey, NULL, pszValue ); + } + + bool SetValue( HSCRIPT hScope, const char *pszKey, const ScriptVariant_t &value ) + { + return SetValueInternal( hScope, pszKey, value, NULL ); + } + + //------------------------------------------------------------- + // set key:value pair in given scope's instance object dict. + // if hScope is NULL, set data in global scope. caller still owns + // object if is an Hscript (i.e. must free it). + // + // !!!NOTE!!!: data is not actually flushed into the instance object + // until a 'self' instance value is set in the scope. At that + // time, all previously set data will be visible in python + // on the instance object. In python code, the instance is named 'self' + // and is passed as the first param to all function calls. + //------------------------------------------------------------- + bool SetValueInternal( HSCRIPT hScope, const char *pszKey, const ScriptVariant_t &value, const char *pszValue ) + { + if ( hScope == INVALID_HSCRIPT ) + return false; + + AssertIsScope( hScope ); + CPyScope *pScope = (CPyScope *)hScope; + PyObject *pyobj; + + if ( pszValue ) + { + pyobj = PyString_FromString( pszValue ); // new reference + } + else + { + // trap special 'self' instance - save it in the CPyScope object + if ( value.m_type == FIELD_HSCRIPT ) + { + // instance object... + + if ( !V_strcmp(pszKey, "self") ) + { + // save instance in scope + PyObject *pyobj = ConvertToPyObject( value, true ); // new ref + pScope->SetInstanceObject( pyobj ); // inc ref to object + Py_XDECREF( pyobj ); // for hscript objects, caller owns the hscript within the variant, not us + + // copy scope temp dict into instance dict. + pScope->TransferTempDictToInstance(); + return true; + } + } + // set a new copy of the value in instance's dict + pyobj = ConvertToPyObject( value, true ); + + if ( value.m_type == FIELD_HSCRIPT) + { + Py_XDECREF( pyobj ); // for hscript objects, caller owns the hscript within the variant, not us + debugTrackObject( pyobj ); + } + } + + + PyObject *pGlobals; + + if ( !hScope ) + { + // set data in valve module scope + pGlobals = m_pValveScope->GetModuleDict(); + + } + else + { + // place all other data in scope's instance object dict + pGlobals = InstanceDictFromScope( hScope ); + } + + if ( !pGlobals ) + { + // instance object 'self' not yet set up in scope - add to temporary dict + pScope->SetTempDictValue( pszKey, pyobj ); + return true; + } + else + { + int ret = PyDict_SetItemString( pGlobals, pszKey, pyobj); // dict does not own the objects in it - but will decref old obj when overwritten. + + if ( ret == -1 ) + return false; + + return true; + } + } + + //------------------------------------------------------------------------------ + // Purpose: create a new python dictionary object and return wrapped in a + // scriptVariant HScript object. + //---------------------------------------------------------------------------- + void CreateTable( ScriptVariant_t &Table ) + { + PyObject *pdict = PyDict_New(); + ConvertToVariant( pdict, &Table ); + return; + } + + //------------------------------------------------------------------------------ + // Purpose: returns the number of elements in the scope's instance object dict + // Input : hScope - the table + // Output : returns the number of elements in the table + //------------------------------------------------------------------------------ + int GetNumTableEntries( HSCRIPT hScope ) + { + if ( hScope == INVALID_HSCRIPT ) + return 0; + AssertIsScope( hScope ); + PyObject *pGlobals = InstanceDictFromScope( hScope ); + + int ret = (int) PyDict_Size( pGlobals ); + + return ret; + } + + + //------------------------------------------------------------------------------ + // Purpose: Gets a key / value pair from the instance dictionary + // Input : hScope - the instance dictionary + // nInterator - the current location inside of the table. NOTE this is nota linear representation + // Output : returns the next iterator spot, otherwise -1 if error or end of table + // pKey - the key entry + // pValue - the value entry + //------------------------------------------------------------------------------ + int GetKeyValue( HSCRIPT hScope, int nIterator, ScriptVariant_t *pKey, ScriptVariant_t *pValue ) + { + if ( hScope == INVALID_HSCRIPT ) + return -1; + + PyObject *pGlobals = InstanceDictFromScope( hScope ); + + Py_ssize_t nNextIterator = (Py_ssize_t)nIterator; + + PyObject *pPyKey, *pPyValue; + int ret; + + ret = PyDict_Next( pGlobals, &nNextIterator, &pPyKey, &pPyValue ); + if ( !ret ) + { + // iteration complete + return -1; + } + + ConvertToVariant( pPyKey, pKey ); + ConvertToVariant( pPyValue, pValue ); + + return (int)nNextIterator; + + } + + + //------------------------------------------------------------- + // lookup a key value in the scope's instance dictionary + //------------------------------------------------------------- + bool GetValue( HSCRIPT hScope, const char *pszKey, ScriptVariant_t *pValue ) + { + PyObject *result = LookupObject( pszKey, hScope, false ); + if ( ConvertToVariant( result, pValue ) && (result != Py_None) ) + { + return true; + } + return false; + } + + //------------------------------------------------------------- + // remove key from the given hscope - search instance scope, + // then module scope. + //------------------------------------------------------------- + bool ClearValue( HSCRIPT hScope, const char *pszKey ) + { + if ( hScope == INVALID_HSCRIPT ) + return false; + + + PyObject *pInstGlobals = NULL; + PyObject *pModuleGlobals = NULL; + int res; + + if ( !hScope ) + { + // clear data in valve module scope + pModuleGlobals = m_pValveScope->GetModuleDict(); + } + else + { + pInstGlobals = ((CPyScope *)hScope)->GetInstanceDict(); + pModuleGlobals = ((CPyScope *)hScope)->GetModuleDict(); + } + + PyObject *pystr = PyString_FromString( pszKey ); + + if ( pInstGlobals && PyDict_Contains( pInstGlobals, pystr ) ) + { + res = PyDict_DelItemString( pInstGlobals, pszKey); + Py_XDECREF( pystr); + if ( res == -1 ) + return false; + return true; + } + + if ( pModuleGlobals && PyDict_Contains( pModuleGlobals, pystr ) ) + { + res = PyDict_DelItemString( pModuleGlobals, pszKey); + Py_XDECREF( pystr); + if ( res == -1 ) + return false; + return true; + } + + return false; + } + + //------------------------------------------------------------- + // release resources saved in script variant + //------------------------------------------------------------- + void ReleaseValue( ScriptVariant_t &value ) + { + if ( value.m_flags & SV_FREE ) + DEBUG_VARIANTCOUNT--; + + if ( value.m_type == FIELD_HSCRIPT ) + { + // drop our ref count to the python object + Py_XDECREF((PyObject *)value.m_hScript); + } + else + { + value.Free(); + } + value.m_type = FIELD_VOID; + } + + + bool RaiseException( const char *pszExceptionText ) + { + PyErr_SetString(PyExc_Exception, pszExceptionText); + return true; + } + + + virtual void DumpState() + { + // UNDONE: + /*struct CIterator : public CSQStateIterator + { + CIterator( HPYTHONVM hVM ) + { + indent = 0; + m_hVM = hVM; + m_bKey = false; + } + + void Indent() + { + for ( int i = 0; i < indent; i++) + { + Msg( " " ); + } + } + + virtual void PsuedoKey( const char *pszPsuedoKey ) + { + Indent(); + Msg( "%s: ", pszPsuedoKey ); + m_bKey = true; + } + + virtual void Key( SQObjectPtr &key ) + { + Indent(); + SQObjectPtr res; + m_hVM->ToString( key, res ); + Msg( "%s: ", res._unVal.pString->_val ); + m_bKey = true; + } + + virtual void Value( SQObjectPtr &value ) + { + if ( !m_bKey ) + { + Indent(); + } + m_bKey = false; + SQObjectPtr res; + m_hVM->ToString( value, res ); + if ( ISREFCOUNTED(value._type) ) + Msg( "%s [%d]\n", res._unVal.pString->_val, value._unVal.pRefCounted->_uiRef ); + else + Msg( "%s\n", res._unVal.pString->_val ); + } + + virtual bool BeginContained() + { + if ( m_bKey ) + { + Msg( "\n" ); + } + m_bKey = false; + Indent(); + Msg( "{\n" ); + indent++; + return true; + } + + virtual void EndContained() + { + indent--; + Indent(); + Msg( "}\n" ); + } + + int indent; + HPYTHONVM m_hVM; + bool m_bKey; + }; + + CIterator iter( m_hVM ); + m_hVM->_sharedstate->Iterate( m_hVM, &iter );*/ + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void WriteState( CUtlBuffer *pBuffer) + { + // UNDONE: +//#ifdef VPYTHON_DEBUG_SERIALIZATION +// Msg( "BEGIN WRITE\n" ); +//#endif +// m_pBuffer = pBuffer; +// sq_collectgarbage( m_hVM ); +// +// m_pBuffer->PutInt( SAVEVERSION ); +// m_pBuffer->PutInt64( m_iUniqueIdSerialNumber ); +// WriteVM( m_hVM ); +// +// m_pBuffer = NULL; +// +// SQCollectable *t = m_hVM->_sharedstate->_gc_chain; +// while(t) +// { +// t->UnMark(); +// t = t->_next; +// } +// +// m_PtrMap.Purge(); + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void ReadState( CUtlBuffer *pBuffer ) + { + // UNDONE: +//#ifdef VPYTHON_DEBUG_SERIALIZATION +//#ifdef VPYTHON_DEBUG_SERIALIZATION_HEAPCHK +// g_pMemAlloc->CrtCheckMemory(); +// int flags = g_pMemAlloc->CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ); +// g_pMemAlloc->CrtSetDbgFlag( flags | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_CHECK_CRT_DF ); +//#endif +// Msg( "BEGIN READ\n" ); +//#endif +// +// if ( pBuffer->GetInt() != SAVEVERSION ) +// { +// DevMsg( "Incompatible script version\n" ); +// return; +// } +// sq_collectgarbage( m_hVM ); +// m_hVM->_sharedstate->_gc_disableDepth++; +// m_pBuffer = pBuffer; +// int64 uniqueIdSerialNumber = m_pBuffer->GetInt64(); +// m_iUniqueIdSerialNumber = max( m_iUniqueIdSerialNumber, uniqueIdSerialNumber ); +// Verify( pBuffer->GetInt() == OT_THREAD ); +// m_PtrMap.Insert( pBuffer->GetPtr(), m_hVM ); +// ReadVM( m_hVM ); +// m_pBuffer = NULL; +// m_PtrMap.Purge(); +// m_hVM->_sharedstate->_gc_disableDepth--; +// sq_collectgarbage( m_hVM ); +// +//#ifdef VPYTHON_DEBUG_SERIALIZATION_HEAPCHK +// g_pMemAlloc->CrtSetDbgFlag( flags ); +//#endif + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void RemoveOrphanInstances() + { + + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + virtual void SetOutputCallback( ScriptOutputFunc_t pFunc ) + { + + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + virtual void SetErrorCallback( ScriptErrorFunc_t pFunc ) + { + + } + //--------------------------------------------------------------------------------- + // The main call dispatcher - dispatches to C++ functions called from python. + // Get script binding object, translate args and dispatch to actual c function call + // NOTE: this must be static! (ie - it is called without a this ptr from the proxy functions) + //--------------------------------------------------------------------------------- + static PyObject *TranslateCall( ScriptFunctionBinding_t *pVMScriptFunction, scriptClassInstance_t *pSelf, PyObject *pArgs) + { + int nActualParams = (int) PyTuple_Size( pArgs ); + + int nFormalParams = pVMScriptFunction->m_desc.m_Parameters.Count(); + CUtlVectorFixed params; + ScriptVariant_t returnValue; + + params.SetSize( nFormalParams ); + + // convert python params to vector of scriptVariant_t params as req'd by binding function + int i = 0; + PyObject *pyobj; + + if ( nActualParams ) + { + int iLimit = MIN( nActualParams, nFormalParams ); + ScriptDataType_t *pCurParamType = pVMScriptFunction->m_desc.m_Parameters.Base(); + for ( i = 0; i < iLimit; i++, pCurParamType++ ) + { + pyobj = PyTuple_GetItem( pArgs, (Py_ssize_t)i ); + + switch ( *pCurParamType ) + { + case FIELD_FLOAT: + { + if ( !PyFloat_Check( pyobj) ) + { + PyErr_SetString(PyExc_ValueError, "expected float argument"); + return NULL; + } + params[i] = PyFloat_AsDouble( pyobj ); + } + break; + case FIELD_CSTRING: + { + if ( !PyString_Check( pyobj ) ) + { + PyErr_SetString(PyExc_ValueError, "expected string argument"); + return NULL; + } + + params[i] = PyString_AsString( pyobj ); // DO NOT FREE THIS + Assert( !(params[i].m_flags &= SV_FREE ) ); + } + break; + case FIELD_VECTOR: + { + if ( pyobj->ob_type != &PyTypeVector ) + { + if ( !PyString_Check( pyobj ) ) + { + PyErr_SetString(PyExc_ValueError, "expected vector argument"); + return NULL; + } + } + + Vector *pVector = ((PyVectorInstance_t *)pyobj)->pVector; // get pointer + if ( pVector ) + { + params[i] = pVector; // DO NOT FREE THIS + Assert( !(params[i].m_flags &= SV_FREE ) ); + break; + } + } + break; + case FIELD_INTEGER: + { + if ( !PyInt_Check( pyobj ) ) + { + PyErr_SetString(PyExc_ValueError, "expected integer argument"); + return NULL; + } + params[i] = PyInt_AsLong( pyobj ); + } + break; + case FIELD_BOOLEAN: + { + if ( pyobj == Py_False ) + { + params[i] = false; + } + else if ( pyobj == Py_True ) + { + params[i] = true; + } + else + { + PyErr_SetString(PyExc_ValueError, "expected boolean argument"); + return NULL; + } + } + break; + case FIELD_CHARACTER: + { + if ( !PyString_Check( pyobj ) ) + { + PyErr_SetString(PyExc_ValueError, "expected string argument"); + return NULL; + } + const char *psz = PyString_AsString( pyobj ); + params[i] = *psz; + } + case FIELD_HSCRIPT: + { + if ( pyobj == Py_None ) + { + params[i] = (HSCRIPT)NULL; + } + else + { + if ( ((scriptClassInstance_t *)pyobj)->typeTag != TYPETAG_INSTANCE ) + { + PyErr_SetString(PyExc_ValueError, "expected HSCRIPT instance object argument"); + return NULL; + } + params[i] = (HSCRIPT)pyobj; // (HSCRIPT)PyCObject_AsVoidPtr( pyobj ); + } + break; + } + default: + break; + } + } + } + +#ifdef _DEBUG + for ( ; i < nFormalParams; i++ ) + { + Assert( params[i].IsNull() ); + } +#endif + + // get object instance pointer from pSelf if this is a method call on object + InstanceContext_t *pContext; + void *pObject; + + if ( pVMScriptFunction->m_flags & SF_MEMBER_FUNC ) + { + pContext = &( pSelf->instanceContext ); + + if ( !pContext ) + { + PyErr_SetString(PyExc_ValueError, "Accessed null instance"); + return NULL; + } + + pObject = pContext->pInstance; + + if ( !pObject ) + { + PyErr_SetString(PyExc_ValueError, "Accessed null instance"); + return NULL; + } + + if ( pContext->pClassDesc->pHelper ) + { + pObject = pContext->pClassDesc->pHelper->GetProxied( pObject ); + } + + if ( !pObject ) + { + PyErr_SetString(PyExc_ValueError, "Accessed null instance"); + return NULL; + } + } + else + { + pObject = NULL; + } + + // call the binding function, which will make the actual C function call + + (*pVMScriptFunction->m_pfnBinding)( pVMScriptFunction->m_pFunction, pObject, params.Base(), params.Count(), ( pVMScriptFunction->m_desc.m_ReturnType != FIELD_VOID ) ? &returnValue : NULL ); + + PyObject *pret = NULL; + + // use the returned scriptvariant to create a new python object + + if ( pVMScriptFunction->m_desc.m_ReturnType != FIELD_VOID ) + { + // this is the ONE case where we must actually embed a reference to the returned Vector, + // instead of creating a copy of the returned Vector. + // this is because the binding function call above auto-creates a new Vector for the return value. (see vscript_templates.h line 278 etc) + pret = ((CPythonVM *)g_pVm)->ConvertToPyObject( returnValue, false ); // create new ref + } + + + // NOTE: returning NULL and setting error state above should throw the python error... + if ( pret == NULL ) + Py_RETURN_NONE; + + return pret; + } + +private: + //---------------- + // inline Helpers + //---------------- + + //------------------------------------------------------------------------------ + // Purpose: print most recent python error to console + //------------------------------------------------------------------------------ + inline bool PyPrintError() + { + if ( PyErr_Occurred() ) + { + PyErr_Print(); + return true; + } + return false; + } + + //------------------------------------------------------------------------------ + // Purpose: given hscope, return scope's instance object's dictionary. + // returns NULL if no instance object associated with scope. + //------------------------------------------------------------------------------ + inline PyObject *InstanceDictFromScope( HSCRIPT hScope ) + { + if ( !hScope ) + return NULL; + AssertIsScope( hScope ); + Assert ( hScope != INVALID_HSCRIPT ); + return ((CPyScope *)hScope)->GetInstanceDict(); + } + + //---------------------------------------------------------- + // given hscope, return scope's module-level dictionary + //---------------------------------------------------------- + inline PyObject *ModuleDictFromScope( HSCRIPT hScope ) + { + if ( hScope ) + { + // get module's dict + AssertIsScope( hScope ); + Assert ( hScope != INVALID_HSCRIPT ); + return ((CPyScope *)hScope)->GetModuleDict(); + } + else + { + // get global scope dict + return m_pRootScope->GetModuleDict(); + } + } + + //--------------------------------------------------------------- + // given class descriptor, get our pre-defined python type object. + // return NULL if not found. + //--------------------------------------------------------------- + static inline PyTypeObject *PyTypeFromDesc( ScriptClassDesc_t *pDesc ) + + { + if ( !pDesc ) + return NULL; + + UtlHashFastHandle_t h = ((CPythonVM *)g_pVm)->m_TypeMap.Find( (int)pDesc ); + + if ( h == ((CPythonVM *)g_pVm)->m_TypeMap.InvalidHandle() ) + { + return NULL; + } + return (PyTypeObject *)(((CPythonVM *)g_pVm)->m_TypeMap.Element ( h )); + } + + //--------------------------------------------------------------- + // given python object, get class descriptor associated with object's type. + // return NULL if object is not a server-side object. + //--------------------------------------------------------------- + static inline ScriptClassDesc_t *pDescFromPyObj( PyObject *pobj ) + { + if ( ! pobj ) + return NULL; + + AssertIsPyObject( (HSCRIPT)pobj ); + PyTypeObject *ptype = pobj->ob_type; + + UtlHashFastHandle_t h = ((CPythonVM *)g_pVm)->m_ClassMap.Find( (int)ptype ); + + if ( h == ((CPythonVM *)g_pVm)->m_ClassMap.InvalidHandle() ) + { + return NULL; + } + return (ScriptClassDesc_t *)(((CPythonVM *)g_pVm)->m_ClassMap.Element ( h )); + } + + ////--------------------------------------------------------- + //// Callbacks + ////--------------------------------------------------------- + //static void PrintFunc(HPYTHONVM m_hVM,const SQChar* s,...) + //{ + // Msg( CFmtStr( &s ) ); + //} + +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// static SQInteger ReleaseHook( SQUserPointer p, SQInteger size ) +// { +// InstanceContext_t *pInstanceContext = (InstanceContext_t *)p; +// pInstanceContext->pClassDesc->m_pfnDestruct( pInstanceContext->pInstance ); +// delete pInstanceContext; +// return 0; +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// static SQInteger ExternalInstanceReleaseHook( SQUserPointer p, SQInteger size ) +// { +// InstanceContext_t *pInstanceContext = (InstanceContext_t *)p; +// delete pInstanceContext; +// return 0; +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// static SQInteger GetFunctionSignature( HPYTHONVM hVM ) +// { +// StackHandler sa(hVM); +// if ( sa.GetParamCount() != 3 ) +// { +// return 0; +// } +// +// HPYOBJECT hFunction = sa.GetObjectHandle( 2 ); +// if ( !sq_isclosure( hFunction ) ) +// { +// return 0; +// } +// +// std::string result; +// const char *pszName = sa.GetString( 3 ); +// SQClosure *pClosure = hFunction._unVal.pClosure; +// SQFunctionProto *pProto = pClosure->_function._unVal.pFunctionProto; +// +// result += "function "; +// if ( pszName && *pszName ) +// { +// result += pszName; +// } +// else if ( sq_isstring( pProto->_name ) ) +// { +// result += pProto->_name._unVal.pString->_val; +// } +// else +// { +// result += ""; +// } +// result += "("; +// +// for ( int i = 1; i < pProto->_nparameters; i++ ) +// { +// if ( i != 1 ) +// result += ", "; +// if ( sq_isstring( pProto->_parameters[i] ) ) +// { +// result += pProto->_parameters[i]._unVal.pString->_val; +// } +// else +// { +// result += "arg"; +// } +// } +// result += ")"; +// +// sa.Return( result.c_str() ); +// +// return 1; +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// static SQInteger GetDeveloper( HPYTHONVM hVM ) +// { +// StackHandler sa(hVM); +// sa.Return( ((CPythonVM *)hVM->_sharedstate->m_pOwnerData)->developer.GetInt() ); +// return 1; +// } +// + //------------------------------------------------------------- + // called from python directly during object construction. + // same as class __init__ function - init the member data for server object instance + // If the context has a constructor, call it to create the server object instance. + // args and keywords params currently ignored. + //------------------------------------------------------------- + static int InitInstance( scriptClassInstance_t *pSelf, PyObject *args, PyObject *kwds ) + { + InstanceContext_t *pInstanceContext = &( pSelf->instanceContext ); + + pInstanceContext->pInstance = NULL; + pInstanceContext->pClassDesc = NULL; + pInstanceContext->pPyName = NULL; + pSelf->pDict = PyDict_New(); + + //((scriptClassInstance_t *)pSelf)->typeTag = TYPETAG_INSTANCE; + + ScriptClassDesc_t *pDesc = pDescFromPyObj( (PyObject *)pSelf ); + + if ( pDesc ) + { + pInstanceContext->pClassDesc = pDesc; + + if ( pDesc->m_pfnConstruct ) + { + pInstanceContext->pInstance = pDesc->m_pfnConstruct(); + } + } + else + { + return -1; + } + + + return 0; + } + + //---------------------------------------------------------------------- + // called from python directly during object destruction (tp_dealloc) + // call destructor on the server object instance, then release the python object + //---------------------------------------------------------------------- + static void FreeInstance( scriptClassInstance_t *pSelf ) + { + AssertIsInstance( (HSCRIPT)pSelf ); + InstanceContext_t *pcontext = &( pSelf->instanceContext ); + + ScriptClassDesc_t *pDesc = pDescFromPyObj( (PyObject *)pSelf ); + + if ( pDesc ) + { + if ( pDesc->m_pfnDestruct ) + { + pDesc->m_pfnDestruct( pcontext->pInstance ); + } + } + + pcontext->pInstance = NULL; + + Py_XDECREF( pcontext->pPyName ); + Py_XDECREF( pSelf->pDict ); // will decref all objs held in dict + + pSelf->ob_type->tp_free( (PyObject *)pSelf ); + + } + + //------------------------------------------------------------- + // UNDONE: script execution throttle - equivalent in python? + + //static int QueryContinue( HPYTHONVM hVM ) + //{ + // CPythonVM *pVM = ((CPythonVM *)hVM->_sharedstate->m_pOwnerData); + // if ( !pVM->m_hDbg ) + // { + // if ( pVM->m_TimeStartExecute != 0.0f && Plat_FloatTime() - pVM->m_TimeStartExecute > 0.03f ) + // { + // DevMsg( "Script running too long, terminating\n" ); + // // @TODO: Mark the offending closure so that it won't be executed again [5/13/2008 tom] + // return SQ_QUERY_BREAK; + // } + // } + // return SQ_QUERY_CONTINUE; + //} + + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + static PyObject *InstanceIsValid( PyObject *pSelf, PyObject *pArgs ) + { + // UNDONE: + //InstanceContext_t *pContext = (InstanceContext_t *)pSelf; + // + //if ( pContext && pContext->pInstance ) + // Py_RETURN_TRUE; + //else + // Py_RETURN_FALSE; + } + + //------------------------------------------------------------- + // allow C++ function to be called from python - + // function parameter binding is described by + // ScriptFunctionBinding_t + //------------------------------------------------------------- + void RegisterFunctionGuts( ScriptFunctionBinding_t *pScriptFunction ) + { + PyObject *pdict = m_pValveScope->GetModuleDict(); + + if ( PyDict_GetItemString( pdict, pScriptFunction->m_desc.m_pszScriptName ) != NULL ) + return; // already registered + + + // alloc space for small (2 element) array of PyMethodDefs - elements must not move in memory. + PyMethodDef *pmethod = new PyMethodDef[2]; + + // save pointers so we can free 'em all later + Assert (m_iMethodDef < MAX_VALVE_FUNCTIONS_EXPORTED ); + m_rgpMethodDefs[m_iMethodDef++] = pmethod; + + // create NULL semaphore at tail of list + PyMethodDef *pm = &(pmethod[1]); + + pm->ml_name = NULL; + pm->ml_meth = NULL; + pm->ml_flags = 0; + pm->ml_doc = NULL; + + // fill the python method def + pm = &(pmethod[0]); + + pm->ml_name = pScriptFunction->m_desc.m_pszScriptName; + pm->ml_flags = METH_VARARGS; + pm->ml_doc = pScriptFunction->m_desc.m_pszDescription; + + int proxyId = GetNewProxyId(); + SetProxyBinding( proxyId, pScriptFunction ); + + // the function callback chain - python calls Translate_XXX -> calls TranslateCall -> calls binding function -> actual function. + pm->ml_meth = GetProxyFunction( proxyId ); + + Py_InitModule3("valve", pmethod, "Import module for access to all exported Valve methods."); + + // set up parameter checking + + char szTypeMask[64]; + + if ( pScriptFunction->m_desc.m_Parameters.Count() > ARRAYSIZE(szTypeMask) - 1 ) + { + AssertMsg1( 0, "Too many arguments for script function %s\n", pScriptFunction->m_desc.m_pszFunction ); + return; + } + + // UNDONE: implement help - function param type documenting in python + + //szTypeMask[0] = '.'; + //char *pCurrent = &szTypeMask[1]; + //for ( int i = 0; i < pScriptFunction->m_desc.m_Parameters.Count(); i++, pCurrent++ ) + //{ + // switch ( pScriptFunction->m_desc.m_Parameters[i] ) + // { + // case FIELD_CSTRING: + // *pCurrent = 's'; + // break; + // case FIELD_FLOAT: + // case FIELD_INTEGER: + // *pCurrent = 'n'; + // break; + // case FIELD_BOOLEAN: + // *pCurrent = 'b'; + // break; + + // case FIELD_VECTOR: + // *pCurrent = 'x'; + // break; + + // case FIELD_HSCRIPT: + // *pCurrent = '.'; + // break; + + // case FIELD_CHARACTER: + // default: + // *pCurrent = FIELD_VOID; + // AssertMsg( 0 , "Not supported" ); + // break; + // } + //} + //Assert( pCurrent - szTypeMask < ARRAYSIZE(szTypeMask) - 1 ); + //*pCurrent = 0; + + //sq_pushstring( m_hVM, pScriptFunction->m_desc.m_pszScriptName, -1 ); + //ScriptFunctionBinding_t **pVMScriptFunction = (ScriptFunctionBinding_t **)sq_newuserdata(m_hVM, sizeof(ScriptFunctionBinding_t *)); + //*pVMScriptFunction = pScriptFunction; + //sq_newclosure( m_hVM, &TranslateCall, 1 ); + //HPYOBJECT hFunction; + //sq_getstackobj( m_hVM, -1, &hFunction ); + //sq_setnativeclosurename(m_hVM, -1, pScriptFunction->m_desc.m_pszScriptName ); + //sq_setparamscheck( m_hVM, pScriptFunction->m_desc.m_Parameters.Count() + 1, szTypeMask ); + //sq_createslot( m_hVM, -3 ); + + //if ( developer.GetInt() ) + //{ + // const char *pszHide = SCRIPT_HIDE; + // if ( !pScriptFunction->m_desc.m_pszDescription || *pScriptFunction->m_desc.m_pszDescription != *pszHide ) + // { + // std::string name; + // std::string signature; + + // if ( pClassDesc ) + // { + // name += pClassDesc->m_pszScriptName; + // name += "::"; + // } + + // name += pScriptFunction->m_desc.m_pszScriptName; + + // signature += FieldTypeToString( pScriptFunction->m_desc.m_ReturnType ); + // signature += ' '; + // signature += name; + // signature += '('; + // for ( int i = 0; i < pScriptFunction->m_desc.m_Parameters.Count(); i++ ) + // { + // if ( i != 0 ) + // { + // signature += ", "; + // } + + // signature+= FieldTypeToString( pScriptFunction->m_desc.m_Parameters[i] ); + // } + // signature += ')'; + + // sq_pushobject( m_hVM, LookupObject( "RegisterFunctionDocumentation", NULL, false ) ); + // sq_pushroottable( m_hVM ); + // sq_pushobject( m_hVM, hFunction ); + // sq_pushstring( m_hVM, name.c_str(), name.length() ); + // sq_pushstring( m_hVM, signature.c_str(), signature.length() ); + // sq_pushstring( m_hVM, pScriptFunction->m_desc.m_pszDescription, -1 ); + // sq_call( m_hVM, 5, false, /*false*/ true ); + // sq_pop( m_hVM, 1 ); + // } + //} + + return; + } + + //------------------------------------------------------------- + // drop our ref count on the script object + //------------------------------------------------------------- + void ReleaseScriptObject( HSCRIPT hScript ) + { + AssertIsPyObject( hScript ); + Py_XDECREF( (PyObject *)hScript ); + + } + + //------------------------------------------------------------- + // create a new python object from the script variant + // UNLESS variant is an HSCRIPT - in this case, just returns + // the embedded PyObject * with incremented ref count. + // if bAllocNewVector is true, create a new C++ Vector, + // otherwise, embed a reference to the variant's Vector, within new py object. + // NOTE: all references will be freed when the py object is freed! + //------------------------------------------------------------- + PyObject *ConvertToPyObject( const ScriptVariant_t &value, bool bAllocNewVector ) + { + switch ( value.m_type ) + { + case FIELD_VOID: Py_RETURN_NONE; + case FIELD_FLOAT: return PyFloat_FromDouble( (double)value.m_float ); + case FIELD_CSTRING: + if ( value.IsNull() ) + Py_RETURN_NONE; + + return PyString_FromStringAndSize( value, (Py_ssize_t) strlen( value.m_pszString )); + case FIELD_VECTOR: + { + PyObject *pretObj; + if ( !bAllocNewVector ) + { + // Vector was alloc'd by caller, and in this (rare) case we are expected to free it. + // create a python vector object that references the variant's vector object + // NOTE: the variant's vector object will be deleted when the python object is deleted. + DEBUG_VECCOUNT++; + pretObj = CreatePyVector( (Vector *)value.m_pVector ); + } + else + { + // create new python vector object and copy from scriptvariant data. must be freed by caller + pretObj = CreatePyVector( NULL ); + *(((PyVectorInstance_t*)pretObj)->pVector) = *((Vector *)value.m_pVector); // copy operator + } + return pretObj; + } + case FIELD_INTEGER: return PyInt_FromLong( value.m_int ); + case FIELD_BOOLEAN: return PyBool_FromLong( value.m_bool ); + case FIELD_CHARACTER: + { + char sz[2]; + sz[0] = value.m_char; + sz[1] = 0; + return PyString_FromStringAndSize( sz, (Py_ssize_t)1 ); + } + case FIELD_HSCRIPT: + { + if ( value.m_hScript ) + { + PyObject *pyobj = (PyObject *)value.m_hScript; //PyCObject_FromVoidPtr((void *)value.m_hScript, NULL); + Py_XINCREF( pyobj ); + return pyobj; + } + else + { + Py_RETURN_NONE; + } + } + } + Py_RETURN_NONE; + } + + //------------------------------------------------------------- + // fill variant struct with appropriate value from python object + // NOTE: does not decref the python object. + //------------------------------------------------------------- + bool ConvertToVariant( PyObject* object, ScriptVariant_t *pReturn ) + { + AssertIsPyObject( (HSCRIPT)object ); + + if ( object == Py_None ) + { + pReturn->m_type = FIELD_VOID; + } + else if ( PyLong_CheckExact( object ) ) + { + *pReturn = (int)PyLong_AsLong( object ); // UNDONE: need error checking for overflow - will return NULL + } + else if ( PyInt_CheckExact( object ) ) + { + *pReturn = (int)PyInt_AS_LONG( object ); // No error checking is performed, since we started with int + } + else if ( PyFloat_CheckExact( object ) ) + { + *pReturn = (float)PyFloat_AS_DOUBLE( object ); // no error checking since we started with float + } + else if ( PyBool_Check( object ) ) + { + if ( object == Py_True ) + *pReturn = true; + else + *pReturn = false; + } + else if ( PyString_Check( object ) ) + { + // create a new string in the variant + char *buffer; + Py_ssize_t length; + + PyString_AsStringAndSize( object, &buffer, &length); + + int size = (int)length + 1; + pReturn->m_type = FIELD_CSTRING; + pReturn->m_pszString = new char[size]; + V_memcpy( (void *)pReturn->m_pszString, buffer, size ); + pReturn->m_flags |= SV_FREE; + DEBUG_VARIANTCOUNT++; + Assert( DEBUG_VARIANTCOUNT < 1000 ); // if this fails, server is likely not freeing return values from python fn calls each frame + } + else if ( IsPyVector( object ) ) + { + // create a new vector in the variant that copies the object's vector data + Vector *pVector = ((PyVectorInstance_t *)object)->pVector; + + pReturn->m_type = FIELD_VECTOR; + pReturn->m_pVector = new Vector( *((Vector *)pVector) ); + pReturn->m_flags |= SV_FREE; + DEBUG_VARIANTCOUNT++; + Assert( DEBUG_VARIANTCOUNT < 1000 ); // if this fails, server is likely not freeing return values from python fn calls each frame + } + else + { + // save the actual object pointer + pReturn->m_type = FIELD_HSCRIPT; + pReturn->m_hScript =(HSCRIPT)object; // PyCObject_AsVoidPtr( object ); + return false; // don't free object + } + return true; // ok to free python object + + } + + +// +// //------------------------------------------------------------------------- +// // UNDONE: Serialization for save/restore +// //------------------------------------------------------------------------- +// enum +// { +// SAVEVERSION = 2 +// }; +// +// void WriteObject( const SQObjectPtr &object ) +// { +// switch ( object._type ) +// { +// case OT_NULL: +// m_pBuffer->PutInt( OT_NULL ); +// break; +// case OT_INTEGER: +// m_pBuffer->PutInt( OT_INTEGER ); +// m_pBuffer->PutInt( object._unVal.nInteger ); +// break; +// case OT_FLOAT: +// m_pBuffer->PutInt( OT_FLOAT ); +// m_pBuffer->PutFloat( object._unVal.fFloat); +// break; +// case OT_BOOL: +// m_pBuffer->PutInt( OT_BOOL ); +// m_pBuffer->PutInt( object._unVal.nInteger ); +// break; +// case OT_STRING: +// m_pBuffer->PutInt( OT_STRING ); +// m_pBuffer->PutInt( object._unVal.pString->_len ); +// m_pBuffer->PutString( object._unVal.pString->_val ); +// break; +// case OT_TABLE: WriteTable( object._unVal.pTable ); break; +// case OT_ARRAY: WriteArray( object._unVal.pArray ); break; +// case OT_USERDATA: WriteUserData( object._unVal.pUserData ); break; +// case OT_CLOSURE: WriteClosure( object._unVal.pClosure ); break; +// case OT_NATIVECLOSURE: WriteNativeClosure( object._unVal.pNativeClosure ); break; +// case OT_GENERATOR: WriteGenerator( object._unVal.pGenerator ); break; +// case OT_USERPOINTER: WriteUserPointer( object._unVal.pUserPointer ); break; +// case OT_THREAD: WriteVM( object._unVal.pThread ); break; +// case OT_FUNCPROTO: WriteFuncProto( object._unVal.pFunctionProto ); break; +// case OT_CLASS: WriteClass( object._unVal.pClass ); break; +// case OT_INSTANCE: WriteInstance( object._unVal.pInstance ); break; +// case OT_WEAKREF: WriteWeakRef( object._unVal.pWeakRef ); break; +// default: Assert( 0 ); break; +// } +// +//#ifdef VPYTHON_DEBUG_SERIALIZATION +// SQObjectPtr res; +// m_hVM->ToString( object, res ); +// Msg( "%d: %s\n", m_pBuffer->TellPut(), res._unVal.pString->_val ); +//#endif +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// void WriteVM( PYVM *pVM ) +// { +// unsigned i; +// +// m_pBuffer->PutInt( OT_THREAD ); +// m_pBuffer->PutPtr( pVM ); +// +// if ( pVM->_uiRef & MARK_FLAG ) +// return; +// pVM->_uiRef |= MARK_FLAG; +// +// WriteObject( pVM->_roottable ); +// m_pBuffer->PutInt( pVM->_top ); +// m_pBuffer->PutInt( pVM->_stackbase ); +// m_pBuffer->PutUnsignedInt( pVM->_stack.size() ); +// for( i = 0; i < pVM->_stack.size(); i++ ) +// { +// WriteObject( pVM->_stack[i] ); +// } +// m_pBuffer->PutUnsignedInt( pVM->_vargsstack.size() ); +// for( i = 0; i < pVM->_vargsstack.size(); i++ ) +// { +// WriteObject( pVM->_vargsstack[i] ); +// } +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// void WriteArray( SQArray *pArray ) +// { +// m_pBuffer->PutInt( OT_ARRAY ); +// m_pBuffer->PutPtr( pArray ); +// +// if ( pArray->_uiRef & MARK_FLAG ) +// return; +// pArray->_uiRef |= MARK_FLAG; +// +// int len = pArray->_values.size(); +// m_pBuffer->PutInt( len ); +// for ( int i = 0; i < len; i++ ) +// WriteObject( pArray->_values[i] ); +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// void WriteTable( SQTable *pTable ) +// { +// m_pBuffer->PutInt( OT_TABLE ); +// m_pBuffer->PutPtr( pTable ); +// +// if ( pTable->_uiRef & MARK_FLAG ) +// return; +// pTable->_uiRef |= MARK_FLAG; +// +// m_pBuffer->PutInt( pTable->_delegate != NULL ); +// if ( pTable->_delegate ) +// { +// WriteObject( pTable->_delegate ); +// } +// +// int len = pTable->_numofnodes; +// m_pBuffer->PutInt( len ); +// for(int i = 0; i < len; i++) +// { +// WriteObject( pTable->_nodes[i].key ); +// WriteObject( pTable->_nodes[i].val ); +// } +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// void WriteClass( SQClass *pClass ) +// { +// m_pBuffer->PutInt( OT_CLASS ); +// m_pBuffer->PutPtr( pClass ); +// +// if ( !pClass || ( pClass->_uiRef & MARK_FLAG ) ) +// return; +// pClass->_uiRef |= MARK_FLAG; +// +// bool bIsNative = ( pClass->_typetag != NULL ); +// unsigned i; +// if ( !bIsNative ) +// { +// for( i = 0; i < pClass->_methods.size(); i++) +// { +// if ( sq_isnativeclosure( pClass->_methods[i].val ) ) +// { +// bIsNative = true; +// break; +// } +// } +// } +// m_pBuffer->PutInt( bIsNative ); +// if ( !bIsNative ) +// { +// m_pBuffer->PutInt( pClass->_base != NULL ); +// if ( pClass->_base ) +// { +// WriteObject( pClass->_base ); +// } +// +// WriteObject( pClass->_members ); +// WriteObject( pClass->_attributes ); +// m_pBuffer->PutInt( pClass->_defaultvalues.size() ); +// for( i = 0; i< pClass->_defaultvalues.size(); i++) +// { +// WriteObject(pClass->_defaultvalues[i].val); +// WriteObject(pClass->_defaultvalues[i].attrs); +// } +// m_pBuffer->PutInt( pClass->_methods.size() ); +// for( i = 0; i < pClass->_methods.size(); i++) +// { +// WriteObject(pClass->_methods[i].val); +// WriteObject(pClass->_methods[i].attrs); +// } +// m_pBuffer->PutInt( pClass->_metamethods.size() ); +// for( i = 0; i < pClass->_metamethods.size(); i++) +// { +// WriteObject(pClass->_metamethods[i]); +// } +// } +// else +// { +// if ( pClass->_typetag ) +// { +// if ( pClass->_typetag == TYPETAG_VECTOR ) +// { +// m_pBuffer->PutString( "Vector" ); +// } +// else +// { +// ScriptClassDesc_t *pDesc = (ScriptClassDesc_t *)pClass->_typetag; +// m_pBuffer->PutString( pDesc->m_pszScriptName ); +// } +// } +// else +// { +// // Have to grovel for the name +// SQObjectPtr key; +// if ( FindKeyForObject( m_hVM->_roottable, pClass, key ) ) +// { +// m_pBuffer->PutString( key._unVal.pString->_val ); +// } +// else +// { +// Assert( 0 ); +// m_pBuffer->PutString( "" ); +// } +// } +// } +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// void WriteInstance( SQInstance *pInstance ) +// { +// m_pBuffer->PutInt( OT_INSTANCE ); +// m_pBuffer->PutPtr( pInstance ); +// +// if ( pInstance->_uiRef & MARK_FLAG ) +// return; +// pInstance->_uiRef |= MARK_FLAG; +// +// WriteObject( pInstance->_class ); +// +// unsigned nvalues = pInstance->_class->_defaultvalues.size(); +// m_pBuffer->PutInt( nvalues ); +// for ( unsigned i =0; i< nvalues; i++ ) +// { +// WriteObject( pInstance->_values[i] ); +// } +// +// m_pBuffer->PutPtr( pInstance->_class->_typetag ); +// +// if ( pInstance->_class->_typetag ) +// { +// if ( pInstance->_class->_typetag == TYPETAG_VECTOR ) +// { +// Vector *pVector = (Vector *)pInstance->_userpointer; +// m_pBuffer->PutFloat( pVector->x ); +// m_pBuffer->PutFloat( pVector->y ); +// m_pBuffer->PutFloat( pVector->z ); +// } +// else +// { +// InstanceContext_t *pContext = ((InstanceContext_t *)pInstance->_userpointer); +// WriteObject( pContext->name ); +// m_pBuffer->PutPtr( pContext->pInstance ); +// } +// } +// else +// { +// WriteUserPointer( NULL ); +// } +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// void WriteGenerator( SQGenerator *pGenerator ) +// { +// ExecuteOnce( Msg( "Save load of generators not well tested. caveat emptor\n" ) ); +// WriteObject(pGenerator->_closure); +// +// m_pBuffer->PutInt( OT_GENERATOR ); +// m_pBuffer->PutPtr( pGenerator ); +// +// if ( pGenerator->_uiRef & MARK_FLAG ) +// return; +// pGenerator->_uiRef |= MARK_FLAG; +// +// WriteObject( pGenerator->_closure ); +// m_pBuffer->PutInt( pGenerator->_stack.size() ); +// for(SQUnsignedInteger i = 0; i < pGenerator->_stack.size(); i++) WriteObject(pGenerator->_stack[i]); +// m_pBuffer->PutInt( pGenerator->_vargsstack.size() ); +// for(SQUnsignedInteger j = 0; j < pGenerator->_vargsstack.size(); j++) WriteObject(pGenerator->_vargsstack[j]); +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// void WriteClosure( SQClosure *pClosure ) +// { +// m_pBuffer->PutInt( OT_CLOSURE ); +// m_pBuffer->PutPtr( pClosure ); +// if ( pClosure->_uiRef & MARK_FLAG ) +// return; +// pClosure->_uiRef |= MARK_FLAG; +// +// WriteObject( pClosure->_function ); +// WriteObject( pClosure->_env ); +// +// m_pBuffer->PutInt( pClosure->_outervalues.size() ); +// for(SQUnsignedInteger i = 0; i < pClosure->_outervalues.size(); i++) WriteObject(pClosure->_outervalues[i]); +// m_pBuffer->PutInt( pClosure->_defaultparams.size() ); +// for(SQUnsignedInteger i = 0; i < pClosure->_defaultparams.size(); i++) WriteObject(pClosure->_defaultparams[i]); +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// void WriteNativeClosure( SQNativeClosure *pNativeClosure ) +// { +// m_pBuffer->PutInt( OT_NATIVECLOSURE ); +// m_pBuffer->PutPtr( pNativeClosure ); +// +// if ( pNativeClosure->_uiRef & MARK_FLAG ) +// return; +// pNativeClosure->_uiRef |= MARK_FLAG; +// +// WriteObject( pNativeClosure->_name ); +// return; +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// void WriteUserData( SQUserData *pUserData ) +// { +// m_pBuffer->PutInt( OT_USERDATA ); +// m_pBuffer->PutPtr( pUserData ); +// +// if ( pUserData->_uiRef & MARK_FLAG ) +// return; +// pUserData->_uiRef |= MARK_FLAG; +// +// // Need to call back or something. Unsure, TBD. [4/3/2008 tom] +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// void WriteUserPointer( SQUserPointer pUserPointer ) +// { +// m_pBuffer->PutInt( OT_USERPOINTER ); +// // Need to call back or something. Unsure, TBD. [4/3/2008 tom] +// m_pBuffer->PutPtr( pUserPointer ); +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// static SQInteger SqWriteFunc(SQUserPointer up,SQUserPointer data, SQInteger size) +// { +// CPythonVM *pThis = (CPythonVM *)up; +// pThis->m_pBuffer->Put( data, size ); +// return size; +// } +// +// void WriteFuncProto( SQFunctionProto *pFuncProto ) +// { +// m_pBuffer->PutInt( OT_FUNCPROTO ); +// m_pBuffer->PutPtr( pFuncProto ); +// +// // Using the map to track these as they're not collectables +// if ( m_PtrMap.Find( pFuncProto ) != m_PtrMap.InvalidIndex() ) +// { +// return; +// } +// m_PtrMap.Insert( pFuncProto, pFuncProto ); +// +// pFuncProto->Save( m_hVM, this, &SqWriteFunc ); +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// void WriteWeakRef( SQWeakRef *pWeakRef ) +// { +// m_pBuffer->PutInt( OT_WEAKREF ); +// WriteObject( pWeakRef->_obj ); +// } +// +// //-------------------------------------------------------- +// template +// bool BeginRead( T **ppOld, T **ppNew ) +// { +// *ppOld = (T *)m_pBuffer->GetPtr(); +// if ( *ppOld ) +// { +// int iNew = m_PtrMap.Find( *ppOld ); +// if ( iNew != m_PtrMap.InvalidIndex() ) +// { +// *ppNew = (T*)m_PtrMap[iNew]; +// return false; +// } +// } +// *ppNew = NULL; +// return true; +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// void MapPtr( void *pOld, void *pNew ) +// { +// Assert( m_PtrMap.Find( pOld ) == m_PtrMap.InvalidIndex() ); +// m_PtrMap.Insert( pOld, pNew ); +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// bool ReadObject( SQObjectPtr &objectOut, const char *pszName = NULL ) +// { +// SQObject object; +// bool bResult = true; +// object._type = (SQObjectType)m_pBuffer->GetInt(); +// if ( _RAW_TYPE(object._type) < _RT_TABLE ) +// { +// switch ( object._type ) +// { +// case OT_NULL: +// object._unVal.pUserPointer = 0; +// break; +// case OT_INTEGER: +// object._unVal.nInteger = m_pBuffer->GetInt(); +// break; +// case OT_FLOAT: +// object._unVal.fFloat = m_pBuffer->GetFloat(); +// break; +// case OT_BOOL: +// object._unVal.nInteger = m_pBuffer->GetInt(); +// break; +// case OT_STRING: +// { +// int len = m_pBuffer->GetInt(); +// char *pString = (char *)stackalloc( len + 1 ); +// m_pBuffer->GetString( pString, len + 1 ); +// pString[len] = 0; +// object._unVal.pString = SQString::Create( m_hVM->_sharedstate, pString, len ); +// break; +// } +// default: +// Assert( 0 ); +// break; +// } +// } +// else +// { +// switch ( object._type ) +// { +// case OT_TABLE: +// { +// object._unVal.pTable = ReadTable(); +// break; +// } +// case OT_ARRAY: +// { +// object._unVal.pArray = ReadArray(); +// break; +// } +// case OT_USERDATA: +// { +// object._unVal.pUserData = ReadUserData(); +// break; +// } +// case OT_CLOSURE: +// { +// object._unVal.pClosure = ReadClosure(); +// break; +// } +// case OT_NATIVECLOSURE: +// { +// object._unVal.pNativeClosure = ReadNativeClosure(); +// break; +// } +// case OT_GENERATOR: +// { +// object._unVal.pGenerator = ReadGenerator(); +// break; +// } +// case OT_USERPOINTER: +// { +// object._unVal.pUserPointer = ReadUserPointer(); +// break; +// } +// case OT_THREAD: +// { +// object._unVal.pThread = ReadVM(); +// break; +// } +// case OT_FUNCPROTO: +// { +// object._unVal.pFunctionProto = ReadFuncProto(); +// break; +// } +// case OT_CLASS: +// { +// object._unVal.pClass = ReadClass(); +// break; +// } +// case OT_INSTANCE: +// { +// object._unVal.pInstance = ReadInstance(); +// if ( !object._unVal.pInstance ) +// { +// // Look for a match in the current root table +// HPYOBJECT hExistingObject = LookupObject( pszName, NULL, false ); +// if ( sq_isinstance( hExistingObject ) ) +// { +// object._unVal.pInstance = hExistingObject._unVal.pInstance; +// } +// } +// break; +// } +// case OT_WEAKREF: +// { +// object._unVal.pWeakRef = ReadWeakRef(); +// break; +// } +// default: +// { +// object._unVal.pUserPointer = NULL; +// Assert( 0 ); +// } +// } +// if ( !object._unVal.pUserPointer ) +// { +// DevMsg( "Failed to restore a Python object of type %s\n", SQTypeToString( object._type ) ); +// object._type = OT_NULL; +// bResult = false; +// } +// } +// +//#ifdef VPYTHON_DEBUG_SERIALIZATION +// lastType = object._type; +// SQObjectPtr res; +// if ( ISREFCOUNTED(object._type) ) +// object._unVal.pRefCounted->_uiRef++; +// m_hVM->ToString( object, res ); +// if ( ISREFCOUNTED(object._type) ) +// object._unVal.pRefCounted->_uiRef--; +// Msg( "%d: %s [%d]\n", m_pBuffer->TellGet(), res._unVal.pString->_val, ( ISREFCOUNTED(object._type) ) ? object._unVal.pRefCounted->_uiRef : -1 ); +//#ifdef VPYTHON_DEBUG_SERIALIZATION_HEAPCHK +// _heapchk(); +//#endif +//#endif +// objectOut = object; +// return bResult; +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// PYVM *ReadVM() +// { +// PYVM *pVM = sq_newthread( m_hVM, MIN_STACK_OVERHEAD + 2 ); +// m_hVM->Pop(); +// return pVM; +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// void ReadVM( PYVM *pVM ) +// { +// unsigned i; +// +// ReadObject( pVM->_roottable ); +// pVM->_top = m_pBuffer->GetInt(); +// pVM->_stackbase = m_pBuffer->GetInt(); +// unsigned stackSize = m_pBuffer->GetUnsignedInt(); +// pVM->_stack.resize( stackSize ); +// for( i = 0; i < pVM->_stack.size(); i++ ) +// { +// ReadObject( pVM->_stack[i] ); +// } +// stackSize = m_pBuffer->GetUnsignedInt(); +// for( i = 0; i < pVM->_vargsstack.size(); i++ ) +// { +// ReadObject( pVM->_vargsstack[i] ); +// } +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- +// SQTable *ReadTable() +// { +// SQTable *pOld; +// SQTable *pTable; +// +// if ( !BeginRead( &pOld, &pTable ) ) +// { +// return pTable; +// } +// +// pTable = SQTable::Create(_ss(m_hVM), 0); +// +// MapPtr( pOld, pTable ); +// +// if ( m_pBuffer->GetInt() ) +// { +// SQObjectPtr delegate; +// ReadObject( delegate ); +// pTable->SetDelegate( delegate._unVal.pTable ); +// } +// else +// { +// pTable->_delegate = NULL; +// } +// int n = m_pBuffer->GetInt(); +// while ( n-- ) +// { +// SQObjectPtr key, value; +// ReadObject( key ); +// if ( !ReadObject( value, ( key._type == OT_STRING ) ? key._unVal.pString->_val : NULL ) ) +// { +// DevMsg( "Failed to read Python table entry %s", ( key._type == OT_STRING ) ? key._unVal.pString->_val : SQTypeToString( key._type ) ); +// } +// if ( key._type != OT_NULL ) +// { +// pTable->NewSlot( key, value ); +// } +// } +// return pTable; +// } +// +// //------------------------------------------------------------- +// // +// //------------------------------------------------------------- + //SQArray *ReadArray() + //{ + // SQArray *pOld; + // SQArray *pArray; + // if ( !BeginRead( &pOld, &pArray ) ) + // { + // return pArray; + // } + + // pArray = SQArray::Create(_ss(m_hVM), 0); + + // MapPtr( pOld, pArray ); + + // int n = m_pBuffer->GetInt(); + // pArray->Reserve( n ); + + // while ( n-- ) + // { + // SQObjectPtr value; + // ReadObject( value ); + // pArray->Append( value ); + // } + // return pArray; + //} + + ////------------------------------------------------------------- + //// + ////------------------------------------------------------------- + //SQClass *ReadClass() + //{ + // SQClass *pOld; + // SQClass *pClass; + // if ( !BeginRead( &pOld, &pClass ) ) + // { + // return pClass; + // } + + // SQClass *pBase = NULL; + // bool bIsNative = !!m_pBuffer->GetInt(); + // // If it's not a C++ defined type... + // if ( !bIsNative ) + // { + // if ( m_pBuffer->GetInt() ) + // { + // SQObjectPtr base; + // ReadObject( base ); + // pBase = base._unVal.pClass; + // } + + // SQClass *pClass = SQClass::Create( _ss(m_hVM), pBase ); + // MapPtr( pOld, pClass ); + + // SQObjectPtr members; + // ReadObject( members ); + // pClass->_members->Release(); + // pClass->_members = members._unVal.pTable; + // __ObjAddRef( members._unVal.pTable ); + + // ReadObject( pClass->_attributes ); + // unsigned i, n; + + // n = m_pBuffer->GetUnsignedInt(); + // pClass->_defaultvalues.resize( n ); + // for ( i = 0; i < n; i++ ) + // { + // ReadObject(pClass->_defaultvalues[i].val); + // ReadObject(pClass->_defaultvalues[i].attrs); + // } + + // n = m_pBuffer->GetUnsignedInt(); + // pClass->_methods.resize( n ); + // for ( i = 0; i < n; i++ ) + // { + // ReadObject(pClass->_methods[i].val); + // ReadObject(pClass->_methods[i].attrs); + // } + + // n = m_pBuffer->GetUnsignedInt(); + // pClass->_metamethods.resize( n ); + // for ( i = 0; i < n; i++ ) + // { + // ReadObject(pClass->_metamethods[i]); + // } + // return pClass; + // } + // else + // { + // char *pszName = (char *)stackalloc( 1024 ); + // m_pBuffer->GetString( pszName, 1024 ); + // pszName[1023] = 0; + + // SQObjectPtr value; + // if ( m_hVM->_roottable._unVal.pTable->Get( SQString::Create( _ss(m_hVM ), pszName ), value ) && sq_isclass( value ) ) + // { + // MapPtr( pOld, value._unVal.pClass ); + // return value._unVal.pClass; + // } + // MapPtr( pOld, NULL ); + // } + // return NULL; + //} + + ////------------------------------------------------------------- + //// + ////------------------------------------------------------------- + //SQInstance *ReadInstance() + //{ + // SQInstance *pOld; + // SQInstance *pInstance; + // if ( !BeginRead( &pOld, &pInstance ) ) + // { + // return pInstance; + // } + + // SQObjectPtr pClass; + // ReadObject( pClass ); + + // unsigned i, n; + // if ( pClass._unVal.pClass ) + // { + // pInstance = SQInstance::Create( _ss(m_hVM), pClass._unVal.pClass ); + + // n = m_pBuffer->GetUnsignedInt(); + // for ( i = 0; i < n; i++ ) + // { + // ReadObject(pInstance->_values[i]); + // } + // m_pBuffer->GetPtr(); // ignored in this path + // if ( pInstance->_class->_typetag ) + // { + // if ( pInstance->_class->_typetag == TYPETAG_VECTOR ) + // { + // Vector *pValue = new Vector; + // pValue->x = m_pBuffer->GetFloat(); + // pValue->y = m_pBuffer->GetFloat(); + // pValue->z = m_pBuffer->GetFloat(); + // pInstance->_userpointer = pValue; + // } + // else + // { + // InstanceContext_t *pContext = new InstanceContext_t; + // pContext->pInstance = NULL; + // ReadObject( pContext->name ); + // pContext->pClassDesc = (ScriptClassDesc_t *)( pInstance->_class->_typetag ); + // void *pOldInstance = m_pBuffer->GetPtr(); + // if ( sq_isstring(pContext->name) ) + // { + // char *pszName = pContext->name._unVal.pString->_val; + // if ( pContext->pClassDesc->pHelper ) + // { + // HPYOBJECT *pInstanceHandle = new HPYOBJECT; + // pInstanceHandle->_type = OT_INSTANCE; + // pInstanceHandle->_unVal.pInstance = pInstance; + // pContext->pInstance = pContext->pClassDesc->pHelper->BindOnRead( (HSCRIPT)pInstanceHandle, pOldInstance, pszName ); + // if ( pContext->pInstance ) + // { + // pInstance->_uiRef++; + // sq_addref( m_hVM, pInstanceHandle ); + // pInstance->_uiRef--; + // } + // else + // { + // delete pInstanceHandle; + // } + // } + + // if ( !pContext->pInstance ) + // { + // // Look for a match in the current root table + // HPYOBJECT hExistingObject = LookupObject( pszName, NULL, false ); + // if ( sq_isinstance(hExistingObject) && hExistingObject._unVal.pInstance->_class == pInstance->_class ) + // { + // delete pInstance; + // return hExistingObject._unVal.pInstance; + // } + + // pContext->pInstance = NULL; + // } + // } + // pInstance->_userpointer = pContext; + // } + // } + // else + // { + // Verify( m_pBuffer->GetInt() == OT_USERPOINTER ); + // pInstance->_userpointer = ReadUserPointer(); + // Assert( pInstance->_userpointer == NULL ); + // } + + // MapPtr( pOld, pInstance ); + // } + // else + // { + // MapPtr( pOld, NULL ); + // n = m_pBuffer->GetUnsignedInt(); + // for ( i = 0; i < n; i++ ) + // { + // SQObjectPtr ignored; + // ReadObject(ignored); + // } + // void *pOldTypeTag = m_pBuffer->GetPtr(); // ignored in this path + + // if ( pOldTypeTag ) + // { + // if ( pOldTypeTag == TYPETAG_VECTOR ) + // { + // m_pBuffer->GetFloat(); + // m_pBuffer->GetFloat(); + // m_pBuffer->GetFloat(); + // } + // else + // { + // SQObjectPtr ignored; + // ReadObject( ignored ); + // m_pBuffer->GetPtr(); + // } + // } + // else + // { + // Verify( m_pBuffer->GetInt() == OT_USERPOINTER ); + // ReadUserPointer(); + // } + // pInstance = NULL; + // } + // return pInstance; + //} + + ////------------------------------------------------------------- + //// + ////------------------------------------------------------------- + //SQGenerator *ReadGenerator() + //{ + // SQGenerator *pOld; + // SQGenerator *pGenerator; + // if ( !BeginRead( &pOld, &pGenerator ) ) + // { + // return pGenerator; + // } + + // SQObjectPtr closure; + // ReadObject( closure ); + + // pGenerator = SQGenerator::Create( _ss(m_hVM), closure._unVal.pClosure ); + // MapPtr( pOld, pGenerator ); + + // unsigned i, n; + // n = m_pBuffer->GetUnsignedInt(); + // pGenerator->_stack.resize( n ); + // for ( i = 0; i < n; i++ ) + // { + // ReadObject(pGenerator->_stack[i]); + // } + // n = m_pBuffer->GetUnsignedInt(); + // pGenerator->_vargsstack.resize( n ); + // for ( i = 0; i < n; i++ ) + // { + // ReadObject(pGenerator->_vargsstack[i]); + // } + // return pGenerator; + //} + + ////------------------------------------------------------------- + //// + ////------------------------------------------------------------- + //SQClosure *ReadClosure() + //{ + // SQClosure *pOld; + // SQClosure *pClosure; + // if ( !BeginRead( &pOld, &pClosure ) ) + // { + // return pClosure; + // } + + // SQObjectPtr proto; + // ReadObject( proto ); + // pClosure = SQClosure::Create( _ss(m_hVM), proto._unVal.pFunctionProto ); + // MapPtr( pOld, pClosure ); + + // ReadObject( pClosure->_env ); + + // unsigned i, n; + // n = m_pBuffer->GetUnsignedInt(); + // pClosure->_outervalues.resize( n ); + // for ( i = 0; i < n; i++ ) + // { + // ReadObject(pClosure->_outervalues[i]); + // } + + // n = m_pBuffer->GetUnsignedInt(); + // pClosure->_defaultparams.resize( n ); + // for ( i = 0; i < n; i++ ) + // { + // ReadObject(pClosure->_defaultparams[i]); + // } + + // return pClosure; + //} + + ////------------------------------------------------------------- + //// + ////------------------------------------------------------------- + //SQNativeClosure *ReadNativeClosure() + //{ + // SQNativeClosure *pOld; + // SQNativeClosure *pClosure; + // if ( !BeginRead( &pOld, &pClosure ) ) + // { + // return pClosure; + // } + + // SQObjectPtr name; + // ReadObject( name ); + // SQObjectPtr value; + // if ( m_hVM->_roottable._unVal.pTable->Get( name, value ) && sq_isnativeclosure(value) ) + // { + // MapPtr( pOld, value._unVal.pNativeClosure ); + // return value._unVal.pNativeClosure; + // } + // MapPtr( pOld, NULL ); + // return NULL; // @TBD [4/15/2008 tom] + //} + + ////------------------------------------------------------------- + //// + ////------------------------------------------------------------- + //SQUserData *ReadUserData() + //{ + // m_pBuffer->GetPtr(); + // return NULL; // @TBD [4/15/2008 tom] + //} + + ////------------------------------------------------------------- + //// + ////------------------------------------------------------------- + //SQUserPointer *ReadUserPointer() + //{ + // m_pBuffer->GetPtr(); + // return NULL; // @TBD [4/15/2008 tom] + //} + + ////------------------------------------------------------------- + //// + ////------------------------------------------------------------- + //static SQInteger SqReadFunc(SQUserPointer up,SQUserPointer data, SQInteger size) + // { + // CPythonVM *pThis = (CPythonVM *)up; + // pThis->m_pBuffer->Get( data, size ); + // return size; + // } + // + ////------------------------------------------------------------- + //// + ////------------------------------------------------------------- + //SQFunctionProto *ReadFuncProto() + //{ + // SQFunctionProto *pOld; + // SQFunctionProto *pResult; + // if ( !BeginRead( &pOld, &pResult ) ) + // { + // return pResult; + // } + + // SQObjectPtr result; + // SQFunctionProto::Load( m_hVM, this, &SqReadFunc, result ); + // pResult = result._unVal.pFunctionProto; + // pResult->_uiRef++; + // result.Null(); + // pResult->_uiRef--; + // MapPtr( pOld, pResult ); + // return pResult; + //} + + ////------------------------------------------------------------- + //// + ////------------------------------------------------------------- + //SQWeakRef *ReadWeakRef( ) + //{ + // SQObjectPtr obj; + // ReadObject( obj ); + // if ( !obj._unVal.pRefCounted ) + // { + // return NULL; + // } + + // // Need to up ref count if read order has weak ref loading first + // Assert( ISREFCOUNTED(obj._type) ); + // SQRefCounted *pRefCounted = obj._unVal.pRefCounted; + // pRefCounted->_uiRef++; + + // SQWeakRef *pResult = obj._unVal.pRefCounted->GetWeakRef( obj._type ); + + // obj.Null(); + // pRefCounted->_uiRef--; + + // return pResult; + //} + + ////------------------------------------------------------------- + //// + ////------------------------------------------------------------- + //bool FindKeyForObject( const SQObjectPtr &table, void *p, SQObjectPtr &key ) + //{ + // SQTable *pTable = table._unVal.pTable; + // int len = pTable->_numofnodes; + // for(int i = 0; i < len; i++) + // { + // if ( pTable->_nodes[i].val._unVal.pUserPointer == p ) + // { + // key = pTable->_nodes[i].key; + // return true; + // } + // if ( sq_istable( pTable->_nodes[i].val ) ) + // { + // if ( FindKeyForObject( pTable->_nodes[i].val, p, key ) ) + // { + // return true; + // } + // } + // } + // return false; + //} + + // add instance object to consistency checker + void debugTrackObject( PyObject *pobj ) + { +#ifdef DEBUG_PY + if (m_debugObjCount < 1000) + m_debugObjects[m_debugObjCount++] = pobj; +#endif // DEBUG_PY + } + + void debugRemoveTrackedObject( PyObject *pobj ) + { +#ifdef DEBUG_PY + for (int i = 0; i < m_debugObjCount; i++) + if ( m_debugObjects[i] == pobj ) + m_debugObjects[i] = NULL; +#endif // DEBUG_PY + } + + CPyScope *m_pRootScope; // __main__ module scope + CPyScope *m_pValveScope; // valve module scope + +public: + + int m_iMethodDef; + int m_iClassDef; + + void *m_rgpMethodDefs[MAX_VALVE_FUNCTIONS_EXPORTED]; // array of pointers to fixed blocks of memory - passed to python, must not move! + void *m_rgpClassDefs[MAX_VALVE_CLASSES_EXPORTED]; + + bool m_bInitialized; + +private: + char m_szScriptPath[MAX_PATH]; // full path to scripts/vscript directory + int64 m_iUniqueIdSerialNumber; + float m_TimeStartExecute; + + int m_debugObjCount; + PyObject *m_debugObjects[1000]; + +#ifdef VPYTHON_TEST + ConVar developer; +#else + ConVarRef developer; +#endif + + CUtlHashFast m_TypeMap; // map pClassDesc to PyTypeObject python type + CUtlHashFast m_ClassMap; // map PyTypeObject to pClassDesc + + // friend class CVPythonSerializer; + +// // Serialization support +// CUtlBuffer *m_pBuffer; +// CUtlMap m_PtrMap; +}; + + +//------------------------------------------------------------------------- +// Serialization and Debug Helpers +//------------------------------------------------------------------------- + +//const char *FieldTypeToString( int type ) +//{ +// switch( type ) +// { +// case FIELD_VOID: return "void"; +// case FIELD_FLOAT: return "float"; +// case FIELD_CSTRING: return "string"; +// case FIELD_VECTOR: return "Vector"; +// case FIELD_INTEGER: return "int"; +// case FIELD_BOOLEAN: return "bool"; +// case FIELD_CHARACTER: return "char"; +// case FIELD_HSCRIPT: return "handle"; +// default: return ""; +// } +//} + +//static const char *SQTypeToString( SQObjectType sqType ) +//{ +// switch( sqType ) +// { +// case OT_FLOAT: return "FLOAT"; +// case OT_INTEGER: return "INTEGER"; +// case OT_BOOL: return "BOOL"; +// case OT_STRING: return "STRING"; +// case OT_NULL: return "NULL"; +// case OT_TABLE: return "TABLE"; +// case OT_ARRAY: return "ARRAY"; +// case OT_CLOSURE: return "CLOSURE"; +// case OT_NATIVECLOSURE: return "NATIVECLOSURE"; +// case OT_USERDATA: return "USERDATA"; +// case OT_GENERATOR: return "GENERATOR"; +// case OT_THREAD: return "THREAD"; +// case OT_USERPOINTER: return "USERPOINTER"; +// case OT_CLASS: return "CLASS"; +// case OT_INSTANCE: return "INSTANCE"; +// case OT_WEAKREF: return "WEAKREF"; +// } +// return ""; +//} + +//---------------------------------------------------------------------------------- +// return true if interpreter init is finalized - block attempts at re-init. +//---------------------------------------------------------------------------------- +inline bool VMInitFinalized( void ) +{ + return ((CPythonVM *)g_pVm)->m_bInitialized; +} + +//---------------------------------------------------------------------------------- +// create interpreter singleton and save pointer to interface in g_pVm +//---------------------------------------------------------------------------------- +IScriptVM *ScriptCreatePythonVM() +{ + if ( !g_pVm ) + { + g_pVm = new CPythonVM; + } + else + { + // set semaphore to block more than one init of interpreter, + // this blocks registration of any more classes or functions, but not of instances + ((CPythonVM *)g_pVm)->m_bInitialized = true; + } + + return (IScriptVM *)g_pVm; +} + +//---------------------------------------------------------------------------------- +// called after shutdown() on restart or level load or exit +// NOTE: we should not actually kill the interpreter unless it's a full game exit. +// UNDONE: we don't cleanly shut down the interpeter on game exit. +//---------------------------------------------------------------------------------- +void ScriptDestroyPythonVM( IScriptVM *pVm ) +{ + // UNDONE: ivscript interface needs a flag to indicate game exit - the only case we should actually kill the interpreter + bool bGameExit = false; + + if ( bGameExit ) + { + + // release memory associated with dynamically allocated data + CPythonVM *pPythonVM = assert_cast( pVm ); + + if (1) + { // UNDONE: ONE shutdown per game session only! + // whether these are allocated using new/delete, python PyObject_Malloc/Free, + // this dealloc causes the next Py_Initialize/Py_Finalize to fail intermittently (ie on restart). + // Python documentation indicates that Py_Finalize does NOT reliably release all allocated resources, + // and users of various versions report problems with Py_Finalize followed by a subsequent + // Py_Initialize. + + int i; + + for (i = 0; i < pPythonVM->m_iMethodDef; i++) + { + PyMem_Free( pPythonVM->m_rgpMethodDefs[i] ); + } + + for (i = 0; i < pPythonVM->m_iClassDef; i++) + { + PyMem_Free( pPythonVM->m_rgpClassDefs[i] ); + } + pPythonVM->m_iMethodDef = 0; + pPythonVM->m_iClassDef = 0; + + } + + + if (1) // TEST2: + delete pPythonVM; + } + +} + +//------------------------------------------------------------------- +// C function & method call proxies: +// Do a bunch of proxy work to expose server-side functions/methods +// with their specific bindings to python. +// +// Since python does not support +// specifying user data along with c-defined function/method callbacks, +// and we need specific python->c binding data for each function/method callback, +// we have to create unique proxy functions for every callback. +// +// Each unique proxy gets the correct binding info for the function, +// then calls the general TranslateCall routine to do the dispatch. +//------------------------------------------------------------------- + +//------------------------------------------------------------------ +// define a static callback proxy - python calls this back to access +// a function or method definition of a valve class +//----------------------------------------------------------------- +#define DPX(N) \ + static PyObject *Translate_##N( PyObject *pSelf, PyObject *pArgs ) \ + { \ + ScriptFunctionBinding_t *pBinding = GetProxyBinding( ##N ); \ + return ( CPythonVM::TranslateCall( pBinding, (scriptClassInstance_t *)pSelf, pArgs ) ); \ + } \ + +// set proxy definition +#define SPX(N) g_proxies[##N].pfn = Translate_##N; + +static int g_proxyid = 0; + +static int GetNewProxyId( void ) +{ + int proxyId = g_proxyid; + Assert ( proxyId < MAX_VALVE_FUNCTIONS_EXPORTED ); // if this fails, just need to bump up MAX_VALVE_FUNCTIONS_EXPORTED and add more DPX(n),SPX(n) entries + g_proxyid++; + return proxyId; +} + +// associate the function and/or class binding with the proxy function id +static void SetProxyBinding( int proxyId, ScriptFunctionBinding_t *pBinding ) +{ + Assert( proxyId < MAX_VALVE_FUNCTIONS_EXPORTED ); // if this fails, just need to bump up MAX_VALVE_FUNCTIONS_EXPORTED and add more DPX(n) entries + g_proxies[proxyId].pBinding = pBinding; +} + +static PyCFunction GetProxyFunction( int proxyId ) +{ + Assert( proxyId < MAX_VALVE_FUNCTIONS_EXPORTED ); // invalid proxyId + return g_proxies[proxyId].pfn; +} + +// retrieve the function binding, given the proxy index +static ScriptFunctionBinding_t *GetProxyBinding( int proxyId ) +{ + Assert( proxyId < MAX_VALVE_FUNCTIONS_EXPORTED ); // invalid proxyId + return ( g_proxies[proxyId].pBinding ); +} + +DPX(0) DPX(1) DPX(2) DPX(3) DPX(4) DPX(5) DPX(6) DPX(7) DPX(8) DPX(9) DPX(10) DPX(11) DPX(12) DPX(13) DPX(14) DPX(15) DPX(16) DPX(17) DPX(18) DPX(19) +DPX(20) DPX(21) DPX(22) DPX(23) DPX(24) DPX(25) DPX(26) DPX(27) DPX(28) DPX(29) DPX(30) DPX(31) DPX(32) DPX(33) DPX(34) DPX(35) DPX(36) DPX(37) DPX(38) DPX(39) +DPX(40) DPX(41) DPX(42) DPX(43) DPX(44) DPX(45) DPX(46) DPX(47) DPX(48) DPX(49) DPX(50) DPX(51) DPX(52) DPX(53) DPX(54) DPX(55) DPX(56) DPX(57) DPX(58) DPX(59) +DPX(60) DPX(61) DPX(62) DPX(63) DPX(64) DPX(65) DPX(66) DPX(67) DPX(68) DPX(69) DPX(70) DPX(71) DPX(72) DPX(73) DPX(74) DPX(75) DPX(76) DPX(77) DPX(78) DPX(79) +DPX(80) DPX(81) DPX(82) DPX(83) DPX(84) DPX(85) DPX(86) DPX(87) DPX(88) DPX(89) DPX(90) DPX(91) DPX(92) DPX(93) DPX(94) DPX(95) DPX(96) DPX(97) DPX(98) DPX(99) +DPX(100) DPX(101) DPX(102) DPX(103) DPX(104) DPX(105) DPX(106) DPX(107) DPX(108) DPX(109) DPX(110) DPX(111) DPX(112) DPX(113) DPX(114) DPX(115) DPX(116) DPX(117) DPX(118) DPX(119) +DPX(120) DPX(121) DPX(122) DPX(123) DPX(124) DPX(125) DPX(126) DPX(127) DPX(128) DPX(129) DPX(130) DPX(131) DPX(132) DPX(133) DPX(134) DPX(135) DPX(136) DPX(137) DPX(138) DPX(139) +DPX(140) DPX(141) DPX(142) DPX(143) DPX(144) DPX(145) DPX(146) DPX(147) DPX(148) DPX(149) DPX(150) DPX(151) DPX(152) DPX(153) DPX(154) DPX(155) DPX(156) DPX(157) DPX(158) DPX(159) +DPX(160) DPX(161) DPX(162) DPX(163) DPX(164) DPX(165) DPX(166) DPX(167) DPX(168) DPX(169) DPX(170) DPX(171) DPX(172) DPX(173) DPX(174) DPX(175) DPX(176) DPX(177) DPX(178) DPX(179) +DPX(180) DPX(181) DPX(182) DPX(183) DPX(184) DPX(185) DPX(186) DPX(187) DPX(188) DPX(189) DPX(190) DPX(191) DPX(192) DPX(193) DPX(194) DPX(195) DPX(196) DPX(197) DPX(198) DPX(199) +DPX(200) DPX(201) DPX(202) DPX(203) DPX(204) DPX(205) DPX(206) DPX(207) DPX(208) DPX(209) DPX(210) DPX(211) DPX(212) DPX(213) DPX(214) DPX(215) DPX(216) DPX(217) DPX(218) DPX(219) +DPX(220) DPX(221) DPX(222) DPX(223) DPX(224) DPX(225) DPX(226) DPX(227) DPX(228) DPX(229) DPX(230) DPX(231) DPX(232) DPX(233) DPX(234) DPX(235) DPX(236) DPX(237) DPX(238) DPX(239) +DPX(240) DPX(241) DPX(242) DPX(243) DPX(244) DPX(245) DPX(246) DPX(247) DPX(248) DPX(249) DPX(250) DPX(251) DPX(252) DPX(253) DPX(254) DPX(255) DPX(256) DPX(257) DPX(258) DPX(259) + +static void InitProxyTable( void ) +{ + g_proxyid = 0; + +SPX(0) SPX(1) SPX(2) SPX(3) SPX(4) SPX(5) SPX(6) SPX(7) SPX(8) SPX(9) SPX(10) SPX(11) SPX(12) SPX(13) SPX(14) SPX(15) SPX(16) SPX(17) SPX(18) SPX(19) +SPX(20) SPX(21) SPX(22) SPX(23) SPX(24) SPX(25) SPX(26) SPX(27) SPX(28) SPX(29) SPX(30) SPX(31) SPX(32) SPX(33) SPX(34) SPX(35) SPX(36) SPX(37) SPX(38) SPX(39) +SPX(40) SPX(41) SPX(42) SPX(43) SPX(44) SPX(45) SPX(46) SPX(47) SPX(48) SPX(49) SPX(50) SPX(51) SPX(52) SPX(53) SPX(54) SPX(55) SPX(56) SPX(57) SPX(58) SPX(59) +SPX(60) SPX(61) SPX(62) SPX(63) SPX(64) SPX(65) SPX(66) SPX(67) SPX(68) SPX(69) SPX(70) SPX(71) SPX(72) SPX(73) SPX(74) SPX(75) SPX(76) SPX(77) SPX(78) SPX(79) +SPX(80) SPX(81) SPX(82) SPX(83) SPX(84) SPX(85) SPX(86) SPX(87) SPX(88) SPX(89) SPX(90) SPX(91) SPX(92) SPX(93) SPX(94) SPX(95) SPX(96) SPX(97) SPX(98) SPX(99) +SPX(100) SPX(101) SPX(102) SPX(103) SPX(104) SPX(105) SPX(106) SPX(107) SPX(108) SPX(109) SPX(110) SPX(111) SPX(112) SPX(113) SPX(114) SPX(115) SPX(116) SPX(117) SPX(118) SPX(119) +SPX(120) SPX(121) SPX(122) SPX(123) SPX(124) SPX(125) SPX(126) SPX(127) SPX(128) SPX(129) SPX(130) SPX(131) SPX(132) SPX(133) SPX(134) SPX(135) SPX(136) SPX(137) SPX(138) SPX(139) +SPX(140) SPX(141) SPX(142) SPX(143) SPX(144) SPX(145) SPX(146) SPX(147) SPX(148) SPX(149) SPX(150) SPX(151) SPX(152) SPX(153) SPX(154) SPX(155) SPX(156) SPX(157) SPX(158) SPX(159) +SPX(160) SPX(161) SPX(162) SPX(163) SPX(164) SPX(165) SPX(166) SPX(167) SPX(168) SPX(169) SPX(170) SPX(171) SPX(172) SPX(173) SPX(174) SPX(175) SPX(176) SPX(177) SPX(178) SPX(179) +SPX(180) SPX(181) SPX(182) SPX(183) SPX(184) SPX(185) SPX(186) SPX(187) SPX(188) SPX(189) SPX(190) SPX(191) SPX(192) SPX(193) SPX(194) SPX(195) SPX(196) SPX(197) SPX(198) SPX(199) +SPX(200) SPX(201) SPX(202) SPX(203) SPX(204) SPX(205) SPX(206) SPX(207) SPX(208) SPX(209) SPX(210) SPX(211) SPX(212) SPX(213) SPX(214) SPX(215) SPX(216) SPX(217) SPX(218) SPX(219) +SPX(220) SPX(221) SPX(222) SPX(223) SPX(224) SPX(225) SPX(226) SPX(227) SPX(228) SPX(229) SPX(230) SPX(231) SPX(232) SPX(233) SPX(234) SPX(235) SPX(236) SPX(237) SPX(238) SPX(239) +SPX(240) SPX(241) SPX(242) SPX(243) SPX(244) SPX(245) SPX(246) SPX(247) SPX(248) SPX(249) SPX(250) SPX(251) SPX(252) SPX(253) SPX(254) SPX(255) SPX(256) SPX(257) SPX(258) SPX(259) +} + + + +#ifdef VPYTHON_TEST +CPythonVM g_PythonVM; +IScriptVM *g_pScriptVM = &g_PythonVM; + + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#include + +int main( int argc, const char **argv) +{ + if ( argc < 2 ) + { + printf( "No script specified" ); + return 1; + } + g_pScriptVM->Init(); + + const char *pszbuild; + pszbuild = Py_GetVersion( ) ; + + printf("You should be using python 2.5.x. You are using python \"%s\".\n", pszbuild); + + // run a script without a source file - remote debugger will ask for a source file + g_pScriptVM->Run( + "import pydevd\n" + //"pydevd.settrace(stdoutToServer = True, stderrToServer = True, port = 5678, suspend = True)\n" + "from time import time,ctime\n" + "print 'Today is',ctime(time())\n" + ); + + + + //CCycleCount count; + //count.Sample(); + //RandomSeed( time( NULL ) ^ count.GetMicroseconds() ); + ScriptRegisterFunction( g_pScriptVM, RandomFloat, "" ); + ScriptRegisterFunction( g_pScriptVM, RandomInt, "" ); + + if ( argc == 3 && *argv[2] == 'd' ) + { + g_pScriptVM->ConnectDebugger(); + + // exec a script that invokes the remote python debugger in eclipse pydev + // NOTE: this is the only valid way to get an hFile to use with Py_ calls. FILE * returned from fopen is not compatible. + PyObject* pyfile = PyFile_FromString( "debug.py", "r"); + FILE* hFile = PyFile_AsFile( pyfile); + int ret = PyRun_AnyFile(hFile, "debug.py"); + Py_XDECREF(pyfile); + } + + int key; + CScriptScope scope; + scope.Init( "TestScope" ); + do + { + const char *pszScript = argv[1]; + FILE *hFile = fopen( pszScript, "rb" ); + if ( !hFile ) + { + printf( "\"%s\" not found.\n", pszScript ); + return 1; + } + + int nFileLen = _filelength( _fileno( hFile ) ); + char *pBuf = new char[nFileLen + 1]; + fread( pBuf, 1, nFileLen, hFile ); + pBuf[nFileLen] = 0; + fclose( hFile ); + + if (1) + { + printf( "Executing script \"%s\"\n----------------------------------------\n", pszScript ); + HSCRIPT hScript = g_pScriptVM->CompileScript( pBuf, ( strrchr( pszScript, '\\' ) ? strrchr( pszScript, '\\' ) + 1 : pszScript ) ); + if ( hScript ) + { + if ( scope.Run( hScript ) != SCRIPT_ERROR ) + { + printf( "----------------------------------------\n" ); + printf("Script complete. Press q to exit, m to dump memory usage, enter to run again.\n"); + } + else + { + printf( "----------------------------------------\n" ); + printf("Script execution error. Press q to exit, m to dump memory usage, enter to run again.\n"); + } + g_pScriptVM->ReleaseScript( hScript ); + } + else + { + printf( "----------------------------------------\n" ); + printf("Script failed to compile. Press q to exit, m to dump memory usage, enter to run again.\n"); + } + } + key = _getch(); // Keypress before exit + if ( key == 'm' ) + { + Msg( "%d\n", g_pMemAlloc->GetSize( NULL ) ); + } + delete pBuf; + } while ( key != 'q' ); + + scope.Term(); + g_pScriptVM->DisconnectDebugger(); + + g_pScriptVM->Shutdown(); + return 0; +} + +#endif diff --git a/vscript/languages/python/vpython/vpython.h b/vscript/languages/python/vpython/vpython.h new file mode 100644 index 00000000..1c751130 --- /dev/null +++ b/vscript/languages/python/vpython/vpython.h @@ -0,0 +1,17 @@ +//========== Copyright © 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: +// +//============================================================================= + +#ifndef VPYTHON_H +#define VPYTHON_H + +#if defined( _WIN32 ) +#pragma once +#endif + +IScriptVM *ScriptCreatePythonVM(); +void ScriptDestroyPythonVM( IScriptVM *pVM ); + +#endif // VPYTHON_H diff --git a/vscript/languages/python/vpython/vpython.vpc b/vscript/languages/python/vpython/vpython.vpc new file mode 100644 index 00000000..ef78d059 --- /dev/null +++ b/vscript/languages/python/vpython/vpython.vpc @@ -0,0 +1,51 @@ +//----------------------------------------------------------------------------- +// Project Script +//----------------------------------------------------------------------------- + +$Macro SRCDIR "..\..\..\.." +$Macro OUTBINDIR "." + +$Include "$SRCDIR\vpc_scripts\source_exe_con_win32_base.vpc" + +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE,..\python25\include" + //$AdditionalIncludeDirectories "$BASE;$SRCDIR\common\python\$PYTHONVER;$SRCDIR\public\python" + + $PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE;VPYTHON_TEST" + } + + $Linker + { + $AdditionalLibraryDirectories "..\python25\lib" + } + +} + +$Project "vpython" +{ + //$Folder "Link libraries" + //{ + // $File "..\python25\lib\python25.lib" + //} + + $Folder "Source Files" + { + $File "..\..\..\..\public\vscript\ivscript.h" + $File "..\..\..\..\public\vscript\vscript_templates.h" + $File "vpython.cpp" + { + $Configuration + { + $Compiler + { + //$AdditionalOptions "/EHa" + } + } + } + } + +} + diff --git a/vscript/languages/squirrel/COMPILE b/vscript/languages/squirrel/COMPILE new file mode 100644 index 00000000..a9d9883e --- /dev/null +++ b/vscript/languages/squirrel/COMPILE @@ -0,0 +1,41 @@ +Squirrel 2.2.3 stable +-------------------------------------------------------- +What is in this distribution? + +squirrel + static library implementing the compiler and interpreter of the language + +sqstdlib + the standard utility libraries + +sq + stand alone interpreter + +doc + The manual + +etc + a minimalistic embedding sample + +samples + samples programs + + +HOW TO COMPILE +--------------------------------------------------------- +GCC USERS +......................................................... +There is a very simple makefile that compiles all libraries and exes +from the root of the project run 'make' + +for 32 bits systems + + $ make + +for 64 bits systems + + $ make sq64 + +VISUAL C++ USERS +......................................................... +Open squirrel.dsw from the root project directory and build(dho!) \ No newline at end of file diff --git a/vscript/languages/squirrel/COPYRIGHT b/vscript/languages/squirrel/COPYRIGHT new file mode 100644 index 00000000..d2c3cf02 --- /dev/null +++ b/vscript/languages/squirrel/COPYRIGHT @@ -0,0 +1,29 @@ +Copyright (c) 2003-2009 Alberto Demichelis + +This software is provided 'as-is', without any +express or implied warranty. In no event will the +authors be held liable for any damages arising from +the use of this software. + +Permission is granted to anyone to use this software +for any purpose, including commercial applications, +and to alter it and redistribute it freely, subject +to the following restrictions: + + 1. The origin of this software must not be + misrepresented; you must not claim that + you wrote the original software. If you + use this software in a product, an + acknowledgment in the product + documentation would be appreciated but is + not required. + + 2. Altered source versions must be plainly + marked as such, and must not be + misrepresented as being the original + software. + + 3. This notice may not be removed or + altered from any source distribution. +----------------------------------------------------- +END OF COPYRIGHT \ No newline at end of file diff --git a/vscript/languages/squirrel/DXSquirrel/DXSquirrel.cbp b/vscript/languages/squirrel/DXSquirrel/DXSquirrel.cbp new file mode 100644 index 00000000..acaade7f --- /dev/null +++ b/vscript/languages/squirrel/DXSquirrel/DXSquirrel.cbp @@ -0,0 +1,253 @@ + + + + + + + diff --git a/vscript/languages/squirrel/DXSquirrel/DXSquirrel.cpp b/vscript/languages/squirrel/DXSquirrel/DXSquirrel.cpp new file mode 100644 index 00000000..f49ea48b --- /dev/null +++ b/vscript/languages/squirrel/DXSquirrel/DXSquirrel.cpp @@ -0,0 +1,41 @@ +#include "stdafx.h" +#include +#include +#include + +#pragma comment(lib,"d3d9.lib") +#pragma comment(lib,"d3dx9.lib") + +#include "sqplus.h" + +LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { + switch( msg ) { + case WM_CLOSE: + PostQuitMessage( 0 ); + return 0; + } + return DefWindowProc( hWnd, msg, wParam, lParam ); +} + +BOOL DXSquirrel_Initialize(); +void DXSquirrel_Shutdown(); + +INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT ) { + if(!DXSquirrel_Initialize()) { + MessageBox(NULL,_SC("Error initilizing the app"),_SC("DXSquirrel"),MB_OK); + return -1; + } + try { + SquirrelObject main = SquirrelVM::CompileScript(_SC("dxsquirrel.nut")); + SquirrelVM::RunScript(main); + } + catch(SquirrelError &e) { + MessageBox(NULL,e.desc,_SC("DXSquirrel"),MB_OK); + return -2; + } + DXSquirrel_Shutdown(); + return 0; +} + + + diff --git a/vscript/languages/squirrel/DXSquirrel/DXSquirrel.h b/vscript/languages/squirrel/DXSquirrel/DXSquirrel.h new file mode 100644 index 00000000..d00d47e7 --- /dev/null +++ b/vscript/languages/squirrel/DXSquirrel/DXSquirrel.h @@ -0,0 +1,3 @@ +#pragma once + +#include "resource.h" diff --git a/vscript/languages/squirrel/DXSquirrel/DXSquirrel.ico b/vscript/languages/squirrel/DXSquirrel/DXSquirrel.ico new file mode 100644 index 0000000000000000000000000000000000000000..d551aa3aaf80adf9b7760e2eb8de95a5c3e53df6 GIT binary patch literal 23558 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/DXSquirrel/DXSquirrel71.vcproj b/vscript/languages/squirrel/DXSquirrel/DXSquirrel71.vcproj new file mode 100644 index 00000000..29a6fa81 --- /dev/null +++ b/vscript/languages/squirrel/DXSquirrel/DXSquirrel71.vcproj @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/DXSquirrel/DXSquirrel_Binds.cpp b/vscript/languages/squirrel/DXSquirrel/DXSquirrel_Binds.cpp new file mode 100644 index 00000000..81cdc5cf --- /dev/null +++ b/vscript/languages/squirrel/DXSquirrel/DXSquirrel_Binds.cpp @@ -0,0 +1,35 @@ +#include "stdafx.h" +#include "sqplus.h" +#include "DXSquirrel_Binds.h" + +WNDCLASSEX gWC; +LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); +IDirect3D9 * gpD3D = NULL; +BOOL DXSquirrel_Initialize() +{ + WNDCLASSEX t = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, + GetModuleHandle(NULL), NULL, NULL, NULL, NULL, + _T("DXSquirrel"), NULL }; + gWC = t; + RegisterClassEx( &gWC ); + SquirrelVM::Init(); + if( NULL == ( gpD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) ) + return FALSE; + + //initializes classes + _INIT_STATIC_NAMESPACE(DX); + _INIT_CLASS(Device); + _INIT_CLASS(Vector3); + _INIT_CLASS(Matrix); + _INIT_CLASS(BaseMesh); + _INIT_CLASS(Mesh); + // + return TRUE; +} + +void DXSquirrel_Shutdown() +{ + if(gpD3D) { + gpD3D->Release(); + } +} diff --git a/vscript/languages/squirrel/DXSquirrel/DXSquirrel_Binds.h b/vscript/languages/squirrel/DXSquirrel/DXSquirrel_Binds.h new file mode 100644 index 00000000..3a444223 --- /dev/null +++ b/vscript/languages/squirrel/DXSquirrel/DXSquirrel_Binds.h @@ -0,0 +1,11 @@ +#ifndef _DXSQUIRREL_BINDS_H_ +#define _DXSQUIRREL_BINDS_H_ + +_DECL_STATIC_NAMESPACE(DX); +_DECL_CLASS(Device); +_DECL_CLASS(Vector3); +_DECL_CLASS(Matrix); +_DECL_CLASS(BaseMesh); +_DECL_CLASS(Mesh); + +#endif //_DXSQUIRREL_BINDS_H_ diff --git a/vscript/languages/squirrel/DXSquirrel/DXSquirrel_DX.cpp b/vscript/languages/squirrel/DXSquirrel/DXSquirrel_DX.cpp new file mode 100644 index 00000000..9c6b770e --- /dev/null +++ b/vscript/languages/squirrel/DXSquirrel/DXSquirrel_DX.cpp @@ -0,0 +1,230 @@ +#include "stdafx.h" +#include "sqplus.h" +#include "DXSquirrel_Binds.h" + +//updates the message loop +_MEMBER_FUNCTION_IMPL(DX,Update) +{ + StackHandler sa(v); + MSG msg; + ZeroMemory( &msg, sizeof(msg) ); + while( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) + { + if(msg.message == WM_QUIT) + { + return sa.Return(false); + } + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + return sa.Return(true); +} + +// +_BEGIN_NAMESPACE(DX) +_MEMBER_FUNCTION(DX,Update,0,0) +_BEGIN_NAMESPACE_CONSTANTS(DX) +//D3DDEVTYPE +_CONSTANT(D3DDEVTYPE_HAL,OT_INTEGER,D3DDEVTYPE_HAL) +_CONSTANT(D3DDEVTYPE_REF,OT_INTEGER,D3DDEVTYPE_REF) +_CONSTANT(D3DDEVTYPE_SW,OT_INTEGER,D3DDEVTYPE_SW) +//SWAPEFFECT +_CONSTANT(D3DSWAPEFFECT_DISCARD,OT_INTEGER,D3DSWAPEFFECT_DISCARD) +_CONSTANT(D3DSWAPEFFECT_FLIP,OT_INTEGER,D3DSWAPEFFECT_FLIP) +_CONSTANT(D3DSWAPEFFECT_COPY,OT_INTEGER,D3DSWAPEFFECT_COPY) +//D3DCREATE +_CONSTANT(D3DCREATE_ADAPTERGROUP_DEVICE,OT_INTEGER,D3DCREATE_ADAPTERGROUP_DEVICE) +_CONSTANT(D3DCREATE_DISABLE_DRIVER_MANAGEMENT,OT_INTEGER,D3DCREATE_DISABLE_DRIVER_MANAGEMENT) +_CONSTANT(D3DCREATE_DISABLE_DRIVER_MANAGEMENT_EX,OT_INTEGER,D3DCREATE_DISABLE_DRIVER_MANAGEMENT_EX) +_CONSTANT(D3DCREATE_FPU_PRESERVE,OT_INTEGER,D3DCREATE_FPU_PRESERVE) +_CONSTANT(D3DCREATE_HARDWARE_VERTEXPROCESSING,OT_INTEGER,D3DCREATE_HARDWARE_VERTEXPROCESSING) +_CONSTANT(D3DCREATE_MIXED_VERTEXPROCESSING,OT_INTEGER,D3DCREATE_MIXED_VERTEXPROCESSING) +_CONSTANT(D3DCREATE_MULTITHREADED,OT_INTEGER,D3DCREATE_MULTITHREADED) +_CONSTANT(D3DCREATE_NOWINDOWCHANGES,OT_INTEGER,D3DCREATE_NOWINDOWCHANGES) +_CONSTANT(D3DCREATE_PUREDEVICE,OT_INTEGER,D3DCREATE_PUREDEVICE) +_CONSTANT(D3DCREATE_SOFTWARE_VERTEXPROCESSING,OT_INTEGER,D3DCREATE_SOFTWARE_VERTEXPROCESSING) +//D3DFMT +_CONSTANT(D3DFMT_UNKNOWN,OT_INTEGER,D3DFMT_UNKNOWN) +_CONSTANT(D3DFMT_R8G8B8,OT_INTEGER,D3DFMT_R8G8B8) +_CONSTANT(D3DFMT_A8R8G8B8,OT_INTEGER,D3DFMT_A8R8G8B8) +_CONSTANT(D3DFMT_X8R8G8B8,OT_INTEGER,D3DFMT_X8R8G8B8) +_CONSTANT(D3DFMT_R5G6B5,OT_INTEGER,D3DFMT_R5G6B5) +_CONSTANT(D3DFMT_X1R5G5B5,OT_INTEGER,D3DFMT_X1R5G5B5) +_CONSTANT(D3DFMT_A1R5G5B5,OT_INTEGER,D3DFMT_A1R5G5B5) +_CONSTANT(D3DFMT_A4R4G4B4,OT_INTEGER,D3DFMT_A4R4G4B4) +_CONSTANT(D3DFMT_R3G3B2,OT_INTEGER,D3DFMT_R3G3B2) +_CONSTANT(D3DFMT_A8,OT_INTEGER,D3DFMT_A8) +_CONSTANT(D3DFMT_A8R3G3B2,OT_INTEGER,D3DFMT_A8R3G3B2) +_CONSTANT(D3DFMT_X4R4G4B4,OT_INTEGER,D3DFMT_X4R4G4B4) +_CONSTANT(D3DFMT_A2B10G10R10,OT_INTEGER,D3DFMT_A2B10G10R10) +_CONSTANT(D3DFMT_A8B8G8R8,OT_INTEGER,D3DFMT_A8B8G8R8) +_CONSTANT(D3DFMT_X8B8G8R8,OT_INTEGER,D3DFMT_X8B8G8R8) +_CONSTANT(D3DFMT_G16R16,OT_INTEGER,D3DFMT_G16R16) +_CONSTANT(D3DFMT_A2R10G10B10,OT_INTEGER,D3DFMT_A2R10G10B10) +_CONSTANT(D3DFMT_A16B16G16R16,OT_INTEGER,D3DFMT_A16B16G16R16) +_CONSTANT(D3DFMT_A8P8,OT_INTEGER,D3DFMT_A8P8) +_CONSTANT(D3DFMT_P8,OT_INTEGER,D3DFMT_P8) +_CONSTANT(D3DFMT_L8,OT_INTEGER,D3DFMT_L8) +_CONSTANT(D3DFMT_A8L8,OT_INTEGER,D3DFMT_A8L8) +_CONSTANT(D3DFMT_A4L4,OT_INTEGER,D3DFMT_A4L4) +_CONSTANT(D3DFMT_V8U8,OT_INTEGER,D3DFMT_V8U8) +_CONSTANT(D3DFMT_L6V5U5,OT_INTEGER,D3DFMT_L6V5U5) +_CONSTANT(D3DFMT_X8L8V8U8,OT_INTEGER,D3DFMT_X8L8V8U8) +_CONSTANT(D3DFMT_Q8W8V8U8,OT_INTEGER,D3DFMT_Q8W8V8U8) +_CONSTANT(D3DFMT_V16U16,OT_INTEGER,D3DFMT_V16U16) +_CONSTANT(D3DFMT_A2W10V10U10,OT_INTEGER,D3DFMT_A2W10V10U10) +_CONSTANT(D3DFMT_UYVY,OT_INTEGER,D3DFMT_UYVY) +_CONSTANT(D3DFMT_R8G8_B8G8,OT_INTEGER,D3DFMT_R8G8_B8G8) +_CONSTANT(D3DFMT_YUY2,OT_INTEGER,D3DFMT_YUY2) +_CONSTANT(D3DFMT_G8R8_G8B8,OT_INTEGER,D3DFMT_G8R8_G8B8) +_CONSTANT(D3DFMT_DXT1,OT_INTEGER,D3DFMT_DXT1) +_CONSTANT(D3DFMT_DXT2,OT_INTEGER,D3DFMT_DXT2) +_CONSTANT(D3DFMT_DXT3,OT_INTEGER,D3DFMT_DXT3) +_CONSTANT(D3DFMT_DXT4,OT_INTEGER,D3DFMT_DXT4) +_CONSTANT(D3DFMT_DXT5,OT_INTEGER,D3DFMT_DXT5) +_CONSTANT(D3DFMT_D16_LOCKABLE,OT_INTEGER,D3DFMT_D16_LOCKABLE) +_CONSTANT(D3DFMT_D32,OT_INTEGER,D3DFMT_D32) +_CONSTANT(D3DFMT_D15S1,OT_INTEGER,D3DFMT_D15S1) +_CONSTANT(D3DFMT_D24S8,OT_INTEGER,D3DFMT_D24S8) +_CONSTANT(D3DFMT_D24X8,OT_INTEGER,D3DFMT_D24X8) +_CONSTANT(D3DFMT_D24X4S4,OT_INTEGER,D3DFMT_D24X4S4) +_CONSTANT(D3DFMT_D16,OT_INTEGER,D3DFMT_D16) +_CONSTANT(D3DFMT_D32F_LOCKABLE,OT_INTEGER,D3DFMT_D32F_LOCKABLE) +_CONSTANT(D3DFMT_D24FS8,OT_INTEGER,D3DFMT_D24FS8) +_CONSTANT(D3DFMT_L16,OT_INTEGER,D3DFMT_L16) +_CONSTANT(D3DFMT_VERTEXDATA,OT_INTEGER,D3DFMT_VERTEXDATA) +_CONSTANT(D3DFMT_INDEX16,OT_INTEGER,D3DFMT_INDEX16) +_CONSTANT(D3DFMT_INDEX32,OT_INTEGER,D3DFMT_INDEX32) +_CONSTANT(D3DFMT_Q16W16V16U16,OT_INTEGER,D3DFMT_Q16W16V16U16) +_CONSTANT(D3DFMT_MULTI2_ARGB8,OT_INTEGER,D3DFMT_MULTI2_ARGB8) +_CONSTANT(D3DFMT_R16F,OT_INTEGER,D3DFMT_R16F) +_CONSTANT(D3DFMT_G16R16F,OT_INTEGER,D3DFMT_G16R16F) +_CONSTANT(D3DFMT_A16B16G16R16F,OT_INTEGER,D3DFMT_A16B16G16R16F) +_CONSTANT(D3DFMT_R32F,OT_INTEGER,D3DFMT_R32F) +_CONSTANT(D3DFMT_G32R32F,OT_INTEGER,D3DFMT_G32R32F) +_CONSTANT(D3DFMT_A32B32G32R32F,OT_INTEGER,D3DFMT_A32B32G32R32F) +_CONSTANT(D3DFMT_CxV8U8,OT_INTEGER,D3DFMT_CxV8U8) +//D3DCLEAR +_CONSTANT(D3DCLEAR_STENCIL,OT_INTEGER,D3DCLEAR_STENCIL) +_CONSTANT(D3DCLEAR_TARGET,OT_INTEGER,D3DCLEAR_TARGET) +_CONSTANT(D3DCLEAR_ZBUFFER,OT_INTEGER,D3DCLEAR_ZBUFFER) +//D3DTS +_CONSTANT(D3DTS_WORLD,OT_INTEGER,D3DTS_WORLD) +_CONSTANT(D3DTS_VIEW,OT_INTEGER,D3DTS_VIEW) +_CONSTANT(D3DTS_PROJECTION,OT_INTEGER,D3DTS_PROJECTION) +_CONSTANT(D3DTS_TEXTURE0,OT_INTEGER,D3DTS_TEXTURE0) +_CONSTANT(D3DTS_TEXTURE1,OT_INTEGER,D3DTS_TEXTURE1) +_CONSTANT(D3DTS_TEXTURE2,OT_INTEGER,D3DTS_TEXTURE2) +_CONSTANT(D3DTS_TEXTURE3,OT_INTEGER,D3DTS_TEXTURE3) +_CONSTANT(D3DTS_TEXTURE4,OT_INTEGER,D3DTS_TEXTURE4) +_CONSTANT(D3DTS_TEXTURE5,OT_INTEGER,D3DTS_TEXTURE5) +_CONSTANT(D3DTS_TEXTURE6,OT_INTEGER,D3DTS_TEXTURE6) +_CONSTANT(D3DTS_TEXTURE7,OT_INTEGER,D3DTS_TEXTURE7) +// +_CONSTANT(D3DX_PI,OT_INTEGER,D3DX_PI) +//RS +_CONSTANT(D3DRS_ZENABLE,OT_INTEGER,D3DRS_ZENABLE) +_CONSTANT(D3DRS_FILLMODE,OT_INTEGER,D3DRS_FILLMODE) +_CONSTANT(D3DRS_SHADEMODE,OT_INTEGER,D3DRS_SHADEMODE) +_CONSTANT(D3DRS_ZWRITEENABLE,OT_INTEGER,D3DRS_ZWRITEENABLE) +_CONSTANT(D3DRS_ALPHATESTENABLE,OT_INTEGER,D3DRS_ALPHATESTENABLE) +_CONSTANT(D3DRS_LASTPIXEL,OT_INTEGER,D3DRS_LASTPIXEL) +_CONSTANT(D3DRS_SRCBLEND,OT_INTEGER,D3DRS_SRCBLEND) +_CONSTANT(D3DRS_DESTBLEND,OT_INTEGER,D3DRS_DESTBLEND) +_CONSTANT(D3DRS_CULLMODE,OT_INTEGER,D3DRS_CULLMODE) +_CONSTANT(D3DRS_ZFUNC,OT_INTEGER,D3DRS_ZFUNC) +_CONSTANT(D3DRS_ALPHAREF,OT_INTEGER,D3DRS_ALPHAREF) +_CONSTANT(D3DRS_ALPHAFUNC,OT_INTEGER,D3DRS_ALPHAFUNC) +_CONSTANT(D3DRS_DITHERENABLE,OT_INTEGER,D3DRS_DITHERENABLE) +_CONSTANT(D3DRS_ALPHABLENDENABLE,OT_INTEGER,D3DRS_ALPHABLENDENABLE) +_CONSTANT(D3DRS_FOGENABLE,OT_INTEGER,D3DRS_FOGENABLE) +_CONSTANT(D3DRS_SPECULARENABLE,OT_INTEGER,D3DRS_SPECULARENABLE) +_CONSTANT(D3DRS_FOGCOLOR,OT_INTEGER,D3DRS_FOGCOLOR) +_CONSTANT(D3DRS_FOGTABLEMODE,OT_INTEGER,D3DRS_FOGTABLEMODE) +_CONSTANT(D3DRS_FOGSTART,OT_INTEGER,D3DRS_FOGSTART) +_CONSTANT(D3DRS_FOGEND,OT_INTEGER,D3DRS_FOGEND) +_CONSTANT(D3DRS_FOGDENSITY,OT_INTEGER,D3DRS_FOGDENSITY) +_CONSTANT(D3DRS_RANGEFOGENABLE,OT_INTEGER,D3DRS_RANGEFOGENABLE) +_CONSTANT(D3DRS_STENCILENABLE,OT_INTEGER,D3DRS_STENCILENABLE) +_CONSTANT(D3DRS_STENCILFAIL,OT_INTEGER,D3DRS_STENCILFAIL) +_CONSTANT(D3DRS_STENCILZFAIL,OT_INTEGER,D3DRS_STENCILZFAIL) +_CONSTANT(D3DRS_STENCILPASS,OT_INTEGER,D3DRS_STENCILPASS) +_CONSTANT(D3DRS_STENCILFUNC,OT_INTEGER,D3DRS_STENCILFUNC) +_CONSTANT(D3DRS_STENCILREF,OT_INTEGER,D3DRS_STENCILREF) +_CONSTANT(D3DRS_STENCILMASK,OT_INTEGER,D3DRS_STENCILMASK) +_CONSTANT(D3DRS_STENCILWRITEMASK,OT_INTEGER,D3DRS_STENCILWRITEMASK) +_CONSTANT(D3DRS_TEXTUREFACTOR,OT_INTEGER,D3DRS_TEXTUREFACTOR) +_CONSTANT(D3DRS_WRAP0,OT_INTEGER,D3DRS_WRAP0) +_CONSTANT(D3DRS_WRAP1,OT_INTEGER,D3DRS_WRAP1) +_CONSTANT(D3DRS_WRAP2,OT_INTEGER,D3DRS_WRAP2) +_CONSTANT(D3DRS_WRAP3,OT_INTEGER,D3DRS_WRAP3) +_CONSTANT(D3DRS_WRAP4,OT_INTEGER,D3DRS_WRAP4) +_CONSTANT(D3DRS_WRAP5,OT_INTEGER,D3DRS_WRAP5) +_CONSTANT(D3DRS_WRAP6,OT_INTEGER,D3DRS_WRAP6) +_CONSTANT(D3DRS_WRAP7,OT_INTEGER,D3DRS_WRAP7) +_CONSTANT(D3DRS_CLIPPING,OT_INTEGER,D3DRS_CLIPPING) +_CONSTANT(D3DRS_LIGHTING,OT_INTEGER,D3DRS_LIGHTING) +_CONSTANT(D3DRS_AMBIENT,OT_INTEGER,D3DRS_AMBIENT) +_CONSTANT(D3DRS_FOGVERTEXMODE,OT_INTEGER,D3DRS_FOGVERTEXMODE) +_CONSTANT(D3DRS_COLORVERTEX,OT_INTEGER,D3DRS_COLORVERTEX) +_CONSTANT(D3DRS_LOCALVIEWER,OT_INTEGER,D3DRS_LOCALVIEWER) +_CONSTANT(D3DRS_NORMALIZENORMALS,OT_INTEGER,D3DRS_NORMALIZENORMALS) +_CONSTANT(D3DRS_DIFFUSEMATERIALSOURCE,OT_INTEGER,D3DRS_DIFFUSEMATERIALSOURCE) +_CONSTANT(D3DRS_SPECULARMATERIALSOURCE,OT_INTEGER,D3DRS_SPECULARMATERIALSOURCE) +_CONSTANT(D3DRS_AMBIENTMATERIALSOURCE,OT_INTEGER,D3DRS_AMBIENTMATERIALSOURCE) +_CONSTANT(D3DRS_EMISSIVEMATERIALSOURCE,OT_INTEGER,D3DRS_EMISSIVEMATERIALSOURCE) +_CONSTANT(D3DRS_VERTEXBLEND,OT_INTEGER,D3DRS_VERTEXBLEND) +_CONSTANT(D3DRS_CLIPPLANEENABLE,OT_INTEGER,D3DRS_CLIPPLANEENABLE) +_CONSTANT(D3DRS_POINTSIZE,OT_INTEGER,D3DRS_POINTSIZE) +_CONSTANT(D3DRS_POINTSIZE_MIN,OT_INTEGER,D3DRS_POINTSIZE_MIN) +_CONSTANT(D3DRS_POINTSPRITEENABLE,OT_INTEGER,D3DRS_POINTSPRITEENABLE) +_CONSTANT(D3DRS_POINTSCALEENABLE,OT_INTEGER,D3DRS_POINTSCALEENABLE) +_CONSTANT(D3DRS_POINTSCALE_A,OT_INTEGER,D3DRS_POINTSCALE_A) +_CONSTANT(D3DRS_POINTSCALE_B,OT_INTEGER,D3DRS_POINTSCALE_B) +_CONSTANT(D3DRS_POINTSCALE_C,OT_INTEGER,D3DRS_POINTSCALE_C) +_CONSTANT(D3DRS_MULTISAMPLEANTIALIAS,OT_INTEGER,D3DRS_MULTISAMPLEANTIALIAS) +_CONSTANT(D3DRS_MULTISAMPLEMASK,OT_INTEGER,D3DRS_MULTISAMPLEMASK) +_CONSTANT(D3DRS_PATCHEDGESTYLE,OT_INTEGER,D3DRS_PATCHEDGESTYLE) +_CONSTANT(D3DRS_DEBUGMONITORTOKEN,OT_INTEGER,D3DRS_DEBUGMONITORTOKEN) +_CONSTANT(D3DRS_POINTSIZE_MAX,OT_INTEGER,D3DRS_POINTSIZE_MAX) +_CONSTANT(D3DRS_INDEXEDVERTEXBLENDENABLE,OT_INTEGER,D3DRS_INDEXEDVERTEXBLENDENABLE) +_CONSTANT(D3DRS_COLORWRITEENABLE,OT_INTEGER,D3DRS_COLORWRITEENABLE) +_CONSTANT(D3DRS_TWEENFACTOR,OT_INTEGER,D3DRS_TWEENFACTOR) +_CONSTANT(D3DRS_BLENDOP,OT_INTEGER,D3DRS_BLENDOP) +_CONSTANT(D3DRS_POSITIONDEGREE,OT_INTEGER,D3DRS_POSITIONDEGREE) +_CONSTANT(D3DRS_NORMALDEGREE,OT_INTEGER,D3DRS_NORMALDEGREE) +_CONSTANT(D3DRS_SCISSORTESTENABLE,OT_INTEGER,D3DRS_SCISSORTESTENABLE) +_CONSTANT(D3DRS_SLOPESCALEDEPTHBIAS,OT_INTEGER,D3DRS_SLOPESCALEDEPTHBIAS) +_CONSTANT(D3DRS_ANTIALIASEDLINEENABLE,OT_INTEGER,D3DRS_ANTIALIASEDLINEENABLE) +_CONSTANT(D3DRS_MINTESSELLATIONLEVEL,OT_INTEGER,D3DRS_MINTESSELLATIONLEVEL) +_CONSTANT(D3DRS_MAXTESSELLATIONLEVEL,OT_INTEGER,D3DRS_MAXTESSELLATIONLEVEL) +_CONSTANT(D3DRS_ADAPTIVETESS_X,OT_INTEGER,D3DRS_ADAPTIVETESS_X) +_CONSTANT(D3DRS_ADAPTIVETESS_Y,OT_INTEGER,D3DRS_ADAPTIVETESS_Y) +_CONSTANT(D3DRS_ADAPTIVETESS_Z,OT_INTEGER,D3DRS_ADAPTIVETESS_Z) +_CONSTANT(D3DRS_ADAPTIVETESS_W,OT_INTEGER,D3DRS_ADAPTIVETESS_W) +_CONSTANT(D3DRS_ENABLEADAPTIVETESSELLATION,OT_INTEGER,D3DRS_ENABLEADAPTIVETESSELLATION) +_CONSTANT(D3DRS_TWOSIDEDSTENCILMODE,OT_INTEGER,D3DRS_TWOSIDEDSTENCILMODE) +_CONSTANT(D3DRS_CCW_STENCILFAIL,OT_INTEGER,D3DRS_CCW_STENCILFAIL) +_CONSTANT(D3DRS_CCW_STENCILZFAIL,OT_INTEGER,D3DRS_CCW_STENCILZFAIL) +_CONSTANT(D3DRS_CCW_STENCILPASS,OT_INTEGER,D3DRS_CCW_STENCILPASS) +_CONSTANT(D3DRS_CCW_STENCILFUNC,OT_INTEGER,D3DRS_CCW_STENCILFUNC) +_CONSTANT(D3DRS_COLORWRITEENABLE1,OT_INTEGER,D3DRS_COLORWRITEENABLE1) +_CONSTANT(D3DRS_COLORWRITEENABLE2,OT_INTEGER,D3DRS_COLORWRITEENABLE2) +_CONSTANT(D3DRS_COLORWRITEENABLE3,OT_INTEGER,D3DRS_COLORWRITEENABLE3) +_CONSTANT(D3DRS_BLENDFACTOR,OT_INTEGER,D3DRS_BLENDFACTOR) +_CONSTANT(D3DRS_SRGBWRITEENABLE,OT_INTEGER,D3DRS_SRGBWRITEENABLE) +_CONSTANT(D3DRS_DEPTHBIAS,OT_INTEGER,D3DRS_DEPTHBIAS) +_CONSTANT(D3DRS_WRAP8,OT_INTEGER,D3DRS_WRAP8) +_CONSTANT(D3DRS_WRAP9,OT_INTEGER,D3DRS_WRAP9) +_CONSTANT(D3DRS_WRAP10,OT_INTEGER,D3DRS_WRAP10) +_CONSTANT(D3DRS_WRAP11,OT_INTEGER,D3DRS_WRAP11) +_CONSTANT(D3DRS_WRAP12,OT_INTEGER,D3DRS_WRAP12) +_CONSTANT(D3DRS_WRAP13,OT_INTEGER,D3DRS_WRAP13) +_CONSTANT(D3DRS_WRAP14,OT_INTEGER,D3DRS_WRAP14) +_CONSTANT(D3DRS_WRAP15,OT_INTEGER,D3DRS_WRAP15) +_CONSTANT(D3DRS_SEPARATEALPHABLENDENABLE,OT_INTEGER,D3DRS_SEPARATEALPHABLENDENABLE) +_CONSTANT(D3DRS_SRCBLENDALPHA,OT_INTEGER,D3DRS_SRCBLENDALPHA) +_CONSTANT(D3DRS_DESTBLENDALPHA,OT_INTEGER,D3DRS_DESTBLENDALPHA) +_CONSTANT(D3DRS_BLENDOPALPHA,OT_INTEGER,D3DRS_BLENDOPALPHA) +_CONSTANT(D3DRS_FORCE_DWORD,OT_INTEGER,D3DRS_FORCE_DWORD) +_END_NAMESPACE(DX,NULL) \ No newline at end of file diff --git a/vscript/languages/squirrel/DXSquirrel/DXSquirrel_Device.cpp b/vscript/languages/squirrel/DXSquirrel/DXSquirrel_Device.cpp new file mode 100644 index 00000000..807fa963 --- /dev/null +++ b/vscript/languages/squirrel/DXSquirrel/DXSquirrel_Device.cpp @@ -0,0 +1,151 @@ +#include "stdafx.h" +#include "sqplusWin32.h" +#include "DXSquirrel_Binds.h" + +extern WNDCLASSEX gWC; +extern IDirect3D9 * gpD3D; + +_MEMBER_FUNCTION_IMPL(Device,constructor) +{ + StackHandler sa(v); + + //PARSES the params + SquirrelObject params = sa.GetObjectHandle(2); + + D3DPRESENT_PARAMETERS d3dpp; + ZeroMemory( &d3dpp, sizeof(d3dpp) ); + //defaults + d3dpp.Windowed = TRUE; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; + d3dpp.EnableAutoDepthStencil = TRUE; + d3dpp.AutoDepthStencilFormat = D3DFMT_D16; + d3dpp.BackBufferWidth = 640; + d3dpp.BackBufferHeight = 480; + //windowed + if(params.Exists(_T("Windowed"))) { + d3dpp.Windowed = params.GetBool(_T("Windowed"))? TRUE : FALSE; + } + if(params.Exists(_T("SwapEffect"))) { + d3dpp.SwapEffect = (D3DSWAPEFFECT)params.GetInt(_T("SwapEffect")); + } + if(params.Exists(_T("BackBufferFormat"))) { + d3dpp.BackBufferFormat = (D3DFORMAT)params.GetInt(_T("BackBufferFormat")); + } + if(params.Exists(_T("EnableAutoDepthStencil"))) { + d3dpp.EnableAutoDepthStencil = params.GetBool(_T("EnableAutoDepthStencil"))? TRUE : FALSE; + } + if(params.Exists(_T("AutoDepthStencilFormat"))) { + d3dpp.AutoDepthStencilFormat = (D3DFORMAT)params.GetInt(_T("AutoDepthStencilFormat")); + } + if(params.Exists(_T("BackBufferWidth"))) { + d3dpp.BackBufferWidth = params.GetInt(_T("BackBufferWidth")); + } + if(params.Exists(_T("BackBufferHeight"))) { + d3dpp.BackBufferHeight = params.GetInt(_T("BackBufferHeight")); + } + + + //create the window + HWND hWnd = CreateWindow( _T("DXSquirrel"), _T("DXSquirrel"), + 0, CW_USEDEFAULT, CW_USEDEFAULT, d3dpp.BackBufferWidth, d3dpp.BackBufferHeight, + NULL, NULL, gWC.hInstance, NULL ); + + if(!hWnd) return sa.ThrowError(_T("Error creating the window")); + EnableWindow(hWnd,TRUE); + ShowWindow(hWnd,SW_SHOW); + //d3dpp.hDeviceWindow = hWnd; + //PARSES the params + IDirect3DDevice9 *pDev; + HRESULT hr; + if(FAILED(hr = gpD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, + D3DCREATE_SOFTWARE_VERTEXPROCESSING, + &d3dpp, &pDev))) { + return sa.ThrowError(_T("Error initializing the device")); + } + + + return construct_RefCounted(pDev); +} + +_MEMBER_FUNCTION_IMPL(Device,BeginScene) +{ + StackHandler sa(v); + _CHECK_SELF(IDirect3DDevice9,Device); + if(FAILED(self->BeginScene())) { + return sa.ThrowError(_T("BeginScene failed")); + } + return 0; +} + +_MEMBER_FUNCTION_IMPL(Device,EndScene) +{ + StackHandler sa(v); + _CHECK_SELF(IDirect3DDevice9,Device); + if(FAILED(self->EndScene())) { + return sa.ThrowError(_T("EndScene failed")); + } + return 0; +} + +//params (this,flags,[color],[z],[stencil]) +_MEMBER_FUNCTION_IMPL(Device,Clear) +{ + StackHandler sa(v); + _CHECK_SELF(IDirect3DDevice9,Device); + FLOAT z = 1.0f; + DWORD color = 0xFF000000; + DWORD stencil = 0; + INT params = sa.GetParamCount(); + if(params > 2) { + color = (DWORD)sa.GetInt(3); + } + if(params > 3) { + z = sa.GetFloat(4); + } + if(params > 4) { + stencil = (DWORD)sa.GetInt(4); + } + HRESULT hr; + if(FAILED(hr = self->Clear(0,NULL,(DWORD)sa.GetInt(2),color,z,stencil))) + { + return sa.ThrowError(_T("Clear failed")); + } + + return 0; +} + +_MEMBER_FUNCTION_IMPL(Device,Present) +{ + StackHandler sa(v); + _CHECK_SELF(IDirect3DDevice9,Device); + self->Present(NULL,NULL,NULL,NULL); + return 0; +} + +_MEMBER_FUNCTION_IMPL(Device,SetTransform) +{ + StackHandler sa(v); + _CHECK_SELF(IDirect3DDevice9,Device); + _CHECK_INST_PARAM(mat,3,D3DXMATRIX,Matrix); + self->SetTransform((D3DTRANSFORMSTATETYPE)sa.GetInt(2),mat); + return 0; +} + +_MEMBER_FUNCTION_IMPL(Device,SetRenderState) +{ + StackHandler sa(v); + _CHECK_SELF(IDirect3DDevice9,Device); + self->SetRenderState((D3DRENDERSTATETYPE)sa.GetInt(2),(DWORD)sa.GetInt(3)); + return 0; +} + +_BEGIN_CLASS(Device) +_MEMBER_FUNCTION(Device,constructor,2,_T("xt")) +_MEMBER_FUNCTION(Device,BeginScene,0,NULL) +_MEMBER_FUNCTION(Device,EndScene,0,NULL) +_MEMBER_FUNCTION(Device,Present,0,NULL) +_MEMBER_FUNCTION(Device,Clear,-2,_T("xnnnn")) +_MEMBER_FUNCTION(Device,SetTransform,3,_T("xnx")) +_MEMBER_FUNCTION(Device,SetRenderState,3,_T("xnn|b")) +_END_CLASS(Device) \ No newline at end of file diff --git a/vscript/languages/squirrel/DXSquirrel/DXSquirrel_Math.cpp b/vscript/languages/squirrel/DXSquirrel/DXSquirrel_Math.cpp new file mode 100644 index 00000000..d2b6c647 --- /dev/null +++ b/vscript/languages/squirrel/DXSquirrel/DXSquirrel_Math.cpp @@ -0,0 +1,532 @@ +#include "stdafx.h" +#include "sqplus.h" +#include "DXSquirrel_Binds.h" + +_IMPL_NATIVE_CONSTRUCTION(Vector3,D3DXVECTOR3); + +_MEMBER_FUNCTION_IMPL(Vector3,constructor) +{ + D3DXVECTOR3 temp; + D3DXVECTOR3 *newv = NULL; + StackHandler sa(v); + int nparams = sa.GetParamCount(); + switch(nparams) { + case 1: + temp.x = 0; + temp.y = 0; + temp.z = 0; + break; + case 2: + if(sa.GetType(2) == OT_INSTANCE) { + _CHECK_INST_PARAM(vec,2,D3DXVECTOR3,Vector3); + if(vec) temp = *vec; + else return sa.ThrowError(_T("Vector3() invalid instance type")); + } + break; + case 4: + temp.x = sa.GetFloat(2); + temp.y = sa.GetFloat(3); + temp.z = sa.GetFloat(4); + break; + default: + return sa.ThrowError(_T("Vector3() wrong parameters")); + } + newv = new D3DXVECTOR3(temp); + return construct_Vector3(newv); +} + + +_MEMBER_FUNCTION_IMPL(Vector3,_set) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXVECTOR3,Vector3); + const SQChar *s = sa.GetString(2); + int index = s?s[0]:sa.GetInt(2); + switch(index) { + case 0: case 'x': case 'r': + return sa.Return(self->x = sa.GetFloat(3)); + break; + case 1: case 'y': case 'g': + return sa.Return(self->y = sa.GetFloat(3)); + break; + case 2: case 'z': case 'b': + return sa.Return(self->z = sa.GetFloat(3)); + break; + } + + return SQ_ERROR; +} + +_MEMBER_FUNCTION_IMPL(Vector3,_get) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXVECTOR3,Vector3); + const SQChar *s = sa.GetString(2); + if(s && (s[1] != 0)) + return SQ_ERROR; + int index = s && (s[1] == 0)?s[0]:sa.GetInt(2); + switch(index) { + case 0: case 'x': case 'r': return sa.Return(self->x); break; + case 1: case 'y': case 'g': return sa.Return(self->y); break; + case 2: case 'z': case 'b': return sa.Return(self->z); break; + } + return SQ_ERROR; +} + +_MEMBER_FUNCTION_IMPL(Vector3,_nexti) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXVECTOR3,Vector3); + int index = -1; + if(sa.GetType(2) == OT_NULL) { + index = -1; + }else { + const SQChar *s = sa.GetString(2); + if(s && (s[1] != 0)) + return SQ_ERROR; + index = s && (s[1] == 0)?s[0]:sa.GetInt(2); + } + switch(index) { + case 0xFFFFFFFF: return sa.Return(_T("x")); + case 0: case 'x': case 'r': return sa.Return(_T("y")); + case 1: case 'y': case 'g': return sa.Return(_T("z")); + case 2: case 'z': case 'b': return sa.Return(); + } + return sa.Return(_T("invalid index")); +} + +_MEMBER_FUNCTION_IMPL(Vector3,_cmp) +{ + + StackHandler sa(v); + _CHECK_SELF(D3DXVECTOR3,Vector3); + _CHECK_INST_PARAM(vec,2,D3DXVECTOR3,Vector3); + if((*self) == (*vec)) + return sa.Return(0); + if((*self) < (*vec)) + return sa.Return(-1); + return sa.Return(1); +} + +_MEMBER_FUNCTION_IMPL(Vector3,_add) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXVECTOR3,Vector3); + _CHECK_INST_PARAM(vec,2,D3DXVECTOR3,Vector3); + D3DXVECTOR3 tv = (*self)+(*vec); + SquirrelObject so = new_Vector3(tv); + return sa.Return(so); +} + +_MEMBER_FUNCTION_IMPL(Vector3,_sub) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXVECTOR3,Vector3); + _CHECK_INST_PARAM(vec,2,D3DXVECTOR3,Vector3); + D3DXVECTOR3 tv = (*self)-(*vec); + SquirrelObject so = new_Vector3(tv); + return sa.Return(so); +} + +_MEMBER_FUNCTION_IMPL(Vector3,_mul) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXVECTOR3,Vector3); + D3DXVECTOR3 tv = (*self)*sa.GetFloat(2); + SquirrelObject so = new_Vector3(tv); + return sa.Return(so); +} + +_MEMBER_FUNCTION_IMPL(Vector3,_div) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXVECTOR3,Vector3); + D3DXVECTOR3 tv = (*self)/sa.GetFloat(2); + SquirrelObject so = new_Vector3(tv); + return sa.Return(so); +} + +_MEMBER_FUNCTION_IMPL(Vector3,DotProduct) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXVECTOR3,Vector3); + _CHECK_INST_PARAM(vec,2,D3DXVECTOR3,Vector3); + return sa.Return(D3DXVec3Dot(self,vec)); +} + +_MEMBER_FUNCTION_IMPL(Vector3,CrossProduct) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXVECTOR3,Vector3); + _CHECK_INST_PARAM(vec,2,D3DXVECTOR3,Vector3); + D3DXVECTOR3 ret; + D3DXVec3Cross(&ret,self,vec); + SquirrelObject so = new_Vector3(ret); + return sa.Return(so); +} + +_MEMBER_FUNCTION_IMPL(Vector3,SquareDistance) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXVECTOR3,Vector3); + _CHECK_INST_PARAM(vec,2,D3DXVECTOR3,Vector3); + D3DXVECTOR3 tmp = *self - *vec; + return sa.Return(D3DXVec3LengthSq(&tmp)); +} + +_MEMBER_FUNCTION_IMPL(Vector3,Distance) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXVECTOR3,Vector3); + _CHECK_INST_PARAM(vec,2,D3DXVECTOR3,Vector3); + D3DXVECTOR3 tmp = *self - *vec; + return sa.Return(D3DXVec3Length(&tmp)); +} + +_MEMBER_FUNCTION_IMPL(Vector3,Length) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXVECTOR3,Vector3); + return sa.Return(D3DXVec3Length(self)); +} + +_MEMBER_FUNCTION_IMPL(Vector3,SquareLength) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXVECTOR3,Vector3); + return sa.Return(D3DXVec3LengthSq(self)); +} + +_MEMBER_FUNCTION_IMPL(Vector3,Normalize) +{ + _CHECK_SELF(D3DXVECTOR3,Vector3); + D3DXVec3Normalize(self,self); + return 0; +} + +_MEMBER_FUNCTION_IMPL(Vector3,GetNormalized) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXVECTOR3,Vector3); + D3DXVECTOR3 tmp; + D3DXVec3Normalize(&tmp,self); + SquirrelObject so = new_Vector3(tmp); + return sa.Return(so); +} + + +_BEGIN_CLASS(Vector3) +_MEMBER_FUNCTION(Vector3,constructor,-1,_T(".n|xnn")) +_MEMBER_FUNCTION(Vector3,_set,3,_T("xs|n")) +_MEMBER_FUNCTION(Vector3,_get,2,_T("xs|n")) +_MEMBER_FUNCTION(Vector3,_add,2,_T("xx")) +_MEMBER_FUNCTION(Vector3,_sub,2,_T("xx")) +_MEMBER_FUNCTION(Vector3,_mul,2,_T("xn")) +_MEMBER_FUNCTION(Vector3,_div,2,_T("xn")) +_MEMBER_FUNCTION(Vector3,_nexti,2,_T("x")) +_MEMBER_FUNCTION(Vector3,_cmp,2,_T("xx")) +_MEMBER_FUNCTION(Vector3,DotProduct,2,_T("xx")) +_MEMBER_FUNCTION(Vector3,CrossProduct,2,_T("xx")) +_MEMBER_FUNCTION(Vector3,SquareDistance,2,_T("xx")) +_MEMBER_FUNCTION(Vector3,Distance,2,_T("xx")) +_MEMBER_FUNCTION(Vector3,Length,1,_T("x")) +_MEMBER_FUNCTION(Vector3,SquareLength,1,_T("x")) +_MEMBER_FUNCTION(Vector3,Normalize,1,_T("x")) +_MEMBER_FUNCTION(Vector3,GetNormalized,1,_T("x")) +_END_CLASS(Vector3) + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +_IMPL_NATIVE_CONSTRUCTION(Matrix,D3DXMATRIX); + +_MEMBER_FUNCTION_IMPL(Matrix,constructor) +{ + D3DXMATRIX temp; + D3DXMATRIX *newm = NULL; + StackHandler sa(v); + switch(sa.GetParamCount()) { + case 1: + D3DXMatrixIdentity(&temp); + break; + case 2: + if(sa.GetType(2) == OT_INSTANCE) { + _CHECK_INST_PARAM(mat,2,D3DXMATRIX,Matrix); + if(mat) temp = *mat; + else return sa.ThrowError(_T("Matrix() invalid instance type")); + } + else { + SquirrelObject arr = sa.GetObjectHandle(2); + if(arr.Len() != 16) { + return sa.ThrowError(_T("Matrix(array) need a 16 elements array")); + } + FLOAT *fp = (FLOAT*)&temp.m; + SquirrelObject idx,val; + if(arr.BeginIteration()) { + while(arr.Next(idx,val)) { + fp[idx.ToInteger()] = val.ToFloat(); + } + arr.EndIteration(); + } + } + break; + default: + return sa.ThrowError(_T("Matrix() wrong number of parameters")); + break; + } + newm = new D3DXMATRIX(temp); + return construct_Matrix(newm); +} + +_MEMBER_FUNCTION_IMPL(Matrix,_set) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXMATRIX,Matrix); + int index = sa.GetInt(2); + if(index < 0 && index > 4*4) + return SQ_ERROR; + ((FLOAT *)self->m)[index] = sa.GetFloat(2); + return SQ_OK; +} + +_MEMBER_FUNCTION_IMPL(Matrix,_get) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXMATRIX,Matrix); + int index = sa.GetInt(2); + if(index < 0 && index > 4*4) + return SQ_ERROR; + return sa.Return(((FLOAT *)self->m)[index]); +} + +_MEMBER_FUNCTION_IMPL(Matrix,_add) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXMATRIX,Matrix); + _CHECK_INST_PARAM(mat,2,D3DXMATRIX,Matrix); + D3DXMATRIX tm = (*self)+(*mat); + SquirrelObject so = new_Matrix(tm); + return sa.Return(so); +} + +_MEMBER_FUNCTION_IMPL(Matrix,_sub) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXMATRIX,Matrix); + _CHECK_INST_PARAM(mat,2,D3DXMATRIX,Matrix); + D3DXMATRIX tm = (*self)-(*mat); + SquirrelObject so = new_Matrix(tm); + return sa.Return(so); +} + +_MEMBER_FUNCTION_IMPL(Matrix,_mul) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXMATRIX,Matrix); + int t = sa.GetType(2); + if(t == OT_INSTANCE) { + _CHECK_INST_PARAM(mat,2,D3DXMATRIX,Matrix); + D3DXMATRIX tm = (*self)*(*mat); + SquirrelObject so = new_Matrix(tm); + return sa.Return(so); + } + D3DXMATRIX tm = (*self)*sa.GetFloat(2); + SquirrelObject so = new_Matrix(tm); + return sa.Return(so); +} + +_MEMBER_FUNCTION_IMPL(Matrix,_div) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXMATRIX,Matrix); + D3DXMATRIX tm = (*self)/sa.GetFloat(2); + SquirrelObject so = new_Matrix(tm); + return sa.Return(so); +} + +_MEMBER_FUNCTION_IMPL(Matrix,CreateIdentity) +{ + _CHECK_SELF(D3DXMATRIX,Matrix); + D3DXMatrixIdentity(self); + return 0; +} + +_MEMBER_FUNCTION_IMPL(Matrix,CreateRotationAxis) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXMATRIX,Matrix); + _CHECK_INST_PARAM(vec,2,D3DXVECTOR3,Vector3); + D3DXMatrixRotationAxis(self,vec,sa.GetFloat(3)); + return 0; +} + +_MEMBER_FUNCTION_IMPL(Matrix,CreateRotationAngles) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXMATRIX,Matrix); + _CHECK_INST_PARAM(vec,2,D3DXVECTOR3,Vector3); + D3DXMatrixRotationAxis(self,vec,sa.GetFloat(3)); + return 0; +} + +_MEMBER_FUNCTION_IMPL(Matrix,CreateScalingMatrix) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXMATRIX,Matrix); + D3DXMatrixScaling(self,sa.GetFloat(2),sa.GetFloat(3),sa.GetFloat(4)); + return 0; +} + +_MEMBER_FUNCTION_IMPL(Matrix,CreateTranslationMatrix) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXMATRIX,Matrix); + D3DXMatrixTranslation(self,sa.GetFloat(2),sa.GetFloat(3),sa.GetFloat(4)); + return 0; +} +_MEMBER_FUNCTION_IMPL(Matrix,CreateLookAtMatrix) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXMATRIX,Matrix); + _CHECK_INST_PARAM(eye,2,D3DXVECTOR3,Vector3); + _CHECK_INST_PARAM(at,3,D3DXVECTOR3,Vector3); + _CHECK_INST_PARAM(up,4,D3DXVECTOR3,Vector3); + D3DXMatrixLookAtLH(self,eye,at,up); + return 0; +} + +_MEMBER_FUNCTION_IMPL(Matrix,CreatePerspectiveFovMatrix) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXMATRIX,Matrix); + D3DXMatrixPerspectiveFovLH(self,sa.GetFloat(2),sa.GetFloat(3),sa.GetFloat(4),sa.GetFloat(5)); + return 0; +} + +_MEMBER_FUNCTION_IMPL(Matrix,RotateAngles) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXMATRIX,Matrix); + _CHECK_INST_PARAM(vec,2,D3DXVECTOR3,Vector3); + D3DXMatrixRotationYawPitchRoll(self,vec->y,vec->x,vec->z); + return 0; +} + + +_MEMBER_FUNCTION_IMPL(Matrix,RotateAxis) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXMATRIX,Matrix); + _CHECK_INST_PARAM(vec,2,D3DXVECTOR3,Vector3); + D3DXMatrixRotationAxis(self,vec,sa.GetFloat(3)); + return 0; +} + +_MEMBER_FUNCTION_IMPL(Matrix,Translate) +{ + _CHECK_SELF(D3DXMATRIX,Matrix); + _CHECK_INST_PARAM(vec,2,D3DXVECTOR3,Vector3); + D3DXMATRIX temp; + D3DXMatrixTranslation(&temp,vec->x,vec->y,vec->z); + D3DXMatrixMultiply(self,&temp,self); + return 0; +} + +_MEMBER_FUNCTION_IMPL(Matrix,Scale) +{ + _CHECK_SELF(D3DXMATRIX,Matrix); + _CHECK_INST_PARAM(vec,2,D3DXVECTOR3,Vector3); + D3DXMATRIX temp; + D3DXMatrixScaling(&temp,vec->x,vec->y,vec->z); + D3DXMatrixMultiply(self,&temp,self); + return 0; +} + +_MEMBER_FUNCTION_IMPL(Matrix,GetInverse) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXMATRIX,Matrix); + D3DXMATRIX temp; + D3DXMatrixInverse(&temp,NULL,self); + SquirrelObject so = new_Matrix(temp); + return sa.Return(so); +} + +_MEMBER_FUNCTION_IMPL(Matrix,GetTransposed) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXMATRIX,Matrix); + D3DXMATRIX temp; + D3DXMatrixTranspose(&temp,self); + SquirrelObject so = new_Matrix(temp); + return sa.Return(so); +} + +_MEMBER_FUNCTION_IMPL(Matrix,GetInverseTransposed) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXMATRIX,Matrix); + D3DXMATRIX temp; + D3DXMatrixInverse(&temp,NULL,self); + D3DXMatrixTranspose(&temp,&temp); + SquirrelObject so = new_Matrix(temp); + return sa.Return(so); +} + +_MEMBER_FUNCTION_IMPL(Matrix,Invert) +{ + _CHECK_SELF(D3DXMATRIX,Matrix); + D3DXMatrixInverse(self,NULL,self); + return 0; +} + +_MEMBER_FUNCTION_IMPL(Matrix,TransformCoord) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXMATRIX,Matrix); + _CHECK_INST_PARAM(vec,2,D3DXVECTOR3,Vector3); + D3DXVECTOR3 ret; + D3DXVec3TransformCoord(&ret,vec,self); + SquirrelObject so = new_Vector3(ret); + return sa.Return(so); +} + +_MEMBER_FUNCTION_IMPL(Matrix,TransformNormal) +{ + StackHandler sa(v); + _CHECK_SELF(D3DXMATRIX,Matrix); + _CHECK_INST_PARAM(vec,2,D3DXVECTOR3,Vector3); + D3DXVECTOR3 ret; + D3DXVec3TransformNormal(&ret,vec,self); + SquirrelObject so = new_Vector3(ret); + return sa.Return(so); +} + + +_BEGIN_CLASS(Matrix) +_MEMBER_FUNCTION(Matrix,constructor,-1,_T(".a|x")) +_MEMBER_FUNCTION(Matrix,_set,2,_T("xn")) +_MEMBER_FUNCTION(Matrix,_get,2,_T("xn")) +_MEMBER_FUNCTION(Matrix,_add,2,_T("xx")) +_MEMBER_FUNCTION(Matrix,_sub,2,_T("xx")) +_MEMBER_FUNCTION(Matrix,_mul,2,_T("xx|n")) +_MEMBER_FUNCTION(Matrix,_div,2,_T("xn")) +_MEMBER_FUNCTION(Matrix,CreateIdentity,1,_T("x")) +_MEMBER_FUNCTION(Matrix,CreateRotationAxis,3,_T("xxn")) +_MEMBER_FUNCTION(Matrix,CreateRotationAngles,2,_T("xx")) +_MEMBER_FUNCTION(Matrix,CreateScalingMatrix,4,_T("xnnn")) +_MEMBER_FUNCTION(Matrix,CreateTranslationMatrix,4,_T("xnnn")) +_MEMBER_FUNCTION(Matrix,CreateLookAtMatrix,4,_T("xxxx")) +_MEMBER_FUNCTION(Matrix,CreatePerspectiveFovMatrix,5,_T("xnnnn")) +_MEMBER_FUNCTION(Matrix,RotateAngles,2,_T("xx")) +_MEMBER_FUNCTION(Matrix,RotateAxis,3,_T("xxn")) +_MEMBER_FUNCTION(Matrix,Translate,2,_T("xx")) +_MEMBER_FUNCTION(Matrix,Scale,2,_T("xx")) +_MEMBER_FUNCTION(Matrix,GetInverse,1,_T("x")) +_MEMBER_FUNCTION(Matrix,GetTransposed,1,_T("x")) +_MEMBER_FUNCTION(Matrix,GetInverseTransposed,1,_T("x")) +_MEMBER_FUNCTION(Matrix,Invert,1,_T("x")) +_MEMBER_FUNCTION(Matrix,TransformCoord,2,_T("xx")) +_MEMBER_FUNCTION(Matrix,TransformNormal,2,_T("xx")) +_END_CLASS(Matrix) + diff --git a/vscript/languages/squirrel/DXSquirrel/DXSquirrel_Mesh.cpp b/vscript/languages/squirrel/DXSquirrel/DXSquirrel_Mesh.cpp new file mode 100644 index 00000000..2d8d18b3 --- /dev/null +++ b/vscript/languages/squirrel/DXSquirrel/DXSquirrel_Mesh.cpp @@ -0,0 +1,37 @@ +#include "stdafx.h" +#include "sqplusWin32.h" +#include "DXSquirrel_Binds.h" + +_MEMBER_FUNCTION_IMPL(BaseMesh,constructor) +{ + StackHandler sa(v); + return sa.ThrowError(_T("BaseMesh cannot be constructed directly")); +} + +_MEMBER_FUNCTION_IMPL(BaseMesh,DrawSubset) +{ + StackHandler sa(v); + _CHECK_SELF(ID3DXBaseMesh,BaseMesh) + self->DrawSubset(sa.GetInt(2)); + return 0; +} + +_BEGIN_CLASS(BaseMesh) +_MEMBER_FUNCTION(BaseMesh,constructor,NULL,NULL) +_MEMBER_FUNCTION(BaseMesh,DrawSubset,2,_T("xn")) +_END_CLASS(BaseMesh) + +_MEMBER_FUNCTION_IMPL(Mesh,constructor) +{ + _CHECK_INST_PARAM(dev,2,IDirect3DDevice9,Device); + ID3DXMesh *pMesh; + if( FAILED(D3DXCreateTeapot(dev,&pMesh,NULL))) { + MessageBox(NULL, _T("Could not create the mesh"), _T("Meshes.exe"), MB_OK); + return E_FAIL; + } + return construct_RefCounted(pMesh); +} + +_BEGIN_CLASS(Mesh) +_MEMBER_FUNCTION(Mesh,constructor,2,_T("xx")) +_END_CLASS_INHERITANCE(Mesh,BaseMesh) \ No newline at end of file diff --git a/vscript/languages/squirrel/DXSquirrel/ReadMe.txt b/vscript/languages/squirrel/DXSquirrel/ReadMe.txt new file mode 100644 index 00000000..d95bccbb --- /dev/null +++ b/vscript/languages/squirrel/DXSquirrel/ReadMe.txt @@ -0,0 +1,53 @@ +======================================================================== + WIN32 APPLICATION : DXSquirrel Project Overview +======================================================================== + +AppWizard has created this DXSquirrel application for you. +This file contains a summary of what you will find in each of the files that +make up your DXSquirrel application. + + +DXSquirrel.vcproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +DXSquirrel.cpp + This is the main application source file. + +///////////////////////////////////////////////////////////////////////////// +AppWizard has created the following resources: + +DXSquirrel.rc + This is a listing of all of the Microsoft Windows resources that the + program uses. It includes the icons, bitmaps, and cursors that are stored + in the RES subdirectory. This file can be directly edited in Microsoft + Visual C++. + +Resource.h + This is the standard header file, which defines new resource IDs. + Microsoft Visual C++ reads and updates this file. +DXSquirrel.ico + This is an icon file, which is used as the application's icon (32x32). + This icon is included by the main resource file DXSquirrel.rc. + +small.ico + This is an icon file, which contains a smaller version (16x16) + of the application's icon. This icon is included by the main resource + file DXSquirrel.rc. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named DXSquirrel.pch and a precompiled types file named StdAfx.obj. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/vscript/languages/squirrel/DXSquirrel/Resource.h b/vscript/languages/squirrel/DXSquirrel/Resource.h new file mode 100644 index 00000000..670be347 --- /dev/null +++ b/vscript/languages/squirrel/DXSquirrel/Resource.h @@ -0,0 +1,29 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by DXSquirrel.rc +// + +#define IDS_APP_TITLE 103 + +#define IDR_MAINFRAME 128 +#define IDD_DXSQUIRREL_DIALOG 102 +#define IDD_ABOUTBOX 103 +#define IDM_ABOUT 104 +#define IDM_EXIT 105 +#define IDI_DXSQUIRREL 107 +#define IDI_SMALL 108 +#define IDC_DXSQUIRREL 109 +#define IDC_MYICON 2 +#define IDC_STATIC -1 +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS + +#define _APS_NO_MFC 130 +#define _APS_NEXT_RESOURCE_VALUE 129 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 110 +#endif +#endif diff --git a/vscript/languages/squirrel/DXSquirrel/dxsquirrel.nut b/vscript/languages/squirrel/DXSquirrel/dxsquirrel.nut new file mode 100644 index 00000000..ab678982 --- /dev/null +++ b/vscript/languages/squirrel/DXSquirrel/dxsquirrel.nut @@ -0,0 +1,44 @@ +local presentparams = { + Windowed = true, + SwapEffect = DX.D3DSWAPEFFECT_DISCARD, + BackBufferFormat = DX.D3DFMT_A8R8G8B8, + EnableAutoDepthStencil = true, + AutoDepthStencilFormat = DX.D3DFMT_D16, + BackBufferWidth = 800, + BackBufferHeight = 600 +} + + +local dev = Device(presentparams); + +//INIT the mesh +local mesh = Mesh(dev); +local perspective = Matrix(); +local view = Matrix(); +local world = Matrix(); +local eye = Vector3( 0.0, 3.0,-5.0 ); +local lookat = Vector3( 0.0, 0.0, 0.0 ); +local upVec = Vector3( 0.0, 1.0, 0.0 ); + +view.CreateLookAtMatrix(eye,lookat,upVec); +perspective.CreatePerspectiveFovMatrix(DX.D3DX_PI/4, 640.0/480, 1.0, 100.0) + +dev.SetTransform(DX.D3DTS_VIEW,view); +dev.SetTransform(DX.D3DTS_PROJECTION,perspective); + +dev.SetRenderState(DX.D3DRS_ZENABLE,true); +dev.SetRenderState(DX.D3DRS_AMBIENT,0xFFFFFFFF); + +//MAIN LOOP +local rot = Vector3(0,0,0); +while(DX.Update()) { + dev.Clear(DX.D3DCLEAR_TARGET|DX.D3DCLEAR_ZBUFFER,0xFF0000FF); + dev.BeginScene(); + rot.y += 0.1; + world.RotateAngles(rot); + dev.SetTransform(DX.D3DTS_WORLD,world); + mesh.DrawSubset(0); + // + dev.EndScene(); + dev.Present(); +} diff --git a/vscript/languages/squirrel/DXSquirrel/small.ico b/vscript/languages/squirrel/DXSquirrel/small.ico new file mode 100644 index 0000000000000000000000000000000000000000..d551aa3aaf80adf9b7760e2eb8de95a5c3e53df6 GIT binary patch literal 23558 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 +#include + +// C RunTime Header Files +#include +#include +#include +#include + +#include "squirrel.h" diff --git a/vscript/languages/squirrel/HISTORY b/vscript/languages/squirrel/HISTORY new file mode 100644 index 00000000..fee33064 --- /dev/null +++ b/vscript/languages/squirrel/HISTORY @@ -0,0 +1,341 @@ +***version 2.2.3 stable*** +-added sq_getfunctioninfo +-added compile time flag SQUSEDOUBLE to use double precision floats +-added global slot _floatsize_ int the base lib to recognize single precision and double precision builds +-sq_wakeupvm can now resume the vm with an exception +-added sqstd_format +-generators can now be instantiated by calling sq_call() or closure.call() +-fixed a bug in sqstd_printcallstack(thx takayuki_h) +-fixed modulo by zero(thx jup) +-fixed negative enums and constants +-fixed generator crash bug if invoked as tail call (thx Mr.Accident) +-fixed some minor bug + +***2008-09-24 *** +***version 2.2.2 stable*** +-fixed some behaviour inconsistencies in thread.call() and thread.wakeup() (thx Mr.Accident) +-fixed coroutine error propagation +-fixed lingering return value from native function (thx Tom Leonard) +-fixed a bug if array.sort() is given a bad sort function (thx Tom Leonard) +-fixed some minor api bug +-added sq_arrayremove() and sq_arrayinsert() + +***2008-05-16 *** +***version 2.2.1 stable*** +-fixed a tailcall bug + +***2008-02-17 *** +***version 2.2 stable *** +-added _newslot metamethod in classes +-added enums added constants +-added sq_pushconsttable, sq_setconsttable +-added default param +-added octal literals(thx Dinosaur) +-fixed debug hook, 'calls' and 'returns' are properly notified in the same number. +-fixed a coroutine bug + +***2007-07-29 *** +***version 2.1.2 stable*** +-new behaviour for generators iteration using foreach +now when a generator is iterated by foreach the value returned by a 'return val' statement +will terminate the iteration but will not be returned as foreach iteration +-added sq_setclassudsize() +-added sq_clear() +-added table.clear(), array.clear() +-fixed sq_cmp() (thx jyuill) +-fixed minor bugs + +***2006-08-21 *** +***version 2.1.1 stable*** +-vm refactoring +-optimized internal function memory layout +-new global symbol _version_ (is the version string) +-code size optimization for float literals(on 32bits float builts) +-now the raw ref API(sq_addref etc...) is fully reentrant. +-fixed a bug in sq_getdelegate() now pushes null if the object doesn't have a delegate(thx MatzeB) +-improved C reference performances in NO_GARBAGE_COLLECTOR builds +-sq_getlocal() now enumerates also outer values. +-fixed regexp library for GCC users. + +***2006-03-19 *** +***version 2.1 stable*** +-added static class fields, new keyword static +-added 64bits architecture support +-added global slot _intsize_ int the base lib to recognize 32bits and 64bits builds +-added functions with fixed environment, closure.bindenv() built-in function +-all types except userdata and null implement the tostring() method +-string concatenation now invokes metamethod _tostring +-new metamethods for class objects _newmember and _inherited +-sq_call() sq_resume() sq_wakeupvm() have a new signature +-new C referencing implementation(scales more with the amount of references) +-refactored hash table +-new api functions sq_newslot(),sq_tobool(),sq_getbase(), sq_instanceof(), sq_bindenv() +-the api func sq_createslot was deprecated but still supported in form of C macro on top of sq_newslot +-sq_setreleasehook() now also works for classes +-stream.readstr() and stream.writestr() have been deprecated(this affects file and blob) +-fixed squirrel.h undeclared api calls +-fixed few minor bugs +-SQChar is now defined as wchar_t +-removed warning when building with -Wall -pedantic for GCC users +-added new std io function writeclosuretofile() +-added new std string functions strip(),rstrip(),lstrip() and split() +-regular expressions operators (+,*) now have more POSIX greedyness behaviour +-class constructors are now invoked as normal functions + +***2005-10-02 *** +***version 2.0.5 stable*** +-fixed some 64bits incompatibilities (thx sarge) +-fixed minor bug in the stdlib format() function (thx Rick) +-fixed a bug in dofile() that was preventing to compile empty files +-added new API sq_poptop() & sq_getfreevariable() +-some performance improvements + +***2005-08-14 *** +***version 2.0.4 stable*** +-weak references and related API calls +-added sq_objtobool() +-class instances memory policies improved(1 mem allocation for the whole instance) +-typetags are now declared as SQUserPointer instead of unsigned int +-first pass for 64bits compatibility +-fixed minor bug in the stdio stream +-fixed a bug in format() +-fixed bug in string.tointeger() and string.tofloat() + +***2005-06-24 *** +***version 2.0.3 stable*** +-dofile() and loadfile() in the iolib now can decode ASCII, UTF8 files UCS2 big-endian and little-endian +-sq_setparamscheck() : now typemesk can check for null +-added string escape sequence \xhhhh +-fixed some C++ standard incompatibilities + +***2005-05-15 *** +***version 2.0.2 stable*** +-performances improvements (expecially for GCC users) +-removed all dependencies from C++ exception handling +-various bugfixes + +***2005-04-12 *** +***version 2.0.1 stable*** +-various bugfixes +-sq_setparamscheck() now allows spaces in the typemask + +***2005-04-03 *** +***version 2.0 stable*** +-added API sq_gettypetag() +-added built-in function to the bool type(tointeger, tostring etc...) + +***2005-02-27 *** +***version 2.0 release candidate 1(RC 1)*** +-added API sq_reseterror() +-modified sq_release() +-now class instances can be cloned +-various bufixes + +***2005-01-26 *** +***version 2.0 beta 1*** +-added bool type +-class properties can be redefined in a derived class +-added ops *= /= and %= +-new syntax for class attributes declaration instead of ( and ) +-increased the max number of literals per function from 65535 to 16777215 +-now free variables have proper lexical scoping +-added API sq_createinstance(), sq_pushbool(), sq_getbool() +-added built-in function type() +-added built-in function obj.rawin(key) in table,class and instance +-sq_rawget() and sq_rawset() now work also on classes and instances +-the VM no longer uses C++ exception handling (more suitable for embedded devices) +-various bufixes + +***2004-12-21 *** +***version 2.0 alpha 2*** +-globals scoping changed, now if :: is omitted the VM automatically falls back on the root table +-various bufixes +-added class level attributes + +***2004-12-12 *** +***version 2.0 alpha 1*** +-codebase branch from version 1.x +-added classes +-added functions with variable number of parameters(vargc & vargv and the ...) +-0 and 0.0 are now considered 'false' by all conditional statements(if,while,for,?,do-while) +-added new api functions sq_newclass() sq_setinstanceup() sq_getinstanceup() sq_getattributes() sq_setattributes() +-modified api sq_settypetag() + +***2004-11-01 *** +***version 1.0 stable*** +-fixed some minor bug +-improoved operator 'delete' performances +-added scientific notation for float numbers( eg. 2.e16 or 2.e-2) + +***2004-08-30 *** +***version 1.0 release candidate 2(RC 2)*** +-fixed bug in the vm(thx Pierre Renaux) +-fixed bug in the optimizer(thx Pierre Renaux) +-fixed some bug in the documentation(thx JD) +-added new api functions for raw object handling +-removed nested multiline comments +-reduced memory footprint in C references + +***2004-08-23 *** +***version 1.0 release candidate 1(RC 1)*** +-fixed division by zero +-the 'in' operator and obj.rawget() do not query the default delegate anymore +-added function sq_getprintfunc() +-added new standard library 'auxlib'(implements default error handlers) + +***2004-07-12 *** +***version 1.0 beta 4*** +-fixed a bug in the integer.tochar() built-in method +-fixed unary minus operator +-fixed bug in dofile() +-fixed inconsistency between != and == operators(on float/integer comparison) +-added javascript style unsigned right shift operator '>>>' +-added array(size) constructor built-in function +-array.resize(size,[fill]) built-in function accepts an optional 'fill' value +-improved debug API, added sq_getclosureinfo() and sq_setnativeclosurename() + +***2004-05-23 *** +***version 1.0 beta 3*** +-minor vm bug fixes +-string allocation is now faster +-tables and array memory usage is now less conservative(they shrink) +-added regular expression routines in the standard library +-The 'c' expression now accepts only 1 character(thx irbrian) +-multiline strings <[ ]> have been substituted with C# style verbatim strings (eg. @"string") +-added new keyword 'parent' for accessing the delegate of tables and unserdata +-The metamethod '_clone' has been renamed '_cloned' +-the _delslot metamethod's behaviour and prototype have been changed +-new default function in the integer and float object 'tochar()' +-the built-in function chcode2string has been removed +-the default method [table].getdelegate() has been removed +-new api sq_rawdeleteslot() +-new table built-in method rawdelete(key) +-the dynamic mudule loading has been removed from the standard distribution +-some optimizations in the VM + +***2004-04-21 *** +***version 1.0 beta 2*** +-minor compiler/parser bug fixes +-sq_newclosure has a different prototype, the "paramscheck" of paramter has been moved to the new function sq_setparamscheck() +-sq_setparamscheck allows to add automatic parameters type checking in native closures +-sq_compile() lost the lineinfo parameter +-new api sq_enabledebuginfo() globally sets compiler's debug info generation +-added consistency check on bytecode serialization +-fixed += operator, now works on strings like + +-added global slot in the base lib _charsize_ to recognize unicode builds from ascii builds runtime +-added registry table +-new api call sq_pushregistrytable() +-added type tag to the userdata type sq_settypetag() +-sq_getuserdata now queries the userdata typetag +-the built in function collect_garbage() as been renamed collectgarbage() for consistency reasons +-new standard libraries(sqlibs are now obsolete) + +***2004-02-20 *** +***version 1.0 beta 1*** +-fixed a bug in the compiler (thanks Martin Kofler) +-fixed bug in the switch case statement +-fixed the _unm metamethod +-fixed minor bugs in the API +-fixed automatic stack resizing +-first beta version + first pass code clean up in the VM and base lib + first pass code coverege test has been done on VM and built-in lib +-new VM creation API sq_open() sq_close() (sq_newvm and sq_releasevm are now obsolete) +-new api allows to specifiy a "print" function to output text(sq_printfunc) +-added some small optimizations +-new cooperative multi-threading capabilities in the base library(coroutines), VMs are now a built in type("thread") +-new built in functions have been added for manipulating the new "thread" type +-friend virtual machines share the same root table, error handler and debug hook by default +-new compile time options + +***2004-01-19 *** +***version 0.9 alpha*** +-fixed a garbage collection bug +-fixed some API bugs(thanks to Joshua Jensen) +-fixed tail calls (in the version 0.8 the tail call optimization was erroneously disabled) +-new function parameters semantic, now passing a wrong number of parameters generates an exception +-native closures have now a built in parameter number checking +-sq_rawget and sq_rawset now work also on arrays +-sq_getsize now woks also on userdata +-the userdata release hook prototype is changed(now passes the size of the userdata) +-the lexer reader function now returns an integer instead of a char that allows better error checking on the input(thx Joshua Jensen) +-faster compiler +-try/catch blocks do not cause any runtime memory allocation anymore + +***2003-12-06 *** +***version 0.8 alpha*** +-fixed a bug that was preventing to have callable userdata throught the metamethod _call +-fixed a garbage collection bug +-fixed == operator now can compare correctly different types +-new built in method getstackinfos(level) +-improoved line informations precision for the debug hook +-new api call sq_compilebuffer() +-new built-in api function compilestring() +-new syntactic sugar for function declarations inside tables +-the debug API has been finalized + +***2003-11-17 *** +***version 0.7 alpha*** +-fixed critical bug SQInteger the tail call system +-fixed bug in the continue statement code generation +-fixed func call param issue(thanks to Rewoonenco Andrew) +-added _delslot metamethod(thanks to Rewoonenco Andrew) +-new multiline string expression ( delimited by <[ and ]> ) +-normal strings ("") do not allow embedded new line anymore +-reduced vm memory footprint(C refs are shared between friend VMs) +-new api method sq_deleteslot() +-new debug hook event 'r' is triggered when a function returns + +***2003-11-04 *** +***version 0.6 alpha*** +-fixed switch statement(was executing the default case after a break) +-sq_call() doesn't pop the closure (just the params) +-the vm execution can be suspended from the C API anytime (micro-threads) +-new api calls sq_suspendvm() sq_wakeupvm() sq_getvmstate() and sq_reservestack() + +***2003-10-13 *** +***version 0.5 alpha*** +-fixed some minor bug +-tested with non ASCII identifiers in unicode mode(I've tried chinese chars) +-added built-in function string.find() +-the built-in function array.sort() optionally accepts a cmp(a,b) function +-the debug hook function now has a new prototype debug_hook(event_type,sourcefile,line,functionname) +-fixed some debug info imprecision + +***2003-10-01 *** +***version 0.4 alpha*** +-faster VM +-sq_call will pop arguments and closure also in case of failure +-fixed a bug in sq_remove +-now the VM detects delegation cycles(and throws an exception) +-new operators ++ and -- +-new operator ',' comma operator +-fixed some expression precedence issue +-fixed bug in sq_arraypop + +***2003-09-15 *** +***version 0.3 alpha*** +-fixed a bug in array::insert() +-optional Unicode core(define SQUNICODE or _UNICODE on Win32) +-sq_compiler uses a new reader function SQLEXREADFUNC +-the debug hook passes 'l' instead of 'line' for line callbacks + and 'c' instead of 'call' for call callbacks +-new array.extend() bulit-in function +-new API sq_clone() + +***2003-09-10 *** +***version 0.2 pre-alpha*** +-new completely reentrant VM (sq_open and sq_close are now obsolete) +-sq_newvm() has a new prototype +-allocators are now global and linked in the VM +-_newslot meta method added +-rawset creates a slot if doesn't exists +-the compiler error callback pass the vm handle(thanks Pierre Renaux) +-sq_setforeignptr() sq_getforeingptr() are now public +-sq_resume() now is possible to resume generators from C +-sq_getlasterror() retrieve the last thrown error +-improved docs + +***2003-09-06 *** +***version 0.1 pre-alpha*** +first release diff --git a/vscript/languages/squirrel/Makefile b/vscript/languages/squirrel/Makefile new file mode 100644 index 00000000..a2843059 --- /dev/null +++ b/vscript/languages/squirrel/Makefile @@ -0,0 +1,18 @@ + +SQUIRREL=. +MAKE=make + +sq32: + cd squirrel; $(MAKE) + cd sqstdlib; $(MAKE) + cd sq; $(MAKE) + +sqprof: + cd squirrel; $(MAKE) sqprof + cd sqstdlib; $(MAKE) sqprof + cd sq; $(MAKE) sqprof + +sq64: + cd squirrel; $(MAKE) sq64 + cd sqstdlib; $(MAKE) sq64 + cd sq; $(MAKE) sq64 diff --git a/vscript/languages/squirrel/README b/vscript/languages/squirrel/README new file mode 100644 index 00000000..dbd17078 --- /dev/null +++ b/vscript/languages/squirrel/README @@ -0,0 +1,22 @@ +The programming language SQUIRREL 2.2.3 stable + +-------------------------------------------------- +The project has been compiled and run on Windows(Windows XP/2000 on Intel x86 Windows XP Pro on AMD x64) and +Linux(Slackware 9.0 on Intel x86, Fedora Core 4 on AMD x64). + +Has been tested with the following compilers: + MS Visual C++ 6.0,7.0,7.1 and 8.0 (32 and 64bits) + MinGW gcc 3.2 (mingw special 20020817-1) + Cygnus gcc 3.2 + Linux gcc 3.2.3 + Linux gcc 4.0.0 (x86 64bits) + + +Feedback and suggestions are appreciated +project page - http://www.squirrel-lang.org +community forums - http://www.squirrel-lang.org/Forums +wiki - http://wiki.squirrel-lang.org +author - alberto@demichelis.net + +END OF README + diff --git a/vscript/languages/squirrel/README_SQPLUS.txt b/vscript/languages/squirrel/README_SQPLUS.txt new file mode 100644 index 00000000..2df2b815 --- /dev/null +++ b/vscript/languages/squirrel/README_SQPLUS.txt @@ -0,0 +1,16 @@ +10/08/05 + +To build and test the minimalSqPlus/ example: + +Open Squirrel.sln and build for Debug and Release. + +Open the minimalSqPlus/minimalSqPlus.sln and build (Debug or Release), then run. +Alternatively, after building testSqPlus2 in Squirrel.sln, set minimalSqPlus as +the Startup Project, then build and run (dependencies are not set for minimalSqPlus +to illustrate building with pre-compiled libs). + +See testSqPlus2/testSqPlus2.cpp for many examples (in the Squirrel.sln solution). + +testSqPlus/testSqPlus.cpp is included to show how the old version using macros was used (it is no longer updated). + +John diff --git a/vscript/languages/squirrel/Solution Items b/vscript/languages/squirrel/Solution Items new file mode 100644 index 00000000..59807918 --- /dev/null +++ b/vscript/languages/squirrel/Solution Items @@ -0,0 +1,14 @@ + + + + + + + diff --git a/vscript/languages/squirrel/doc/sqdbg.chm b/vscript/languages/squirrel/doc/sqdbg.chm new file mode 100644 index 0000000000000000000000000000000000000000..3f4b25d21b0acbf5c03b05d6d8716a0b99f6dd50 GIT binary patch literal 19006 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 literal 0 HcmV?d00001 diff --git a/vscript/languages/squirrel/doc/sqdbg.pdf b/vscript/languages/squirrel/doc/sqdbg.pdf new file mode 100644 index 00000000..14266017 --- /dev/null +++ b/vscript/languages/squirrel/doc/sqdbg.pdf @@ -0,0 +1,494 @@ +%PDF-1.3 +%ª«¬­ +4 0 obj +<< /Type /Info +/Producer (FOP 0.20.5) >> +endobj +5 0 obj +<< /Length 196 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GaqdY]+0EX&;B(lT41D@*+tSN;/4Ut;R\G?OEDk#&6F++6)>^%qht(5^"An`O:%O/^cqrFJZf5C'FZgXJMj2O1`/_b3XrfU>BYFS9hM,(@3_nF3gBoT9Bc3qXP4mt@uMS5.jO.p#ClaLCf.d3?VEJJ<[f`FTjmgRGAS)Ccn@nXebn8]oeWu"qgWh^iWC>m0t%~> +endstream +endobj +6 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 5 0 R +>> +endobj +7 0 obj +<< /Length 1032 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gasao968i1&AJ$CE(_rr;`u\TDGNtK1[1kLh:`p3KHqH]*!CH`mu*-((.W6uT(0&.o'MVOh.MXI+(H"fnJYuh,!bfF7"P/f.#\3ITJY<\-jii&U@5SKShuXoniO49dM2/YRh4D)V6*SD;n]*>Y%oLMAVbt#oFkf.N5l'T"1[mbHe[m"]Ltb5Dg>*S&d(Z[C`:rl'b09+++Z$SDqFFH40_"A<]A/Art-QNPG01U=6;/UWrG.#,2^ZM^.E;WVq-(C$jTJk3uk.)]'Vq_N^QdDo.BZ6**>d*W4O5OMY/o$W&lcb#d'bWF=/Kbhg7qA%pVZOEP(DXpLI`sUf/WLPn+n"3oN(ZcqaCVE=QR1Gf^S8_NnM)\S#;blp\i1agl%]q,ps5?'9@g582-SVc-qn9mbJs,$E7'g*nL#=so:Y=@)[H&/DQ]!-2g2Sr[G'inYY"eVaU[rhBW8g>L1#X*UbuiN2W(tu\\JID7K'9dtlZ0(o<>D6FW@SnF!+g*2X!#Pqeh83A[9U59+:+jIS<:0hrKS_M0b1+u.`l_55eED8/Z+c)QCq_Ks$[<'!O'6s!gV\K*5-nX(X71TcDeOLO"B)EG`"&ZpM8[t6P7fS_@RIJJ6]YXe3PU19QJ^k\lVYl";#Te`d12]At[%@]l=u=TjIq'E5Gcq(/\-uNcKFU[\/F1;`cU\7\DXMeJ7.bZsdD*C*!@)L'8O:T`Z"eQA0r`>pqBF"<&&:SN(Xnf'UP+cb[8.)<%*['SRURShGgs+,./IB>kiUR#<5h\Q^9dN!:2H#LkOfCDtFUTr-p6%jej'EFOU[qe*&Uo[XC%$P:a;b(6gJgM(,gLVGbMe+")*-1VY"'1eY)BY;c[f3EQG6@\ufcb%;uGCR;d\^?otfbREY^KEbR,`[gm:u/4`kSJlJD9;#G8P8TVFb&.JrZ3l/CnLa#NV#El=i7A-3)+at]KTka-i6>G^BDgQQ([eq*LN+fW*4ROgh2t.Rl-50g&1q"H]<^~> +endstream +endobj +8 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 7 0 R +>> +endobj +9 0 obj +<< /Length 71 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Garg^iGoCd.c`?]8EV`b1=.gR0K1`91K?+0ZOMGdU/Zh'Y!=Te%#&:?HH*JE! +endstream +endobj +10 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 9 0 R +>> +endobj +11 0 obj +<< /Length 500 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb"/h4)]a*&:etR`JnDaMdI=@V@P+]qN/1d6QUtO9qeC?l-HOB8Xr1GUoFN2F^k/oR):!5dpWGA34n<<'k%F4/;PDZ-q*d'TGWM.N`2)J$2PAX6Tl@69b7(o.?[:Q+=sjiiC-o!VPl_*n-&U-VNsIlS&JuGB;NfU@Z_5%BUb;#QUJE0W1T%k>ak1qSt!klKQO7$h9>R6&eYfioViB3kt3uUd59gL.kd@GKrGhDZYU&F\m@<.'%5[1j,RQQGKeEW5^>5eB1:\31c"`I=#9MT%Cb0Dam9TGl$q.OlD;p1n':)d@HqE,^%fBI+X-5P38:Y+p95\Q^;:cXomD3IoRdC4RE?5-7K?$8oo>,qOA:j;VVqc,$(5gPR]Y%34Dd>M6MdNgRVkSAD#:SJC;0$JK(5u[NJ)tsQ/\rgnD=.lDB,PW,n`V`Oep2c(>K,s]g"4eKHH_nFs`9O/La4cKPHc4>PNDk"5=c#SH~> +endstream +endobj +12 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 11 0 R +/Annots 13 0 R +>> +endobj +13 0 obj +[ +14 0 R +16 0 R +18 0 R +20 0 R +22 0 R +24 0 R +26 0 R +] +endobj +14 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 655.001 187.48 645.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 15 0 R +/H /I +>> +endobj +16 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 644.001 183.43 634.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 17 0 R +/H /I +>> +endobj +18 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 633.001 242.31 623.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 19 0 R +/H /I +>> +endobj +20 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 622.001 230.65 612.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 21 0 R +/H /I +>> +endobj +22 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 611.001 189.14 601.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 23 0 R +/H /I +>> +endobj +24 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 600.001 183.43 590.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 25 0 R +/H /I +>> +endobj +26 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 589.001 142.77 579.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 27 0 R +/H /I +>> +endobj +28 0 obj +<< /Length 1965 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gatm<>B?Pt'RnB3@(-Z']8csPhKBu]nRgV!g.>!3Th?_b6+1J^&:s5GSc8@)&0QODZIA(57H^=bqfFHR0:\fD:TB(*A6Gqn/<47TH)*tdr"R8k8@MgM1XHgZQa8+'q'!+b6C&a1n54Ff.,Hn,)gTKUg?e+B[!&,+f-ID*(ne=\34NBj#["i':*>NKt`n/8W4Q=!.5ZPW\1$^J6+TRCD@]8/YUp\m,!In[ZRD%9PS`pF`@la>er(^YfTcSW`LVe]Cq"nAd'"CL+iB^A0>7*Z:Aa-IO"L2t_*$cm%9=rSpH[Q%1O"OG(hUJfH(\o$2&pW19+/B\3OLfM?o+E-JSQ][rc9&bljbM0AnD9%XG,K/O,-kGq0%VN&'rPEb3$M1L64^ZTIZWqXdM)lenrTIB27k`]B!@=?$[Fsn.dTkBuAE$5/\15KP?8aB'PKfsM3@"=USt^!MdW*`7LmT#Rh=_NgoSmf-=,42MEHF8ME*l46u8DslKuMbUlLh#H0j&7HpE:_&aUC9.4VMXY6F"=:jTuZkVa",SIu?_K?cZIP3NNk$GP7lQE&Q"I]B1OIgRja'6ipQ?7,bp`5V-R]Jpuir1>WDgq(=b2cB9SHi'eJlbfM9T[WTJi1\>=:bi607+)u@Kpt>*Pu'8j8JEq[7LJ1,mjC3pN=<]4,9iFVC!6RRZ0.,Q8(YLDHr^JjrpXT,joW?gW&2=`c-rmh6pU!c2r?fMH*KG=B\orR<,+'05\::'\2F.ggb8d-d:doqo`jl7\/2s6Jg0hU>M;u)W&e1oNF;]glO8-E[;KeUY:gQP?iNDm'^%?EfWmW%96D\-P[qhAs+YTDO$j0J\X1#>4OrNOaX>V(5NaY%)"oa7)n)(0-&^XLP[&bIHpAXFFh)fM&4;g6@o:,8gUD[]*T1>E])I5I1?]XV8B0&&WQ/11Eic]Y:E([t3hQ*CC9sI]/C;%?@-Kc1(U0m'ocLg)hlJ*9MX0P]8#q'[VqD*1_Xe[EbbFqiG`p%YKpcG#%3HRUuTrJfV>o;J^GmU4$qPPd?Y"+]'rOF_U:>BSj0`j^KMM6WPKe_mU*pO*XWN+dc0KYkecS%KT&fUp[qiITW3-Zbb=m:3e^f<(D0ffdf~> +endstream +endobj +29 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 28 0 R +>> +endobj +30 0 obj +<< /Length 822 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gas1]>u03/'RfGR0MI[.$/@MKj$XOk1c6?g.dc4fP6e0\j-4:).8C3\e,K67-H--nP_[3&\`]R]fb^4970nt_>p-G5$Pj`c>l>dqr'4UEf7OJ4nHA9M/>#)IZVnlBooC`8#NDW^HSpEtH8)!$pmYNRnfqmBkm&7<_gT[q>.iXaqZEW&6\KZZH+M5dX;"%M$8(FV[EP[&EMd`?361Q6d(eq!;r=\`SSYj"k&g=19To<5l(2_1,i)6O)Ld8]D.?dbjs--T/<]GY%q#qD2&KieLNYCMWBqKsAMmE:11-E]U*.N^R,KiD75B4\2$&&Y&7OHS-`ji734*Jao.(p_0DT+sXZ!kgMK?LR+!E5n)d`.rutgk[Iu%d0UL3D>1eqW7cs_#'>=9E*,i6oW_F./(rq_]b(/C_mp"LdP+&GW^s5;8i9\%hbdfT%4(6^>hSF6)1`LVle#+X[-=/LeY/5C!1>t?h`R>5^6cP)^!oO2H6hi>KYXgoLCS48.3DPe<7U>D,noJ'TR0A+]BdDuZ:_$/;>7g`C&7cR*ad.`W9UigRtL*(4UO@MA]#Vt0s``2FMlF[PEF\DV3%F\YdQD>+#d2']]QgufbKX26Jj&!^+)a%,$K4V+Ud[9in?=%@2+G<@d[N0TRS^jl[?=]1TuQ!K_n%;(Y]i$(kZ6^>R$^'Xhm^Kpf7,fi%,:1'Bcd*=d]!s=A34/oTTa`cLmq0bDG?d`Fc01euYig/@U7/m99iIp:~> +endstream +endobj +31 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 30 0 R +>> +endobj +32 0 obj +<< /Length 1571 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatTIgMYb(o\ElJ[jFAWLn_',;q!'tL)/%QmE7U+Zpi_;AC6MfBA(n'OsoikAfM%CJ;!+Tgi[MYj`GN_9cVJLED2neEoK-\$$KSHK:U(NXqSe]$N8&6DOeI;5-='MZJs@opS%p>Z($ElM2-iTa4m(,igq`)_=@akFoHBXJ$g2#'To'>37J]HaRt`tgLiFJ2irq!VdRejE]:P!!`GPeM\(4`<2;A`%McC*1@Q6V7o3snRaS)4i];'uN<\fZYON.DL]i1m?hs?#8E[%G4QfW>BW,_?+:/TN2"dIOGP>0G^J1mq?iJFX'&u,DSkI))(.C+p]dO_=c>'cEDsm(t^ARc+^+.-?c#g6Q"$i-d!Ca$;(YLqt^+jS"$bBcHZHD(KVfh`>9Bq`M0]3q"*Z_9:Jaeb%4-VJh9@@:gUk'Jqh467_q7`ckgU?tc0mZ.BKYt/':"HuAb!>%[e*Y-!Xg+sm@'`)XV.;SW$$h3sW^l`^*q!@XcaQW'E`c*")7rFb=o[;R+(4)1__@j5*uh0_P?!aGCcYYfnJcB(m$d&ce-,qA&*8$sCrmn(e8Ja1L),h]@f^am;dFMtq/1jVlO3*Ml&`P7B3A3lVG0nsJB2EJ1XEA#lj]5-6*opsTPMn>>u/s%j^`OLmb!O704PgQ$uckV2giO8V!I$k*]'C?MoI8qB)f/*-!?*6l6H)(2AREZ,t)L@`EMa7?s8EhE,E(P$@q1]#I`7c+TE`em9FY+=K>-*G692G&%HcfB3=Buc4/d-KYG!!IY&o\;Li;tk;!VO0_7%"<%?&hsK%ukX(VEVH%8tqe:QlD/oX-*KN2=@&r"03AWPJQe3B.gsYu$:KV^r";$+jPAB`'>gK;XA"g[>A?R[)g2NN`V/8bMJfngV123gcpOf[cA]lpLImO8'de_kWM[ie8ceO'2%6U"&?bjnk?+6I]a@7_;a4Y%0#RF)0qaWi^qO2q%/u*km,l*np.'(lu46d:;#(6@[3B)m,I_:od#+ZYk'RQ/Hf%*ia8(neCFpK+4UCJSh[)\RfX2JhK+d3Odbq(Fh(oN=#&WW&t,@?]W*uZ0oVA3(GccWH4LGN-_a"5gYaYN>"EEH==#)p>od\+3^8M!$hP+gSrVX'B#rn\JCnPHG_&,)?5cOT7^8=W'2nXbEraqZLs$ASY![S_*Q[U +endstream +endobj +33 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 32 0 R +>> +endobj +34 0 obj +<< /Length 941 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatU1hf"u<&:Vr4_.+[3'SCsKHYTs3l[GdJbFY$!EkkMP`2:Og[/KYR`oK6K>A4``]!HhBh0hKESRo.f$P[h6n,kH]nT'eQ`mUC>o-`Z;2AhhEq`+;/e:B;>4$oLU"*b6rm9kI)h::\`B94:)@:^fkW1B"\TTP*c50gdT"O52Q2rOqE`@3BBLJ.a>g*'Ts`gL;3B"r&b>56S-L.dl0+7Hd%^Zub>buY;*CT,`CD-C&P]E27"D9/nflgN1MlCL"?4''t+Yt[T+ja_@&cABm+EB:?Ih'Zgp,s8*-D]hqBo]?tg^%BJB?M`3@4]'KTZD#PjF(@l5>\FWO/RZt*Vj1Jd*+sbdf&>SNe1I4b/(XaBLQN6;UX^]0cgD+24"mEbO4>_Ve/8aWjZK"qpANCOQ8f1.n(>^4Q6c.Gg%F\_Et4q@hM?/dO.\,bM/tC0J?PQNNm5*`a2]">KC4Z7Yd90R5I!$S>jM_p\dWVq3R-qS:NV:mGD-b(VU/=[[n#Z/@>[QUY<&224,V&'="fN)e`,Bm'?DL5/H*Y!FeLd3ZgUFc@9ckdj-h/mX_ZB)"/?+h[:]=p?\*#thc.Nc]=p`FS1L&(JRN5Kau1,5+U^l1m!<8/ikcTJ5D?^N0(Nq>X$e#2(U!WRnCELkQm#7:+!(\+7ClJ?@<@uH?JkRY5-16q~> +endstream +endobj +35 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 34 0 R +>> +endobj +36 0 obj +<< /Length 287 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GasJM_/@+D%#44r$6MQC-Ae9M>`gpYgns0k9o.14H6=5F&:=>/Q>R*XTj4\os1ZFngl(D1JS'"a^m@C)7OX@4.EF>F0)mWht;E]SO,5b#q412`=ou,c,oV3.-h`4ms=llYUJ~> +endstream +endobj +37 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 36 0 R +/Annots 38 0 R +>> +endobj +38 0 obj +[ +] +endobj +41 0 obj +<< + /Title (\376\377\0\123\0\161\0\165\0\151\0\162\0\162\0\145\0\154\0\40\0\122\0\145\0\155\0\157\0\164\0\145\0\40\0\104\0\145\0\142\0\165\0\147\0\147\0\145\0\162\0\40\0\61\0\56\0\60) + /Parent 39 0 R + /Next 43 0 R + /A 40 0 R +>> endobj +43 0 obj +<< + /Title (\376\377\0\124\0\141\0\142\0\154\0\145\0\40\0\157\0\146\0\40\0\103\0\157\0\156\0\164\0\145\0\156\0\164\0\163) + /Parent 39 0 R + /Prev 41 0 R + /Next 44 0 R + /A 42 0 R +>> endobj +44 0 obj +<< + /Title (\376\377\0\103\0\150\0\141\0\160\0\164\0\145\0\162\0\240\0\61\0\56\0\240\0\124\0\150\0\145\0\40\0\104\0\145\0\142\0\165\0\147\0\147\0\145\0\162) + /Parent 39 0 R + /First 45 0 R + /Last 47 0 R + /Prev 43 0 R + /Next 48 0 R + /Count -3 + /A 15 0 R +>> endobj +45 0 obj +<< + /Title (\376\377\0\117\0\166\0\145\0\162\0\166\0\151\0\145\0\167) + /Parent 44 0 R + /Next 46 0 R + /A 17 0 R +>> endobj +46 0 obj +<< + /Title (\376\377\0\111\0\156\0\164\0\145\0\147\0\162\0\141\0\164\0\151\0\156\0\147\0\40\0\164\0\150\0\145\0\40\0\144\0\145\0\142\0\165\0\147\0\147\0\145\0\162) + /Parent 44 0 R + /Prev 45 0 R + /Next 47 0 R + /A 19 0 R +>> endobj +47 0 obj +<< + /Title (\376\377\0\124\0\150\0\145\0\40\0\156\0\145\0\164\0\167\0\157\0\162\0\153\0\40\0\160\0\162\0\157\0\164\0\157\0\143\0\157\0\154) + /Parent 44 0 R + /Prev 46 0 R + /A 21 0 R +>> endobj +48 0 obj +<< + /Title (\376\377\0\103\0\150\0\141\0\160\0\164\0\145\0\162\0\240\0\62\0\56\0\240\0\101\0\120\0\111\0\40\0\122\0\145\0\146\0\145\0\162\0\145\0\156\0\143\0\145) + /Parent 39 0 R + /First 49 0 R + /Last 49 0 R + /Prev 44 0 R + /Next 50 0 R + /Count -1 + /A 23 0 R +>> endobj +49 0 obj +<< + /Title (\376\377\0\104\0\145\0\142\0\165\0\147\0\147\0\145\0\162) + /Parent 48 0 R + /A 25 0 R +>> endobj +50 0 obj +<< + /Title (\376\377\0\111\0\156\0\144\0\145\0\170) + /Parent 39 0 R + /Prev 48 0 R + /A 27 0 R +>> endobj +51 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F3 +/BaseFont /Helvetica-Bold +/Encoding /WinAnsiEncoding >> +endobj +52 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F5 +/BaseFont /Times-Roman +/Encoding /WinAnsiEncoding >> +endobj +53 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F10 +/BaseFont /Courier-Oblique +/Encoding /WinAnsiEncoding >> +endobj +54 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F6 +/BaseFont /Times-Italic +/Encoding /WinAnsiEncoding >> +endobj +55 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F1 +/BaseFont /Helvetica +/Encoding /WinAnsiEncoding >> +endobj +56 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F11 +/BaseFont /Courier-Bold +/Encoding /WinAnsiEncoding >> +endobj +57 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F9 +/BaseFont /Courier +/Encoding /WinAnsiEncoding >> +endobj +1 0 obj +<< /Type /Pages +/Count 9 +/Kids [6 0 R 8 0 R 10 0 R 12 0 R 29 0 R 31 0 R 33 0 R 35 0 R 37 0 R ] >> +endobj +2 0 obj +<< /Type /Catalog +/Pages 1 0 R + /Outlines 39 0 R + /PageMode /UseOutlines + >> +endobj +3 0 obj +<< +/Font << /F3 51 0 R /F5 52 0 R /F10 53 0 R /F1 55 0 R /F6 54 0 R /F9 57 0 R /F11 56 0 R >> +/ProcSet [ /PDF /ImageC /Text ] >> +endobj +15 0 obj +<< +/S /GoTo +/D [29 0 R /XYZ 115.0 725.0 null] +>> +endobj +17 0 obj +<< +/S /GoTo +/D [29 0 R /XYZ 115.0 666.009 null] +>> +endobj +19 0 obj +<< +/S /GoTo +/D [29 0 R /XYZ 115.0 589.684 null] +>> +endobj +21 0 obj +<< +/S /GoTo +/D [31 0 R /XYZ 115.0 448.64 null] +>> +endobj +23 0 obj +<< +/S /GoTo +/D [33 0 R /XYZ 115.0 725.0 null] +>> +endobj +25 0 obj +<< +/S /GoTo +/D [33 0 R /XYZ 115.0 687.009 null] +>> +endobj +27 0 obj +<< +/S /GoTo +/D [37 0 R /XYZ 67.0 725.0 null] +>> +endobj +39 0 obj +<< + /First 41 0 R + /Last 50 0 R +>> endobj +40 0 obj +<< +/S /GoTo +/D [10 0 R /XYZ 115.0 725.0 null] +>> +endobj +42 0 obj +<< +/S /GoTo +/D [12 0 R /XYZ 115.0 715.0 null] +>> +endobj +xref +0 58 +0000000000 65535 f +0000012880 00000 n +0000012993 00000 n +0000013085 00000 n +0000000015 00000 n +0000000071 00000 n +0000000358 00000 n +0000000464 00000 n +0000001588 00000 n +0000001694 00000 n +0000001855 00000 n +0000001962 00000 n +0000002554 00000 n +0000002677 00000 n +0000002746 00000 n +0000013232 00000 n +0000002882 00000 n +0000013297 00000 n +0000003018 00000 n +0000013364 00000 n +0000003154 00000 n +0000013431 00000 n +0000003290 00000 n +0000013497 00000 n +0000003426 00000 n +0000013562 00000 n +0000003562 00000 n +0000013629 00000 n +0000003698 00000 n +0000005756 00000 n +0000005864 00000 n +0000006778 00000 n +0000006886 00000 n +0000008550 00000 n +0000008658 00000 n +0000009691 00000 n +0000009799 00000 n +0000010178 00000 n +0000010301 00000 n +0000013693 00000 n +0000013744 00000 n +0000010321 00000 n +0000013809 00000 n +0000010565 00000 n +0000010761 00000 n +0000011032 00000 n +0000011162 00000 n +0000011400 00000 n +0000011600 00000 n +0000011877 00000 n +0000011993 00000 n +0000012105 00000 n +0000012218 00000 n +0000012328 00000 n +0000012443 00000 n +0000012554 00000 n +0000012662 00000 n +0000012774 00000 n +trailer +<< +/Size 58 +/Root 2 0 R +/Info 4 0 R +>> +startxref +13874 +%%EOF diff --git a/vscript/languages/squirrel/doc/sqstdlib2.chm b/vscript/languages/squirrel/doc/sqstdlib2.chm new file mode 100644 index 0000000000000000000000000000000000000000..4d39dd7b69cf3d018f693aefba0fbfa16b15858d GIT binary patch literal 36875 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 kq$v2Tkm&O8X`$rxGr??!%*g+|3;Ms^^#5-`0`> +endobj +5 0 obj +<< /Length 246 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gaqd[\IQJ1&-UA:?a4/j=Osr[Jq*pMi=8^1`.4Za_?id24lM2b[+uF7AnR]0Q4ej;k9Tg),:)c*7W;lXW&kJok9tubis9_(_4P/*D/T*8;Q*)>(=mXhjT`"b>?n0Pb;#0GGp)YQMZ:%Nr.,]Ee)267S5JJPh(qWc.2JUaBD$]k#7;O+_Nj2/Q4AiQp[&KcBNMUK-,KPb[[BBjHJC?@,=d"kc#.j8KbXf_i75B.qFL8(7~> +endstream +endobj +6 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 5 0 R +>> +endobj +7 0 obj +<< /Length 1048 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gasao966RV&AJ$CE(_tHW'$"nl)EoW-Cl43$+I>J!Q(cIL^7FUIpZW@C?=A3PF7AQ=m^\8qW.Nip#]36"WOi=Z>/KJqc2SMl7_XYcptg:pcB1EJX87NpZol_JI4]qNHZ"&?p]Mnle.MPES[cKaYGb!&6k'!()=-').>W,jOO_%3mu-.H5Zrg*7ZCT'5qfQJd2'fg4jP.uP/AOm9f)Fi8hC97%aAZ?aM\KtR]9Gs"XcgV-%V@81=bFEAcul?:gNR,7N3+TWTHC;@TY]Pe7j1];NWPl6@B-o4]oa0%;'OU3=_aJ2%mKF?i!d=n?#rD`fJ8GplF9bD@Bon"3cP(p2tR-ibOaeq:3u`4Uc\WI\d:#Y_LJK$H(rcCq2-d[-:e3-iAcmY!6Kabd@=:<2^7/sU5XW;GI'+)bX^7M2S:eHps3M2#I?[e,4&<4`?tiTG`&_m]>DK9q85sF']rpe[,60WII=9k:?6aVmER%Jp>i2gZgsa2r&:IFNNq]6B.Jh~> +endstream +endobj +8 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 7 0 R +>> +endobj +9 0 obj +<< /Length 71 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Garg^iGoCd.c`?]8EV`b1=.gR0K1`91K?+0ZOMGdU/Zh'Y!=Te%#&:?HH*JE! +endstream +endobj +10 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 9 0 R +>> +endobj +11 0 obj +<< /Length 1275 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb"/l9llag*6.GrMEQ\]$2_`c1!(]3FJdNRE9m.H8dl^SK@iclkmOSI`N7'NX((Wn%fY*'\qfHgs">qd@INiG'C+8p-fJpg+ep)):AID:a)$O@DI<]9P&O*DS:ja(N@j^PH(H$I.`b2)gH*!g-:L$GAet26_GB9i-)"(ZQ1E)@X&;t-\AG_S8(D1M?!Tj!j!WHB,0u#86'5]AEg05+)Qcb2rs+*?TU1HA;'B4)d>Ig?YAkY]\PIGdlW,j5(T1X&7JYAjVFa"5o#L%5-p.&P5p/usnSD4qoruWp7e&G3o-DZBZk;uafB`!XQcl&I9Et\%Fid0Z^G6EO)^G0GB)P9,OkJd)T;Al/+:s=""pb@c7ad<1,^krR=pQfQUKJmUEVLu55bS)06Tlt&hUo`"[1Y8$%nQa4#dat0il2.[oNC3Ff9<"$U,;ZZ/P7A6%hAR*5p4OT'JI[fpZT1"-0tSg#?lPM)m]Qr5eD1Cf?oHoK05ReFil6R-Bh:_&5@o(_(NFW1tB/H>B*-I'k])P$RFbfSdu)0g/d;b!cTD'"$e!UhAs]sXuf#ockl`a]d;C6G[G5]C_ngt)?YXc%m:./#kX/f&/a`&!pt`p@R#NY)^V6TV/NJj>m'(Ol%&J-#o\"PU!VR.jktbX]&B"?KRe.rU]?Ufq-#XNssdD'^NI*bRo([LB-,Na"/%TXR0ZUNj5/mn.U/XB%d/s[VJ[TY0'h8Q%5_;8WV&/dIZl[r(dK4jDXGKW$QO@QPScZYA#7H@AqAOAGa7CNW$kV&JP1:PY7:Vb?70sg:.rftX[KufNH4>6Uptf>`j8hDb?h(SHmJSST`;.3]!BXEX`)Rm/TYM'D#Rh1mO=;Ihgn&]L_amFbR\o0/fsEh!eL&^5:WUn>+=M_SnD4tE>M?(WCeQEEU\7(5jt2n.TqHOK'LJW@9gbn!mbuiJO!M:V4T>XTXYDWpH=:jHHOUIda06O2*3,G0tH\"l^`g3-b@1W`q,K#admI76]'m4n +endstream +endobj +12 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 11 0 R +/Annots 13 0 R +>> +endobj +13 0 obj +[ +14 0 R +16 0 R +18 0 R +20 0 R +22 0 R +24 0 R +26 0 R +28 0 R +30 0 R +32 0 R +34 0 R +36 0 R +38 0 R +40 0 R +42 0 R +44 0 R +46 0 R +48 0 R +50 0 R +52 0 R +54 0 R +56 0 R +58 0 R +60 0 R +62 0 R +64 0 R +66 0 R +68 0 R +70 0 R +72 0 R +74 0 R +76 0 R +78 0 R +80 0 R +82 0 R +84 0 R +86 0 R +88 0 R +] +endobj +14 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 655.001 179.44 645.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 15 0 R +/H /I +>> +endobj +16 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 644.001 228.88 634.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 17 0 R +/H /I +>> +endobj +18 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 633.001 194.83 623.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 19 0 R +/H /I +>> +endobj +20 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 622.001 231.06 612.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 21 0 R +/H /I +>> +endobj +22 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 611.001 205.5 601.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 23 0 R +/H /I +>> +endobj +24 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 600.001 169.28 590.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 25 0 R +/H /I +>> +endobj +26 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 589.001 219.11 579.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 27 0 R +/H /I +>> +endobj +28 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 578.001 210.5 568.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 29 0 R +/H /I +>> +endobj +30 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 567.001 292.71 557.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 31 0 R +/H /I +>> +endobj +32 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 556.001 196.66 546.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 33 0 R +/H /I +>> +endobj +34 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 545.001 194.83 535.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 35 0 R +/H /I +>> +endobj +36 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 534.001 231.06 524.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 37 0 R +/H /I +>> +endobj +38 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 523.001 225.77 513.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 39 0 R +/H /I +>> +endobj +40 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 512.001 169.28 502.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 41 0 R +/H /I +>> +endobj +42 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 501.001 219.11 491.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 43 0 R +/H /I +>> +endobj +44 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 490.001 214.39 480.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 45 0 R +/H /I +>> +endobj +46 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 479.001 198.32 469.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 47 0 R +/H /I +>> +endobj +48 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 468.001 194.83 458.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 49 0 R +/H /I +>> +endobj +50 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 457.001 231.06 447.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 51 0 R +/H /I +>> +endobj +52 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 446.001 169.28 436.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 53 0 R +/H /I +>> +endobj +54 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 435.001 219.11 425.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 55 0 R +/H /I +>> +endobj +56 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 424.001 206.66 414.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 57 0 R +/H /I +>> +endobj +58 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 413.001 194.83 403.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 59 0 R +/H /I +>> +endobj +60 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 402.001 231.06 392.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 61 0 R +/H /I +>> +endobj +62 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 391.001 169.28 381.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 63 0 R +/H /I +>> +endobj +64 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 380.001 219.11 370.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 65 0 R +/H /I +>> +endobj +66 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 369.001 201.66 359.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 67 0 R +/H /I +>> +endobj +68 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 358.001 194.83 348.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 69 0 R +/H /I +>> +endobj +70 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 347.001 231.06 337.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 71 0 R +/H /I +>> +endobj +72 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 336.001 220.49 326.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 73 0 R +/H /I +>> +endobj +74 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 325.001 169.28 315.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 75 0 R +/H /I +>> +endobj +76 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 314.001 219.11 304.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 77 0 R +/H /I +>> +endobj +78 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 303.001 212.45 293.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 79 0 R +/H /I +>> +endobj +80 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 292.001 247.16 282.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 81 0 R +/H /I +>> +endobj +82 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 281.001 194.43 271.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 83 0 R +/H /I +>> +endobj +84 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 270.001 169.28 260.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 85 0 R +/H /I +>> +endobj +86 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 259.001 226.6 249.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 87 0 R +/H /I +>> +endobj +88 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 248.001 142.77 238.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 89 0 R +/H /I +>> +endobj +90 0 obj +<< /Length 971 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gas1_9lHOU&A@P9n8Y3KKWesRgleV$dR2K`83JdmGer`M1,^j6$2sN;0Z5l'C8I3YH"NZH4C`H)D/MO-.#bjW+[T>Bn^2%a+?K1_oT0L)u?7'<'Uc<.IgYI(MXYSh0b7UseQ*4HA+>@ot>=.0YoI#q_d9RA:nfmE="Y]=WF]2C+F1.:S5Ptjk"\nDH/A/3%'Eaf\B&b/"qbEg=^47!#no2XVcga.TRAe30!LU%FfUH]Br5g^OuBPH.:?gGZ2J7ZhGJGWph&\0A'BQ7^Ea[i-@JF\X6RMQf*R;fF,"?Bp.'LHK8,r^ZQ>M<6J\)!\Q:IU03Ya@FDimSA(MM0+Zi+>n^7Y#om:hK)RFBB:X,nb=qJ6YCaT.u>UW24(%@8__iKUmj!F:YFl!J*m_#m,Pn9Tm.FO0TlR(S*ujDD!hQN/CC3L,\uI2JA^tAI5M1_nLm$C8>#~> +endstream +endobj +91 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 90 0 R +>> +endobj +92 0 obj +<< /Length 2083 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau`Uhf%7-&:Vr4+loI0eh[)=$,[h8@NDb@D5`@U1ju$.3n>WNY!f\>rq]L'U[BPbEI^1d!Kt&>ms+b$hFB&6=')m",;5!EQ:9YFHf]Sb=+TP(T>4Zc_Y;J0(MUPSp.R^AYask)\7pQ0VJZ:H.-CDtTUA,k1rnN+qje3<\;K8CLZDb8c\l&3h$N(1iIk5rA[Gg\t$K]rH3F[^GJE@ci-o9W5?NJ)%:g_,>s>E>UnQM%0&leZ@jH,RIpud66mK:";sXK&@&88`gtY"9NG/D-[7X>(,W8iRljkFs@0*)F(P0&W,^'AmeUY[3PmY+.*`-nC!L.ML_/a.Ense3C#tYg1aLhGCq#F8S"DY\`?$F?hCuo!^JHsXSg't5\&#n;i]fn4T/ea.%7Nutfhi("INMFD>kE>`A+rM+ZndhR]WV`=7)So/K\9Q3!&!lmUfl5ZfeZ4p8-@3XQN?Ld]PkpY.g0$#:mUdlt/'8.l!NPCDp5am!!2=_Bl>+3120L'l2HmRZqht$:0E]G,cmK9)F-Pr"a?PgTaB<`a]@%O04b3`6;L-/TAFRpW%J"hLtL7C3.-l2gg:$q*9h;2^Q]("sg`7>7bc3IID(WRE"WRo%=Z=-`k6DI9SDRmW>MjT!9soB\5AEf\)>i;+(k%4rpWk\>*Rd)mtrZV8[",NO)%J\ZIoIJM%OLRa&PF2ke7Rnrr4VKGl2*,si=!;6gr]QY[jFPV&RMa)MF9]%2a]Y"9tW6po'#Phg',SjpQO[No).J<;iH6%V?qVjS`(,/O^;>agHSb1W<"W!0U>knB+4'4aN9?:Dss+PV<%.R[:8:K.KYY'nBi$5?68@'N[b8J"lB8$Z*JF($YiF)^q8KBn5-(7DXZ(noEf[a_=UR]\RQr6dqe%(!ME]udD*1N(*T0;5ep:h=6kFfI$)DG@;MMX:/N4YKI!la+%r#-]'@4h4C%id963q3e6(+#Uo-tgrGejS2;RLuZ]'d=2L"aZ_oG&,K2P?*S#W'TYuWs^[59F!96,BbL^$MEOEG`s3tg;^f&`L2Yq)J.r/7serVV.S,I/6]fiY.h^O/&mO7EF<\:nL49(C6c9AqXa">C>R?#Vk]IS/-=5g1#=^i8Gd=dO@K-Y0P:Zc~> +endstream +endobj +93 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 92 0 R +>> +endobj +94 0 obj +<< /Length 1700 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gatm=bAQW(&Dd46gf5=:@DnKR/\:-t=s+!+[X`SRG9P_*,?0t68PY@rI;+fZLPeL)Llk+oC*%#BUZ%a(bBi^N/&k4%TO>=U(;]RG^ro"Ba?=RsN%dO0?ET@4Y:EI-pWIKuol!_Wl#h;t)@tmfX3LSR]a"M8dNQnJO5PaDs`$bh=-Ml9g\:o@ms(#iQX6P+>*e8VqTmHeL\li477j7aIBKEtb0PHDB^oTM[RE<6I&0Yq,lr$Xl0BoO)!16bT;8$,KFR>k!hK:q1dF.@2h-GKm^dl884=/apD+9O1Sn^)9T$*[D\;8HRA4^GG2Y.3J4:Z4]9n"M0IK[P5&&[USOCN/N^Ni'KnjCLho:6$/D@/F6#5$1C1m!cHdi@@O+qCS<]_+MujCA3@o:'4O`*gkQ0E_.0pQcOo2a&H<,-q9Wn/OQF%D9@Z47$Pi^PZdd^/8IZ>#argK,<2unnoC?qJ$X]q9A/[2n]\*3l,IP=]6cRKNk(Z,\K+225AD59Yc&PcY!V]0?&.0oW_hQ?:!@,U@@"R++d\+S+rjfJl=-ZUFd&/2<&)32P\40j1s1ZOYS@dYWQ#&-ZTA`sXA2SFe=?0h5]dS`gd^A;/h#nLWSWO4>h>]dNSA4t",*g`b+oFbA4=!^0Sps]Z_I5k?TsS)Gg=;Z/kS<,`#.=4Nd9BrHc?ubqUomoGqZJq>Zg91KU7CtYn#NL*,Y+,kVM6p[%h%0u/SSZo/q[nqiSV&L,TR35&/pb_5LXML0'G0a1n>j=M@MCfVjl3dli)O`hQ^KIU1i_CAO`fO#PCh$'jOp%PC#4ce(XXK%>\rh?Q-!O]P.W$]`&C8Y-^e;hYd0IBh6F52dE;MA:(q@6>n27XZY#ftgmh][sQ(4A1b+fs;+/"E`2%cpK/[1c85Fn?nR&A*%\PO,-OSNiLTIT4k`Y-Up:lV08JK+PG;Gm.O1%qeT2#Ku)<;m"<)-S?OTePAs6)C@0%B$q"d:2hjN`M@-O65+6OXBih30CMVpk:cn*DQ^#pKZPJD#7I"g!N`l1&WK-6:02^Jni@!VQunC&)M7;^'+d?i#@Q%U0/X"R:);e.A(2QN"ZKr@*XSJ:RVe+k>m;^O*89VDAAXHen8lVn,*^"sLmG*6rd<;N^T87OW.24RJ$DP5b.GYFc,ced/@3<&M_FDd&R'?l*_I_=O(`FCL)99!GriE1J"0a=bNp#?[SH/_E<%/GON7:naUG-'kH`QBahBM%+$<-s3<~> +endstream +endobj +95 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 94 0 R +>> +endobj +96 0 obj +<< /Length 1355 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatU495iiK&AJ$Cki`^d7\ltaHYS'JFcf+T7(\e'Z(PsfAlk;2&tNk8lUsg63Kbgq:(\W-ORqVY2cT4.amI;nE/7'G,jUH:W5Z@C8>TK^.MV.V4Jd$m[l^,,b"=JL@M5tj]kUJN%pg6,X0WFAbu;qj/;_%e,@2IO#P@>^o_.E04/UG4Y$"SERteI!K(&LU:jj8Zk1"'_QoFM=te-\g]CfES$e-J@)X'EbQak$ie<#kcQA94f2Wj"T'fatG$K;jraO=CT#MUKV;b!1d[mHpGp3jflfbi3=g?ouqJUN6pSh"dE-Wiejn]3#HaHANdEjD>SfZ41H?QCb-M'A[=G$]hY*uj\X?e#_'Q)9G_,b^8F;*ROT7j-qF$dL#)f:cCuN@JUt6ZOcgFi4Im=b/.e0ffGR5F_?;j)"^6Ds5>7kP-[U;a]`Ofbd\al3@1;MoPW,5b_DaFknlR>;RqFa:AhF-%O#GKH,WkoU_\*T1N=/pH3'+T-gGksN'lEB*`6[Zfa?oJ5>X^#K;qOe0YIm>pF=T*PQd.!fY68icQp0l`S80kfurblgr+hbT6/$5Yb;+qUOQ6Ob&er\CPD;H1g@7FE'S7@EQjQBF]L?,!1`Buo::2:/m4XWRI+RS2gs('f^c+F[G#%_#4;7J``Mlc$Al"Wi2UeS6[PP6HEfPHfFUXdFiOo[0q?t1k.GTa&/l_$3s/Hk%Sdp/I"_%?PGTR:ZXOq253[uc)DcHbU73'Dop/_Y3&?>=l6=E=TgN(B6>T8k&H%4m!5Ui8=_@rgDmIjfe;'m&RME'Df0p0E@9'UB+_:"mYlk.ap)L[FbP6k1ZK?M5."1`3!ZO+Cc!&.TY3$$:3Zm18d]c\#2H/76WPJ#Z?<*H]T(kGfE%^((b*(9(1'+%'-O'*~> +endstream +endobj +97 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 96 0 R +>> +endobj +98 0 obj +<< /Length 2063 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb!;d?#SIU'Re<2&Gf;&881rYlJ#DZUO'.l;.eFoF.^mT$0on\A\!dYlo@dAtsHMjrJe%j0[,qYP2?QP.\:?.ThGFFR`QH!Ri5KGHM5]=!Z!M8U+T0HrS/,^_o`9Hf!r`b`jB=J+81+r(rWYH\>n1l?o8hT[C^/2`?_$kd[leJgGKYb`PaLg9ffXDbB]sVbQ"]JV_0=Vu$-fo+6&t!rjcI&Pm$NrXXFkB[e\hZ<*.ckf`Gg=F66$*\/CW%u5RR!)VOhWO-:h!1DsnFbA>Tl;j8em4J81#B-NDdn,\+M4YUfjXU8L2!m4&-;(.`U\WS+AtDuY.UdisRd:ATG5hPhq*?_-!=;gno;oK4>hd]qUCkW68TUT"EJS2%E3N^6c[iYLNu%UWA?%mpGkDi+Nn9tMF_K!\[DVm[C]1q9/gThE`U_CH?)keHgmkrU*a^8f;oj[gThg%q'hu^qaDM%Z#rX+;F(7b'fED+MPbj5SSoK_[j,P9qWTMkuE$p0g=?.7L<7hDQO?,Lp=<,X$FVLHlRXgFRSY*fQt^^l8D4A"]>i\q18U@Xu)';gPVcdR/j(QsjunnV0r<-a&\OYD0Kb"IEa%aBQjBri4K,lMEC<9$j-9>j_n^`/5`(']-HK`QFP^9OWc"71oj:H]>e<^eAck<:CL0H#;"jR^=u`>`F#7$:>HlVQmF-^K(/BKGEq3!nib1Nktr=U.(t[1ej0rW&+KoDG5.G&]/i/pQ2FQ<$D`=-17W("$:Eq)lsoO"9ML&>$P6WO.m9]`I_"H+=88C;+M0,p%KROD0bVLSHhM]W[m')Ua?q4,hSlJ4I1+4*^ekB5r]@qNu*VdS*3j99-ANe)Yl#iU>b.E"elgPg=m,LLkbs0Sj;q"8;B.;K@D4?p_'hB,n?n=^9p6H,%NV50`>[,&:GIZ(W%E"`bPT`E&D#oB&4^H4X%r6Q%cAp'73\XV`#3kJOap9#,c\)),f;[oDb!=T'K0=s":9GYpapa<1ipl.JC*oRSRehLrre]hX6'87PP".[0N#h('48qBBp0>`l!%L5RgrIJ>__6$b$.8oG26I=DKa0,^tPGJ%t'VU4%mL"5,l0\j$iu_RH^[)B_$oB&b>9L[N;2DFJ!5"#8Rlp5?%`>BDd8MUu.J_oMLca)t8b'OU9PjFP@-8jf&1<<'/uUZAVUY'IeHX4_nSm"Z6eg?AN4o-WS2oXNle1d$4m))9>_&Q,qC$N^>5MHGYSRSaEnDB4&(&ZNY(s:`cq-S,Hn>#?3muXUjH%f(Hn9KTR+9&/qSP(mTGR*BHB6hsj'h9!U#!:"Gg?+: +endstream +endobj +99 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 98 0 R +>> +endobj +100 0 obj +<< /Length 727 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gasan?#SFN'Rf.Gp^sB4il!Q^Hg='WVG7edmU_q9"&?*:P12Csm+9R?PM"5Yp(X-gHd;S3EZ=bMEUUI$JYsR[4m7I%(Vp[@lKmc!?m+^YHag.&.U>SuCDTD2Tu/P%V9!dD'A3)&"WlJg!0u\+1&aFb!!JDP=1eg%0o1&3B4!hq[JBbF\74b\Q[?PJT(%sR^b67KFbj&50nEhFLs,U'\pV#KCWFgC6>af02&V`l400skgq4Sg+@'Q`O8U`Tq87$RR,7l<2?6)YKdEXH\8f;Fc_PUNErL>W7<_mf^e&4H5A1Do.Roh-7X+3=n>T,8Hst).#-';#Wk>R/a0VZ$H,A7Se[iOIW*h]aQuL$!h9?JI[WA>'YU#X1bn>B#p=LX&cjNoZMs]f=m'V2EER+&4BWFQ;Zr4hS+f!QJab-_4+64>EbJ;YFih,\Y/clW%TGgo^j*>bgVq3qXOT&)D7Abhu`)2&crQ2.^fuNU[#D(9V+%-dg%g`Z$G+:fsJ!a`Tc<437e`cm:l%bH`?O83Bh*D@%_7ME(0@9DhpUlMWXO'28hjUb~> +endstream +endobj +101 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 100 0 R +>> +endobj +102 0 obj +<< /Length 1445 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gatm<9=(*G']/^gclIE[<4L`)>_I.G<_6E-JA'$cmmlM%#q/s=Fn/M$kLuOeJgM@OJ`sq_DqnZT,:uLk'5s1+=mE,7bJ',a`8G1uU-W,P[3(URB;rk*j\TBc:b;scias'hP]tJYt^$VHC"6SRXg9UEj[P;JT3"HU]P0S.ag*N"\ojQp@k''(cc5AINUqVTEfTSEfu.Yl1[&24FG-A2m+qR:]d]2/jZS=7+S,GkJ,KE?i!>J?5n-IjN_Zk:hpc@c@SUT_UR[4d6bdkW6Tb4Jj)MlaFcnnlS0JbFYO2^?p.8eMg`4j^mh-6pJc;E5U&mJLc8UHshu1c3Hi;9:ggONfci7CB]iH4TS5Kp0jTH5<6N('pl!M9#h`h@=k"7--I74I#EcF0#Y,1X1R"2CY(?LNLY9rU$E#n\nCZ$pn8C"I!Ekc#.7)C[E`+.E[d@daDg@R^pTfCsJ0TdLcu>CK.'f"3)KUT%s2epH!-];3jn9I"^^E*c-3-Qp=DVQrduY^S:$F$]fB&"Xm+dRfEI511H"FL&;D8;\2uJS\,?K-2;S*&R$3BfcC+HehLRXMm`Pm8A^SZB5F&gnEq[W#GC+9-.t6pc[_M.Wb,INa1tPF5H_o-q=NL;,Wq@N@5V]bJeNtXGXoNa`36WF9orV'sM;qF^#=_e^Pp'Wk13aj;48NX:S-Zfj;d^lCf2L9$TVG689b`B(d"De79eDPXmg?!c:[>#?JgM>6H\R/$J8+:"PWo)L$6"u."loP1.l]WNfG2g@`Jbgp_0XX6j9o[eFR^-6pf(rN2U[_GokHF,^KOW[jpkkcL#/R7,Z5cn07+oZG]Q+qM2=6`n)CCS&2*jqLB)_^EH*,US6t;1mUaI<9)kAWgQ&`pHWcq)@3n4Ab/+D3s6586mMo3tINQ5P.oku]-,^-Hs`]u@%hF%#l6Iht;OHWa99B:n!GSG=D#^M^bqqO^rnGR&NYd)-l2fE=od]_EMp[55[X7@[WLtO5kr>sU08p]1Qn'10AI#s,>:7dsAe,csi(e(o`US>U$ItpNe"9~> +endstream +endobj +103 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 102 0 R +>> +endobj +104 0 obj +<< /Length 1752 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb!kuhiFNj&:Vr4_:rRu4V$KoR.dL`[F/*Ue4P"uS5(>\4]I#S5^'R0f67K1*YU5t\o1TE-oNm\^):eV2f0;HqhkYDI=@S0\PnpFi_a=,d/P:S$s%LSW[L:Um6GuIJ,RKJ/op!%CmBC,O1&HAOX(aid`=,D(GJ8J7+_q6r4,K3,9/md+en_+*"#(/FTH&!5GWZZVb+4=,u(lm]jF#CaigMu(?@Ur#L"mY/RXOuj`3$GpZ0P.C,fktS?`"]IEMt_1bakk'[@?@_K5@F$2&Lt"n[nh$%DoB*[+J["S!^WNIQ*M4a!12`B\"HDH4.>5:[('ho(Il6Vs"\d/"g?jbJn82^piB.,>J2XH%iMS_Y0_PVD3'^1@%`9b+J:ro--\U$I]C]WEqVE7Dbrg&;7_-bX>YpI=/0fAh\^4m42-F[$<=lu<%cP'1V7\qOJ2_8RW=-t@b3\Zdm:MolI%7Wt6PthnDVJ%M*sUgo[olDE]b#"aCNHHpa?.(,)"f2]jL[5/JrgPtUnuO?Q^"f!Mrf8o6ZSqaP6,,h*a/o_'F:"1NN+]d)kqh+4/`BiWW(g`e-^rcB&lX\P]NJ;[f,BhJkFS/?B6jNkfPUgAD"[JWJ^i\%at%X'[)F5iL>\%D#D4?o&`@43>7*GFj-V]g!T`)3<_Kdt.6N3JGb+1t:0\Q\8HF'eMomPF:X:5pNm2@Xh)jCZhn7Jgc",JKp3!dJU%+(WbJqZm*f]8Q@'T2N-fY8.&_DQFVE$X>?%mZg%]56f8kJNRQPX`ZU7P)ae,o8+_;;1"b9q(B*3OToe$GC]>P0MV1l2.kKJB2QBL-P3i<=`tq[%B^b;&'mjZ0]\'_nOnmEu2aA=D'HHd5U.5>c+N2U2q!&6bPOnUmck]I609lUj'jMgNI"k'5!\WN,`21@]ASfb$aNFSr5;fjGi6p:sa[aV%(/#KtWMYk="Q2I]DQf#>'c'F>f7<,a)Ni7%3-9h`V3W=%IBtnitJ9RUZrJL5!6'V*k'TD4VUP,aO1:ZY8eU@/8o4RlM*:1*iBL(ek(R:GcPC&0[,-LsFk77RZe\]bS3^KjB;SbjcU5bFRoTp9fpB5'Dh_qNRh&dpZ$erE(M"'&.&GY%];D28Q]mAHV8J8oC$$R\WCh6/,*_$8mCKFX]fO8R31$nE^Bao`2O-DsIE8TsCn>1_P64M?;9:I\pHoGqV`!@KE@uX_V_3lJK-.=p4i3`ApAS2"FP3Qm(=>6A-iq>kiTJ4]kc`W7&Zd?HH@3OA~> +endstream +endobj +105 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 104 0 R +>> +endobj +106 0 obj +<< /Length 1223 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb!;c92jS!&AI=/pf?TTR3-B7ujSa8:?*-:^qs!2?k9N;(^`]1D@'H#k!3.+J&?[?)KL(9CoK)cPF#lHE3'B>qGCs6gqGdP.lB+4ZU'"A?;p($UJhQ[mEq+Lb>g8T1XS7in\0*IF\G3W+j`GflG]IhDo_j"nGSe4(Z?,b]pLEZID,R>H#SRV;lR+?+R:j_@03:n&X.;oK#?4(?;dF#[]B4uCq*C>dDW[\E&rXSj8t.Vr9E,?,Na47h4d>ir(RcXc.+T?GZMd!oUb>8gl_-#Zr3o0V;#dql+"]'(pgl"@UD>1-u^YLF&_';\.&0Hu%sRn'VPrlZ<^@`7>mXZd!B11`9;V5g`W,(5(7o\Y?S>@MTHI6T%4bDDpaN0fY^F(6U?9-L0aaM[/"tXQ8Bq.PL'nF!V`7^fVQLXd4UI'L'r:6OXOTRp+nNNfQ`d\tdYIeGH2n=Be,LPQiae>cohLK'-TcD5sr4?d*P)/+.^`k,ebKVnr'"FmCY+8E[OKn>\@raK:_o1so#>Ia\)r,Eb=Zc"s,?O6WEO)-K/)o._mNpk*Li4iiA78_.Y>Nj.?JcZ;$NISs9;,(LeheEg%BZ5.>!>j#NhgaZ?BjCK\*RJVBBFG08lBQ[mU$&`pQUYEf9c3-Yg[e2kC#@^@L!AsL2$ZN0WQe:IPn?HfHGF%!S"ZRYJA1j-"l[,8!?oW`\9K)Xh'*gk:JK#!Y4;;6eKTBDYp[it0DY=\5C:/'@-fh+H48t:?*32QqPMAdL;.:YTG^m/L]NW:T$O:isUnlQO-^C$sKn?jbqWhKoHemdH0Yi'1N>)C*#7&;R<(jh2c\[i/js_Qn,=7T2Z=BFW@iP'(+m))NOUj~> +endstream +endobj +107 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 106 0 R +>> +endobj +108 0 obj +<< /Length 452 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GasId3H)bg']/F34MlWRF#G&$5c&3#^h'K+38bck85dKYkc\n7A31>@AU2VBG)eP=RegFA4pXOAO`X0W%YV4bG=3!N`?]\[mS4Y48]Pg]^JN0hlBZdT(I1)P;aGO(0I](iR6I4X"9q:kVV,'?aMHBK,j*JE[P)i0M\6$^C*@lt/kT&KHC,lqtSlK9ifY1qS]ZVKpW]55f>K9"KcKV0\IDB58DGH._p?-.>)B2$KfM.@*MDGe^.q;%Jk+2lbY<)G(D%L!sX@&:#!N5kD:ZgBXqNoAl\5(8"p6>q/L%GU`D!Jh~> +endstream +endobj +109 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 108 0 R +>> +endobj +110 0 obj +<< /Length 1150 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GauHLac>C>&A@rkG]X&P)XaCTVp$7i&g0Gkpm0$QG%e>b/T+1PFT6d3D9F9f7@[a40ORusCO**UO!T9Xbhi:H#a\r$+H,oOP0JptMB>:r#>2?T5YFH[2>M=mn]>Wp+!/KJ2[0U^$Vfardd+l9:D\J&rDU:*Q-8+&lN?s@/:PDD'O_\c@Jh9,j80"^,qr7;K(fMb70/]Pb/q:[qE;$ThfN9Gg<\m<^.VOoXt*S?^-$k(f0d19bJnaf/hb5TS.HuAbIUr<@UGf'3"!02qQeE:?ImlRf=pM*j,qCpGtLKcQ#-UN^9QZ3N)27hLMCl2<$#oUGi"]/q!(g?8I_);s4bk^+(g&X$TG*DTE[>>M8XtZ[X#DH/o.U@dpU:mh1IC7i&X';@C(W,;Q>S$[f7cWFHjF9gcQe"..R?(FSLjAeK>tOU59-"'4Ias!$)pU\ptiEaVNB_@3YqQN91VaG%kr'IFVSB!FY0atG_WD9G8e\!^2@`b*UXhb9Rjk/L.%mIT(%(?%5dbKAQmj+cU'>\Nt@>];kF-Imks8qr86!PfP1rf8m?u;9>Oorcr]Ih2WH/He"?QKA\0d),2]%5Vn&X9rRg@0pig=QA4C-PGd8E.,@jQ26$Tad+esV#0l`mgI]bK5pg9J"fOQF`Y@-=hf<_IY8mRDNCWBKFhuVBO,r^%h?5bs^niLBn0W.0)\d?V0f6R,aGE>\'O0hEVO^^'g+Rl3q],`,)>O3B@IpO8BfVmh,ae`H2$K[fd=-2IS[X[(FQ:V6tZ7M!'6%paQ%hcEis-[\[GlQ$Fmt\mKq='0\+bjO#E$!j8VYDZdZC_"YqlgoUe>PT5pKcf]:kfAQW]p@$_UpmH^Dp)BYQ~> +endstream +endobj +111 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 110 0 R +>> +endobj +112 0 obj +<< /Length 1243 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gasap?#uJp'Rf_Zi6chK<^IFNmSg\kB=$(R1l9uOb^(W]A!o#.i!A,LrUgmIL+<=ma\2oT4nn!lUFZ/rC@T=LmLY>]Ze@"8'.o#mbo^q]>J:g(779,9`;+>N^8M!Jt1"T[k/eK%:H7B=>/9-Inij@L[YSDUt:V_"VQo\X5c)gPK8pTD4D@kJu$BM#e:-WJL)B*a2@Sbn"9$N^WrL,@H@#@n%=T?c4'Amp?UgS(,b5=j!3&U`L-kY>iCd[."PRI:RB8d6%FQ[.JH7I(R4t$1[F-H5WkE6n&nRCf\A#.AoAZU,##+HF6_oh,.+?LdT5:S`-Rh%[@P9f&W8Wh;8jpaL"&P]7W^!J?T);#Xc8sP^N4kNrKd]pr3rap#ZHj4N-0?7^*:E_B0'50U/2CoE\mgo%Ver"JPV"9k'"VREgs"m_@SW3,BlVG!VPNTS9?bp!r@q+.)Ft^]`2-l!j+6)^6]qgH<_?5"1"o:'q7&boW\Drl\)!g[Ym$(ObW.s]9D7t^PK+Kcenhuej.a#;MM+u,rH="kY;,.F75uok"4N5DSkkMdF+(;n0'$qRiE0b;_H'QJ/OhUYEj);:UC0p[9L?78AO33/DB;#l>YWL3_>:CXE.\M7?JieLq=iqJkM(cIRu^qE9TM>AX*`.aFF@a>gc12;*UR6%_)?u(^-cD(*G!oL`ITg?EK8rQKI#H@#4P/!R%mZ_h('Hi1QR^tWYXRDp.Y38Ck0`U,(c/lQ[:_+/%qAU2HKJppmtOh+'[1(Ki1>`nX-OW/ZR-<)4& +endstream +endobj +113 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 112 0 R +>> +endobj +114 0 obj +<< /Length 1631 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau0D9lJcG&A@7.kS=D:=HV*GM`kmg?S,)^GN1h;iZ)X"ZAD,:.oAme?b_gOR6t2A($mOk'I'YI(q7\tQ73,:j=I=fC,\=[lmMS;I8TOW9GDh[1*u")gdoR#OU3ZP%t.V":'_(0i-k*C\G.F&>JV-sIWI6BUSV(@JofU+CS5%"RMqcJln%563i*6mOfLj2V;u]pW66@a0p&I-``Ujm++kNcm)tM4u*1)WJ5\P,q1qO-o\^ih&M;Mq-)LMn,R],/8nt>h,[PN-*9+VHLa")4#YWnk'.o9oX$k[;"D+A=]pY]PkhZC7ZrI'QO:ViYgKPHir4:1>sID/&b+K8"8B%lI9Mjq;\-3Di'o,NB>d%mqo&uOKSg(M70(!Vq!kfI6bRGc]hoN/=i`=WZU.[\VK=e:pN0jd\a-1h3(rKRi9iE2=K5cOj?hE)OBO5@1Uo<'I_<6XQam1-<\kJF:=_.2[#gDG!W_XX:#l(A"%.3+\BD2mV`.K$YT#Hgi&GjuK-'f,5jcmun?l6X;K?m6BD/nqiIP?iN/CK1g"tuLka9%1mqg^AbP?M$E$,YPdSAbS?A+b+JKHXe]_U"`:?Igq5P2=`0_u>XiqJ\?McLM)^7Ql#WOa>Xn)Yd7qJM6h1qa/3Q0GCE7EpeJL]"h\md2%K,b,!>sHiao<9I]Or6=L[jZW+9S&2[APW^#KN&A?X\LhI1cP`%hPE"R[7#3t.c:qk5Xbs43tD-&[W>QHV=\d#+JQ60tf)k]__+YApo_c'TKf$CG'BWd*R_9F^g"]6p>KQ]t(\^G?lABPj\@TH3%cQm;W]A3*V&u)=[r]/C"<3!![;9"ua>eM&1WrLnWm3J-"4a]-"%LnN,$4j^^Yo,0QaZ@%%a_pWKt%L]UH'\T@7JbE==kIG:t]KdP@f)"tpJfB+_8tMs_*p9_nYgLandlBOfYn>]-.Im"UY9:8dW@#SZ$`p34a[lbTD'6]CG=o$+7<\iq<$MLXYX4eD0AWA7=N@N?"p)q@>'=:d'JGCiZ'ZDb7E&Jde=ca>lJd^kt5)hu(>li1T;h`11'3*>%X0!Q1$hY.'kG_hC:0Fk`lnmEg[#N1!o/)^W]&NJ(7fu@.N-$AO>d6J'N.1NrrEepnV$~> +endstream +endobj +115 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 114 0 R +>> +endobj +116 0 obj +<< /Length 586 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GasIe9iJn_&A@g>j9Q!+dO$EnRklb`kQ*):`,Pj5R\:EhU5o5!e'Gs9o[M.Z]sfZ,41RtrET4ZX&>U?STFXh(q"Aoj)i!:r'rl8#m.pQH?o19?eO\W>"*Z,#F!!P[1MgZLpA.K^cl;d*3-co;\1m_#'dsUkW=:`4m88]GW=YQS!KIYu/3ZHB]G=`6+T-2XLCfqA&\68?A`AUeOarZ?/:Y*``i%)F(C+0T[qBamalK?oM#7B3(%9rR\%MJ4q]1dLm#alJkJiIlYUtXFD]'?A6_Ph"pZdf/"XDfbpu,L7R<%\`n+BH"ll3\"qG$+lpDJuY>d`5lF>g*C6UF:Tcf@id3XDI3S!;2b*;^lrCu=fC(5L[WQoaet<_gMdR]SB$m*bObkks'o5MU9OZd$c:5@1k\Y(hq,4mE\QZbr5Cp>#)`c[M+B,rfT8dG.e\gXCS<0KS_X[A0TrnIe67jJ2Q;8DI@o:Mk>`3GJctB=4t6R2IEUCE[MZ^&^uf5(`~> +endstream +endobj +117 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 116 0 R +>> +endobj +118 0 obj +<< /Length 1596 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gatm<>E@K-'Ro4H=K!`9b"g!$4-^]r8s3601h!B5.Scgk*PdhVCCf6,[JfPW@-fm`0P6N+(XI%Qhmn.kp?R"m]/QU!=N'f)D8,:4D;EYu$9qg;%72qmo8-tfg-!qM%43$[$(_[8CVt:Omnqui"qFM^o*nb[DFGTnCNV9;(HK[2L>$9Wr\Ird24]=X5YuaXNST?L=@@B3d_.%\gUfZS7;]G;K13;=1QQ,iWbBZsC*im^a**n4_*JHL4TYm!h.MBP&e)PDXL/N5ZR\[)0"-&20:ukia7jumb+gS#7HNC"Wr0#n\Ql$-h-RZb!^2-D\iI_tWd*_RM;cgqE[/g3oMSgC\XTjo`>ln!BLWb+l,-B6TciX?]]hm7A0^350**.*aNbrt+EdY`,\m0m`/u<\C:,s^iKu;#.Zb'XLt0%`;]Qc_rBH`$T]ErFrNnh"Y!sJhre]Z,:@a4Wr]"O?Rji/bA8btkhiD*DMr:IN=,F4tC#&]OP_2@"0s\`0o55\^;hPkg6_BQo_7TM60'D9H(GMiOA+rQmHRo^%^*lZ77W@r'+aAKX! +endstream +endobj +119 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 118 0 R +>> +endobj +120 0 obj +<< /Length 1842 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gatm+T$L,Ie[3(i2HYru;odXCu6Q>Frd''4("?:9M.O/+1eo#(+Zp,R<#Md0o+]PsFl"a4/H_[\$#9ShU(EOFkT@Aql0oCM=[Np!8Q6.!C+cM29WHJ?DWKEIf7`d`,,#5rT*]34$<3;r3(9g^d%>_Lb4+(P;03FN2c3a!<0Q?$+D,R0a.h9H52UH>;XI1cl-=*_SalJ-&N"A-(THH/rcPMH.UM8EM9n'9,mjCNgC(aST0U/47^!!R&/g'.?5_.;nS6sJZE1(.H<%CGJ0u6&b^g6ss;#m+mb?eFd!*$KSQ-]dR!(QE1Nq(249XgoYk@JK3%h3G#YqoE%K.agM7oUo2@ik7coLf3nfX-RU,#aa&7bJIL7Sbtf7Jed%CpL2jCK0@W*)+ubPBW67i)6e\Nn&#;+,qlFHpiU?nD^^ah_1q>Jo1!ge=XRH4sPHo1W)X%SDmK\h!`roMBNRbZb*RVFTG+E<'^*LPScUI][,M2Kp>9Gi)BB#'Qf:/[R-DVuIS6Z9UVs34k2$'k**XMEE8#pml7J4)jfr6PH"TQT?]"'#:/)kbpN)PEi$#,k)A!&Z@$+?.6/YL5Pbm7_@35Yh&DrQ"JbP.j.1de$$=%[C#kn?!i(_KLLpS&^)]DEB7_N2Kl+F`<.-":l\%OqC3io"$m8^@E#rQ]7/)-nQo-ds/W"eE<1F7#.,P6`eJceMIdlR*(RQU%RmGdaB)=cLkYOslCN]lqU4!G2ETm_E1Su?i,[P[n'3<9J3r)kgaB3+<)84Tf2TiLM/q!$/Wenc+&]HpXH7\@4\rUT(>rK)+Cn>Vhf"Ba>g>,rWZRZHHjpSo,AaO?lL+5XsgKO!Tm=]Ebn;o8Y$V's7P9Adl(*(J8W0?EFD(r2P$B=p!i43sX",/jM9JlgrQ+o>7T@PL=!(FRajL?MpohMlY1_*gYi^f<44#l;ZPA?Mnj60K!iI+-&_Xm;r]9nV`g'=uo=>Q$I>/huXG:PA&Ibm8jq]Be15@:&b7:DhMK~> +endstream +endobj +121 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 120 0 R +>> +endobj +122 0 obj +<< /Length 1681 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GauHLD/\/e&H;*)+UBK(@h'`HHtcp>$sqOITU+pMG6/6AD*7/]QDeUhhe'q8u<;8+,0cHNoIbAT&\WOIg@Fb*utGfa>1X*`%j4aCfp1^%8.V`VK'jOio^;(#=#HgIeGEOVB!+P/*Xg"8"Soe3VJp@l5ll-i3f0#kh)6]T[MfKL,aY"h_.V_E&=$,P<3Ma\$`UQ_KR:.!Z4'J[Q[!guHgC;HXaA[/>5'&6FcmQ;'NrSe/1XNc<`^;;Kij3'4FW-U120dkBVoT;TAg[KjNCh0`^s2>pfQsmqimAgau1l=&#]Xc3!)nrf+*o2eAk:-b;]Y5Y#V+`=[)j0+*4l!chhDPWu4X,B_<%">.fcjGOa@IpLet-@(CTsO(Mu\]?k2Z"t0baY%rQpm`hIgXOg@iKM!Cu78Z$Ye=]Fh)gOr(39(R&Oi*JmhmLU%549f6EU;7R>Zu$Ura6I!2i-\RT8N;/6`.p1S0`Ko(b9V8BI`36"4S)lG--c"X*j/GIZ!,6nT&!hcIk7Lkok0-)m&G*f=:E`e]L>l8*$TMm3oD>GW/sFOVf.>Lf,b(qJM%)7&JGUUPk1ba;6h<3^Kf#6Z+3't-aHkoOfR]/Y3JIYHk]dENBa#1.)L6;HmE0.IDb5:HI_)/d3Y6Q5,[kC2:*odc22f'AWP8W=N:(aPG/n:o`/[64RJr[k@ObNN]/1]Z'h_i?p]K$q/?rS2-U^e*YaCSA/A]r=^G$jKd@KqL"42C]q!R[g=.sUjs+VD(-/5HYR@e]FZX3TlOA4?OiG'"[Tdk@ZFF#=SF*n.P:kD6;XeR89s%c:9CQk2.6PaB_o"PRC3a7"eoJZOjX@C;noEKo&TRbU?H7o,K3_k]\>-B7CEh/k!=X&R5Jc$X"NUPm!W0aI0<)>YdP:b#U4]nB/4JCUFIM'2Gm_Yq%W.m&]#%4*BuaF^#k!#8F__.k^2_U0N,!_G#iMjkjgCdc=^B/G:4P6tkF`hd##eq%SjLJ'[P`^#Dj)G#bS+/(+"`gZpLo2`I(q^4)AZnotKhW-BJ&$mcA*8cu#)\E%NidT:Zr,K!+D3.Fe/BJuNo8KO;jmd"Na`s(TO.AGY=H+\iLm(E+=ZnVecf`[2,5$K82,/2khd0UjTmtR*Bo_JsT!P*C~> +endstream +endobj +123 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 122 0 R +>> +endobj +124 0 obj +<< /Length 1763 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatU4968iG&AJ$CE,q*t%8?8noTkG!9ukM;D7Q"5PCY/R@RH7d#l2kT?P!3g,m@Im3kf"OphFM42S_@;@iJ@-bJ#/6&!]+L#-XZYB!t!Q+\>X6Z_+9$[^sqT`i5/N7SO6YQc2B\X&HW]-X)XPYnBsSf->u/Z3DOdAEue887=oG[Q3E5n#>H31!&Y;onN0G#Shitum2fc!AggK:;'.=bA-j!EV,c<@Y(12Wf5*>&Oq4][bNG^YqV`OD"Fr$_2g&>H:M>\=i3$*ZHCIZ-529H`@:UPk;.tO5;:,b4*9&N7IB,!DqFLjcY6p:@TphK[Ie/RD90N^fo?']ad+`0WPMWR]D(bF;7-%%e_Cf)^1h=/.V3mcg^\F9UN`A(Qcd9;qt0j);O3;$b(-;bq7cD>6L!Am`umK>fS4uC3k\$H8pm\af`;eV(b5MQ#<4:3@hCtq7CAl9+=ku1meT5K8QdVt5#^0)NnG]L3nsjk!#72_'s_ION&[]XN1(f;`M11c2"e22X"a@)Sd)OdH>Fn]k`LG>aF)?S0BaVX+F)JSFNlgCh^RC=0"WrTO/(U"pZ_lH_DH#fm=FVN:7/`Di9aI3GD";e-9RM2(?[2UD(JRdNICu!V,LSoefpg5+k;PbHP3]U:194(q%Pfo)hgqU*Ug:*kl4YI^;20==EMH!e!9g[Cp1:/n\+0+r5<6_KjV%Lm&ZVPH*ZBJ#_j45D%L!A!i8+bF'0E_p(SVW7e,pJF?jf^]u$f.k9AuopqYFMA@pc;H/G3904Eu`A7u5co3-$glSul]WZ?t!q9WC3q2/nE?'2$SS/6ALqCATOX)"/)[o]DS-:8p4,KgC,+To=?o*^IU:QR>6Xm28f6+HaEuq,MG6u;*WOmf[l--E?k#c7]I1.58'u?Q+5d)-YQ>>od&Jg)d)S9TtWF+%N0g#4Rdg#4)D?S/P(V0))eo>17G8O&XJZ!tTMYt.~> +endstream +endobj +125 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 124 0 R +>> +endobj +126 0 obj +<< /Length 1330 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb!Slc#]@8&AS+Gi958$<>(+Kp6JHpGdfND]tDGu>K"`FOFmDirqB22+Y?e5aL(E_*#qQ,hsP5DIZ(biXM/OP5??E`?4i&,p*-"Ljot,jb>lNpCj!4uJV'[0$'RW4OAIPLE\(mg9Znm&9$V#Cdr"*,k'3(=Gu%%W`$:MT\-.MJ[s@NC?IqDVZ$WSIkqT4u^[hBo2Lbbtek?dPLa_eCbC$4A52?i\N#2[:,+Jk1IiXdM_#X>9^;'Qj:KQCqL`>=G#J9&pf8$C[7NFSb7/>+pjD/m"Ic,h0;?q'P>c2`oeQ'8bo?a"1/^.?SMqQgV_5/0qB'LR[.n7$JlKSDs^s1L7kuW"K,G&haT.B-pF^&QW.eqcC?[T7PX4,G>jf_Mk(R1!QJuofh-(:SS4j\G.0&]>1i6@h:I'Y3H9YC`1.lZ,Y!@YUZ/S8MPa@#T:qq*^T!7KmdnZ*0+C>2@");4iu7`cM[ei^'(f[^QWPU+H)(1Kal\EPmmJ:ABk:'4daOE5sIb-;IB@4%]&c:6Gp"Dj'>QAR5puNk%-Z8i(Kmahj_X@aEBLa\YH2/Hn.[noVBcK3C61KAjY([nDtiI/fUcH%#jaG,F&HKq!O9u3X@VA_N@HiDq+ctOfCMJWdj>*]lZD2VlnWIGDdXO0dnDN:>[)E2*Wc.q'X:ZbR6i[i6^=Zm0B#-`%L9TTi&6/Z7-& +endstream +endobj +127 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 126 0 R +>> +endobj +128 0 obj +<< /Length 1612 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb!Sl997gc&AJ$CkdVRJ)3LY"a_cq=B[IkZ<_deBODW\a?qVG1DDqO/'M4ESRC;0F%RmXX--%e`B86#P*j`i_c`)\JjEoQtiHtG*p3cjp4\U02N!YBHQQJs$i!7+\YSP$Ug-,Mj1]TqB:I_Z^#`%\B8l1sKeHKo&E4KGYqiCS[_XkC)&2?JEJro`K=q28C'_Mf0DJ$_$_QI^.Jq.se]1l^tlJ2RO^YadRD->QQnbu4bm@(?7gU&OoPfL(>>FW;)0nK"\2u/SYX;UQmOKn%q[<:@oKXDJKW'FUP`"lWnr(%i_qdlV:.XIU>9Mbm?YsOP;glAK?l]+U>OC$^-+FP0P,eB:S:9ie0!CJjZ5i9EA!`ScDj?1Csm[,g4h7I=*IS%/=DTVn/=j@%:o_U#&2hb)MXC@P%cMJCu\h%QHE1#aFiX_UG_A/")'J+@:*N$a\AQL89\u72#^\@b-f2s4Bi/AXH@'(fo]?4Ci3Jobr(iA$%.;PCBCVPb/tI0pIc6G67QrSUmCU!o9g]_MhnT4JXkjZ.)8a9W5Nj21!PJ@(63(#`j4Zo6*GO:/f?DX&_@KBg@LRJ+FlSTqUi8T+_Df_H!B,OJS\I]h7S(#6?a_[7_'AEdeGF0oJ!=Xm9TU@@a`9^n)3/<>q$]`8[Ud$&b6d9_a5sCDh[9`&M/Q"*3YK&PPk05mRZ-<%DS&(gW:(kkF+Dh=djgi89V:Z3:C82l>Ei\&qNXb3W$DtN;H!o1:/'M>^L4`>LMVQ!<+)#5nAZlLj+nJ+).qI3KK]Onc6O-Fk?q&q\bl-rE6)0t$2+;rI(Di6tO!(>0GR0f)F?`ZC(hi!"MBi[ji0tgf;?_UC'-F3@f3Y5FM0c#Oe`gB)"TU*e`7<0NUj*<)C:_"JJafM=firg]hB/$BebukS4FXB4;!I;UO&:25A3'_7NBX+7epcN!^cOFCR9RI&12t+tfk[)-qTL.I`77grMYj[*;:eP*ob!3EA((Aj2ImAIBas=>,a@UADgo3WM^Sq8Segg8Z@A)_Wm2g&62DCZ3Hd1~> +endstream +endobj +129 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 128 0 R +>> +endobj +130 0 obj +<< /Length 263 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gas1X]afWJ(u5!&h["kB/Oe0O6j>S:2rfElYR-Ut^n8*FLp7tZl#K#%?8!%,T#Er$-6Od+TLKWO4VT:``Iop='+bu4"\/3Jhj@MV,ZH0^WVGmn#oOO,I/+d8r0]ulPcc$FeA7C3q7CO\EV-^l,1LpYK__O(;>8KH]09R>~> +endstream +endobj +131 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 130 0 R +>> +endobj +132 0 obj +<< /Length 907 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatU2hf$st&:X(TiQ"t#cTgFmT%LE,+ct=^]MO8Jla@C>dO!2Wq!2o4Vfiu^l\>8a]A.hlqhUR+1N\(-/-KW,RquH6l>lY*HBduj7;e+68Jq--I7"kb]#1/D*<7W5$-2jt6Jgm42V%L<*&H%R?&?D.N$ii*1:38'Tn%`7^fh+3%S@%.PFK[>m"F@h5N%uikg1X^#C_n8'NF]YR(cUt3\:j2X$BnpKE3R^\WH1sb=h"MTE0bke,*2W4k91!ZT0qZ2[EqAu#p@e(;[nhuE$(B#rLA]-(cLPGhW$-Cdd0BTLB&K^97[:pN^9[<0^Ci;.!.BW,;1-cqb?rmL9M)4qOUkY:.0AB[RId84'7J/:eCRCB/6<(N>g4\N_GPTrS&$&]D4s%$79#mNOhY7VD#OR/=A1Rd%![D,s-e(d7GB8[s8bmasaE/spV7n^=;K_qFFEGd'-AKTC"M(-*DUk79;*7_4TG4dAR1?p^k3D-0eaaBeF#8f*lZ="M5V;pt_MF$NelRS\8[s&&C5Oo)bPlC^a&7^k~> +endstream +endobj +133 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 132 0 R +>> +endobj +134 0 obj +<< /Length 1408 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gat=lhf%7-&BE],=6Qmi2GH=5e75em6\i,&3^4$$MEnFX=/]rGP1jIFl[-'NPG1gL1'C,Lj$$!(m`W5;n!8mh?LnFjC^cAjRmds,(G&2JLIE-@,Z5tKQ-dp!(O^]$B"uW`DPBqSnk\=W`"KFBC.K`b1S&^-0/q:^+HL+fi$LM`F["76Nu0**j2>SNr#*:]D`hJQ(@L&KN4:g<`k]3gh$+Ak.S`]NS38^c-;X!TSk3_4Wb)6fYWu.RK7HY+"kmbs?sis778-0D8eWSBFnf5j>Z/XFS)4"8X<*+Q*c0,lgiHnTHk7sb*k8W8Pi%qU6%XY6b'Y;<:RJPno5$SQ(a;\/:iI;G;jV0T+1["@&lHXm9qHh@!`D+q@s3AF+k2Sb6%V09DtC7C!oRVeYqFbc$SY:0mSS<4R8bn"-8li)r:c;1\Q1HARa-5E*SPG>RiJ<(CW;W]Tr-X2ECC!N,K5`n?k[&RGF6#kK*?dHE/:f'IIZSPJH0a&\r9>f)c@D$hH/?rTjRubQ^ciXS[E`^F.g'2<1BW+LFjjW4^hg97>JVbDNCic)*nuc\sX0-"mNOA3]o'_8V5bjG4=hEDOJmSl[.sBS;,"iEX3("Fo.Phen>a#_HmSiWE5qpS9BSDQ5EY:g7Er)-`T!4TrJ>oGSuJ2L%%\e$)FQ.pSoBNO*0\r:DH50db9>VSV+7YRPk(VqOEYIWil`(8$ES/A2tR.M&2UqgVk5J%qLA=m4^iRq$!C;s!)_H@Y#coS)aNGWd&@["\n?c3t:[JC[5UXX=J0O?/DQ%^cc/o/Hud"A<>\RQ4'jf#?Tnq3*d7R.I]`/f;pp3%/ofNac/%U166s>_4UDkY(;M_<"(bA$4/?DqqbaW!f@OE2XgjQZCUcE%DdO?ec1Nh2)j7cFI1kqt5pHEFY+A\*m\\^UsGg"pWdaM6*TGZn.R_3r32B66t"PZLrO@oV$0@98/(3$uJ.=\>:MUk:ml+e)XXPJ64`O1A=JSlMK*tVh\gB6MkRX#NDn&68+7g!Co*AkaniJ[!BNn:92[V5=&uc[Y7\]kCjK:alG^91\S4FT+pc,AXs7eg[sS-Hpq2t:_rFu=`k.=4j/5TgDS2m6cq]`G(%-B)`3uh;OU'dP-ih7"ARqBb+hIJp#stLA-+qTDY%rs=NZ"*48,c)16YD)T%YQ2PnNkn824h+P\A`lXI.?uH`2jN]?3`^XkDW8#.-o<=2#'DO%%O[p&4FUAT@)`h>;_bcn7M>C?T(M#](cpM[)rSkFmqC]sD7F\VlY]!SVHT2fqnf8,BPurkgr^cO5.F1Ql4<5M`NCh-l]'Mj.R#(LKsFPb&pn>2XJto_f1Z`W,3cg+<50gatZN/,4HDAW3WMnH7%~> +endstream +endobj +135 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 134 0 R +/Annots 136 0 R +>> +endobj +136 0 obj +[ +] +endobj +137 0 obj +<< /Length 550 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gat=i92C1*&:j6IMESD)Y09)gC8-RA9Lq8_e'PC"&dl3dA,Z.>+3Kga9/R\3S,GN_L=tNDMf.r/JXFG&/#/I_,9X8+J8")s1b]9*A1R4+krq.0bcKLA8o)Z$P[$#TjX-'aaXbIS#A=MHFD5!hSt!tdi`R8\<>qLi([\eRit@me,cf]PhF8/T.LE>MamCCYe0e[o2p:af.A6s#c8] +endstream +endobj +138 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 137 0 R +/Annots 139 0 R +>> +endobj +139 0 obj +[ +] +endobj +142 0 obj +<< + /Title (\376\377\0\123\0\161\0\165\0\151\0\162\0\162\0\145\0\154\0\40\0\123\0\164\0\141\0\156\0\144\0\141\0\162\0\144\0\40\0\114\0\151\0\142\0\162\0\141\0\162\0\171\0\40\0\62\0\56\0\62) + /Parent 140 0 R + /Next 144 0 R + /A 141 0 R +>> endobj +144 0 obj +<< + /Title (\376\377\0\124\0\141\0\142\0\154\0\145\0\40\0\157\0\146\0\40\0\103\0\157\0\156\0\164\0\145\0\156\0\164\0\163) + /Parent 140 0 R + /Prev 142 0 R + /Next 145 0 R + /A 143 0 R +>> endobj +145 0 obj +<< + /Title (\376\377\0\103\0\150\0\141\0\160\0\164\0\145\0\162\0\240\0\61\0\56\0\240\0\111\0\156\0\164\0\162\0\157\0\144\0\165\0\143\0\164\0\151\0\157\0\156) + /Parent 140 0 R + /Prev 144 0 R + /Next 146 0 R + /A 15 0 R +>> endobj +146 0 obj +<< + /Title (\376\377\0\103\0\150\0\141\0\160\0\164\0\145\0\162\0\240\0\62\0\56\0\240\0\124\0\150\0\145\0\40\0\111\0\156\0\160\0\165\0\164\0\57\0\117\0\165\0\164\0\160\0\165\0\164\0\40\0\154\0\151\0\142\0\162\0\141\0\162\0\171) + /Parent 140 0 R + /First 147 0 R + /Last 150 0 R + /Prev 145 0 R + /Next 154 0 R + /Count -7 + /A 17 0 R +>> endobj +147 0 obj +<< + /Title (\376\377\0\123\0\161\0\165\0\151\0\162\0\162\0\145\0\154\0\40\0\101\0\120\0\111) + /Parent 146 0 R + /First 148 0 R + /Last 149 0 R + /Next 150 0 R + /Count -2 + /A 19 0 R +>> endobj +148 0 obj +<< + /Title (\376\377\0\107\0\154\0\157\0\142\0\141\0\154\0\40\0\163\0\171\0\155\0\142\0\157\0\154\0\163) + /Parent 147 0 R + /Next 149 0 R + /A 21 0 R +>> endobj +149 0 obj +<< + /Title (\376\377\0\106\0\151\0\154\0\145\0\40\0\143\0\154\0\141\0\163\0\163) + /Parent 147 0 R + /Prev 148 0 R + /A 23 0 R +>> endobj +150 0 obj +<< + /Title (\376\377\0\103\0\40\0\101\0\120\0\111) + /Parent 146 0 R + /First 151 0 R + /Last 153 0 R + /Prev 147 0 R + /Count -3 + /A 25 0 R +>> endobj +151 0 obj +<< + /Title (\376\377\0\111\0\156\0\151\0\164\0\151\0\141\0\154\0\151\0\172\0\141\0\164\0\151\0\157\0\156) + /Parent 150 0 R + /Next 152 0 R + /A 27 0 R +>> endobj +152 0 obj +<< + /Title (\376\377\0\106\0\151\0\154\0\145\0\40\0\157\0\142\0\152\0\145\0\143\0\164) + /Parent 150 0 R + /Prev 151 0 R + /Next 153 0 R + /A 29 0 R +>> endobj +153 0 obj +<< + /Title (\376\377\0\123\0\143\0\162\0\151\0\160\0\164\0\40\0\154\0\157\0\141\0\144\0\151\0\156\0\147\0\40\0\141\0\156\0\144\0\40\0\163\0\145\0\162\0\151\0\141\0\154\0\151\0\172\0\141\0\164\0\151\0\157\0\156) + /Parent 150 0 R + /Prev 152 0 R + /A 31 0 R +>> endobj +154 0 obj +<< + /Title (\376\377\0\103\0\150\0\141\0\160\0\164\0\145\0\162\0\240\0\63\0\56\0\240\0\124\0\150\0\145\0\40\0\102\0\154\0\157\0\142\0\40\0\154\0\151\0\142\0\162\0\141\0\162\0\171) + /Parent 140 0 R + /First 155 0 R + /Last 158 0 R + /Prev 146 0 R + /Next 161 0 R + /Count -6 + /A 33 0 R +>> endobj +155 0 obj +<< + /Title (\376\377\0\123\0\161\0\165\0\151\0\162\0\162\0\145\0\154\0\40\0\101\0\120\0\111) + /Parent 154 0 R + /First 156 0 R + /Last 157 0 R + /Next 158 0 R + /Count -2 + /A 35 0 R +>> endobj +156 0 obj +<< + /Title (\376\377\0\107\0\154\0\157\0\142\0\141\0\154\0\40\0\163\0\171\0\155\0\142\0\157\0\154\0\163) + /Parent 155 0 R + /Next 157 0 R + /A 37 0 R +>> endobj +157 0 obj +<< + /Title (\376\377\0\124\0\150\0\145\0\40\0\142\0\154\0\157\0\142\0\40\0\143\0\154\0\141\0\163\0\163) + /Parent 155 0 R + /Prev 156 0 R + /A 39 0 R +>> endobj +158 0 obj +<< + /Title (\376\377\0\103\0\40\0\101\0\120\0\111) + /Parent 154 0 R + /First 159 0 R + /Last 160 0 R + /Prev 155 0 R + /Count -2 + /A 41 0 R +>> endobj +159 0 obj +<< + /Title (\376\377\0\111\0\156\0\151\0\164\0\151\0\141\0\154\0\151\0\172\0\141\0\164\0\151\0\157\0\156) + /Parent 158 0 R + /Next 160 0 R + /A 43 0 R +>> endobj +160 0 obj +<< + /Title (\376\377\0\102\0\154\0\157\0\142\0\40\0\157\0\142\0\152\0\145\0\143\0\164) + /Parent 158 0 R + /Prev 159 0 R + /A 45 0 R +>> endobj +161 0 obj +<< + /Title (\376\377\0\103\0\150\0\141\0\160\0\164\0\145\0\162\0\240\0\64\0\56\0\240\0\124\0\150\0\145\0\40\0\115\0\141\0\164\0\150\0\40\0\154\0\151\0\142\0\162\0\141\0\162\0\171) + /Parent 140 0 R + /First 162 0 R + /Last 164 0 R + /Prev 154 0 R + /Next 166 0 R + /Count -4 + /A 47 0 R +>> endobj +162 0 obj +<< + /Title (\376\377\0\123\0\161\0\165\0\151\0\162\0\162\0\145\0\154\0\40\0\101\0\120\0\111) + /Parent 161 0 R + /First 163 0 R + /Last 163 0 R + /Next 164 0 R + /Count -1 + /A 49 0 R +>> endobj +163 0 obj +<< + /Title (\376\377\0\107\0\154\0\157\0\142\0\141\0\154\0\40\0\163\0\171\0\155\0\142\0\157\0\154\0\163) + /Parent 162 0 R + /A 51 0 R +>> endobj +164 0 obj +<< + /Title (\376\377\0\103\0\40\0\101\0\120\0\111) + /Parent 161 0 R + /First 165 0 R + /Last 165 0 R + /Prev 162 0 R + /Count -1 + /A 53 0 R +>> endobj +165 0 obj +<< + /Title (\376\377\0\111\0\156\0\151\0\164\0\151\0\141\0\154\0\151\0\172\0\141\0\164\0\151\0\157\0\156) + /Parent 164 0 R + /A 55 0 R +>> endobj +166 0 obj +<< + /Title (\376\377\0\103\0\150\0\141\0\160\0\164\0\145\0\162\0\240\0\65\0\56\0\240\0\124\0\150\0\145\0\40\0\123\0\171\0\163\0\164\0\145\0\155\0\40\0\154\0\151\0\142\0\162\0\141\0\162\0\171) + /Parent 140 0 R + /First 167 0 R + /Last 169 0 R + /Prev 161 0 R + /Next 171 0 R + /Count -4 + /A 57 0 R +>> endobj +167 0 obj +<< + /Title (\376\377\0\123\0\161\0\165\0\151\0\162\0\162\0\145\0\154\0\40\0\101\0\120\0\111) + /Parent 166 0 R + /First 168 0 R + /Last 168 0 R + /Next 169 0 R + /Count -1 + /A 59 0 R +>> endobj +168 0 obj +<< + /Title (\376\377\0\107\0\154\0\157\0\142\0\141\0\154\0\40\0\163\0\171\0\155\0\142\0\157\0\154\0\163) + /Parent 167 0 R + /A 61 0 R +>> endobj +169 0 obj +<< + /Title (\376\377\0\103\0\40\0\101\0\120\0\111) + /Parent 166 0 R + /First 170 0 R + /Last 170 0 R + /Prev 167 0 R + /Count -1 + /A 63 0 R +>> endobj +170 0 obj +<< + /Title (\376\377\0\111\0\156\0\151\0\164\0\151\0\141\0\154\0\151\0\172\0\141\0\164\0\151\0\157\0\156) + /Parent 169 0 R + /A 65 0 R +>> endobj +171 0 obj +<< + /Title (\376\377\0\103\0\150\0\141\0\160\0\164\0\145\0\162\0\240\0\66\0\56\0\240\0\124\0\150\0\145\0\40\0\123\0\164\0\162\0\151\0\156\0\147\0\40\0\154\0\151\0\142\0\162\0\141\0\162\0\171) + /Parent 140 0 R + /First 172 0 R + /Last 175 0 R + /Prev 166 0 R + /Next 179 0 R + /Count -7 + /A 67 0 R +>> endobj +172 0 obj +<< + /Title (\376\377\0\123\0\161\0\165\0\151\0\162\0\162\0\145\0\154\0\40\0\101\0\120\0\111) + /Parent 171 0 R + /First 173 0 R + /Last 174 0 R + /Next 175 0 R + /Count -2 + /A 69 0 R +>> endobj +173 0 obj +<< + /Title (\376\377\0\107\0\154\0\157\0\142\0\141\0\154\0\40\0\163\0\171\0\155\0\142\0\157\0\154\0\163) + /Parent 172 0 R + /Next 174 0 R + /A 71 0 R +>> endobj +174 0 obj +<< + /Title (\376\377\0\122\0\145\0\147\0\145\0\170\0\160\0\40\0\143\0\154\0\141\0\163\0\163) + /Parent 172 0 R + /Prev 173 0 R + /A 73 0 R +>> endobj +175 0 obj +<< + /Title (\376\377\0\103\0\40\0\101\0\120\0\111) + /Parent 171 0 R + /First 176 0 R + /Last 178 0 R + /Prev 172 0 R + /Count -3 + /A 75 0 R +>> endobj +176 0 obj +<< + /Title (\376\377\0\111\0\156\0\151\0\164\0\151\0\141\0\154\0\151\0\172\0\141\0\164\0\151\0\157\0\156) + /Parent 175 0 R + /Next 177 0 R + /A 77 0 R +>> endobj +177 0 obj +<< + /Title (\376\377\0\106\0\157\0\162\0\155\0\141\0\164\0\164\0\151\0\156\0\147) + /Parent 175 0 R + /Prev 176 0 R + /Next 178 0 R + /A 79 0 R +>> endobj +178 0 obj +<< + /Title (\376\377\0\122\0\145\0\147\0\165\0\154\0\141\0\162\0\40\0\105\0\170\0\160\0\145\0\163\0\163\0\151\0\157\0\156\0\163) + /Parent 175 0 R + /Prev 177 0 R + /A 81 0 R +>> endobj +179 0 obj +<< + /Title (\376\377\0\103\0\150\0\141\0\160\0\164\0\145\0\162\0\240\0\67\0\56\0\240\0\124\0\150\0\145\0\40\0\101\0\165\0\170\0\40\0\154\0\151\0\142\0\162\0\141\0\162\0\171) + /Parent 140 0 R + /First 180 0 R + /Last 180 0 R + /Prev 171 0 R + /Next 182 0 R + /Count -2 + /A 83 0 R +>> endobj +180 0 obj +<< + /Title (\376\377\0\103\0\40\0\101\0\120\0\111) + /Parent 179 0 R + /First 181 0 R + /Last 181 0 R + /Count -1 + /A 85 0 R +>> endobj +181 0 obj +<< + /Title (\376\377\0\105\0\162\0\162\0\157\0\162\0\40\0\150\0\141\0\156\0\144\0\154\0\151\0\156\0\147) + /Parent 180 0 R + /A 87 0 R +>> endobj +182 0 obj +<< + /Title (\376\377\0\111\0\156\0\144\0\145\0\170) + /Parent 140 0 R + /Prev 179 0 R + /A 89 0 R +>> endobj +183 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F11 +/BaseFont /Courier-Bold +/Encoding /WinAnsiEncoding >> +endobj +184 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F1 +/BaseFont /Helvetica +/Encoding /WinAnsiEncoding >> +endobj +185 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F10 +/BaseFont /Courier-Oblique +/Encoding /WinAnsiEncoding >> +endobj +186 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F5 +/BaseFont /Times-Roman +/Encoding /WinAnsiEncoding >> +endobj +187 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F3 +/BaseFont /Helvetica-Bold +/Encoding /WinAnsiEncoding >> +endobj +188 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F9 +/BaseFont /Courier +/Encoding /WinAnsiEncoding >> +endobj +189 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F6 +/BaseFont /Times-Italic +/Encoding /WinAnsiEncoding >> +endobj +190 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F7 +/BaseFont /Times-Bold +/Encoding /WinAnsiEncoding >> +endobj +1 0 obj +<< /Type /Pages +/Count 28 +/Kids [6 0 R 8 0 R 10 0 R 12 0 R 91 0 R 93 0 R 95 0 R 97 0 R 99 0 R 101 0 R 103 0 R 105 0 R 107 0 R 109 0 R 111 0 R 113 0 R 115 0 R 117 0 R 119 0 R 121 0 R 123 0 R 125 0 R 127 0 R 129 0 R 131 0 R 133 0 R 135 0 R 138 0 R ] >> +endobj +2 0 obj +<< /Type /Catalog +/Pages 1 0 R + /Outlines 140 0 R + /PageMode /UseOutlines + >> +endobj +3 0 obj +<< +/Font << /F1 184 0 R /F11 183 0 R /F10 185 0 R /F5 186 0 R /F3 187 0 R /F9 188 0 R /F6 189 0 R /F7 190 0 R >> +/ProcSet [ /PDF /ImageC /Text ] >> +endobj +15 0 obj +<< +/S /GoTo +/D [91 0 R /XYZ 115.0 725.0 null] +>> +endobj +17 0 obj +<< +/S /GoTo +/D [93 0 R /XYZ 115.0 725.0 null] +>> +endobj +19 0 obj +<< +/S /GoTo +/D [93 0 R /XYZ 115.0 666.009 null] +>> +endobj +21 0 obj +<< +/S /GoTo +/D [93 0 R /XYZ 115.0 632.684 null] +>> +endobj +23 0 obj +<< +/S /GoTo +/D [93 0 R /XYZ 115.0 233.665 null] +>> +endobj +25 0 obj +<< +/S /GoTo +/D [95 0 R /XYZ 115.0 127.26 null] +>> +endobj +27 0 obj +<< +/S /GoTo +/D [97 0 R /XYZ 115.0 725.0 null] +>> +endobj +29 0 obj +<< +/S /GoTo +/D [97 0 R /XYZ 115.0 514.701 null] +>> +endobj +31 0 obj +<< +/S /GoTo +/D [99 0 R /XYZ 115.0 725.0 null] +>> +endobj +33 0 obj +<< +/S /GoTo +/D [103 0 R /XYZ 115.0 725.0 null] +>> +endobj +35 0 obj +<< +/S /GoTo +/D [103 0 R /XYZ 115.0 655.009 null] +>> +endobj +37 0 obj +<< +/S /GoTo +/D [103 0 R /XYZ 115.0 621.684 null] +>> +endobj +39 0 obj +<< +/S /GoTo +/D [103 0 R /XYZ 115.0 347.085 null] +>> +endobj +41 0 obj +<< +/S /GoTo +/D [105 0 R /XYZ 115.0 177.98 null] +>> +endobj +43 0 obj +<< +/S /GoTo +/D [105 0 R /XYZ 115.0 144.655 null] +>> +endobj +45 0 obj +<< +/S /GoTo +/D [107 0 R /XYZ 115.0 570.14 null] +>> +endobj +47 0 obj +<< +/S /GoTo +/D [111 0 R /XYZ 115.0 725.0 null] +>> +endobj +49 0 obj +<< +/S /GoTo +/D [111 0 R /XYZ 115.0 655.009 null] +>> +endobj +51 0 obj +<< +/S /GoTo +/D [111 0 R /XYZ 115.0 621.684 null] +>> +endobj +53 0 obj +<< +/S /GoTo +/D [113 0 R /XYZ 115.0 415.7 null] +>> +endobj +55 0 obj +<< +/S /GoTo +/D [113 0 R /XYZ 115.0 382.375 null] +>> +endobj +57 0 obj +<< +/S /GoTo +/D [115 0 R /XYZ 115.0 725.0 null] +>> +endobj +59 0 obj +<< +/S /GoTo +/D [115 0 R /XYZ 115.0 655.009 null] +>> +endobj +61 0 obj +<< +/S /GoTo +/D [115 0 R /XYZ 115.0 621.684 null] +>> +endobj +63 0 obj +<< +/S /GoTo +/D [115 0 R /XYZ 115.0 145.225 null] +>> +endobj +65 0 obj +<< +/S /GoTo +/D [115 0 R /XYZ 115.0 111.9 null] +>> +endobj +67 0 obj +<< +/S /GoTo +/D [119 0 R /XYZ 115.0 725.0 null] +>> +endobj +69 0 obj +<< +/S /GoTo +/D [119 0 R /XYZ 115.0 666.009 null] +>> +endobj +71 0 obj +<< +/S /GoTo +/D [119 0 R /XYZ 115.0 632.684 null] +>> +endobj +73 0 obj +<< +/S /GoTo +/D [121 0 R /XYZ 115.0 209.54 null] +>> +endobj +75 0 obj +<< +/S /GoTo +/D [123 0 R /XYZ 115.0 281.78 null] +>> +endobj +77 0 obj +<< +/S /GoTo +/D [123 0 R /XYZ 115.0 248.455 null] +>> +endobj +79 0 obj +<< +/S /GoTo +/D [125 0 R /XYZ 115.0 662.0 null] +>> +endobj +81 0 obj +<< +/S /GoTo +/D [125 0 R /XYZ 115.0 335.841 null] +>> +endobj +83 0 obj +<< +/S /GoTo +/D [133 0 R /XYZ 115.0 725.0 null] +>> +endobj +85 0 obj +<< +/S /GoTo +/D [133 0 R /XYZ 115.0 666.009 null] +>> +endobj +87 0 obj +<< +/S /GoTo +/D [133 0 R /XYZ 115.0 632.684 null] +>> +endobj +89 0 obj +<< +/S /GoTo +/D [135 0 R /XYZ 67.0 725.0 null] +>> +endobj +140 0 obj +<< + /First 142 0 R + /Last 182 0 R +>> endobj +141 0 obj +<< +/S /GoTo +/D [10 0 R /XYZ 115.0 725.0 null] +>> +endobj +143 0 obj +<< +/S /GoTo +/D [12 0 R /XYZ 115.0 715.0 null] +>> +endobj +xref +0 191 +0000000000 65535 f +0000053911 00000 n +0000054177 00000 n +0000054270 00000 n +0000000015 00000 n +0000000071 00000 n +0000000408 00000 n +0000000514 00000 n +0000001654 00000 n +0000001760 00000 n +0000001921 00000 n +0000002028 00000 n +0000003396 00000 n +0000003519 00000 n +0000003805 00000 n +0000054436 00000 n +0000003941 00000 n +0000054501 00000 n +0000004077 00000 n +0000054566 00000 n +0000004213 00000 n +0000054633 00000 n +0000004349 00000 n +0000054700 00000 n +0000004484 00000 n +0000054767 00000 n +0000004620 00000 n +0000054833 00000 n +0000004756 00000 n +0000054898 00000 n +0000004891 00000 n +0000054965 00000 n +0000005027 00000 n +0000055030 00000 n +0000005163 00000 n +0000055096 00000 n +0000005299 00000 n +0000055164 00000 n +0000005435 00000 n +0000055232 00000 n +0000005571 00000 n +0000055300 00000 n +0000005707 00000 n +0000055367 00000 n +0000005843 00000 n +0000055435 00000 n +0000005979 00000 n +0000055502 00000 n +0000006115 00000 n +0000055568 00000 n +0000006251 00000 n +0000055636 00000 n +0000006387 00000 n +0000055704 00000 n +0000006523 00000 n +0000055770 00000 n +0000006659 00000 n +0000055838 00000 n +0000006795 00000 n +0000055904 00000 n +0000006931 00000 n +0000055972 00000 n +0000007067 00000 n +0000056040 00000 n +0000007203 00000 n +0000056108 00000 n +0000007339 00000 n +0000056174 00000 n +0000007475 00000 n +0000056240 00000 n +0000007611 00000 n +0000056308 00000 n +0000007747 00000 n +0000056376 00000 n +0000007883 00000 n +0000056443 00000 n +0000008019 00000 n +0000056510 00000 n +0000008155 00000 n +0000056578 00000 n +0000008291 00000 n +0000056644 00000 n +0000008427 00000 n +0000056712 00000 n +0000008563 00000 n +0000056778 00000 n +0000008699 00000 n +0000056846 00000 n +0000008834 00000 n +0000056914 00000 n +0000008970 00000 n +0000010033 00000 n +0000010141 00000 n +0000012317 00000 n +0000012425 00000 n +0000014218 00000 n +0000014326 00000 n +0000015774 00000 n +0000015882 00000 n +0000018038 00000 n +0000018146 00000 n +0000018966 00000 n +0000019076 00000 n +0000020615 00000 n +0000020725 00000 n +0000022571 00000 n +0000022681 00000 n +0000023998 00000 n +0000024108 00000 n +0000024653 00000 n +0000024763 00000 n +0000026007 00000 n +0000026117 00000 n +0000027454 00000 n +0000027564 00000 n +0000029289 00000 n +0000029399 00000 n +0000030078 00000 n +0000030188 00000 n +0000031878 00000 n +0000031988 00000 n +0000033924 00000 n +0000034034 00000 n +0000035809 00000 n +0000035919 00000 n +0000037776 00000 n +0000037886 00000 n +0000039310 00000 n +0000039420 00000 n +0000041126 00000 n +0000041236 00000 n +0000041592 00000 n +0000041702 00000 n +0000042702 00000 n +0000042812 00000 n +0000044314 00000 n +0000044440 00000 n +0000044461 00000 n +0000045104 00000 n +0000045230 00000 n +0000056979 00000 n +0000057033 00000 n +0000045251 00000 n +0000057099 00000 n +0000045505 00000 n +0000045706 00000 n +0000045942 00000 n +0000046289 00000 n +0000046487 00000 n +0000046655 00000 n +0000046799 00000 n +0000046955 00000 n +0000047124 00000 n +0000047289 00000 n +0000047563 00000 n +0000047863 00000 n +0000048061 00000 n +0000048229 00000 n +0000048396 00000 n +0000048552 00000 n +0000048721 00000 n +0000048871 00000 n +0000049171 00000 n +0000049369 00000 n +0000049522 00000 n +0000049678 00000 n +0000049832 00000 n +0000050144 00000 n +0000050342 00000 n +0000050495 00000 n +0000050651 00000 n +0000050805 00000 n +0000051117 00000 n +0000051315 00000 n +0000051483 00000 n +0000051639 00000 n +0000051795 00000 n +0000051964 00000 n +0000052124 00000 n +0000052316 00000 n +0000052610 00000 n +0000052751 00000 n +0000052904 00000 n +0000053019 00000 n +0000053132 00000 n +0000053241 00000 n +0000053357 00000 n +0000053468 00000 n +0000053582 00000 n +0000053689 00000 n +0000053801 00000 n +trailer +<< +/Size 191 +/Root 2 0 R +/Info 4 0 R +>> +startxref +57165 +%%EOF diff --git a/vscript/languages/squirrel/doc/squirrel2.chm b/vscript/languages/squirrel/doc/squirrel2.chm new file mode 100644 index 0000000000000000000000000000000000000000..2d661bfb4e32ee10998e1e5cdd0212cac43b42ba GIT binary patch literal 132589 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%0D|$Oo`fMqjiv|Gs$a(jgVxm6v8)zXRH= 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�m~JvVagq;r1ghaUg7fL5&4zIr1t8B^TWi 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 literal 0 HcmV?d00001 diff --git a/vscript/languages/squirrel/doc/squirrel2.pdf b/vscript/languages/squirrel/doc/squirrel2.pdf new file mode 100644 index 00000000..97ee0112 --- /dev/null +++ b/vscript/languages/squirrel/doc/squirrel2.pdf @@ -0,0 +1,6409 @@ +%PDF-1.3 +%ª«¬­ +4 0 obj +<< /Type /Info +/Producer (FOP 0.20.5) >> +endobj +5 0 obj +<< /Length 247 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gaqco]l(\P&-i#YMChQ=Z?LYF/qX3o,T:\DU+k.b//b4Q+jZ4#=Mid0Un.=I8M/L%`aXl8l)4jo;QU4"8coO#5s']m!IQ.DUP!ZC?1Il?CN>_a#'1Hp^o?s&(c50qQ(qmSC74'Ue_R7aG7Ws(21RBbIgd0pL+P/Nn +endstream +endobj +6 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 5 0 R +>> +endobj +7 0 obj +<< /Length 1101 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gasaoa_oie&A@rkFDD4/X;3=Ddo0o.4$fanN+p[lmXsps\:JY:?if]$->DSE,h1)-TiZC5B7cWTYeGNc[?ZRRqMcN>.LE)nP%[g!=4)c@RX3CqsVu`]u0n-!=1gkR5*+A`VdI*$1]bL5se'i(SJf8!gFAiUWI""%'=7K^/tg%//:=nP/]]<04jm&VLZmREjq!8k_aUM@f0?g`@/6DbR\@,;6AGj_7n'fY9jOrB%]d:03Wj.PF@r<%dlb1L./l?BCm2D5h)^p/D(D`>2Z(GH??"l^gq$_=Wq4XP5P;YpI7:.LoR6]<),T3L;3&ghf'0,?\i?$?I=lGpBO=A/&PZ_SirDa0OAdajT%_C7=Gi=o7P#WIF\IjC]#]ZmcBUJpLQ8l&3JEqqGIH0t!Ro@W<<$?YIH!8/)IM#"YaC6pah>_(>lLLNCtMIe=(`A:`>s)M(q00)*c/fL<-olMFPaVidf%.7Rj9gTQ/m/4Df8Ua7K;OPGT^fKglR9QI?$H>S6Z,SF/1N+iFt1Vb\EcbkBfm/P73bphs4/8@p>fdgb:><^3ZND#cRWm+7b_Qt>$>aUA:QO?4#\6sb*cl7[nULiA\Y72BZr9C!KD^"ipRW[e]n$034>.hJ?BOop0GOH=mW;!TAbicnZEa]bUJ__p(!oBTjd1Q'HArVF'Hr3-bbsS==bm."f$%Dp-ciYS&]pZ]t,DKWm3gH4QjAi[JGT<@UGFe4^NRGXW8HW#s4ZVRoob@AH53@R_Vr;jW&\.e~> +endstream +endobj +8 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 7 0 R +>> +endobj +9 0 obj +<< /Length 71 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Garg^iGoCd.c`?]8EV`b1=.gR0K1`91K?+0ZOMGdU/Zh'Y!=Te%#&:?HH*JE! +endstream +endobj +10 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 9 0 R +>> +endobj +11 0 obj +<< /Length 1810 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb"/lc#]C5(rl%A=)dGlK*hD4CSj8IC#!]tBr9-%4Z#;5ZEp.qndD\&+UTAM7%q7/dba*rb2SW+[6XLX*.U<3(_$_!5`E'Y>1UTB9Z=T`0d-Q!*>&bHK^X(FnZo[8Bj;LQgkU@\"?HP:`'i4g.)&p8;+OG,W6P82InB>iF?KS(dl6HA]J"0%35TnET(C].R(t:6"?=ZK0ek`O4M.op2"9M;OL;ef_p;OM;9_5*_4sH)B"G&h!dLb"a4T8Mqb5][6jt&e@d/R)\*Z<8Fo:f']_D*YDJNs`\M:\pWU#E\$(V=b2`i_-("I]Z,91WGM2:&(WfC]dcP;FBnk]%6p)kPB6.c9ZJK=Mp4kjW:g*B_g8RDg[n#A=(6&cno*pELs,I#BSiE#D"3q_dQ:La66;CDjHRPkD9l&5J^=FU8=qUbo"d/2GG>Iu*l`]hK[J0!9jAH(l+@nc5Em&8:^7e\s'rb`]0t6rIma(,qqfcgSBm$cON?ILt]^UZ"Bu@-/dJ10"fS^&%ndq&n%XddW@6Vrl.I\.m]2UBhaLjrb4KHF-P6Y^`&!)?.VHX@Q<.J3cjo+OK-oK^W_iWQkW(:a&Kei]33[bo4!ZDq'6Rg/Mk-dkk@LkF0kU:/+@"a9XE1Mk[S!&o0!.g0$>3-n*aq8SK]pZgYr5!$`qQq\TLa7migq"Y]d9?hWN>b#FleR5m2dX"LaaF`a.HAaL&+7iM)glD'HnpZ_JI[n;KI\uDDl$^R8E)D8[aiDJ\jd7pTP0B%0Z1P(?;#-9@t$+TX[+)VR!R/0Fuq"tc33r8XhU\U$oK0SOjbB5E"+=haK$7a3Us>>(Bcck)O:aD),<;6G:UXI[?K-J[7b4MU_Q1gVi*cF:.!jnIA`&hS_6MZ!!G>Xg='gBL'R.Ja0)_B^@hA%I4pLJD^u+cKX'JT0!@4CbmsKm9KDrJ&Ej+m<<1UR!++!6]pl`3kL*q,1oF[L!6=8R5gL@Er?ou(DOB)m+qr/0e8^@o-UFCmV,e<,GG?J.YfnCrOXili(cl@BkU:/+?;SO?G:$n6[N?FP'6n.TTP"_^TRVjBNUD4Tli#qmX+N[1B94,s2Mf5@m:)Qi5\"[$(`U*T+;!bO7\c>u8\7%-3H70>CNaKV_Rc372ERPg^X;3Slb0Ke%H^QD&BePn%iX+l5Bm/!+&YAoQ2~> +endstream +endobj +12 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 11 0 R +/Annots 13 0 R +>> +endobj +13 0 obj +[ +14 0 R +16 0 R +18 0 R +20 0 R +22 0 R +24 0 R +26 0 R +28 0 R +30 0 R +32 0 R +34 0 R +36 0 R +38 0 R +40 0 R +42 0 R +44 0 R +46 0 R +48 0 R +50 0 R +52 0 R +54 0 R +56 0 R +58 0 R +60 0 R +62 0 R +64 0 R +66 0 R +68 0 R +70 0 R +72 0 R +74 0 R +76 0 R +78 0 R +80 0 R +82 0 R +84 0 R +86 0 R +88 0 R +90 0 R +92 0 R +94 0 R +96 0 R +98 0 R +100 0 R +102 0 R +104 0 R +106 0 R +108 0 R +110 0 R +112 0 R +114 0 R +116 0 R +118 0 R +] +endobj +14 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 655.001 179.44 645.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 15 0 R +/H /I +>> +endobj +16 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 644.001 184.15 634.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 17 0 R +/H /I +>> +endobj +18 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 633.001 211.48 623.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 19 0 R +/H /I +>> +endobj +20 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 622.001 209.1 612.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 21 0 R +/H /I +>> +endobj +22 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 611.001 209.1 601.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 23 0 R +/H /I +>> +endobj +24 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 600.001 207.43 590.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 25 0 R +/H /I +>> +endobj +26 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 589.001 219.38 579.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 27 0 R +/H /I +>> +endobj +28 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 578.001 198.55 568.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 29 0 R +/H /I +>> +endobj +30 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 567.001 211.34 557.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 31 0 R +/H /I +>> +endobj +32 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 556.001 233.7 546.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 33 0 R +/H /I +>> +endobj +34 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 545.001 196.32 535.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 35 0 R +/H /I +>> +endobj +36 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 534.001 188.56 524.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 37 0 R +/H /I +>> +endobj +38 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 523.001 192.45 513.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 39 0 R +/H /I +>> +endobj +40 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 512.001 185.78 502.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 41 0 R +/H /I +>> +endobj +42 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 501.001 187.45 491.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 43 0 R +/H /I +>> +endobj +44 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 490.001 190.77 480.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 45 0 R +/H /I +>> +endobj +46 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 479.001 191.32 469.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 47 0 R +/H /I +>> +endobj +48 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 468.001 203.56 458.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 49 0 R +/H /I +>> +endobj +50 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 457.001 189.67 447.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 51 0 R +/H /I +>> +endobj +52 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 446.001 224.94 436.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 53 0 R +/H /I +>> +endobj +54 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 435.001 207.98 425.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 55 0 R +/H /I +>> +endobj +56 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 424.001 203.54 414.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 57 0 R +/H /I +>> +endobj +58 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 413.001 196.32 403.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 59 0 R +/H /I +>> +endobj +60 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 402.001 238.24 392.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 61 0 R +/H /I +>> +endobj +62 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 391.001 218.72 381.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 63 0 R +/H /I +>> +endobj +64 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 380.001 206.32 370.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 65 0 R +/H /I +>> +endobj +66 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 369.001 187.89 359.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 67 0 R +/H /I +>> +endobj +68 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 358.001 191.89 348.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 69 0 R +/H /I +>> +endobj +70 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 347.001 268.01 337.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 71 0 R +/H /I +>> +endobj +72 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 336.001 193.0 326.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 73 0 R +/H /I +>> +endobj +74 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 325.001 190.21 315.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 75 0 R +/H /I +>> +endobj +76 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 314.001 202.44 304.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 77 0 R +/H /I +>> +endobj +78 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 303.001 191.88 293.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 79 0 R +/H /I +>> +endobj +80 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 292.001 188.0 282.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 81 0 R +/H /I +>> +endobj +82 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 281.001 276.3 271.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 83 0 R +/H /I +>> +endobj +84 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 270.001 250.49 260.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 85 0 R +/H /I +>> +endobj +86 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 259.001 236.6 249.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 87 0 R +/H /I +>> +endobj +88 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 248.001 202.99 238.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 89 0 R +/H /I +>> +endobj +90 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 237.001 191.33 227.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 91 0 R +/H /I +>> +endobj +92 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 226.001 189.11 216.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 93 0 R +/H /I +>> +endobj +94 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 215.001 190.22 205.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 95 0 R +/H /I +>> +endobj +96 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 204.001 251.6 194.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 97 0 R +/H /I +>> +endobj +98 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 193.001 192.33 183.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 99 0 R +/H /I +>> +endobj +100 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 182.001 290.1 172.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 101 0 R +/H /I +>> +endobj +102 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 171.001 207.43 161.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 103 0 R +/H /I +>> +endobj +104 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 160.001 238.26 150.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 105 0 R +/H /I +>> +endobj +106 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 149.001 201.32 139.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 107 0 R +/H /I +>> +endobj +108 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 138.001 189.66 128.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 109 0 R +/H /I +>> +endobj +110 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 127.001 238.81 117.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 111 0 R +/H /I +>> +endobj +112 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 116.001 170.66 106.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 113 0 R +/H /I +>> +endobj +114 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 105.001 219.67 95.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 115 0 R +/H /I +>> +endobj +116 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 94.001 218.83 84.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 117 0 R +/H /I +>> +endobj +118 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 83.001 218.84 73.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 119 0 R +/H /I +>> +endobj +120 0 obj +<< /Length 2025 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb"/l?#SIU(kqGW.ss4m(\L1YPcW%S98a;D`EF(i(^>VYka7`*V6lIFqt8EnA]fiLoj`Vcq]nGr8?j-`n2V\"*Ko%GdEf#lQoJ#W4C=)pI8rEeDE1R-$XWoG)>c">_r,I:le"pb@sO`\"gUO4HRRojJboj-62qItRITMqVWp4LQ^c";!hE(ns4Y64thGNr$UTnh-toHk54XP+#OprC)Y&Ejb+d4ah:Y@@ZIDtR9Pj7YSg&p+;!anK630p@GE4#(3c$r:`iVIJ3]d2EtDr)KF9@rDrS-m#nH>6&Epd*`sJ[R'J:RIDk2DU4JDt0cBNW;_6r7?KnuJO%oBk@JM*K3hrpXkJ.^Y4Pue4D:L;h_Z]Q@J3]d2GEA6IC3cUP*g[8nT^`$aSJh);JT$aAMd.XK!=V[/&EkmKa"=r)N&,gnQg(M4)O%CU5j(a&QG?\7bV6T"Pf#hMb63AKP'Yo8[PF63HJ9+O/3k?)c8`ISj)A4bbqMo#X:e\N"\TEj9W?&FLt<]onKh,a_+-_*&-t*0QZ-.(bUhR\VOjFjcT4@b1S^;=^^XIe93&1[=Ec"Z!!EQ2)M0h.Zpa/b&,.\^$]FDBo_>BH4,BQ%1C&"dlRN%FG6S=gN)!hC0FXaiRXl.''UGLi504\.>>^hB@qiF@N==?LD]SLNS;Kpc1cY>cK0]I1:hDW)F_aZcm"[buog@+Yh*1b5%LQ,Wcq.&pk'``WHE1&C7'-AJ=HKC^ciXCh#W9cmc>jNCB"@'ie7%\2r(cIgSD'Y%'YNH(?T\GUcsf5;;muZ%&,)"^"i1n?SH~> +endstream +endobj +121 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 120 0 R +/Annots 122 0 R +>> +endobj +122 0 obj +[ +123 0 R +125 0 R +127 0 R +129 0 R +131 0 R +133 0 R +135 0 R +137 0 R +139 0 R +141 0 R +143 0 R +145 0 R +147 0 R +149 0 R +151 0 R +153 0 R +155 0 R +157 0 R +159 0 R +161 0 R +163 0 R +165 0 R +167 0 R +169 0 R +171 0 R +173 0 R +175 0 R +177 0 R +179 0 R +181 0 R +183 0 R +185 0 R +187 0 R +189 0 R +191 0 R +193 0 R +195 0 R +197 0 R +199 0 R +201 0 R +203 0 R +205 0 R +207 0 R +209 0 R +211 0 R +213 0 R +215 0 R +217 0 R +219 0 R +221 0 R +223 0 R +225 0 R +227 0 R +229 0 R +231 0 R +233 0 R +235 0 R +237 0 R +] +endobj +123 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 719.0 171.21 709.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 124 0 R +/H /I +>> +endobj +125 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 708.0 183.45 698.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 126 0 R +/H /I +>> +endobj +127 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 697.0 250.49 687.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 128 0 R +/H /I +>> +endobj +129 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 686.0 224.39 676.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 130 0 R +/H /I +>> +endobj +131 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 675.0 318.27 665.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 132 0 R +/H /I +>> +endobj +133 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 664.0 224.37 654.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 134 0 R +/H /I +>> +endobj +135 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 653.0 223.82 643.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 136 0 R +/H /I +>> +endobj +137 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 642.0 174.0 632.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 138 0 R +/H /I +>> +endobj +139 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 631.0 236.6 621.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 140 0 R +/H /I +>> +endobj +141 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 620.0 228.83 610.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 142 0 R +/H /I +>> +endobj +143 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 609.0 212.98 599.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 144 0 R +/H /I +>> +endobj +145 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 598.0 222.44 588.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 146 0 R +/H /I +>> +endobj +147 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 587.0 187.87 577.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 148 0 R +/H /I +>> +endobj +149 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 576.0 251.78 566.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 150 0 R +/H /I +>> +endobj +151 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 565.0 207.45 555.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 152 0 R +/H /I +>> +endobj +153 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 554.0 223.55 544.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 154 0 R +/H /I +>> +endobj +155 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 543.0 254.94 533.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 156 0 R +/H /I +>> +endobj +157 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 532.0 176.21 522.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 158 0 R +/H /I +>> +endobj +159 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 521.0 223.27 511.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 160 0 R +/H /I +>> +endobj +161 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 510.0 214.24 500.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 162 0 R +/H /I +>> +endobj +163 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 499.0 187.88 489.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 164 0 R +/H /I +>> +endobj +165 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 488.0 198.44 478.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 166 0 R +/H /I +>> +endobj +167 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 477.0 184.11 467.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 168 0 R +/H /I +>> +endobj +169 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 466.0 185.22 456.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 170 0 R +/H /I +>> +endobj +171 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 455.0 204.11 445.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 172 0 R +/H /I +>> +endobj +173 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 444.0 199.67 434.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 174 0 R +/H /I +>> +endobj +175 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 433.0 187.44 423.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 176 0 R +/H /I +>> +endobj +177 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 422.0 186.89 412.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 178 0 R +/H /I +>> +endobj +179 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 411.0 188.56 401.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 180 0 R +/H /I +>> +endobj +181 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 400.0 185.78 390.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 182 0 R +/H /I +>> +endobj +183 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 389.0 203.56 379.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 184 0 R +/H /I +>> +endobj +185 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 378.0 190.78 368.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 186 0 R +/H /I +>> +endobj +187 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 367.0 198.55 357.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 188 0 R +/H /I +>> +endobj +189 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 356.0 190.22 346.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 190 0 R +/H /I +>> +endobj +191 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 345.0 187.44 335.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 192 0 R +/H /I +>> +endobj +193 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 334.0 199.66 324.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 194 0 R +/H /I +>> +endobj +195 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 323.0 193.0 313.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 196 0 R +/H /I +>> +endobj +197 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 312.0 203.56 302.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 198 0 R +/H /I +>> +endobj +199 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 301.0 208.55 291.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 200 0 R +/H /I +>> +endobj +201 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 290.0 222.43 280.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 202 0 R +/H /I +>> +endobj +203 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 279.0 214.84 269.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 204 0 R +/H /I +>> +endobj +205 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 268.0 231.06 258.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 206 0 R +/H /I +>> +endobj +207 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 257.0 237.7 247.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 208 0 R +/H /I +>> +endobj +209 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 246.0 210.83 236.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 210 0 R +/H /I +>> +endobj +211 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 235.0 232.04 225.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 212 0 R +/H /I +>> +endobj +213 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 224.0 177.88 214.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 214 0 R +/H /I +>> +endobj +215 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 213.0 271.76 203.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 216 0 R +/H /I +>> +endobj +217 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 202.0 290.1 192.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 218 0 R +/H /I +>> +endobj +219 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 191.0 215.93 181.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 220 0 R +/H /I +>> +endobj +221 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 180.0 222.61 170.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 222 0 R +/H /I +>> +endobj +223 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 169.0 184.27 159.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 224 0 R +/H /I +>> +endobj +225 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 158.0 223.27 148.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 226 0 R +/H /I +>> +endobj +227 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 168.0 147.0 245.5 137.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 228 0 R +/H /I +>> +endobj +229 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 136.0 237.88 126.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 230 0 R +/H /I +>> +endobj +231 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 125.0 218.45 115.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 232 0 R +/H /I +>> +endobj +233 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 114.0 216.22 104.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 234 0 R +/H /I +>> +endobj +235 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 103.0 222.04 93.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 236 0 R +/H /I +>> +endobj +237 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 92.0 269.81 82.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 238 0 R +/H /I +>> +endobj +239 0 obj +<< /Length 836 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb"/j:N)^V(rl#l$6RH"$tGbka/.Od9T%Q3FI-\HLH(,L!i\PuFe=+@#oKKaLM7E=o.$*!h\]lO4HEjnb:%MiIUi`]Sr_=1j.h<\Ofptd@7kYr_L[IePciBbMn=sF1L>&;]a:&didqt&gFuuAQa3QCg?9q2To"(6GM`K'!M-*\(>T-=0)C=N:PWEOE@]%N.BN0+=NF45*c7_4e(f&<'N>>@oHNM+qSU6ieN`"]`FU3NKpB;/J?mp1@P3ln19p)r6>?8hIOgZr\W&`@I,"$O=66H'CtEYZ/\\hj2oWncdf]_uDU_4)c7=B)j)3^j8ba+bU[#@oep_$!K*YG-NaKnNjKUBm.ZC)-+Oq2FGO6Ja+ChhqE*UW*0,GCB+<[=i8r]B!O"EPkcMd1ee(W+lMEQ]-c+YMNd+nH`N7-;ObR"R(*NeipI@DPP!k5oYH5E%>U98G$)a^LLIrY\1Ch[@sLe%1AG`_VuIfRXY=4d~> +endstream +endobj +240 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 239 0 R +/Annots 241 0 R +>> +endobj +241 0 obj +[ +242 0 R +244 0 R +246 0 R +248 0 R +250 0 R +252 0 R +254 0 R +256 0 R +258 0 R +260 0 R +262 0 R +264 0 R +266 0 R +268 0 R +270 0 R +] +endobj +242 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 719.0 250.64 709.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 243 0 R +/H /I +>> +endobj +244 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 708.0 214.54 698.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 245 0 R +/H /I +>> +endobj +246 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 697.0 398.68 687.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 247 0 R +/H /I +>> +endobj +248 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 686.0 208.69 676.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 249 0 R +/H /I +>> +endobj +250 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 675.0 189.14 665.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 251 0 R +/H /I +>> +endobj +252 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 664.0 209.82 654.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 253 0 R +/H /I +>> +endobj +254 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 653.0 181.78 643.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 255 0 R +/H /I +>> +endobj +256 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 642.0 212.6 632.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 257 0 R +/H /I +>> +endobj +258 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 631.0 259.81 621.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 259 0 R +/H /I +>> +endobj +260 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 620.0 164.56 610.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 261 0 R +/H /I +>> +endobj +262 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 609.0 229.83 599.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 263 0 R +/H /I +>> +endobj +264 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 598.0 233.15 588.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 265 0 R +/H /I +>> +endobj +266 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 587.0 226.77 577.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 267 0 R +/H /I +>> +endobj +268 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 576.0 208.14 566.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 269 0 R +/H /I +>> +endobj +270 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 565.0 142.77 555.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 271 0 R +/H /I +>> +endobj +272 0 obj +<< /Length 726 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GarnUa_oie&A@B[G]]$LeRgDR-:i[\&erluk^f$h'G2r)76,M*^=3orJdV[t]]Y^AbjZ&`9CL%sN2"8:o,*aP(Eh^k-nrCIAW\(-1b\b`a\^+,YJX:s3t:Hb*MY1WM``CcF9qgsr[,"8oh]?P`?"f7b4"JO'++i*c()"M9Xe&2d'@SZspI@s151\p$6mJ`H'sV)ou[_OOOjS5:cXJ-e>?WeR)X!OZLG[.YAT(=^G::sIotd8u3KH?5I>Ot?dh%H/#U+m9^-EM05Z%u[1'd@m8Fh_J/IZ#3uCo^qV%P='?J;I-ce)2n?Df"0]5)L>%)_!J!KLHRfW(iU&`$>$QefQE-RGgs[WPL6jFN^%mOWKr;'gKXg!o>VGLG7J/l_'91H4EF)E-L!L9$Vt=\I5XRD#jj9*0F-ouns[1p?IQ%ZYW,Ao6#rI-i^pKK\!ap\,G&Z3GfXn[\;KkGNDO1.srTF3.qt`_q=*mt^X>mN'P^(uOsiRuW-RnE.8`?f]S*p^\5kD&i~> +endstream +endobj +273 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 272 0 R +>> +endobj +274 0 obj +<< /Length 1525 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gasap>Ar7S'Roe[:]iOGPF.J#?*cNC3\8'!5V^JY9='59.%@//\J,e!?+/WS8tsNS7@jn#S-sVfiQ&iseGK(&qArkDLS>&Yo5%l?bDB`^l>s&R7CEq!0abS?R]iiKo,h%E,H5p#:#.KkEFd+@Fmc!<5$u^O+X_Y?Oeo?I>4Z*#6Jlg"'j@I";E8W3#QbMs@GL"6Y?4rJnS?JHL'VM#+u?N@e$VeO,h8?(0JoV;,1qL5#A02^0$1HI#u?,9XpLFG.DI$K[n=#7VS^kQ+njk]>>2;WCeq8+2u:`2P4'Rclqf!oU.SrB-j\sgaGjNHZ8(p^=?i]um4;aHPXiR`,9(og5;I6D.Mo7Gd%Il5QH>E>#S?UPMCb^Cak2ak&L>c;d[CLcT7&aV8lk"uZ)+G)/9W-s#7@ZcMdFWo)p9Y5%OA6YC60@,'>t*GPV&<)J\edS<'u-tJ$>j@j2ZAbf`(YD0d14J/.B`F7SH?ENE/q`1ZCeY3hTp&$G_,(J>d8/Eg[oTNRB':%Q,A9(X#K;`4.&p^3A-K073\cNaAnY>6d4-GF"0K%.g'6<.)^`@jUeibA<&@=DD(3X`ASDYO0MI=^n\,!#)-:+g'+k!c.uKN@T\h8JI/.)^QJ^_ZPO(Y"Vc1&Uc],@5,U!=;P(K)):^[K/`Ce6s!dKZl'5AB(Yn%jm2aFXO94dA49Ebdi-I;j_If3^OkGQAD:9&[:i[E3!Z&N!/nQ3;lCM4%UROa%GN.OA!=Dd65%L9Bh#+-o=MHlFK+!#2S$iW(pMU1B\k8+.RG1Pm=7(CB1[APJlGlo-@MF2X&Q./<73()24+)a1ugjCMrqGfabaN3>[B:#YU`]G:UPob&QE&>*#M:j^GXA^##2[7"M#/aG!'[GegeWKXA&%?[&$23FLu!BgctJ7d0ulWlkn!rrW]imJWYkj8KNCN57t.o^uS[K!d_n99hC@'Wp"Cp1SV?\]??Z*PG9KGj1s/QpgNeK-cM:Ho'SJWpgB;=!W(#sIRUmj.XOt0md5di;Alnf'KJomlN_P9&r#an134Z^"egAPKDU*n;+\%Rm-DKcjp:&`?1R#,iWcR-rheAQ2TD4hZWjhHgTG\uo$Z-&"97V"?b[WVB6Se&DRAk;FW'Vj\HM#!%`1qkD`[An"5ideG6*(-ZgeqfJE/:!s)nt>no@RUF9'-BT7L+B5lPQ3$jT&f!f$^_jLYGm\$lI(n*Z50XV4/0LT^&LeQ_o81#MM#ZPB)]5MjD?mirW=K.(4g?5F.mio>IPW(ks#s1=jB[m]ctO<9#N#\4)!)^mWPDO!$9p^Y@m5lUcD.%7E!@Z9tU(fM]TLeghCBg2@@rX(T?KqEFZV3lT[>Oa/JmIG"q]1!$GpHm/~> +endstream +endobj +275 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 274 0 R +>> +endobj +276 0 obj +<< /Length 1670 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau0D95iQE&AI=/#e_WXCPJ(PLDO'cBt"+@//D@+fLt$&/^q.)4WI$g@\>r7.>cI]*SGHL=nk=4jNN!-S0>rL1qU9.o.3?;[:ZHIC99.V7FdH%bc/F/3eR[f/@E2t5!88mU6*K^20$9TnPVc;gf>^$EE:2h/-*b7ks?0I#=)<]/ugm8"1$1:fIIPE-!S6^XC]dg&m)@M8P-(dn(-j+EbF+<"0OTjn:PHDMTbnahQ-%HHas$'fWFu26Bi*Z7d!k51jn0GV([%:PhrE:O4-C(kL/nHTu4]@)L1[0&cTsn$.%ShJq(55a(`&YnJJaW^_K=$BA=mJ\2u@)a%9*f8B1krM/uU\CQ`7$,niIY/LJ%KK.M63]jm`-pt.9m;nkr195beUH...F/Os"9QRhJmkCRhZnA+S!<@*Gj%@%YQ"hP&R5D9ej.q+([$l-'(D>t9m#J*_-?l:km1PeiEhme]jQf,\_F<8tFXY2$6UZL8.3>HZP5XD9N=Lu+ue,Oo#p(3V;.<&?^?Ns2g'c>\cE+Pk,JLBnjhLmF]c!_Knq578S`:1-V=?1n8PD*05@CUALgnl^LfR%n#=u#_9*JVSsrhb'd$Y5pDkE]e$&*#RL5Xh%9&=#MGSTiZL\,005Vnq%$*VuHYEc]Z^Wb<1EVSrD'@9*%07V2=mY3pbq%?-.+I`Ps"Vp3&H.ND$q6'Aa?2]odQTT!l6)Wd=`&R76cbfAZ/"!S!\N!hSU%>D%PDUUj@gO="qWTlCE3d+BFVN+>IAG,+l@ee.&/2oA"?@;Ve=/S@%5p#SNX'+OH6NJp_gPmh=UEZh=")0_?He@:0l@crC)-H!'Y;CW4mWSan@O]iR?;;o.P%lPr@!e")[0EQDk@Ik1ZZ%oEWHWV0OVh?ScfEN&p6bLb5gXEtW7Z%1eRT8>Cbg+KB-CO8^A-6c[_`**4?jtM5s74]427/E6`\ZIhSfn_"98>EWg!NdWt-JtpaBZ!:`Jq[I;NKmho#F.L'dFMb'1:qdI^D=7b#rs6%`LAS^UI&.bMn^o/c2*ecf='_=SRMPZdHL$A.RODfeN'2Mmo!6GSkF>&Kb"mr$b@n;WW~> +endstream +endobj +277 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 276 0 R +>> +endobj +278 0 obj +<< /Length 1772 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau0D997gc&AIV:0RVO_ZJk*I.'Pt*U&i\0JKdQ:FUti9[Y^h/Y=/3VmmDqr3V(U*[hg)QQSNl_qIt-Sc4Yua4ihs+O2>cQ&DQ/"Bq[b"R8S/KE%BZJ8F:X\3Ft-9L+I;s%g9ILUDE06$Z=:Beae]FZbCkNX1lms/ju&E[DIp`("u/Nd3?fbTEHoF])g]Bl3`/FK$cLbLJ;24X=8VH&n](eu8a`2O.QD;"iFq"".=58j70/4PWb[Vc\SZk_QDO]q>mj@u,pc%Ne)t]4V^0@[V])[.KAMD0,Ztaq/&#\]cA1cX?&BZ%BQKf0j6ma[3K#dOG%lE0!F(>M:38l4S"2?Q;N\8.r&rF!$T)]eB(Zgk:7K53i8cIJSG;]g7_%'pc2,oM..9-4&F&DEpC''pJ+*aKfP;KCHJ`bP-%O*2f6f6cFT,D!P?@EX#$S5oZ[:=u]-iX\6@Jrkn_qCa>;4OpsBhHp5"+Zc;Zbuiiqod6i&:+Z)_sdn7Pkg[Cb.6\3M\;J$LEu'gnT@jcC`cpfbEAb>3/Q7,Y]7Dt'JbaO*RD&:ers2;eOt_%Z1U17,[ff'S(%mRf\j$iemXM*JKu%W2Y,O><]P%D:NoRS7;Sg[EFM1la,3?`f>`7Qm@1nd6YGV5..6&*I1Bkq*L13Bmn]A=,/*As(kcq+S>?93mZsc*s<(!=jNTWf6%#pF?iNO*P27U2j:3C1U>s8_&ld.QTG-!C+8@9p.)/TRT,`Rh35LBWraq$ad$+2F^24dDO?+>,oT@PpjO9JFNcsiMaN<2'9GS@4,7MFR6l8E+Uk3I"67Jrq&E?E?d@h*-!m3sXDSd_Te17u:(uWHmu4<&_^G@-+b">&c>U/_^7UUbkP*a2lo;`tSpXT8sbtceqc=3k>@$JjfS.ql]kD$Pbl98S!KE +endstream +endobj +279 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 278 0 R +>> +endobj +280 0 obj +<< /Length 1556 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gasaq95iQE&AJ$C#e;4sVQ<2NM8G#nfE0a\!kpZTcn]HZ.oE96a7TZ8mi=Q)NYKSF!X,#*B/ohabp.L9beAO%*7#q6Ze3K,B05])(OeKeUU;jN.#A%=OZUaUX@RV[l[0#pqTB>?X*k3CMmN0`]J.Ba#`WUY`^N:2%t4fLcG`.J=Gu*Zmbgd]L_k<utH7_QcM/!#hF7A*b4_g#Z2f^Km$["h6@Un$F0%3/'5$9;7HG7cNb:9PPli\;3>(q7$.1[%/[h!M:!dSK6I(gn>Y]"Fq`#ac'2kD7;3Od3.cu0^6-XZrd-uAi7paSB"U0T0)aG_;VFB-6@<^Eeoq#7-/O\)nqT2R[>a?V&+I\e^?i/J$N1j\r>K[:NZtXhn%V@!kXQ[cJdEZ!l1qhh#Z$S)s9Pcl?9;lS%VF0<^,F1k?AnH]3U^hmn8A5oU#%F.1+\;S(2mh2r4j.VuT]E)6T:nbFC6MbN318Kn`D_DXG/^jLiPcR0oG;ttl:j(g5)[.=`J;%K7*5pU)/bLT4:I(-XLL(-Q7$jAP\:>Pc%"3lK6B5(j.h9(D:-Q2RP:0,Y=qJ)n2DLBf0$(po^[LI%t$l%eX1H0WS]m@7-]4ZUW^p-\]Qc\7sVJq&SCn&f+Sh$m'TicU.**$?*/(;Xm5JrI5E#L%B`cqPY=RbO\/Bk4/H\q0+7=QNpd0(N##YPI&!`1=+FFtFG*;mr%[<*eH=OXQEHj%$N-)sp/]#"Mlk#(Qi5"[pPHH`DhCpD]+@a8.M/HU4ulUTZ2<;B&E08a.4nU)>#V8RHhi[*R!:D+=QSKLp&oi==7D\];tq?XE2m7lg:X(k*]0>=bi#MS+0QDR)D4.9i)_Kc/jSpW\N=#]+Kk@JbG`VE8J.2Lk^4b^R##RV7(<^'Af"Dq9&b.>>*rrB#@.==-Kl8SA)ciRPO0G(F_d2#6YD66E.Fc9H@fkQ=;ull9+tIfPdF(Ei~> +endstream +endobj +281 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 280 0 R +>> +endobj +282 0 obj +<< /Length 1982 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gat%$968iG&AJ$CE,r3GP;%BAA3)k1D3Cirk;++.4=U+I+Uj5ME\)Q\AmeNAX4(^6?t.o(Cu=XIR>`h&X3$/QqQ'UDT1-,G0=l2o^M>Bc%8hRN!6F=pITecdt'-$b^[g,?n"@ui7n2rWs,j@%%>b:F%-A>rQ.Q;f]:,FA@q`*lOi^=JdLN5IDQnBHHim\C#n/![?lnI9fb\+Y)CpKX6?$SEuRi2d*:jSHl*%Ge&C`)nYD6$M%2i._I\(tn8S[*X-hH#t`rQpHGYd*]&scn,*FCNE%PW[uYWTBNmX$`Y&QX1I"cL.ZQ3u?s]f.Ta)-()L3nR79=Q*FQfE-:-n(rmb_Y2&imNpRKI3]6&B9XAha(Li)iNpnIV&-8PEPY7HlkMQSd#.uBUN]`-DJ*gX+D'bqSK3LHZ(b1B("CSKZ:hS7]dP]hld3ufDpDB-_V&PYH9r!!,g^_Gmpo"!BuBS@E?6Gdc]pW>V4WNQP/6m@CLh,>Jb2@2_hj+A'q-h!m._XE3Dd+F@iJ;U]P)S3`l=ql:dA`j[tNp&LE\=!"GI^_in-#\c\o5"5Zh&S=@,+Lm3pU`[1Hq:I0@4&1I'6refm.H8"$l]P=-X1%^4GU]CYB4K!Z0G"-3(^%>ECQc!C-?f:/["oG409eP*D@&^FDl$@1'HAkuE3.ER7%P)+ON5lH^HR5M2h[UmVE$ELEXZSa=4f(V0]&YGT5A?QbCp0*-qfg&KJL!;$+RADjLj5!LpA>NjKanc.\?aZW($tHc[<4RoH':Ulr,UPd&!XO/dZ-m+9FPaj@CC/K`?V,t3SQFd+fi6?E4;Vrn^0%=ZK,E1T^2E++&V@cKe%:QltZ(Yb5>%V>'6:+ah`\-JN7W^g/^?ZeikBdFNqc,7]AXTP^?Y?cD>9,A'&IZDu;%!kR"+D5V/+2p!WZ1kUP8*Omcf#4gPs,>.]j[c:n)00U0pAUmaK_Rrr>i4:\m0(RW`aYjph+XL92mLAub/ZC=Ji$/p1/#KL$T(SK=>6@A[t@hhF]"&k?:^k%,1AWD]djmkr,4a9O*2N;XsmjP$O7H\0Q/n/Ai&Qe;`t`aq1`ms,\>(M]t4hat[oBJW);km`4"MhK&g5YSSSW?aif0#C__6^Wt+$e9I.^6^Il[]Z\nJUQuDE.iR]Lb"Jpg-W;@>BK6P&s5=sHedot%1Z'=4H]KMoZUY7,o@*TVL8S[:IFisTh/J\21sk0T)M'^Vu$oU1&,8"9=*KtcelF9BO(4#>_6&cpE[7Z^XH@.<`e2/8)Q\8aPnn/)bBuK_3:P.p?Ku)pT)\h!hI%tEYo)fK#52OX,9I%gEX8*dh=:+TKI!SNDdR`FK?`\CZp80UO:k~> +endstream +endobj +283 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 282 0 R +/Annots 284 0 R +>> +endobj +284 0 obj +[ +285 0 R +287 0 R +288 0 R +290 0 R +292 0 R +294 0 R +295 0 R +] +endobj +285 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 505.14 689.561 540.12 679.561 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 286 0 R +/H /I +>> +endobj +287 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 678.561 132.22 668.561 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 286 0 R +/H /I +>> +endobj +288 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 191.92 617.122 298.56 607.122 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 289 0 R +/H /I +>> +endobj +290 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 161.11 505.244 231.35 495.244 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 291 0 R +/H /I +>> +endobj +292 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 526.45 428.919 549.78 418.919 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 293 0 R +/H /I +>> +endobj +294 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 417.919 139.45 407.919 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 293 0 R +/H /I +>> +endobj +295 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 314.494 395.919 352.814 385.919 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 296 0 R +/H /I +>> +endobj +297 0 obj +<< /Length 1181 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatU3_/e!Y&A@6W4C"<`+=t^AXY="ITeP7=_MRpC\8j(=Z&7nT0F\!,g6+&@FlKi'&(PPuX53Mn=7Z75ilre@Y`F0MP:q<%^VHEOJ(VY)UPr<*''aerb;:Z;rG'1Zf&enelX*B%l:Ab[uK2"DpOga[lOgP_YQn7\pdA.=MI6a+gWj6XsmCLKlLj,g2l)rrFF-0cgT#th!ZoL3c+fmjuFs9Hq!u:@4RA9gC`oi_b!-CJuakm8oLO^PQ43*H_4GpbXi+5&GoL3g.)L@T^(rZ.bnGA+o1mr+be90/g/EEsfQM:ks``Q\CV])R6`J9>NQAT#[FY+O"VP.+]P&s[=CbbW]hi*MYPkB\W1t6rSNo99uq1p*ehG6C5Ab)/5m,R2u:pN3j6qtK;i>uUAqnY(Z6%Ta,pB(]&)Tpk:]qSd/1/SuuH@8"OcGe^l1Q5eAb*>)J]U'8$WM-VOp!q9K-FK?g+LumBV=a-IL_)5lOO,ofC/(A0g:RBY33h4,hVq(FB_q5!"K)*9uJ"+[pDkEERAGIl3oKP4:IPlS+kU4S6)'JHO75^pU9-]6]^;nI-43b/1og+''G+/OcML+21SuU$!5uG6/ItBR7'YC!]/MPWg!MP=3F'Z%V[X8q:K@4\l_@(r$q;%6)8o*ker'UeR#Vb?2Ge8GmO6M(In]TaqQMA9AFchI5CkHul8;p.`d)A@r<#.I/?]~> +endstream +endobj +298 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 297 0 R +>> +endobj +299 0 obj +<< /Length 1717 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gat=,95iQE&AI=/#hXcH1grdDe>#;FBS6$*gS2D^4jYrq$_^!ZU65`:r:a)%jVc$XSDE8C)%MGnr.ae*ji-mohsjqaq93"((Tt*TTT3geW=sQqFX#EbDW!'icB%dFc*c2\;V)<>VmH;5c8(0d7`q5@:/S3+KMbG&JG&(h/Y">P[Hr2;ckKJ+,]NIBg/NG)N1u%a7jj5N?4')YLIRLGii!ja*_[jb>H)tl=;DQ7[`5a'>73d,;tTSqf'O5L5@uj\IqNJ!c@1dBh@Ub],0=dINp;nu`E`mE=JLs\%^-!HRG.%R`E*]BZpO(1g:4ckb'/Pe#*.d+VVrJF/l1YSf68<#>QX(-J)lEuq[:tAB7u@gnI_0jf>XV'4hA"_Gi_'t_>Cko1L6s1?SA9%2@a^UlV!mJJb4n+W[B'p8mNkPN*9:WVOOT,amqJCO\4<"c!'K;dauuPmBAX@*am+L*Z]JXKNoaK[EXCOH+?C4FYt0PQU+.lhWDk:6GbeXHA>I""#ld#OqL=!LG'+cB4uV(,T:Xp$!iD2hQiNFRflnbf2_FUak"f-bHl2uHP+AX7if0\W_ZPo46pLDptmLB4Z11QHo^mT\[&:\*cLSmYXI,YXY,X3&Gd`#FQsOm1Ga-j2pdoLr=d*g>QSqc8$p!r_&fjFb0QJdMX?2VB5@MKA[T^D?f+9gJ3V+i+J`*b;.4%DAE%F@@mmYs8],hiM)h`P(k+$#8l#%sA&-ATQY\j]P61P@g?8b\f!pQQdmBtT&$K'G?@1XSOaA``&,7u?pn0fWB`ZuPEjBNOi+-@Z`T:)i,57Tr3QO%cY_!)pC4o*01K-5%71c@%C@6We,k9n4?p#s-(?qqL`A&Mm;,O_R%;e^mp?SFot/T@dd%M@TObesmDaCoZ03LUtpFH.d>CQGq?YD17&I6P$(]\<@1^):2IGTI8Ld((d_f<`;:PUl8sA;s(CGoO0C@P<\3EeCZ'Ss]<8XPM`.e\sF8kp6D23+Z)Ak<*@7XjB7JZ?9B!R:Wo4U[^PsY:qV(7@X4%++3b>7=WL#Dc-lIu/19:6;OJ)nK6/Tm,Fk_0I8ZGDCTe$ce!#oVChiRlUSN[>?p"s5='^3WC"W"U6"\AR5'bffedU4H)acb@6,)0ET@W+SlRj@&le9)a;FS`u5hP&Rr-9A^'EI_[e:0'%l;c\?$nn^q\EGUW8=bDV/T\!516.%k1,#Mn)kX%GAI`BP02QY>*m,VeKu"Yl]ogb/-a_fttL"eeNDS,.R)>%M:WOC=HqT]coN9KWa~> +endstream +endobj +300 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 299 0 R +>> +endobj +301 0 obj +<< /Length 1437 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gasap95iQE&AJ$C#eek[)b(P7@_5d9"^5:MHWe.n3*=Nc'l,$m?9O_q7K31E6qSHPFAh>>O.>CR)3Xj%Rb`GQ*qbBYXg4A`4jL"h_acj.FH^\_&C.u>_7O&bXkG[YWKuC8m!"AG7b5gu]hn%VdX1IaJ"A/qT[`+g;afQ42&lPk'][$tr?ARM8&4Y4EGP"3\:-2b$8B`HmoJ1YC)DI=\$XQJ&7^ragcakNP*6"e(tGQLf"majRZ]?2[9DCBk2W#WEkX'e(3QZkX`o;]kN`:,<6:mL%5KJ]=$#3S=uOcWeT7d[]PrV9/_)JG)P3$Hb^C;HNO'25,dE<8@\?(IBkbVU-u)=CK)%9U=\M^7rc2@\V#Xt4iD_s%,:dHam^]BdPuahCKoJ3HlN&bbp+a`q+R.C>=plr+Bd:j11S.`ip"naIT(/C8\N@/rY;uZ2=>lAtglGq(LA*DHVSY5<*jAL]\8!7*]/r4tV?d+r^%PUMl)Nl7:NtT`LX_/F:rJKPg;o!!.!\H66[^YaSpo^;Ykn\]^1aPk%)M&!NiLG?O98IZ*C:(gOVA9N!\-?7m\$HVFcC1*(b_pgunXH".P^)Md.?U)JmRPM-.:9/i>mk)bm-\<'o-'X=CbJP9h,C9UY*%.`=e#Zd8NS5*IimCh=.YRReXc>tPl,AFn$*Q(_6RN`m6#:rjk_-KqTmCsX*n6!3oP(PP#o>$d+6:W#)R&S7c.;V-mBFT7f(s\KYijKsaia^%9qT>Tea,O!0A+=9KTnmo]^*R$N%4('ZbL-[sJ@ak3gQI4=4S~> +endstream +endobj +302 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 301 0 R +>> +endobj +303 0 obj +<< /Length 1348 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gat%#>E>75'RnB35kC.,PT'n4*dhr>C,b\OqYK/(WeQ!^KK39>-`DJ%kf_e,)rD!%et#pY]I6u#LMQWZMbM%[b2flTcjX]=ZH#-o;Ag+sT(meS#8[N"1!=i-&]R*/e`rHhgo#ttNg`P*SI4[*73LJuIU@*_;+*iSn`:ReKIBs<[.0"0NWm:ZTis^kHYlPepI;;?i?RJ@F)"l#Rp&OaRi.SVa6?o:rf-[$`Uq-dDdd[P$3eK0'HE=''4dVc-%.@L/bptE4Wh4oP44bf_m'asW,JZ+G&FpG,9:"pkU?Aq6-6o.Fn-r]JNET8P=&L>,,iY[%kW`M.:&8tAB)U)YIpH!WWtMG2GOh1@A;[\$GWti?=pt8iqK_opp#5>A;-g/C$cG3u_>ElE;'aQ2,_0MN7cZ-LmR1fm3B#[&J*=GLZ&NdP`@9>Sc#_e/1.cFs5nsKjhQJX[.OsU@6Wl[6jjPbB*uNoR,H:gs1m;6aY4JD'.!F(cJuSc]322NqXp`1),PuVQ8SGN84Z2$VD3D06eTTgj9o\%2I#CP][>aAeshgM`8^Zh6D_57^o,n=0DVT.CftS:S/[L($"=AY?35UrSF`meE;Ws2UWD?`t@?[/,n<*c4LjU$gsrs2$+k^i2R;!U&%%'-+?L=n)I](p`AFDh6K^GDA<*9$'ak8DE:t)$1h+UC:^fEa8dIQ2#9&X:74#%b1L3oL38'N0h6][)noWfGr_qR?(d";K/,AQQKp`$(@L-Pc)iWS@*rC\9XGmJ860?SAub`Mp"Y@hHcH`i,hs7_E.L%m&jQ.Q!)2kgWOmlak"8RR&bl[4MQTNACT7B"`J^5F%S@Mnn$O77JLqFk-Pgp`?&&VI\OF#SZf*"@cOWAFC955al(MX]sPe.*uX6@'&g=rF4#_H-Xn/Zk-3MKRG?Zk!Hu54pKQld"c[tjpD@P?&&uLG*G`]h[PUG^gXG3@Y=MKorHKZ8flrp8n+dZX,~> +endstream +endobj +304 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 303 0 R +>> +endobj +305 0 obj +<< /Length 1523 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatU395iiK&AJ$Ckb\KPAOPgS1m_Jn`>4AL$Q*Q.3!VpMD5"8";Kc?*8;SS1Y-M=M0K:<&lf1+K&+eK9?0G+GGg:[oo:5K43Ze3t6^_E'*[X@C9J?37`.4KLo_Lht]('iIu4:@-5K;@^(;G%IO]0@up4OuJZ5hfu\".\G3K?5/1"pYaYU1]M/'Eg5!9AE*`&^^$QZ=#?5o^?RR/m97.b_:BN`'$L3+2@m1Kh3ODZaN?DZ)R2CJh4\4:qn+>]ceU>J(lt[E&1D3*qHnj(/jRKjGjU=mtW6L@.];k=]5tDO:TU>='Zf"JV!?,RS[]LKkP:?A*WQ!KE324i1[.AJB`(2tC.a=#Y;>ZutFmAAgj=4?TTqZSGM4LMRPI(\m#Y_d(2>Aii1'noIWQO]?8\$A@7_NHTh._oSAjHDQl(E?AP;\>`Lu.I?2d&Wfcfr#8"h1Kh/Q[R6bKQHG!CMb1=KU*6'(dgi%i[K<5AOD>5oQe0,[/6^:d)mI)-8J!kf_o(/..EP!d5I)cT*TFDQ135a/Rc=e_cC+kmnZ%ukI"\2jNO6j\\e;oj\WR`X@l8oO46Ek;V6Ts+/&E],S=@+,:I38dUDIdM;;9KUc;;n\t=sA:O+_8m#K``17oQs0J-g5sjS\2o1$UP&J;YqMBQAKr]WI]R0E;,d6[kmP3oCh9^<%C?$cql?mG%kRp[,R7/?+!O7,MHf!\%O:b+p_XZe+GAMET*>'CYQ)JS@XP.+.lU(;0X,EP^-BJ<[THC`e@1o$_7`Vk]JS!&O6o8r\:;+8o.3e!JC0V.eI(3@Jpgok;Z==ZBR;KCjl/rl26=TGMchkuV'(HkJLj2G;s/AlteOMQ1QV2&pM#h)I<'41O\[1j84l$722Tr?/t7j%p6P&R,aP>o2hXc"Sh)i`IOkpEZtFX]eCXcpWC(A%YLk$Pf16RJNfS^7;bms5EJA:=eO>cg.k8`?a_^Wo$eD7urr)[g(e14&b?QOR9(GC2!&)h?f's/1>'U[@`EFE[aXXepRKEtRa]~> +endstream +endobj +306 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 305 0 R +/Annots 307 0 R +>> +endobj +307 0 obj +[ +308 0 R +] +endobj +308 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 138.6 606.701 182.47 596.701 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 286 0 R +/H /I +>> +endobj +309 0 obj +<< /Length 1061 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GauHJ>Aoub'RnB35^d;YWV('02K[22]i.h"@o\t]36R*IEB-0En[Nt!2]Bn`1Y?B-CG!uI]=FhnRFpm`Oh-#8EW`2.-7?3i/\o>i2Y%tdd\sfSn9rU$2V(B0kP3[?pa9.J>SQa$h[;BEq3"(dTDtWqGs(Ld?a7%#i>c]Hd9'HC._"L=&M7k06X'Er]M=('1Yh[@e\F[lqq9Rs43(0B,UEC`4p,RLKW^AkK%k(@hmA4NJnB]@p;='A/`P$lfXB*B']7nX1H\"fe,XpWf4u(R&2Vo*;Ll/=)`h$<4q4[:sgK0&pT:sB=S!Nn?`N#"K5LUqZL0bCM=:$K3a_2F0b.X394p:Fl*sZ$'@QWJOhn]=.!q!K%o^"_Pq8Zk#F04=ibX^V`u*X-[dOF:!C).JW^QCbd&N-H=NV5bh=[(WH[j45ZFcg?%jVNNmK&=1Vgl6d&B5<_G8AYMopW;A7R_6GJOBtC,D:tV;?$7HCPq9`/f.pF`C[WQ;4#5WA-P,1V8lAd!T'%[A`dCPgW^#lQfa9!(5?3]lVI&e-nc1IV2aR`UC=^m[/V?Nm4FEgJD&BSWOki"S"K<%>$3khG;Vk_tOB&,F^T;I6\T#;DrE`2fG2a_kV46$B0.VCO>L2BprqKlTM>VEb&8`oR~> +endstream +endobj +310 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 309 0 R +/Annots 311 0 R +>> +endobj +311 0 obj +[ +312 0 R +314 0 R +] +endobj +312 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 218.85 538.542 326.63 528.542 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 313 0 R +/H /I +>> +endobj +314 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 240.51 408.943 348.29 398.943 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 313 0 R +/H /I +>> +endobj +315 0 obj +<< /Length 1781 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau0Dh/D%+&:aF]Tg#i'C7EfK7l%2[JHb8AU"EuDAKD1JVAu;8jAJmG!<(qJM3RG(89#[dpuUp7hYlkpa-/`)B'UC+1N]@,Rs:fGqjF/Bib)qZ=URCK,_i46%ba/=boOFGVJJ=I(kT>uA\rWXc[:(2@-)Hg:1E\genE2Dh*#3XPG0T^S:R8][EYn-8@jB"7C#3^+)r2m8I>#@];,,%!(!'$6X)"$=j@O778"icqs;,(Osg=r)bVtL@et4b>;VpSK5iL&]8f;NjiBD5F'dd72R.klkrHp5So;en+0KA=Sjrk*#s>?=e#>(oY-J8:0H?g6b.K,=TuY\&-a#e/`PU4TcZUGApi+Vb2UKlPJ'%%R3"mDSh^34KU:-8MU1?]d5!hrr4\[G1iWNe*[9)Qi[UVfS<+UCfiFQ##OqEJM']hN>ce0K);rfn=n`l@jDLLS;H$ee7[$92eK&+.IE.q\GNOR@`Pf%3C3t6^Ps@$#!k.D-1Jg9_7;-"g]C*2I[a_bY\d>8a2-CTM.HgeP'Q#pgg1W+sR!.41Nn8jgl!augh<"g`<'3;ojSU/T@P!@M6U^j3N/QkeWU(l,"Q=mr#=<<8Q4PbdI%2G!IfZ$/WdO2%;dD8ZiGg^=WCS/d%36P3@+Bub$]RhjJ(.m*%=I2I$=(_kB).mmoPfb6O91Z2An5daH!&FO:i)ndZ@p7*0at7U^D0iN^"^7#?ne)pPbG;(0!rI#%`?KeMMqOO[gdR_=U\4!0J*>Z=\V(MjeKKe8B>m/D38Y4f\Sr&Da;7W_Qm8M%LdCHS)dr0T.4_^6X'-7B<3!qX3rnD"iPW_D6Mu"f;G$-VLG/Ra04qB&F9W[pE^]0ZE)3[`U>)B:d?NNECEN;;pSL;S)uc%"\BaO\#C+,*DXp3*HK_m/V7U(Q,(\7?fB0f?HVI"u0b%`O!90X(3f67(-O^eJ/'MYDqLn"*:`7AHkY)XWp-(X_6h5O^/U?N6;6sLPigK-Y$SoC^>C0.u(4\BCYW`_5BP:ErZ#\TW8.O_VR1q_N_i$onM-b51%F6DVl^e'I)o(CW_FTQCH:lc7WP*Ot0rA]s96Od[T0SYtCs'T%/c^AoN0)asc/Fgi&4LB'c0BNq"rU-r2\^1okAeF%n5-,Np%?)OK+cbS`^/"$1]8(P[M%In#Z`C^$]YqcE>pt\am)&tO`O\(XV05TnRQViqdJh%!3Y%5,r8/B68m>_d<%cR\k7.&$jjLRT+:cOOMaJS*'hgn +endstream +endobj +316 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 315 0 R +/Annots 317 0 R +>> +endobj +317 0 obj +[ +318 0 R +] +endobj +318 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 385.406 709.0 412.066 699.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 319 0 R +/H /I +>> +endobj +320 0 obj +<< /Length 1315 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatU395iQE&AJ$CBROlP\-sH'AT$+d!aB(,[L;!X*gi=8e]qd\bElFh"%=#W>;^*lXHe&^t(<'IKHKMk8,dp6X:>C;bX8!h"D_qM\.2kH^4M(V1_5DU3q`"SW^F?$*/r:0.B!Dnn=n^4CG-e,FuVRAP^`l15`B9pdnSdQ!oAna6l2csBt,,RI'DiOmJGj&:\ZQP]fAPL6:;^s4^N$0@SE"W@T]@tk.G92e)Q3l8snrLZ`:`8KRqSU=BV9@&K1AuSP\P]HQ%D9u3.e.%KoZ'&r_4>^>om$LTo+WlTMPLZeQWcNM&p=P[RB;sk`:PAuXJYiAg;SJ.5*]%7N^"bE8$HJ)S(%$P3jY:H2gI[%:`maMI'2(Y_C`K'8T:^p'AQWMtegfui;*%L_N#JFT!17Jc+/+K_(aY=XJ;l4->q`,Ub]Xb(EMi?;+sDJ5XnW32ni9OKL6m%%i\"[A;QaGW`^Nk:138?t?XHJs1kRr%N=!Q"dLr%\m1+EFn0n%[p#Z'!I*)cRaFRE:Gn%:&IAY*7P_0BVVT@LeW9P47i_@C`@\q!Zd:,&u@Ds1T:?CB!U2=78q1NC2)LJ@Pq_m%b?0&@c9adR5li\6\T7@kO*?4XW>4id!ZKXbS79fmXch`6EY@8?S*ZZgU^MZc8PH6'.`Q+Qq!V0UW26J5N->eDpNe&sa(=G`&7&3uala]R3RK64Tq[CqQ)BB6K@)N+K7U&K5)=_-D3)HJ:;G[0:4?29r_#lT!V%`U_'qq9W2g4dB@q21/kOT*,$8ABQl.^Nn'5pT$Uj>%,Y\9L$rG_bYF@/aHCkJguGDH5jNXfjQh:kG[m#t#CafT,spU0Vk@Gf/7/aCLL8ssm`\0KfDgFqC3,W"6_5CTTm9;:iab2(NdIQ^)=KofGah?N4XoALCMC[SS.f")QiXc=4AcKKVBi^W(3%^`^V??f_2m9tlVeKZASX.06'\_dTQeRS' +endstream +endobj +321 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 320 0 R +>> +endobj +322 0 obj +<< /Length 1608 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gat%$h,!&j&:a.UOaT3t*3$36DkK66VqZuR=fnjT4TI!de86EsP"jAWC>&R?f8cDJ;As;'KKS;bb\o[Sch)NI3r]ms"=%a-QQp=K7`<1AO'%&BAq2<;Lc'[hDT5hA`7_+InZg^aa7dF4WHDjus4KKo7hgZK4;2N+WF"GA+/Zu*32<&9jEB.L`p4nm+ah^.t/qZtUfP]\r&Q]@b8L@U:!$q!]7MB&q,us/BG,uAS`VsWP['-Y!fhA`qCbp`PPLo%KB)k5_Y1CC#]hXnghrs-/J3D6-OV#%@+jWZM24i')85jSD?P:`"jQu5+EbAaB:IXqQCQ^j$8X"!KUPk_>)JCTRWlOf@1,@?JpQhSh4bXXba!T&<^coj9s4gCTu+W)MV+0d_'!=d]e8,YA=.P56B0_g),htI$2918FCL*+fDnj[!j(uVJ>;OF3Y#TEeUKHf(S8Z4JpS@qeNjN=RgQDT;!:)MCg"sir;9=,VZV4:h]RfW/D4\=I6ntNlLuYc+e\`!9309j/%#sN[[]ETJ(+`7KdeEK`oM*%MD)bi#&`YRPgm5giA1M7D7pea;F!+(!^-P,F*%,QVpq;OJ6!;MKMTfTWKMM58#S)hji)sq/+to1,M)Trc3i4/OD@cHk_DbM^Q\_U[$F$4_l%EE6+)I)6[V4/8@%X"CPK=d4JE+;j[,s:TX.0&-FC+dg/m:cX;NgMAaqp>;YajJ%Qf#XU\)T),2$fm!GPJM*c'"kJhs6))QYA6l%8r5IGV?Wl:n!+IF0#(Da79>7#][#TAH3='g4o]I9;0IX`2eC+Me(ZMMKHLae#K'f]t'tI^D(A!TGcPMq:qd8'YHc$7O^Z>fp?X6n$[j_4gGR*!sc<&/Xn;-iiqIhq4J9tVA]:42R6_cuuVD'_Y%g..~> +endstream +endobj +323 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 322 0 R +>> +endobj +324 0 obj +<< /Length 1176 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau0C8T3Y*UXdGqF3R6N!G9'YqW%>+LH3IX@@=qJh.t.JhqC]kCak/ON2&YUdJ*tKiD-jf/+<05O;PLO@WDHOW?&M1bP11=o&hEN#$5Pl6\LBNK$dH1u6)a87MZ*ST&Ml_]f@jNQ6rp@G@%N+c(B&7>1l9oY1o[,&jeu6Jt[[WU?_BSJMrMF51-+:FB-A@+tRa9P)9aR^)bldG"7G3o0k)"d&Pi'=*3BA(D*YjTElT-.jc!c/]>_#r]i[[>lS8d)-r!*293TVrFM+-)\t(G*L?CU=rQ51rj71DMKE,uYfVVkel=%9Y;4/!7J[%W!c[#7;9D90!1e+D0Q@V1eHoX?[M3-Q!O^iEr<\.i%fUg]U3)Y=SmP[$1m\TMj:'b_^_-/nCp,$8NU"lsJg?j4j/F6Gki-Bf,hS5!8G5lTVaX#qh/_3nlWV-K.nl1X3Z+Q%A`/m(>W^s-9B9F@]Dl]qK2*%HQ^V`c#AB2;WmUFKV!:M(9hJB_4Ospp(3V4kBpId=Bg:-lA]$<`\>DSYaP<4`Pj9?f/s5>PKQABZ#Q%c^:%$"667fD+AEb@ab3!]R-`lPH.RdG,qRrVYb"+;pRjpW@HJh*,?m(7eJ0tQ7&Q?<_nt@"\h=cp3BY9`&(\s>\f(d/kS7.d]F:rH#C\l/q:43kTlT5#_]7f86XTOFe.)B@ptd*m&R*1J,-fZAPR'8aO;mP2-gZlWnK?m;^eRo[YNN1=us6)h4CY?&ChmrR\aTs,E+Me>NsjGU01HkaBNaKp;J]oL8aVTG^2)qLRq[?5Sd^1H +endstream +endobj +325 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 324 0 R +/Annots 326 0 R +>> +endobj +326 0 obj +[ +327 0 R +] +endobj +327 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 200.54 177.341 244.42 167.341 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 328 0 R +/H /I +>> +endobj +329 0 obj +<< /Length 1585 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gasaq?Z4s_%"HU$nG8:`B[oZQJ%^3]h0';2p+S&5*noVHfLhl3D)oe3DJm*K<LRV#os?F+e'/YX93.loeWi#0>\h?n5E$-#^G.rs%;(ceeS\Sh!Zi4'-l:QE5>WfkU%1b=Y9GmFDH9q/O?o'-[@a9IOTV-7!OL)ckB#C9@&8o,/9pjeHhqBaclaqGQ8!X:+ru23X;b3(/UI:#.Q<<,5!EWCn]s"umM.=+NBcL2Jr8d4KNEWJY,$WChE^?G.2;b^u1O$N=C\QU#r)dm1WTiom?+dd)_X^SY9P[a>=OJ?VgEir@T@DRI>;XcOeV8PbS\]Gh&5837\pRV_33qAtY/8YFn,<#Pn7,RSB$('SPaM,>2NTEh#FKkG$N2Q)=EMF`[F>O6KJ/4Hm+&O(S_CQj2AdJP5Lok9!^fB)V'e8lil$B.,*1@VZKIPE-F16AhaUl8t%.XL-XXDpHj@;(X!kMF6@i&u&Vr]]X1YUh9[RVfLp&Ss=L?O/>V'1C:"LJ$[(-D_q&TGkH/Kb\smjkL-L`rmgq"Jn"H"kJL2X8S7<@HA=1=7:[m,>U+%H]D9A6U$'`blMgFucF:^4qSfFQR0u\ba(E"@&?sgW!gZbcJ6WD^gJ4C?a;&m!)lEWFJ)BT&"@m;!$0NK4DD:Y[00neIW**K002oPTK6XIcaD.W\)sh_j1MNbPcMN,;3X:ZY?-.<5i@&(Xb^[.X/60209T!Wi7/ZD:Ijf!08bJe,H)3Uoq667EnbA97qnPA)$qjfYhqkG,D*dh4u,U6cK%ZWn;][ou-'#M(BK*ZW;qbo>DpJtn^go0URAriP3%9L(jV-.IMJQhIfE*R"WbC\(f8*8#nXd:$i8%']!B="dGl5bFfjk"uIZ6a`d143$/@h[e)8XnOJ9]kt.A%6G$YIatpR$>c,Q$Noc4hV*71m7#j#=p@L"q&:f,!kX6k0bkW2Ul"8Q@7R#/!2s@O%kPYX-fHV]K1)RL$ciK2po%Y3bL`&@k,Z)S*RFE/2DZf[aB4J`CjTl>J5EHcUcPc!/dlK9Y]o",GdfZ9TZ_Bp_.N12=s-dFLYE:HT76^NR(bOT:eIg?Go`VT655l3Y(TW,-I459E!ZZKqj,Cg:4pgf27;`Sj5s@HX9Iq3Qge[HY,.ri]#l$R2;)(<9HD=9ho\=J)Lk7t3HCoIT7L7beP+R=FG)a5B"UZ%^9r>DcQ02VP1i7M3/+2D%]<<~> +endstream +endobj +330 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 329 0 R +/Annots 331 0 R +>> +endobj +331 0 obj +[ +332 0 R +333 0 R +335 0 R +] +endobj +332 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 237.19 709.0 281.07 699.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 328 0 R +/H /I +>> +endobj +333 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 404.65 688.0 459.09 678.0 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 334 0 R +/H /I +>> +endobj +335 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 331.6 317.777 401.86 307.777 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 336 0 R +/H /I +>> +endobj +337 0 obj +<< /Length 1421 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GasIh95iiK&AJ$C#ei,b@n*7^4dtN;gNJ/?:nWedE=T?MgVV*r6W*Ac(]Eg!7+*&(;M>+eb\/'T$thQlkLJqe9Boq-q;,jNo=`$MHbT?o*[Zk#p'HV][lSf\2[gH!;WX`[Gg"0H^>Ae!F>P=1Ge``S][`Xs.D7e03fG876E2&lii8T1WjLHO$B0T-]d%;D_/'m>OG#R<,.G-P+9-h!Y<>-,S46TPTEOIU6/%08Jd-"0hNl)]pg%g\]i4Ul3@,18Q&QPe5hue49+m0TX8#bj9=EkS]O2s_J[J!_&6ANlJn(h"-32#eRs$$"G8d%s+R:^^sh:c4h_EM#[#aRt(s"h@sp47V-t3Gua(UGZsK3hPhpjif#.-f7cnp=6**9TC]Q@M.#=B5'C"Ct$)Qh;dXC4ID$_&`p"(t?p^h%#b9N"[iiODJ(YQjjnTE[+^f^o;DldoF1>iRkT3dpj>q)]pF3?s[^gkX5(5]I"nK<!l?dd1foIf(`UI@OOJjrho)6ekY%#`VbBa1:V,[Z)1=ngIkFJD'$DXR3GUeC2ZMER?&?6MC4l:b!C*a%cWC9)F@OWcZRY:lT40YJ.fE7RS[Ri#Wm)D8A%^H*9D)W@"D_gUdTdD9BLXB(!`Ff6;f[n*N6!k)Q5E&i1f#fZ0iD#m)Eg_Ig#JOAj]g1%J)/8eJCdNO6Tc$'DXS,SUi"'Gb+d4&(Pa4CCT8?0$G+5fFW*\pF_ro]S@-_\Y,:ESpHP_ERO4VD!j0+j[LM!C@3uGl_P&56csF,'pQ\,b/lQE'qW]#^1i0B5G.q$H?@q\B_&it_raPH)mMj+c*(_GYg0S)FRjC._N51"Sd&^Pcb;R^a&@oaitVX(.X4!M/AEH!R#mHdk@bfEID]q][p-@(IL%QA;#n5#2p:U%I;/\cR_@u.S,,XPH>6>2Ch[6RJp[CJhm:Y0_0QWb:p;?9_-eh[5O`[io*L,j3DQ*BrrCo2S,*~> +endstream +endobj +338 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 337 0 R +/Annots 339 0 R +>> +endobj +339 0 obj +[ +340 0 R +] +endobj +340 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 138.6 253.036 207.77 243.036 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 341 0 R +/H /I +>> +endobj +342 0 obj +<< /Length 995 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gat%"9lnc;&A@7.pdR:iWqC3F37%[9bV0-OLC<4:3_JD2CU^b#9S_k^B5K/]&o=J&0@FJ*;)%qU6OPC)UVe'u_bR&43dqr^JDJ%JR:$UoYW75@WBA0F$/H-;.?QiagO*;F68;nbL`EI-dJ1(f@&7LKZAu`M3WnHbj]t(@L8*^=JESR\rHgJRNj1ulXg3HZOCaos&]tKu7n+qSQ6,\rUZ;6)`V#cg7\FVUoAK2.^mDf!BPte?'61M?bt+YQ,1H"$L:2W!+L[6[2Qt6o%0pnZeug%n)o#dV5j)pP+Q_#X+Kq#0oPP4mqIQP":1gAAP<`!`&3#4.Ga8a$e?(N9lqQCC`kn[TtoWp+?]\M(>-i4nG!j3.oUbec]@s-pm+5@E_1H/J/\r^mhk[F`q;)WB:>HM<`i81^k#_)_;7)Ch!?@1!h^t`M6?0epEE7j:O"k-0c)8d0.*0c?l&0&VY[Qk*fP",aM]!?KVZf7ssl`/YV<3[:mi*ISPPe(;fR=2Tf6RYRe-MC/-~> +endstream +endobj +343 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 342 0 R +>> +endobj +344 0 obj +<< /Length 2142 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatU595iiK&AI=/#en5C[#@DdZgD0;fL=O^JRT)\YZeE@9\V*4.FfZ';=qVi+t7N1LRgjG^u10miQO4k%[iBIRto=@jZ:Jf2Z"H63o%62_uEub`>paT0leLSo438TfBc>`GLek%j1HX/@Vad>WQEf?4_aN-AA4/<*R/BB.tZKLI\n";1V,A,4HkXbd=t]CjF;E,,/[TJSWUd"Ce)X0i]OK%NV'7NDHTueguQo8GB_UsC\,^d=2u>#IBI6hZa/d'_Emp=]b,33K"gq71lp2FH\X7g"AjtE)Ek7WU1$h3.6S_9H^VSn-7LVWX%'r.%5+/TnefPQ^W>"8DaIWp.AQ)P$V/,Oh:Z^U!Agrop)o66*sGouKgQBMZeG^BY_hX+DGA2VDb!onH8"%9!O57p42%fQ$;5%5ETqMO)k/.;l>RAF"GX.'8`YcArCrCBBN\KM<73Zn_/M;ee3e2S[u/rP@X3Op8f^,?_RV"U_KSJYVF"cGs&GAi)T530K9!D#iOn48h#l$4mRkf9me=pJ&GrU.Q_o(p3E[fmtaV&]E4Gs*unrt7d;/_Y?d-=HU)W1WY865Gt[J$?PM\(mrm@MXNHgE$Lm9[TU'F0S7cA/D\35=tY$50Ph0d%!F/tFQ>`p0R%gb35OVUF@Bqn!FosIoC87'JEDUP!6p1QCr_+R.;dS479c;_GsdO5,>SYh%j$`b@\.6XWs?@t!klaLF:)8?g\(A.(eSX?8#BT0,30:/FYVI.;i3m5&A05:NfemE1F0#oLAKX4"66YQ"VZ,`d'oPjDf*b_]e_`S(TlrW&Q0iq*"S^;Zuf/](,Nd'`N1G:.Sl;$=>j7^(2a[roZ(^t6.@%I;q6CYk?l?u,FM,f\=:D^(2)@@!7&>Cg)7\pom*bDtN8[Uj_?s"KgJNKH>Hh(Hq'r.mA!([q3oNuVu;=$!TU2F(Cbk5G@%?i?Is%`Efa=3UY\uZSU,V77oVFdXD$'`o%dD'L`R?(U^:(@k7eeq0+,^@ +endstream +endobj +345 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 344 0 R +>> +endobj +346 0 obj +<< /Length 2208 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gasa1?#SIUn3+NQ^`FI?$*3NUF<.S$/'pHg)!8;Q&%#$bXC]L"W?g?Is1X[fM'lH7LB''t`4I8_qtP/Np[3+`GV4!,`TGHg[We>'_Op"9IY1Snh>:eFr"H*C2gjm%@Sb]d.aqYS%>i.WpH/rNWhLp9T.&-;64HF7i^S].X&T5Ic(AEdl]knACkTtYUrjK&p*,XT+f6Q[3b_1#:UeT,U$J*lgt-_.FqF"gQ*cBLq"JEU/cEq73mIH'U>a'6L5RO8deP/Ht@D<+i-'1YVJ_EmFAd*(=Lm^JB!&r0,@Wk^9Lp++rZbGYQrme_;%%3,Muaf>HOL:p=JSc6E?,9/i'aQRREP\0ZMS5We$>HNLXG2ao`igDhI8j6plRJ]"l?8m@*`\cHaWRJ:WntGd4Pl3+)<:+S1FS,3^\3h-?Gh\n0fE$1Us;4X&g8:$h.$IIQ%4dg+d$ekkFkYflgtd1#-_:NjGDrSS(]o+)VgD?jE+brP8bS=Q!G6elF?5-C4Ck9]?ZoVf=FVg8)%8HZlrhsm#:WoR)oCGiK;D$-*kO5F`L,.kp/_3t'!X1*f)gB4TL"d"A*j-`RIdnTf,\IL@l$;E/f<++p%o-8,6`$HXmaWC$9V38)%NT<($.Q2ENh<;$dUh*kCZg[jG4U!:p;Eu5l>UjCl03:h_#'U1bNe1)cr]F(mG*[?Ra?1)(l%kCuo6S`Y6g9g"276)em&jMrGZ+nVJ2S*s>Fd<;$!KsRF>/"4N8^#bEcU>?<*R^-hP]aSG%(qh&_bn-)<9*#,8cS<4&1mK<_^7@&1V8EQs>r%$lZPmUWic$$F$O&ca;A(8>[=TL1TN9BTi>^_JMn>LOm>[U?`m7NqG:)OCK;POq5;Whn6i#+,/=0rFF5AQ`/nmq@/=l2F\dLZHQeDm58P.KIjN$>hI0`"q\\9B68C1Y]#kbt:Xjj6C^t'cecDlqlAL*0CnY`*1Upm6307aEZ#rL&%2J2nE+G#C&mKl,gnT5'!NPltI4\&m:H5s.[>p(\'cuN@>/K:rGpmqpL?g.rHpZ^Yq*E+sAAGC.G]f&l>LdYZdOZGnWXjqO@nR*j2't-;koYC'aZ;%tXai^i&i`O&0LBUI(@B[Y`sZgfk8cZa4h\D]%U'`m=6d&e76Hd.up/P,eQ2qfsm)"@8thrS"K,oFrI$C/>l!_Amt[?+ED&SZ(i@%O7>Ep?_ET$+,-3b*lH9Z-*B`)P=o]hbi%"cBp"H;F&fToHB0#nqg=Ek*~> +endstream +endobj +347 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 346 0 R +>> +endobj +348 0 obj +<< /Length 1087 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GauI6bAu;j'Sc?EKngC:aGG&IS[P#pA^NrES[b_^Kjk1p0fJ\NP>8"D?3uRm&D>F-e&b(ANm:)nd>*)a%PFX&5q]ZB\/;a$Ee#-2r?2DS4mBKoOQV:4k@QQqo!*7rR@YM>Bi0aEP*]\Aed4Pi2aQKd\I7gKnCc)UP_c&1::RoY1;5V4mX&%`Ah#_$C9sncI^6JK6=>)#*:fr3pZ=F_RY4UU6hS]DA5KB0g/H%"`7sm,I)$@V5,_M?SVdrXPk0Jk^^&EdOhNnEOm6NHQ2%:`BsE_^8D)T_!Xb`i4iF6`s,K7\UVL6S*hmPbf?55P-j9R+4bPS0HeCal"8'@]6SJVjb8u6PcsHDWQN9=14ZHj-]n/E";b(O)L*YdK0&t<"e)X]2q&E&ThG5@O&\_W[QW.`9f7F93%L%^J^nYS/_DWm^Bp=*PCfl>.CQAQ_4#m@csO-N*%qEX#p5`)(1,.Dn&%>Z[q$hk'sl`&SrP6$*?7&EA:n5-cnlXaIpU%tT$6HIQjs2+$nWP)+3_M5@Qa;nOI.=F:(d7GC=86V`SE:VQoQ!WSk~> +endstream +endobj +349 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 348 0 R +>> +endobj +350 0 obj +<< /Length 2025 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gat=,95iQE&AI=/(r"Kc'3_-emK;Z'B_P?iU>F@F&%"_d6tF]1W$]NYs*[I9'M4"a]A!;h3LUb>1Z*0LIXSW:b@\Hn]\.UTjj!L#rljDPrlg.LR!9/frbR"MrO(:ceM'N(M+AMcUF$p$7qf%cV8#;4L_[S]lm@/q\J^-]W4VSC>EZ5Ag&G7dBZif>>B>fB%`7]g2$@rgqhF5?LO4ud2KqVCNOHME)Z_pYfY6J/GCS"uAL)-'=UX8Y?=t7mKiRru:">SdPu6a+>Gn&`_D<'7jlBjV[k,8B-j!T#ce/_=3C?-\eKO.r'V80RcWsUhh%8,uNb1^YNVKZ7>p5-V^bdm4U98eudiC&p7?$:cacQLM`EoSZ]pfs@^!T*&#d&_K0VTP-@;e&e^d],E8IKfp/!WBBed$7_:c7dU>t_$lIm6sD%cB/VG)Jg=#jd4GEa@b(I9`91T$].C;T/@9UNGM?!Q,V)I?]5q]%h+paPa/orI[^ch.mS^0:Zn&I\GF[cNgGTrF'@hJKPKE9-8"Kf,[SOVP1P6kp*Lm`]8%U?ApjSJ*J00TY?oB-YpsPf\7EB.@\b."NqiR"_&]:3R4"VIbrM+mDs>&@.ub0cTE624okN/76dW^qqY:H7jM.IW-F=^k>1PO;b/2EeZgtjRTu!\6WZSFp4+Y?fh@UhrG0R/Z_aJbjNo;6?Trooq/]^VG4rG_[2[p",h'dLK:JGIH+`piTB-%Q]iU'GDscoUBeiY.A+\WL67TZL;erkaD:P@((cu6P4*?Pk2?#d@1d%9Z+,9+H]r[*RbHAp*$lU]hRaY\g"#=jeU3UbR:?2="QT2`:,cVAEq=nO,PUl?E.g\1dq00L?2cZ3IhE7ejMIf_Z1dsm`j=LO+'7p_mW.8^V$ogu.M_F=cI]H1![Xl?/_X^D0n.E`BhR\,*D? +endstream +endobj +351 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 350 0 R +>> +endobj +352 0 obj +<< /Length 2278 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gasar997gc&AIV:E;,N$X@)=P8CIQ1cl@@ICS6GB#MPn'2R;C7e8D`]s*I6[,n=M/Rfj!V@h(Nj%HjR8f\UF.V(:.@c>&j+332)!]5li5]CO__R'G\6fNi>iX3Z"ih64Po[_GNugaI^o;GF+ZoI"'Z=07)kDHG.nQQ6#6?ZV#UgfA>6]U)BGEBYC*+1jn0eenT)nlS\S_T'b7P5&l"M^"R&.^?Wl3kIJ7WrtL/N$"aH\5(s[4Ze`>k*4>Z,f%CGik7mosmV'Mh-KbNoZ,Yi6efd)P#;Hme-7S/mAAmR-q5r[O_b--I[Co>XPk;g,h[uNqVXF3GH?^\F$IuqIp%jOGqn(2q'JmDe%)Zk:JF,26s%"@a#raJ!.3^p`4;/gZEYsV)%.X565VPs0V=,2OX(5W$Zd60.nGUE+l*I#)6>OY[OSf"R@.1.O]7EZB&E,V]]T"5]W2Oj22dMGFAg27JY=[*['dZ&0M6I%eGI#&OU7#b%NKTEZ_jHE[_'9i<)--"-oR+?5s"DXM7n_`L,FiE)?UN\q![X-rfI\9=:l1unK;r;WQob6=gk#,emiL%0MM+Sf8,L6#ea`,\)dGegn#T"a2XK^Mq1Z]MCWE8'N?t)Pqc$%U3'"GN#mig[2q&.%0muS2-`")Bc\(d&P5r5rGJaNI3MEr\`:r(F2KL_?MJKOgJt_pqhq1!"lm,ecQH?@#HV-jdt1C!6)$CXT'mdeqRtI#%n>4sEHg:Z4)Xq0efiu/jqc-h.gTYEcQVH:7m"0Xr>4ClK7]JD$fH@#H=7%@c"IS>TIOh$pqs5am+[%<>\tVd2^[e>(,Bje?NgffLZ3Il7R'V'k?DbL>Lb'JdXCS[!S4m],U%WLT\]+!rAYtZ7>p?4^aq.T@2+(em_C-*UWi\hkFt-SiuS7\OF7S?%]I3Il4n_+!=)AB]*H1h0cohhn9m.'MS[o+t.?SH"aE!0b*anK?dd0'SMbjV!pqqJ)q[&mRI0bdnO"u+Xh^1SoA4XE'F\dD(p"mo"q7&I2YMT5O9D_c@5=q'R<-/\%MoPTnekfmA$Y$ND",tMee6*W`aGCs``I?mbP(0n.__Be6$Y\>-#1"^@GDqWtguruk8Gk3;D`/5Fo]:UtZHf%\D4[80q8P*F>rF&6+UM%n\'gnYe:Bl?16pYV.cGXrPYQAt?NhC1KL4`LW8quN8s8uB.1Z1h]fu+a5ekH2#i3qe@k%u9Q;Fs@kA*T6,&EN&q1HQ$*"[7FpTUCAa;MoJsNRfq#gO"9+oe2F""%W\1=gac7Yp;,k6V+T8XX>HQ3^]VQYRJp_%PWhNRCd?CXYjIN=R1CAN&J!-1M^U(-U(30UKX4e:U$VG_4Fld`7*l?lEMBSfQU7S^$)m%&u#Z.X!Ag4L1+GOqH])Yk_L6^>:bj)cqKFng,,TX725A+ae-DaYT8Ij2:c_kl\ZTX;$rl>['.S03+>t,+`W2G,gd(J5ZF9]%RmEnAlrhcYcql&oMJ[?>3nbV-5ZY_pM0^](V(rJ/EiMbNHiNS)V0B[Pl?f8O4ko$%#WV9h4,lSUX/H'@!!V`?`^t09Xu/[,ir#p4jo'\I>XK,`ftR*(E9;'h@@\s;(7JrH]ko4#rG6NTu!s`&97sA!77*+$t!7GW)^!eOuUIR2KY)V6T1#6UQQU8>^4rd3%LbSg>+ooMhR;7m8Y%iUO<2bqbOp%d:>V!^FWkjp6dXXM!lkQK(3>Z07nn+OA?i/bl?/OfBpgAq>VB9C,$-*+cN;sg4<8A +endstream +endobj +353 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 352 0 R +/Annots 354 0 R +>> +endobj +354 0 obj +[ +355 0 R +] +endobj +355 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 340.168 575.84 409.338 565.84 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 341 0 R +/H /I +>> +endobj +356 0 obj +<< /Length 1785 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatlQ9lJcEoU]DuoTB>J)3NE]L)jH6_)e6EXTirNG+^G@dO%U>75kO-rqAR4Pk\cf:-'(T!kh+L7m'Mrj(F=DTYS,(LcHTQ(=[,[_mkMrejHkLJ&Sib]ZW=0I'pT>;&iMn^%N?]PKQN0,qPK[8ODQnjh9L@DIlFl=XL%okJST5[--TeBre/bJ?HYjNp"3FRbQnC<"5jh;8,`fD;dqSC^KkC3'lgt\a8:4#/LcH5$SV<\@msC<1Ji%1@Vf5ah&!q!k^Kg8[u8C[JMSmo:fPaKPB9:>"PE!IY1BQ3o6oL09n.9-GeJ=Li4fO!udu\7d>+>F+e5,Wd-/]X[AML%\1>B%T8&hbL_G5El#32lLmGr.r')E=uPh\-'A3M4c$q<8#hJ$EBE$\Vj=oAdIj^@D_iNe=FX:*Pu[KT,CK%6QroNNk`F/[^%D!J8*ZBG?G)"%/CG"#QKot-,niuMV5fg7`C^3[;8\3A"7GT[B7'#"s*BH>#_+'\'(52]WiSLQ2]jAf;BQX'l'kfrUQi]0kA_?9,dg:&XBPFoG0iI[kYsWSHWskBs.LnV:lnCO]tNTjaFpBLW(C'.]PH"a:d8B%VDdY2-R7g+1kQ]-\%ea1[1eG(],7I;@WON]KT]!;4*^IK7JT`EqsPA_rgP*1(?^hcHnmM@<['35jY1=;\EcR+()ISuYN8A^]Mf576'k&!VBV")L.uJ.5rrYQ;o_hsL!Wm&Us[e@WV79%@[pY1]9bFq@rQ].;:O96>u52(K[rD:?Z.[="KE=\ijf7=$OsmXHcASi@hF(Pb^mq*e6fW1cD6^'oc07U%.0Y`ikO@eAnMA#I5VN\HJb15UrUN+O!T2G&\.Xu-3"V*1pmX3'\Eif"&,\!`3klG@Xq%ad^\lK^9]eQSq-a$RaEMM&JioliqB7*]/JOEhD$1^F.@NWP!?HkE72m45`2ciHqabnJ@!H7dkr8hgLOQZ@AIfrffU*SoP!Zgfq#*ll\[FH5a$f?h^Q=6+`PN/A(r"GYTlU>\l$A]6M*_5GMW_A[%dR0\32k$!2t0HOsEG(D]AUHY&0u@6hF0@cohjS4/IeJ"T?cXT~> +endstream +endobj +357 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 356 0 R +/Annots 358 0 R +>> +endobj +358 0 obj +[ +359 0 R +] +endobj +359 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 240.6 536.4 309.77 526.4 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 341 0 R +/H /I +>> +endobj +360 0 obj +<< /Length 1385 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gatm<95iiK&AJ$C#^],EF;aVF`tl@aD1M#I5S;o=*YaO@eWiR)O)0HCs1KY>1auUkP@EJYLRK(jkOHgD&*qdE@iF8:Ku&)E$A89a#9j"aJ>36*j,foN#O>mhqsF?qHkCL,jLM5WJr`d]9ALXXH]\&/n40_^`=n80JeG5>G?qUn$g@rr,bJU#>ZCUFmH2]Cpr?<&E7?C2#YJ$*aYkZm`eq,.@>X0K&Qe>J.V">i<@U4]HB]%f2LReA(/[J/,Bg)FWnlHZpj@.iLZT4+=L'YR5@!L'Y2U-MmH8tI%alka(e'sU3US!b3HcH&"rjtZT!Dkp%h`kM__<@PD;CK6:3J[`YN)`cHM#%;fug=/lYbJ")NDM5(Ke^"MT3!?1K<_Q1@o%H<-!.@E/1N44knPGI\-,ncDW:G0/O/3PEl.c0W&h#6@j?Ej)6I4$*gOME*du_EH;E4CKmbRDmNb8><&RTQ/""9#T71R12W:*SU-k$>q7FPH*#;7:h($Eu$K&]Sd'ir[86Mq8JRPH&%tbmY2tU7D+)7FhU]'$q!qh@A]"!15M*Q_Zr)5f2]/rk%h2QJgBfG;AQS]t(BB%bIEpLRKD$fRZQocQB2^42U6\npn5aeRVfp6h&^MEHBYc:Flnj46H2qW>CRPG,P-3iUZX9S%q!=E;5in4->g+AnqpOnkq'd.a*-nO*ucQIDaGfMVkE2G8.iYnbFEQZfmfqNU1>7+RqkRqu]*SR(R>.)LS<.Djs,l_R(F'ZJOb%M[NG:,gMS+ej)8pU/7+c(#^AGZNk+_(d44,-G]>^Y.Falud=i4P!b3aP%]4frKurZjn\u/1o`)Wd0uo)uX&gZ\)"EN8GWo8PIE^g]-5\%M1U#fRcmKTLh;l`o]4#a"k9O,)>9u:H=)&g:dqJhgR!I0Ycg0+gl7[d@,OSh@P@M?;@9&4n\,'t7Yb#Zg,Yh/CO-,eUk?M3&85j-N^ +endstream +endobj +361 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 360 0 R +>> +endobj +362 0 obj +<< /Length 2241 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gat%%997gc&AIV:0RTi9lYn.JcOF'N8Xgn-H7370LH&CT/_X5MM67n+H].mt%RnekD989a(XA-6qD^hPj`cWPq[_r0pQ.=:XDbbnk/O$.@`Fp&1`(j_T5>G$&NJ&<:lQ]/m-!.u``5mn,sT>KcJoebPeJdp]@%6%L\s$Koc3r*sM(EW:S`r#"B\TW;X6%&./C,9JFHIq(&^=hEcuEtSmW]AhNQ+d+Z^7c,#h&TIr&MQhZf@aUq.c\@[h.:Ugb/MH]3g?-%'m!c#-&luIu[jGgqA#m$U?L;D2,-MI/Y``%(^2!!L2=EG-_^H60D[+T!6YmqOW0X)TfHUBp5B0!UpMP87bk)-H)rghPSKW/6hpf"a=ku1Wm^0@oC$lYhd_05!&"km#7Zi2.VYQh6"fE6]/0LuRa<3]Adr7'HoDi)(f1BbPl#o-p\%Q4.rH*/GPt3$@-;/,t9#L9F%7q*UiWZKgO#5&BTZ-Z"=R>*Ydlf^5fbG!fja2dNWcC93$1TQ&--s/ScV8gO2QX=.ND$_#*TLq);mA]ZgPf.CF%E5HS'G-`'YKu$[_->5gt98CTg>,R<[\I>1&1C-.NcV@--Kt6(i&(^OfH_\7:@uopKfQrY3d25XKh(5i:1'XnqkoJWEs-O!-tu+1U,3$f)e_\UKF)kb,[B9a&!;#gfE?27+bHka:frGp's$FW0XW3V5RR%M(ref'PnPH17?F1\f.&a*>29M$jU<<>]H*:]i+8itcIHAg&kd2$4<6u,?I&8OhQ2Yl5?J^X&SB%q`).Z,M5-[kFbdg!>o;4Dp:d&(m7Mqr,,12\?;]XA-m2=sTuQ?YM?81)TLXY\.>frqrsn$\iY9Arod(37V$:Db<@`2BlT0\M>L#4(Cd#(J,_Ca?e\*2hl<&gFZaQnd$P*atZ'M`6?#Kuhk!q9icu[&3eLPpp@-FQgMfhoFL[gcVfsgSlG:["FLeKMG/l^g]0P5Ao_Ofqf*1\2'S@d[]?+eb%-Y(\L,*%p@[KehY;a@>TG\i_9*=71WU&(nh3A+(J#Gh72k20kjEgf"\-2S)nEL4>!%OV2=o,#/:1FtcB;T\S0ST/7QM>ESSV5Sm>=gbgFLANg,h4CT2d'1&"nrbaJ'&$S*atKh/cRjB7]m@Kh,X`]6Uth"4[Xa/=RroMtNm8_<6#.e'aGo.T1Hag$a:&CDoE<5ksgG$q@GG3t-W!Ks[7;4K#**Gm=hO`Y;<[P=(ZC,s[kPYsou2*4jBo-U+3Mb%3[iQ`aK?Q#b1[dsN$QR"M+ccUfh.Ibs5+fuj5/M9J=Sdj![*jRO)L/tCAEYeIF'1U$[$Z2KjDO5u[`%?N&5.,n2RNlk;Bl9@8-0f;<'Il5uqA$sraW.Fk0)P0M@`GfW$G`-a`E+SpVK;FRfA:N;B.CJJ::XdlQ3rEP[[%\H^SM3$^;.r_RSo?JhneQic$nKM4iCZ^J^P\2>-H?Ir\SXC:,\=,/@S:o,>EMKk`NU-\KLNVdZt8GbYD8e`Q)^NTR?+,Is-T(eY15/\IfZlhG0!n\@DX]5UkW;";3igoVV\ncO)()ZB-LWhKs[)"]]6tgm4Ji!0ANbC8mI$^dWNh3=.p<&C=UjobL=L^m@[,Gl(N+rH#`Gbr)96n3ek@4KSDsT4W)^cZG-/5k2!ne1?/M63/!P'o$upsKmhVj[+]VD_hJUcZV%Cc-Q\Mg7!s,Yb&M5Sr +endstream +endobj +363 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 362 0 R +/Annots 364 0 R +>> +endobj +364 0 obj +[ +365 0 R +] +endobj +365 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 154.932 559.821 209.372 549.821 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 334 0 R +/H /I +>> +endobj +366 0 obj +<< /Length 1713 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GasaqhiHeE&:Vr4iSHqkea66Rr);?ukaekSqbX8,UcpV`+:^u)Crg%3ZdGcPHa1D;*PA@HX(+=L__Bt%%/I85rV0"u6m2hgc!_=ka&Nh,nm<)!YQqKGJg_!bFn#,D[p2#u:GD#tXD)1bU19.fj.f&s'=#E:0I!CJ(Ksg>_Hk?#gsQg:e^_N`8q<1UG!6JMJ(K())<7iaGE+V61gNfqIE\iO(]@83"In:Z5RJ0dBe[sd!dUMlETgNX;U2)+1`Y>]DV&_%T^BsFdg-YAdeu(r&]aj/7"uUolWe8X'pnHpp?>6F9RgNto]&Sd]1ACb-=R7RB'W&\[5dSInM,EZJfVT92e7oN%*(7YX1,%n#]UOWje5VhommJcO5jVZ%Gf!f?V-o?TZ-UtX;Q56E*kBhsZ!,bkF/pmS4Y(sG6K'Lb3MVC@%rL//CeXc,s.hNBKo#43=3Ei79O=9ak0K])DX"e/O2WsNRX'`[Jek,qFtBq_s&c#uWaERinA]=Ye@T5ftnq)=/'EIKY-$-I.m*ka\1gh-O&V&7-Z(e4+F);#o^KC!3-mT!`3_q^8\^`\M2FaH)ea')ZkB?jTFCNKZUk[qQ(Sq.hfHd0+-]B`E;@^F9Vg7S"p?Q(H(gl?TCmB'?&h^gN:\tD,a'Kr=?))HT36o]6`fWh6i33Gp@fKHaaOnpWtd\iD^6SG=qNOkLs2&ecD@;;Qg7Q6GC0/VK\=`or0b;3ZMqGWKk+ZnSKjtBFYdfaZf*4)V.!(]QMhmc&hsMg6\gP/fCEk_k],&YF\ce`)N'#%P].*1cL%"3S`R!%W4P?*.b:BA(Qi.LhTpOHb/EM3n3o`gG:"LMg7BW2=Q.'m7E5%1J=8!(n_="$;O#9Csg;$Ij'ojM47#iL["mC=s3c'3016^U9MlT8k]GQ%@""K=+e;s]c-FB=IHgm?:NX86s/rMh*STL?M2qJdoRJcpkZ+0/0V_oH_C_F2\nc0mk9[mX3$n94T:YWs*/oWETV7f@*9JQNkH\[D&OAJAbb~> +endstream +endobj +367 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 366 0 R +>> +endobj +368 0 obj +<< /Length 1653 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gat=,>ApT$&:Vs/5j+t8PrRQ%c;>[0W`,m^:91Cqp7^`'=hG+ThuoNS<;""M^kN_/G*>CX,(G7.4s#dZoCh2;a2mdUjuV8qL$K^24NE.?cggq)R(,?O&nbE1IpHY>=3cdIp#O:kQ-B?'0#X%H\$Q#N`2/[-8Q=]S+J$XNpi5"0*UhlRCbstP?5h(\n#k;'21rkfm'/B)>a=+7$ET3B_9-CqIYZ+[PSnBOIu?u"e"eSr0:9MJq@^PEk=."[,GX^#e((2S\s/18kMKZ\"T2]d):%\Zs%VF(hp1Xp)(F-gUZ8)TuV&!m&n+!aX@Y.uFk/@:-9FSod[l!,F-(ckkVb_Q)Us+n$d5G"u_#CLKr>so^9;dFAaG+[AmE"keb?!kCA@]D(7B$h_PniO+6YY5]].Q3<=YrTIM4JJRG=hP[V2$LXPOZF&AXgG)[_GuR@?@dSB4_,?CAS?90P-2P?PfnV/a*;s]g$9ums7C.[bB!>os=k[>a!C\ZHE0_<:u#h+`LW5?p4A9"L]B0T`:Xs3P[hCBc>7-;rFnd]9>NZ@lJA*!5%ATBMZc-A,DOIiOGt_K8LGL0"Cn8#Z>5>7bHDlNiX.YD1Sg2Adf)Ym7%CK"I^i/BZ&ZLQ5GT?V[:%qW"=Y6o2BlXMC42\rF)qCS^AEYt."KqS#!L4,'BS&f@3P?4I3pNFdLCNZp,=k%1J3DO$^aOG4&sbV,QLZkeR!_/oF*Qo?Z(%M_Z=FE9N::ItZ]cK8iXU)'.W%LLh*0JeiKI'kdo2ob(O???J'*;5E0]Ag9f8tV2)N+dBo,9#Mri>[?9dI+fE*Ua^CfU?;Bb>Zs##uPeY7X^=DY3SiD*('G\lQ!f:d[Gt()RPV1g\<[s#fa=EEpTtGD`?fL$QndKW`H0sbZ=5g^47Qqp1uKO2dmc_%lA6D9.%li4Y]aI*$>4kYgVr@CA;-YkCuImgF#3bsZRs8)Y(?n'`t)Wb5o`3SSWb/*?N3b0=D3Ec.8'FI_]rLp~> +endstream +endobj +369 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 368 0 R +>> +endobj +370 0 obj +<< /Length 2748 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau0E969.'&\e-DW-#:M,@gLtfZ@R1.]I6%WH\qXX0!((5n[XaeFI%-Z^(P3OPO;'3L&Vs.]!NeO$KIIBKYq)o?HG_LC;]GcJj+nj"0m_m_U\CGN!ig)7uJZj2LV0n]P47o)$CYQ\6Q&*62:=20+n]V_RpU1$NaUA"o:0$$2DN@m\a&14ELks4&Ne%a%sD^!IR0&<'U@bGNm/(`.WWc8S.#`:Iu[):+hpM)h&^m`0@KG?Sk(Ct0;\4t8:!IkKJ+dUe`DqR_[s*FjIP2EiXL\p;(WPAiSNd-[9Ogs?_>+-";\Wj:G&3XoS+6pl2"Cg*Ag&%Wlqf+qMabMp5)7B)*ld4BXpoJZ=[Y4's9mmSu%7-KWb`DViW8lB'3G2rF9AiC'FQolldao,/Y(d0E\E>)1ph]=L*[UqY"3.9DT!klV"#7&27;r;8RUP\`B8Ojf5NeEdp875OB:f;Re=Aj6#BW/7o`+rK<_4+9h!uHf21S:\tnHVZ]=i+24)=C'm&&U-Z@LKH`<48r:e[Q.7l#+coPa=En.+WL-dMB,\gbXM?m]&@VF]-.*dZ*\XE47e*CbY_Gm?$pT%oDG@_YG-=7F.iU]A0KfDdpJ/d*Eh5KA$PBgK+-iKKSN)*HAWGPk-^2N$b>F":_<\':j2A<&ldthDGW`S4V:t->Rb/0=_F=c`]pY3N2Q:TJ=?VL-=Rh(dJ%)/fmCNY?/LF.e?khBbY2:Q>KY+`Y-.Y$_Ytk_KFmHr6.B8aZ[,UdRgR%?kcAj&e5.9D52>r5k&c3_IcIhHY7^7b4S"$;9D!p"ChoLu8A>l#\KE:j@a%pd%^[I<4bs?Mg_=n!Cg@H)3\uec.f_.foUbqsreCt6$S=pk<@s+jFH/fK=S4LtstYtpPI3^c^SpP!bHl)J>L0?Y.u(Y5Zj5]\HpMZ]mrR$id#i!oai"SeZAG&=?`f.NYJ,W5=rkZ0rOXbbG"lqV.%f0JSXcZtVU\ni5fFUd'EJ;.c)Q:s$O_L8))of7qrmYE^$mU]YCEeLE^c59jZ^3D#]-&1SOc7C:-HcJ!hKK[T9;BAB$sR;G.5_iWPD-N!S3!I6&5Z%<@92Iejhae+$4&6;+R\YC]m;3Gqn1_VFs4juT7pCm!2up_,Dje&PdVnc:W21ZaH!Z@+,ef'6R>6-1(B!=+^qg97PW\p6@D-gPP%Urh;$TQ/rF.Z&UG425\MCZ;jlrFX.!tBDCiH]S,Lqt"$G@gJ#]1^HY/^'FG""_]Xf?b7_"XMPAU66:F"g:;ka*iJ8,r5&kSRIW)SR?uoUVq]sF(Ui6j[cgu-r+u5d]$@QuhF!9rH]Yn7l&@'V]#.=oVOE1h_[tl``R.dae93f%'Vom6:#>^4^"*I'3S@D;(ID[iQOjDL=YiVqQ8(=$3&RHB=UQ#HHXHeUomM"5*FJJ6:`)>+!eYW?%&iR_*_+1UKgUBYgb#^SGU[/!jK(mjD^`F%,;T/'d77C/=.W4EG`k*AXXA.'o/oh[p8YEfXXWeO6M-IbYNueAMcq'UqhKr4`Jn#0NVeE/(7G-1T'_(Y^4'`^%ga(,bFBAEX8Y3\g/RK\c(qk!RL9qL@^UdNenm8k'5\T;Z[*HE*)FFlL=YH>0FJA@BRYj5Wo+esTr[0iFQ]:t@0ku^6UF9&SB1I"YnSd;O1LdnG9NLr#Y9mN%,J#-J\LYG&oJuGe+,Cl!-*$k_aq!<[+D*e6BV^7^C84X`P>g`Y9!@8`8<&qf_8c^Je(WN`7!YE98d_*2^K\Q`kJ6H9`U-J2O^@]qDlkb&1+?KQ6Fo\o+!460AL8?W"[@>+pXi(a5aXJ77WfFZPn2uUKAgnpO1&u9XRXO2Y2INK+,(Z)=)7bpCsj5\6`eqs=3V"p=K2P6<$Fg53/J+IRYaDfBYgtHK2[Q)nBk'laUKu_5Bb?E?2YlD[IT#r&-LOXK"mWg>HgQ#uJC9bDHgW^8TZaWdb:./hLaK\l"p5d+(?ANW)ls%#%o92Uon7Uo&rfqW]mQU\Y"=W&L8CDtf@UJQ0~> +endstream +endobj +371 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 370 0 R +>> +endobj +372 0 obj +<< /Length 1105 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatUs9lJ`N&;KZO$B%Q0BF""89q"_N7VZk,\CFU@^]IPr:&Q5=`]9As@laI@%ZDg0[p[Rd\R\f4[c3V#@Q?[qH\SelZX-(4;'N;o-uC,dhV2',4a2N1-",O`6'qf3I,LDU*DKMfa3OVqO+r,0uc(3q6^k]AY*YRb5^u0n//AQGHdT2aso"nK<_I$[e)8)J6:8nXEbu02A(MEV7F\7-9_U_WopRnn1:Acft"gR-CHHs'Xi!a8n4u>`Wqf%=eeGjp':[&d`UQ1ra#G#em%6bT#A/giP[$J-7H)6kBNNL=YW[&\#`nZlQhaTQs_3jZeG`GbPnh$Xi-\o3]-W:[E<-S-;jaj"7l4@@6H\'sapiWa"Z0m^ZLKA[gA/q5PUp^=X`Gg9$t.0o=8>"BBtDb>,OcCNWAeF,%9C?P1eA$$'!q1'NB":gSJ[Sn\Vc]rV!enFirg.r1l$6f+Cl[X6%'HuXMa`0E2hJC3,X-?eiA"6-h5/sF#ZL8#8bm3!Se(g@4so/+^98[dnjR;EUM`quj#Wo9rkA,/4CCfA6Ffn/O;BD/+7]MoKlrJZXA:TUb$%lBD\Bke"-.\a?mcPf1aQ6G&^2*qTnDZb1!Jt,,Qigp57#7<jF/oD:9rU=Tj?rk6kAUN&g#lHcgUNu_^O6K1!'>;pSiln5db:r:J\278O+\h.ZZ<=&4PBQ@lAna-lUfa!-%19sB3R7to:5K0G:$ +endstream +endobj +373 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 372 0 R +>> +endobj +374 0 obj +<< /Length 2006 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatU49lK&M&A@7.#e;2]*(Jhk2X$hB[-757_S@3NH_>5u<\$gL8`$OGoY6aPOIDk0`RujP(n@9V1E8Tm)=%1clJ^@9$[n=0M74t;HuF3DGeX(Z?5>/>RU2UBirS+U,tdn_$20)L':*8(Y))\/F2,G^oOaPpH"Y)r1t:nY:gF(Mc#_C+clcG@*qZH#Z35O:/hBa`J5APh3V'n[\?*JhJXuKC!euu&oU4lG5_B:ia"JPJLDZ$>8hM9S9Fdt-*0mRe_c_$4"!UW3B7A5q5qMH.d%#^Ck.e0qs!h=NoA4.gd>,o_Yn@:=P6^^qJjB7-&d!DJ`P-U5?U[W3ei6tp:":i<\edG^?IuLC"IIAKZfYA-6.PHG7>rhlm/0Db)]!Ka\J>(BXh1"17jr'hT_'KO.`j2VZ/MTU:`FMFjuPEa0gbQWcXcSp@3eCRCD,o6/ru4M;HJ%9(pigR0,2>JE`'Z@>c;@qDA/SabWr^>!9bR'c2GN$!ZmX`gum*\5fWcO$=G/:M\=:@,DN>agdt.ZT4"X8c@F7qnO^+h_)MS>EX4.6#\/>KRfi-&NSMf8W]STAlOAl0_T0[!/t_Cn')?JZl=d4f)OD4;+0=Gj-QN-WYC"s-cdL<[LcZ&o\lK9\p#iK,n1`m*AB,UlqBfIMiFCp"7]4]DMuH>W<-6+%Wj9lroYLsR#G_l$-5,9:'goSgQ)9eO'R4<19bBk/P>\A*Z"qGIEglU&d,d/7=Z>PDSi75L$pm`SI5a]`4jNibG>PK415D=,sX3VG&ME_NXYAbT^r3.4Joh#tP.<%X,1Z@hl!]O;^+_ZN9"R\:-81lr$;JRV?`J\ON/(RZG,Eu(/GXg7[hOS[*!r$F*%3=C58Y_Hl;'"O)B=:D!#&uE%<1LeE@9j<;iW#7u(>nkFkEbr/OW.)h[[(MSO..PeoA'76=?VKn7kiM.G6/15k0/VlM:r)%2e\Rek_Q-Bb"of<4"c(/dXeI.9f1m%mQfIk2MginL^f2l4):?%?iQ,g9'#l%e88o_WC$LDNn0W?tY9g&f[KQJHH0DC9[g*5.MT:"WlP`)NL\H!$nL-g(].d40s?NlDn^M[2g)1MO*?t1)7RTD_^B<%@=GO1[HeJJ"HY5DgM+H(BD`q$k)[DFGsrj[9h)WM.1--ITMB!JGlR3SG`f=M^R$+GODB$m[Q,C("GmQ`>S`hO(sr +endstream +endobj +375 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 374 0 R +>> +endobj +376 0 obj +<< /Length 1972 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatlQgMYb(oK?Pim%k#M0Y1VSAjEu:5R6piW3JP16U4;OX]?'7Ofk/_rV%=iU.E\=K4.,tJEM_NpT%XS05f\/$f=>.@_'&=(>B4HiPD/$n,n58nc37k@bE=3\@fH>qPrYX9E*EQ\li;[#l[0BT2AAa=C$cuX2U]hjf^p+>ep4nN!3?Q1(=B*-q$oV.D?r_fj\:8G'Xs#_H;Eb3=:pHP)iuELH"BNJ/-OGXH+t#)dK"_`HTrWM*;V1,O]Q!is.e%`?82WXYm(.Y@CAoHP(5H(HI[)/rfCn"cHu%i+!H0mF1W+]!04ZDtp/Pd#J$1_&Hr8G@&,UcX3f^.@%e6o(&H/@AjTca)Z1DE_G)*^El2j-06-Ao_V00r0?=6mmB2c*`HSQ)@H60W[jUGPE2P/!m5ON+'b/NJnYrWhOr>;6TES[%9!I[!)u.LcW^+!<).pEDI5rE'8b(-ht"'_02F8=ZD.3j3=dU*LSZ9ZeNr2trcsmHn:iVD5kIr"%eYmX?;nX=8mi14-;qp*H7S7@ejXk.&6S-O#NY-qAQ',d;Uq#W&6_SCblD4;?*`#jHHI"S]AP]J`A=eDY2DHCr\0#]^VkF&#)B+Insa01^/K=jIq?K$oUO/U?fhfg_oE>j1CJd2#p*#qhig"^qfO)7^+qk^6Xo*ZTkFalpmb#*sdXJa*4n$cPD-5P!DagZZe@&I#3]Y-O-6)%4QJ1X]V>qj#!LuWYoaOC(Mlg%/PGGQg2@2H71W8$L'RRN/q'LI[mrec`#I*h&XAZAX<"Lo4b-UU6f(]GMHd\#JObUoe?%+R8$4Uo$JL+4T(2aM4[MnKAN5=g9`/o`7f$J<*r0f(?O[f"#!/W\SmmLa?`H3W!F/;Qr*\c0o?.cA*]`ZGmG71D,[nHrr%JG@9$O+(HYNBRA6e,1K;D:FEt\u-SN]4$(cD\]PL&td=A6l-,])CF`"Q.@CaFQkpG.VEZ68&B)@KM:M-!X]'l%=YS=-A;mf(BS1Rno2U&&?%tq;;mRmdKh`#s#ZM_es2@J5hN#C1*3N8XsOZGo8\m@9ud=1'q4ct$p.E\u +endstream +endobj +377 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 376 0 R +>> +endobj +378 0 obj +<< /Length 1121 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb!ks9lJN8&A@P9LjIcI`JqY'!>GhO4`EblM$&YcDrTR^c,P\%ZpffNNh(E1-V^%M7XI]Rj#?!W1XFngX2X1C)Sco;_.pRfKA?S5U&Mk.,%HR!"C`4L%`,VcZ!B$9]?U3M4STu!5!)P,ZtGUIOO2;E.#U^"QY5%Lm&>=>*$kldC$3dbRZCsu(dQlsgq:=0)YB"pE-Y/"diUt#3d&&Z/*)!F$;k;?AgOKn?9r2pTjpGintpO0q8ET"#B_l$Gl+TfS;f1+7$;:n3_'SdosCf>@eq`Q2I8dpNQT3>,K;:S8sR1aPRXIdko/tfc_Oem1+M-sjV2"?F!V.'Z_Ke)n"]bs>$Fj]2dm@SBZ86=%'HJ;De.R`B+DmI9#]bHoR3L)hJ!7>HN-Q(dkFem^.gD1Eh7tZ-q-b3uf(]G-hDTb@U$n1O2^3^aY'I(C:Z:#.gKG3--$ki=d[ikr)SZ?!oQ;7Rh%7sG\;X$T"c6FY9gT4&1Z-pIod9s,>ojGKe2d@ikc/o!h,(RO-oZ]Mp=4&EKVnocI`9Bp:MI6K`r*l3@Lk7=Pd4#,G5]B2jDuaBu&mm*[3/%Ca`Jo\UlV5XSXKl8$23TCfY3s4[c^d>Wms-daD+0`]#OaPE?Tc<.K^&kQbq%nN9YcS2&"\',^?GEO$K]7LH-(8(GqdpC)=JGk`MP>2>&#mVCU:p:4')1kI!OBSUo27WVAEmFKTZIG'%nc%?;Mp^RAN7LGEn8X98Y's['NaNX,sZ0q:h5f=4tF"BH&3$gcQnQTG!gJpR\V0L*i3TAfUpH.g9.cd;KA*'l5TOd;0Q=2C`PI\?n3SYna5)BbLgn%%UABihRD;WA_FOl_o+K]R,;Baq7E]H^ho++2+#s(8=qj>Jb6)(akg\lC4FN#LEtJb*TAr +endstream +endobj +379 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 378 0 R +>> +endobj +380 0 obj +<< /Length 921 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau0Ba_oie&A@rkGU_Q-/^7R#dGtk33V6@f\%48,MmA%ME@<;js1ZulMmfI^-kHXq3#)2N]bti[:WqGNR0/Bj!m>hC^i"l-EXrAAe<9nW&-lU2JY2NZIk+iIF9auC?@SIEhWqh`<'MqC-99`8Nc_;'/r/&UKsrfq75h["W_KMP*V]f(hlf!HM0k8f[q2ai,L^gCGh`snc&Jsu[7ZD*W@'Pp4Y-7U>BBFqi`c!\T1dl7,V+!UGOcNqiAi2c;?_XQDPb?Q^9pO0B0`*oAaMV2\?#F`5-F>!BGBA)''[:;UdcR;,/d]q[>L^M%R0%43Kb`k(OGNH@<'X`ftpF_i=\G2a5o9M.u..U3R',k7bc)HANsc#8U4Y_-Im-+@=UbD[]DBNC:S]_J./A^&L)r4T>/_$jMb?\8=<3Y$Rm?q43Hlj8gc'n!'sXBfY,[Glje#n"rdI-b:+$P"W&)QrrD0DfjJ8"uc/k6T51qJ_,W0m1-^&gQN$V:SBP8NCi-+VPfD8(*Ghj1V#pA]u(NWKJ3'N,"a5[;[kb@hI5Ia"CLhTGO&X'LON?0Ga/:T_p.A3I7hFQ8\_?qk`4^t:MH14#f=]n9AkmD`k@^m-_d(qK<"FHD==(_RW--I70Y9E/h(.c46@Vh^fL7sr\8$(iDH[r)OU#>TQ*oEUO7KNS~> +endstream +endobj +381 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 380 0 R +>> +endobj +382 0 obj +<< /Length 1367 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gatm;995i-&AI=/E9rn=*rH'a9j^AY3Qu?:gbu4!'27Ck0H"i@HiEs^0\?pB4ekm(C!%mVj.j>/q9*[IFgq1O$%p\2iWR1VLdM5W&=PgSbuZ3CD"H9@Mm%q'&6_6LmKlC@T=uTPCfGR\V]UTS!s=?UZd8OPj'YpkIm8UI_*>d(]4[RWVHY!Ldt9))2'oTLi$f#&/J%\/CF;80]B<(a7/n7PRrqLcKf,,_%Z-N01YMW5(HGdDuaBu=9DOk,Apd`$6i#&+"p-UkJJ&r5jP.Z(*\\;@F0V"?H`@:C>:#e\pZXJjWs782*^/2lf;h5Wg%9pUTE8B1$<]H7&aqGePUQAhQKZ+9airLA1;J21.F1km&H(LQHB6ZB"p9%aHKRcIqb##??jGIHB1D(IpP>VN+6b`ffT>7UhEc8d_9>ush9GP$Mg@_W8k:F'G//BT[0aM8GNq$S+l8r_=2usFXj%\AL[[p\Z[?J-;e8WQPZ;8a"KGp.@c+ZV?R#@VO"MiE*kI8Juk]?!.gLi^rldG57PNLo7JPjUmIge3=IqTZ\(qdr?IXi"4&D^gIpOfa4PmTlMCmqjkJ7%N*OS^iW%Hb%ZNU?O_nY30f6N#.&.k42hFM3)*iVACjs&6@UGp,"&ATP_Qn*Z0"/F`mAsgU_@+7\,IL$lZbZJWBc-ai6/12#1bga[D91+;B2[KVL+o,f4Bg8%Z^q57RX6!2mL25oR=0:`Dd2S;^[s,r0h=gk(c9jDr5372[J#Ool#qr`VtMIlH-/aZoM@Sn^3H*,#4Z^WV@a'1GA.-'Xcp- +endstream +endobj +383 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 382 0 R +>> +endobj +384 0 obj +<< /Length 1290 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau0C95iQE&AJ$CBRo8sq\L<>RgRIL]p#?W-PFO)^+lXjt9%,WEN[a_*5]YCI'.i;sUY?MdcbWE4AQ/1ojFU1S%=9?I>Ld^[WiD&NXj_g-As/^pippnCp0X1]dKIrCFq$CeHGrlm5Z&5NmN0b,1.\@cG<]3W:<\!jlChb/HTH&OBGuj5g;`FCP>>1$&NdYa%6Q$bIfr>]U@pZ."\hiCPJ+m190Rp;m+3AW#\04['t4etUM-sP`mBHZcmo+2l6MTLg0L%4hBA7A?l@gFoioo.g?$eP3eUQ>]q>]?KZuN=+[Y4r;[>M"!6QP,A2D7`0,`/&H"X^1%\OBu=m*rb?&RjnA+k'B30*Hk`J[(QL1UQ#W&1Si\5^%74k33XLYtk+UT>NqaBF19s-3&"-o?@Ib2MZ4^7dTinY-&'b,hEf2?0R#m,>HbpArN7Ybb[qDPM=.@M3e?W`=2BXtn!O35^00D3SXOd.=O@IK-Neo:4!%:Q.s/A.6*GJ2i%,YkUt*.4.YW#![TWF(mBYC'EDqB03>?\8T0I!5K,e98F^96l_ZdB +endstream +endobj +385 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 384 0 R +>> +endobj +386 0 obj +<< /Length 1578 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gasaqhf%7-&:X@\+lpTKcmkc=CHrrl-3HA<*JSleR>69M+?+(QP(;20pCUW?U\X?Z/P7O^pJ%eD:/Oj3jeiPGB6>5o!B5n>\*O-)?@PZA=GHT,WPgl">CK#6"Ejbn,\_I]SJ:.3@M3Ol@YCl)TCEmlckSj$5,M8t"p2^CHtrJZ&:7FsMP<5(@Z+c$rWCpNH:C=mH^i5EM)'ILe?S>]]H6Kgf&5;oEKo!,T77O\,ItjR9Io2!K2Pt('CFm;CkS]i2s!4=l;2Yq`@eli!R,n`2p3j,,co"nt6+7AT'e#PU8'I$m(;m5ik7hOusnc!=J`7WDORRWQdSWj?nX>SjHnjFHnb2d_fu*FK@]KCS\n5Pl_bug_AS/]eQ5RTu@]-7>"ErJoafA";ela5Vb;MF.A[6`3uS0X5WaLFLPEpZk"D88oP('DOLkr[KFLeJ)_D`jnN.uLXC(\r8.$Rqt_f;[d'>[%=L=&`2]N+LIJ&[C2Z]fXZY[qD?Qa5o:;Q,s(ZdRFA.\D:Xp\\Q<)'`.l1t!OSMb;2Y26"<^>R_2n\)UP,_mu@:es'M0[iRA\%^73s@a>@81JRjcijb]@H9onfUgPRkFDCu+oAjLR_P,YSN,C$!N_cDZ9]g:"_=hc@\a?%C`:_nk^Q89b7!Jlg^0],$H+fKu>2&3Ie(RJZ,?;mEmJLt']M>(WJ,D'cCs!5Xk`Yl?o")*,;bZp&]_tL+kNGB+k6Mj]]'0o+F%5Hbp+09KM/DHk/cM,gd&H?B[S(")`^FYR.L;`U;n;;'BLtt/;*PNC:`>.h_p3#]9[GdAqoJd$XlHP;m,2+`\-n]lu&L4`Oc)_k*4gDa[K'O5qX.-E4@uI8$J;+P-mmpXlZ]m)]5#_Xd,\tq3$"$9i5FLgADZ`hjIP3J"`WV^eJ!3(I%HuBjH)i5%F8/&q9\56=F7uD-#9M14-5Z[Mt_%'tFbX>WRtAmX!2)a#._[asaQZ!;Z2R[?Cj?[?X7rSO=s!Q`hhu8gIr&8Wq$_S/c9CYLSNA,!o(JLW^s$`CL3+OTO7A10;E6#G*qN4j**!F'12:VAbg:2:+f-h8o2Q@AX"^uiKVa5HLXH'CST-%nrXqpIQM^\`/0a4ITq2%:DTE-\+[`L^e2@Kf4Mf4Qb0j-ho1g9\G(94^,gYf61'lYp(b(RCS^t20X<_r~> +endstream +endobj +387 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 386 0 R +>> +endobj +388 0 obj +<< /Length 811 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb!#[bDr&G']&?q<`Y(,\pf5#2H"0B]1VEN>rW^cM+V0qR&T6:CQ]AN&mgbQW^m^+T6p#ef,U9&&q#$;!$d:bOp23Y!Xt1h@=Upt1D0h"%[$qh\MQaD(",2rT2mK3$RCcK)`H=Y0#e?<>NG6FRhb]j_YVs6]I5_[X2@D@mpY1XO87R-k0Iq<8@>3XL%YQ]mr[@SHX)sdAQo;IG/pnO=E7^!?QXd##e.ka[ArmAYQbeNLal4-M6;M/TS6k.d_T[1"E&QTd(h4&#T65NVrqTRAcYqTu=6XY@_f*?#99GT'*TkugiK46!l;O60_ISuWU&??OZWn;82U3*HaE]o*Ukmj')rLl=%$AT-cpMqp!?#ap1V.b;h?jOocJ!iBknsd:+VJX:.^S\Qau3,@\Za@"kJMK/+4+]46F`oIMDh1?(3(p@$Sl"[\p2U,&*RNRo^nP[U=c%CqW1l0'Glrj&dUt.*HGs2@=)2E5Sck]PHtn6%E+eKrCRC]B$ITHQoNm'cE]I!_KBAaSciu0c_Y,Tc7fY-4'j.YV%lOR+2L!XoXWd788)YI'78_Ob@J>fjA&uV&6TYcN)(%g%tGA"F)WU6Uq_=A6^7~> +endstream +endobj +389 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 388 0 R +>> +endobj +390 0 obj +<< /Length 1377 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau`T99Yi)&AJ$CE:hXT#RJZ7R]WB#pU7KDNH:2T@C2.C#K4jIhlf9H[68bBWfg!!7GXmah^>D84eMG;O'a(aN;Y0N]m[9p]Qt6;Jc6%jPk]fr#+87XjR#b"_tIHf0N$_Q?bQEqg+`9<5]>%^UIe"&7?[*:4H5=0#BAB;mO"^b/YaS77LcP/7sBPeZ_X@(M&EB1-LEY4OH69u(*]&X-:VM,^[d&=A*.I#DAVGg;g3oLfgVA;JbndpGR\>3jSUg4c6'M(U0T*Zpk0d%-U*MOs/h[MV_bO0KKJZs6j:eV31lt2\Pl@QF6'l_N+Bqt)<5a5VWU`8L=CqBK57%-WTCgflW.:hPk(7*c:SWe2J*"$r)hWR&?TCU2+mB.@Q_V6q%'N;3)jL0)EbJidl".7u/WUJo>pc162<.k9:AVQe>4>CE20T)>]iHn)jI,.n%dJ_$c(rrSN=.22K#eQl*G5j6=B'%49V\l,uh?%POJ]/o)1]%g0;Yrq8XW]$!+2rZm6Q8-W1Hm02=m/>Bc5YN(87O0M&Q#$#p1Y(5Vn@.>#jO?.ff\cAnaOdA>na!;\Ji<3Cj2MFTjsY">C-%biQ1#;[j0Br#g9c$=P\l$MP!c4n^k#N3"=m&-q),O4?4SMWMUNbq`W_sq);c`V!UFQ'BSeuO4&q5alW-:5pf4\lB)do^trWg>P(GoGt,JF,'Yn^Gm/pN`>H2XGqB4Uh`+tO(gR&<$m\@!k8EKm#-(Z?8G:WAM_OcunN^*jn5*39<-eC;%h9'O*qM$SI$3^l,W3.!l&ik=DNaj1R_'@T]bQXn7)X;:j:7-<8Sg3kDr3HS5&L0nd^d9QFj^)a`5]f&/+[S&jjsa@Hp^5BG[2a>b]DK!ZrbO^=4`SU>%6]UpZ`Jl\sHbU>,!EY&2G)P5&IWkH9M!`JDfRXq8/T4j!qH'<@JfqUB06=jihg&8-?J;`k!Vb7A3`I2BUq?HV8R"2(l3R^`/eOf<+IS6p#k0\a!%h9r4].2qCTbiR9N>9U]n4W=`/eH+L<-;.k"",d6?a!4_fYXDVc?N;I`PHp)FPjBPrc#>pUHb%[p@EJq*%2'*WrlC0Tg`,.m6U/>J,ml+V)M.LPc4G[O9&RM:kPaPTq=fdj.1Z$@*Y7R%Y8Zo1bs.[nqh\"0l;gZ'H=uAqA+di1Jl>Nj["eAVM/EN9qN$5IpegG!ep/5p:]CO)I9f5~> +endstream +endobj +391 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 390 0 R +>> +endobj +392 0 obj +<< /Length 1268 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb!;d;3.J1&:Vs/5khQeBog.9!o2P$FHtRh8pNKnPnORGQe7f_a_lTVD'34J+gKNhfFhO"aUqf!MJns4R;.D1@`tfn8W[GkRGBPSqg9+E+AHm"+)"8kVldJ=@RbDtuo@FVY*OA5D*#Wc-)>SMF$Oa@AO)U+=OgpB6WqIEcQSV:<&Cgg7(1ALWab`S0W31KKeeEhT9L]Z2<67NrbAHC6djc%S;a(;u.W="aBWeu?-RYM5kSk4%J1#:mC,a^JRBFib`:RR$Z$K?.`0bLK%SC#DM67cV/3HB`+gS>*2/634DYk.!qZ?cK0sILBTfm/1#d)%#t$;R7s<@DY9SBK[Wcj+*2^(6\))C%nAs`Ih.bmm;FY_25.sABUUCE$$gT9__UR<=E?bgC6q][YS.6mi2Yt7s)pr-Cn$JZ,g:t4sGado?ERc4g_b1>S[)O@rouG@;abkVLYVX\=RBcT:+u3d\7XQ!a;Q?Fe[))<>[>fXM3!$LE((%E:gQG\8P/0V,9d8iT;JUP6Sns`KD2/e\BoI.mJ3!n@ +endstream +endobj +393 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 392 0 R +>> +endobj +394 0 obj +<< /Length 1480 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb"/'9on$e&A@sB#e@lCG?'(F;HrdTU&i\H!SpemJsIi=)d-,gg"SrXs'AU!1a?.,$Rq6;&R`Ko%Ylj$DhaM6-*&-Fa-Q&DNg8ZUa#^A.bE;g0bOq*?kBOGIZ]^OFYcbNMde,uI:DFK60gD#Xa)nYm5$H&MdS8B+)7nJ?m_D9)Z0o;-]!^,6'*Wpm6!e@Q__=1(%6l"=LB%Yr9>c"29F):)aHTcKO;,YAkUKK^oO'%BYI^eAU(c63cXh$^OFm^UCkfXTWLd!c@="4-?"X-;.Ol'^T%j^V&k&I`A9R-?-B=nIk$Jl"oHtBMeR]Bb?(Td(".CTq[kB/YI;9E?))ZB-4S0(kQOS(A(!fc$ukSq2B#l$Qu_f``5;[HBTYK'D55Q"j:F/F[JQP,\uN*D/t5XQ0"kc]k:Jf!MUnXY;cCj";^mW6\%naBqN27s6f3^[[1YA=O%`$I&K!/$pOnfj1Ha6Fnd0>/\Rb3$7?-h4SULjKk>[60LheYfh-F#LTsbd6t>4oRS(IhajhWS<5!W(Sm`0ck/*Ad.5gOJc#TYoa)kP3K-]3fD@i8S`Y8fC4lFm*9e0)]u/5S_>+kU^'RY2Hc_`B%76:\K9fe%+-e.HA.iTtdc(!Imqci:A=[@mH(3kAApPE6*`kEj5Z=",)+iD#?c#UpZiEL2-qs)mh5[)b9T%"#-Z@1V;lSiib0+93<9[Y]OFT'iSZ20K:A"@p@\,ZO_Eecj@:(BLE$mD#kn#9g"BZ>'N/B\D7]MqtjR$mND4O6rgX8goj5mJL7Abi,F-RoF"haU);kd%5&()hJ+?UGJUcZ'rt)1quX"PO?__&bX12k/s%-2:\MS/USkP_VhbreTCGP0HSS5X%&?%b'?&4Gs`l0!0(ek-EkH\ZA_gYNBL%b`0GO/i&J@c10uklQ%Rh$^`D2O^jr(qdh,\TqnZJ/"ht,6]T?bFJ^`7G%RKD8kSNp#9sQ=P0&eoFSN]Q2dGW53niSoZpfoCPPs;NZC+meB1jBY21Ig +endstream +endobj +395 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 394 0 R +>> +endobj +396 0 obj +<< /Length 1415 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb"/';3.J1&:Vs/5kf:e\t`XU5Td1EV=pT\V7`(nEeoph9C*?dp@dCq`.f.3#h`.WIAp7N0k6:-o6C2X3+'+pms^.b_"W4hHW^*hE>:IIrX56H[)sX:?B@/$Zh(e51"B6t?9=cNglAoZ5+`^@!i]W6<\[H*:aq78:M<#]raLTPf$5A_p(r]8ld6-'CsntHU1CAU/rmK3YC"03c7neO[kN>A('XM$mM;Y#RgRF9*^26?$cT,nrS[eL@J5]E8c&GMj"0F\m't\(ER!>5h_P0jh=RQ_NaOI:0F0hi_7.:T&V]4Bj=YkTTXJ'<4`r5(p)p_]AldC]GpUd1.+"Au6O"1;\]S2HG:!,cPdEn>AVDIf>#CjDq:ZduSW.%t`*Sb+K2AK[YErac`4a!@c60*`&L,1(umB/=I&/(FKs'V"5kplQL02!L!dO4W29GD%m=<]6Kpg37_5-ab\7%K'"7H\Qe]qmHH/ZF<\FrS-b,X-7/&dN.FP)\VWo>7H/nqer+R"haS;R:7>-s;Q!D-q.SS,.CcJ"niPi847KB#D0YBC^t/]p-1fl?:_THn7q!cWrBnkb6rnP(0oenIY=4l#/\"BAY+T+e>>e"PcMEW7"[Zf-j\_m[9ViX:gu1*m(R@9P%9r1^3TC@0H'#3l?XbPNrT,pjjBA0e.h!!sP;Q*fr!47^`SUBFKkqXFt<4BVtM`Po='2Om+>o`tds`&X\7MQWh-7Z8QJRu.@!n4P3-l.E>**GHIRjiehbW`EuKV44QAH3f[gPDSf>mn".eK(Gie)2Wr,Rok-'%IWDrMeoip,=1>b,T3t<3Wo#6%J=M]EI[BqQA%:$](8IU[''QjHk41>84'Pn+,A7@m=V&Nm,%eAVHrAmI%l10+TThmpaXW:G%rE)o@5qo +endstream +endobj +397 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 396 0 R +>> +endobj +398 0 obj +<< /Length 1022 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau`S>Aoub'RnB3Yjt2XeADK"fOLapdbZl*m@dLC$RT;Y^l3!WIm4SP5,=kqe[-c_ilel\h`3lDDSsGKcN,4J[S`DECp[IZAEsalKXQf.J7?Alpk8&dfU`#3?LeT,:"bM0aknW7UHN4(autcfLo%HTNqWH1Yd9SqQ,"].9(&0TqlEb-P=ufITRe)Hd(7b=Hu^\LM(HlD#4tAQC3&UX]tf-lk]\li[@-a_2(2gL*XE%d+X*#g$'q#JFN&*U;R5\XhGTW*42keFSJBe>U(_2r_$IC?B(g+h0C\+.%3]m>R5/aGMg!fb?kZ(6lDrd>j\%T!Z6T"?DdHS%95$+qA)W,&a'UWWE$(n4+qU=fcnmIY0LqL94P4TT@[m(h45$V\AYaO"?7[%+O^b2N#)AV4%IfqFH?GAnj9D:F5!Oblj-2\85B-OS*091b^*?q4hW'aL^[AcTJt7K8TG6'*h>Q(OO5<.Pp4!31L_ie0/-#nMh;LWmBssQ-.7$k@S:U$nZL2B)=+aiXZ+/=Mm*XnCSJQR;5,-TU;#iDfDU'igZOL'=)FdaD+#VXEO.-Bn[6q<_0$]Dfc/s]M`R,+\:HhrZ/F%nQa\[SW.8]s&/_XXo$1CAk=V@lXetBok7`F3_bJJHo(WDH,0#hkgGQC1_G=1%0,4rk>q=Fr*?6Uh@W'9,V\h@&meH?f>a:-:Muh9h31p?.&'8WC,ld67rlCq)1ZYC.M:/HoX;W0;OBeHZ;lnk,]/C0:kb_s#=d^hhMF22.qp4CN(31V6eb%2=n&#$5^Ih^GlJMbgjYtX1THg-BSuj?$ol3L-pc]l1Ytd[%oqaQO.(k3A7fMhhq"8oW@8gC#?2;iB<"QhRMki97HrbBL"i~> +endstream +endobj +399 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 398 0 R +>> +endobj +400 0 obj +<< /Length 2720 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gasar93:/`'&N41Z3/D!^4+)DYQBQI_jk>K%I)_SmcgM!$IQ4j]-TO\k1>[\P$B;C)IT?/ZRhC,/a%.soUk$9=VuLD75S4cNr7SZ;)%V7IkXM_c_&Gu95blLZdise^QY]MWuEZeB-4uIop,u83M2j1Sr9drCS'^`HueJ,n#_\7(T4V>cW5P\D]#2[ek#oromK&lSLC'eU+0G(k:2[)bsuiae[%n*Q&Bo8X%T.VPSKr&fm"alN$d%s+YqW*HKIE%Eacf,Vj9JcQi0rccNVY8oN2uoGLDM4d%.IDnjp#WKSjWiS4hD:'&N#IT/9U%4fXod&60Z1O!E;^Z=S_KQo006XAOec?h0/`W`pbV;_KlKRk[HB5foHq^+tiNBR$Ml)%:)aH%qP@k[PHaADsWDeY;8ufeB',"85&>qHQSX=LJqjOb?T:`3(`fNgEIQM^dJ;!M5lc/Vd!tB0B^SKigtp&"^tI#,Sr\>a#,c/&b$E1D_Ot\AVcZK/[Z#a4P&C'0H@T)B:?3j03FNfk;icMHBKgc.)/,lF(*FB\f19ULWrYRSpQe^HpD`MtAX98A4iW\cC*sL+kOZOLZd\j.'`cPAF&)YU/Hm-X1C:M1F&c3$A?_IUF;I^mNM(-58ehd@1gG8q"gJ2_.9NHDf9b/B=Lm@ji<>aGlV9;@/pH!`1eq9nkEZe6qf_IbR[+b=(NQYJF$Pn,\E%5@Oij]4ColoKk4.O3lL>QC,7E"!lqBA>Tan*]42f^Q4kL361O(n13KguOn3*+NaB73o:5YGp=qorK1%eYtS:%l$Eu78"P./8AbddTp$@u?Sce%_,SP8UhHKMk0pr)7I(8d\EWhRkj[j!HRC`+Z7);TX6hA#(cqSpWX'q(G1XhEMZejC"C*cqaRA5Pf^8.&FpPZS`^i&"AT@Z)6m'M;3:#9JcK,a3B?aJ](1U3;)YL-)OJ[JE[./Z3Q/)l8.!fpQPH8upK&uMMg"^sF5^M:S7(\G&8:B\U@ooH)Ol(+s5N60$\W!3l:J;;=K>o3^:QorVCe]7QQ_[rO&>NrXLV,O+^9G`mf_eEG67UT(_\f``6.]*kSp@]cjV0h0o7^ir8N.O6`uNG99%U?`iba+&C4\QSWKfh3odu;"nKm6,=P%Xap4b(dob475YXaB%M=,FMM2m('Ih%T2\@+/[TK-R?<+n$JpI,_#"M5=:(X'pj=p8A2ld&%LQaS!nNB.#jd\eJm!3,"RT^^UO]qpT/0R`!J$<7TOf(n_E6XUXu"*%`Hh9f6Zq)gd$i8l>8jh@XC;-'TQbN7CP$WP`W(!/\\r+^9tkEm75V!2PA+Pdn63qr^c9a#\o7[kkkX(h)lj\epi==)[p]lA"uTq=NM",Y2Y1b((FCfPP+F28_/qM$Y7kE"r'-BD\S@[U*8!Y+]XT$YP;B9Nr:T#Vh8:d271OtFYuM+=73B*X86u2.U1Z3VpcnQN(NbA7on87IFT1@\q-4A>"9>\7fkjDP&%1$;Ork\6DK'!V(F+Q4LSrCM&bW8/-60<8a"])D78Q:]p(m0;(nD0,]]&Bb)1;_CpPja(@]ZP+Jihuo64HKU*/sRd"qJ-'Np^m2t'c&FYO3iQP`7@8QUt0cN?Hc?%u3NfCUI:bZ>>UFhpa[lf$iUF^W!$%p(\K#d^YI9P7Y"3(MEPR?.t!*8=^'U)\@BMMQHRnEKOO2ck4<>p#9>?dqkJ5rqLN5k0$3K+Y_E\NN;F4rR.$TJ$4jKA]l@h`Uhnfb"@.Wu8P;TSdq14k/^==tX1=Mt*)B^4^_P]@cP3%$UOJfl[:sjQ^Ru$:?K=-a)Sm/Vh5,&-0(qjoO[!8#@Id5t^a7OV#l1\ma"fa1W3^6Oq?1f8!/np_X<'p+eN1E:qC-#\qJ(bE?kAbbYPXq^!0-VI33KSu!ZPd#?[ZD*e)P?AW$6*GnJP8U:gtc/2:5E%g%Ab_e=A`1)eWZd&#%r$fuO>X+c5-@1HHEeMQ8ei'$#V_seIo0&DdS"aB:gHH>t]#pj&h)\`&D[QdAMDSg6]Xeq"OAg"%=8h;t6O_rm9LUh''m&#[X@Jf(0O;,4\Gkm`oArK`2bQ!%)4PFGTQdXIIgP*;:H`m7-s1f=_=\3c7g@YPc2R&+^ZFG\VGVG@CFVmI,VW#]%a)%NFgc)'`,d$PIl<8<_>:SleYR[9S`cZ\.=6W2ja0-K<@J1f`5pkM?1qXDY5qqZTcdZ;)kIR_#:ZGPMSqN0.Mkan-&?KLbeE_H#kIUAo`%bBui!>eC_4tH?Jj#IbF'&P3Tb6RDo-7q[b:RCif75k]/PP301adEh69Mj9PXm>0m15)CN&V^YJ0%iW~> +endstream +endobj +401 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 400 0 R +>> +endobj +402 0 obj +<< /Length 2090 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatU4997gc&AIV:&:,b;`@`b-XTgp6RpBRZUhI&/06%PBD;$<\99((M,Xq`[7j]MlAbluQ^2QQ:Da)I*Ak9\(>`A,9l4&&_$iM@INVOluF+M]XN,sN_35)4p0o^Z/2dm'Xne-'8>EcUBEf-GE,809/Vm"E"Y$qU12*jB3!0*nYK=mf]fIZ`9M9-R$hLV9G&9l]lM=M$uOXHFYNp>AUXf`/M+_7jb<(5_WOjM^p@bA2GesX1?d<#VWIU04Y'K(#'"OimBMKXdVq(5fZTn6CFa#7Df-%Q/WtfL$7(g>mG#9=4^+asKK?s*g`pWY!\"$GCmV00g7nVAb?A4Giq7"N1gBka@qa+LA/Jpkah%WJi-PokDBdm9cN0,gb\H7jETV3Sk:rbIT+tl2DCFOLT^kb%og#ekA=i%2CC[ZR[WQ@K=,^uO_?9PrLJ,ermmH\%uQ&"`_qhkc6^C/n!S,]@PI^k='&ih4/lqV8\\GIH:A$@A>(=ItVW'Ai]+bNb>=[%Mp(8(C/kUt<0#4PbqR$sp9Hmf(!A8A],P\=MhM$tCun3@b&hAJ"QA@o+$dSo/oZoBT,/aTnTnum3j5Ls4](CK,,9'+7GI\o/,H]P8^S#FaGN=Pg\P:tlAYha`WE9O-3qjg&[Fd2rrWl,lhpDb(3Hm,GLs27tfC-NZs>hWWTKGSXXVOo.n5ng3FdLNg(j(1^OZ3f4VBC!F:ZfKEkipF^C#r8>bj]jB0Za3g]S6TIT"D(2la+OWEqJN[FI/5G=8@pRPtgNtNC5\:)3`K6[T$"`mAR7P]?V?_,A^aQEWF)VWB'Tr@!*+6(d4U#+&:8IqX?$l8l*![/h!q-C1h#9[NrPq4Ps8RJYIcU+2qI`d9qS?OB"#j(Br1dSGQaZq05g:\n6)9YB"*']n56~> +endstream +endobj +403 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 402 0 R +>> +endobj +404 0 obj +<< /Length 1485 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau0D9lo&I&A@C2E,q+'0hQi_X#\]JBBi5JNFSfO30U$]87kL,1-s'&IsmXd7=Z"9a_c)DJAps2LI^]o=0p$AD"9RU^%DLA+8K5r',5[NBV'Ws._3$WgeP"G_q$)l@h]*K%E4-*/P4I%3QG#$mjuMSLIkthq5gp=J\t=Ge(V';O$FZ`pb))U@kq7;HOp%"fY`BLq[sT4hJD5#T#/2Lmu'.%eSlT(-qLRti?3]A$TQOaW>0C!"7EuPLLA4I<'h$8NeuS=,4s72,sBCSE?@O<3c!Whl&a4F@>GNWpshum8L-A5@D)VXNP?+C+l62@;ZiG$Jbsec?X1DD4R4(,j2P(2-$J6JeI/LS<<@,*P[c>:s"NZAQSj],&FmP8mF_RL\DgHWW_\")tkq?dsU(i;@;"!bOFR`G=*?ld1B&7Wn(>6.Adm6G=c4tUYc!mc%btM#arc"V;@^Y3l_5?9T?DdNQKn`;Jo^fMW%sjHU6NYC=h!(5<>,?u:;J[?9G5#*OA]YAuZ=*i@rh7^P7]dYGFk,"ZnQJ_*`hOKg05[tK@)pr7-WKCmucEjNE97t'ThTXa,]`@^]chRdtQ)E*O0uBV?IBe2lp-fWq_E#E?1K\%)KVHi16HM1'<4b^iQe>O$n!%mF!Z"7]qCW*hQLCII7RNF8f'Eq)G.5]%@`cCLiVi9&OP/Nk4BN:Qn@>LVN\F&\AS"l>LUW!Z5)WST2RPBM0%)j(iLH#90fI8TYY6#JKgXM?R9KCRGIn@LSC=-N#Z\rd)CnZ;>Xrd!MKt[1GN=@BaSDR_'F^@6AER4$gD8dL=!KM/u?`g'(,/b;g$rt:2,7J54VDu_[%3/We'`=a/XZgkBXL:Z29N<.Z55o/\=^+`b&)H`l9(KfEkPFp,0D`i(06I[ZU73%ni?TG*X66T>EqT]-DnD8_97NsGn8hh3;sY*T@bh=f56$g"WgV"=fF,LMGNdZlXS\([I/&r*o0Eap,W[kU0$[n\E`KT(+FcHKkFd890oQ0IXI +endstream +endobj +405 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 404 0 R +>> +endobj +406 0 obj +<< /Length 2190 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatmpN1OGbE%j%)fBISXhI$5.mqMb\RpGXce%%F50Ne\ODK\8Z)rR`&r?hXKeH+tF>ED::,Wf>fZm[&umEeF2?RspqOi59(h=cC&k7CDHZHblOXDsm'/\YV6Vhj3kPBB/)O#[\q=58KGEAcM.g;]kjdMf!2r960QGoWn52F9LIX,Z0f=K^fgD7I92G&n_4?8c27b%KHMaqd+r7d0PhH&f&JU(k\>ggK@;LDeL\9h>d1^@s-@"f3&P]ZOM32jhkQ5I%5J0O+FIt5&G#*jc#gWec0L^n2O])-F;#?@ES37nmNI"FA!L%@IWu>!Ca0#b#dVjf^;o[E!l:C6!A(;^bB>.]F3Y.dZ0RnA$-):@m++$-@[f`LU+c3,CW9n9a+tV`>G/ASE>NnfRf"a;9>hM\2SgPL#?Je)>R9!QiI`7](5PInaWP[[gq6Q=cWnmWF[\^J=EUYA/8_G?Su[aJ15e$sh,2*!-DDk3l6qrFDN57Pd;'&BfulL,LU9K9g"?FV9fdM$$Qks)9O7)Cn10a!9#C\`u]D\&RipZX3<+Q[jd'rcl/I[XT[BW',46]%##;/UM#A98*%*`pV/7+NY^Qb$#usJ=IM,K(?G_)F."I\kf=*rcI5K)6.&VD1kLZgd=RE0S&B[d##@Jh$"Qbr*Y`/[.8;/M=KMEQ6;P?=R?W9lafW`dN\aFq_Tdt?T!Bgnf26FM4.O3f>X%gVG(db.f3^;W3HJMr+XjfWe^[$:"$,"OJ[p'4uS56$_cjT"-O`]<>D=SPHK&h8_(EC((tc"\2-T6`1IMGNLd6V(,,6U?FPhJiBKoc<@L-=K1:"AN(S06aNmhCY$>jI]W1;BZ7]U$1`Epg:]Mr69i,./d)Cd;5nd1")Bi]kjXgPeMj%`(blJG!Y_o&?QGe-8%UgJ_s$Q_eCfT>)=juo,#OG"9:0J;nE_i/f?a+C*0@KnkYL1OL`31T?NZM;s8(>g#I$;#RK43;`n9umHe9uuO:RZ$`B$Nf#3>cM>.l[Hr'Yqp?kcs<;-Ln?+>TOmmAN1]1n@")s>kQC#A=9Tt>7I=$KrPu4T$MG)N]nqm*+`<&k*8^R,q8WS>e(q>0Q51CS6Y]J.O/1Hr^@t(\DSfMDB<+_Mi8Q5oo8sUoc:.=)$Hl&:05o,]LQ!+r',st?UJ:L`lT[M!lVW=-@1s6/O"\;\Bb/OqYWOdr/6CLB;?Tg5L37SbRQ'M+]pbW5lJ)Cpq*E4'l1"?ObdEboQmUqc=8uG#FBT^C`gkH<8>"9MVV$iN^r6,/?3qATY[H!N)!aYuZ_fOSC[^j7uC0/om8$qNnjO7ba?9q$IIGH"o"eS.+0gBaa.RA-$QkQ+LQ?RjRF-(SKXcn3uZ@&RAh@ifp&A`;fE`Vs!`TKqA1;/*1H.k1N=a'0rH!sRbK6j%^(l-eIHr@?=@T[S:2n5_J*E`*JNq(oco6A69IYWKp*Q:R))82Is]AO0)n`p8=NN8+R[Q9Ic3t>Odi`?%*Y._fAnJi^a[n"KDM[2&/Bq3BC_q9k(N[e1XT~> +endstream +endobj +407 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 406 0 R +>> +endobj +408 0 obj +<< /Length 1658 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gat%$>Ar7S'Roe[d*lAA%P![<]80l%FE%C[>B7+/n&LLkDK2b#*QXI9u[$Mub(tGBW#gR\!L;-,RUI,q8Z-`+XgRq@j.A:`o@b7YCMA-!\3@(U4fd:`BFeOTfgU,lXSq.O/CmBBDpe/R$qYe>)mB$n(^Z7Mh'/B!"3*QAE2S^K^X).^_jfg;X@0*I:iW-YaCW;8kr=Teh;?nE$#+?dqJ,mF,_R56A+"IBj)=5%rb)hR3$>4Y^2]'7KqNDegq;[OF?Z$SHe=XfTCPjJ-9F682GO)pRYBLZ_N^A(/W5nfn/V4d]k#nR&`eA_fNfujeT=ntETt(dUZ0>T;[XIFTa5f-LfC3+Tp,BRS=MKjHl"`f\I^"[/Qe`h:L;?KO12@pX6,p=k&EMP-&4n(;0+J*lID`+LV0Lhf235,M(\([ISC<8jlYg/!TKX/NMoE/Z58iZ$oBF_GhX)1'I,$T$r\`$>*tmghMn0%ZFZRjH\N"+C#@0LaD*C\RFRWQaP/AoCc;cG+B/kSWf(9+O]tuq^2Zl3J3S39c*#Dh-i:CjEicLqdn*b.:"#>172CPlh._6@bD+[3q5@2-ZQ.]9gD:YEo!0iodr%d%[S@$.NKI78Du's$FDs>^>W7BYOHFuM2H=@WP3NOR,t`_=7UtADE/+cj8pUL4#t%:bc\_-g;/!u)c**c9VabQDpi+f-P),d,oGAF\b<9YEA`Cp;T$R2)k!7q7YqCCHm/Fmje,NA\Yr^$q98Z2\3agN>$S+(kGO^O;rM5J_!X6/88Mi$aGYK2E!LA*k@\7/8%'R@[a*%9/F#q\k1;=jliuGcUR/]"02QWSPMG=n<@o;)VpHnr]9\a@-VDK[PE?4Rn?1LjXFT!^oDX&FH[+fdM0GtQP8Ie>ma~> +endstream +endobj +409 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 408 0 R +>> +endobj +410 0 obj +<< /Length 1991 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gat=,hf%7-&:Vr4+VYdYX=5[bVqnEbD32+GdKE.smU7.D>,Gf'ZKP1adU<+Q8O.Ccjfq6,_f_B4YM.."kgPd-TU[fU7@#260<@8X_-_a6LG!V=?28i9rrN[!7tZm'4=)HM8V9SiWYngXn[-9anDXA$o!-)D%:`A*g?"#j8^!:d-BY,XT]aIc["2\J$BMXt.8$)Ms4P;7QZ<^*iWle?)2[e@uk@nZtdceai^M5IG8/#$t'Ob&IL[\)*Ks2M*Hg6r?WFV7KJ=8Q!K4G(SPLF6O<-u^7F0G9p=*7dpu/s"\_8;_rPn4a.9B$&&t=&]*R_37p)Rq]`rl1`"][Q@\6epTtXBW-ZfuZlfqLK",Zf&tUR1ofQ[cf0poV$Fk9Gr-6`cl4LN'\u'_ZiIk:q#COrHk=NEhsQ^OOAgOc4E!3&0#Ll_SK3=)J#M8dk(bm6)X=\aJJZ((P+j%YLQN[H/^!k$(XkHnRfDo\L3B$#HF96UnqAe*h4a2SW@t-Y=R8XCV5AMq+2&57D6Vo`G+8U\?C^*MCIHo-(,ZXBg5F"Y9\+8Pf@*b_3Zb*a/o"r[`b=?@Tq9?/9NZaZMOLS2IGAO9f<]Bs?S4"DO*FIm7I`V5OQUenc)WCBZ($V/#sI>gJejl>mlMsK8:cPJnIVM\ea34oq<\/3haph&?@=Ytc=]X3e7W1^q,_CrcjB!BCdadSX.u/Z&$u6k-ORg]2&'*NOV4^>k@/'VQ`X>lI>ITNMurPIl&42aoO8?A:?\H +endstream +endobj +411 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 410 0 R +>> +endobj +412 0 obj +<< /Length 1416 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GasapgMZ%0&:O:S#lEZs%O9guWI7ZBV<^$^)I(mhW/H22kmLOX*(ii3./ND/,g2o"0eNM1,W2)PS2l?E?cRf"gVA@mE1M52E1QY%3j/=3%YC9UA1dol3q:MkF1@RkZrkS.TCP=.et;(@5?p0t3UtG8*\TdoVp1fG.JQun$n;?jjs(E?NS/pHiki7ug^;-l5(8C,lauBXIeO6QL^clYInkY;ObWsHk7LQ"#db]]Vpk,G$R10'V$8+r-3)_[#\2crk7JjGHu)+@3/aXuL2gl-"Yg:M!NO@t>k3L$EOc3;GSV))#XHmklfRVap,KHZO89";^jrg`ZFlE25$XB;U=a)Br5+>Q1'/jfO3f,e@hs`]0HP_#5/p/#n4ho?]\'r5Y)^#1]!_QZ"@>@m?6Bq\i7\>);`'?.@=1;I^df(];^?.@$H\3"g6"Z.n9L^(QNCn88k$q\m`1MNZ="mX"eI00MOF?89nXN-nL7l/77.mqJP@s[GN!@M_<%ZrVIC;IcZ;/ll2c!5/qeHLgZ1,]bi3S^A)STI*[%=d[V9(;FCDrR#kELi?6hoV1RgpaO2>8$dB*Sh$#*LcofWS#;Y9h:\oq=&O&P5*1`mBSP$F3/V8fQQNEWnrta.pVZp^+I:;d^fb>o.)X="6>R!In^;n""4Q"J-SPL@>Qb^b2aPreKMbVtfaetP?Lb2kZC%To-@o4"JW+>%f`6?_s:V<("GbFM034Z0cVr6t;=<0s=$0iH-!'FgWVL#(fm/9n/c'tt(+::K[gM5:L]\aN4=n,`#6*t.C@4]._h*04MegW_?2q_Co.C*hB`Hn!iFllo#h6;<7NX,_+6H'skTYg&(gos&i72+`rSRg&/H)gefLS&2iO5oI]])2'!QI4+HiV%83'9DT0g-[f&AEk5a?Gd6(r-u1Jq+f-eH?5&[:"c6(s7F_@+[opb6=cKq7G[,U.bj`Z<"WD\ZE<@l/,IkR7[MK5fi8HRa3CT.4$N.Ko>hr_L3=?tdOI)VED8OSmMr)I.+9b)A>idm1m]0;93:.sV';PQHU[iUZr@R0I8Fk]i[[!hHduNQ[Pr]\oES,Q7^m'[I)iiI*kX);2nj=P/:?2*X:59Di'RR>")F27_7>3;U9=^61i)83Qq@AkrPp$~> +endstream +endobj +413 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 412 0 R +>> +endobj +414 0 obj +<< /Length 1006 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GauHKa_oie&A@rkFGtd(,t1Z=EbYRj9p$J:/%mc.6-$?!2m)[904E8QJa$0OSih`&u>7Ku5Ejo&16:&-UALf+Vg#'4aB(6O#:RV#sGB*5dhrmq7))2(hR#W6ZLfUDZucU^s"=JC/-K;jJjU&S`?M+0nCrKo@WO9jFrb"XQlu#a#(X2aDmUbKebP);'R0#Tu50)&r[_T60'Xi7<2HZ!bea!,6JO&uZB6[h&<1^+=U*X>:\4cmZU'B_tl8#m9RH2Nco,Z^@.Sj"n=L5nB!gk1]#o\nDu[W1-0EC0nh=E`(0.RLe&.je.G6hqfUgUQrgab)&m9pX408['RjA[is#B:9hjFF]`kS;%YuV&@W0-I0L?*)(O-4^ch5[S?OsQ$'^+.HOcsY97@Tp-B5)Nfp<0%?!+,['$j6@EuI?DK31N&_GaV\n>77j8l83f*-g9'PV9Y3qWf:e06M1j>BY`7EN!MqPNDFa"&qM*^dM6k6%De2-(lnQU>P:YF@M8j'h>F+=$!=FsA!?#WpJj02BMgK+q#.?=HG+'[G->j#44_?fdU@5A[[YB$_B_g +endstream +endobj +415 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 414 0 R +>> +endobj +416 0 obj +<< /Length 2487 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gasa2flH+2loe_7a/"nI&p;m`Vql35G'coP`bcg_:5>-KMiB96Fi:4`I:^KY%#Iu%`gn+j?_WTjj5<6D*7>0!mod=9okmqYDcoe=/ul*nAq/$jhh%DWhThgS8K)jF=PJ(M^[ITm`$E&0EthpIYa2FbG#.Fm*Z_L^DCHSN\Ok^2(0YVIq+iHLlH4-irNa!8G$(R8n*_RQajZQ6H%]1^2*FaI5CeYqu)=@)q")#rWf1aSWO$Vgg'q`:M=`K!?!*X%j)*GqEh"5D1ghPD1g;pQS4f@HaOU/,lARF\Z-jcV9jSMg=B]2EZdUW8cD<3\r^,D:NFWNAg@p$RY$'N00HYFgt1hbXIShT_X\ZmP^Q>,Z?c9Vs^HbREg(J&F7)5edcE,]"lh&1ja[-;VmG%:Ag41?][Au4&`aV@^c`5)EL3ZFtXXA4qs)"0.K)=_HZYt7G)T&AY=HfUk'1=H23A\]D(N>OlhL'KPEi$]^)c8[b`p;hb!F!n&FiV]!N[%E,7!]>klbEuh2FZ"4AORaMp9\O9Ne@`E,CW^[HLm58%CBFm"C$_9Vu^p"E.3V'Ft$V^=5lNJ>6*iuit0PiL3@,i,bd>RW8MqI7Or\iiqom3'HN%l2&sSUUs)="c&`?t\]JeYe0iQ#XuTsk$$)*E*^FoedDd5oCjTWq'JpEIE'[<;=%=j$]ti2HK0Tun`R%*[Y$"%t\CtCZ0mROg/Ft!q1<6J['%Pic%Y)MS$@tVR$HtJsIARb4,%B1.EX]dDfJ+d'eTNuMo=tOPe02-e]so_S)R5&h@kQRpY1$[oBGj!fRc6rQ`XdA*Y[YtG/OP?Lqc:1:]kFuG<5!,90)>s3+:Im(&J[mIjL@J_,SMdL&g;I[B$6c!J)pej.ZX4c#6aH3uaNiJc(uTAjoL%omj2p)f])M!Z&I.'H[ndMVJ,Jgu\1/$0jkC*=iNPDL!%pHlSb-7l7sE/jmp?s>:NZ1*bO*)CpIU5<+1!mt+?29FD_'RE_iUh/0fMO`oPZAe`j;_Ckg;f9[UAc$c#!1[0,ZJ-/'W_qh4P1.e@Fg6j(eF1BO?s!mAWLe;`FT9/%:^h8)h&ecrs^0jge.`_eCgi^_J#DguY^>+HC8Ii&Sq-`8C;uK0ti2PL<=;ZQJieBgg"eBX@l#_,\`7E.<^%GU!bA9]iphS>o)k3?9c_48&-d"`#S*"][VVIF\&"rb:faOFC-qa*pXnI*;mg]S1k'O@be#l*"B*Vln!cI$W&ATEK4`$r^ZQ;E%2A<`67UDd"s:p/F0LSNiu;&peLO`I_NY$&1c(`<`iLBno*;3"@QcT!R]5>>nAQa,04Im=F6h00:^$Xe_gM)D+KCZk5e!eb,g%%!0)JRamD\nE#bt'nH!BZ`qg8i,_>"hQ+?&\_qrrXd+\4(e8fmbnA*3V'\B.C]CPLL_gpOfU/[>YjZch:i@"0e<:IgAYRoJD--IqZMS0U&$al*7l3Aj2Uc(BrB>&+*]K[k>>+m=LQ?-8hR.3Wb>J:_2brA5pL@POorIGFCV~> +endstream +endobj +417 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 416 0 R +>> +endobj +418 0 obj +<< /Length 2168 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb!S-bAu>qnF!L(Z"nd1fE;%;X>an,f?qhFB[^A5://s%u'tM8k,24?NDb\j7kG.cCd3Pf$`U_YB%D74EU$l,SF]4P-<(.V1U.%Oe"5T1Gq!"qm&Bqqt-DmY^J@N2leUX@;!42oih4]PddA3Y0=G-rsM_H;Bmgk'biB`9AE%&ioEbOk)VQEpATFDhol@LqV?J"T#qr`;IOhgDQ!7-*'[^C(\g:b,W6M9^gI3".+7rgHZJCDOV_,37@T1^/J?Kc;4Aol4A\;ZZL!V9\g_D(bZm)Ka7TpI&r"$U.V#qt]##fRRHPs"[Rum,O']u)0jQotlXm:?@+fV>YAW(5@[r)2&PkmtkLle&SDX]:(!MOuKJM<&["7*$LFE2`%3JT(n(.@KcZ#=50c3X=%t"H'[?LAA:"uMtF0CLV%eHh,DqI3166JdPO.hIPDDJAcoposE<7ssJl>lc^_W^8SDUd9t:mOrcWUd\1f*6CfWQ8bR"/_V1IZCje<d-+L5ukY_nDdK)XCJf/eq'nuTX"(\>Ak+6^U7[S;1O@#[V[rRn24$c(,&6P>f&sU:dJlW0@P#@kI9!br,O1(kelfsM%3hkFRZ/E*DA&<_73$uO]G\(V;%pVt`AV_9nQb_G:cg6d]!$4gKJlD-CFI$bC>#b(d:eK/eHCuAE9Znqo[L3\la!WJ6m1WaB-"r)[_NU!)BG1OO8"STShj/e;+Q*-QML13O6_iKYMS)W0+q9)[j@N=)K/s')';5aW@lNHRBE>M;-?%H,dq2^g])jH@(_VbmNPL?B+t7e;Q[,C8=8_hqf#"2gGK"Hm)-UC--ga(Ao4J6^p.6+i8s4`mJV=G01cP?+F<\#6_/ak=PPp0,j2o>s`Xuuk-uBVnb4oU?!q/#iJYj'\CRUT/T@#(-=hdok?E(p>@9_M&jaD-Y1ZJh.;*Z+6S7Pu;>l0lAOB6b-)3=@u"6'NJDgfs#$k5h]9mD?J@l:'5(\\Xb%ll<6([$#KlKc.%W-U*_*ep(t/eZ3sQjG:i?s8n4MYH9Y&ITsk0g?e3MV.b#VLkLOG'*NIqU[5rVM78VlLg58LsX0#(DL9`l'%VQZFl1%3n3h6?jQdY'C?XR_u-;qR3[,Ic=Y%O<7_Ge<&Yp5Q$R.5PM85Ll3&@B`oE[S*rl*P7Fs@NI;.Qs-S?3p&FA/;_,o'Q@F]E-HC!)lJ3B$&KH]SH99XgqXe'Ja._X!BE?'q^2eD(jljF%RLfqB'cu:1e]L+pLp4RG$Y:^:eCEMBV0D%Lq(`\AH0:F):fT7osp5EoBsfO-E4e7n5=XM!gkscGC>++DI8IGG9M+Ba>"1)DkOcJks-KWBI;^AC7L.FSdY +endstream +endobj +419 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 418 0 R +>> +endobj +420 0 obj +<< /Length 758 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gatm99lo#B&A@sBkQZ-\@YXe?EI&d"lFX?&?(%\^6o^b!MkjEXmqg.L\"ms+O<:=\2KK&c.?YcPMrA6DqHf8!W*f,X9sqk^0ka;&9k*%j`5l0UjjD;[hb,fIFG1pD4pM\6r!4o;Xa=n'o"nTk-+2#Hk2X$3l)kt0rYZb-c!<;'R.le$uE/Ot"jCZJZ7P7UOEf"PdUK6_YCFE;UH@h/M(s[98J/d5s%%>##]6NWomM%fpNF*@`c'T&^@7Wb[anFAb4042=FE.3Nt9fkk+W$OL]4]T7HIpFnZ?FJ_VYRa3:Ak=+-ekdU$#"0=>5(n_hFp%`8\Nfk)g&:3CpS^=BckbmON"A3;?H +endstream +endobj +421 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 420 0 R +>> +endobj +422 0 obj +<< /Length 1063 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatU3>Ar4L(k(RKpb>=?lYE#,:M\Kq9J($_g6XNg))Vs3'']V,T0ML.S7$#DeX+:Gms`Ouk:.Uih(p1,n;YLX`Mh]-M^U2\b:>kPW,kj4p)dmrbb0cF9F,:SZ%mk3i%O&&UiHNO,)a^[)t\95R+B_4Y-s;K=)$4Sf41Ec]+[ht2%1.1KrcMHD_iIPDmE#"kAr8TRM1)m*p`[DQ:=ZU:b?5/DM*r6bX7JT?;tR?Q8e%qofgGHI"a\Dl:`>A$o[BCkD>AL,2QkQ3[ViLjKu5>]hYDM8>#1Nht!bbsg#S$T6R-umhk"`O&Pg@[oiL77a_oLAKHo\D]Wl[pb+f?!RU7M1Am>6,\>X.4+gRC0^rGgI1P\NNVUj5BWFHl\/pN)'e`aM)5&%qjMKJal8&7^r\[BMmiXh@:B#Uhap;-_/hkaU6.B[Ui;EP(qQ,T=a=;Rk4E"M58t]k`GIQ-VPK\Ir`Q3fUhCjeLT%2imHPq/8G.'*5%!,Em9L#g.oN)L>]lo),-YM0l,H>#+GUMs?X8k=j"N1%8m3Gu[Nsl5l("]NcSDQ"LXM +endstream +endobj +423 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 422 0 R +>> +endobj +424 0 obj +<< /Length 1558 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gat=,D/\G_&H88.@I9CuUt0=sYBunMCA+g.h.k]?qrMju85'q/'0A&smG>$2$j;B=o5^j11#n[7#+0[d>`X3'^.'.Lr4j8rH@bhG"(&eCJ-TJW9EOF1`#C;A^FiQs`_40>9gABc^V/$eg_U+I=Z^4M=2_(Xr*t!OGl-taq"F<+hn+bu`o1C%0qpf:R"d0u2CI8p7`(GLqO'#^2m<@!2to95g:ntN?'d\BX"Zo7!"k#87=ON-:kkAa<\lPgZ.ghSR$?&L-b3)^C;r]aa>9eI:V9dChoI#]G#g11eQYm7)qD;FGu>rp0QCs?jCD;U,lcYk\Qo%dcncd#5Q1LD*.8\6So/J\%5'XD5QO-p)Hbl<*q/N7ms`#nj2&rn2gcVE(u3pUDLCP')"h3H&W$sQZH/*>:lGK?Wei\#h=n'BQ6F?ELFCuIJ0pf(/d_d?;*,LpfXV'5qO6df/;1kfnmaOIqYIS#2T/`u;%3C+8@qSrjJE[-5'#0HfL9sqPJNR2f\JeQU$U3`:)dA4/X,/lXY*8C.e<=Rs0i*4W$WNO+/s?_CHs.gZ^K`N/3I=r,2qm5c\k0[jFtU-5*/"X3IDK8+,c:#tBk(%if)N=Wm#_9-6"fMPj2C.]TKg_(1j0]LSlgX8iW#i-W'1:L+9Vg4HF:j5N#I-M'[FWo:"Umfl/>DIMt63Z^Z1_9O!O;.'E2=d#Qaj?Tq=aKX864A\M;R>.US3YM=3WGEFFTjk-TqOqT!FM#*jb^Z6(m7L8dOJt)<[0gWnY=SEEj>VkG>2M/TSaRM08UQKaA3EC>FoqAaG'rFseGuQ=Fm]X@M'nHB==RLA2X!um.qG>u9nTr$16M7,glDe;%:DT7rTOpm\r2l&"q5n&r%O=o=C2B>Cb1M:=)lH?II4%GYLh#L"eU_a;f+hHbqEf%gA($@j4@6)G1_C.1a=D[!*Ncrmg\q:)\jG6>@4`T<\!FqEGJ_2";7/51@"0W",[R`30 +endstream +endobj +425 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 424 0 R +>> +endobj +426 0 obj +<< /Length 965 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gatn&?#Q2d(kqGM/%A8*io2W,gXRd]>,P,!'=sZURRl]hX9k]\FP;3B$oll_-AAga'G5ECpDhCeE%]&E`AMe2$X>&a$s[F*J;u-Ed"/,4oN_Tmmt;YCa)Du/d=r%#jW?t;:FH&aCS=rKf7hG4"(%W.Vft)A=Ht^B5-.b906oHr`h$Bk*6(Q$ib4m@B`=7:s*/BPNuTls)ieARoj^s]&$,!oYB6J!%qUHYrY[*'WHB]]LLILCbfYa-N)Qs=)HCW<[Znl-)V#A9cdTN'S&saV[_0.c[Cn\]5+Ykb.QbHHX$/rTT!p8Iq+e5`#\0M5CP]%D[\[S?P.#(X84Vq9>TuiXg1TE`1n]@U=rbHq;7>QFE:qip-R8[5l,#Er(dQLMnd\"J>m^C::2g2b6i8^RN,t-[D'tl>$3JqJFL17cPneJnD"&4m0r'9G%^>E^]dM[h,MKd@hO*ND1\!A-S:rnf:4COnD\Q#uJe!$L&6@X[fFMo=>eh9%Vu#jT3M#GL^kK`)aCo%i\Jpi7unfr,VB&6B#gC&E4=Dq_:+Z* +endstream +endobj +427 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 426 0 R +>> +endobj +428 0 obj +<< /Length 1342 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatU4h/h:0&:`lHn6oB8+,WqC$'H"k0hcD9=_T15QjftU9^GYs1Z?.f%S3`oS+1LZMWD,If+#,Q]9j.;\/cHpThcZpRXn-o?@Me37o`k57%>ZG2>Op)E270o_,99!%'FT0GKq4?S#$rUOsp9d5)UE3X14kRg4EO:HqMEoS(bdT&*rbdE`1YU.kUD"PEP7%&E:-AZuD4T"9:\@3<')SO=E+\p8u;%V;*Gb;UcNfk%Eh=:g]\$&\$&(>o-Dp4ZOF/Qk8EEE-AMh42Qa.)qOq:5ZUL$9eqd],nXO>WE!Fl*sN9g,^8SI\O/Ki\[>WXDp.=;qP,'P[&i1_lafEc+[>Cg#HlpMld&X;V?-:[+Om^`[h?L\-C%\0OkOTeMc#gbpR)iXLbPYEqYAg@]t1),14auro,+fLgc4kak[IHJ&U#5IG6,5+kXh*?#nO"e.gE;=>IkYpr6h1]pB=Xm;WPFUF04:-i;mE19Bo?Gld^o@'`,Nc1im4Cod/>79bSBmje=?5[Q*;>1XQ4Q0*l*N)og!4*4=>MY@f.B(M"O6VOiHA9YIg`gS,'4k6mDRS)Xe=)BhK'LI/>AO>F^0gcR0Z`*/G%3_ruGBej)NQ$2WhNifa?&d/L$:WLOKfb1lIRN5n,$Hlb]BJIl#O)>.3A(&lb/-ZT`FZc:IO!'03n>UfPcu)S(p:[%0!6JV<7pXJ7"qk1X#9b(V-hsXs?cbaf6'@s%)+)o*kuNlS+R9&_FmR9?4L,IV'W!B.h'c3o`AX>KLFf)19%.jk)LAn<\>d(*4,Bp*+)^MPlc6X3g!/Du?sF0RLQH[eSe(ITE(/J(Nffs2Bl[>rtoWN;]"@\kFr*tn"deQ#b4l,@cBVLpDTo+]QKfQ+#O>Hj!Rs/4[PLJuWGSOIZ\[Z5!!?!*s-+oXFN@2_%3@!X3V>?AfiBT.<#qt9;A_#8m>$t;UI.FsB>q$uS&,\kN?\6!,SoH6_UE;+U(lc,EPJj$5\kDj\6i/Xr)\!A/)B-Mhq>]E7q\tIn^_^6qo4lqL[tFLaFV6nilY\&/eEA`s83[-(UCU9~> +endstream +endobj +429 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 428 0 R +>> +endobj +430 0 obj +<< /Length 1388 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatU4>B?Pt'Roe[i6dra=9RX74uGFTBfb":3qd_=et!5SKjb&(&`=q`l$olJ!ZbbgPP.^@S=>PQF$AN*27m);?=oM.Rj$NA/].r`dl"@3>C=DG&^M6!>H!>r'ed@#"aPKhd;uR3GYq6@(4*R-T>#s_C:72`X)Dqd!u]1gKjAA<^9Ph?+7o'bYp:'Z[&TjuN*I6M)6;YF^51fpVN4pZ"&67&l-gH%qC'%241*@)J/NO=2BLSTkJ&VchsMR-m_8\rqiu0]=cLH!YeKtEpZ%k-ct88#duf+QFC0'0>9l.ge5E0nM(tbcGaO"OAJK'RJWF7JSrlVO.9K(_C/]\I^q+8*=61I--moa6<_7'=4,QAJ;3/C#Wpm5^D)hY''(fg;_1*!9EQr2c4?a\9+M9$$7<[I]i!frteb64QLO=+rV+1GGcRF[=cVj\Zs^jXi&,NY4hI?(s5tb)#c*R^rMYPQCN4p9Jt=1sM31XhM%[cfks1G36k:Oi?7t6B3#hMu04m42OrUak?<2aLllIb5=OC\1Fb&D9`=1FQW+K7]-9o`8c(E]-..U$%Qg!?7p+Ec'7!WQ(2[dm>`YrLFBdc+-mRIk]\G?FqQ#N8kVJfU[20$%[EKKHkf7Pp^qLpFChuN]LJq"lMYgr"C91uhBA_9.\nmBZX$LE`f.5Kog]'b">@j3Y&YCp/&+Ek=JV0'Ya_Q8L^[IjHKd;G.L!kYlpUkTY*j$([,d41IqO4+G6jn!C'r==U2:AasceDZ:9M<%6Xq;Yd]qgl\=O^^]M!Bb0ZU]);(MWjVt$gHKRPc'!3B,pOf~> +endstream +endobj +431 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 430 0 R +>> +endobj +432 0 obj +<< /Length 1822 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb!"q?#SIUn3+NQO%GJ6U:tG$:MlGk)7lM5S702g'T>`)67g5)V52eJ+"88UUEmnJSd)t!:A;`>j*g^_ioo2eifV"e]L?fSGRm<_$fm@n;)"?X1^e^eo+mVcf5Y"QoniE$9GI/>]:uE]6mjmo?K0;T!piG6\_IYO6!DYKOVM/m%iB*ET6Pj4MdN=B,hSQ'bU-Jmbass!ff)tSRq=5uUd6Ybdo%m>\M=3H,U5$_HR,I>UkgF]#\c$^fVo&E-Ye^TX4sph('.#:f]7=uKnYj60C&k=AVGDZYcSEFIfU?&(nCjhAD":M?*@%J\G`D4kN?m![SU*k232QT@,XQTY%YLR1O_lFU24Img(eOt%h'!^USBLRr!3H35j_,PoN-`&>]i]j4BmWmp+-lED2e5JZ`n)im.sVS1M:X(!uB1kQOmHAQG2>b;ErF3Cqd=6+rkALH:)&j%:-QdWY;Lm\K=?UCd_)VS>fW%pp/ab5FHBUQari3f[PWDhiq4>B\jceSbN9n,ZJS@[?kqb;N6QAQfq1q!O/,hd"uD?=0=Sq;XCOa*FcPc)Ej!JhQ;:?Cu`Bjl6".:DV7o>p;$Q7POhL.I2/ELN#t%FV9:4'l6fF2Q-8=2g,-C!5,l=[%`BKNBN/rj#O/S`D//dY%D]uEqW,9!Xf[0kJfi-Vm+9;n[n$Xc5EY")r<\r>+MA0>bJFPMt9#([q+mNAs1nDIu1&SmH1N]k*34a5iQW#DR-!jR0?&R`CFWDCV,4@B(sKZ-/9ZcOob>p%aS>q*(DOd5L]Wkd1s)Th$%Z4g>$pD1.kAYpH7e()!ij(6.l$[K#Eqh3DQ5]a%48;%d%Qkfl1"HG;,<']l)Lm!D;OH8tsW=]*cK`;sCQ%1)G@5i=GKqF53:W=W1YrQDPM@kpfmR4S0:2g\4?ATPke&8-N`(YN;+0(7,Fjsph==Y:dREG\hm+GVCsLVueC+dc;@$a=QIA^YTsAR&"?]S?]9E3M%qd]r;Z=k*UWpi"@$c`K<4PM[Y8V_]l],*ZIo>;bAjZR@CV\RSW!?aDR!*;'qPCfig^b/>gq[l%b,IXj%;M;UXMg->>?)N6Ahc$0=rCqVnh',>WH3D2R\mNqQ'Q48C$S7"+-4hrqPa8dXrAJ:KL6C4RoP\;MZ.?9+Bt7eUljA:^l8QbrFc1g#u,LNXK=2g.TQ`W@C:t4E%ei[?48Y?]C8]"e@27B-'QHohHn8h]V#[fFHU6bS/em\OAfG==64E1f]2n7h_TS&1[(fled4g_XM_)/p,\"VLu^@5*4G2$VXFjpf1`;s3c6BQ]%+L8dBJ9H.CNGfUHX5OAEU3"WWSa2*"?L][C,ola)9&1nG!MgCm^(;-VQPuTQla'N#@NpW6meBJ*3mD(-WR:*)fG(MF1097[dD(/SYfi53C"2EKW0bOF:Z#2_+L(59e9Fc0ncdLsc$sb+bm@QK_^0Y"-f1c%'eN'+"ON+T/]d>u/X0o#>0h>)sQ1Q`H$R7S~> +endstream +endobj +433 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 432 0 R +>> +endobj +434 0 obj +<< /Length 1707 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau0DlYkN9&HD156Jq&:N?[Y!]0ee66],I=J0f40AKD%ZVCWp;\>#53qs-cBH'7:ADD;hkH)H#ZmeGhi\')nE;C_R[?B>eklprh.(Qi"hD]?c!)G3)uL?DfK*0fGa.'1([g9JdXGWkRCe)dI;QA*M;*a`q9*N$VKG)B6fI_p94'J$9?)3](4RgH]os/U;e1U_R"L/Zd\`m0RAACad2;gr:8"8?-,hF0]f3fR2nNE1\3>H&Ptd>jn$Y929CCfT6Hl@=VV?RF9Nd':qdcF?O)Y"tUBS9-C?pP;4He/R"b(#pJiIdWC>-h#C<\NkO!YM--ETN?MlHte6>sk/^'/k]C2o=ag4(C4VWG6'tA^)@XlHd`[!lji!(NnRM<<^"GVN>aI8F2BI[lBUnJN&:o1R[HK7Y?->kb:XbR-^*?B)VoDEYMh4Z#teV1'gl:P^SDE7MBms'tp0V5n='8eYc?Df,F3dI+J/qG-KF@%4H2KTu[\-,H5glTre.kaFOqMY[gL%!fn5>qZ<6QpC8Nl"J&Ol@2nAfHtnKSpq6PJiU1Lq&$`J\A"Ii](nI.n$eKRkj9?G+bW!#$'@WP!^;H4+6L]OK%74KR:a+9FZRr+O\'0Ilr)pnZ/sE['CW@0C#*0N\qg(RO>O`^L6l;3eHBgK=0R-"H%#n=r#&"[n/O"N3MrP?$nsb1;#-E/Qbf*9Z$1)JL0oiqh06@-57-"c).TGPpVY(C8!cIZe9KHi.'1\lJVjCAepO*NW6kdQVXJ(M2Qcdccl4oW8s9:9_4aG,P@3UYM&C5]Zj9Bf(SM_8=iG;I1MGd[d1#PL=<%-,1kR,#`[lA8=>Z3U5Vr'nK3ra1,me?83Pub-D?\gH)Ch4^%Bg#u;^$q1:#R$k7`^CFJDBP+HVqoXL8;?()p;%g1.d9'X0nB'"$MOU<6sW]Ra-d75un[i^>k0Se?6dOWm0a>#,9>EH"np>Z8aUT,2O*/JUgYR2uJ;Q3:1X/D3>=5n;^WabNGWGFu<^(Cb.s!pe!7CP%nT0PaM6b,c`rr/L&fAW+J/B[@6=9%t'E(GePjNQ6hJV=@,TY(_rkS-j`g;/#`n)3@Xlbb<8[U78p9(![q2g\R(K^Q,&Hb+Bg+qP39_P(]380Vr$SlK9*:%@/`-=@j:^#1=H%'T_F'>/Ts-'Ga3Ud4Ya?\3E.'1_Ik#Qnes4fQp:/ZJ.('Q9n)s;hKjDlr8gMmKT&"V-G_Y.bB)#rR^+"3f$]%uX9/>~> +endstream +endobj +435 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 434 0 R +>> +endobj +436 0 obj +<< /Length 1136 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GauHKhbVu\&:X(TOiJXT'E-KQ0CIMh2k9N3HF>^"6"C)PU:q-XMo`:XJe7/(.:^iq1-'-A7b`'Vbb'*QA*Fq*A&.AS0r[r`)Ep)Y^Tc>YD0(d8L\W;`q:X7VTS,d*5XI=l/C,TFp9bo/mtnXCG>M]0=Nla(ZY%)o_n?r3i$redXV(cf=*]2Y:d"37`4b84MDa"J'@Wjs3bPLD5N](-,g_:VD^=m<`/jsu"BCqsF8Es3NDdIhFuL?(?(;`AAR`X#CU@@3h1H:m%$jOE2(TQfn-]Xl4g""FW/oXZ@JJ&F:p7m9V&5KJR(SI^O[5me&TF/Ng-;h.Q-&r^(@d4";fhlZ"HUj5,s(-s`uH*Y(HCD!!'N2i=V*dZ!3Q]WO4^Vc^KNE7jRl4^<)$F#c,n=(dL#Gp-VS`BH5B3h?6Ai14nDb_SW@jereUi`%2-u:-&3l-%r,&R/9k(0%gJTO#(q(YnS'E1N]WpT)dkP'+n:C$`9G-\jESIa\hLgUV$aCWpL?7Y"Aj`-U<-Qd9QifHTQG[h=8_>,)Yl"@V;h1i^**h@OJ\-LrD:f;-iDMqFE"[2iI`e3f?g&,_fhD=\MF5r79LoG,N2<0):d4aV; +endstream +endobj +437 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 436 0 R +>> +endobj +438 0 obj +<< /Length 952 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau0C?#S1G'RfGRn7*u"M*DZk'9e.f!f;&R(PYbt\nb\J[`#;f^W6.`m&!PDF@(D4dsKBNn\+*H\X8B5Hk68]0EAH@-iiud"9SNh!9*K\LbK5LR'"2cnMX#U'CZ[Z5%tQp/ZM7D/u!Ueop@nN(i]hSs'\M9TmTR0n'4=@,VZ75Lq/d0*R2pj;siT7_oS`c.3]\*]>`p`#ZaF%#]=48-PMZob&8Zl0R_YeFn_lh:dZV/aFZLV&ioj]pf$-CGNn$t.lmf0tT$qIm6)msh\46X5!Xe9M)R(hX`?(ej,I#Ru",DkjlC!T^F1KT)db1`>LCfRk_nefa\bcmn)tdRY!tI:!)kf;OX8)5D]4Tr_B8=M&4AgBos0Z3]MF8anlJKL>bt!)Em;a4(.M+DO1Im-nn`!Ds#]7]/*#1A#B0,[rrh+pWpqH0Y*odV2"7G4HnkA$a[QbeaHj3Vk_b;-qLi$K71=sch2.'EPJ#TXn%7c]U$U#dS'L_Kqf7<*eeV9Vn_t4JH"`*0~> +endstream +endobj +439 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 438 0 R +>> +endobj +440 0 obj +<< /Length 1438 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau0Ch/f>L&:aF]_:pt+$&9)OUODFPUsjFgdnA]dbGE\(=?,q,3"gD;rTbteKGH-:OdhAIB0'd+>^DWo<6kHodQGbr-L(Un)_hNfu'NWhAf&?qrZ#@a5+1C-^]+tr-eW5Q0UGPQN`_PHm&_N82:Abfcm5!*Z0eVFsB['FOZ)PTl4%BfiGK6><S0N;D[p7Pptll=&;aqPYX[`0@bbN7fun1CL642mkgb25c@/FQ:CA-`72s]kGTuC)OaD44,4bHca4BSRCi[MC-%WWVOgB?)gd:ufMkB^7E8ML@go<;#)hkf"57rhRtk_599t?oJ`du]`rP/3f7u$Cbn$`HL[4Gja.mEKCj3dBdZfZgAlY\F6"]oP1F"2&qfu/:X$&U(O=Xt"+id/^,/+4HN'jb$L[dmVZ#j`eHr2JX^bBYCr)g`AS53Oj=a1D8EE9-u4DEi-U$$;gm8,:K`_kOS2'!!#YA?`(a[elP3AG+j7.-(jW+ZDdaSOiS4:^,G#+GCKF1hf;4@VjPVqsbBf+'X]*j:5=P$8Tn(ZMg_2[],,cjP$(AG"@.;Tifc@GB,or\hdjnE-uI*qr"7E=ON;@)?pO3,R3KtBLQWc~> +endstream +endobj +441 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 440 0 R +>> +endobj +442 0 obj +<< /Length 1212 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb!;c968Q9&AI=/pdWG'f6[2q-T]]dARL8$.2QA/,uKPtM%#Oei85bD,-;O5E=*MZQUos2p=n-c-i%443PPna'_m5<>ttIi@=l/-r#lU0E\e30O(*%=p-,&2DuA*H_dU**U,8?(qPW0dDu+Xt-]4&Zq9C6iF3UP-g";m'Ttgl>NbMHRL6h9GokmHs#IO7,fi.&_`8/4R,SJJ5TsdGh3pI,N_\9A"lE879:%DQ\]U%pV.Rg#CUl4occ?$i\=(aHqG5&CpT6.FhSc0MO.1jLUGi<;DKMU^V[g*5p[XmH*1&]4j2rS,ed2PE2_q5ll#]84`^+4'<>.Y-VBCSOLhhGc':d-8tZEE,#,\_DI:?K:R9?Zn1?#QbM4Ek.j6&VL\g_6Z>^M^nT3Ofl#*cd=tM7F'^Ync.Qk)gXXL0Y[)#JcGMDd!Tr@]f+Pu:4md[VntUNAMer2Ae_4rZg^,..1eQsZ#'bK8#i@LUbP/HIN'>l%jf7nliT4\QO8npK!DF(U)7ZlQ8LF..YJqZ10;j0]\rM\d_PDP)9?jbR;6UqtOZ"q8;<0SNl-S:IMYB!W6Sr%%8=Xfl:IM*\PVU2@s:8au/d>mt9dF@VuDaT)q(R5K0*om@:V+8mp*&XM5F``"=S<-=jZ6*LGQE?>l4O*_q@2lD774W!S(YYGW;<4g43_=;G+&f6Q$5S8jP?j7fU4gG']s^%ngM__\*GHNJo^W?5fiuk0L4cqZ`]`,%%FU1m&U!2r=!5M6Bp^%L1eFO7UmkdXqU&,IOrScJhhsr([]_^"A$4p(,%-!K9;`Z0fD:#'!+oMFl3t]j~> +endstream +endobj +443 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 442 0 R +>> +endobj +444 0 obj +<< /Length 1303 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau`T>AqtE'RoMSa;Z':?@9qM4`/UoL-T3``sX#S[8%ZtD_c?t;%Md4:16c:!GX^/K[KbKO87TU.W2\7WM$A(FOYi%LA%.;(``tcn^q"uI\n4#NsCV1l(%X'NLQ!T8/hjJk95+NBP^FhTi![fBY.n3#dl)EY[F^E,VPRjd4j%E@+[f()s6CYJrMY0eJqlg=;cS+5=PmJ["V]8uDVSQDDp6(Ij81[FSeD-Dh-aGhU9rFu@NC;5bdV-1g1:G6fTHomHOIHD]Q!g6\#;P!;L]j(iLq&(d9@%5+u3)tZE$eHu#bee0s=cnq?Q@baX*ke;,VVdL66Xm2S=[dW.?'HNd?CPltDO2L$Zl]g=Q0)WnD=7mYs_[(tBX@COlBR!#&51Xu#T`BUK)nasi-g7jm^8(g+A&SWV"cEtDn@XRXF:gcZt,,tor7`U5q!Zko(QdR9I\Eh0,6[9g,"ZDu<3M%5Aa.#eB2o%4L/ANiPM%:IWc5ioT^mc2bSQSLcj6&Xuj<45:X($h-m:lKH0n3[JH,LY$*EFWQ[+*Ws]XQgJ:WbMtRPnGNHeUWEAj<'iQZR*^Q$H(RBB_:tt`Q\p'@&4I%^K7.gk!R4X&WV+g+_M=2VJ3*U=p>@18gRFN]oAU9UB4P4b%r?gjAbF\2:m)lge,,t8]0!qfGBNZC*S%u.eEe@K7IT+*/e'tp?S5WVFr7-TSbCE2gXn[=fW,!9tX6!9ocVl\e*>/"bbJbYpepQf%V`7lc:V!ULK!Rgg_:P)C9r#7J"'WRJg&^/p[p@.kscX"JVadKtW!heHJX^24nK/G<)asP!mEt5\>KRm'ONFIJCV-i=:%Z-M:o@p9V>PB/\;\[>tmK-T_!S7L7.rikZiBV5.V\kRiDEXGn5_6E#-ZM17KO:an;b[V48J8:\=F2f<"7grdM^M(Y8=2,E;-=>.krAK^Q_!m7b-hUl$4BW@)Hb!u[=#.1$u9'mBk!Ii28q@VAY%Zd!J)+hdZg0atu1iJ*Q=EMiY$,6Prr!PmEu!Zj8F&Q^:r[c]3\%[JU'!$b/JI2kU+Rh+g-a%8emH(N&\!5Kr'O;SIR0(S854cje4rl5ZiP>LF_d/A])U\L0OA8'udqb98KI!X9M)-AllG3^,@TAcAkbKQ_M&gEUV!+GORe`DQjA,KY4"7B.@*I.-l^XGAhZ2@>1W0ssZq8Ui)9EpRY~> +endstream +endobj +445 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 444 0 R +>> +endobj +446 0 obj +<< /Length 1237 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau0DgJZc[&:Ml+p^n?X/6T^7Vp^,FST`^lkY(/^KVJ[:`!0@qUgIL)WjO&bLJ0'K?@2G5Y&o%lcGa=5G(hIL=f,b(Acp5D&!15A+#6[Nb+!:!:#m1UV=F.j4M6[XRkoM0]Q:2+jQK!;7`WM%A+Eb(3]15tKmhCdqB,mFP6X8uObDi]L.K,Q4]=gLVlu^jTraSoYu"IN'$`OgT'9_'b'NB&EV@Ir;-bDZ@`@AK)+FZhCZ(!uM",G+3PP;E.8_]FK;W2S$5i,tN^<5O93uUMbQbu$`<8/p5X'-!/mV;^g_rD4jFB>jb/Ci_0(IUpYdH+ij#k=;h6Q59l1^^)1uqVhpQ'Er>pLd?VM?X!I(Z@O7[,_pBKMhV>2^LtFN%^mSbr-Eds-+Y4W7UTq=.IMn9h7=24RrAE>nde\&[rE@;OVqXOfq'%B3e:m7CaE[q*[8Dj5[ZRa&G>*5Q1DrdrN3Qk['d7!7PT>[neI&*8bR;=35=$(,5Y>;;2%T\/WXa"E6D9Hi`1u;(q\R^H#1YA8k=L\S$hYGtb!LQ>NS3rq__SE49V%\V#2C\Ka:gp$bFS,a;_+#&]hJ>7C;9W0P5+)g`_A\$MiKIb-ltZfMY[>*sj2jKFmCAJNY!rgkFd;.S-@Gqb:'g>\S&8782Uk7'^;+YUDC*\fT$n0rS*3;iFW\H+je*qqLYt&cgu*T9e*:4!B6>EL*:2-3'[nlO;%gdWhc5?&iIc<3Cr`[tfh9b0>6XFHBuN(;66%Oj[N+MLl'/Q&j`]/V+D>7fVege..UsR.kQ4OQ4o(g6RI+ODL*Y4MHZ:XaMah[o=d=aR>O),9%]f6@SKqNXPkC3\E*u/p?)T]0%/&VN#^=+K4/^`g;@-HMHkU9a^js^obEGr'2)-ONN)G;r*Wj(j$(J3'W+sOQ&Vmf<&\Ta=bo5J5=1hcU^C."0W-Y3o9l:h@b?J`W#="d\!iX7Wg5.%AcaNWk^QbZQ[9'6V4Sg_V0>`($,FK6Ut&?jn/oEq".T/P-.Aml0,1_,JIM8n.Cl)BblItT>6`LKWjCiq8C>a+=4Vb/#7YAp&ZW~> +endstream +endobj +447 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 446 0 R +>> +endobj +448 0 obj +<< /Length 1042 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb!#[bAu;j']&?q?:(MhoWi;2X/(qQdn-GX7]Z=AK`nH7^H/J5XWnOr%].;fV@PKj`2ZCU`pV:.P5W*YeA,Y?`Z"VAAtt14^cR&dP?>lY_kG+!'?CPMGR]B!=aBR`#0.(rI[SB#+#m=;441@)%Ca[0S=!(P1Bn$;8U9i>rlGhi1Ju5S/%JqY@qab-KR%RhRY69p7oj="[KIFEL[bQ.J58EgM[EG0b/^UuDt8WbTRq8\0oE+mF7nZ!A%_HHt8a:ss?4+ADXXP5:,Mg6!7ga8U2"dr[@L9E-EJgM`3F)J$8":'QQ:9'gAUKMhp3BS2Q3+E3)2@YI-mJNXs8.?1Ac)6jEM\L[4d'[/qG,\OaYb.dR>+r2A;,:ZU>%?BaJ*?D=bk+oMN''"-!~> +endstream +endobj +449 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 448 0 R +>> +endobj +450 0 obj +<< /Length 1250 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GauHL>>O!-'RoMSaP4kU]\&6cfq+Q6)AASEPeE#i19Cp%-0^R,`kUD&il!4D92j1a,iiI-Ru`WFcfp5,kj8t)*U49hRES1(F$67X$\-["OUmY)`!?gBadr$OI"$C(X6aU?-\]_:S2\/dRZ1[D@I^j,KtQ8`IQ3Nei**LZ)mA&gHM"1q8C@3%)<"n6Z+O6g]IXF84iE84On'^@e-8\qh0.h[>k!0qVO4>lPpPn7aGY;25>M(Qo^))FiacNmijm.RS]l!CapiKmab2IB#\Q8,-.=&5'/T6AK"_iY,#?Tq>hg/F:@^^u;jA"Q2`Kbl,hTFQN0mrM;H"j]3+fH;@t0]scKY*"Ldc/(d^c>`>eJ4=FX.Bf+l.H-Q4c7hY!bJI=&]E:daaa>DP?G^RS&n!#4%f:,"LP_$S^rFo9\4n"!V&6Pef_F!(gMWpl/h[bJAC^.g#:&^cYseb?f/kO1Hn#dL-'cgh-rM^ci/##3[eIlU0o5\F[Q?bbC)/f$q6M0n"2ii*KN#9l$-#Be7R%FVSrn!\D')kjojCW`@+O26n2,6!OaTai:YL?]b0/=YHZg"=1jILnYQ/L0!P.P&&l6^kO1$j(9Y5J6!pr>"5@%>cgUug%lepO-m)J?SUF>d.`[cN-HaA-#RlHdg4&'0u*.+<#B]\K):nomoB'>QLeSQ\h=SZ9_QhR-1'i4??DdTUCA'Y/\0EMq-)Ot:F5CcWV)r_bp4;E5[m4ZD#eH:)$`fP=VW:.%@C-jjr7d:BXr,g3@C:CLIYF[\*t[V2O`W-$8MFlcGaIU1-`L%"8-c/godb00kNkGi2mOdMEU%8pu8^`F3"WX1`*2rtD&L+a>j-[*_m_J@D?GuOB\&&&q/^4XSYEC5^S9=H2fuBuSbSS_`c-,cG/Ko0(\9?bN+eaKcGrpKfYp)9@g\<1149`Vf4cIZ#L@ZU>+>#l+1AcP/ZhK&DtA>W%+DL7rX]nV4X0e).(iihNa1o;L;B!F(iQ*&;%GG*jJ.-9JO_YH5M?U^6r/kr;:p?V*dg+/ +endstream +endobj +451 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 450 0 R +>> +endobj +452 0 obj +<< /Length 1315 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau0ChfIg7&:Vr4iO;Hm>%(S)06j3bD[:D(ZqYh>%&9V=@qb8"XQ4oH*nc^Q[A,Pg2b[Pbb3l1`eaDVNolBcVq`MY;$A2nE$\RU[%RTj+!KPmY'LsRj_=BJYFhY'&Vi0KB@/5F1_Ur$pMg0'cI/:P9T:$8WDek^^fL7b;ffdWq^V>2!gtge6puTPSi$o%;PPP4+Xm^0EQ/p7r\?2Y+LHf*m@o%sm4mZWMnd#hKdTUT:H)!X!cMKVC9BA4ef0NNDH?-lGf5)R!.D`T9CUrD!BI$g^Bm^rsQXK.:Q3m9-,o=hX0(n13@!S6YKK;JM!oM'nP_UK>J\.)%B+Ep9@8H`p_Wemsgt-7q!6-^BSTQU9`K3Ajl$SUK6GuP@iIYGnt&@`#8PEc@ca9baDEf"1:kdXmsjM!K==bbD[WSCIJV`]$srq#`Z">nKX@(b4H2DCTG#I=>RG9*qtgL4"[l`KA/3`7(LKS]q%F[>rDIOKB/F('3srnV97eTk(Jc/pEP\;d4Ip<9!]sG:M>c_C]`-_:c)g#`Ug%"`"_;X,-IE+i;P8>N:MAUTU3SF)-H\'rDZQ^Q=Hpr_k?&d?;N-?+$P._>l=4+m'_$B[Fu5Qard-G#UZF?L-nL3#gW0<1fM+.,fD)WnB94F1/T,G;t>6K4rd%"ZJ5OFPGCj\drVnDGKW-rfl?L_dufJ!jJHhQnNa8e$)36=X^3,Hf1$O2+7]9U;bchrgM6!o_0Al82KYRs+n,0E12Tq_pN@86(B#fD!iFjb78<:+!ncrnHcVQu1l/,O>#AtXJ.p`;V*q"Ym[H45udI#^dQia`+_:J`l\CW5o?*)h_=!r5m*_0c%\7i4\Z3R;k^EJT)AfadD0NU9ZC'eA)k4nDNg>l9'mjeFn1e]TrG?C=NDH43]G'JkD:,iAU6E8YrQ)sc,2ImDFW6uV%n?QV.eX2g,a:U*:`(GO>M-i~> +endstream +endobj +453 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 452 0 R +>> +endobj +454 0 obj +<< /Length 996 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatU3?#Q2d'Re<2i3AD&(Oq"hSeeJa^STRI;/.d.>3]H4\VbToT0^^%g1UH#f5caXs]@;1=mZ^V'?"^d>d[t/TSc`+\Mi$`5?VF'G!`-(-unK!KO=e:6UPiI<5'#M#+-0P?1saM^TeP/5nl$,fKSH^m\MfCkn#R]\+UAY7MFt76PbimSSqcE"qc9@-m(ga)dT.o=%cm9dPULSOD%Eg`/gl%^@DNWUj06@0ub6ekg#6E@\A(AoWMA2=O!u^,;&'6D[Z]8^>2u2'Gh;"H=#h*e`AQs.E1b4?+>\Z+Cm+A73\4W3=+6Q;#+u;V[4/n&W$;3g>CuaeQF@5d/ZS^']kbh$b]QO9j@nL8\3*"[U%OtBG]V-d-.EOZEF'T;,^?5[G[bU:E'I(!^l<\9jPg +endstream +endobj +455 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 454 0 R +>> +endobj +456 0 obj +<< /Length 980 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatU3a_oie&A@rkFGu-2iMr_;2+<+oBRtDB06L-j2Jj>:AOhsuo^>F)+Xr8*U`-t/d`e1>S=)nCAj3f?@h+(j3qN"M3h$_%T_orVZF_*RP=J)WZ2+"F(F"po5+!rIQG1@qW"'(l,#RFZbg)Z#jg"Y7"oLs-6&QAI0SHJLHl#$S(t'^.G;YqC^bh$S&Ral;.u&L6DH_V"o]>UGo]s4LYMXgWMk/M!p7+F3Ab)1\OsB<*_f*_F2JOmncb5b.SN[)Z,MaN*3dnp%%Q)*!ajggc""aQpMkagSs"?pS`LTYFusJX0h-\K$JXa]G,:+QRcpj@d6tIK_Kh$9hkHqf(ZQ$EoK^Nc&3s(TkS9UoGL,79`6TDj->-Wg*\rK"f8fkkL*f='0s($[,sH9^T+7`c!(;1@E"BiAG%!A3M(/.L?YqT]-JNcTXUTsmphWJ?RiXJ8CElJIiN.uKrYif-k//fLE>-%sPK0crXselMDs+RUW_rGa4A@[<_L*LpV%/5#Cr+HP\6Qdbbr]SVmZsbVR.;$=m.A^smn]Zu7e4bY"h5,%Z!H?Dp42?#Oa)g=^jZfNmpT>G[;Wf#2#mYW-Zqq&][W9(4:i[;M(.?TA!qXa=KiEi9Tq3iZn??1AmQNH_)505*LI\,"$h'3j&+"Iq<2#~> +endstream +endobj +457 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 456 0 R +>> +endobj +458 0 obj +<< /Length 1571 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gatm<9lo&I&A@C2n.rW7,6Yd7SskZqFXNT6/NGi@SIR2:&ge6jOJ!Tff,"QT@R39q(&-_(Y'/\T(5msEhp!M"ZcT\5n#[orn<*/cH&c>eP&"F+.dAT5\!)$_&@WuX(24GPLkW`!N[3OS3uqGW\H9NoT6n(Jc^)`1',DY_E"GRT*$qRCgNn?TeDL8).A(NL>rR\1rC\fW^V/r&U8=k)CHqeHH;p-j[ZQPdj)HA8c.@7J*E0)A8[dIa\Mlh:]2RbWRM@FN*'d\6``7Lfh2?"`W05EVQ(j`E\k+nB:W6IWMoi>?-&B+P#WEj$8C-CVf(.LS*$cZ=POH%Z<4/,VMiY1's+!FfV7:#X'*&hZ(XqGCKXOP605=j[Cnf*Y#rX_,/_ij,SEhNb2+Na+(,Tu]*Hf%(^29ij;#O\K+"kn2R1L6l,]fplk:cUKK'#)"I7=P]?B1,[NoieW^/B9ofY:d3EIfI\W+p'@;cTkPm&KdE4qG]V:k:i2Gu!!^'kL)jBP42[&b-@5`l;j-H,WV"c;fO%f&].?uPHt%I4,618%#s(:n;XS^ae"GUaN`9O^`VJ-#Qj:JmjNG2ag#CXDg'"UYGQ.a+L41h,Y]dfR[A'=)/aUT,6>ZE9]I#ZYnX,il#=+@P]+<[h>L[rteVNcO0mIC$Y['bBEfWQc_B&rCo?hCVPhPD@\?j4g:-f[^nl(ug=W*o_E^8eK\h-PG5'05=;\c%UY+e%;A;_C[_4WP#St[W&Bf9R>MaAKhfnd1UKV=F.$r9T8p='k31!3uc9m*qNfsqKE"-ht]$uMu2?7`9)@@T,Xb5mq#E+[9;1U?7&lp%W#"']\_0:Lm!HO8Ia)[VtPTaGJ@nSZR`(5f"Be_YF-Y8uK$iN";jqGeJ/SUcDS]\g+:-@l&(1ekL53/hjlWO(5:%#s9XZ8%#W2&h<;h1>MI)afE_Yjn\d"7\Zg1@8;sDTJ$`655eX%5B?K>"mnbWfDP)Q!rDO:ZYZrh_kK+&"iiNZV@g=28l.t?,Xn>#ZaOgBeg3-[7@t&caJDM(\PrsU&\j?!cchiJOY[).fnj(iNu$?`#jUh-WCJ11gK4kOoW_O:EE>'X6)pp\c +endstream +endobj +459 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 458 0 R +>> +endobj +460 0 obj +<< /Length 2750 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gat$:?$#$amQJ>%ZS,'kZDp**CN''RmHe0.g[-i&pL\:q2]Z)!'2E)cQ/m>JoZ&%B5QX@&8NV5A5QCpP&-/[O&_N*__D4WC-s.-6?2KH)h9J7TH6Uug02UZQWO#+t^[kr!k,m-P`-X20QdAf\p?^/,^e8eZ\g#2'YO+tU]>r=4u^:aI8?8,U_7`.jbjP+i4d3Ib(S*Ud3OF,BZ.8Ah[@qe!QmHTf`qdIGLUYJORH%[G?k=cClQ?GUOVLsSRcF<:eTC_(`N+:$e$YF'ooDuTP%ikarXCn:e$W/oVo,>=n$a6P:Nc;qr-C)rq4nKMt_DpNo:?@TSu\bYmZ?XM'L6j[\Pj!=g&@HqhI>Og-[g+3OGfj>3Op15n$U3X8^q"lR=N@UerOQ$U?flkc3`/A$[+&E*AVQuIE,Bsp!g6dMm/&HGKlknV\f-_gR7i^LHM"_1%N-q.thD<,mUW+d^l3(JCMW,d%pg[Il-Z60^mm.Qs*^Z(Xfej@,BafOWYZoj&7Mt\:N3*?4JVXq-+nr+o&8(l]6LshH'kh4*>VSFUmj:J+NqjF=V$i/-+S]^KVjAll@)$L:BQ24N-+?LQ'NjST*qTO/8[\:?b.nR"/2q_Q-(J4#,Z,o^kR:hH*)Djj\T9gc#:RQ4oR3j6Wk`CfRYQO+FnIE+0Bu2$Xn&WoE.64EU9!QVJ='ZtdOj[&6(2K4m7@!8++S[&^.jme.hIUtX7Am"'_^nZ*8J#;tpa.3O)'Gm\<=i'SpR'9W>7$TOGPQNs"BM"UsYmlm@EVDS$NBeXC4$C?su!N4RP5)Z/Ck7nTB,:tV9(W+F'(2Bmd%dSgKIXT(Ld"f7-p0?Hs].c$H9o?Q5@qQShqu-7G:2"=koW4PCl*)d5D94?9OWYL6/$Ks8gS#'eAI16rN&_LS(0#5rj;-/5U$Jtf1GCFm_k92t!"/OT,QIlR`^=/0[$o#d]g05AEu&ZoYTaM^cjqK/-NW!a#p:k,PbL1GKNL20]jJetHsiTVG8u6O"GZ,/Qq&g(D"l;?G?])SQ]0A_DA:,_PhF";CaWV-m,Ieg6K9HDpaBn-'q0m96nPHR)_at;>ko-BB<:P#p@[J2a.HE4rq4alO3<#*=#X3qr57**]Be+6A5G:U#'LF<.XtF;3T\njQ,4S31D>7fU\3fu1*5"3$ta-5KR3/M3HTcYY7-?N=@kRt1/L@^(UG[!uSsW'9Y9\j"&3O!G.O(iSjO*a0:FD/6h+R%OIhM#M:Hl%2X/'=uHJ':g5&ni*lCJu3kWT.8C/W9J1>/r8bfE\5H'YjiPc&B^'l"n8o7ANNc%;+l26ld?bZ:MMl8a;H5nkl#ODs4Yr=U"\[h)i0+MQ?SE&Qp'J1`Rf4JCULW7&)7A4QXpFXYF+LIO9\$8-l^g"%>$Q)0-FC:$VZ*$S83il*3)3(/Nkeg>5>Q`b;kW&<]fi$6KsJ6+D"F[b.I,4B%gCN1g41TL*dp+8mgDEIPj!]o`C]%`;YaWi$En'.DG_e5UpX>62LR7irHn?54\$.$%N/><;&>5i17u[C0r`qrR",3Zc1[]cM0m1T\$MIP-Aa*:<:fh&<-[i`jDZI>-IWbWHO0DTisHX.j&&hHGV7n#IbhF?ik[.kKM+pmq&BeE\@dl:QBi\1Z5Fa2/\:?1e5m"i/j>[-!E9@$g0EmA_djEltlPE,pT>$!`3t+_Antuam2^K>*Z+9#mg?0f:s)JEUc]gHV">D%8Sh.BPSAN#tV#7LOQ-(/l/Z`_@)9ZK!%=C>GW?#cMkqV+1.NA?*\0P>Z]Tp;d!jiU!-[dB\s-f(aCRaUMrB!@$@aW!n`Ep^RZt2n]sQ.N5AEkP'iV-u"'&pGkV6Y_nDCR,IfoBkkkg@DG&BKE$(F,+^HC[nFQ/YMn/lRd)NVfJ/r"kW++Ltu2/_L+,Z&hs^&M'V[I$uiM=#jMPFYSI4 +endstream +endobj +461 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 460 0 R +>> +endobj +462 0 obj +<< /Length 1332 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gasap>Ar7S'Roe[&GcsjJ\m4%?+-Z>aO"bVg;M9CjrmPIaqeGXXsb[jMZ3?I=4._L"9rD#53G$%Ma"4SQbQB*3l&"$aiq"J1MAf.""f>o9@#m(HIaRPrgC)%=BPT,X5=(V0^oMCJL`?X*s&"BoTtp2H^O2EXQ(3rH3aX>9=_^Kc7?>3jheTJSJl`Z0jYmPo2!Qaqs1l+X.-m(PlEnK(OAUg",L1&+!V+\852B)5[H,9T!Ru\OUBKni;Kj*:4`Lt/SA&D]TO8XgQ1)c5re$3#`Je\7Z11I(W*rsHB73BihGJ)a]#QXd:8V`C]uOjLpnjN\D&I163QPOO;8&//EDk<*?bVNmWITGP+CO1(s*q^W`1rS?9P3d2Z++TN5\%8aMB"_ilAesCfkfk0oX"">gK$YBV4\Z^[?#XedK/EBg;ZO.Qah+iNnsjfk9*]k7`BEb*TQaWu80jQ5UW(!q6a`!._F4;(r8HPC^Ua[K:3fseEM2P$-Vd5bM&r,n8r$KUqIq:a]J-"&oqk6?f[!(fBQLjD8$7j4;RDj$5`=cp&7Z4A6;`LQ`<:I6^Oe9JU\l#eA6:HTXJ7+mo33Q%ReIqn"]aIS(dqY21h80(^Le%R=_dIs?His5dErh]5@C.=&l(_SjTR?ebm*;gmYJWn5sG-.;ffV-d4~> +endstream +endobj +463 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 462 0 R +>> +endobj +464 0 obj +<< /Length 1217 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau0D9lo&I&A@C2n.rVL,6S;A,<<^`Hg49c'AIO\Ff,=5OMZ`!D1GTTIp_[Q=Ab_[g#F"Om_4*O0&D1BT?f.PZ_s5[D.]11aS3Os6-Q+Kf[h>s]_1W;Fq+t$D%ajq1Vob+3:%K!!"[e+JK$[Pi")02L[4't]!_:>Knhfb8E6&00_4?:hOc1\l#.ljo&lbrq<$3(bF>J,Fc\SS:R$ccPlDR+u"Tje^T8$.dPTJ%I%O9#tp>R[7[T9sP>LX:9Y?8culY<3i8o%l4DdO>3)[[$4hpZqH$BN`'8P(bdD]9'3\nc=dj;"qj8iaMpKbBG@3iSg'ga$kS7C.-LfO/p;#T84.UoPD1eaR*i@J=;43dbRgTZ,tVm_/^i1U]#f[J6YrZ4qK1XQeBAIpB"5%3iJq:aKC^F+5QA\4(K7]&&r'N/B/?]E>FnjS%?q5cK$\Weh3o*)eBg?Ndt5Y%*j'.PC#9K]eX@8X^jmH-BcS8qnV3K5bE6?s?>YJn!hdlDIX6_78JWP(gB2%0_(,@Abqcf:6Ajr!fi;9@2?]k$i:;YMaaNcHtV'jN1RH;VsQ]Y>[$i'/[fGg)B\WA0h,RjjB%paat5W955+EZ(/FjkrjWEE;iG\ikMYs@/'I9KXG%@J,.iHkn"d`:bC#j;btqb1BSRWt(?p +endstream +endobj +465 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 464 0 R +>> +endobj +466 0 obj +<< /Length 1642 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gat%$a`?E"&A@B[GdLC-LB.(m.8JP2V^>EK/a!bEVB?5/),m12/ee855QE'uRml5]@/&sjkQSV%YAVsme&nrh.teqtZ%=sDIERgi8$"\XG,pDK%:hj99+ZB;"U/?i_<6.Xn1:24/GZ.WJ%:Ihe82=4MVf$d(:"Lk;D,D1crqNm^FtJnpOm)1V=fnWrZ1K"r#i42V"gN&*cI[B^TBBRQTKj]%@pJ^$\#9,f>iYi[8Iiq,H7#fhjtm\miNWi^]!iGV0*f5aEHT'%]kTbW_YiBgp<13.IV0s#q(L;`-[^2=auL]Z6n7\nTm5?IUG[[Z;Esm:@mFrPI.!Io:3R#IdOf@a"^IODI@f0V[6-BJ?U\XLfl'-?>]CR7aEjTnr.UHaUKi&QiK#0jQ-=nuR77iZO"n<--C,R,=MOfe7J<;R+I:OQ;P:K#;:W+f0`QIgOdsFJX0@cq]AN^*UHgU2on[01d][Ed8Yq&RCLh'\O0%nS\NG*JCYr>^(Rm!.%dXZ?K?3OWT+fFinB;rDbu2n4^rs$`rP3dpfenMOFr(+JNpf>C?Ls+$UYNfV]pGMrA<'[ChnicP+'Z%K6jRV;DuEADt@&G\23G/D7a`%'U=m\kfA,>H-u-J")MJ7Di3uR9p)FYWHCuHqB@l*)04Qo2r32"j*hIBhVN<'H`&dM=]EA&Z7Xm-qsT9TJ"Ba=V>tloQI.mEf@'?Njl5Cmb'[(kBYsPG2q5rFZ&4!/*@NEGZ_auu;_0R2Z%8'=?\cn@ck9+3R'sc*"_5-86fFFZ&1Su+G2NAO]R0sk>DT-j/TF*km_3ZULlU3//dJQ=+ji=aIF_lcF,HE[eP=,1T,#/dkNo.T:+\XA->+[`F8T#J.To$\A%@_%m0U_:1,C\Qp65MD/#.%oN8uDKRe;b!#B#3]t#Em\AbF>3N&NuQL@=)PDpEkG)Vbu,8S>\i<@oEJ5PW5N1\9_N5W:"F!XW'oV2r9@RbA1dj/SshBL"f%K=s\_SO5f+6=r;\fop4pLK:Rd6MT:UTJk<(,X#oZQe3]\i"DWp01"%g5Jj,r^OuK@68Ih+`pnlJtA9m";Eh=UuL;ji7cY9?*"dTN)eE)C=e&f[2=q7BW]b2p>R\eEg19m&6C1W*N.C`XfI0/+rkt`3@1LQ%II64fnF9nF_18)mq*$sANO8+TF>M\'1*',N) +endstream +endobj +467 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 466 0 R +>> +endobj +468 0 obj +<< /Length 1462 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gat=+95iiK&AJ$CW4/SD.O%CSNs1X^cM%i\;EY6)17l0$2L\'NMI!5GjGRj4Jc^CtKT!P!h`tNsZ4V1G,pj--JBmadTG,k>UTpU),iCPPil)gR8'k&;)%."7m*[_"`WiE>Z]5Oc]EDnuSKOC.=QN_^#]c#=p;ho5[AO3DNqbL,@5,/Pj2`m#sQ+ENC#La's_m=tF@BUcX(p5o#Q`gnV>(Q;QNdqM2,=Kem='aoM%-h?gq]hqu&/lZPI=C\,:1<=ntDi1O]LM%q8\CA'?nR;7a(&KcTIQ7S\`\*sR"!BeIO'fULu`Rd>;_k_kVOb;#)6[>R"m2nei_?j]UZ\Cb_:BXkhI??*];M%:6^m)(^gFRt22C'(T^PIi_H[NK>s7817b590>QQrI\D&0lMkX&@L=+N#GX52jHe36GCqfJMV;YuFCWm0mrYf5iRUDa@je='E`DKRLfPMXA$Y1$NuWVh.Tkb1fZg3n(]5qkb4`8GGOZaK5()V,\n#R51&VF3NZ('$07j+?T-"O=#T6Mercl6E;I]`WV:JEQ2ark0]dV'NS0)7VU9HLp4XFtC#eDGJdmb=M*(b]=TnHjWV[FP=11'=sAlk4"2m0NP[Z+JOR\o9%Y6]^9d'HWjLJ%(&eFC6)J=)W`a6XCA;'0S^b<9^'#*J/aA/-!PX?JGKPkQ`\lIi'a+J@7OSEjoZCSmV0:AFu]agaS3=?bs_*N&@`+,F(+ouWKQlCY:aZAS4S)/(:hCCG5fUgg2QeUCZ+N35#i)dW/iUm6%F-bhG"[ao+H1Kss^*mCh-HI6p&&i7*P?H48*BQY7fQT8LJA:o?,<<[FR`!XI3Q3N5FkmD![fk]9V!"\^cT8KnehHk^.Wn-&,Mp'Kl@jtsbQs=8*=cNo=+GObJ:[*EQN*I2qk^aBaV='Z>]H.>HI8C@/pbY$,&#EBJ[X5i@F<95L<7=b`E^'qL9rcjb)4jW0`^546M/8qYU.]fj>?as1%$7VGE\$:V,^P\'V#LGQ?!R7~> +endstream +endobj +469 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 468 0 R +>> +endobj +470 0 obj +<< /Length 1225 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GauHK=``%G&:Vs/n0;L0kk"mOPUSs;R*mnS"W0^OPfAg+7Ws+UHfQE;X=C3edE,$,m='CqpKRH43dL62_#Qb$KB[abK<#:cT`1Vb-)'0('+@\O9NT&s-h#>V094B(N]qjiGRutJ@BK1_qB5PK9]'V*f#);H#bhes[1HLVZUV@^l:P#f?,LhfQ;aCZFjS\YpJh+0VCAnR:*d6"!*k43DAZE&1b&V2So=5Tk/Zhb/b!+idKF;*i8%JGFBr>O9nf-9XgII=jZ]N&\7jY1COtX3a9aJ0)Lggo_#dM)_^0Ea()h6(,kE@3T&(d-X6u,oK*3$R/RLbaJ=4st`PV2QJXdmX0%bJ7[$+8O(-=MpW#=[FFU;+OgcO[*8Q7$q7e&_<[-:&q(Ak/l]qO]H>Q,EThX7Q$FSMY3.A?8came&ef%-_&k'@GOI*TZmfF(+9d=-`<0GW?mE7IDBM%67l@KTfOH[,bkh4#g(A>-g_gkS7#%%<*cB[C5]I8H'GtX[lglo735G>/"ZaI0]^G/MKQH@Q@[9>ThK>)]H#jH-+PA7f!=!R=6*pNj@u2D&T0FF!H3D5VIMM5jGL-/,uj^2iR'rZV7H=O__H9grd'r/&fNTVN\/fR=Y-ZE%m_0M;[6S?Z\3HF`l?7K"#X`]-(h+)R9TT/!.#iu$_DECdW7j9SfKDCpoWgThB)2U@%>"F:.Cj:?#]1P,!^V3kARqgTBsfZ!W$.`K!\HF1Ab[.DAYGYBUC&Jn'lcFCGHIk\;3N]X#,&\ZG#-a]@s:h#>rXrh#5f7#;BET>h7jH?(:+`_3&^:W?(p&V@.T:2mu$OsD.W*R<81kfmNMlE@,!hrhH!I1+no6="C,i+_U)/(-4r>HU(!0's&n=t/mS%UX]H2FVU4k.2dJ.f@;.#nsKoe#@I%1'2-E*^bSP)nsT(,Q~> +endstream +endobj +471 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 470 0 R +>> +endobj +472 0 obj +<< /Length 1061 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb!#[92F;-&AI=/p]sbPhO!VH:IP>MMQ4pR?:n5.YXpAY)qGt$rUjG\iZ4M2iWOf^?bF!,h`Q)E)uF/$3'Lg^nm'M/9F%.F)^*2M%rr6,2ZjT&-u^M+kJtDEHC#X58!rBC#Ea:[L__LLQ;a2(bt?6sdI6;qeu[;6LKGg5oEQpILYQ1(`@=UrZP24YJOS"\QRVQ#^O%5o9!-VDU91u8q'g?&orLm&eJeDoiJY-tKRo9EErKQ1=F+ba+A7,Purjb1(bE',,2N\<%4G*F*P.*G0TYZD.hS$'Psp_\!cY2FA[mi.)*U7EcO0m9>Xp0gY;29ss!e*!R7SKR4b3mL!F")R,La42d;pO@i8TKWeVMI7XF%1NHIZaZ`,XI/n%]!*q0Gi'H!B@N*hKNeOB'!GC)&%\)X$DT_hO1#;.tbjb3CJ*@7%te4JadE(c,onS(1rI"kKPo+t?3Dim'q\]W_S0@\TSkVVt#%0UmdI)-&2522eA.2_4JTe,pWCTS3bJ@=*s_?oa@F1i';'E,`\KRGg"k6)Up+RpM)V?CYIYpP:7P<03R'H4qR#69F%nGkh':kS-q!$K401&qmY2ap_Hj7^OoN"l":Of=j]CM+!5^->S_.RJplr-bQ4;ZP7bb_0EV2p>MYMk6m(.qXg>Auj5+H3556Uki!4eS7ItXTYeWhXsK5OXRQ`KPeeFUFiBog*0O"3silcLSR\^A%Ypra5g3l^^GOKe_I6heRHo`R0&7,IP)&fl2aJ`T_[.6q!Hk0O2P#]**`l`!M?r6, +endstream +endobj +473 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 472 0 R +>> +endobj +474 0 obj +<< /Length 968 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gaua>gJZc[&;KZF'Y]6g+KU3,]=f[7R*q[,EhG@fdkQ[\/rg%B3V;\hbI4bpOZ:W?]p"W8J,bd7+67)r31^WJ#Hi,2^r/[E_o!%2%T@.EXtnre#,B!H%)c]_%p0j(\Qi7r4Ji6?`mocCS?;;>8a,+'j6<:qG@ZAZ*DD:3$PE-(l-fCuCW,?bo3jpm3F1nk\c9D`jKPQDn"M@:MF*X(?k1M2m40aVg^?iN^&9gj&N(A$U::5@'iB-+$F;Bs2u8Y<9(`JB:4';h+;(MmnSB2H(;S`eX(uV37:':gZWlaTG`74^0-7DuhSoR(.9$(4U,D-d(&ipK2'B&Fq-,0Z/[\kTnAuG=7=V)_$\q#M1'OfRD/0+fXg/[&X[_1Z.o)f\o(I(P\PZa'.God=*D1Mbp>4P^W<1ZA']97hE&$`^-Z3IHo8s2+;2h\4X\JlN'Bro59i671?(e]uk52`JuV61>UD[pnE=2m"mADYqs*BVcp/L^7[l$I''RNLfptr^F1D^7XokaN.FTNI]9#oK:^@M_N"=Snq/Q6,FfkhFF[SN^q+\(\/j?1pJD4\ZV'Wb/J6!!(iB^?R+7@L)f@@o?/\6Y6XF'^F(qbhF%Wu*]6\Fc9fWbPZYt(gDc`?0c]T[]13"e!5+M^+"ZKWt5e8:fr]GkV0-/%tW1)(&kTR]dZ^"KP!TVGJeS\So[R%].+5.XSidg6sXWWP48aHad.'YR=0uI1r-Y/phItTA=mM[&!5dnWL^[/st);V^H&Yh*85e-eZp?DM)k`<\LA4!s:>64P(M6>C,MW^T/b>kSJ`$kQd0-shY~> +endstream +endobj +475 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 474 0 R +>> +endobj +476 0 obj +<< /Length 1477 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GauHL95iQE&AJ$Cki`!Q.n\Y`cIZe%oR1&p[&$Jo[:dcDBD)k_m_+8sMD3Yr]=GVdqtskL']6RD=Se.\&M^A'5%'%rV&+B2jo+i?]:7-u\$oE\^3i%a/jd$'R6I7Dn_MH4g!V1KePr.=\3GF-l[(F8O_&EOMi]8kGJ%2=a%auZXHRiVdGR)el)4a,fZ?@_#Y2BdH$l&-r]0uL#cX,L&DWO[In2Y5l@#Vi(X?*XN"^_B%8Aar\j0,4j//fLr'5l'-:\c]'QT%=%eq69\6[[_u9j+8o1SMePn&tO70"6:d^k9*dNlp,4aN$2#j`,,VJqDCTo3qHkVZ1pmVC'@<)@!+.t$0F2`PAY1#<9651qbm;fjl^5;9'A!_km,B#Gf!-Z"6-cre+[,SG!'4(GQ>\^8XR,5jX+A:eml=A>6'<5fg7UE`P\[-97?Ar#aa86?b6P!+@&!I1W.1+TX#D)9]^,_Mq)9)0;B=Qjmm868M%@$onlF-3qdUg_FPT9IN.h01In-thaVF=mi&ri['eZ0^:H&a$f4?([qKb#)=H#62BiqH=P4l,9(fEDUA,9\a%:rsp]*?>5`tpZMT=,Ta*MKpW4"p`Q8ISL60t.a,`b;C%GXS6fQ?bX^;"['ZB4;B*6-h%10$\-cWh;HO\qK/jTDs;j:_tmH$bs=m^^D#MnGpHd!D1Nc*$L&A;NTTg~> +endstream +endobj +477 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 476 0 R +>> +endobj +478 0 obj +<< /Length 1248 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau0D>AqtE'RoMSa;^TO?CWu6GQMT3+ct>WGQEKQf'PeF.?6L@Iuff'p1`fp:!5A9no9])F7n]UmtQIQX2)P(Eh202i&\1FG$Oiu*UM=?Om=/13Q'YJI`@dXo&B>Qo84eWOUod:*.'uRGBS1OH[5AYe*u/gkmTe":r4%OPaq;ie\GQ/f5&?R>"R*hIP$OnQ5Sq*$Dk+S.-D!eMgK&h$-Ut[MR4qY>d^R7bDi$gF0L7b@8ZTcAe9p-WVdK@TUuQI/rONLr%)DUh;FL$%R+oUn;V'1@tK^r75=p[6],F*i'iS[Md9l9k-&-WPX`i^;$k"H"=K6K\UL_KS,oWV60Fm:N(!GMQ.l7'W1T$?cDTZDE?-q7/(KVGlRu'[KeIFAn+2+Ugo#KF=]:6"U\$q]r^3u=?#i2@!%kl3&mcM(lCrWuQ8gfZacJN;&JL)3,6kK7:=,,QfdI^6`.7"cb't!:=Wgn[]AiS(L"]06.ZOu6=bR>XIm,W>%;(a=Kn=6Vr3aUr1>]'ZrSDNR.6oPdWIU9aiPd7^L>Cnlb0utYGXHE8V,i0flDrRc]ltG]b'MrbuDkhpdU%lMA^bKJAQE5OPPZ[C)[Q'AJ5EjlSE7gCYeCVd't-)Zd?GRT%HqI9KE_(&IHTk]LK&4p\@297"a0:q-JOn7+6_,K6#QMdri&sN2I0mCILc*CG5OsBQONPGQ``]OJ@Q?$,YbRZfV6VA\1t/GM3U%:qUcVW*EMHjO`lb.a).EA&G!^nrYCI)UXf)459jmgZ3/U0.Hq+p#Ic'Os97ms&k`$#!\;k$'1~> +endstream +endobj +479 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 478 0 R +>> +endobj +480 0 obj +<< /Length 1366 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau0DhfId8&:WfGn0?]kTCp+ADP&Q5gbbR,Vb'Ed9'8YE!H&mHaG/dTqoZ@+(0Li_R=!D?h/@MFX)DQ%Vh;&7i+:h,Wr^)/lT%6F\\:G3[3o%-43PJ-i"@N6;C)UJ;F,k==S-uE!M7e>N[m8^j,[Ok#F4&mAZbDl%0nm!j2rupK8DC4G5`BA0AfgC=:3>t9Z69Pi?RMmBDMieWE]UX4$g9r4A59TjG\`rP#q^X'!$AruZk&ls_[*lg"G1lh+i#WI!$]<8!G97,mr';Nn*[>rrr/o"fj2B9YLA*,3/B@s]GV&dHg6(6-Wad@n+mo!jL^<:@og!^bULQPXK;jP%r-oCn$E@=gZ6JrBOCh(;t1oV/YkrD4FOKs&V'4&Q%uGm;2Q]EJtS+BgC+:W='p4kN&-H2=1/`<.7BFMZj\'[I1FHi/rNMnV':28u2IH=TRgYmega5Fj"6n8p@F/E[BXFMHo(/O(0]T!0Eq_.1WJ2ud])Dbj^q;\Q@m`E&e?29.Nt<$Mu[deGM]]rRtZB!jg!;_]d/>gqj09P@j5hb,9W0ABUMh"6Va5'Q\NT+>,oa&.*Fud#KVUL?K!qORcdTCJqr\oVf1hRr"K57bdN3G6a1[OmA6PN#>4[5`)C!m$HZ,@jn,3c[d!^OaBmmP!=Y@.ZL8p--&WG8>HG7)=YE^KlTf`qJ;m,pWLR!tT/QftaMhSK7m[_Tjh"PUoh7>m,#C;)+s5+n=3dB??g=\1e-$@BMAjXI]=NL%R3$\\TF!KW3o&@s`"UU2lNs42_hDFOWOgFN-4t6Gj_2!Ff=YmLS!:S-@d+NPh;e5>b;*q]qg?Kh:Zia^qBl\a&n%9i3Q%7]D0Z&!XraeYin_M?@'g/#IlQ'M!/M^;cCOX8S:*CN)h77s__djteCm'Andg+*tk'L#O0GfL&O3Xqf9X7uSakk,ha7&2@>EX>N=[(ERQ.BmT>*bEAXE(gt8$k.sZJeF_<\Mg\\P>.]SP.ie=]2UF9(N!+bd!"U_iX@(.%c5R-6Wm#I3bFi%9](;hIX4K!Veb>+na1^^U(HJZ`lnt6I;h'/se50!&edKr>_In&\C;rCOt'gie:5Cl#sFfj'[N+$;sksSft'VA>,a-U._$9e#=df9.[F.*~> +endstream +endobj +481 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 480 0 R +>> +endobj +482 0 obj +<< /Length 1878 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatU4969,O%)2U?psrtfQP&mkpXDm#Bfb":9qq$Ol0QbT*NP;KY9Z4"^L)joLo+[-CL72U"@)qi5Opk->hqkJllg;90.5WKH%Mq8qr9.!HY2:5#Ue)K4oOQ[&nfA$tE4S$pgo,+mRa1F:KR_9t`Ga#OSl=RD5EKDm)'t_KjFCNpC2SZX&9]HEoFuX9rIA.VG52]e#h/QXCYW..#\hhXL4]Bi-7[@1`%09IY9^f/),'_oPm_R&MUXYi'J+Q$]PMV5nEDb11?%(F/X6SH/P[/\lfY?rQ^r_S%8437CVZ[+dJRLBJJZ4.m)LTX(qX.F<*c/FKNDr;u`h?r?&7;]HRt5,,*(0qu1Z,$`KX5-r`_GNTOjd!_^%T#*cdD0lDRKK)A>3!PfS=b^lT!h5,['XjjrH0?MarB,eliQVg+JeXt:3Z"7#=[VRO>f,(tkPR.h)1su%(o'nGqQas>U(.hYV5gK4[k'!pBNX10'?a==`$p;"cp83]O9ea+<@%maRtg8o!*cIpjg<$TlZ6DoaYjS`A6ofEDn71m(EEK&C:jOmHgLd[>omg#W*!dD$-GBVoD8W:_n&],A`g:m]DNEPOi4o83`8okfMgt__Yp(b2YJG7(JNuB$;#.(#eY]%PU>Bp5X?hS%#(hpk&;6'p+D9HS&1&Va0IE,/#aKuh"jRi)=I&'`1(-Pi\tfe;k!7n&/h3N,.C/9D/3D@s%i36a94YR.YpeR!8*TLT?jOE3U]Ap1M?6?N"oDI'kNkeD9uD07:O#MK:[COSKQ;M]"8*DE#/#YA_)83Lc*fHeG-'.g@oEj"g]dW.9K`>-OG9'Ys*Y^Q_al:>s"5Gl!@iQl/oUeZa'8hMPV?(5gc,Os=o\l,*_Oj8i!dX5Q6sZpbW94Q$.mV@RV]l!SGg0ilRN4,N;01R.YG=#[>2N@"3!tG!$!&@FiI3WT89.cG',5P[c?;.;p8jOtT:[@LAAlZ9OE9/XT)\S$LleeMESu!Y`;Q=:\,o9+E^Nq(-]&?QMuq0*cY7E)dhQ2X(RR([L:@.d2(XQCq@K<^E[BR@neG&3!V*R-h^4&6(<$%ZMCa$BfpBk"/22'Q6diqCsAjgQN=VN`qEgHP09]L\0>b*aA0i3^T6'3g)"J>%i'Fd[5^_aE+fHC'cs +endstream +endobj +483 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 482 0 R +>> +endobj +484 0 obj +<< /Length 1263 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau`S92jS!&AI=/p]rZ`/6RG#4d?nPd\5+kTpO3l(nq-L`sT+>i87V%os/(k30`[gU0VQLh3E/uNK2&SUXR!ZT'JDsl,[pX,N*hE#93^oA`Q,n7*^&Fr7kL%/=D]bYiS4uqnFP2Lp"AHgan_"$qp&X6<XtJ#jP0=1fdA2uhc1+mIBg*]d-3?69U3eKA1:bZ2cY;6G=-Uh__\QAuccYO?d`eMo=;LX,8[^W2$R6C3K\/^n4DA4LEVW)25F$%VCbn_O0(Z\1V7G!TdO__$H&On`4EMO.:4)\/aIu;4Pnq;!Xc-?K`&c\4Q>XmE0)#@dg5(l3a`:_QLC!dUZ:bVEe]$Xleb/`?U7@04O*13H0HkH=#Dok/=,],fdDb%*W#m`!&s>0NlA^ba%*%P]nRZ2C]`[P1?[Ze2bR2G@_5CU#AsZD[5AGEf-jbAO&4$"NSbHcKQ53#VM@GIbdtE_DtZE0;Z8F#!*ikl>0o]Df?as]`j*0s,2_()lWS.WE9]iV/6.BF%IWH6+L-mgWQPe%2%"B5NJu$Q*fTU/^ecT6'Dbs-=7toK;NOOQM5LS;e,are9-lK,,6f*4u7UG+W6^4S0dtdZf^kYRSig$;KR+BiiJiWHcSH>a;>C/BJF6f]Qp.nhBkG=FeI:T=:i(S1fI$L-O_V-)l<"Lj"TWiIH\Z[AhJCshtO>o#=Fp:[VFjs1V[f"Y07DdrWaW\0Y\,B2l^Xg/o/I.H;P(9S()p&.E\>,V7I&1TS>`KTJZl'?&4\CJkc/8Q1oOQ%B;+a[70Xa;\QeVg6`nG!M`a=U>^FOAW#Z9i]RPfU<)-L&420!)"'rY2T2'k*I=C`gQBj"M#U$0+:<3-]+[6`s%bA$Q]7&^1I2k-s_+otH8;7t.A_T7H$('A:B^=mYADqI%dfYqH+oSk%YjtRo>/N<];#dmDT6D3Lif\,"A(?BN]o/?R>rQKB2-(,B8niP:eN5%g[:1"@c(C_,KP*5$KA +endstream +endobj +485 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 484 0 R +>> +endobj +486 0 obj +<< /Length 1441 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau`T95iiK&AJ$Cka2@,,"eRNmAUI=W/E7S,i2jrU7cAGX%&DfPjGRQI4:<,N+C)7TI>3HN98+<2`%6obpErse09q?=L2Pt=K;b5*;LfpEGK1M\2FYqg"Q;_AlENg>O1,jTcI;q%$p@0O8/P!.(!L;Q33P2@LZ<0'n%P^[WilK\D\V\`7c2$aX\J@.E\Zta:TpEnQ=$8jpS!.d!AWTC#;Uqr/QT,bs/>`07tMS1$OkRCsFqs"V0U^$+At2(Zc02p>Lifh*H1@EDS1^T_S-Eo9\^bbN%dCJ!GQg:9AKAlYOoM'5lkA9W6INZr*rm=>agCFD^_^4='?R]fo6`MQaO?BU\jiM?fP?o-ODH&JPP/mT?FDWG9").[-S2SDd"P'Qmgi?>W+`O5o)X]fO.;HJ6='o?61[Qd7IoPorIqekE`CN>^^e'h_`jfaXYo6jo;l5lHmU.a<1V3sSsX64lk^nPtKlbq&O"`Rd@f.9:)cb[jX+jGB.5]#rVeYO7ML$J%Y;m897)g_9ZHbX7!j8co&2RqKCHK+'LYfY0aq;tc[4Q7fOq]/O&qo8d_6E?#dpZt"2^kd,D)!3n_ua<[;QXL7DtF"ZfCG;f)[D"C)";8C_7E87-*M"nRdo9_j+*3j9:+HL*/*L+SaQ00FchMf'M7%Xo\]7`Xa8Q7N`R4j+KhnrVY6'TU6gF\L:T:I)9h*EKq)8gc[`j"U(1#*CO-JNh#daP!.(:&H1k?HJZ%JDJ"Zj3.1,]$)M+*Pa/4>s%!nK#qPj(gAe")g4Yo6LC:_ecqeE5&t(;(/`H_%j0SM5lM3S==BkPp>\Vo@/0.nRXq%dr<\Ta,<7Rau^(kn_lQi(K+pOfA1GNM/2Q>""7Gr,bFIK@9din)2pmXDDL_-)8^8bD;q0BL!L<0^9um1F'*TM46d8GI=j9kYT&=?6nb+J=NfpH3.kf&mAp5a1YAOtmF0o2YO)i;Gk/S'qG',C7W6bqHX&Lh<."tm%.PK0-gP2ca(NqY+J'Yh9(X?^j159Pm?1f<3hU_/0>f,#gri5V4(D@c12Ps"I'4.IG@=bV?6c%sX;nt+MV:hlg6&s28WdK&q`GlP0I3N"8-?3#,2f]<:I@m-Ve.^23FD9]A7@b/@1];`6Oi\[/I-PS%t`r!;5^sP<3kU.ct$P,p]@NYD[5%.UPq>!jKgq,cC#uPB=lP/UZAePrkGLr]53R^OWF1"Hm1Q-0p/K%C"cqXPE?*NZ,At3m%.1.59kXRD$j["i<^;_?]6rPjEro_C@-?WY,MQ;[N7kFl!Kp!VB>~> +endstream +endobj +487 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 486 0 R +>> +endobj +488 0 obj +<< /Length 1456 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau0ChfGPN&:X@\_4s0R:a?UFldM]T:"-Xr/r=X&Ff-H'@FJWR$1R'Qf2mJfMh6H'[Gr'(hYhW*]@p&l>tf_B5V;'LNjXZjNjY8tbE5#"+^?Z)#hoBc(-CiCl-mQ1h:(u9`Q\2->5TiZ&aCrpWt=%B^oI2#=2E'^E.21=@B5Xep@O>)VN,*!SGr*On9k92Gk^b"D_p\`H!Y>D4j8KHoPgFfI)?+i9;5Kdj[OMR[ch*\,d"Nc`-3,pm(h'2m)M:tnohbWKO=1O61"2k+V?DB&=EH]=;BFs/Fo?tatSnDH$mR'3mERTJ-AspdG3nR;C6YnJr*fbOIb*q4^&/a+IttKfT);''^p.Y3H+LbrS#WKL;S13KfkkR@GPulLdA["',qFE:rAla7kT!nYW#Q=9qoqP"!EaXiia.4cO;[l[SejWDF72@^ZH<%!)^OYeCcYrd;IOk4TO.+K%JPAMX$0o^&,c!9mLUAQN,6mMdm78j<##&QG8Cd=]E/CH4Y;EF-#>D':pmN4V9Q>Q'*,/>&.hXo(MJ#=BCcjNnFYh/T1-!2&,`;Y>9nGN/ZHEHlW%s4CS76fn>e]49p)#H5YD@:D;rGP3B>[_-'Yu@Bkd8YA]qCcfYI+lJ/[mR4jYG^4$F-;/2;C)7E.1P2YJf-s98q5tU<+fcM0PP$4>O01?>[+uo-;aU!#]9\3aP`QM(Zs9.)dCfdqVs(XF-^VbH"4cFg-_mh(4KFLa=*%Y5Q15!At,BHr(Ad?_Bf_7bdK*)[F3[&-'MA5EW)G=L\ui.W7 +endstream +endobj +489 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 488 0 R +>> +endobj +490 0 obj +<< /Length 1346 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gatm<8TWWE'Y`m7n7Zqa(a&f2l)DtL;eON:QK@1(FZPTeafK&O+Xq]b?XF?IM+7p,g5[fdptkc=`O_TKDXP#)0Z)[W3PaKd5Wl.ILe%C.0uQ7"Tf78iI_X$:\]rUt6gl%R.8q=lKKB"CU:Y`!(lo`15#$dg+5Z)=?o/aKX5Pm/&4D>$9V8RNjjI?C*X9(e5Y,AW+lLk3O?ag+FI['\PB99uVK3'X\Vj\(Xj+TBM,7Sr0#%;[Q7&N!YHq]-94M8Z7fh^",W1"r%6&Kalq7XP'Qgk?;Ht.:6(`@Ip%.4]e,=MRqXikc'ot?$n^q.%oAda?nbm!?p[mbVqksZN4&f"0bhos*oJqeR/b!hIUnu9M@t6GsFu(0mtFjnY";lAGcV#\f<9fO%(6nu]1(&[K*FK^\u_:*Foc:t)XcEepGXN>eEI@9biP'!&(kWFA`htt4fDIG(p4f5K#pBm(!Rj[Ic:_K7LdA`#K#QlCr$rpRpWqLNG!/_5;+8E6mg2Z7eS7ZZm@HP3778_ZqiQLRjMYXTl<@-Y%1VPQ;R_l).O#$_[m7KDOMj=c4A+j,GGNIf+?QB\%Z/9;,L]b;mJZSa##M_r[D.F&pD;*!;4P^5s&OE)2dYjrQh,=MK6c`q_q5h%KF,DJS96>(eiH.dUm(?o;1o?oMIX)r"PXMIXl8$O7$4ke5U1u\u+A`KM,A4?j1ToS[Q#sRa\i61sgIHQ1Ngcl`7Fba(H,>;/sJC3JDeiAM(Wi]W?'Dm%Y,VQ3rg2])9:)V-#a!N!(km0Y_-UB772jJt/YWmKoGU8;@W'oRT:;W/V/I'K9H8Xu0B2"$gjMe%N$/[7J1n:eqICY-gE%W]0'o-imrbP'=W@gV@ppmKc5RUK6K73^O5l:\ah>d_f/tl[LCu,FYZ)bOG$jD*S"ID1JQ-&kC42A4D^K=Vk&*9-;YWIMs*;E+@Q;`;NlCF+cspmSrW1$pm2Q~> +endstream +endobj +491 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 490 0 R +>> +endobj +492 0 obj +<< /Length 1162 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GauHK9iKe#&A@7.pt!dm@EFZsg/HIO.1Db*&:,drN_!]"EGVj"!rp!?/R+,XPGCGk(Tk>r]AE:*,EF1(rBk1*)qidf*8&im!*co0@1/9>e$B@tSi)p?5DPXT(0U3:a4d;>6fl3/QYXH1^Z!l@o\f*6A?o_DZ6mU4'\CA*A^7WO]RmsX0$bMu8]hko)6n7ts.(#CKrXi(:7keP\)Ip5ep@20Sk\_OF[k*2F[tR@??+m1]QYYoMk<`D%R-3C9"P07pVUo:3<31_oi3)4HY.@Qo6`[UH=.-;0_0@Z&!(S$M#;3j8"d_e!r"uO9fD;J^Q(KMpraF029hU.=B3aMtb2dc],r;jLdi1l9=])V[4C#LBUpki0nS/VrG"rp-R.;KGmi9"XIQ8@>+.\uESG`.3fl6>9NVd"p4rYRiKt%b`hMPnU^d0/l)]^#JT'3:)pEMfUN.jA715m=X'3!DDFB\bF)BIU8NZ7$Pp6"/oqd_d,4ODXel?-IUMZ(6t;=1-[;G[4_g%DUV/--j//!RgE6>af$Q/Ji:D&s')$c7L;F7h.28_s"]8l#"*J77hrXZghr'Kb`K"US1Ig*?D_FQ/T"0a'0?d&Q=!i5MaU5K>")1<=Hr_X%+(A4#,RbbNCU\4pe?;]bZ88U2s?!Gc7\JH.%!UKU\I*Fn(p-0k#VN7p'U@oDpbPiK,]P%/p_ih=&FO*`2]4X0ME^H/.i*$k?/u"AJo\8iW:Z%3innB?.Skhb3S7hA_MItunWmCjLOo>Dg"L=U~> +endstream +endobj +493 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 492 0 R +>> +endobj +494 0 obj +<< /Length 1086 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GauHKb>R(K']%q&]IS)]Z"1tbg/Z&+1^nd868tai;%hskM%shS%"DX[.9S'Zh9p0rML=hZpYKt%pIDpg;=CdQ=S!SaNpTpi+Z?c*[W]S=@b.V>m.F@$80M;i$4-.>_LTNPF*J6t"O:t`^o&!e!pTDlQK'QJY^cm"bj:/Qq:94rrA]ZVJ+<&W_O"]Jjt&R%ITiL>"eWd(4PL*$ran-g+\s`kW'XKrJSo'0US_2J6=74848O%Tr7\nJ58tVI-_?Mc5C+iH)h*#/U%4"HAs4;.A[:V=&'e(5O!cSe(($M_B)TYYbof8HH$U$*0?U!d_`SUBTqI9Yj@7Q;8lH,Q>ujfXoFro37TROQE+#6B>VP,Mfd"ns/Z4co6a6uqX1DS+ll5TTu-2CSFrcL<-38WG9NRrlrID:UW/]eF#MB*bOLu@E,'FGY,^OUL_[`pR9o7jT>)%+YS>*g*".[9JCrD1+dEV/s6),@9p<+Q]\i4,B[e5Ju4:d0rCJ[i>Y^@NLeJo\P.,%.miaep?HB'pK`@>K/VM/76b5-K)7-M7I2#HNVfl75pZCegNZS]daT;qgP"YO*FDP\hf>r=@Ie>I2[hOdN8:sqlg+/Cn"8^WmbZ'n@C/Ir2Pc,H[rE!.c*,q7=7\86HfO:L"AiF)pn#<^'0:Cm9*,fB<@-Kj&g3?lk/'"_62"Ka\u=_[ctL^hZ_hUNjo_lWO.hVio2/aLl]&n&&-/382N.h(jT&L=[KWmkSHHJY(AQlj1+H``7Up$M&:fQGh"&XachXT'YTD;1?FVr#>Gph(1GG@IS?ImQ*:pmpX39=sWYbH>9m6TajQKBFJ`kF5_*B8Y)Y"Yd/HnLa\/gH^)!Q;odG83^Z(rO^a20&F!5iLN6ukr6.,XG[~> +endstream +endobj +495 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 494 0 R +>> +endobj +496 0 obj +<< /Length 1498 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau0C968iG&AII3n.rXb0Eg9L:3C;ISOo]DV=[Z03\UkDW$tX,_k-MPG&QbuQsBQ^Qb2P2qTE&l"HUC_:cWS1BBF#3nZl^`fXjFfhc>%t9>.JLraBNApD[:JKeVkGNG.-35Y/lp2/Bh8r!hL<)?Q=bSr-k)5_$63G13";qB_Cn=,6;COtRchH%'S>.Jg,e&jjUEd[L?\dNl;ugrgKXe=5pb13qPi^p5TJ3RH%TA`?(&.66H+E8I59ldAdq+mT@b2I(8g\&G1c3JL7s\K3>'5EcnV&B;,pF7I_B&M%kZ7[H&r/P@/9cTJQ9srI'Hp]XcXf!i/]!].R_e%TGRC:_kVN5E3Em]r9bobCIR6o]hMmi]'t-FYO,pGN=T.n$(&HY0Nai2aisEF-Pk+F!':6;Q_*WDhkWG*#&%/_Dm'l[LlM*UVk%/@9d]'EQQWMY1mrPfHF_N&B_M)c4&IT\e;=>K)5:q?:kJ.?;*q$_kZI\@74A'aXOR;$&V)dWHd8F&k@*ZlKJ<*$(2XH2HBE\rkc`(#Mt-ROZ3\bhZKWuHp[l2qlS0+SU,mVK)rT0``S[g"jK>WqpKiNBi"a0:(9#U~> +endstream +endobj +497 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 496 0 R +>> +endobj +498 0 obj +<< /Length 1017 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gat%">Ar4L'Ro4Hj:+/XDO`[&DbmF`BhY!Q+Pe*iBhF#O(*TQ8U$BCbSXUW5BIdCK-g*RX0?9]+PDlZZ?jF9YFct:rFk.f$\FKkFkUC-I4V0n,ffFU0#=b$rcGc"ZTcL%.g7)]+*`>:iQeKK;r'ai7-Ig%;&UDWXf^iRRh(?>%n0BcfS`H4$\R)':A'&D(?lQCfO2YrkHE,Mpg8uJ_+@H^>$l9$V-dHH`)r2c/,fK7>i*uaa'a%J/J\[qASi6d1[HkW%g-`^]4\pV?!jNo+8l!kd323?(iB\"[FnB-$^KoWC:X0;c'S3KD)QGM?]0TgJD:um:XV[?#s'dl<"Bee2X`ssf@N<*=HshD.JQ(?o`n'D8qj\lZ0]>15LdD+RL\AVlgX93%kOItK]Y"Q,%"X6fLON7BJo(.>"A-V+rD$<:55JS+C>>m!(M+IcTe>=^mqJ3-UgLZ$\V&KE%\n4I<,NT5YZE\FJf(s(m0I~> +endstream +endobj +499 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 498 0 R +>> +endobj +500 0 obj +<< /Length 1658 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatUtgMZ%0&;KZF'Y6tg<\'crb#a%PWU6BDcIRaX4,De=d/V4go_=,upAiMTrrT<7u#8U/XV^[N^O#KY;]-1#QIj@oK:*Q*f;@.EoMZt+pmA2GHk\rsBpR<0MgOG,lLDp9o"%OMaB9>JtL?AJfJ^;<]&jSl7:/WC-2,;7/nc*F;".h7rnQ_XCJ]LmR*'#R`Y!p(iR,\TgCV9Y%4u]!`]!^]/P6+%Sb!MGY"aN"/2KTdn$E//IK[qOt""&.nTC]QW1TrDGPN2p2)4%9i,44s'%,6@D:We&8_2R\ffLp9e_E@t+/P8E&)j("0'Tna)(_k#Q\<,8G.LW00]iR*(bSM\rP&$Bhe4uJiKdP?ctKhnAHL;f@`\NL\f/gT-C804QXsP;NO9ur-^cM5)ZCA#%DsOAZObp353is5bKe&?a018=7jq?\0ub4TDJd]WuV,2b][Ie][AR`.4b0=lDjDCL&4lCQVCGVd!SUk,b^J`aOE0OM=`%>aNfU@.UC\4hE9j\bUuBAObMrZf_lkVB]!dthl)3GL..aHi180b@YCDF+m;a'H]$`Yo4.L"OYQZpJ^$NW-3(9Kcp\G$O^@&B[lng,+#ou+UqlnN^R$-"0>hAd=V76<[\1?l8'@&V0ED.JKs!d,Ub)jc8/rlM&-?H)=9+hm.#D,;D6okR_.'sY]YH^Y3T2t8&0*d-I%6m"hbi$GUimW\i7f(*r1iPcBcBf(Y0J4@-$,1mg,E.!CZXP1,PYH>Q:JA3t&`MSCNV?AkU,&25lGk8u#rFWJJnq).RSP9,0\sK&ZkrjA?g]P:k=5-WV~> +endstream +endobj +501 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 500 0 R +/Annots 502 0 R +>> +endobj +502 0 obj +[ +] +endobj +503 0 obj +<< /Length 1657 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gat=lgMYb8&;KZP'YKBU7c>E!"F:fU"aWAsXsj]M>"PeE0!hA?\52"E7%:LfHANh:?o\&.T)P/RQQOh'+22;(i@CM%pNLn+\0G,dIn3').aMY)9M;('PgC)F71>iM^TV<:*`H%>ZFR#mU8WjUG2@"(h9bn=YPR;t]p53/^\1S1%T)eSQ5HeV"@.+)KaS0]aClPnIX_;,=cLY^6?#<7fA&-,[usrVnj,;.'F4K0Erf?)H\-F5(2YA$[r5#_naqA#d@tY!8]aEJajXb=lE)]QkYV'[>OHOB2^#Z'3#:PcL>&>C[en)9`h"'u`0/5sIRO]8NNSr,b9-'P4`R5:3;gE[?T_FAi\mP9sEa3"lQQgT$Zla3)u`VU>A7X.=tb"8UIO-Oh6Hd'*`hqG98i?Y#*s86G.F=BVdPjgUUAV+u]C@`=4EoLTQ.r&kt]%TkRF=Wo0^mqT>LKO;''KG95mSMh=I;+,A^1oAg81rL8d:0i0WN$;^9m@Z1/Y"!1CUBFNg@sT3+Jr,"mS=G5KAPU1r+VpRK<=3^nZTC)m\NF%0(cjTi6=LP6qWXeO)n.`EQR@I0/NRjn\O1c_lL[aYMkOKuj:mNG5B"uJ5d1f/V)H&p*33Lmm\#=]k9:6@inU,7`,'95d)S*\2u;]:D'7b3826-Z90sC#Y3XQKYMXi@a/(4g4UF(_*+V$4>r_sea]/u\VGQ,9r/t<-Id+K)kZA.f@H/Y2T2F$-TF'nbhJ+a8Na3lJhLQ(tm]UPFLQTC5G+^BV_F8c38Z%7?H[7`UVN,J8F)>HG]93tg'fac`[`B`7Cc9DagO[GL%KDL]Fs+n54"R3-epq*I/hK/.MCpD%f.ahcS+GTPbejLh:_'M-2>1.[]>gt51UJ\Qg)@;BblTnqrpus@]+2!fiuAjfB5RNHUmHF0"BM_n^[P^mOUGk=gQd$V-/e&oqiYN7Sk@>j6(LWN2R@OYc`udhoSTn+TS+cJYdG[BkRQ2X$KoB_id%AJeg0&s+!>RNVP/!E.r%:G;VB37+4I60@H<;?7.(p&'%QP:\"#Q:hJF&V3P,Y`csg-;J0bd=00J%;EY>]P.2We_2_h[X20ph5.?+MbPD?4;L2DIm'%PQgW(8ZHj@@/i%p>55@5N[98!5V'=XSM%0(&#=CI:lm"q)+`"grjb,qL'g-gB%f.?J^U\:nT+'^)^e&s[=/MGDL:^iM_8Yn/d&e4m;icuJ^WJB[h#]a]]FD.,qMkqnDKb)QNm9nSg2\`/2j4Jd+2S?Zm_(B]"2-aHGVF6<%*VA +endstream +endobj +504 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 503 0 R +/Annots 505 0 R +>> +endobj +505 0 obj +[ +] +endobj +506 0 obj +<< /Length 1695 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gasb]9on$e&;KZQ'fm[,lP70&ko-2qg04TeQ_GmARBkA.77Es;h>[9![_*f>e5F@6$1nYJR?tg:GJEN'0AfoadVYH>W_Jp%2^h8B+-^_\rf8;:76K7oPJ=g?5Q3Z84V"dd<8DRNq"VT$8PZ!.&NJZLG0Dd>cl[X4:N*>H1+G7uVI!X;WC,S0XLmhJVH&\X,a0]9mm1T_l;``_kf189M4tf/%OPe>^_g-j_'(^];b77>"S-#cAVs;k2eqA3f7n8u&J<>\U".iS@meOJY%6@G)H_,ohMceJD&P6*qXOkG7'?+9jj$(g6.&=D1;MfumlBV"VMT9r&ndTW&OASH.PdqWU@`*C((Y#9T0eUnelK)fObm@oT%=@3$0mH+1Yt+Z-%k7Ql#b^3\`YW0GDUqbuP6)jn)ia;VUGa&$?4`':!8f/cnM&Jm3P,_J(3)mGF&t<+^SgfOg-an*Q>ibBC$(+Ph*t8X!.9n*nT[ss2-M5h;ibeVd@F%MM*md5FQ(:l=D*k,J6/b;os*oV$CDtBpJP>kW4#ajqBDi7d>E!M2@)UrFeT]8Tfbp02Y5jWN`%::c?+/6NGTQX>QKO:2(bI:*c0"['O']@b2Apg:r#I:(^r4iW"YK69'c5s>]Am)JmI>d!rI*.P]^1Z]-e;s4;7"KVdURhLj-A!j2V;baUJ(3)XXmFl?XjsG[e5CrPFSH@@Ne(fTtfo?hg&2MI0R]NdTg^&G#28[FXGR7R"1m96c?bnsu/WAkR&,7i[IA9U^A^'(1E471Q/sT6EU)%IbSN.P1*,Z!6cXp0mqj,oXg"LK0#;XePgnV%h;mNP\R[R4T^@C"b"==IjFJ;:Wl=o-aoaPA0Z35c-]?(dC@d&UbZ2::H`hT9$m<3-h\#8S+7?2hj*.j:Uk,kjgae1-U+,)QBTO'dfAZt0P$q)5M%hg1\iS)60^G4T#I]$1dB?d9nEYO+Wi"ll#1P>B(.,Mh**[&$^&K$T#I#;(uVJ,~> +endstream +endobj +507 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 506 0 R +/Annots 508 0 R +>> +endobj +508 0 obj +[ +] +endobj +509 0 obj +<< /Length 338 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GasJN9hPRC&;KZL'm"1WdnDOmfP@14hLpE8GUPIS(Y^P0/u\g,m"]1SbEcC"nifhrRB/PUh'bPJ"?pH"p'a7*JKTdW0U^s!,5M`O]bZBbLq;7ti>B^LA9#?pRp%O`K.pP$faAlT[6\G_>b$^3WrhAKSumF@/L,.0a/%a/qt"^K?2-PJ1W7hF:'ka;=.BIrk*"pIp.LXQ~> +endstream +endobj +510 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 509 0 R +/Annots 511 0 R +>> +endobj +511 0 obj +[ +] +endobj +514 0 obj +<< + /Title (\376\377\0\123\0\161\0\165\0\151\0\162\0\162\0\145\0\154\0\40\0\62\0\56\0\62\0\40\0\122\0\145\0\146\0\145\0\162\0\145\0\156\0\143\0\145\0\40\0\115\0\141\0\156\0\165\0\141\0\154) + /Parent 512 0 R + /Next 516 0 R + /A 513 0 R +>> endobj +516 0 obj +<< + /Title (\376\377\0\124\0\141\0\142\0\154\0\145\0\40\0\157\0\146\0\40\0\103\0\157\0\156\0\164\0\145\0\156\0\164\0\163) + /Parent 512 0 R + /Prev 514 0 R + /Next 517 0 R + /A 515 0 R +>> endobj +517 0 obj +<< + /Title (\376\377\0\103\0\150\0\141\0\160\0\164\0\145\0\162\0\240\0\61\0\56\0\240\0\111\0\156\0\164\0\162\0\157\0\144\0\165\0\143\0\164\0\151\0\157\0\156) + /Parent 512 0 R + /Prev 516 0 R + /Next 518 0 R + /A 15 0 R +>> endobj +518 0 obj +<< + /Title (\376\377\0\103\0\150\0\141\0\160\0\164\0\145\0\162\0\240\0\62\0\56\0\240\0\124\0\150\0\145\0\40\0\154\0\141\0\156\0\147\0\165\0\141\0\147\0\145) + /Parent 512 0 R + /First 519 0 R + /Last 654 0 R + /Prev 517 0 R + /Next 681 0 R + /Count -128 + /A 17 0 R +>> endobj +519 0 obj +<< + /Title (\376\377\0\114\0\145\0\170\0\151\0\143\0\141\0\154\0\40\0\163\0\164\0\162\0\165\0\143\0\164\0\165\0\162\0\145) + /Parent 518 0 R + /First 520 0 R + /Last 525 0 R + /Next 526 0 R + /Count -6 + /A 19 0 R +>> endobj +520 0 obj +<< + /Title (\376\377\0\111\0\144\0\145\0\156\0\164\0\151\0\146\0\151\0\145\0\162\0\163) + /Parent 519 0 R + /Next 521 0 R + /A 21 0 R +>> endobj +521 0 obj +<< + /Title (\376\377\0\113\0\145\0\171\0\167\0\157\0\162\0\144\0\163) + /Parent 519 0 R + /Prev 520 0 R + /Next 522 0 R + /A 23 0 R +>> endobj +522 0 obj +<< + /Title (\376\377\0\117\0\160\0\145\0\162\0\141\0\164\0\157\0\162\0\163) + /Parent 519 0 R + /Prev 521 0 R + /Next 523 0 R + /A 25 0 R +>> endobj +523 0 obj +<< + /Title (\376\377\0\117\0\164\0\150\0\145\0\162\0\40\0\164\0\157\0\153\0\145\0\156\0\163) + /Parent 519 0 R + /Prev 522 0 R + /Next 524 0 R + /A 27 0 R +>> endobj +524 0 obj +<< + /Title (\376\377\0\114\0\151\0\164\0\145\0\162\0\141\0\154\0\163) + /Parent 519 0 R + /Prev 523 0 R + /Next 525 0 R + /A 29 0 R +>> endobj +525 0 obj +<< + /Title (\376\377\0\103\0\157\0\155\0\155\0\145\0\156\0\164\0\163) + /Parent 519 0 R + /Prev 524 0 R + /A 31 0 R +>> endobj +526 0 obj +<< + /Title (\376\377\0\126\0\141\0\154\0\165\0\145\0\163\0\40\0\141\0\156\0\144\0\40\0\104\0\141\0\164\0\141\0\40\0\164\0\171\0\160\0\145\0\163) + /Parent 518 0 R + /First 527 0 R + /Last 540 0 R + /Prev 519 0 R + /Next 541 0 R + /Count -14 + /A 33 0 R +>> endobj +527 0 obj +<< + /Title (\376\377\0\111\0\156\0\164\0\145\0\147\0\145\0\162) + /Parent 526 0 R + /Next 528 0 R + /A 35 0 R +>> endobj +528 0 obj +<< + /Title (\376\377\0\106\0\154\0\157\0\141\0\164) + /Parent 526 0 R + /Prev 527 0 R + /Next 529 0 R + /A 37 0 R +>> endobj +529 0 obj +<< + /Title (\376\377\0\123\0\164\0\162\0\151\0\156\0\147) + /Parent 526 0 R + /Prev 528 0 R + /Next 530 0 R + /A 39 0 R +>> endobj +530 0 obj +<< + /Title (\376\377\0\116\0\165\0\154\0\154) + /Parent 526 0 R + /Prev 529 0 R + /Next 531 0 R + /A 41 0 R +>> endobj +531 0 obj +<< + /Title (\376\377\0\102\0\157\0\157\0\154) + /Parent 526 0 R + /Prev 530 0 R + /Next 532 0 R + /A 43 0 R +>> endobj +532 0 obj +<< + /Title (\376\377\0\124\0\141\0\142\0\154\0\145) + /Parent 526 0 R + /Prev 531 0 R + /Next 533 0 R + /A 45 0 R +>> endobj +533 0 obj +<< + /Title (\376\377\0\101\0\162\0\162\0\141\0\171) + /Parent 526 0 R + /Prev 532 0 R + /Next 534 0 R + /A 47 0 R +>> endobj +534 0 obj +<< + /Title (\376\377\0\106\0\165\0\156\0\143\0\164\0\151\0\157\0\156) + /Parent 526 0 R + /Prev 533 0 R + /Next 535 0 R + /A 49 0 R +>> endobj +535 0 obj +<< + /Title (\376\377\0\103\0\154\0\141\0\163\0\163) + /Parent 526 0 R + /Prev 534 0 R + /Next 536 0 R + /A 51 0 R +>> endobj +536 0 obj +<< + /Title (\376\377\0\103\0\154\0\141\0\163\0\163\0\40\0\151\0\156\0\163\0\164\0\141\0\156\0\143\0\145) + /Parent 526 0 R + /Prev 535 0 R + /Next 537 0 R + /A 53 0 R +>> endobj +537 0 obj +<< + /Title (\376\377\0\107\0\145\0\156\0\145\0\162\0\141\0\164\0\157\0\162) + /Parent 526 0 R + /Prev 536 0 R + /Next 538 0 R + /A 55 0 R +>> endobj +538 0 obj +<< + /Title (\376\377\0\125\0\163\0\145\0\162\0\144\0\141\0\164\0\141) + /Parent 526 0 R + /Prev 537 0 R + /Next 539 0 R + /A 57 0 R +>> endobj +539 0 obj +<< + /Title (\376\377\0\124\0\150\0\162\0\145\0\141\0\144) + /Parent 526 0 R + /Prev 538 0 R + /Next 540 0 R + /A 59 0 R +>> endobj +540 0 obj +<< + /Title (\376\377\0\127\0\145\0\141\0\153\0\40\0\122\0\145\0\146\0\145\0\162\0\145\0\156\0\143\0\145\0\163) + /Parent 526 0 R + /Prev 539 0 R + /A 61 0 R +>> endobj +541 0 obj +<< + /Title (\376\377\0\105\0\170\0\145\0\143\0\165\0\164\0\151\0\157\0\156\0\40\0\103\0\157\0\156\0\164\0\145\0\170\0\164) + /Parent 518 0 R + /First 542 0 R + /Last 542 0 R + /Prev 526 0 R + /Next 543 0 R + /Count -1 + /A 63 0 R +>> endobj +542 0 obj +<< + /Title (\376\377\0\126\0\141\0\162\0\151\0\141\0\142\0\154\0\145\0\163) + /Parent 541 0 R + /A 65 0 R +>> endobj +543 0 obj +<< + /Title (\376\377\0\123\0\164\0\141\0\164\0\145\0\155\0\145\0\156\0\164\0\163) + /Parent 518 0 R + /First 544 0 R + /Last 572 0 R + /Prev 541 0 R + /Next 573 0 R + /Count -22 + /A 67 0 R +>> endobj +544 0 obj +<< + /Title (\376\377\0\102\0\154\0\157\0\143\0\153) + /Parent 543 0 R + /Next 545 0 R + /A 69 0 R +>> endobj +545 0 obj +<< + /Title (\376\377\0\103\0\157\0\156\0\164\0\162\0\157\0\154\0\40\0\106\0\154\0\157\0\167\0\40\0\123\0\164\0\141\0\164\0\145\0\155\0\145\0\156\0\164\0\163) + /Parent 543 0 R + /First 547 0 R + /Last 555 0 R + /Prev 544 0 R + /Next 556 0 R + /Count -5 + /A 71 0 R +>> endobj +547 0 obj +<< + /Title (\376\377\0\164\0\162\0\165\0\145\0\40\0\141\0\156\0\144\0\40\0\146\0\141\0\154\0\163\0\145) + /Parent 545 0 R + /Next 549 0 R + /A 546 0 R +>> endobj +549 0 obj +<< + /Title (\376\377\0\151\0\146\0\57\0\145\0\154\0\163\0\145) + /Parent 545 0 R + /Prev 547 0 R + /Next 551 0 R + /A 548 0 R +>> endobj +551 0 obj +<< + /Title (\376\377\0\167\0\150\0\151\0\154\0\145) + /Parent 545 0 R + /Prev 549 0 R + /Next 553 0 R + /A 550 0 R +>> endobj +553 0 obj +<< + /Title (\376\377\0\144\0\157\0\57\0\167\0\150\0\151\0\154\0\145) + /Parent 545 0 R + /Prev 551 0 R + /Next 555 0 R + /A 552 0 R +>> endobj +555 0 obj +<< + /Title (\376\377\0\163\0\167\0\151\0\164\0\143\0\150) + /Parent 545 0 R + /Prev 553 0 R + /A 554 0 R +>> endobj +556 0 obj +<< + /Title (\376\377\0\114\0\157\0\157\0\160\0\163) + /Parent 543 0 R + /First 558 0 R + /Last 560 0 R + /Prev 545 0 R + /Next 561 0 R + /Count -2 + /A 73 0 R +>> endobj +558 0 obj +<< + /Title (\376\377\0\146\0\157\0\162) + /Parent 556 0 R + /Next 560 0 R + /A 557 0 R +>> endobj +560 0 obj +<< + /Title (\376\377\0\146\0\157\0\162\0\145\0\141\0\143\0\150) + /Parent 556 0 R + /Prev 558 0 R + /A 559 0 R +>> endobj +561 0 obj +<< + /Title (\376\377\0\142\0\162\0\145\0\141\0\153) + /Parent 543 0 R + /Prev 556 0 R + /Next 562 0 R + /A 75 0 R +>> endobj +562 0 obj +<< + /Title (\376\377\0\143\0\157\0\156\0\164\0\151\0\156\0\165\0\145) + /Parent 543 0 R + /Prev 561 0 R + /Next 563 0 R + /A 77 0 R +>> endobj +563 0 obj +<< + /Title (\376\377\0\162\0\145\0\164\0\165\0\162\0\156) + /Parent 543 0 R + /Prev 562 0 R + /Next 564 0 R + /A 79 0 R +>> endobj +564 0 obj +<< + /Title (\376\377\0\171\0\151\0\145\0\154\0\144) + /Parent 543 0 R + /Prev 563 0 R + /Next 565 0 R + /A 81 0 R +>> endobj +565 0 obj +<< + /Title (\376\377\0\114\0\157\0\143\0\141\0\154\0\40\0\166\0\141\0\162\0\151\0\141\0\142\0\154\0\145\0\163\0\40\0\144\0\145\0\143\0\154\0\141\0\162\0\141\0\164\0\151\0\157\0\156) + /Parent 543 0 R + /Prev 564 0 R + /Next 566 0 R + /A 83 0 R +>> endobj +566 0 obj +<< + /Title (\376\377\0\106\0\165\0\156\0\143\0\164\0\151\0\157\0\156\0\40\0\144\0\145\0\143\0\154\0\141\0\162\0\141\0\164\0\151\0\157\0\156) + /Parent 543 0 R + /Prev 565 0 R + /Next 567 0 R + /A 85 0 R +>> endobj +567 0 obj +<< + /Title (\376\377\0\103\0\154\0\141\0\163\0\163\0\40\0\144\0\145\0\143\0\154\0\141\0\162\0\141\0\164\0\151\0\157\0\156) + /Parent 543 0 R + /Prev 566 0 R + /Next 568 0 R + /A 87 0 R +>> endobj +568 0 obj +<< + /Title (\376\377\0\164\0\162\0\171\0\57\0\143\0\141\0\164\0\143\0\150) + /Parent 543 0 R + /Prev 567 0 R + /Next 569 0 R + /A 89 0 R +>> endobj +569 0 obj +<< + /Title (\376\377\0\164\0\150\0\162\0\157\0\167) + /Parent 543 0 R + /Prev 568 0 R + /Next 570 0 R + /A 91 0 R +>> endobj +570 0 obj +<< + /Title (\376\377\0\143\0\157\0\156\0\163\0\164) + /Parent 543 0 R + /Prev 569 0 R + /Next 571 0 R + /A 93 0 R +>> endobj +571 0 obj +<< + /Title (\376\377\0\145\0\156\0\165\0\155) + /Parent 543 0 R + /Prev 570 0 R + /Next 572 0 R + /A 95 0 R +>> endobj +572 0 obj +<< + /Title (\376\377\0\145\0\170\0\160\0\162\0\145\0\163\0\163\0\151\0\157\0\156\0\40\0\163\0\164\0\141\0\164\0\145\0\155\0\145\0\156\0\164) + /Parent 543 0 R + /Prev 571 0 R + /A 97 0 R +>> endobj +573 0 obj +<< + /Title (\376\377\0\105\0\170\0\160\0\162\0\145\0\163\0\163\0\151\0\157\0\156\0\163) + /Parent 518 0 R + /First 574 0 R + /Last 599 0 R + /Prev 543 0 R + /Next 600 0 R + /Count -16 + /A 99 0 R +>> endobj +574 0 obj +<< + /Title (\376\377\0\101\0\163\0\163\0\151\0\147\0\156\0\155\0\145\0\156\0\164\0\50\0\75\0\51\0\40\0\46\0\40\0\156\0\145\0\167\0\40\0\163\0\154\0\157\0\164\0\50\0\74\0\55\0\51) + /Parent 573 0 R + /Next 575 0 R + /A 101 0 R +>> endobj +575 0 obj +<< + /Title (\376\377\0\117\0\160\0\145\0\162\0\141\0\164\0\157\0\162\0\163) + /Parent 573 0 R + /First 577 0 R + /Last 595 0 R + /Prev 574 0 R + /Next 596 0 R + /Count -10 + /A 103 0 R +>> endobj +577 0 obj +<< + /Title (\376\377\0\77\0\72\0\40\0\117\0\160\0\145\0\162\0\141\0\164\0\157\0\162) + /Parent 575 0 R + /Next 579 0 R + /A 576 0 R +>> endobj +579 0 obj +<< + /Title (\376\377\0\101\0\162\0\151\0\164\0\150\0\155\0\145\0\164\0\151\0\143) + /Parent 575 0 R + /Prev 577 0 R + /Next 581 0 R + /A 578 0 R +>> endobj +581 0 obj +<< + /Title (\376\377\0\122\0\145\0\154\0\141\0\164\0\151\0\157\0\156\0\141\0\154) + /Parent 575 0 R + /Prev 579 0 R + /Next 583 0 R + /A 580 0 R +>> endobj +583 0 obj +<< + /Title (\376\377\0\114\0\157\0\147\0\151\0\143\0\141\0\154) + /Parent 575 0 R + /Prev 581 0 R + /Next 585 0 R + /A 582 0 R +>> endobj +585 0 obj +<< + /Title (\376\377\0\151\0\156\0\40\0\157\0\160\0\145\0\162\0\141\0\164\0\157\0\162) + /Parent 575 0 R + /Prev 583 0 R + /Next 587 0 R + /A 584 0 R +>> endobj +587 0 obj +<< + /Title (\376\377\0\151\0\156\0\163\0\164\0\141\0\156\0\143\0\145\0\157\0\146\0\40\0\157\0\160\0\145\0\162\0\141\0\164\0\157\0\162) + /Parent 575 0 R + /Prev 585 0 R + /Next 589 0 R + /A 586 0 R +>> endobj +589 0 obj +<< + /Title (\376\377\0\164\0\171\0\160\0\145\0\157\0\146\0\40\0\157\0\160\0\145\0\162\0\141\0\164\0\157\0\162) + /Parent 575 0 R + /Prev 587 0 R + /Next 591 0 R + /A 588 0 R +>> endobj +591 0 obj +<< + /Title (\376\377\0\143\0\157\0\155\0\155\0\141\0\40\0\157\0\160\0\145\0\162\0\141\0\164\0\157\0\162) + /Parent 575 0 R + /Prev 589 0 R + /Next 593 0 R + /A 590 0 R +>> endobj +593 0 obj +<< + /Title (\376\377\0\102\0\151\0\164\0\167\0\151\0\163\0\145\0\40\0\117\0\160\0\145\0\162\0\141\0\164\0\157\0\162\0\163) + /Parent 575 0 R + /Prev 591 0 R + /Next 595 0 R + /A 592 0 R +>> endobj +595 0 obj +<< + /Title (\376\377\0\117\0\160\0\145\0\162\0\141\0\164\0\157\0\162\0\163\0\40\0\160\0\162\0\145\0\143\0\145\0\144\0\145\0\156\0\143\0\145) + /Parent 575 0 R + /Prev 593 0 R + /A 594 0 R +>> endobj +596 0 obj +<< + /Title (\376\377\0\124\0\141\0\142\0\154\0\145\0\40\0\143\0\157\0\156\0\163\0\164\0\162\0\165\0\143\0\164\0\157\0\162) + /Parent 573 0 R + /Prev 575 0 R + /Next 597 0 R + /A 105 0 R +>> endobj +597 0 obj +<< + /Title (\376\377\0\144\0\145\0\154\0\145\0\147\0\141\0\164\0\145) + /Parent 573 0 R + /Prev 596 0 R + /Next 598 0 R + /A 107 0 R +>> endobj +598 0 obj +<< + /Title (\376\377\0\143\0\154\0\157\0\156\0\145) + /Parent 573 0 R + /Prev 597 0 R + /Next 599 0 R + /A 109 0 R +>> endobj +599 0 obj +<< + /Title (\376\377\0\101\0\162\0\162\0\141\0\171\0\40\0\143\0\157\0\156\0\163\0\164\0\162\0\165\0\143\0\164\0\157\0\162) + /Parent 573 0 R + /Prev 598 0 R + /A 111 0 R +>> endobj +600 0 obj +<< + /Title (\376\377\0\124\0\141\0\142\0\154\0\145\0\163) + /Parent 518 0 R + /First 601 0 R + /Last 603 0 R + /Prev 573 0 R + /Next 604 0 R + /Count -3 + /A 113 0 R +>> endobj +601 0 obj +<< + /Title (\376\377\0\103\0\157\0\156\0\163\0\164\0\162\0\165\0\143\0\164\0\151\0\157\0\156) + /Parent 600 0 R + /Next 602 0 R + /A 115 0 R +>> endobj +602 0 obj +<< + /Title (\376\377\0\123\0\154\0\157\0\164\0\40\0\143\0\162\0\145\0\141\0\164\0\151\0\157\0\156) + /Parent 600 0 R + /Prev 601 0 R + /Next 603 0 R + /A 117 0 R +>> endobj +603 0 obj +<< + /Title (\376\377\0\123\0\154\0\157\0\164\0\40\0\144\0\145\0\154\0\145\0\164\0\151\0\157\0\156) + /Parent 600 0 R + /Prev 602 0 R + /A 119 0 R +>> endobj +604 0 obj +<< + /Title (\376\377\0\101\0\162\0\162\0\141\0\171\0\163) + /Parent 518 0 R + /Prev 600 0 R + /Next 605 0 R + /A 124 0 R +>> endobj +605 0 obj +<< + /Title (\376\377\0\106\0\165\0\156\0\143\0\164\0\151\0\157\0\156\0\163) + /Parent 518 0 R + /First 606 0 R + /Last 614 0 R + /Prev 604 0 R + /Next 615 0 R + /Count -7 + /A 126 0 R +>> endobj +606 0 obj +<< + /Title (\376\377\0\106\0\165\0\156\0\143\0\164\0\151\0\157\0\156\0\40\0\144\0\145\0\143\0\154\0\141\0\162\0\141\0\164\0\151\0\157\0\156) + /Parent 605 0 R + /First 608 0 R + /Last 610 0 R + /Next 611 0 R + /Count -2 + /A 128 0 R +>> endobj +608 0 obj +<< + /Title (\376\377\0\104\0\145\0\146\0\141\0\165\0\154\0\164\0\40\0\120\0\141\0\162\0\141\0\155\0\141\0\164\0\145\0\162\0\163) + /Parent 606 0 R + /Next 610 0 R + /A 607 0 R +>> endobj +610 0 obj +<< + /Title (\376\377\0\106\0\165\0\156\0\143\0\164\0\151\0\157\0\156\0\40\0\167\0\151\0\164\0\150\0\40\0\166\0\141\0\162\0\151\0\141\0\142\0\154\0\145\0\40\0\156\0\165\0\155\0\142\0\145\0\162\0\40\0\157\0\146\0\40\0\160\0\141\0\162\0\141\0\155\0\141\0\164\0\145\0\162\0\163) + /Parent 606 0 R + /Prev 608 0 R + /A 609 0 R +>> endobj +611 0 obj +<< + /Title (\376\377\0\106\0\165\0\156\0\143\0\164\0\151\0\157\0\156\0\40\0\143\0\141\0\154\0\154\0\163) + /Parent 605 0 R + /Prev 606 0 R + /Next 612 0 R + /A 130 0 R +>> endobj +612 0 obj +<< + /Title (\376\377\0\102\0\151\0\156\0\144\0\151\0\156\0\147\0\40\0\141\0\156\0\40\0\145\0\156\0\166\0\151\0\162\0\157\0\156\0\155\0\145\0\156\0\164\0\40\0\164\0\157\0\40\0\141\0\40\0\146\0\165\0\156\0\143\0\164\0\151\0\157\0\156) + /Parent 605 0 R + /Prev 611 0 R + /Next 613 0 R + /A 132 0 R +>> endobj +613 0 obj +<< + /Title (\376\377\0\106\0\162\0\145\0\145\0\40\0\166\0\141\0\162\0\151\0\141\0\142\0\154\0\145\0\163) + /Parent 605 0 R + /Prev 612 0 R + /Next 614 0 R + /A 134 0 R +>> endobj +614 0 obj +<< + /Title (\376\377\0\124\0\141\0\151\0\154\0\40\0\162\0\145\0\143\0\165\0\162\0\163\0\151\0\157\0\156) + /Parent 605 0 R + /Prev 613 0 R + /A 136 0 R +>> endobj +615 0 obj +<< + /Title (\376\377\0\103\0\154\0\141\0\163\0\163\0\145\0\163) + /Parent 518 0 R + /First 616 0 R + /Last 623 0 R + /Prev 605 0 R + /Next 624 0 R + /Count -6 + /A 138 0 R +>> endobj +616 0 obj +<< + /Title (\376\377\0\103\0\154\0\141\0\163\0\163\0\40\0\144\0\145\0\143\0\154\0\141\0\162\0\141\0\164\0\151\0\157\0\156) + /Parent 615 0 R + /First 618 0 R + /Last 620 0 R + /Next 621 0 R + /Count -2 + /A 140 0 R +>> endobj +618 0 obj +<< + /Title (\376\377\0\123\0\164\0\141\0\164\0\151\0\143\0\40\0\166\0\141\0\162\0\151\0\141\0\142\0\154\0\145\0\163) + /Parent 616 0 R + /Next 620 0 R + /A 617 0 R +>> endobj +620 0 obj +<< + /Title (\376\377\0\103\0\154\0\141\0\163\0\163\0\40\0\141\0\164\0\164\0\162\0\151\0\142\0\165\0\164\0\145\0\163) + /Parent 616 0 R + /Prev 618 0 R + /A 619 0 R +>> endobj +621 0 obj +<< + /Title (\376\377\0\103\0\154\0\141\0\163\0\163\0\40\0\151\0\156\0\163\0\164\0\141\0\156\0\143\0\145\0\163) + /Parent 615 0 R + /Prev 616 0 R + /Next 622 0 R + /A 142 0 R +>> endobj +622 0 obj +<< + /Title (\376\377\0\111\0\156\0\150\0\145\0\162\0\151\0\164\0\141\0\156\0\143\0\145) + /Parent 615 0 R + /Prev 621 0 R + /Next 623 0 R + /A 144 0 R +>> endobj +623 0 obj +<< + /Title (\376\377\0\115\0\145\0\164\0\141\0\155\0\145\0\164\0\150\0\157\0\144\0\163) + /Parent 615 0 R + /Prev 622 0 R + /A 146 0 R +>> endobj +624 0 obj +<< + /Title (\376\377\0\107\0\145\0\156\0\145\0\162\0\141\0\164\0\157\0\162\0\163) + /Parent 518 0 R + /Prev 615 0 R + /Next 625 0 R + /A 148 0 R +>> endobj +625 0 obj +<< + /Title (\376\377\0\103\0\157\0\156\0\163\0\164\0\141\0\156\0\164\0\163\0\40\0\46\0\40\0\105\0\156\0\165\0\155\0\145\0\162\0\141\0\164\0\151\0\157\0\156\0\163) + /Parent 518 0 R + /First 626 0 R + /Last 628 0 R + /Prev 624 0 R + /Next 629 0 R + /Count -3 + /A 150 0 R +>> endobj +626 0 obj +<< + /Title (\376\377\0\103\0\157\0\156\0\163\0\164\0\141\0\156\0\164\0\163) + /Parent 625 0 R + /Next 627 0 R + /A 152 0 R +>> endobj +627 0 obj +<< + /Title (\376\377\0\105\0\156\0\165\0\155\0\145\0\162\0\141\0\164\0\151\0\157\0\156\0\163) + /Parent 625 0 R + /Prev 626 0 R + /Next 628 0 R + /A 154 0 R +>> endobj +628 0 obj +<< + /Title (\376\377\0\111\0\155\0\160\0\154\0\145\0\155\0\145\0\156\0\164\0\141\0\164\0\151\0\157\0\156\0\40\0\156\0\157\0\164\0\145\0\163) + /Parent 625 0 R + /Prev 627 0 R + /A 156 0 R +>> endobj +629 0 obj +<< + /Title (\376\377\0\124\0\150\0\162\0\145\0\141\0\144\0\163) + /Parent 518 0 R + /First 630 0 R + /Last 630 0 R + /Prev 625 0 R + /Next 631 0 R + /Count -1 + /A 158 0 R +>> endobj +630 0 obj +<< + /Title (\376\377\0\125\0\163\0\151\0\156\0\147\0\40\0\164\0\150\0\162\0\145\0\141\0\144\0\163) + /Parent 629 0 R + /A 160 0 R +>> endobj +631 0 obj +<< + /Title (\376\377\0\127\0\145\0\141\0\153\0\40\0\122\0\145\0\146\0\145\0\162\0\145\0\156\0\143\0\145\0\163) + /Parent 518 0 R + /First 633 0 R + /Last 633 0 R + /Prev 629 0 R + /Next 634 0 R + /Count -1 + /A 162 0 R +>> endobj +633 0 obj +<< + /Title (\376\377\0\110\0\141\0\156\0\144\0\154\0\151\0\156\0\147\0\40\0\167\0\145\0\141\0\153\0\40\0\162\0\145\0\146\0\145\0\162\0\145\0\156\0\143\0\145\0\163\0\40\0\145\0\170\0\160\0\154\0\151\0\143\0\151\0\164\0\154\0\171) + /Parent 631 0 R + /A 632 0 R +>> endobj +634 0 obj +<< + /Title (\376\377\0\104\0\145\0\154\0\145\0\147\0\141\0\164\0\151\0\157\0\156) + /Parent 518 0 R + /Prev 631 0 R + /Next 635 0 R + /A 164 0 R +>> endobj +635 0 obj +<< + /Title (\376\377\0\115\0\145\0\164\0\141\0\155\0\145\0\164\0\150\0\157\0\144\0\163) + /Parent 518 0 R + /First 636 0 R + /Last 653 0 R + /Prev 634 0 R + /Next 654 0 R + /Count -18 + /A 166 0 R +>> endobj +636 0 obj +<< + /Title (\376\377\0\137\0\163\0\145\0\164) + /Parent 635 0 R + /Next 637 0 R + /A 168 0 R +>> endobj +637 0 obj +<< + /Title (\376\377\0\137\0\147\0\145\0\164) + /Parent 635 0 R + /Prev 636 0 R + /Next 638 0 R + /A 170 0 R +>> endobj +638 0 obj +<< + /Title (\376\377\0\137\0\156\0\145\0\167\0\163\0\154\0\157\0\164) + /Parent 635 0 R + /Prev 637 0 R + /Next 639 0 R + /A 172 0 R +>> endobj +639 0 obj +<< + /Title (\376\377\0\137\0\144\0\145\0\154\0\163\0\154\0\157\0\164) + /Parent 635 0 R + /Prev 638 0 R + /Next 640 0 R + /A 174 0 R +>> endobj +640 0 obj +<< + /Title (\376\377\0\137\0\141\0\144\0\144) + /Parent 635 0 R + /Prev 639 0 R + /Next 641 0 R + /A 176 0 R +>> endobj +641 0 obj +<< + /Title (\376\377\0\137\0\163\0\165\0\142) + /Parent 635 0 R + /Prev 640 0 R + /Next 642 0 R + /A 178 0 R +>> endobj +642 0 obj +<< + /Title (\376\377\0\137\0\155\0\165\0\154) + /Parent 635 0 R + /Prev 641 0 R + /Next 643 0 R + /A 180 0 R +>> endobj +643 0 obj +<< + /Title (\376\377\0\137\0\144\0\151\0\166) + /Parent 635 0 R + /Prev 642 0 R + /Next 644 0 R + /A 182 0 R +>> endobj +644 0 obj +<< + /Title (\376\377\0\137\0\155\0\157\0\144\0\165\0\154\0\157) + /Parent 635 0 R + /Prev 643 0 R + /Next 645 0 R + /A 184 0 R +>> endobj +645 0 obj +<< + /Title (\376\377\0\137\0\165\0\156\0\155) + /Parent 635 0 R + /Prev 644 0 R + /Next 646 0 R + /A 186 0 R +>> endobj +646 0 obj +<< + /Title (\376\377\0\137\0\164\0\171\0\160\0\145\0\157\0\146) + /Parent 635 0 R + /Prev 645 0 R + /Next 647 0 R + /A 188 0 R +>> endobj +647 0 obj +<< + /Title (\376\377\0\137\0\143\0\155\0\160) + /Parent 635 0 R + /Prev 646 0 R + /Next 648 0 R + /A 190 0 R +>> endobj +648 0 obj +<< + /Title (\376\377\0\137\0\143\0\141\0\154\0\154) + /Parent 635 0 R + /Prev 647 0 R + /Next 649 0 R + /A 192 0 R +>> endobj +649 0 obj +<< + /Title (\376\377\0\137\0\143\0\154\0\157\0\156\0\145\0\144) + /Parent 635 0 R + /Prev 648 0 R + /Next 650 0 R + /A 194 0 R +>> endobj +650 0 obj +<< + /Title (\376\377\0\137\0\156\0\145\0\170\0\164\0\151) + /Parent 635 0 R + /Prev 649 0 R + /Next 651 0 R + /A 196 0 R +>> endobj +651 0 obj +<< + /Title (\376\377\0\137\0\164\0\157\0\163\0\164\0\162\0\151\0\156\0\147) + /Parent 635 0 R + /Prev 650 0 R + /Next 652 0 R + /A 198 0 R +>> endobj +652 0 obj +<< + /Title (\376\377\0\137\0\151\0\156\0\150\0\145\0\162\0\151\0\164\0\145\0\144) + /Parent 635 0 R + /Prev 651 0 R + /Next 653 0 R + /A 200 0 R +>> endobj +653 0 obj +<< + /Title (\376\377\0\137\0\156\0\145\0\167\0\155\0\145\0\155\0\142\0\145\0\162) + /Parent 635 0 R + /Prev 652 0 R + /A 202 0 R +>> endobj +654 0 obj +<< + /Title (\376\377\0\102\0\165\0\151\0\154\0\164\0\55\0\151\0\156\0\40\0\146\0\165\0\156\0\143\0\164\0\151\0\157\0\156\0\163) + /Parent 518 0 R + /First 655 0 R + /Last 656 0 R + /Prev 635 0 R + /Count -14 + /A 204 0 R +>> endobj +655 0 obj +<< + /Title (\376\377\0\107\0\154\0\157\0\142\0\141\0\154\0\40\0\163\0\171\0\155\0\142\0\157\0\154\0\163) + /Parent 654 0 R + /Next 656 0 R + /A 206 0 R +>> endobj +656 0 obj +<< + /Title (\376\377\0\104\0\145\0\146\0\141\0\165\0\154\0\164\0\40\0\144\0\145\0\154\0\145\0\147\0\141\0\164\0\145\0\163) + /Parent 654 0 R + /First 658 0 R + /Last 680 0 R + /Prev 655 0 R + /Count -12 + /A 208 0 R +>> endobj +658 0 obj +<< + /Title (\376\377\0\111\0\156\0\164\0\145\0\147\0\145\0\162) + /Parent 656 0 R + /Next 660 0 R + /A 657 0 R +>> endobj +660 0 obj +<< + /Title (\376\377\0\106\0\154\0\157\0\141\0\164) + /Parent 656 0 R + /Prev 658 0 R + /Next 662 0 R + /A 659 0 R +>> endobj +662 0 obj +<< + /Title (\376\377\0\102\0\157\0\157\0\154) + /Parent 656 0 R + /Prev 660 0 R + /Next 664 0 R + /A 661 0 R +>> endobj +664 0 obj +<< + /Title (\376\377\0\123\0\164\0\162\0\151\0\156\0\147) + /Parent 656 0 R + /Prev 662 0 R + /Next 666 0 R + /A 663 0 R +>> endobj +666 0 obj +<< + /Title (\376\377\0\124\0\141\0\142\0\154\0\145) + /Parent 656 0 R + /Prev 664 0 R + /Next 668 0 R + /A 665 0 R +>> endobj +668 0 obj +<< + /Title (\376\377\0\101\0\162\0\162\0\141\0\171) + /Parent 656 0 R + /Prev 666 0 R + /Next 670 0 R + /A 667 0 R +>> endobj +670 0 obj +<< + /Title (\376\377\0\106\0\165\0\156\0\143\0\164\0\151\0\157\0\156) + /Parent 656 0 R + /Prev 668 0 R + /Next 672 0 R + /A 669 0 R +>> endobj +672 0 obj +<< + /Title (\376\377\0\103\0\154\0\141\0\163\0\163) + /Parent 656 0 R + /Prev 670 0 R + /Next 674 0 R + /A 671 0 R +>> endobj +674 0 obj +<< + /Title (\376\377\0\103\0\154\0\141\0\163\0\163\0\40\0\111\0\156\0\163\0\164\0\141\0\156\0\143\0\145) + /Parent 656 0 R + /Prev 672 0 R + /Next 676 0 R + /A 673 0 R +>> endobj +676 0 obj +<< + /Title (\376\377\0\107\0\145\0\156\0\145\0\162\0\141\0\164\0\157\0\162) + /Parent 656 0 R + /Prev 674 0 R + /Next 678 0 R + /A 675 0 R +>> endobj +678 0 obj +<< + /Title (\376\377\0\124\0\150\0\162\0\145\0\141\0\144) + /Parent 656 0 R + /Prev 676 0 R + /Next 680 0 R + /A 677 0 R +>> endobj +680 0 obj +<< + /Title (\376\377\0\127\0\145\0\141\0\153\0\40\0\122\0\145\0\146\0\145\0\162\0\145\0\156\0\143\0\145) + /Parent 656 0 R + /Prev 678 0 R + /A 679 0 R +>> endobj +681 0 obj +<< + /Title (\376\377\0\103\0\150\0\141\0\160\0\164\0\145\0\162\0\240\0\63\0\56\0\240\0\105\0\155\0\142\0\145\0\144\0\144\0\151\0\156\0\147\0\40\0\123\0\161\0\165\0\151\0\162\0\162\0\145\0\154) + /Parent 512 0 R + /First 682 0 R + /Last 699 0 R + /Prev 518 0 R + /Next 700 0 R + /Count -18 + /A 210 0 R +>> endobj +682 0 obj +<< + /Title (\376\377\0\115\0\145\0\155\0\157\0\162\0\171\0\40\0\155\0\141\0\156\0\141\0\147\0\145\0\155\0\145\0\156\0\164) + /Parent 681 0 R + /Next 683 0 R + /A 212 0 R +>> endobj +683 0 obj +<< + /Title (\376\377\0\125\0\156\0\151\0\143\0\157\0\144\0\145) + /Parent 681 0 R + /Prev 682 0 R + /Next 684 0 R + /A 214 0 R +>> endobj +684 0 obj +<< + /Title (\376\377\0\123\0\161\0\165\0\151\0\162\0\162\0\145\0\154\0\40\0\157\0\156\0\40\0\66\0\64\0\40\0\142\0\151\0\164\0\163\0\40\0\141\0\162\0\143\0\150\0\151\0\164\0\145\0\143\0\164\0\165\0\162\0\145\0\163) + /Parent 681 0 R + /Prev 683 0 R + /Next 685 0 R + /A 216 0 R +>> endobj +685 0 obj +<< + /Title (\376\377\0\123\0\161\0\165\0\151\0\162\0\162\0\145\0\154\0\40\0\167\0\151\0\164\0\150\0\40\0\144\0\157\0\165\0\142\0\154\0\145\0\40\0\160\0\162\0\145\0\143\0\151\0\163\0\151\0\157\0\156\0\40\0\146\0\154\0\157\0\141\0\164\0\163) + /Parent 681 0 R + /Prev 684 0 R + /Next 686 0 R + /A 218 0 R +>> endobj +686 0 obj +<< + /Title (\376\377\0\105\0\162\0\162\0\157\0\162\0\40\0\143\0\157\0\156\0\166\0\145\0\156\0\164\0\151\0\157\0\156\0\163) + /Parent 681 0 R + /Prev 685 0 R + /Next 687 0 R + /A 220 0 R +>> endobj +687 0 obj +<< + /Title (\376\377\0\111\0\156\0\151\0\164\0\151\0\141\0\154\0\151\0\172\0\151\0\156\0\147\0\40\0\123\0\161\0\165\0\151\0\162\0\162\0\145\0\154) + /Parent 681 0 R + /Prev 686 0 R + /Next 688 0 R + /A 222 0 R +>> endobj +688 0 obj +<< + /Title (\376\377\0\124\0\150\0\145\0\40\0\123\0\164\0\141\0\143\0\153) + /Parent 681 0 R + /First 689 0 R + /Last 690 0 R + /Prev 687 0 R + /Next 691 0 R + /Count -2 + /A 224 0 R +>> endobj +689 0 obj +<< + /Title (\376\377\0\123\0\164\0\141\0\143\0\153\0\40\0\151\0\156\0\144\0\145\0\170\0\145\0\163) + /Parent 688 0 R + /Next 690 0 R + /A 226 0 R +>> endobj +690 0 obj +<< + /Title (\376\377\0\123\0\164\0\141\0\143\0\153\0\40\0\155\0\141\0\156\0\151\0\160\0\165\0\154\0\141\0\164\0\151\0\157\0\156) + /Parent 688 0 R + /Prev 689 0 R + /A 228 0 R +>> endobj +691 0 obj +<< + /Title (\376\377\0\122\0\165\0\156\0\164\0\151\0\155\0\145\0\40\0\145\0\162\0\162\0\157\0\162\0\40\0\150\0\141\0\156\0\144\0\154\0\151\0\156\0\147) + /Parent 681 0 R + /Prev 688 0 R + /Next 692 0 R + /A 230 0 R +>> endobj +692 0 obj +<< + /Title (\376\377\0\103\0\157\0\155\0\160\0\151\0\154\0\151\0\156\0\147\0\40\0\141\0\40\0\163\0\143\0\162\0\151\0\160\0\164) + /Parent 681 0 R + /Prev 691 0 R + /Next 693 0 R + /A 232 0 R +>> endobj +693 0 obj +<< + /Title (\376\377\0\103\0\141\0\154\0\154\0\151\0\156\0\147\0\40\0\141\0\40\0\146\0\165\0\156\0\143\0\164\0\151\0\157\0\156) + /Parent 681 0 R + /Prev 692 0 R + /Next 694 0 R + /A 234 0 R +>> endobj +694 0 obj +<< + /Title (\376\377\0\103\0\162\0\145\0\141\0\164\0\145\0\40\0\141\0\40\0\103\0\40\0\146\0\165\0\156\0\143\0\164\0\151\0\157\0\156) + /Parent 681 0 R + /Prev 693 0 R + /Next 695 0 R + /A 236 0 R +>> endobj +695 0 obj +<< + /Title (\376\377\0\124\0\141\0\142\0\154\0\145\0\163\0\40\0\141\0\156\0\144\0\40\0\141\0\162\0\162\0\141\0\171\0\163\0\40\0\155\0\141\0\156\0\151\0\160\0\165\0\154\0\141\0\164\0\151\0\157\0\156) + /Parent 681 0 R + /Prev 694 0 R + /Next 696 0 R + /A 238 0 R +>> endobj +696 0 obj +<< + /Title (\376\377\0\125\0\163\0\145\0\162\0\144\0\141\0\164\0\141\0\40\0\141\0\156\0\144\0\40\0\125\0\163\0\145\0\162\0\120\0\157\0\151\0\156\0\164\0\145\0\162\0\163) + /Parent 681 0 R + /Prev 695 0 R + /Next 697 0 R + /A 243 0 R +>> endobj +697 0 obj +<< + /Title (\376\377\0\124\0\150\0\145\0\40\0\162\0\145\0\147\0\151\0\163\0\164\0\162\0\171\0\40\0\164\0\141\0\142\0\154\0\145) + /Parent 681 0 R + /Prev 696 0 R + /Next 698 0 R + /A 245 0 R +>> endobj +698 0 obj +<< + /Title (\376\377\0\115\0\141\0\156\0\164\0\141\0\151\0\156\0\151\0\156\0\147\0\40\0\163\0\164\0\162\0\157\0\156\0\147\0\40\0\162\0\145\0\146\0\145\0\162\0\145\0\156\0\143\0\145\0\163\0\40\0\164\0\157\0\40\0\123\0\161\0\165\0\151\0\162\0\162\0\145\0\154\0\40\0\166\0\141\0\154\0\165\0\145\0\163\0\40\0\146\0\162\0\157\0\155\0\40\0\164\0\150\0\145\0\40\0\103\0\40\0\101\0\120\0\111) + /Parent 681 0 R + /Prev 697 0 R + /Next 699 0 R + /A 247 0 R +>> endobj +699 0 obj +<< + /Title (\376\377\0\104\0\145\0\142\0\165\0\147\0\40\0\111\0\156\0\164\0\145\0\162\0\146\0\141\0\143\0\145) + /Parent 681 0 R + /Prev 698 0 R + /A 249 0 R +>> endobj +700 0 obj +<< + /Title (\376\377\0\103\0\150\0\141\0\160\0\164\0\145\0\162\0\240\0\64\0\56\0\240\0\101\0\120\0\111\0\40\0\122\0\145\0\146\0\145\0\162\0\145\0\156\0\143\0\145) + /Parent 512 0 R + /First 701 0 R + /Last 709 0 R + /Prev 681 0 R + /Next 710 0 R + /Count -9 + /A 251 0 R +>> endobj +701 0 obj +<< + /Title (\376\377\0\126\0\151\0\162\0\164\0\165\0\141\0\154\0\40\0\115\0\141\0\143\0\150\0\151\0\156\0\145) + /Parent 700 0 R + /Next 702 0 R + /A 253 0 R +>> endobj +702 0 obj +<< + /Title (\376\377\0\103\0\157\0\155\0\160\0\151\0\154\0\145\0\162) + /Parent 700 0 R + /Prev 701 0 R + /Next 703 0 R + /A 255 0 R +>> endobj +703 0 obj +<< + /Title (\376\377\0\123\0\164\0\141\0\143\0\153\0\40\0\117\0\160\0\145\0\162\0\141\0\164\0\151\0\157\0\156\0\163) + /Parent 700 0 R + /Prev 702 0 R + /Next 704 0 R + /A 257 0 R +>> endobj +704 0 obj +<< + /Title (\376\377\0\117\0\142\0\152\0\145\0\143\0\164\0\40\0\143\0\162\0\145\0\141\0\164\0\151\0\157\0\156\0\40\0\141\0\156\0\144\0\40\0\150\0\141\0\156\0\144\0\154\0\151\0\156\0\147) + /Parent 700 0 R + /Prev 703 0 R + /Next 705 0 R + /A 259 0 R +>> endobj +705 0 obj +<< + /Title (\376\377\0\103\0\141\0\154\0\154\0\163) + /Parent 700 0 R + /Prev 704 0 R + /Next 706 0 R + /A 261 0 R +>> endobj +706 0 obj +<< + /Title (\376\377\0\117\0\142\0\152\0\145\0\143\0\164\0\163\0\40\0\155\0\141\0\156\0\151\0\160\0\165\0\154\0\141\0\164\0\151\0\157\0\156) + /Parent 700 0 R + /Prev 705 0 R + /Next 707 0 R + /A 263 0 R +>> endobj +707 0 obj +<< + /Title (\376\377\0\102\0\171\0\164\0\145\0\143\0\157\0\144\0\145\0\40\0\163\0\145\0\162\0\151\0\141\0\154\0\151\0\172\0\141\0\164\0\151\0\157\0\156) + /Parent 700 0 R + /Prev 706 0 R + /Next 708 0 R + /A 265 0 R +>> endobj +708 0 obj +<< + /Title (\376\377\0\122\0\141\0\167\0\40\0\157\0\142\0\152\0\145\0\143\0\164\0\40\0\150\0\141\0\156\0\144\0\154\0\151\0\156\0\147) + /Parent 700 0 R + /Prev 707 0 R + /Next 709 0 R + /A 267 0 R +>> endobj +709 0 obj +<< + /Title (\376\377\0\104\0\145\0\142\0\165\0\147\0\40\0\151\0\156\0\164\0\145\0\162\0\146\0\141\0\143\0\145) + /Parent 700 0 R + /Prev 708 0 R + /A 269 0 R +>> endobj +710 0 obj +<< + /Title (\376\377\0\111\0\156\0\144\0\145\0\170) + /Parent 512 0 R + /Prev 700 0 R + /A 271 0 R +>> endobj +711 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F11 +/BaseFont /Courier-Bold +/Encoding /WinAnsiEncoding >> +endobj +712 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F1 +/BaseFont /Helvetica +/Encoding /WinAnsiEncoding >> +endobj +713 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F10 +/BaseFont /Courier-Oblique +/Encoding /WinAnsiEncoding >> +endobj +714 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F5 +/BaseFont /Times-Roman +/Encoding /WinAnsiEncoding >> +endobj +715 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F3 +/BaseFont /Helvetica-Bold +/Encoding /WinAnsiEncoding >> +endobj +716 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F9 +/BaseFont /Courier +/Encoding /WinAnsiEncoding >> +endobj +717 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F6 +/BaseFont /Times-Italic +/Encoding /WinAnsiEncoding >> +endobj +718 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F7 +/BaseFont /Times-Bold +/Encoding /WinAnsiEncoding >> +endobj +1 0 obj +<< /Type /Pages +/Count 104 +/Kids [6 0 R 8 0 R 10 0 R 12 0 R 121 0 R 240 0 R 273 0 R 275 0 R 277 0 R 279 0 R 281 0 R 283 0 R 298 0 R 300 0 R 302 0 R 304 0 R 306 0 R 310 0 R 316 0 R 321 0 R 323 0 R 325 0 R 330 0 R 338 0 R 343 0 R 345 0 R 347 0 R 349 0 R 351 0 R 353 0 R 357 0 R 361 0 R 363 0 R 367 0 R 369 0 R 371 0 R 373 0 R 375 0 R 377 0 R 379 0 R 381 0 R 383 0 R 385 0 R 387 0 R 389 0 R 391 0 R 393 0 R 395 0 R 397 0 R 399 0 R 401 0 R 403 0 R 405 0 R 407 0 R 409 0 R 411 0 R 413 0 R 415 0 R 417 0 R 419 0 R 421 0 R 423 0 R 425 0 R 427 0 R 429 0 R 431 0 R 433 0 R 435 0 R 437 0 R 439 0 R 441 0 R 443 0 R 445 0 R 447 0 R 449 0 R 451 0 R 453 0 R 455 0 R 457 0 R 459 0 R 461 0 R 463 0 R 465 0 R 467 0 R 469 0 R 471 0 R 473 0 R 475 0 R 477 0 R 479 0 R 481 0 R 483 0 R 485 0 R 487 0 R 489 0 R 491 0 R 493 0 R 495 0 R 497 0 R 499 0 R 501 0 R 504 0 R 507 0 R 510 0 R ] >> +endobj +2 0 obj +<< /Type /Catalog +/Pages 1 0 R + /Outlines 512 0 R + /PageMode /UseOutlines + >> +endobj +3 0 obj +<< +/Font << /F1 712 0 R /F11 711 0 R /F10 713 0 R /F5 714 0 R /F3 715 0 R /F9 716 0 R /F6 717 0 R /F7 718 0 R >> +/ProcSet [ /PDF /ImageC /Text ] >> +endobj +15 0 obj +<< +/S /GoTo +/D [273 0 R /XYZ 115.0 725.0 null] +>> +endobj +17 0 obj +<< +/S /GoTo +/D [275 0 R /XYZ 115.0 725.0 null] +>> +endobj +19 0 obj +<< +/S /GoTo +/D [275 0 R /XYZ 115.0 666.009 null] +>> +endobj +21 0 obj +<< +/S /GoTo +/D [275 0 R /XYZ 115.0 632.684 null] +>> +endobj +23 0 obj +<< +/S /GoTo +/D [275 0 R /XYZ 115.0 519.385 null] +>> +endobj +25 0 obj +<< +/S /GoTo +/D [275 0 R /XYZ 115.0 337.946 null] +>> +endobj +27 0 obj +<< +/S /GoTo +/D [275 0 R /XYZ 115.0 207.507 null] +>> +endobj +29 0 obj +<< +/S /GoTo +/D [275 0 R /XYZ 115.0 122.068 null] +>> +endobj +31 0 obj +<< +/S /GoTo +/D [277 0 R /XYZ 115.0 433.98 null] +>> +endobj +33 0 obj +<< +/S /GoTo +/D [277 0 R /XYZ 115.0 139.361 null] +>> +endobj +35 0 obj +<< +/S /GoTo +/D [279 0 R /XYZ 115.0 693.0 null] +>> +endobj +37 0 obj +<< +/S /GoTo +/D [279 0 R /XYZ 115.0 563.401 null] +>> +endobj +39 0 obj +<< +/S /GoTo +/D [279 0 R /XYZ 115.0 453.522 null] +>> +endobj +41 0 obj +<< +/S /GoTo +/D [279 0 R /XYZ 115.0 148.763 null] +>> +endobj +43 0 obj +<< +/S /GoTo +/D [281 0 R /XYZ 115.0 675.42 null] +>> +endobj +45 0 obj +<< +/S /GoTo +/D [281 0 R /XYZ 115.0 564.401 null] +>> +endobj +47 0 obj +<< +/S /GoTo +/D [281 0 R /XYZ 115.0 415.082 null] +>> +endobj +49 0 obj +<< +/S /GoTo +/D [281 0 R /XYZ 115.0 295.343 null] +>> +endobj +51 0 obj +<< +/S /GoTo +/D [281 0 R /XYZ 115.0 233.904 null] +>> +endobj +53 0 obj +<< +/S /GoTo +/D [281 0 R /XYZ 115.0 161.465 null] +>> +endobj +55 0 obj +<< +/S /GoTo +/D [283 0 R /XYZ 115.0 725.0 null] +>> +endobj +57 0 obj +<< +/S /GoTo +/D [283 0 R /XYZ 115.0 673.561 null] +>> +endobj +59 0 obj +<< +/S /GoTo +/D [283 0 R /XYZ 115.0 612.122 null] +>> +endobj +61 0 obj +<< +/S /GoTo +/D [283 0 R /XYZ 115.0 561.683 null] +>> +endobj +63 0 obj +<< +/S /GoTo +/D [283 0 R /XYZ 115.0 500.244 null] +>> +endobj +65 0 obj +<< +/S /GoTo +/D [283 0 R /XYZ 115.0 379.919 null] +>> +endobj +67 0 obj +<< +/S /GoTo +/D [300 0 R /XYZ 115.0 725.0 null] +>> +endobj +69 0 obj +<< +/S /GoTo +/D [300 0 R /XYZ 115.0 585.815 null] +>> +endobj +71 0 obj +<< +/S /GoTo +/D [300 0 R /XYZ 115.0 505.516 null] +>> +endobj +73 0 obj +<< +/S /GoTo +/D [302 0 R /XYZ 115.0 169.088 null] +>> +endobj +75 0 obj +<< +/S /GoTo +/D [304 0 R /XYZ 115.0 328.304 null] +>> +endobj +77 0 obj +<< +/S /GoTo +/D [304 0 R /XYZ 115.0 237.005 null] +>> +endobj +79 0 obj +<< +/S /GoTo +/D [304 0 R /XYZ 115.0 145.706 null] +>> +endobj +81 0 obj +<< +/S /GoTo +/D [306 0 R /XYZ 115.0 682.0 null] +>> +endobj +83 0 obj +<< +/S /GoTo +/D [306 0 R /XYZ 115.0 601.701 null] +>> +endobj +85 0 obj +<< +/S /GoTo +/D [306 0 R /XYZ 115.0 410.382 null] +>> +endobj +87 0 obj +<< +/S /GoTo +/D [306 0 R /XYZ 115.0 300.503 null] +>> +endobj +89 0 obj +<< +/S /GoTo +/D [306 0 R /XYZ 115.0 170.904 null] +>> +endobj +91 0 obj +<< +/S /GoTo +/D [310 0 R /XYZ 115.0 704.0 null] +>> +endobj +93 0 obj +<< +/S /GoTo +/D [310 0 R /XYZ 115.0 623.701 null] +>> +endobj +95 0 obj +<< +/S /GoTo +/D [310 0 R /XYZ 115.0 533.542 null] +>> +endobj +97 0 obj +<< +/S /GoTo +/D [310 0 R /XYZ 115.0 403.943 null] +>> +endobj +99 0 obj +<< +/S /GoTo +/D [310 0 R /XYZ 115.0 312.644 null] +>> +endobj +101 0 obj +<< +/S /GoTo +/D [310 0 R /XYZ 115.0 279.319 null] +>> +endobj +103 0 obj +<< +/S /GoTo +/D [316 0 R /XYZ 115.0 693.0 null] +>> +endobj +105 0 obj +<< +/S /GoTo +/D [323 0 R /XYZ 115.0 275.338 null] +>> +endobj +107 0 obj +<< +/S /GoTo +/D [325 0 R /XYZ 115.0 263.64 null] +>> +endobj +109 0 obj +<< +/S /GoTo +/D [325 0 R /XYZ 115.0 172.341 null] +>> +endobj +111 0 obj +<< +/S /GoTo +/D [330 0 R /XYZ 115.0 651.0 null] +>> +endobj +113 0 obj +<< +/S /GoTo +/D [330 0 R /XYZ 115.0 450.541 null] +>> +endobj +115 0 obj +<< +/S /GoTo +/D [330 0 R /XYZ 115.0 363.216 null] +>> +endobj +117 0 obj +<< +/S /GoTo +/D [330 0 R /XYZ 115.0 312.777 null] +>> +endobj +119 0 obj +<< +/S /GoTo +/D [338 0 R /XYZ 115.0 614.7 null] +>> +endobj +124 0 obj +<< +/S /GoTo +/D [338 0 R /XYZ 115.0 414.661 null] +>> +endobj +126 0 obj +<< +/S /GoTo +/D [338 0 R /XYZ 115.0 248.036 null] +>> +endobj +128 0 obj +<< +/S /GoTo +/D [338 0 R /XYZ 115.0 171.711 null] +>> +endobj +130 0 obj +<< +/S /GoTo +/D [345 0 R /XYZ 115.0 441.344 null] +>> +endobj +132 0 obj +<< +/S /GoTo +/D [345 0 R /XYZ 115.0 166.885 null] +>> +endobj +134 0 obj +<< +/S /GoTo +/D [347 0 R /XYZ 115.0 655.866 null] +>> +endobj +136 0 obj +<< +/S /GoTo +/D [347 0 R /XYZ 115.0 443.827 null] +>> +endobj +138 0 obj +<< +/S /GoTo +/D [347 0 R /XYZ 115.0 231.928 null] +>> +endobj +140 0 obj +<< +/S /GoTo +/D [347 0 R /XYZ 115.0 155.603 null] +>> +endobj +142 0 obj +<< +/S /GoTo +/D [353 0 R /XYZ 115.0 370.94 null] +>> +endobj +144 0 obj +<< +/S /GoTo +/D [357 0 R /XYZ 115.0 411.66 null] +>> +endobj +146 0 obj +<< +/S /GoTo +/D [363 0 R /XYZ 115.0 616.26 null] +>> +endobj +148 0 obj +<< +/S /GoTo +/D [363 0 R /XYZ 115.0 191.181 null] +>> +endobj +150 0 obj +<< +/S /GoTo +/D [367 0 R /XYZ 115.0 373.36 null] +>> +endobj +152 0 obj +<< +/S /GoTo +/D [367 0 R /XYZ 115.0 308.035 null] +>> +endobj +154 0 obj +<< +/S /GoTo +/D [369 0 R /XYZ 115.0 634.7 null] +>> +endobj +156 0 obj +<< +/S /GoTo +/D [369 0 R /XYZ 115.0 169.481 null] +>> +endobj +158 0 obj +<< +/S /GoTo +/D [371 0 R /XYZ 115.0 499.68 null] +>> +endobj +160 0 obj +<< +/S /GoTo +/D [371 0 R /XYZ 115.0 379.355 null] +>> +endobj +162 0 obj +<< +/S /GoTo +/D [375 0 R /XYZ 115.0 725.0 null] +>> +endobj +164 0 obj +<< +/S /GoTo +/D [377 0 R /XYZ 115.0 675.42 null] +>> +endobj +166 0 obj +<< +/S /GoTo +/D [377 0 R /XYZ 115.0 338.615 null] +>> +endobj +168 0 obj +<< +/S /GoTo +/D [379 0 R /XYZ 115.0 397.78 null] +>> +endobj +170 0 obj +<< +/S /GoTo +/D [379 0 R /XYZ 115.0 317.481 null] +>> +endobj +172 0 obj +<< +/S /GoTo +/D [379 0 R /XYZ 115.0 237.182 null] +>> +endobj +174 0 obj +<< +/S /GoTo +/D [379 0 R /XYZ 115.0 124.883 null] +>> +endobj +176 0 obj +<< +/S /GoTo +/D [381 0 R /XYZ 115.0 653.14 null] +>> +endobj +178 0 obj +<< +/S /GoTo +/D [381 0 R /XYZ 115.0 572.841 null] +>> +endobj +180 0 obj +<< +/S /GoTo +/D [381 0 R /XYZ 115.0 522.402 null] +>> +endobj +182 0 obj +<< +/S /GoTo +/D [381 0 R /XYZ 115.0 471.963 null] +>> +endobj +184 0 obj +<< +/S /GoTo +/D [381 0 R /XYZ 115.0 421.524 null] +>> +endobj +186 0 obj +<< +/S /GoTo +/D [381 0 R /XYZ 115.0 371.085 null] +>> +endobj +188 0 obj +<< +/S /GoTo +/D [381 0 R /XYZ 115.0 290.786 null] +>> +endobj +190 0 obj +<< +/S /GoTo +/D [381 0 R /XYZ 115.0 210.487 null] +>> +endobj +192 0 obj +<< +/S /GoTo +/D [383 0 R /XYZ 115.0 684.75 null] +>> +endobj +194 0 obj +<< +/S /GoTo +/D [383 0 R /XYZ 115.0 604.451 null] +>> +endobj +196 0 obj +<< +/S /GoTo +/D [383 0 R /XYZ 115.0 524.152 null] +>> +endobj +198 0 obj +<< +/S /GoTo +/D [383 0 R /XYZ 115.0 411.853 null] +>> +endobj +200 0 obj +<< +/S /GoTo +/D [383 0 R /XYZ 115.0 299.554 null] +>> +endobj +202 0 obj +<< +/S /GoTo +/D [383 0 R /XYZ 115.0 187.255 null] +>> +endobj +204 0 obj +<< +/S /GoTo +/D [385 0 R /XYZ 115.0 725.0 null] +>> +endobj +206 0 obj +<< +/S /GoTo +/D [385 0 R /XYZ 115.0 680.675 null] +>> +endobj +208 0 obj +<< +/S /GoTo +/D [387 0 R /XYZ 115.0 167.24 null] +>> +endobj +210 0 obj +<< +/S /GoTo +/D [401 0 R /XYZ 115.0 725.0 null] +>> +endobj +212 0 obj +<< +/S /GoTo +/D [401 0 R /XYZ 115.0 601.009 null] +>> +endobj +214 0 obj +<< +/S /GoTo +/D [401 0 R /XYZ 115.0 343.684 null] +>> +endobj +216 0 obj +<< +/S /GoTo +/D [401 0 R /XYZ 115.0 278.359 null] +>> +endobj +218 0 obj +<< +/S /GoTo +/D [401 0 R /XYZ 115.0 213.034 null] +>> +endobj +220 0 obj +<< +/S /GoTo +/D [401 0 R /XYZ 115.0 136.709 null] +>> +endobj +222 0 obj +<< +/S /GoTo +/D [403 0 R /XYZ 115.0 633.56 null] +>> +endobj +224 0 obj +<< +/S /GoTo +/D [403 0 R /XYZ 115.0 418.775 null] +>> +endobj +226 0 obj +<< +/S /GoTo +/D [403 0 R /XYZ 115.0 331.45 null] +>> +endobj +228 0 obj +<< +/S /GoTo +/D [405 0 R /XYZ 115.0 662.75 null] +>> +endobj +230 0 obj +<< +/S /GoTo +/D [407 0 R /XYZ 115.0 483.82 null] +>> +endobj +232 0 obj +<< +/S /GoTo +/D [407 0 R /XYZ 115.0 323.635 null] +>> +endobj +234 0 obj +<< +/S /GoTo +/D [409 0 R /XYZ 115.0 313.78 null] +>> +endobj +236 0 obj +<< +/S /GoTo +/D [411 0 R /XYZ 115.0 663.14 null] +>> +endobj +238 0 obj +<< +/S /GoTo +/D [413 0 R /XYZ 115.0 161.14 null] +>> +endobj +243 0 obj +<< +/S /GoTo +/D [417 0 R /XYZ 115.0 565.68 null] +>> +endobj +245 0 obj +<< +/S /GoTo +/D [417 0 R /XYZ 115.0 219.335 null] +>> +endobj +247 0 obj +<< +/S /GoTo +/D [419 0 R /XYZ 115.0 725.0 null] +>> +endobj +249 0 obj +<< +/S /GoTo +/D [419 0 R /XYZ 115.0 486.03 null] +>> +endobj +251 0 obj +<< +/S /GoTo +/D [423 0 R /XYZ 115.0 725.0 null] +>> +endobj +253 0 obj +<< +/S /GoTo +/D [423 0 R /XYZ 115.0 687.009 null] +>> +endobj +255 0 obj +<< +/S /GoTo +/D [433 0 R /XYZ 115.0 578.0 null] +>> +endobj +257 0 obj +<< +/S /GoTo +/D [437 0 R /XYZ 115.0 524.14 null] +>> +endobj +259 0 obj +<< +/S /GoTo +/D [441 0 R /XYZ 115.0 422.28 null] +>> +endobj +261 0 obj +<< +/S /GoTo +/D [465 0 R /XYZ 115.0 113.56 null] +>> +endobj +263 0 obj +<< +/S /GoTo +/D [471 0 R /XYZ 115.0 621.0 null] +>> +endobj +265 0 obj +<< +/S /GoTo +/D [489 0 R /XYZ 115.0 328.42 null] +>> +endobj +267 0 obj +<< +/S /GoTo +/D [491 0 R /XYZ 115.0 430.28 null] +>> +endobj +269 0 obj +<< +/S /GoTo +/D [497 0 R /XYZ 115.0 431.14 null] +>> +endobj +271 0 obj +<< +/S /GoTo +/D [501 0 R /XYZ 67.0 725.0 null] +>> +endobj +286 0 obj +<< +/S /GoTo +/D [363 0 R /XYZ 115.0 157.856 null] +>> +endobj +289 0 obj +<< +/S /GoTo +/D [417 0 R /XYZ 115.0 532.355 null] +>> +endobj +291 0 obj +<< +/S /GoTo +/D [375 0 R /XYZ 115.0 701.675 null] +>> +endobj +293 0 obj +<< +/S /GoTo +/D [338 0 R /XYZ 115.0 214.711 null] +>> +endobj +296 0 obj +<< +/S /GoTo +/D [283 0 R /XYZ 115.0 350.48 null] +>> +endobj +313 0 obj +<< +/S /GoTo +/D [367 0 R /XYZ 115.0 340.035 null] +>> +endobj +319 0 obj +<< +/S /GoTo +/D [330 0 R /XYZ 115.0 417.216 null] +>> +endobj +328 0 obj +<< +/S /GoTo +/D [377 0 R /XYZ 115.0 642.095 null] +>> +endobj +334 0 obj +<< +/S /GoTo +/D [377 0 R /XYZ 115.0 305.29 null] +>> +endobj +336 0 obj +<< +/S /GoTo +/D [323 0 R /XYZ 115.0 245.899 null] +>> +endobj +341 0 obj +<< +/S /GoTo +/D [385 0 R /XYZ 115.0 701.675 null] +>> +endobj +512 0 obj +<< + /First 514 0 R + /Last 710 0 R +>> endobj +513 0 obj +<< +/S /GoTo +/D [10 0 R /XYZ 115.0 725.0 null] +>> +endobj +515 0 obj +<< +/S /GoTo +/D [12 0 R /XYZ 115.0 715.0 null] +>> +endobj +546 0 obj +<< +/S /GoTo +/D [300 0 R /XYZ 115.0 444.077 null] +>> +endobj +548 0 obj +<< +/S /GoTo +/D [300 0 R /XYZ 115.0 385.881 null] +>> +endobj +550 0 obj +<< +/S /GoTo +/D [300 0 R /XYZ 115.0 170.505 null] +>> +endobj +552 0 obj +<< +/S /GoTo +/D [302 0 R /XYZ 115.0 566.96 null] +>> +endobj +554 0 obj +<< +/S /GoTo +/D [302 0 R /XYZ 115.0 370.164 null] +>> +endobj +557 0 obj +<< +/S /GoTo +/D [302 0 R /XYZ 115.0 139.649 null] +>> +endobj +559 0 obj +<< +/S /GoTo +/D [304 0 R /XYZ 115.0 545.96 null] +>> +endobj +576 0 obj +<< +/S /GoTo +/D [316 0 R /XYZ 115.0 663.561 null] +>> +endobj +578 0 obj +<< +/S /GoTo +/D [316 0 R /XYZ 115.0 586.505 null] +>> +endobj +580 0 obj +<< +/S /GoTo +/D [316 0 R /XYZ 115.0 345.569 null] +>> +endobj +582 0 obj +<< +/S /GoTo +/D [316 0 R /XYZ 115.0 236.513 null] +>> +endobj +584 0 obj +<< +/S /GoTo +/D [321 0 R /XYZ 115.0 693.0 null] +>> +endobj +586 0 obj +<< +/S /GoTo +/D [321 0 R /XYZ 115.0 476.484 null] +>> +endobj +588 0 obj +<< +/S /GoTo +/D [321 0 R /XYZ 115.0 388.428 null] +>> +endobj +590 0 obj +<< +/S /GoTo +/D [321 0 R /XYZ 115.0 242.072 null] +>> +endobj +592 0 obj +<< +/S /GoTo +/D [323 0 R /XYZ 115.0 675.42 null] +>> +endobj +594 0 obj +<< +/S /GoTo +/D [323 0 R /XYZ 115.0 535.784 null] +>> +endobj +607 0 obj +<< +/S /GoTo +/D [343 0 R /XYZ 115.0 256.9 null] +>> +endobj +609 0 obj +<< +/S /GoTo +/D [345 0 R /XYZ 115.0 703.0 null] +>> +endobj +617 0 obj +<< +/S /GoTo +/D [351 0 R /XYZ 115.0 454.8 null] +>> +endobj +619 0 obj +<< +/S /GoTo +/D [351 0 R /XYZ 115.0 240.87 null] +>> +endobj +632 0 obj +<< +/S /GoTo +/D [375 0 R /XYZ 115.0 288.775 null] +>> +endobj +657 0 obj +<< +/S /GoTo +/D [387 0 R /XYZ 115.0 105.801 null] +>> +endobj +659 0 obj +<< +/S /GoTo +/D [389 0 R /XYZ 115.0 515.0 null] +>> +endobj +661 0 obj +<< +/S /GoTo +/D [389 0 R /XYZ 115.0 278.804 null] +>> +endobj +663 0 obj +<< +/S /GoTo +/D [391 0 R /XYZ 115.0 725.0 null] +>> +endobj +665 0 obj +<< +/S /GoTo +/D [391 0 R /XYZ 115.0 286.804 null] +>> +endobj +667 0 obj +<< +/S /GoTo +/D [393 0 R /XYZ 115.0 535.0 null] +>> +endobj +669 0 obj +<< +/S /GoTo +/D [395 0 R /XYZ 115.0 351.12 null] +>> +endobj +671 0 obj +<< +/S /GoTo +/D [397 0 R /XYZ 115.0 566.0 null] +>> +endobj +673 0 obj +<< +/S /GoTo +/D [397 0 R /XYZ 115.0 243.804 null] +>> +endobj +675 0 obj +<< +/S /GoTo +/D [399 0 R /XYZ 115.0 683.0 null] +>> +endobj +677 0 obj +<< +/S /GoTo +/D [399 0 R /XYZ 115.0 530.804 null] +>> +endobj +679 0 obj +<< +/S /GoTo +/D [399 0 R /XYZ 115.0 283.608 null] +>> +endobj +xref +0 719 +0000000000 65535 f +0000223445 00000 n +0000224325 00000 n +0000224418 00000 n +0000000015 00000 n +0000000071 00000 n +0000000409 00000 n +0000000515 00000 n +0000001708 00000 n +0000001814 00000 n +0000001975 00000 n +0000002082 00000 n +0000003985 00000 n +0000004108 00000 n +0000004509 00000 n +0000224584 00000 n +0000004645 00000 n +0000224650 00000 n +0000004781 00000 n +0000224716 00000 n +0000004917 00000 n +0000224784 00000 n +0000005052 00000 n +0000224852 00000 n +0000005187 00000 n +0000224920 00000 n +0000005323 00000 n +0000224988 00000 n +0000005459 00000 n +0000225056 00000 n +0000005595 00000 n +0000225124 00000 n +0000005731 00000 n +0000225191 00000 n +0000005866 00000 n +0000225259 00000 n +0000006002 00000 n +0000225325 00000 n +0000006138 00000 n +0000225393 00000 n +0000006274 00000 n +0000225461 00000 n +0000006410 00000 n +0000225529 00000 n +0000006546 00000 n +0000225596 00000 n +0000006682 00000 n +0000225664 00000 n +0000006818 00000 n +0000225732 00000 n +0000006954 00000 n +0000225800 00000 n +0000007090 00000 n +0000225868 00000 n +0000007226 00000 n +0000225936 00000 n +0000007362 00000 n +0000226002 00000 n +0000007498 00000 n +0000226070 00000 n +0000007634 00000 n +0000226138 00000 n +0000007770 00000 n +0000226206 00000 n +0000007906 00000 n +0000226274 00000 n +0000008042 00000 n +0000226342 00000 n +0000008178 00000 n +0000226408 00000 n +0000008314 00000 n +0000226476 00000 n +0000008450 00000 n +0000226544 00000 n +0000008585 00000 n +0000226612 00000 n +0000008721 00000 n +0000226680 00000 n +0000008857 00000 n +0000226748 00000 n +0000008993 00000 n +0000226816 00000 n +0000009128 00000 n +0000226882 00000 n +0000009263 00000 n +0000226950 00000 n +0000009399 00000 n +0000227018 00000 n +0000009534 00000 n +0000227086 00000 n +0000009670 00000 n +0000227154 00000 n +0000009806 00000 n +0000227220 00000 n +0000009942 00000 n +0000227288 00000 n +0000010078 00000 n +0000227356 00000 n +0000010213 00000 n +0000227424 00000 n +0000010349 00000 n +0000227492 00000 n +0000010486 00000 n +0000227561 00000 n +0000010624 00000 n +0000227628 00000 n +0000010762 00000 n +0000227697 00000 n +0000010900 00000 n +0000227765 00000 n +0000011038 00000 n +0000227834 00000 n +0000011176 00000 n +0000227901 00000 n +0000011314 00000 n +0000227970 00000 n +0000011451 00000 n +0000228039 00000 n +0000011587 00000 n +0000228108 00000 n +0000011723 00000 n +0000013842 00000 n +0000013968 00000 n +0000014453 00000 n +0000228175 00000 n +0000014587 00000 n +0000228244 00000 n +0000014721 00000 n +0000228313 00000 n +0000014855 00000 n +0000228382 00000 n +0000014989 00000 n +0000228451 00000 n +0000015123 00000 n +0000228520 00000 n +0000015257 00000 n +0000228589 00000 n +0000015391 00000 n +0000228658 00000 n +0000015524 00000 n +0000228727 00000 n +0000015657 00000 n +0000228796 00000 n +0000015791 00000 n +0000228864 00000 n +0000015925 00000 n +0000228932 00000 n +0000016059 00000 n +0000229000 00000 n +0000016193 00000 n +0000229069 00000 n +0000016327 00000 n +0000229137 00000 n +0000016461 00000 n +0000229206 00000 n +0000016595 00000 n +0000229273 00000 n +0000016729 00000 n +0000229342 00000 n +0000016863 00000 n +0000229410 00000 n +0000016997 00000 n +0000229479 00000 n +0000017131 00000 n +0000229546 00000 n +0000017265 00000 n +0000229614 00000 n +0000017399 00000 n +0000229683 00000 n +0000017533 00000 n +0000229751 00000 n +0000017667 00000 n +0000229820 00000 n +0000017801 00000 n +0000229889 00000 n +0000017935 00000 n +0000229958 00000 n +0000018069 00000 n +0000230026 00000 n +0000018203 00000 n +0000230095 00000 n +0000018337 00000 n +0000230164 00000 n +0000018471 00000 n +0000230233 00000 n +0000018605 00000 n +0000230302 00000 n +0000018739 00000 n +0000230371 00000 n +0000018873 00000 n +0000230440 00000 n +0000019007 00000 n +0000230509 00000 n +0000019141 00000 n +0000230577 00000 n +0000019275 00000 n +0000230646 00000 n +0000019408 00000 n +0000230715 00000 n +0000019542 00000 n +0000230784 00000 n +0000019676 00000 n +0000230853 00000 n +0000019810 00000 n +0000230922 00000 n +0000019944 00000 n +0000230989 00000 n +0000020078 00000 n +0000231058 00000 n +0000020211 00000 n +0000231126 00000 n +0000020345 00000 n +0000231193 00000 n +0000020479 00000 n +0000231262 00000 n +0000020613 00000 n +0000231331 00000 n +0000020747 00000 n +0000231400 00000 n +0000020880 00000 n +0000231469 00000 n +0000021014 00000 n +0000231538 00000 n +0000021148 00000 n +0000231606 00000 n +0000021282 00000 n +0000231675 00000 n +0000021416 00000 n +0000231743 00000 n +0000021549 00000 n +0000231811 00000 n +0000021683 00000 n +0000231879 00000 n +0000021817 00000 n +0000231948 00000 n +0000021951 00000 n +0000232016 00000 n +0000022084 00000 n +0000232084 00000 n +0000022216 00000 n +0000023145 00000 n +0000023271 00000 n +0000023412 00000 n +0000232152 00000 n +0000023546 00000 n +0000232220 00000 n +0000023680 00000 n +0000232289 00000 n +0000023814 00000 n +0000232356 00000 n +0000023948 00000 n +0000232424 00000 n +0000024082 00000 n +0000232491 00000 n +0000024216 00000 n +0000232560 00000 n +0000024350 00000 n +0000232627 00000 n +0000024483 00000 n +0000232695 00000 n +0000024617 00000 n +0000232763 00000 n +0000024751 00000 n +0000232831 00000 n +0000024885 00000 n +0000232898 00000 n +0000025019 00000 n +0000232966 00000 n +0000025153 00000 n +0000233034 00000 n +0000025287 00000 n +0000233102 00000 n +0000025421 00000 n +0000026240 00000 n +0000026350 00000 n +0000027969 00000 n +0000028079 00000 n +0000029843 00000 n +0000029953 00000 n +0000031819 00000 n +0000031929 00000 n +0000033579 00000 n +0000033689 00000 n +0000035765 00000 n +0000035891 00000 n +0000035968 00000 n +0000233168 00000 n +0000036107 00000 n +0000036245 00000 n +0000233237 00000 n +0000036384 00000 n +0000233306 00000 n +0000036523 00000 n +0000233375 00000 n +0000036662 00000 n +0000036800 00000 n +0000233444 00000 n +0000036941 00000 n +0000038216 00000 n +0000038326 00000 n +0000040137 00000 n +0000040247 00000 n +0000041778 00000 n +0000041888 00000 n +0000043330 00000 n +0000043440 00000 n +0000045057 00000 n +0000045183 00000 n +0000045212 00000 n +0000045350 00000 n +0000046505 00000 n +0000046631 00000 n +0000046668 00000 n +0000233512 00000 n +0000046807 00000 n +0000046946 00000 n +0000048821 00000 n +0000048947 00000 n +0000048976 00000 n +0000233581 00000 n +0000049113 00000 n +0000050522 00000 n +0000050632 00000 n +0000052334 00000 n +0000052444 00000 n +0000053714 00000 n +0000053840 00000 n +0000053869 00000 n +0000233650 00000 n +0000054008 00000 n +0000055687 00000 n +0000055813 00000 n +0000055858 00000 n +0000055993 00000 n +0000233719 00000 n +0000056128 00000 n +0000233787 00000 n +0000056266 00000 n +0000057781 00000 n +0000057907 00000 n +0000057936 00000 n +0000233856 00000 n +0000058074 00000 n +0000059162 00000 n +0000059272 00000 n +0000061508 00000 n +0000061618 00000 n +0000063920 00000 n +0000064030 00000 n +0000065211 00000 n +0000065321 00000 n +0000067440 00000 n +0000067550 00000 n +0000069922 00000 n +0000070048 00000 n +0000070077 00000 n +0000070216 00000 n +0000072095 00000 n +0000072221 00000 n +0000072250 00000 n +0000072384 00000 n +0000073863 00000 n +0000073973 00000 n +0000076308 00000 n +0000076434 00000 n +0000076463 00000 n +0000076604 00000 n +0000078411 00000 n +0000078521 00000 n +0000080268 00000 n +0000080378 00000 n +0000083220 00000 n +0000083330 00000 n +0000084529 00000 n +0000084639 00000 n +0000086739 00000 n +0000086849 00000 n +0000088915 00000 n +0000089025 00000 n +0000090240 00000 n +0000090350 00000 n +0000091364 00000 n +0000091474 00000 n +0000092935 00000 n +0000093045 00000 n +0000094429 00000 n +0000094539 00000 n +0000096211 00000 n +0000096321 00000 n +0000097225 00000 n +0000097335 00000 n +0000098806 00000 n +0000098916 00000 n +0000100278 00000 n +0000100388 00000 n +0000101962 00000 n +0000102072 00000 n +0000103581 00000 n +0000103691 00000 n +0000104807 00000 n +0000104917 00000 n +0000107731 00000 n +0000107841 00000 n +0000110025 00000 n +0000110135 00000 n +0000111714 00000 n +0000111824 00000 n +0000114108 00000 n +0000114218 00000 n +0000115970 00000 n +0000116080 00000 n +0000118165 00000 n +0000118275 00000 n +0000119785 00000 n +0000119895 00000 n +0000120995 00000 n +0000121105 00000 n +0000123686 00000 n +0000123796 00000 n +0000126058 00000 n +0000126168 00000 n +0000127019 00000 n +0000127129 00000 n +0000128286 00000 n +0000128396 00000 n +0000130048 00000 n +0000130158 00000 n +0000131216 00000 n +0000131326 00000 n +0000132762 00000 n +0000132872 00000 n +0000134354 00000 n +0000134464 00000 n +0000136380 00000 n +0000136490 00000 n +0000138291 00000 n +0000138401 00000 n +0000139631 00000 n +0000139741 00000 n +0000140786 00000 n +0000140896 00000 n +0000142428 00000 n +0000142538 00000 n +0000143844 00000 n +0000143954 00000 n +0000145351 00000 n +0000145461 00000 n +0000146792 00000 n +0000146902 00000 n +0000148038 00000 n +0000148148 00000 n +0000149492 00000 n +0000149602 00000 n +0000151011 00000 n +0000151121 00000 n +0000152210 00000 n +0000152320 00000 n +0000153393 00000 n +0000153503 00000 n +0000155168 00000 n +0000155278 00000 n +0000158122 00000 n +0000158232 00000 n +0000159658 00000 n +0000159768 00000 n +0000161079 00000 n +0000161189 00000 n +0000162925 00000 n +0000163035 00000 n +0000164591 00000 n +0000164701 00000 n +0000166020 00000 n +0000166130 00000 n +0000167285 00000 n +0000167395 00000 n +0000168456 00000 n +0000168566 00000 n +0000170137 00000 n +0000170247 00000 n +0000171589 00000 n +0000171699 00000 n +0000173159 00000 n +0000173269 00000 n +0000175241 00000 n +0000175351 00000 n +0000176708 00000 n +0000176818 00000 n +0000178353 00000 n +0000178463 00000 n +0000180013 00000 n +0000180123 00000 n +0000181563 00000 n +0000181673 00000 n +0000182929 00000 n +0000183039 00000 n +0000184219 00000 n +0000184329 00000 n +0000185921 00000 n +0000186031 00000 n +0000187142 00000 n +0000187252 00000 n +0000189004 00000 n +0000189130 00000 n +0000189151 00000 n +0000190902 00000 n +0000191028 00000 n +0000191049 00000 n +0000192838 00000 n +0000192964 00000 n +0000192985 00000 n +0000193416 00000 n +0000193542 00000 n +0000233925 00000 n +0000233979 00000 n +0000193563 00000 n +0000234045 00000 n +0000193817 00000 n +0000194018 00000 n +0000194254 00000 n +0000194533 00000 n +0000194761 00000 n +0000194912 00000 n +0000195060 00000 n +0000195214 00000 n +0000195385 00000 n +0000195533 00000 n +0000195666 00000 n +0000195932 00000 n +0000196059 00000 n +0000196189 00000 n +0000196325 00000 n +0000196449 00000 n +0000196573 00000 n +0000196703 00000 n +0000196833 00000 n +0000196981 00000 n +0000197111 00000 n +0000197294 00000 n +0000197448 00000 n +0000197596 00000 n +0000197732 00000 n +0000197906 00000 n +0000198149 00000 n +0000198273 00000 n +0000198476 00000 n +0000198591 00000 n +0000234111 00000 n +0000198869 00000 n +0000234180 00000 n +0000199037 00000 n +0000234249 00000 n +0000199179 00000 n +0000234318 00000 n +0000199310 00000 n +0000234386 00000 n +0000199458 00000 n +0000199580 00000 n +0000234455 00000 n +0000199752 00000 n +0000234524 00000 n +0000199856 00000 n +0000199984 00000 n +0000200114 00000 n +0000200262 00000 n +0000200398 00000 n +0000200528 00000 n +0000200788 00000 n +0000201007 00000 n +0000201208 00000 n +0000201361 00000 n +0000201491 00000 n +0000201621 00000 n +0000201745 00000 n +0000201949 00000 n +0000202158 00000 n +0000202401 00000 n +0000234592 00000 n +0000202599 00000 n +0000234661 00000 n +0000202748 00000 n +0000234730 00000 n +0000202909 00000 n +0000234799 00000 n +0000203070 00000 n +0000234868 00000 n +0000203213 00000 n +0000234935 00000 n +0000203379 00000 n +0000235004 00000 n +0000203593 00000 n +0000235073 00000 n +0000203783 00000 n +0000235142 00000 n +0000203967 00000 n +0000235210 00000 n +0000204169 00000 n +0000204374 00000 n +0000204576 00000 n +0000204725 00000 n +0000204856 00000 n +0000205043 00000 n +0000205222 00000 n +0000205380 00000 n +0000205558 00000 n +0000205721 00000 n +0000205858 00000 n +0000206055 00000 n +0000235279 00000 n +0000206302 00000 n +0000235346 00000 n +0000206495 00000 n +0000206834 00000 n +0000207018 00000 n +0000207330 00000 n +0000207514 00000 n +0000207683 00000 n +0000207868 00000 n +0000235413 00000 n +0000208097 00000 n +0000235480 00000 n +0000208278 00000 n +0000208459 00000 n +0000208649 00000 n +0000208816 00000 n +0000208968 00000 n +0000209129 00000 n +0000209413 00000 n +0000209553 00000 n +0000209726 00000 n +0000209931 00000 n +0000210116 00000 n +0000210264 00000 n +0000235548 00000 n +0000210496 00000 n +0000210774 00000 n +0000210935 00000 n +0000211145 00000 n +0000211255 00000 n +0000211380 00000 n +0000211529 00000 n +0000211678 00000 n +0000211803 00000 n +0000211928 00000 n +0000212053 00000 n +0000212178 00000 n +0000212321 00000 n +0000212446 00000 n +0000212589 00000 n +0000212714 00000 n +0000212845 00000 n +0000212988 00000 n +0000213125 00000 n +0000213280 00000 n +0000213441 00000 n +0000213587 00000 n +0000213822 00000 n +0000213991 00000 n +0000235617 00000 n +0000214221 00000 n +0000235686 00000 n +0000214349 00000 n +0000235753 00000 n +0000214480 00000 n +0000235822 00000 n +0000214605 00000 n +0000235889 00000 n +0000214742 00000 n +0000235958 00000 n +0000214873 00000 n +0000236025 00000 n +0000215004 00000 n +0000236093 00000 n +0000215153 00000 n +0000236160 00000 n +0000215284 00000 n +0000236229 00000 n +0000215468 00000 n +0000236296 00000 n +0000215623 00000 n +0000236365 00000 n +0000215760 00000 n +0000215929 00000 n +0000216244 00000 n +0000216431 00000 n +0000216574 00000 n +0000216867 00000 n +0000217186 00000 n +0000217388 00000 n +0000217614 00000 n +0000217810 00000 n +0000217973 00000 n +0000218166 00000 n +0000218397 00000 n +0000218604 00000 n +0000218811 00000 n +0000219023 00000 n +0000219301 00000 n +0000219550 00000 n +0000219757 00000 n +0000220221 00000 n +0000220396 00000 n +0000220680 00000 n +0000220855 00000 n +0000221004 00000 n +0000221200 00000 n +0000221466 00000 n +0000221597 00000 n +0000221817 00000 n +0000222049 00000 n +0000222262 00000 n +0000222437 00000 n +0000222553 00000 n +0000222666 00000 n +0000222775 00000 n +0000222891 00000 n +0000223002 00000 n +0000223116 00000 n +0000223223 00000 n +0000223335 00000 n +trailer +<< +/Size 719 +/Root 2 0 R +/Info 4 0 R +>> +startxref +236434 +%%EOF diff --git a/vscript/languages/squirrel/etc/minimal.c b/vscript/languages/squirrel/etc/minimal.c new file mode 100644 index 00000000..45417110 --- /dev/null +++ b/vscript/languages/squirrel/etc/minimal.c @@ -0,0 +1,63 @@ +#include +#include + +#include +#include +#include + +#ifdef _MSC_VER +#pragma comment (lib ,"squirrel.lib") +#pragma comment (lib ,"sqstdlib.lib") +#endif + +#ifdef SQUNICODE +#define scvprintf vwprintf +#else +#define scvprintf vprintf +#endif + +void printfunc(HSQUIRRELVM v, const SQChar *s, ...) +{ +va_list arglist; +va_start(arglist, s); +scvprintf(s, arglist); +va_end(arglist); +} + +void call_foo(HSQUIRRELVM v, int n,float f,const SQChar *s) +{ + SQInteger top = sq_gettop(v); //saves the stack size before the call + sq_pushroottable(v); //pushes the global table + sq_pushstring(v,_SC("foo"),-1); + if(SQ_SUCCEEDED(sq_get(v,-2))) { //gets the field 'foo' from the global table + sq_pushroottable(v); //push the 'this' (in this case is the global table) + sq_pushinteger(v,n); + sq_pushfloat(v,f); + sq_pushstring(v,s,-1); + sq_call(v,4,SQFalse,SQTrue); //calls the function + } + sq_settop(v,top); //restores the original stack size +} + +int main(int argc, char* argv[]) +{ + HSQUIRRELVM v; + v = sq_open(1024); // creates a VM with initial stack size 1024 + + //sq_pushroottable(v); //push the root table were to register the lib function + //sqstd_register_iolib(v); + sqstd_seterrorhandlers(v); //registers the default error handlers + + sq_setprintfunc(v, printfunc); //sets the print function + + sq_pushroottable(v); //push the root table(were the globals of the script will be stored) + if(SQ_SUCCEEDED(sqstd_dofile(v, _SC("test.nut"), SQFalse, SQTrue))) // also prints syntax errors if any + { + call_foo(v,1,2.5,_SC("teststring")); + } + + sq_pop(v,1); //pops the root table + sq_close(v); + + return 0; +} diff --git a/vscript/languages/squirrel/etc/test.nut b/vscript/languages/squirrel/etc/test.nut new file mode 100644 index 00000000..d72ba431 --- /dev/null +++ b/vscript/languages/squirrel/etc/test.nut @@ -0,0 +1,4 @@ +function foo(i, f, s) +{ + print("Called foo(), i="+i+", f="+f+", s='"+s+"'\n"); +} diff --git a/vscript/languages/squirrel/include/sqdbgserver.h b/vscript/languages/squirrel/include/sqdbgserver.h new file mode 100644 index 00000000..c34536f7 --- /dev/null +++ b/vscript/languages/squirrel/include/sqdbgserver.h @@ -0,0 +1,170 @@ +#ifndef _SQ_DBGSERVER_H_ +#define _SQ_DBGSERVER_H_ + +#define MAX_BP_PATH 512 +#define MAX_MSG_LEN 2049 + +#if defined( _PS3 ) || defined( POSIX ) +#include +#include +#include +#include +#include +#include "tier0/threadtools.h" +typedef int SOCKET; +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#endif + +// Parts of squirrel do a #define of type, which leads to compile warnings/errors when STL files are included. +// -- at least in VS 2013. Luckily we can temporarily #undef it and avoid the problem. +// VALVE BUILD +#undef type +#include +#include +#include +// Redefine type +#define type SQ_TYPE + +/* + see copyright notice in sqrdbg.h +*/ +#if !defined( _X360 ) && !defined( _PS3 ) && !defined( POSIX ) +#include +#endif + +typedef std::basic_string SQDBGString; + +inline bool dbg_less(const SQChar *x,const SQChar *y) +{ + int n = 0; + do { + int xl = *x == '\\' ? '/' : tolower(*x); + int yl = *y == '\\' ? '/' : tolower(*y); + int diff = xl - yl; + if(diff != 0) + return diff > 0?true:false; + x++; y++; + }while(*x != 0 && *y != 0); + return false; +} + +struct BreakPoint{ + BreakPoint(){_line=0;} + BreakPoint(int line, const SQChar *src){ _line = line; _src = src; } + BreakPoint(const BreakPoint& bp){ _line = bp._line; _src=bp._src; } + inline bool operator<(const BreakPoint& bp) const + { + if(_line BreakPointSet; +typedef BreakPointSet::iterator BreakPointSetItor; + +typedef std::set WatchSet; +typedef WatchSet::iterator WatchSetItor; + +typedef std::vector SQCharVec; +struct SQDbgServer{ +public: + enum eDbgState{ + eDBG_Running, + eDBG_StepOver, + eDBG_StepInto, + eDBG_StepReturn, + eDBG_Suspended, + eDBG_Disabled, + }; + + SQDbgServer(HSQUIRRELVM v); + ~SQDbgServer(); + bool Init(); + bool IsConnected(); + //returns true if a message has been received + bool WaitForClient(); + bool ReadMsg(); + void BusyWait(); + void Hook(int type,int line,const SQChar *src,const SQChar *func); + void ParseMsg(const char *msg); + bool ParseBreakpoint(const char *msg,BreakPoint &out); + bool ParseWatch(const char *msg,Watch &out); + bool ParseRemoveWatch(const char *msg,int &id); + void Terminated(); + // + void BreakExecution(); + void Send(const SQChar *s,...); + void SendChunk(const SQChar *chunk); + void Break(int line,const SQChar *src,const SQChar *type,const SQChar *error=NULL); + + + void SerializeState(); + //COMMANDS + void AddBreakpoint(BreakPoint &bp); + void AddWatch(Watch &w); + void RemoveWatch(int id); + void RemoveBreakpoint(BreakPoint &bp); + + // + void SetErrorHandlers(); + + //XML RELATED STUFF/////////////////////// + #define MAX_NESTING 10 + struct XMLElementState { + SQChar name[256]; + bool haschildren; + }; + + XMLElementState xmlstate[MAX_NESTING]; + int _xmlcurrentement; + + void BeginDocument() { _xmlcurrentement = -1; } + void BeginElement(const SQChar *name); + void Attribute(const SQChar *name, const SQChar *value); + void EndElement(const SQChar *name); + void EndDocument(); + + const SQChar *escape_xml(const SQChar *x); + ////////////////////////////////////////////// + HSQUIRRELVM _v; + HSQOBJECT _debugroot; + eDbgState _state; + SOCKET _accept; + SOCKET _endpoint; + BreakPointSet _breakpoints; + WatchSet _watches; + int _recursionlevel; + int _maxrecursion; + int _nestedcalls; + bool _ready; + bool _autoupdate; + HSQOBJECT _serializefunc; + SQCharVec _scratchstring; + +}; + +#ifdef _WIN32 +#define sqdbg_closesocket(x) closesocket((x)) +#else +#define sqdbg_closesocket(x) close((x)) +#endif + +#endif //_SQ_DBGSERVER_H_ diff --git a/vscript/languages/squirrel/include/sqrdbg.h b/vscript/languages/squirrel/include/sqrdbg.h new file mode 100644 index 00000000..e9e8bbb1 --- /dev/null +++ b/vscript/languages/squirrel/include/sqrdbg.h @@ -0,0 +1,52 @@ +/* +Copyright (c) 2003-2005 Alberto Demichelis + +This software is provided 'as-is', without any +express or implied warranty. In no event will the +authors be held liable for any damages arising from +the use of this software. + +Permission is granted to anyone to use this software +for any purpose, including commercial applications, +and to alter it and redistribute it freely, subject +to the following restrictions: + + 1. The origin of this software must not be + misrepresented; you must not claim that + you wrote the original software. If you + use this software in a product, an + acknowledgment in the product + documentation would be appreciated but is + not required. + + 2. Altered source versions must be plainly + marked as such, and must not be + misrepresented as being the original + software. + + 3. This notice may not be removed or + altered from any source distribution. + +*/ +#ifndef _SQ_RDBG_H_ +#define _SQ_RDBG_H_ + +#ifdef __cplusplus +extern "C" { +#endif +#ifndef _GAMECONSOLE +#pragma comment(lib, "WSOCK32.LIB") +#endif +struct SQDbgServer; +typedef SQDbgServer* HSQREMOTEDBG; + +HSQREMOTEDBG sq_rdbg_init(HSQUIRRELVM v,unsigned short port,SQBool autoupdate); +SQRESULT sq_rdbg_waitforconnections(HSQREMOTEDBG rdbg); +SQRESULT sq_rdbg_shutdown(HSQREMOTEDBG rdbg); +SQRESULT sq_rdbg_update(HSQREMOTEDBG rdbg); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif //_SQ_RDBG_H_ diff --git a/vscript/languages/squirrel/include/sqstdaux.h b/vscript/languages/squirrel/include/sqstdaux.h new file mode 100644 index 00000000..c16b0437 --- /dev/null +++ b/vscript/languages/squirrel/include/sqstdaux.h @@ -0,0 +1,16 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_AUXLIB_H_ +#define _SQSTD_AUXLIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +SQUIRREL_API void sqstd_seterrorhandlers(HSQUIRRELVM v); +SQUIRREL_API void sqstd_printcallstack(HSQUIRRELVM v); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* _SQSTD_AUXLIB_H_ */ diff --git a/vscript/languages/squirrel/include/sqstdblob.h b/vscript/languages/squirrel/include/sqstdblob.h new file mode 100644 index 00000000..1d9a4cdc --- /dev/null +++ b/vscript/languages/squirrel/include/sqstdblob.h @@ -0,0 +1,20 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTDBLOB_H_ +#define _SQSTDBLOB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +SQUIRREL_API SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size); +SQUIRREL_API SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr); +SQUIRREL_API SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx); + +SQUIRREL_API SQRESULT sqstd_register_bloblib(HSQUIRRELVM v); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*_SQSTDBLOB_H_*/ + diff --git a/vscript/languages/squirrel/include/sqstdio.h b/vscript/languages/squirrel/include/sqstdio.h new file mode 100644 index 00000000..5eaec31c --- /dev/null +++ b/vscript/languages/squirrel/include/sqstdio.h @@ -0,0 +1,54 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTDIO_H_ +#define _SQSTDIO_H_ + +#ifdef __cplusplus + +#define SQSTD_STREAM_TYPE_TAG 0x80000000 + +struct SQStream { + virtual ~SQStream() {} + virtual SQInteger Read(void *buffer, SQInteger size) = 0; + virtual SQInteger Write(void *buffer, SQInteger size) = 0; + virtual SQInteger Flush() = 0; + virtual SQInteger Tell() = 0; + virtual SQInteger Len() = 0; + virtual SQInteger Seek(SQInteger offset, SQInteger origin) = 0; + virtual bool IsValid() = 0; + virtual bool EOS() = 0; +}; + +extern "C" { +#endif + +#define SQ_SEEK_CUR 0 +#define SQ_SEEK_END 1 +#define SQ_SEEK_SET 2 + +typedef void* SQFILE; + +SQUIRREL_API SQFILE sqstd_fopen(const SQChar *,const SQChar *); +SQUIRREL_API SQInteger sqstd_fread(SQUserPointer, SQInteger, SQInteger, SQFILE); +SQUIRREL_API SQInteger sqstd_fwrite(const SQUserPointer, SQInteger, SQInteger, SQFILE); +SQUIRREL_API SQInteger sqstd_fseek(SQFILE , SQInteger , SQInteger); +SQUIRREL_API SQInteger sqstd_ftell(SQFILE); +SQUIRREL_API SQInteger sqstd_fflush(SQFILE); +SQUIRREL_API SQInteger sqstd_fclose(SQFILE); +SQUIRREL_API SQInteger sqstd_feof(SQFILE); + +SQUIRREL_API SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own); +SQUIRREL_API SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file); + +//compiler helpers +SQUIRREL_API SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror); +SQUIRREL_API SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror); +SQUIRREL_API SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename); + +SQUIRREL_API SQRESULT sqstd_register_iolib(HSQUIRRELVM v); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*_SQSTDIO_H_*/ + diff --git a/vscript/languages/squirrel/include/sqstdmath.h b/vscript/languages/squirrel/include/sqstdmath.h new file mode 100644 index 00000000..65de6fd7 --- /dev/null +++ b/vscript/languages/squirrel/include/sqstdmath.h @@ -0,0 +1,15 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_MATH_H_ +#define _SQSTD_MATH_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +SQUIRREL_API SQRESULT sqstd_register_mathlib(HSQUIRRELVM v); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*_SQSTD_MATH_H_*/ diff --git a/vscript/languages/squirrel/include/sqstdstring.h b/vscript/languages/squirrel/include/sqstdstring.h new file mode 100644 index 00000000..3c3bce82 --- /dev/null +++ b/vscript/languages/squirrel/include/sqstdstring.h @@ -0,0 +1,33 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_STRING_H_ +#define _SQSTD_STRING_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned int SQRexBool; +typedef struct SQRex SQRex; + +typedef struct { + const SQChar *begin; + SQInteger len; +} SQRexMatch; + +SQUIRREL_API SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error); +SQUIRREL_API void sqstd_rex_free(SQRex *exp); +SQUIRREL_API SQBool sqstd_rex_match(SQRex* exp,const SQChar* text); +SQUIRREL_API SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end); +SQUIRREL_API SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end); +SQUIRREL_API SQInteger sqstd_rex_getsubexpcount(SQRex* exp); +SQUIRREL_API SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp); + +SQUIRREL_API SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output); + +SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*_SQSTD_STRING_H_*/ diff --git a/vscript/languages/squirrel/include/sqstdsystem.h b/vscript/languages/squirrel/include/sqstdsystem.h new file mode 100644 index 00000000..b155a91f --- /dev/null +++ b/vscript/languages/squirrel/include/sqstdsystem.h @@ -0,0 +1,15 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_SYSTEMLIB_H_ +#define _SQSTD_SYSTEMLIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +SQUIRREL_API SQInteger sqstd_register_systemlib(HSQUIRRELVM v); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* _SQSTD_SYSTEMLIB_H_ */ diff --git a/vscript/languages/squirrel/include/squirrel.h b/vscript/languages/squirrel/include/squirrel.h new file mode 100644 index 00000000..8e902e3a --- /dev/null +++ b/vscript/languages/squirrel/include/squirrel.h @@ -0,0 +1,469 @@ +/* +Copyright (c) 2003-2009 Alberto Demichelis + +This software is provided 'as-is', without any +express or implied warranty. In no event will the +authors be held liable for any damages arising from +the use of this software. + +Permission is granted to anyone to use this software +for any purpose, including commercial applications, +and to alter it and redistribute it freely, subject +to the following restrictions: + + 1. The origin of this software must not be + misrepresented; you must not claim that + you wrote the original software. If you + use this software in a product, an + acknowledgment in the product + documentation would be appreciated but is + not required. + + 2. Altered source versions must be plainly + marked as such, and must not be + misrepresented as being the original + software. + + 3. This notice may not be removed or + altered from any source distribution. + +*/ +#ifndef _SQUIRREL_H_ +#define _SQUIRREL_H_ + +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "platform.h" +#include "dbg.h" +#if defined(VSQUIRREL_TEST) +#define printf( fmt, ...) Msg( fmt, ##__VA_ARGS__ ); +#else +#define printf( fmt, ...) DevMsg( fmt, ##__VA_ARGS__ ); +#endif +#else +#define Assert assert +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SQUIRREL_API +#define SQUIRREL_API extern +#endif + +#ifdef PLATFORM_64BITS +#define _SQ64 +#endif + +#ifdef _SQ64 +#define SQUSEDOUBLE +typedef int64 SQInteger; +typedef uint64 SQUnsignedInteger; +typedef uint64 SQHash; /*should be the same size of a pointer*/ +typedef int SQInt32; +#else +typedef int SQInteger; +typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/ +typedef unsigned int SQUnsignedInteger; +typedef unsigned int SQHash; /*should be the same size of a pointer*/ +#endif + + +#ifdef SQUSEDOUBLE +typedef double SQFloat; +#else +typedef float SQFloat; +#endif + +#if defined(SQUSEDOUBLE) && !defined(_SQ64) +#ifdef _MSC_VER +typedef __int64 SQRawObjectVal; //must be 64bits +#else +typedef long SQRawObjectVal; //must be 64bits +#endif +#define SQ_OBJECT_RAWINIT() { _unVal.raw = 0; } +#else +typedef SQUnsignedInteger SQRawObjectVal; //is 32 bits on 32 bits builds and 64 bits otherwise +#define SQ_OBJECT_RAWINIT() +#endif + +typedef void* SQUserPointer; +typedef SQUnsignedInteger SQBool; +typedef SQInteger SQRESULT; + +#define SQTrue (1) +#define SQFalse (0) + +struct SQVM; +struct SQTable; +struct SQArray; +struct SQString; +struct SQClosure; +struct SQGenerator; +struct SQNativeClosure; +struct SQUserData; +struct SQFunctionProto; +struct SQRefCounted; +struct SQClass; +struct SQInstance; +struct SQDelegable; + +#ifdef _UNICODE +#define SQUNICODE +#endif + +#ifdef SQUNICODE +#if (defined(_MSC_VER) && _MSC_VER >= 1400) // 1400 = VS8 + +#if defined(wchar_t) //this is if the compiler considers wchar_t as native type +#define wchar_t unsigned short +#endif + +#else +typedef unsigned short wchar_t; +#endif + +typedef wchar_t SQChar; +#define _SC(a) L##a +#define scstrcmp wcscmp +#define scsprintf swprintf +#define scstrlen wcslen +#define scstrtod wcstod +#define scstrtol wcstol +#define scatoi _wtoi +#define scstrtoul wcstoul +#define scvsprintf vswprintf +#define scstrstr wcsstr +#define scisspace iswspace +#define scisdigit iswdigit +#define scisxdigit iswxdigit +#define scisalpha iswalpha +#define sciscntrl iswcntrl +#define scisalnum iswalnum +#define scprintf wprintf +#define MAX_CHAR 0xFFFF +#else +typedef char SQChar; +#define _SC(a) a +#define scstrcmp strcmp +#define scsprintf sprintf +#define scstrlen strlen +#define scstrtod strtod +#define scstrtol strtol +#define scatoi atoi +#define scstrtoul strtoul +#define scvsprintf vsprintf +#define scstrstr strstr +#define scisspace isspace +#define scisdigit isdigit +#define scisxdigit isxdigit +#define sciscntrl iscntrl +#define scisalpha isalpha +#define scisalnum isalnum +#define scprintf printf +#define MAX_CHAR 0xFF +#endif + +#define SQUIRREL_VERSION _SC("Squirrel 2.2.3 stable") +#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2009 Alberto Demichelis") +#define SQUIRREL_AUTHOR _SC("Alberto Demichelis") + +#define SQ_VMSTATE_IDLE 0 +#define SQ_VMSTATE_RUNNING 1 +#define SQ_VMSTATE_SUSPENDED 2 + +#define SQUIRREL_EOB 0 +#define SQ_BYTECODE_STREAM_TAG 0xFAFA + +#define SQOBJECT_REF_COUNTED 0x08000000 +#define SQOBJECT_NUMERIC 0x04000000 +#define SQOBJECT_DELEGABLE 0x02000000 +#define SQOBJECT_CANBEFALSE 0x01000000 + +#define SQ_MATCHTYPEMASKSTRING (-99999) + +#define _RT_MASK 0x00FFFFFF +#define _RAW_TYPE(type) (type&_RT_MASK) + +#define _RT_NULL 0x00000001 +#define _RT_INTEGER 0x00000002 +#define _RT_FLOAT 0x00000004 +#define _RT_BOOL 0x00000008 +#define _RT_STRING 0x00000010 +#define _RT_TABLE 0x00000020 +#define _RT_ARRAY 0x00000040 +#define _RT_USERDATA 0x00000080 +#define _RT_CLOSURE 0x00000100 +#define _RT_NATIVECLOSURE 0x00000200 +#define _RT_GENERATOR 0x00000400 +#define _RT_USERPOINTER 0x00000800 +#define _RT_THREAD 0x00001000 +#define _RT_FUNCPROTO 0x00002000 +#define _RT_CLASS 0x00004000 +#define _RT_INSTANCE 0x00008000 +#define _RT_WEAKREF 0x00010000 + +typedef enum tagSQObjectType{ + OT_NULL = (_RT_NULL|SQOBJECT_CANBEFALSE), + OT_INTEGER = (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE), + OT_FLOAT = (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE), + OT_BOOL = (_RT_BOOL|SQOBJECT_CANBEFALSE), + OT_STRING = (_RT_STRING|SQOBJECT_REF_COUNTED), + OT_TABLE = (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE), + OT_ARRAY = (_RT_ARRAY|SQOBJECT_REF_COUNTED), + OT_USERDATA = (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE), + OT_CLOSURE = (_RT_CLOSURE|SQOBJECT_REF_COUNTED), + OT_NATIVECLOSURE = (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED), + OT_GENERATOR = (_RT_GENERATOR|SQOBJECT_REF_COUNTED), + OT_USERPOINTER = _RT_USERPOINTER, + OT_THREAD = (_RT_THREAD|SQOBJECT_REF_COUNTED) , + OT_FUNCPROTO = (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only + OT_CLASS = (_RT_CLASS|SQOBJECT_REF_COUNTED), + OT_INSTANCE = (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE), + OT_WEAKREF = (_RT_WEAKREF|SQOBJECT_REF_COUNTED) +}SQObjectType; + +#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED) + + +typedef union tagSQObjectValue +{ + struct SQTable *pTable; + struct SQArray *pArray; + struct SQClosure *pClosure; + struct SQGenerator *pGenerator; + struct SQNativeClosure *pNativeClosure; + struct SQString *pString; + struct SQUserData *pUserData; + SQInteger nInteger; + SQFloat fFloat; + SQUserPointer pUserPointer; + struct SQFunctionProto *pFunctionProto; + struct SQRefCounted *pRefCounted; + struct SQDelegable *pDelegable; + struct SQVM *pThread; + struct SQClass *pClass; + struct SQInstance *pInstance; + struct SQWeakRef *pWeakRef; + SQRawObjectVal raw; +}SQObjectValue; + + +typedef struct tagSQObject +{ + SQObjectType _type; + SQObjectValue _unVal; +}SQObject; + +typedef struct tagSQStackInfos{ + const SQChar* funcname; + const SQChar* source; + SQInteger line; +}SQStackInfos; + +typedef struct SQVM* HSQUIRRELVM; +typedef SQObject HSQOBJECT; +typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM); +typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size); +typedef void (*SQCOMPILERERROR)(HSQUIRRELVM,const SQChar * /*desc*/,const SQChar * /*source*/,SQInteger /*line*/,SQInteger /*column*/); +typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM,const SQChar * ,...); + +typedef SQInteger (*SQWRITEFUNC)(SQUserPointer,SQUserPointer,SQInteger); +typedef SQInteger (*SQREADFUNC)(SQUserPointer,SQUserPointer,SQInteger); + +typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer); + +typedef struct tagSQRegFunction{ + const SQChar *name; + SQFUNCTION f; + SQInteger nparamscheck; + const SQChar *typemask; +}SQRegFunction; + +typedef struct tagSQFunctionInfo { + SQUserPointer funcid; + const SQChar *name; + const SQChar *source; +}SQFunctionInfo; + + +/*vm*/ +SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize); +SQUIRREL_API HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize); +SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v); +SQUIRREL_API void sq_close(HSQUIRRELVM v); +SQUIRREL_API void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p); +SQUIRREL_API SQUserPointer sq_getforeignptr(HSQUIRRELVM v); +SQUIRREL_API void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc); +SQUIRREL_API SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool resumedret,SQBool retval,SQBool raiseerror,SQBool throwerror); +SQUIRREL_API SQInteger sq_getvmstate(HSQUIRRELVM v); + +/*compiler*/ +SQUIRREL_API SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror); +SQUIRREL_API SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror); +SQUIRREL_API void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable); +SQUIRREL_API void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable); +SQUIRREL_API void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f); + +/*stack operations*/ +SQUIRREL_API void sq_push(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API void sq_pop(HSQUIRRELVM v,SQInteger nelemstopop); +SQUIRREL_API void sq_poptop(HSQUIRRELVM v); +SQUIRREL_API void sq_remove(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQInteger sq_gettop(HSQUIRRELVM v); +SQUIRREL_API void sq_settop(HSQUIRRELVM v,SQInteger newtop); +SQUIRREL_API void sq_reservestack(HSQUIRRELVM v,SQInteger nsize); +SQUIRREL_API SQInteger sq_cmp(HSQUIRRELVM v); +SQUIRREL_API void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx); + +/*object creation handling*/ +SQUIRREL_API SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size); +SQUIRREL_API void sq_newtable(HSQUIRRELVM v); +SQUIRREL_API void sq_newarray(HSQUIRRELVM v,SQInteger size); +SQUIRREL_API void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars); +SQUIRREL_API SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask); +SQUIRREL_API SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len); +SQUIRREL_API void sq_pushfloat(HSQUIRRELVM v,SQFloat f); +SQUIRREL_API void sq_pushinteger(HSQUIRRELVM v,SQInteger n); +SQUIRREL_API void sq_pushbool(HSQUIRRELVM v,SQBool b); +SQUIRREL_API void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p); +SQUIRREL_API void sq_pushnull(HSQUIRRELVM v); +SQUIRREL_API SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQInteger sq_getsize(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQBool sq_instanceof(HSQUIRRELVM v); +SQUIRREL_API void sq_tostring(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b); +SQUIRREL_API SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c); +SQUIRREL_API SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i); +SQUIRREL_API SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f); +SQUIRREL_API SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b); +SQUIRREL_API SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread); +SQUIRREL_API SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p); +SQUIRREL_API SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag); +SQUIRREL_API SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag); +SQUIRREL_API SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag); +SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook); +SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize); +SQUIRREL_API SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger idx,SQFunctionInfo *fi); +SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars); +SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name); +SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p); +SQUIRREL_API SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag); +SQUIRREL_API SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize); +SQUIRREL_API SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase); +SQUIRREL_API SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API void sq_weakref(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t); + +/*object manipulation*/ +SQUIRREL_API void sq_pushroottable(HSQUIRRELVM v); +SQUIRREL_API void sq_pushregistrytable(HSQUIRRELVM v); +SQUIRREL_API void sq_pushconsttable(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_setroottable(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_setconsttable(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic); +SQUIRREL_API SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval); +SQUIRREL_API SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval); +SQUIRREL_API SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval); +SQUIRREL_API SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize); +SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx); +SQUIRREL_API SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos); +SQUIRREL_API SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval); +SQUIRREL_API SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx); + +/*calls*/ +SQUIRREL_API SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror); +SQUIRREL_API SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror); +SQUIRREL_API const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx); +SQUIRREL_API const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval); +SQUIRREL_API SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err); +SQUIRREL_API void sq_reseterror(HSQUIRRELVM v); +SQUIRREL_API void sq_getlasterror(HSQUIRRELVM v); + +/*raw object handling*/ +SQUIRREL_API SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po); +SQUIRREL_API void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj); +SQUIRREL_API void sq_addref(HSQUIRRELVM v,HSQOBJECT *po); +SQUIRREL_API SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po); +SQUIRREL_API void sq_resetobject(HSQOBJECT *po); +SQUIRREL_API const SQChar *sq_objtostring(HSQOBJECT *o); +SQUIRREL_API SQBool sq_objtobool(HSQOBJECT *o); +SQUIRREL_API SQInteger sq_objtointeger(HSQOBJECT *o); +SQUIRREL_API SQFloat sq_objtofloat(HSQOBJECT *o); +SQUIRREL_API SQRESULT sq_getobjtypetag(HSQOBJECT *o,SQUserPointer * typetag); + +/*GC*/ +SQUIRREL_API SQInteger sq_collectgarbage(HSQUIRRELVM v); + +/*serialization*/ +SQUIRREL_API SQRESULT sq_writeclosure(HSQUIRRELVM vm,SQWRITEFUNC writef,SQUserPointer up); +SQUIRREL_API SQRESULT sq_readclosure(HSQUIRRELVM vm,SQREADFUNC readf,SQUserPointer up); + +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#define sq_malloc malloc +#define sq_realloc(p,oldsize,size) realloc(p, size) +#define sq_free(p,size) free(p) +#else +/*mem allocation*/ +SQUIRREL_API void *sq_malloc(SQUnsignedInteger size); +SQUIRREL_API void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize); +SQUIRREL_API void sq_free(void *p,SQUnsignedInteger size); +#endif + +/*debug*/ +SQUIRREL_API SQRESULT sq_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos *si); +SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v); + +/*UTILITY MACRO*/ +#define sq_isnumeric(o) ((o)._type&SQOBJECT_NUMERIC) +#define sq_istable(o) ((o)._type==OT_TABLE) +#define sq_isarray(o) ((o)._type==OT_ARRAY) +#define sq_isfunction(o) ((o)._type==OT_FUNCPROTO) +#define sq_isclosure(o) ((o)._type==OT_CLOSURE) +#define sq_isgenerator(o) ((o)._type==OT_GENERATOR) +#define sq_isnativeclosure(o) ((o)._type==OT_NATIVECLOSURE) +#define sq_isstring(o) ((o)._type==OT_STRING) +#define sq_isinteger(o) ((o)._type==OT_INTEGER) +#define sq_isfloat(o) ((o)._type==OT_FLOAT) +#define sq_isuserpointer(o) ((o)._type==OT_USERPOINTER) +#define sq_isuserdata(o) ((o)._type==OT_USERDATA) +#define sq_isthread(o) ((o)._type==OT_THREAD) +#define sq_isnull(o) ((o)._type==OT_NULL) +#define sq_isclass(o) ((o)._type==OT_CLASS) +#define sq_isinstance(o) ((o)._type==OT_INSTANCE) +#define sq_isbool(o) ((o)._type==OT_BOOL) +#define sq_isweakref(o) ((o)._type==OT_WEAKREF) +#define sq_type(o) ((o)._type) + +/* deprecated */ +#define sq_createslot(v,n) sq_newslot(v,n,SQFalse) + +#define SQ_OK (0) +#define SQ_ERROR (-1) + +#define SQ_FAILED(res) (res<0) +#define SQ_SUCCEEDED(res) (res>=0) + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*_SQUIRREL_H_*/ diff --git a/vscript/languages/squirrel/minimalSqPlus/Makefile b/vscript/languages/squirrel/minimalSqPlus/Makefile new file mode 100644 index 00000000..ae8818b1 --- /dev/null +++ b/vscript/languages/squirrel/minimalSqPlus/Makefile @@ -0,0 +1,18 @@ +SQUIRREL= .. + +OUT= ./minimalSqPlus +INCDIRS= -I$(SQUIRREL)/include -I. -I$(SQUIRREL)/sqlibs -I$(SQUIRREL)/sqplus +LIBDIR= -L$(SQUIRREL)/lib +#LIBS= -lsquirrel -lsqstdlib -lsqplus +LIBS= -lsqplus -lsquirrel -lsqstdlib + +SRCS= minimalSqPlus.cpp + +all: minimalSqPlus + +FORCE: ; + +minimalSqPlus: FORCE +# g++ -fno-rtti -o $(OUT) $(SRCS) $(INCDIRS) $(LIBDIR) $(LIBS) + g++ -O3 -Wall -o $(OUT) $(SRCS) $(INCDIRS) $(LIBDIR) $(LIBS) + #g++ -O3 -fno-rtti -Os -o $(OUT) $(SRCS) $(INCDIRS) $(LIBDIR) $(LIBS) diff --git a/vscript/languages/squirrel/minimalSqPlus/minimalSqPlus.cbp b/vscript/languages/squirrel/minimalSqPlus/minimalSqPlus.cbp new file mode 100644 index 00000000..f9b1b5d0 --- /dev/null +++ b/vscript/languages/squirrel/minimalSqPlus/minimalSqPlus.cbp @@ -0,0 +1,118 @@ + + + + + + + diff --git a/vscript/languages/squirrel/minimalSqPlus/minimalSqPlus.cpp b/vscript/languages/squirrel/minimalSqPlus/minimalSqPlus.cpp new file mode 100644 index 00000000..818005f1 --- /dev/null +++ b/vscript/languages/squirrel/minimalSqPlus/minimalSqPlus.cpp @@ -0,0 +1,162 @@ +// minimalSqPlus.cpp +// A minimal example and an example with a simple class. +// Example for use with the remote debugger is also shown. +// Created 10/08/05, John Schultz +// Free for any use. + +#include +#include +#include "sqplus.h" + +using namespace SqPlus; + +// Define MINIMAL_EXAMPLE for minimal HelloWorld example. +//#define MINIMAL_EXAMPLE + +// Define USE_REMOTE_DEBUGGER to use the remote debugger. See the example and docs in the sqdbg directory for +// more information. +//#define USE_REMOTE_DEBUGGER // Remote debugger must be started after the program is launched. +#ifdef USE_REMOTE_DEBUGGER +#include "sqrdbg.h" +#endif + +// The following pragmas can be used to link the correct library for Debug/Release builds +// without requiring the application to include the associated Squirrel projects. +// (The libraries must be created before compiling this example). +// Set SQ_REL_PATH as needed for your application. + +#define SQ_REL_PATH "../" + +#ifdef UNICODE +#define LIB "U.lib" +#else +#define LIB ".lib" +#endif + +#ifdef _MSC_VER +#ifdef _DEBUG +#pragma comment(lib,SQ_REL_PATH "lib/squirrelD" LIB) +#pragma comment(lib,SQ_REL_PATH "lib/sqstdlibD" LIB) +#ifdef USE_REMOTE_DEBUGGER +#pragma comment(lib,SQ_REL_PATH "lib/sqdbglibD" LIB) +#endif +#pragma comment(lib,SQ_REL_PATH "lib/sqplusD" LIB) +#else // Release +#pragma comment(lib,SQ_REL_PATH "lib/squirrel" LIB) +#pragma comment(lib,SQ_REL_PATH "lib/sqstdlib" LIB) +#ifdef USE_REMOTE_DEBUGGER +#pragma comment(lib,SQ_REL_PATH "lib/sqdbglib" LIB) +#endif +#pragma comment(lib,SQ_REL_PATH "lib/sqplus" LIB) +#endif +#endif + +#ifdef USE_REMOTE_DEBUGGER +void printSQDBGError(HSQUIRRELVM v) { + const SQChar *err; + sq_getlasterror(v); + if(SQ_SUCCEEDED(sq_getstring(v,-1,&err))) { + scprintf(_T("SQDBG error : %s"),err); + }else { + scprintf(_T("SQDBG error"),err); + } // if + sq_poptop(v); +} // printSQDBGError +#endif + +static void printFunc(HSQUIRRELVM v,const SQChar * s,...) { + static SQChar temp[2048]; + va_list vl; + va_start(vl,s); + scvsprintf( temp,s,vl); + SCPUTS(temp); + va_end(vl); +} // printFunc + +class MyClass { +public: + int classVal; + // See examples in testSqPlus2.cpp for passing arguments to the constructor (including variable arguments). + MyClass() : classVal(123) {} + bool process(int iVal,const SQChar * sVal) { + scprintf(_T("classVal: %d, iVal: %d, sVal %s\n"),classVal,iVal,sVal); + classVal += iVal; + return iVal > 1; + } // process +}; + +#ifdef MINIMAL_EXAMPLE + +int main(int argc,char * argv[]) { + SquirrelVM::Init(); + SquirrelObject helloWorld = SquirrelVM::CompileBuffer(_T("print(\"Hello World\");")); + SquirrelVM::RunScript(helloWorld); + SquirrelVM::Shutdown(); + scprintf(_T("Press RETURN to exit.")); + getchar(); +} // main + +#else + +int main(int argc,char * argv[]) { + SquirrelVM::Init(); + // This example shows how to redirect print output to your own custom + // print function (the default handler prints to stdout). + sq_setprintfunc(SquirrelVM::GetVMPtr(),printFunc); + +#ifdef USE_REMOTE_DEBUGGER + HSQREMOTEDBG rdbg = sq_rdbg_init(SquirrelVM::GetVMPtr(),1234,SQTrue); + if(rdbg) { + // Enable debug info generation (for the compiler). + sq_enabledebuginfo(SquirrelVM::GetVMPtr(),SQTrue); + scprintf(_T("Waiting for SQDBG connection...")); + // Suspends the app until the debugger client connects. + if(SQ_SUCCEEDED(sq_rdbg_waitforconnections(rdbg))) { + printf("SQDBG: connected.\n"); + } // if + } else { + printSQDBGError(SquirrelVM::GetVMPtr()); + return 0; + } // if +#endif + + // See examples in testSqPlus2.cpp for script read-only vars, constants, + // enums, static/global functions, variable arguments, constructor arguments, + // passing/returning classes/structs by value or by address, etc. + SQClassDef(_T("MyClass")). + func(&MyClass::process,_T("process")). + var(&MyClass::classVal,_T("classVal")); + + SquirrelObject helloSqPlus = SquirrelVM::CompileBuffer(_T("\ + local myClass = MyClass(); \n\ + local rVal = myClass.process(1,\"MyClass1\"); \n\ + print(\"Returned: \"+(rVal ? \"true\" : \"false\")); \n\ + rVal = myClass.process(2,\"MyClass2\"); \n\ + print(\"Returned: \"+(rVal ? \"true\" : \"false\")); \n\ + print(\"classVal: \"+myClass.classVal); \n\ + ")); + + try { + SquirrelVM::RunScript(helloSqPlus); + } catch (SquirrelError & e) { + scprintf(_T("Error: %s, %s\n"),e.desc,_T("Squirrel::helloSqPlus")); + } // catch + +#ifdef USE_REMOTE_DEBUGGER + if (rdbg) { + sq_rdbg_shutdown(rdbg); + } // if +#endif + + SquirrelVM::Shutdown(); + + scprintf(_T("Press RETURN to exit.")); + getchar(); + + return 0; + +} // main + +#endif + +// minimalSqPlus.cpp diff --git a/vscript/languages/squirrel/minimalSqPlus/minimalSqPlus.vcproj b/vscript/languages/squirrel/minimalSqPlus/minimalSqPlus.vcproj new file mode 100644 index 00000000..841b5bcd --- /dev/null +++ b/vscript/languages/squirrel/minimalSqPlus/minimalSqPlus.vcproj @@ -0,0 +1,347 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/minimalSqPlus/minimalSqPlus71.vcproj b/vscript/languages/squirrel/minimalSqPlus/minimalSqPlus71.vcproj new file mode 100644 index 00000000..d1fcf8f3 --- /dev/null +++ b/vscript/languages/squirrel/minimalSqPlus/minimalSqPlus71.vcproj @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/readme_valve.txt b/vscript/languages/squirrel/readme_valve.txt new file mode 100644 index 00000000..ae802fc3 --- /dev/null +++ b/vscript/languages/squirrel/readme_valve.txt @@ -0,0 +1 @@ +This directory contains the Squirrel 2.1 distribution and the SqPlus binding sytem, acquired 1/18/2008 \ No newline at end of file diff --git a/vscript/languages/squirrel/samples/ackermann.nut b/vscript/languages/squirrel/samples/ackermann.nut new file mode 100644 index 00000000..7d7b16d6 --- /dev/null +++ b/vscript/languages/squirrel/samples/ackermann.nut @@ -0,0 +1,23 @@ +/* +* +* Original Javascript version by David Hedbor(http://www.bagley.org/~doug/shootout/) +* +*/ + +function Ack(M, N) { + if (M == 0) return( N + 1 ); + if (N == 0) return( Ack(M - 1, 1) ); + return( Ack(M - 1, Ack(M, (N - 1))) ); +} + +local n; + +if(ARGS.len()!=0) { + n = ARGS[0].tointeger(); + if(n < 1) n = 1; +} else { + n = 1; +} +print("n="+n+"\n"); +print("Ack(3,"+ n+ "):"+ Ack(3, n)); + diff --git a/vscript/languages/squirrel/samples/array.nut b/vscript/languages/squirrel/samples/array.nut new file mode 100644 index 00000000..adf39f39 --- /dev/null +++ b/vscript/languages/squirrel/samples/array.nut @@ -0,0 +1,29 @@ +/* +* +* Original Javascript version by David Hedbor(http://www.bagley.org/~doug/shootout/) +* +*/ +local n, i, k; + +if(ARGS.len()!=0) { + n = ARGS[0].tointeger(); + if(n < 1) n = 1; +} else { + n = 1; +} + +local x = []; x.resize(n); +local y = []; y.resize(n); + +for (i = 0; i < n; i+=1) { + x[i] = i + 1; + y[i] = 0; +} + +for (k = 0 ; k < n; k+=1) { + for (i = n-1; i >= 0; i-=1) { + y[i] = y[i]+ x[i]; + } +} +print(y[0].tostring()+" "+y[n-1]); + diff --git a/vscript/languages/squirrel/samples/class.nut b/vscript/languages/squirrel/samples/class.nut new file mode 100644 index 00000000..b8632775 --- /dev/null +++ b/vscript/languages/squirrel/samples/class.nut @@ -0,0 +1,49 @@ +////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////// +class BaseVector { + constructor(...) + { + if(vargc >= 3) { + x = vargv[0]; + y = vargv[1]; + z = vargv[2]; + } + } + + + x = 0; + y = 0; + z = 0; +} + +class Vector3 extends BaseVector { + function _add(other) + { + if(other instanceof this.getclass()) + return ::Vector3(x+other.x,y+other.y,z+other.z); + else + throw "wrong parameter"; + } + function Print() + { + ::print(x+","+y+","+z+"\n"); + } +} + +local v0 = Vector3(1,2,3) +local v1 = Vector3(11,12,13) +local v2 = v0 + v1; +v2.Print(); + +FakeNamespace <- { + Utils = {} +} + +class FakeNamespace.Utils.SuperClass { + constructor() + { + ::print("FakeNamespace.Utils.SuperClass") + } +} + +local testy = FakeNamespace.Utils.SuperClass(); \ No newline at end of file diff --git a/vscript/languages/squirrel/samples/classattributes.nut b/vscript/languages/squirrel/samples/classattributes.nut new file mode 100644 index 00000000..853a49e3 --- /dev/null +++ b/vscript/languages/squirrel/samples/classattributes.nut @@ -0,0 +1,35 @@ +class Foo { + //constructor + constructor(a) + { + testy = ["stuff",1,2,3]; + } + //attributes of PrintTesty + + function PrintTesty() + { + foreach(i,val in testy) + { + ::print("idx = "+i+" = "+val+" \n"); + } + } + //attributes of testy + + testy = null; + +} + +foreach(member,val in Foo) +{ + ::print(member+"\n"); + local attr; + if((attr = Foo.getattributes(member)) != null) { + foreach(i,v in attr) + { + ::print("\t"+i+" = "+(typeof v)+"\n"); + } + } + else { + ::print("\t\n") + } +} \ No newline at end of file diff --git a/vscript/languages/squirrel/samples/coroutines.nut b/vscript/languages/squirrel/samples/coroutines.nut new file mode 100644 index 00000000..dbe0447b --- /dev/null +++ b/vscript/languages/squirrel/samples/coroutines.nut @@ -0,0 +1,25 @@ +function coroutine_test(a,b) +{ + ::print(a+" "+b+"\n"); + local ret = ::suspend("suspend 1"); + ::print("the coroutine says "+ret+"\n"); + ret = ::suspend("suspend 2"); + ::print("the coroutine says "+ret+"\n"); + ret = ::suspend("suspend 3"); + ::print("the coroutine says "+ret+"\n"); + return "I'm done" +} + +local coro = ::newthread(coroutine_test); + +local susparam = coro.call("test","coroutine"); //starts the coroutine + +local i = 1; +do +{ + ::print("suspend passed ["+susparam+"]\n") + susparam = coro.wakeup("ciao "+i); + ++i; +}while(coro.getstatus()=="suspended") + +::print("return passed ["+susparam+"]\n") \ No newline at end of file diff --git a/vscript/languages/squirrel/samples/delegation.nut b/vscript/languages/squirrel/samples/delegation.nut new file mode 100644 index 00000000..2d409475 --- /dev/null +++ b/vscript/languages/squirrel/samples/delegation.nut @@ -0,0 +1,52 @@ + +PEntity <- { + name="noname" + pos={x=0,y=0,z=0} + type="entity" + //methamethod + _typeof=function() + { + return type; + } +} + +function PEntity::PrintPos() +{ + ::print("x="+pos.x+" y="+pos.y+" z="+pos.z+"\n"); +} + +function PEntity::new(name,pos) +{ + local newentity=clone ::PEntity; + if(name) + newentity.name=name; + if(pos) + newentity.pos=pos; + return newentity; +} + +PPlayer <- { + model="warrior.mdl" + weapon="fist" + health=100 + armor=0 + //overrides the parent type + type="player" +} + +function PPlayer::new(name,pos) +{ + local newplayer=delegate ::PEntity.new(name,pos) : clone ::PPlayer; + return newplayer; +} + +local player=PPlayer.new("godzilla",{x=10,y=20,z=30}); + +::print("PLAYER NAME"+player.name+"\n"); +::print("ENTITY TYPE"+typeof player+"\n"); + +player.PrintPos(); + +player.pos.x=123; + +player.PrintPos(); \ No newline at end of file diff --git a/vscript/languages/squirrel/samples/fibonacci.nut b/vscript/languages/squirrel/samples/fibonacci.nut new file mode 100644 index 00000000..e56568d5 --- /dev/null +++ b/vscript/languages/squirrel/samples/fibonacci.nut @@ -0,0 +1,15 @@ +/* +* +* Original Javascript version by David Hedbor(http://www.bagley.org/~doug/shootout/) +* +*/ + +function fib(n) +{ + if (n < 2) return 1 + return fib(n-2) + fib(n-1) +} + +local n = ARGS.len()!=0?ARGS[0].tointeger():1 + +print(fib(n)+"\n") diff --git a/vscript/languages/squirrel/samples/flow.nut b/vscript/languages/squirrel/samples/flow.nut new file mode 100644 index 00000000..093c09e6 --- /dev/null +++ b/vscript/languages/squirrel/samples/flow.nut @@ -0,0 +1,33 @@ +function min(x,y) + return xy?x:y; + +if(min(100,200)>max(50,20)) + print("I'm useless statement just to show up the if/else\n"); +else + print("squirrel!!\n"); + +print("\n") + +function typy(obj) +{ + switch(typeof obj) + { + case "integer": + case "float": + return "is a number"; + case "table": + case "array": + return "is a container"; + default: + return "is other stuff" + } +} + +local a=1,b={},c=function(a,b){return a+b;} + +print("a "+typy(a)+"\n"); +print("b "+typy(b)+"\n"); +print("c "+typy(c)+"\n"); \ No newline at end of file diff --git a/vscript/languages/squirrel/samples/generators.nut b/vscript/languages/squirrel/samples/generators.nut new file mode 100644 index 00000000..ccd6b1da --- /dev/null +++ b/vscript/languages/squirrel/samples/generators.nut @@ -0,0 +1,42 @@ +/* +*Random number function from The Great Computer Language shootout +*converted to a generator func +*/ + +function gen_random(max) { + local last=42 + local IM = 139968; + local IA = 3877; + local IC = 29573; + for(;;){ //loops forever + yield (max * (last = (last * IA + IC) % IM) / IM); + } +} + +local randtor=gen_random(100); + +print("RAND NUMBERS \n") + +for(local i=0;i<10;i+=1) + print(">"+resume randtor+"\n"); + +print("FIBONACCI \n") +function fiboz(n) +{ + local prev=0; + local curr=1; + yield 1; + + for(local i=0;i"+val+"\n"); +} \ No newline at end of file diff --git a/vscript/languages/squirrel/samples/hello.nut b/vscript/languages/squirrel/samples/hello.nut new file mode 100644 index 00000000..1dc45ac1 --- /dev/null +++ b/vscript/languages/squirrel/samples/hello.nut @@ -0,0 +1 @@ +print("Hello World!") \ No newline at end of file diff --git a/vscript/languages/squirrel/samples/list.nut b/vscript/languages/squirrel/samples/list.nut new file mode 100644 index 00000000..cc9b6283 --- /dev/null +++ b/vscript/languages/squirrel/samples/list.nut @@ -0,0 +1,40 @@ +/*translation of the list test from The Great Computer Language Shootout +*/ + +function compare_arr(a1,a2) +{ + foreach(i,val in a1) + if(val!=a2[i])return null; + return 1; +} + +function test() +{ + local size=10000 + local l1=[]; l1.resize(size); + for(local i=0;i0) + l3.append(l2.pop()); + while(l3.len()>0) + l2.append(l3.pop()); + l1.reverse(); + + if(compare_arr(l1,l2)) + return l1.len(); + return null; +} + +local n = ARGS.len()!=0?ARGS[0].tointeger():1 +for(local i=0;i\n"); +else + print("\n"); diff --git a/vscript/languages/squirrel/samples/methcall.nut b/vscript/languages/squirrel/samples/methcall.nut new file mode 100644 index 00000000..da0882d8 --- /dev/null +++ b/vscript/languages/squirrel/samples/methcall.nut @@ -0,0 +1,61 @@ +/*translation of the methcall test from The Great Computer Language Shootout +*/ + +Toggle <- { + bool=null +} + +function Toggle::value() { + return bool; +} + +function Toggle::activate() { + bool = !bool; + return this; +} + +function Toggle::new(startstate) { + local newo=clone this; + newo.bool = startstate; + return newo; +} + +NthToggle <- { + count_max=null + count=0 +} + +function NthToggle::new(start_state,max_counter) +{ + local newo=delegate ::Toggle.new(start_state) : clone this; + newo.count_max <- max_counter + return newo; +} + +function NthToggle::activate () +{ + count+=1 + if (count >= count_max) { + bool = !bool; + count = 0; + } + return this; +} + + +local n = ARGS.len()!=0?ARGS[0].tointeger():1 + +local val = 1; +local toggle = Toggle.new(val); +for (local i=0; i +#include +#include +#include + +#if defined(_MSC_VER) && defined(_DEBUG) +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include + +#ifdef SQUNICODE +#define scfprintf fwprintf +#define scfopen _wfopen +#define scvprintf vwprintf +#else +#define scfprintf fprintf +#define scfopen fopen +#define scvprintf vprintf +#endif + + +void PrintVersionInfos(); + +#if defined(_MSC_VER) && defined(_DEBUG) +int MemAllocHook( int allocType, void *userData, size_t size, int blockType, + long requestNumber, const unsigned char *filename, int lineNumber) +{ +// if(requestNumber==585)_asm int 3; + return 1; +} +#endif + + +SQInteger quit(HSQUIRRELVM v) +{ + int *done; + sq_getuserpointer(v,-1,(SQUserPointer*)&done); + *done=1; + return 0; +} + +void printfunc(HSQUIRRELVM v,const SQChar *s,...) +{ + va_list vl; + va_start(vl, s); + scvprintf( s, vl); + va_end(vl); +} + +void PrintVersionInfos() +{ + scfprintf(stdout,_SC("%s %s (%d bits)\n"),SQUIRREL_VERSION,SQUIRREL_COPYRIGHT,sizeof(SQInteger)*8); + if(sizeof(SQFloat) != sizeof(float)) { + scfprintf(stdout,_SC("[%d bits floats]\n"),sizeof(SQFloat)*8); + } +} + +void PrintUsage() +{ + scfprintf(stderr,_SC("usage: sq .\n") + _SC("Available options are:\n") + _SC(" -c compiles the file to bytecode(default output 'out.cnut')\n") + _SC(" -o specifies output file for the -c option\n") + _SC(" -c compiles only\n") + _SC(" -d generates debug infos\n") + _SC(" -v displays version infos\n") + _SC(" -h prints help\n")); +} + +#define _INTERACTIVE 0 +#define _DONE 2 +//<> this func is a mess +int getargs(HSQUIRRELVM v,int argc, char* argv[]) +{ + int i; + int compiles_only = 0; + static SQChar temp[500]; + const SQChar *ret=NULL; + char * output = NULL; + int lineinfo=0; + if(argc>1) + { + int arg=1,exitloop=0; + while(arg < argc && !exitloop) + { + + if(argv[arg][0]=='-') + { + switch(argv[arg][1]) + { + case 'd': //DEBUG(debug infos) + sq_enabledebuginfo(v,1); + break; + case 'c': + compiles_only = 1; + break; + case 'o': + if(arg < argc) { + arg++; + output = argv[arg]; + } + break; + case 'v': + PrintVersionInfos(); + return _DONE; + + case 'h': + PrintVersionInfos(); + PrintUsage(); + return _DONE; + default: + PrintVersionInfos(); + scprintf(_SC("unknown prameter '-%c'\n"),argv[arg][1]); + PrintUsage(); + return _DONE; + } + }else break; + arg++; + } + + // src file + + if(arg")); + for(;;) { + int c; + if(done)return; + c = getchar(); + if (c == _SC('\n')) { + if (i>0 && buffer[i-1] == _SC('\\')) + { + buffer[i-1] = _SC('\n'); + } + else if(blocks==0)break; + buffer[i++] = _SC('\n'); + } + else if (c==_SC('}')) {blocks--; buffer[i++] = (SQChar)c;} + else if(c==_SC('{') && !string){ + blocks++; + buffer[i++] = (SQChar)c; + } + else if(c==_SC('"') || c==_SC('\'')){ + string=!string; + buffer[i++] = (SQChar)c; + } + else if (i >= MAXINPUT-1) { + scfprintf(stderr, _SC("sq : input line too long\n")); + break; + } + else{ + buffer[i++] = (SQChar)c; + } + } + buffer[i] = _SC('\0'); + + if(buffer[0]==_SC('=')){ + scsprintf(sq_getscratchpad(v,MAXINPUT),_SC("return (%s)"),&buffer[1]); + memcpy(buffer,sq_getscratchpad(v,-1),(scstrlen(sq_getscratchpad(v,-1))+1)*sizeof(SQChar)); + retval=1; + } + i=scstrlen(buffer); + if(i>0){ + SQInteger oldtop=sq_gettop(v); + if(SQ_SUCCEEDED(sq_compilebuffer(v,buffer,i,_SC("interactive console"),SQTrue))){ + sq_pushroottable(v); + if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue)) && retval){ + scprintf(_SC("\n")); + sq_pushroottable(v); + sq_pushstring(v,_SC("print"),-1); + sq_get(v,-2); + sq_pushroottable(v); + sq_push(v,-4); + sq_call(v,2,SQFalse,SQTrue); + retval=0; + scprintf(_SC("\n")); + } + } + + sq_settop(v,oldtop); + } + } +} + +int main(int argc, char* argv[]) +{ + HSQUIRRELVM v; + + const SQChar *filename=NULL; +#if defined(_MSC_VER) && defined(_DEBUG) + _CrtSetAllocHook(MemAllocHook); +#endif + + v=sq_open(1024); + sq_setprintfunc(v,printfunc); + + sq_pushroottable(v); + + sqstd_register_bloblib(v); + sqstd_register_iolib(v); + sqstd_register_systemlib(v); + sqstd_register_mathlib(v); + sqstd_register_stringlib(v); + + //aux library + //sets error handlers + sqstd_seterrorhandlers(v); + + //gets arguments + switch(getargs(v,argc,argv)) + { + case _INTERACTIVE: + Interactive(v); + break; + case _DONE: + default: + break; + } + + sq_close(v); + +#if defined(_MSC_VER) && defined(_DEBUG) + _getch(); + _CrtMemDumpAllObjectsSince( NULL ); +#endif + return 0; +} + diff --git a/vscript/languages/squirrel/sq/sq.cbp b/vscript/languages/squirrel/sq/sq.cbp new file mode 100644 index 00000000..7c9c99d1 --- /dev/null +++ b/vscript/languages/squirrel/sq/sq.cbp @@ -0,0 +1,129 @@ + + + + + + + diff --git a/vscript/languages/squirrel/sq/sq.vcproj b/vscript/languages/squirrel/sq/sq.vcproj new file mode 100644 index 00000000..ac0f09eb --- /dev/null +++ b/vscript/languages/squirrel/sq/sq.vcproj @@ -0,0 +1,458 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/sq/sq71.vcproj b/vscript/languages/squirrel/sq/sq71.vcproj new file mode 100644 index 00000000..b7da7094 --- /dev/null +++ b/vscript/languages/squirrel/sq/sq71.vcproj @@ -0,0 +1,317 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/sqdbg/doc/sqdbg.chm b/vscript/languages/squirrel/sqdbg/doc/sqdbg.chm new file mode 100644 index 0000000000000000000000000000000000000000..3f4b25d21b0acbf5c03b05d6d8716a0b99f6dd50 GIT binary patch literal 19006 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 literal 0 HcmV?d00001 diff --git a/vscript/languages/squirrel/sqdbg/doc/sqdbg.pdf b/vscript/languages/squirrel/sqdbg/doc/sqdbg.pdf new file mode 100644 index 00000000..14266017 --- /dev/null +++ b/vscript/languages/squirrel/sqdbg/doc/sqdbg.pdf @@ -0,0 +1,494 @@ +%PDF-1.3 +%ª«¬­ +4 0 obj +<< /Type /Info +/Producer (FOP 0.20.5) >> +endobj +5 0 obj +<< /Length 196 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GaqdY]+0EX&;B(lT41D@*+tSN;/4Ut;R\G?OEDk#&6F++6)>^%qht(5^"An`O:%O/^cqrFJZf5C'FZgXJMj2O1`/_b3XrfU>BYFS9hM,(@3_nF3gBoT9Bc3qXP4mt@uMS5.jO.p#ClaLCf.d3?VEJJ<[f`FTjmgRGAS)Ccn@nXebn8]oeWu"qgWh^iWC>m0t%~> +endstream +endobj +6 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 5 0 R +>> +endobj +7 0 obj +<< /Length 1032 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gasao968i1&AJ$CE(_rr;`u\TDGNtK1[1kLh:`p3KHqH]*!CH`mu*-((.W6uT(0&.o'MVOh.MXI+(H"fnJYuh,!bfF7"P/f.#\3ITJY<\-jii&U@5SKShuXoniO49dM2/YRh4D)V6*SD;n]*>Y%oLMAVbt#oFkf.N5l'T"1[mbHe[m"]Ltb5Dg>*S&d(Z[C`:rl'b09+++Z$SDqFFH40_"A<]A/Art-QNPG01U=6;/UWrG.#,2^ZM^.E;WVq-(C$jTJk3uk.)]'Vq_N^QdDo.BZ6**>d*W4O5OMY/o$W&lcb#d'bWF=/Kbhg7qA%pVZOEP(DXpLI`sUf/WLPn+n"3oN(ZcqaCVE=QR1Gf^S8_NnM)\S#;blp\i1agl%]q,ps5?'9@g582-SVc-qn9mbJs,$E7'g*nL#=so:Y=@)[H&/DQ]!-2g2Sr[G'inYY"eVaU[rhBW8g>L1#X*UbuiN2W(tu\\JID7K'9dtlZ0(o<>D6FW@SnF!+g*2X!#Pqeh83A[9U59+:+jIS<:0hrKS_M0b1+u.`l_55eED8/Z+c)QCq_Ks$[<'!O'6s!gV\K*5-nX(X71TcDeOLO"B)EG`"&ZpM8[t6P7fS_@RIJJ6]YXe3PU19QJ^k\lVYl";#Te`d12]At[%@]l=u=TjIq'E5Gcq(/\-uNcKFU[\/F1;`cU\7\DXMeJ7.bZsdD*C*!@)L'8O:T`Z"eQA0r`>pqBF"<&&:SN(Xnf'UP+cb[8.)<%*['SRURShGgs+,./IB>kiUR#<5h\Q^9dN!:2H#LkOfCDtFUTr-p6%jej'EFOU[qe*&Uo[XC%$P:a;b(6gJgM(,gLVGbMe+")*-1VY"'1eY)BY;c[f3EQG6@\ufcb%;uGCR;d\^?otfbREY^KEbR,`[gm:u/4`kSJlJD9;#G8P8TVFb&.JrZ3l/CnLa#NV#El=i7A-3)+at]KTka-i6>G^BDgQQ([eq*LN+fW*4ROgh2t.Rl-50g&1q"H]<^~> +endstream +endobj +8 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 7 0 R +>> +endobj +9 0 obj +<< /Length 71 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Garg^iGoCd.c`?]8EV`b1=.gR0K1`91K?+0ZOMGdU/Zh'Y!=Te%#&:?HH*JE! +endstream +endobj +10 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 9 0 R +>> +endobj +11 0 obj +<< /Length 500 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb"/h4)]a*&:etR`JnDaMdI=@V@P+]qN/1d6QUtO9qeC?l-HOB8Xr1GUoFN2F^k/oR):!5dpWGA34n<<'k%F4/;PDZ-q*d'TGWM.N`2)J$2PAX6Tl@69b7(o.?[:Q+=sjiiC-o!VPl_*n-&U-VNsIlS&JuGB;NfU@Z_5%BUb;#QUJE0W1T%k>ak1qSt!klKQO7$h9>R6&eYfioViB3kt3uUd59gL.kd@GKrGhDZYU&F\m@<.'%5[1j,RQQGKeEW5^>5eB1:\31c"`I=#9MT%Cb0Dam9TGl$q.OlD;p1n':)d@HqE,^%fBI+X-5P38:Y+p95\Q^;:cXomD3IoRdC4RE?5-7K?$8oo>,qOA:j;VVqc,$(5gPR]Y%34Dd>M6MdNgRVkSAD#:SJC;0$JK(5u[NJ)tsQ/\rgnD=.lDB,PW,n`V`Oep2c(>K,s]g"4eKHH_nFs`9O/La4cKPHc4>PNDk"5=c#SH~> +endstream +endobj +12 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 11 0 R +/Annots 13 0 R +>> +endobj +13 0 obj +[ +14 0 R +16 0 R +18 0 R +20 0 R +22 0 R +24 0 R +26 0 R +] +endobj +14 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 655.001 187.48 645.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 15 0 R +/H /I +>> +endobj +16 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 644.001 183.43 634.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 17 0 R +/H /I +>> +endobj +18 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 633.001 242.31 623.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 19 0 R +/H /I +>> +endobj +20 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 622.001 230.65 612.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 21 0 R +/H /I +>> +endobj +22 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 611.001 189.14 601.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 23 0 R +/H /I +>> +endobj +24 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 600.001 183.43 590.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 25 0 R +/H /I +>> +endobj +26 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 589.001 142.77 579.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 27 0 R +/H /I +>> +endobj +28 0 obj +<< /Length 1965 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gatm<>B?Pt'RnB3@(-Z']8csPhKBu]nRgV!g.>!3Th?_b6+1J^&:s5GSc8@)&0QODZIA(57H^=bqfFHR0:\fD:TB(*A6Gqn/<47TH)*tdr"R8k8@MgM1XHgZQa8+'q'!+b6C&a1n54Ff.,Hn,)gTKUg?e+B[!&,+f-ID*(ne=\34NBj#["i':*>NKt`n/8W4Q=!.5ZPW\1$^J6+TRCD@]8/YUp\m,!In[ZRD%9PS`pF`@la>er(^YfTcSW`LVe]Cq"nAd'"CL+iB^A0>7*Z:Aa-IO"L2t_*$cm%9=rSpH[Q%1O"OG(hUJfH(\o$2&pW19+/B\3OLfM?o+E-JSQ][rc9&bljbM0AnD9%XG,K/O,-kGq0%VN&'rPEb3$M1L64^ZTIZWqXdM)lenrTIB27k`]B!@=?$[Fsn.dTkBuAE$5/\15KP?8aB'PKfsM3@"=USt^!MdW*`7LmT#Rh=_NgoSmf-=,42MEHF8ME*l46u8DslKuMbUlLh#H0j&7HpE:_&aUC9.4VMXY6F"=:jTuZkVa",SIu?_K?cZIP3NNk$GP7lQE&Q"I]B1OIgRja'6ipQ?7,bp`5V-R]Jpuir1>WDgq(=b2cB9SHi'eJlbfM9T[WTJi1\>=:bi607+)u@Kpt>*Pu'8j8JEq[7LJ1,mjC3pN=<]4,9iFVC!6RRZ0.,Q8(YLDHr^JjrpXT,joW?gW&2=`c-rmh6pU!c2r?fMH*KG=B\orR<,+'05\::'\2F.ggb8d-d:doqo`jl7\/2s6Jg0hU>M;u)W&e1oNF;]glO8-E[;KeUY:gQP?iNDm'^%?EfWmW%96D\-P[qhAs+YTDO$j0J\X1#>4OrNOaX>V(5NaY%)"oa7)n)(0-&^XLP[&bIHpAXFFh)fM&4;g6@o:,8gUD[]*T1>E])I5I1?]XV8B0&&WQ/11Eic]Y:E([t3hQ*CC9sI]/C;%?@-Kc1(U0m'ocLg)hlJ*9MX0P]8#q'[VqD*1_Xe[EbbFqiG`p%YKpcG#%3HRUuTrJfV>o;J^GmU4$qPPd?Y"+]'rOF_U:>BSj0`j^KMM6WPKe_mU*pO*XWN+dc0KYkecS%KT&fUp[qiITW3-Zbb=m:3e^f<(D0ffdf~> +endstream +endobj +29 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 28 0 R +>> +endobj +30 0 obj +<< /Length 822 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gas1]>u03/'RfGR0MI[.$/@MKj$XOk1c6?g.dc4fP6e0\j-4:).8C3\e,K67-H--nP_[3&\`]R]fb^4970nt_>p-G5$Pj`c>l>dqr'4UEf7OJ4nHA9M/>#)IZVnlBooC`8#NDW^HSpEtH8)!$pmYNRnfqmBkm&7<_gT[q>.iXaqZEW&6\KZZH+M5dX;"%M$8(FV[EP[&EMd`?361Q6d(eq!;r=\`SSYj"k&g=19To<5l(2_1,i)6O)Ld8]D.?dbjs--T/<]GY%q#qD2&KieLNYCMWBqKsAMmE:11-E]U*.N^R,KiD75B4\2$&&Y&7OHS-`ji734*Jao.(p_0DT+sXZ!kgMK?LR+!E5n)d`.rutgk[Iu%d0UL3D>1eqW7cs_#'>=9E*,i6oW_F./(rq_]b(/C_mp"LdP+&GW^s5;8i9\%hbdfT%4(6^>hSF6)1`LVle#+X[-=/LeY/5C!1>t?h`R>5^6cP)^!oO2H6hi>KYXgoLCS48.3DPe<7U>D,noJ'TR0A+]BdDuZ:_$/;>7g`C&7cR*ad.`W9UigRtL*(4UO@MA]#Vt0s``2FMlF[PEF\DV3%F\YdQD>+#d2']]QgufbKX26Jj&!^+)a%,$K4V+Ud[9in?=%@2+G<@d[N0TRS^jl[?=]1TuQ!K_n%;(Y]i$(kZ6^>R$^'Xhm^Kpf7,fi%,:1'Bcd*=d]!s=A34/oTTa`cLmq0bDG?d`Fc01euYig/@U7/m99iIp:~> +endstream +endobj +31 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 30 0 R +>> +endobj +32 0 obj +<< /Length 1571 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatTIgMYb(o\ElJ[jFAWLn_',;q!'tL)/%QmE7U+Zpi_;AC6MfBA(n'OsoikAfM%CJ;!+Tgi[MYj`GN_9cVJLED2neEoK-\$$KSHK:U(NXqSe]$N8&6DOeI;5-='MZJs@opS%p>Z($ElM2-iTa4m(,igq`)_=@akFoHBXJ$g2#'To'>37J]HaRt`tgLiFJ2irq!VdRejE]:P!!`GPeM\(4`<2;A`%McC*1@Q6V7o3snRaS)4i];'uN<\fZYON.DL]i1m?hs?#8E[%G4QfW>BW,_?+:/TN2"dIOGP>0G^J1mq?iJFX'&u,DSkI))(.C+p]dO_=c>'cEDsm(t^ARc+^+.-?c#g6Q"$i-d!Ca$;(YLqt^+jS"$bBcHZHD(KVfh`>9Bq`M0]3q"*Z_9:Jaeb%4-VJh9@@:gUk'Jqh467_q7`ckgU?tc0mZ.BKYt/':"HuAb!>%[e*Y-!Xg+sm@'`)XV.;SW$$h3sW^l`^*q!@XcaQW'E`c*")7rFb=o[;R+(4)1__@j5*uh0_P?!aGCcYYfnJcB(m$d&ce-,qA&*8$sCrmn(e8Ja1L),h]@f^am;dFMtq/1jVlO3*Ml&`P7B3A3lVG0nsJB2EJ1XEA#lj]5-6*opsTPMn>>u/s%j^`OLmb!O704PgQ$uckV2giO8V!I$k*]'C?MoI8qB)f/*-!?*6l6H)(2AREZ,t)L@`EMa7?s8EhE,E(P$@q1]#I`7c+TE`em9FY+=K>-*G692G&%HcfB3=Buc4/d-KYG!!IY&o\;Li;tk;!VO0_7%"<%?&hsK%ukX(VEVH%8tqe:QlD/oX-*KN2=@&r"03AWPJQe3B.gsYu$:KV^r";$+jPAB`'>gK;XA"g[>A?R[)g2NN`V/8bMJfngV123gcpOf[cA]lpLImO8'de_kWM[ie8ceO'2%6U"&?bjnk?+6I]a@7_;a4Y%0#RF)0qaWi^qO2q%/u*km,l*np.'(lu46d:;#(6@[3B)m,I_:od#+ZYk'RQ/Hf%*ia8(neCFpK+4UCJSh[)\RfX2JhK+d3Odbq(Fh(oN=#&WW&t,@?]W*uZ0oVA3(GccWH4LGN-_a"5gYaYN>"EEH==#)p>od\+3^8M!$hP+gSrVX'B#rn\JCnPHG_&,)?5cOT7^8=W'2nXbEraqZLs$ASY![S_*Q[U +endstream +endobj +33 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 32 0 R +>> +endobj +34 0 obj +<< /Length 941 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatU1hf"u<&:Vr4_.+[3'SCsKHYTs3l[GdJbFY$!EkkMP`2:Og[/KYR`oK6K>A4``]!HhBh0hKESRo.f$P[h6n,kH]nT'eQ`mUC>o-`Z;2AhhEq`+;/e:B;>4$oLU"*b6rm9kI)h::\`B94:)@:^fkW1B"\TTP*c50gdT"O52Q2rOqE`@3BBLJ.a>g*'Ts`gL;3B"r&b>56S-L.dl0+7Hd%^Zub>buY;*CT,`CD-C&P]E27"D9/nflgN1MlCL"?4''t+Yt[T+ja_@&cABm+EB:?Ih'Zgp,s8*-D]hqBo]?tg^%BJB?M`3@4]'KTZD#PjF(@l5>\FWO/RZt*Vj1Jd*+sbdf&>SNe1I4b/(XaBLQN6;UX^]0cgD+24"mEbO4>_Ve/8aWjZK"qpANCOQ8f1.n(>^4Q6c.Gg%F\_Et4q@hM?/dO.\,bM/tC0J?PQNNm5*`a2]">KC4Z7Yd90R5I!$S>jM_p\dWVq3R-qS:NV:mGD-b(VU/=[[n#Z/@>[QUY<&224,V&'="fN)e`,Bm'?DL5/H*Y!FeLd3ZgUFc@9ckdj-h/mX_ZB)"/?+h[:]=p?\*#thc.Nc]=p`FS1L&(JRN5Kau1,5+U^l1m!<8/ikcTJ5D?^N0(Nq>X$e#2(U!WRnCELkQm#7:+!(\+7ClJ?@<@uH?JkRY5-16q~> +endstream +endobj +35 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 34 0 R +>> +endobj +36 0 obj +<< /Length 287 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GasJM_/@+D%#44r$6MQC-Ae9M>`gpYgns0k9o.14H6=5F&:=>/Q>R*XTj4\os1ZFngl(D1JS'"a^m@C)7OX@4.EF>F0)mWht;E]SO,5b#q412`=ou,c,oV3.-h`4ms=llYUJ~> +endstream +endobj +37 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 36 0 R +/Annots 38 0 R +>> +endobj +38 0 obj +[ +] +endobj +41 0 obj +<< + /Title (\376\377\0\123\0\161\0\165\0\151\0\162\0\162\0\145\0\154\0\40\0\122\0\145\0\155\0\157\0\164\0\145\0\40\0\104\0\145\0\142\0\165\0\147\0\147\0\145\0\162\0\40\0\61\0\56\0\60) + /Parent 39 0 R + /Next 43 0 R + /A 40 0 R +>> endobj +43 0 obj +<< + /Title (\376\377\0\124\0\141\0\142\0\154\0\145\0\40\0\157\0\146\0\40\0\103\0\157\0\156\0\164\0\145\0\156\0\164\0\163) + /Parent 39 0 R + /Prev 41 0 R + /Next 44 0 R + /A 42 0 R +>> endobj +44 0 obj +<< + /Title (\376\377\0\103\0\150\0\141\0\160\0\164\0\145\0\162\0\240\0\61\0\56\0\240\0\124\0\150\0\145\0\40\0\104\0\145\0\142\0\165\0\147\0\147\0\145\0\162) + /Parent 39 0 R + /First 45 0 R + /Last 47 0 R + /Prev 43 0 R + /Next 48 0 R + /Count -3 + /A 15 0 R +>> endobj +45 0 obj +<< + /Title (\376\377\0\117\0\166\0\145\0\162\0\166\0\151\0\145\0\167) + /Parent 44 0 R + /Next 46 0 R + /A 17 0 R +>> endobj +46 0 obj +<< + /Title (\376\377\0\111\0\156\0\164\0\145\0\147\0\162\0\141\0\164\0\151\0\156\0\147\0\40\0\164\0\150\0\145\0\40\0\144\0\145\0\142\0\165\0\147\0\147\0\145\0\162) + /Parent 44 0 R + /Prev 45 0 R + /Next 47 0 R + /A 19 0 R +>> endobj +47 0 obj +<< + /Title (\376\377\0\124\0\150\0\145\0\40\0\156\0\145\0\164\0\167\0\157\0\162\0\153\0\40\0\160\0\162\0\157\0\164\0\157\0\143\0\157\0\154) + /Parent 44 0 R + /Prev 46 0 R + /A 21 0 R +>> endobj +48 0 obj +<< + /Title (\376\377\0\103\0\150\0\141\0\160\0\164\0\145\0\162\0\240\0\62\0\56\0\240\0\101\0\120\0\111\0\40\0\122\0\145\0\146\0\145\0\162\0\145\0\156\0\143\0\145) + /Parent 39 0 R + /First 49 0 R + /Last 49 0 R + /Prev 44 0 R + /Next 50 0 R + /Count -1 + /A 23 0 R +>> endobj +49 0 obj +<< + /Title (\376\377\0\104\0\145\0\142\0\165\0\147\0\147\0\145\0\162) + /Parent 48 0 R + /A 25 0 R +>> endobj +50 0 obj +<< + /Title (\376\377\0\111\0\156\0\144\0\145\0\170) + /Parent 39 0 R + /Prev 48 0 R + /A 27 0 R +>> endobj +51 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F3 +/BaseFont /Helvetica-Bold +/Encoding /WinAnsiEncoding >> +endobj +52 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F5 +/BaseFont /Times-Roman +/Encoding /WinAnsiEncoding >> +endobj +53 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F10 +/BaseFont /Courier-Oblique +/Encoding /WinAnsiEncoding >> +endobj +54 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F6 +/BaseFont /Times-Italic +/Encoding /WinAnsiEncoding >> +endobj +55 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F1 +/BaseFont /Helvetica +/Encoding /WinAnsiEncoding >> +endobj +56 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F11 +/BaseFont /Courier-Bold +/Encoding /WinAnsiEncoding >> +endobj +57 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F9 +/BaseFont /Courier +/Encoding /WinAnsiEncoding >> +endobj +1 0 obj +<< /Type /Pages +/Count 9 +/Kids [6 0 R 8 0 R 10 0 R 12 0 R 29 0 R 31 0 R 33 0 R 35 0 R 37 0 R ] >> +endobj +2 0 obj +<< /Type /Catalog +/Pages 1 0 R + /Outlines 39 0 R + /PageMode /UseOutlines + >> +endobj +3 0 obj +<< +/Font << /F3 51 0 R /F5 52 0 R /F10 53 0 R /F1 55 0 R /F6 54 0 R /F9 57 0 R /F11 56 0 R >> +/ProcSet [ /PDF /ImageC /Text ] >> +endobj +15 0 obj +<< +/S /GoTo +/D [29 0 R /XYZ 115.0 725.0 null] +>> +endobj +17 0 obj +<< +/S /GoTo +/D [29 0 R /XYZ 115.0 666.009 null] +>> +endobj +19 0 obj +<< +/S /GoTo +/D [29 0 R /XYZ 115.0 589.684 null] +>> +endobj +21 0 obj +<< +/S /GoTo +/D [31 0 R /XYZ 115.0 448.64 null] +>> +endobj +23 0 obj +<< +/S /GoTo +/D [33 0 R /XYZ 115.0 725.0 null] +>> +endobj +25 0 obj +<< +/S /GoTo +/D [33 0 R /XYZ 115.0 687.009 null] +>> +endobj +27 0 obj +<< +/S /GoTo +/D [37 0 R /XYZ 67.0 725.0 null] +>> +endobj +39 0 obj +<< + /First 41 0 R + /Last 50 0 R +>> endobj +40 0 obj +<< +/S /GoTo +/D [10 0 R /XYZ 115.0 725.0 null] +>> +endobj +42 0 obj +<< +/S /GoTo +/D [12 0 R /XYZ 115.0 715.0 null] +>> +endobj +xref +0 58 +0000000000 65535 f +0000012880 00000 n +0000012993 00000 n +0000013085 00000 n +0000000015 00000 n +0000000071 00000 n +0000000358 00000 n +0000000464 00000 n +0000001588 00000 n +0000001694 00000 n +0000001855 00000 n +0000001962 00000 n +0000002554 00000 n +0000002677 00000 n +0000002746 00000 n +0000013232 00000 n +0000002882 00000 n +0000013297 00000 n +0000003018 00000 n +0000013364 00000 n +0000003154 00000 n +0000013431 00000 n +0000003290 00000 n +0000013497 00000 n +0000003426 00000 n +0000013562 00000 n +0000003562 00000 n +0000013629 00000 n +0000003698 00000 n +0000005756 00000 n +0000005864 00000 n +0000006778 00000 n +0000006886 00000 n +0000008550 00000 n +0000008658 00000 n +0000009691 00000 n +0000009799 00000 n +0000010178 00000 n +0000010301 00000 n +0000013693 00000 n +0000013744 00000 n +0000010321 00000 n +0000013809 00000 n +0000010565 00000 n +0000010761 00000 n +0000011032 00000 n +0000011162 00000 n +0000011400 00000 n +0000011600 00000 n +0000011877 00000 n +0000011993 00000 n +0000012105 00000 n +0000012218 00000 n +0000012328 00000 n +0000012443 00000 n +0000012554 00000 n +0000012662 00000 n +0000012774 00000 n +trailer +<< +/Size 58 +/Root 2 0 R +/Info 4 0 R +>> +startxref +13874 +%%EOF diff --git a/vscript/languages/squirrel/sqdbg/main.cpp b/vscript/languages/squirrel/sqdbg/main.cpp new file mode 100644 index 00000000..9a133983 --- /dev/null +++ b/vscript/languages/squirrel/sqdbg/main.cpp @@ -0,0 +1,95 @@ +/* + see copyright notice in sqrdbg.h +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include "sqrdbg.h" +#include "sqdbgserver.h" + +#pragma comment (lib ,"Ws2_32.lib") + +#ifdef _UNICODE +#define scfprintf fwprintf +#define scvprintf vwprintf +#else +#define scfprintf fprintf +#define scvprintf vprintf +#endif + + +void printfunc(HSQUIRRELVM v,const SQChar *s,...) +{ + va_list vl; + va_start(vl, s); + scvprintf( s, vl); + va_end(vl); +} + +void PrintError(HSQUIRRELVM v) +{ + const SQChar *err; + sq_getlasterror(v); + if(SQ_SUCCEEDED(sq_getstring(v,-1,&err))) { + scprintf(_SC("SQDBG error : %s"),err); + }else { + scprintf(_SC("SQDBG error"),err); + } + sq_pop(v,1); +} + +int main(int argc, char *argv[]) +{ + if(argc < 2){ + scprintf(_SC("SQDBG error : no file specified")); + return -1; + } + + HSQUIRRELVM v = sq_open(1024); + sqstd_seterrorhandlers(v); + + //!! INITIALIZES THE DEBUGGER ON THE TCP PORT 1234 + //!! ENABLES AUTOUPDATE + HSQREMOTEDBG rdbg = sq_rdbg_init(v,1234,SQTrue); + if(rdbg) { + + //!! ENABLES DEBUG INFO GENERATION(for the compiler) + sq_enabledebuginfo(v,SQTrue); + + sq_setprintfunc(v,printfunc); + + //!! SUSPENDS THE APP UNTIL THE DEBUGGER CLIENT CONNECTS + if(SQ_SUCCEEDED(sq_rdbg_waitforconnections(rdbg))) { + scprintf(_SC("connected\n")); + + const SQChar *fname=NULL; +#ifdef _UNICODE + SQChar sTemp[256]; + mbstowcs(sTemp,argv[1],(int)strlen(argv[1])+1); + fname=sTemp; +#else + fname=argv[1]; +#endif + //!!REGISTERS STANDARDS LIBS + sq_pushroottable(v); + sqstd_register_bloblib(v); + sqstd_register_iolib(v); + //!!EXECUTE A SCTIPT + if(SQ_FAILED(sqstd_dofile(v,fname,SQFalse,SQTrue))) { + PrintError(v); + } + } + //!! CLEANUP + sq_rdbg_shutdown(rdbg); + } + else { + PrintError(v); + } + sq_close(v); + return 0; +} diff --git a/vscript/languages/squirrel/sqdbg/makebin.pl b/vscript/languages/squirrel/sqdbg/makebin.pl new file mode 100644 index 00000000..d57e9e8a --- /dev/null +++ b/vscript/languages/squirrel/sqdbg/makebin.pl @@ -0,0 +1,13 @@ +#!perl +open( HANDLE,shift) || die; +undef $/; +binmode HANDLE; +$data=; +$ctr=0; +for($i=0;$i +#include +#include +#include +#include "tier0/threadtools.h" +typedef int SOCKET; +#define INVALID_SOCKET -1 +#endif diff --git a/vscript/languages/squirrel/sqdbg/serialize_state.inl b/vscript/languages/squirrel/sqdbg/serialize_state.inl new file mode 100644 index 00000000..85020b32 --- /dev/null +++ b/vscript/languages/squirrel/sqdbg/serialize_state.inl @@ -0,0 +1,266 @@ +static const SQChar serialize_state_nut[] = { + 0x2f,0x2a,0x0d,0x0a,0x09,0x73,0x65,0x65,0x20,0x63,0x6f,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x6e, + 0x6f,0x74,0x69,0x63,0x65,0x20,0x69,0x6e,0x20,0x73,0x71,0x72,0x64,0x62,0x67,0x2e,0x68,0x0d,0x0a,0x2a, + 0x2f,0x0d,0x0a,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x63,0x75,0x72,0x72,0x65,0x6e,0x74,0x73,0x63,0x6f,0x70, + 0x65,0x3b,0x0d,0x0a,0x69,0x66,0x20,0x28,0x20,0x3a,0x3a,0x67,0x65,0x74,0x72,0x6f,0x6f,0x74,0x74,0x61, + 0x62,0x6c,0x65,0x28,0x29,0x2e,0x70,0x61,0x72,0x65,0x6e,0x74,0x20,0x29,0x0d,0x0a,0x7b,0x0d,0x0a,0x09, + 0x63,0x75,0x72,0x72,0x65,0x6e,0x74,0x73,0x63,0x6f,0x70,0x65,0x20,0x3d,0x20,0x3a,0x3a,0x67,0x65,0x74, + 0x72,0x6f,0x6f,0x74,0x74,0x61,0x62,0x6c,0x65,0x28,0x29,0x3b,0x0d,0x0a,0x09,0x3a,0x3a,0x73,0x65,0x74, + 0x72,0x6f,0x6f,0x74,0x74,0x61,0x62,0x6c,0x65,0x28,0x20,0x3a,0x3a,0x67,0x65,0x74,0x72,0x6f,0x6f,0x74, + 0x74,0x61,0x62,0x6c,0x65,0x28,0x29,0x2e,0x70,0x61,0x72,0x65,0x6e,0x74,0x20,0x29,0x3b,0x0d,0x0a,0x7d, + 0x0d,0x0a,0x74,0x72,0x79,0x20,0x7b,0x0d,0x0a,0x09,0x0d,0x0a,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x6f,0x62, + 0x6a,0x73,0x5f,0x72,0x65,0x67,0x20,0x3d,0x20,0x7b,0x20,0x6d,0x61,0x78,0x69,0x64,0x3d,0x30,0x20,0x2c, + 0x72,0x65,0x66,0x73,0x3d,0x7b,0x7d,0x20,0x7d,0x0d,0x0a,0x0d,0x0a,0x63,0x6f,0x6d,0x70,0x6c,0x65,0x78, + 0x5f,0x74,0x79,0x70,0x65,0x73,0x20,0x3c,0x2d,0x20,0x7b,0x0d,0x0a,0x09,0x5b,0x22,0x74,0x61,0x62,0x6c, + 0x65,0x22,0x5d,0x20,0x3d,0x20,0x6e,0x75,0x6c,0x6c,0x2c,0x0d,0x0a,0x09,0x5b,0x22,0x61,0x72,0x72,0x61, + 0x79,0x22,0x5d,0x20,0x3d,0x20,0x6e,0x75,0x6c,0x6c,0x2c,0x0d,0x0a,0x09,0x5b,0x22,0x63,0x6c,0x61,0x73, + 0x73,0x22,0x5d,0x20,0x3d,0x20,0x6e,0x75,0x6c,0x6c,0x2c,0x0d,0x0a,0x09,0x5b,0x22,0x69,0x6e,0x73,0x74, + 0x61,0x6e,0x63,0x65,0x22,0x5d,0x20,0x3d,0x20,0x6e,0x75,0x6c,0x6c,0x2c,0x0d,0x0a,0x09,0x5b,0x22,0x77, + 0x65,0x61,0x6b,0x72,0x65,0x66,0x22,0x5d,0x20,0x3d,0x20,0x6e,0x75,0x6c,0x6c,0x2c,0x0d,0x0a,0x7d,0x0d, + 0x0a,0x0d,0x0a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x62,0x75,0x69,0x6c,0x64,0x5f,0x72,0x65, + 0x66,0x73,0x28,0x74,0x29,0x3a,0x28,0x6f,0x62,0x6a,0x73,0x5f,0x72,0x65,0x67,0x29,0x0d,0x0a,0x7b,0x0d, + 0x0a,0x09,0x69,0x66,0x28,0x74,0x20,0x3d,0x3d,0x20,0x3a,0x3a,0x67,0x65,0x74,0x72,0x6f,0x6f,0x74,0x74, + 0x61,0x62,0x6c,0x65,0x28,0x29,0x29,0x0d,0x0a,0x09,0x09,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0d,0x0a, + 0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x6f,0x74,0x79,0x70,0x65,0x20,0x3d,0x20,0x3a,0x3a,0x74,0x79,0x70, + 0x65,0x28,0x74,0x29,0x3b,0x0d,0x0a,0x09,0x69,0x66,0x28,0x6f,0x74,0x79,0x70,0x65,0x20,0x69,0x6e,0x20, + 0x63,0x6f,0x6d,0x70,0x6c,0x65,0x78,0x5f,0x74,0x79,0x70,0x65,0x73,0x29,0x0d,0x0a,0x09,0x7b,0x0d,0x0a, + 0x09,0x09,0x69,0x66,0x28,0x21,0x28,0x74,0x20,0x69,0x6e,0x20,0x6f,0x62,0x6a,0x73,0x5f,0x72,0x65,0x67, + 0x2e,0x72,0x65,0x66,0x73,0x29,0x29,0x20,0x7b,0x0d,0x0a,0x09,0x09,0x09,0x6f,0x62,0x6a,0x73,0x5f,0x72, + 0x65,0x67,0x2e,0x72,0x65,0x66,0x73,0x5b,0x74,0x5d,0x20,0x3c,0x2d,0x20,0x6f,0x62,0x6a,0x73,0x5f,0x72, + 0x65,0x67,0x2e,0x6d,0x61,0x78,0x69,0x64,0x2b,0x2b,0x3b,0x0d,0x0a,0x09,0x09,0x0d,0x0a,0x09,0x09,0x20, + 0x20,0x20,0x20,0x69,0x74,0x65,0x72,0x61,0x74,0x65,0x6f,0x62,0x6a,0x65,0x63,0x74,0x28,0x74,0x2c,0x66, + 0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x6f,0x2c,0x69,0x2c,0x76,0x61,0x6c,0x29,0x3a,0x28,0x6f,0x62, + 0x6a,0x73,0x5f,0x72,0x65,0x67,0x29,0x0d,0x0a,0x09,0x09,0x20,0x20,0x20,0x20,0x7b,0x0d,0x0a,0x09,0x09, + 0x09,0x20,0x20,0x20,0x20,0x62,0x75,0x69,0x6c,0x64,0x5f,0x72,0x65,0x66,0x73,0x28,0x76,0x61,0x6c,0x29, + 0x3b,0x0d,0x0a,0x09,0x09,0x09,0x20,0x20,0x20,0x20,0x62,0x75,0x69,0x6c,0x64,0x5f,0x72,0x65,0x66,0x73, + 0x28,0x69,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x20,0x20,0x20,0x20,0x7d,0x29,0x0d,0x0a,0x09,0x09,0x7d,0x0d, + 0x0a,0x09,0x09,0x0d,0x0a,0x09,0x7d,0x0d,0x0a,0x7d,0x0d,0x0a,0x0d,0x0a,0x66,0x75,0x6e,0x63,0x74,0x69, + 0x6f,0x6e,0x20,0x67,0x65,0x74,0x76,0x61,0x6c,0x75,0x65,0x28,0x76,0x29,0x3a,0x28,0x6f,0x62,0x6a,0x73, + 0x5f,0x72,0x65,0x67,0x29,0x0d,0x0a,0x7b,0x0d,0x0a,0x09,0x73,0x77,0x69,0x74,0x63,0x68,0x28,0x3a,0x3a, + 0x74,0x79,0x70,0x65,0x28,0x76,0x29,0x29,0x0d,0x0a,0x09,0x7b,0x0d,0x0a,0x09,0x09,0x63,0x61,0x73,0x65, + 0x20,0x22,0x74,0x61,0x62,0x6c,0x65,0x22,0x3a,0x0d,0x0a,0x09,0x09,0x63,0x61,0x73,0x65,0x20,0x22,0x61, + 0x72,0x72,0x61,0x79,0x22,0x3a,0x0d,0x0a,0x09,0x09,0x63,0x61,0x73,0x65,0x20,0x22,0x63,0x6c,0x61,0x73, + 0x73,0x22,0x3a,0x0d,0x0a,0x09,0x09,0x63,0x61,0x73,0x65,0x20,0x22,0x69,0x6e,0x73,0x74,0x61,0x6e,0x63, + 0x65,0x22,0x3a,0x0d,0x0a,0x09,0x09,0x09,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6f,0x62,0x6a,0x73,0x5f, + 0x72,0x65,0x67,0x2e,0x72,0x65,0x66,0x73,0x5b,0x76,0x5d,0x2e,0x74,0x6f,0x73,0x74,0x72,0x69,0x6e,0x67, + 0x28,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x63,0x61,0x73,0x65,0x20,0x22,0x69,0x6e,0x74,0x65,0x67,0x65,0x72, + 0x22,0x3a,0x0d,0x0a,0x09,0x09,0x63,0x61,0x73,0x65,0x20,0x22,0x66,0x6c,0x6f,0x61,0x74,0x22,0x3a,0x0d, + 0x0a,0x09,0x09,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x76,0x3b,0x0d,0x0a,0x09,0x09, + 0x63,0x61,0x73,0x65,0x20,0x22,0x62,0x6f,0x6f,0x6c,0x22,0x3a,0x0d,0x0a,0x09,0x09,0x20,0x20,0x20,0x20, + 0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x76,0x2e,0x74,0x6f,0x73,0x74,0x72,0x69,0x6e,0x67,0x28,0x29,0x3b, + 0x0d,0x0a,0x09,0x09,0x63,0x61,0x73,0x65,0x20,0x22,0x73,0x74,0x72,0x69,0x6e,0x67,0x22,0x3a,0x0d,0x0a, + 0x09,0x09,0x09,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x76,0x3b,0x0d,0x0a,0x09,0x09,0x63,0x61,0x73,0x65, + 0x20,0x22,0x6e,0x75,0x6c,0x6c,0x22,0x3a,0x0d,0x0a,0x09,0x09,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75, + 0x72,0x6e,0x20,0x22,0x6e,0x75,0x6c,0x6c,0x22,0x3b,0x0d,0x0a,0x09,0x09,0x64,0x65,0x66,0x61,0x75,0x6c, + 0x74,0x3a,0x0d,0x0a,0x09,0x09,0x09,0x0d,0x0a,0x09,0x09,0x09,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70, + 0x61,0x63,0x6b,0x5f,0x74,0x79,0x70,0x65,0x28,0x3a,0x3a,0x74,0x79,0x70,0x65,0x28,0x76,0x29,0x29,0x3b, + 0x0d,0x0a,0x09,0x7d,0x0d,0x0a,0x7d,0x0d,0x0a,0x0d,0x0a,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x70,0x61,0x63, + 0x6b,0x65,0x64,0x5f,0x74,0x79,0x70,0x65,0x73,0x3d,0x7b,0x0d,0x0a,0x09,0x5b,0x22,0x6e,0x75,0x6c,0x6c, + 0x22,0x5d,0x3d,0x22,0x6e,0x22,0x2c,0x0d,0x0a,0x09,0x5b,0x22,0x73,0x74,0x72,0x69,0x6e,0x67,0x22,0x5d, + 0x3d,0x22,0x73,0x22,0x2c,0x0d,0x0a,0x09,0x5b,0x22,0x69,0x6e,0x74,0x65,0x67,0x65,0x72,0x22,0x5d,0x3d, + 0x22,0x69,0x22,0x2c,0x0d,0x0a,0x09,0x5b,0x22,0x66,0x6c,0x6f,0x61,0x74,0x22,0x5d,0x3d,0x22,0x66,0x22, + 0x2c,0x0d,0x0a,0x09,0x5b,0x22,0x75,0x73,0x65,0x72,0x64,0x61,0x74,0x61,0x22,0x5d,0x3d,0x22,0x75,0x22, + 0x2c,0x0d,0x0a,0x09,0x5b,0x22,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x22,0x5d,0x3d,0x22,0x66,0x6e, + 0x22,0x2c,0x0d,0x0a,0x09,0x5b,0x22,0x74,0x61,0x62,0x6c,0x65,0x22,0x5d,0x3d,0x22,0x74,0x22,0x2c,0x0d, + 0x0a,0x09,0x5b,0x22,0x61,0x72,0x72,0x61,0x79,0x22,0x5d,0x3d,0x22,0x61,0x22,0x2c,0x0d,0x0a,0x09,0x5b, + 0x22,0x67,0x65,0x6e,0x65,0x72,0x61,0x74,0x6f,0x72,0x22,0x5d,0x3d,0x22,0x67,0x22,0x2c,0x0d,0x0a,0x09, + 0x5b,0x22,0x74,0x68,0x72,0x65,0x61,0x64,0x22,0x5d,0x3d,0x22,0x68,0x22,0x2c,0x0d,0x0a,0x09,0x5b,0x22, + 0x69,0x6e,0x73,0x74,0x61,0x6e,0x63,0x65,0x22,0x5d,0x3d,0x22,0x78,0x22,0x2c,0x20,0x0d,0x0a,0x09,0x5b, + 0x22,0x63,0x6c,0x61,0x73,0x73,0x22,0x5d,0x3d,0x22,0x79,0x22,0x2c,0x20,0x20,0x0d,0x0a,0x09,0x5b,0x22, + 0x62,0x6f,0x6f,0x6c,0x22,0x5d,0x3d,0x22,0x62,0x22,0x2c,0x0d,0x0a,0x09,0x5b,0x22,0x77,0x65,0x61,0x6b, + 0x72,0x65,0x66,0x22,0x5d,0x3d,0x22,0x77,0x22,0x20,0x20,0x0d,0x0a,0x7d,0x0d,0x0a,0x0d,0x0a,0x66,0x75, + 0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x70,0x61,0x63,0x6b,0x5f,0x74,0x79,0x70,0x65,0x28,0x74,0x79,0x70, + 0x65,0x29,0x3a,0x28,0x70,0x61,0x63,0x6b,0x65,0x64,0x5f,0x74,0x79,0x70,0x65,0x73,0x29,0x0d,0x0a,0x7b, + 0x0d,0x0a,0x09,0x69,0x66,0x28,0x74,0x79,0x70,0x65,0x20,0x69,0x6e,0x20,0x70,0x61,0x63,0x6b,0x65,0x64, + 0x5f,0x74,0x79,0x70,0x65,0x73,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x61,0x63,0x6b,0x65,0x64, + 0x5f,0x74,0x79,0x70,0x65,0x73,0x5b,0x74,0x79,0x70,0x65,0x5d,0x0d,0x0a,0x09,0x72,0x65,0x74,0x75,0x72, + 0x6e,0x20,0x74,0x79,0x70,0x65,0x0d,0x0a,0x7d,0x20,0x0d,0x0a,0x0d,0x0a,0x66,0x75,0x6e,0x63,0x74,0x69, + 0x6f,0x6e,0x20,0x69,0x74,0x65,0x72,0x61,0x74,0x65,0x6f,0x62,0x6a,0x65,0x63,0x74,0x28,0x6f,0x62,0x6a, + 0x2c,0x66,0x75,0x6e,0x63,0x29,0x0d,0x0a,0x7b,0x0d,0x0a,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x74,0x79, + 0x20,0x3d,0x20,0x3a,0x3a,0x74,0x79,0x70,0x65,0x28,0x6f,0x62,0x6a,0x29,0x3b,0x0d,0x0a,0x09,0x69,0x66, + 0x28,0x74,0x79,0x20,0x3d,0x3d,0x20,0x22,0x69,0x6e,0x73,0x74,0x61,0x6e,0x63,0x65,0x22,0x29,0x20,0x7b, + 0x0d,0x0a,0x09,0x09,0x74,0x72,0x79,0x20,0x7b,0x20,0x2f,0x2f,0x54,0x52,0x59,0x20,0x54,0x4f,0x20,0x55, + 0x53,0x45,0x20,0x5f,0x6e,0x65,0x78,0x74,0x69,0x0d,0x0a,0x09,0x09,0x20,0x20,0x20,0x20,0x66,0x6f,0x72, + 0x65,0x61,0x63,0x68,0x28,0x69,0x64,0x78,0x2c,0x76,0x61,0x6c,0x20,0x69,0x6e,0x20,0x6f,0x62,0x6a,0x29, + 0x0d,0x0a,0x09,0x09,0x20,0x20,0x20,0x20,0x7b,0x0d,0x0a,0x09,0x09,0x09,0x09,0x66,0x75,0x6e,0x63,0x28, + 0x6f,0x62,0x6a,0x2c,0x69,0x64,0x78,0x2c,0x76,0x61,0x6c,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x20,0x20,0x20, + 0x20,0x7d,0x0d,0x0a,0x09,0x09,0x7d,0x0d,0x0a,0x09,0x09,0x63,0x61,0x74,0x63,0x68,0x28,0x65,0x29,0x20, + 0x7b,0x0d,0x0a,0x09,0x09,0x20,0x20,0x20,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x28,0x69,0x64,0x78,0x2c, + 0x76,0x61,0x6c,0x20,0x69,0x6e,0x20,0x6f,0x62,0x6a,0x2e,0x67,0x65,0x74,0x63,0x6c,0x61,0x73,0x73,0x28, + 0x29,0x29,0x0d,0x0a,0x09,0x09,0x20,0x20,0x20,0x7b,0x0d,0x0a,0x09,0x09,0x09,0x66,0x75,0x6e,0x63,0x28, + 0x6f,0x62,0x6a,0x2c,0x69,0x64,0x78,0x2c,0x6f,0x62,0x6a,0x5b,0x69,0x64,0x78,0x5d,0x29,0x3b,0x0d,0x0a, + 0x09,0x09,0x20,0x20,0x20,0x7d,0x0d,0x0a,0x09,0x09,0x7d,0x0d,0x0a,0x09,0x7d,0x0d,0x0a,0x09,0x65,0x6c, + 0x73,0x65,0x20,0x69,0x66,0x28,0x74,0x79,0x20,0x3d,0x3d,0x20,0x22,0x77,0x65,0x61,0x6b,0x72,0x65,0x66, + 0x22,0x29,0x20,0x7b,0x0d,0x0a,0x09,0x09,0x66,0x75,0x6e,0x63,0x28,0x6f,0x62,0x6a,0x2c,0x22,0x40,0x72, + 0x65,0x66,0x22,0x2c,0x6f,0x62,0x6a,0x2e,0x72,0x65,0x66,0x28,0x29,0x29,0x3b,0x0d,0x0a,0x09,0x7d,0x0d, + 0x0a,0x09,0x65,0x6c,0x73,0x65,0x20,0x7b,0x0d,0x0a,0x09,0x09,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x28, + 0x69,0x64,0x78,0x2c,0x76,0x61,0x6c,0x20,0x69,0x6e,0x20,0x6f,0x62,0x6a,0x29,0x0d,0x0a,0x09,0x09,0x7b, + 0x0d,0x0a,0x09,0x09,0x20,0x20,0x20,0x20,0x66,0x75,0x6e,0x63,0x28,0x6f,0x62,0x6a,0x2c,0x69,0x64,0x78, + 0x2c,0x76,0x61,0x6c,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x7d,0x0d,0x0a,0x09,0x7d,0x0d,0x0a,0x09,0x09,0x09, + 0x0d,0x0a,0x7d,0x0d,0x0a,0x0d,0x0a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x62,0x75,0x69,0x6c, + 0x64,0x5f,0x74,0x72,0x65,0x65,0x28,0x29,0x3a,0x28,0x6f,0x62,0x6a,0x73,0x5f,0x72,0x65,0x67,0x29,0x0d, + 0x0a,0x7b,0x0d,0x0a,0x09,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x28,0x69,0x2c,0x6f,0x20,0x69,0x6e,0x20, + 0x6f,0x62,0x6a,0x73,0x5f,0x72,0x65,0x67,0x2e,0x72,0x65,0x66,0x73,0x29,0x0d,0x0a,0x09,0x7b,0x0d,0x0a, + 0x09,0x09,0x62,0x65,0x67,0x69,0x6e,0x65,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x28,0x22,0x6f,0x22,0x29,0x3b, + 0x0d,0x0a,0x09,0x09,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x28,0x22,0x74,0x79,0x70,0x65,0x22, + 0x2c,0x28,0x69,0x3d,0x3d,0x3a,0x3a,0x67,0x65,0x74,0x72,0x6f,0x6f,0x74,0x74,0x61,0x62,0x6c,0x65,0x28, + 0x29,0x3f,0x22,0x72,0x22,0x3a,0x70,0x61,0x63,0x6b,0x5f,0x74,0x79,0x70,0x65,0x28,0x3a,0x3a,0x74,0x79, + 0x70,0x65,0x28,0x69,0x29,0x29,0x29,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x5f, + 0x74,0x79,0x70,0x65,0x6f,0x66,0x20,0x3d,0x20,0x74,0x79,0x70,0x65,0x6f,0x66,0x20,0x69,0x3b,0x0d,0x0a, + 0x09,0x09,0x69,0x66,0x28,0x5f,0x74,0x79,0x70,0x65,0x6f,0x66,0x20,0x21,0x3d,0x20,0x3a,0x3a,0x74,0x79, + 0x70,0x65,0x28,0x69,0x29,0x29,0x20,0x7b,0x0d,0x0a,0x09,0x09,0x09,0x61,0x74,0x74,0x72,0x69,0x62,0x75, + 0x74,0x65,0x28,0x22,0x74,0x79,0x70,0x65,0x6f,0x66,0x22,0x2c,0x5f,0x74,0x79,0x70,0x65,0x6f,0x66,0x29, + 0x3b,0x0d,0x0a,0x09,0x09,0x7d,0x0d,0x0a,0x09,0x09,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x28, + 0x22,0x72,0x65,0x66,0x22,0x2c,0x6f,0x2e,0x74,0x6f,0x73,0x74,0x72,0x69,0x6e,0x67,0x28,0x29,0x29,0x3b, + 0x0d,0x0a,0x09,0x09,0x69,0x66,0x28,0x69,0x20,0x21,0x3d,0x20,0x3a,0x3a,0x67,0x65,0x74,0x72,0x6f,0x6f, + 0x74,0x74,0x61,0x62,0x6c,0x65,0x28,0x29,0x29,0x7b,0x0d,0x0a,0x09,0x09,0x09,0x69,0x74,0x65,0x72,0x61, + 0x74,0x65,0x6f,0x62,0x6a,0x65,0x63,0x74,0x28,0x69,0x2c,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20, + 0x28,0x6f,0x62,0x6a,0x2c,0x69,0x64,0x78,0x2c,0x76,0x61,0x6c,0x29,0x20,0x7b,0x0d,0x0a,0x09,0x09,0x09, + 0x09,0x69,0x66,0x28,0x3a,0x3a,0x74,0x79,0x70,0x65,0x28,0x76,0x61,0x6c,0x29,0x20,0x3d,0x3d,0x20,0x22, + 0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x22,0x29,0x0d,0x0a,0x09,0x09,0x09,0x09,0x09,0x72,0x65,0x74, + 0x75,0x72,0x6e,0x3b,0x0d,0x0a,0x09,0x09,0x09,0x09,0x09,0x0d,0x0a,0x09,0x09,0x09,0x09,0x69,0x66,0x20, + 0x28,0x20,0x3a,0x3a,0x74,0x79,0x70,0x65,0x28,0x69,0x64,0x78,0x29,0x20,0x3d,0x3d,0x20,0x22,0x73,0x74, + 0x72,0x69,0x6e,0x67,0x22,0x20,0x26,0x26,0x20,0x69,0x64,0x78,0x2e,0x66,0x69,0x6e,0x64,0x28,0x20,0x22, + 0x5f,0x5f,0x22,0x20,0x29,0x20,0x3d,0x3d,0x20,0x30,0x20,0x29,0x0d,0x0a,0x09,0x09,0x09,0x09,0x09,0x72, + 0x65,0x74,0x75,0x72,0x6e,0x3b,0x0d,0x0a,0x0d,0x0a,0x09,0x09,0x09,0x09,0x62,0x65,0x67,0x69,0x6e,0x65, + 0x6c,0x65,0x6d,0x65,0x6e,0x74,0x28,0x22,0x65,0x22,0x29,0x3b,0x09,0x0d,0x0a,0x09,0x09,0x09,0x09,0x09, + 0x65,0x6d,0x69,0x74,0x76,0x61,0x6c,0x75,0x65,0x28,0x22,0x6b,0x74,0x22,0x2c,0x22,0x6b,0x76,0x22,0x2c, + 0x69,0x64,0x78,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x09,0x09,0x09,0x65,0x6d,0x69,0x74,0x76,0x61,0x6c,0x75, + 0x65,0x28,0x22,0x76,0x74,0x22,0x2c,0x22,0x76,0x22,0x2c,0x6f,0x62,0x6a,0x5b,0x69,0x64,0x78,0x5d,0x29, + 0x3b,0x0d,0x0a,0x09,0x09,0x09,0x09,0x65,0x6e,0x64,0x65,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x28,0x22,0x65, + 0x22,0x29,0x3b,0x09,0x0d,0x0a,0x0d,0x0a,0x09,0x09,0x09,0x7d,0x29,0x0d,0x0a,0x09,0x09,0x7d,0x0d,0x0a, + 0x09,0x09,0x65,0x6e,0x64,0x65,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x28,0x22,0x6f,0x22,0x29,0x3b,0x0d,0x0a, + 0x09,0x7d,0x0d,0x0a,0x7d,0x0d,0x0a,0x0d,0x0a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x65,0x76, + 0x61,0x6c,0x75,0x61,0x74,0x65,0x5f,0x77,0x61,0x74,0x63,0x68,0x28,0x6c,0x6f,0x63,0x61,0x6c,0x73,0x2c, + 0x69,0x64,0x2c,0x65,0x78,0x70,0x72,0x65,0x73,0x73,0x69,0x6f,0x6e,0x29,0x0d,0x0a,0x7b,0x0d,0x0a,0x09, + 0x6c,0x6f,0x63,0x61,0x6c,0x20,0x66,0x75,0x6e,0x63,0x5f,0x73,0x72,0x63,0x3d,0x22,0x72,0x65,0x74,0x75, + 0x72,0x6e,0x20,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x28,0x22,0x0d,0x0a,0x09,0x6c,0x6f,0x63, + 0x61,0x6c,0x20,0x70,0x61,0x72,0x61,0x6d,0x73,0x3d,0x5b,0x5d,0x3b,0x0d,0x0a,0x09,0x0d,0x0a,0x09,0x70, + 0x61,0x72,0x61,0x6d,0x73,0x2e,0x61,0x70,0x70,0x65,0x6e,0x64,0x28,0x6c,0x6f,0x63,0x61,0x6c,0x73,0x5b, + 0x22,0x74,0x68,0x69,0x73,0x22,0x5d,0x29,0x0d,0x0a,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x66,0x69,0x72, + 0x73,0x74,0x3d,0x31,0x3b,0x0d,0x0a,0x09,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x28,0x69,0x2c,0x76,0x20, + 0x69,0x6e,0x20,0x6c,0x6f,0x63,0x61,0x6c,0x73,0x29,0x7b,0x0d,0x0a,0x09,0x09,0x69,0x66,0x28,0x69,0x21, + 0x3d,0x22,0x74,0x68,0x69,0x73,0x22,0x20,0x26,0x26,0x20,0x69,0x5b,0x30,0x5d,0x20,0x21,0x3d,0x20,0x27, + 0x40,0x27,0x29,0x7b,0x20,0x2f,0x2f,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x20,0x69,0x74,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x73,0x20,0x73,0x74,0x61,0x72,0x74,0x20,0x77,0x69,0x74,0x68,0x20,0x40,0x0d,0x0a,0x09, + 0x09,0x09,0x69,0x66,0x28,0x21,0x66,0x69,0x72,0x73,0x74,0x29,0x7b,0x0d,0x0a,0x09,0x09,0x09,0x09,0x66, + 0x75,0x6e,0x63,0x5f,0x73,0x72,0x63,0x3d,0x66,0x75,0x6e,0x63,0x5f,0x73,0x72,0x63,0x2b,0x22,0x2c,0x22, + 0x0d,0x0a,0x09,0x09,0x09,0x09,0x0d,0x0a,0x09,0x09,0x09,0x7d,0x0d,0x0a,0x09,0x09,0x09,0x66,0x69,0x72, + 0x73,0x74,0x3d,0x6e,0x75,0x6c,0x6c,0x0d,0x0a,0x09,0x09,0x09,0x70,0x61,0x72,0x61,0x6d,0x73,0x2e,0x61, + 0x70,0x70,0x65,0x6e,0x64,0x28,0x76,0x29,0x0d,0x0a,0x09,0x09,0x09,0x66,0x75,0x6e,0x63,0x5f,0x73,0x72, + 0x63,0x3d,0x66,0x75,0x6e,0x63,0x5f,0x73,0x72,0x63,0x2b,0x69,0x0d,0x0a,0x09,0x09,0x7d,0x0d,0x0a,0x09, + 0x7d,0x0d,0x0a,0x09,0x66,0x75,0x6e,0x63,0x5f,0x73,0x72,0x63,0x3d,0x66,0x75,0x6e,0x63,0x5f,0x73,0x72, + 0x63,0x2b,0x22,0x29,0x7b,0x5c,0x6e,0x22,0x0d,0x0a,0x09,0x66,0x75,0x6e,0x63,0x5f,0x73,0x72,0x63,0x3d, + 0x66,0x75,0x6e,0x63,0x5f,0x73,0x72,0x63,0x2b,0x22,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x22,0x2b, + 0x65,0x78,0x70,0x72,0x65,0x73,0x73,0x69,0x6f,0x6e,0x2b,0x22,0x29,0x5c,0x6e,0x7d,0x22,0x0d,0x0a,0x09, + 0x0d,0x0a,0x09,0x74,0x72,0x79,0x20,0x7b,0x0d,0x0a,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x66,0x75, + 0x6e,0x63,0x3d,0x3a,0x3a,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x73,0x74,0x72,0x69,0x6e,0x67,0x28,0x66, + 0x75,0x6e,0x63,0x5f,0x73,0x72,0x63,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x72,0x65,0x74,0x75,0x72,0x6e,0x20, + 0x7b,0x73,0x74,0x61,0x74,0x75,0x73,0x3d,0x22,0x6f,0x6b,0x22,0x20,0x2c,0x20,0x76,0x61,0x6c,0x3d,0x66, + 0x75,0x6e,0x63,0x28,0x29,0x2e,0x61,0x63,0x61,0x6c,0x6c,0x28,0x70,0x61,0x72,0x61,0x6d,0x73,0x29,0x7d, + 0x3b,0x0d,0x0a,0x09,0x7d,0x0d,0x0a,0x09,0x63,0x61,0x74,0x63,0x68,0x28,0x65,0x29,0x0d,0x0a,0x09,0x7b, + 0x0d,0x0a,0x09,0x09,0x0d,0x0a,0x09,0x09,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x7b,0x73,0x74,0x61,0x74, + 0x75,0x73,0x3d,0x22,0x65,0x72,0x72,0x6f,0x72,0x22,0x7d,0x0d,0x0a,0x09,0x7d,0x0d,0x0a,0x7d,0x0d,0x0a, + 0x0d,0x0a,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f, + 0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f, + 0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f, + 0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x0d, + 0x0a,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f, + 0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f, + 0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f, + 0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x0d,0x0a, + 0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x65,0x6d,0x69,0x74,0x76,0x61,0x6c,0x75,0x65,0x28,0x74, + 0x79,0x70,0x65,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x2c,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x74,0x74, + 0x72,0x69,0x62,0x2c,0x76,0x61,0x6c,0x29,0x0d,0x0a,0x7b,0x0d,0x0a,0x09,0x61,0x74,0x74,0x72,0x69,0x62, + 0x75,0x74,0x65,0x28,0x74,0x79,0x70,0x65,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x2c,0x70,0x61,0x63,0x6b, + 0x5f,0x74,0x79,0x70,0x65,0x28,0x3a,0x3a,0x74,0x79,0x70,0x65,0x28,0x76,0x61,0x6c,0x29,0x29,0x29,0x3b, + 0x0d,0x0a,0x09,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61, + 0x74,0x74,0x72,0x69,0x62,0x2c,0x67,0x65,0x74,0x76,0x61,0x6c,0x75,0x65,0x28,0x76,0x61,0x6c,0x29,0x2e, + 0x74,0x6f,0x73,0x74,0x72,0x69,0x6e,0x67,0x28,0x29,0x29,0x3b,0x0d,0x0a,0x7d,0x0d,0x0a,0x0d,0x0a,0x6c, + 0x6f,0x63,0x61,0x6c,0x20,0x73,0x74,0x61,0x63,0x6b,0x3d,0x5b,0x5d,0x0d,0x0a,0x6c,0x6f,0x63,0x61,0x6c, + 0x20,0x6c,0x65,0x76,0x65,0x6c,0x3d,0x33,0x3b,0x0d,0x0a,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x73,0x69,0x3b, + 0x0d,0x0a,0x0d,0x0a,0x09,0x2f,0x2f,0x45,0x4e,0x55,0x4d,0x45,0x52,0x41,0x54,0x45,0x20,0x54,0x48,0x45, + 0x20,0x53,0x54,0x41,0x43,0x4b,0x20,0x57,0x41,0x54,0x43,0x48,0x45,0x53,0x0d,0x0a,0x09,0x77,0x68,0x69, + 0x6c,0x65,0x28,0x73,0x69,0x3d,0x3a,0x3a,0x67,0x65,0x74,0x73,0x74,0x61,0x63,0x6b,0x69,0x6e,0x66,0x6f, + 0x73,0x28,0x6c,0x65,0x76,0x65,0x6c,0x29,0x29,0x0d,0x0a,0x09,0x7b,0x0d,0x0a,0x09,0x09,0x73,0x74,0x61, + 0x63,0x6b,0x2e,0x61,0x70,0x70,0x65,0x6e,0x64,0x28,0x73,0x69,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x6c,0x65, + 0x76,0x65,0x6c,0x2b,0x2b,0x3b,0x0d,0x0a,0x09,0x7d,0x0d,0x0a,0x0d,0x0a,0x09,0x2f,0x2f,0x45,0x56,0x41, + 0x4c,0x55,0x41,0x54,0x45,0x20,0x41,0x4c,0x4c,0x20,0x57,0x41,0x54,0x43,0x48,0x45,0x53,0x0d,0x0a,0x09, + 0x6f,0x62,0x6a,0x73,0x5f,0x72,0x65,0x67,0x2e,0x72,0x65,0x66,0x73,0x5b,0x3a,0x3a,0x67,0x65,0x74,0x72, + 0x6f,0x6f,0x74,0x74,0x61,0x62,0x6c,0x65,0x28,0x29,0x5d,0x20,0x3c,0x2d,0x20,0x6f,0x62,0x6a,0x73,0x5f, + 0x72,0x65,0x67,0x2e,0x6d,0x61,0x78,0x69,0x64,0x2b,0x2b,0x3b,0x0d,0x0a,0x09,0x66,0x6f,0x72,0x65,0x61, + 0x63,0x68,0x28,0x69,0x2c,0x76,0x61,0x6c,0x20,0x69,0x6e,0x20,0x73,0x74,0x61,0x63,0x6b,0x29,0x0d,0x0a, + 0x09,0x7b,0x0d,0x0a,0x09,0x09,0x69,0x66,0x28,0x76,0x61,0x6c,0x2e,0x73,0x72,0x63,0x21,0x3d,0x22,0x4e, + 0x41,0x54,0x49,0x56,0x45,0x22,0x29,0x20,0x7b,0x0d,0x0a,0x09,0x09,0x09,0x69,0x66,0x28,0x22,0x77,0x61, + 0x74,0x63,0x68,0x65,0x73,0x22,0x20,0x69,0x6e,0x20,0x74,0x68,0x69,0x73,0x29,0x20,0x7b,0x0d,0x0a,0x09, + 0x09,0x09,0x09,0x76,0x61,0x6c,0x2e,0x77,0x61,0x74,0x63,0x68,0x65,0x73,0x20,0x3c,0x2d,0x20,0x7b,0x7d, + 0x0d,0x0a,0x09,0x09,0x09,0x09,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x28,0x69,0x2c,0x77,0x61,0x74,0x63, + 0x68,0x20,0x69,0x6e,0x20,0x77,0x61,0x74,0x63,0x68,0x65,0x73,0x29,0x0d,0x0a,0x09,0x09,0x09,0x09,0x7b, + 0x0d,0x0a,0x09,0x09,0x09,0x09,0x09,0x69,0x66,0x28,0x76,0x61,0x6c,0x2e,0x73,0x72,0x63,0x21,0x3d,0x22, + 0x4e,0x41,0x54,0x49,0x56,0x45,0x22,0x29,0x7b,0x0d,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x76,0x61,0x6c, + 0x2e,0x77,0x61,0x74,0x63,0x68,0x65,0x73,0x5b,0x69,0x5d,0x20,0x3c,0x2d,0x20,0x65,0x76,0x61,0x6c,0x75, + 0x61,0x74,0x65,0x5f,0x77,0x61,0x74,0x63,0x68,0x28,0x76,0x61,0x6c,0x2e,0x6c,0x6f,0x63,0x61,0x6c,0x73, + 0x2c,0x69,0x2c,0x77,0x61,0x74,0x63,0x68,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x69,0x66, + 0x28,0x76,0x61,0x6c,0x2e,0x77,0x61,0x74,0x63,0x68,0x65,0x73,0x5b,0x69,0x5d,0x2e,0x73,0x74,0x61,0x74, + 0x75,0x73,0x21,0x3d,0x22,0x65,0x72,0x72,0x6f,0x72,0x22,0x29,0x0d,0x0a,0x09,0x09,0x09,0x09,0x09,0x09, + 0x09,0x62,0x75,0x69,0x6c,0x64,0x5f,0x72,0x65,0x66,0x73,0x28,0x76,0x61,0x6c,0x2e,0x77,0x61,0x74,0x63, + 0x68,0x65,0x73,0x5b,0x69,0x5d,0x2e,0x76,0x61,0x6c,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x09,0x09,0x09,0x7d, + 0x0d,0x0a,0x09,0x09,0x09,0x09,0x09,0x65,0x6c,0x73,0x65,0x7b,0x0d,0x0a,0x09,0x09,0x09,0x09,0x09,0x09, + 0x76,0x61,0x6c,0x2e,0x77,0x61,0x74,0x63,0x68,0x65,0x73,0x5b,0x69,0x5d,0x20,0x3c,0x2d,0x20,0x7b,0x73, + 0x74,0x61,0x74,0x75,0x73,0x3d,0x22,0x65,0x72,0x72,0x6f,0x72,0x22,0x7d,0x0d,0x0a,0x09,0x09,0x09,0x09, + 0x09,0x7d,0x0d,0x0a,0x09,0x09,0x09,0x09,0x09,0x76,0x61,0x6c,0x2e,0x77,0x61,0x74,0x63,0x68,0x65,0x73, + 0x5b,0x69,0x5d,0x2e,0x65,0x78,0x70,0x20,0x3c,0x2d,0x20,0x77,0x61,0x74,0x63,0x68,0x3b,0x0d,0x0a,0x09, + 0x09,0x09,0x09,0x7d,0x0d,0x0a,0x09,0x09,0x09,0x09,0x0d,0x0a,0x09,0x09,0x09,0x7d,0x0d,0x0a,0x09,0x09, + 0x7d,0x0d,0x0a,0x09,0x09,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x28,0x69,0x2c,0x6c,0x20,0x69,0x6e,0x20, + 0x76,0x61,0x6c,0x2e,0x6c,0x6f,0x63,0x61,0x6c,0x73,0x29,0x0d,0x0a,0x09,0x09,0x09,0x62,0x75,0x69,0x6c, + 0x64,0x5f,0x72,0x65,0x66,0x73,0x28,0x6c,0x29,0x3b,0x0d,0x0a,0x09,0x7d,0x0d,0x0a,0x0d,0x0a,0x0d,0x0a, + 0x09,0x62,0x65,0x67,0x69,0x6e,0x65,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x28,0x22,0x6f,0x62,0x6a,0x73,0x22, + 0x29,0x3b,0x0d,0x0a,0x09,0x62,0x75,0x69,0x6c,0x64,0x5f,0x74,0x72,0x65,0x65,0x28,0x29,0x3b,0x0d,0x0a, + 0x09,0x65,0x6e,0x64,0x65,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x28,0x22,0x6f,0x62,0x6a,0x73,0x22,0x29,0x3b, + 0x0d,0x0a,0x0d,0x0a,0x09,0x62,0x65,0x67,0x69,0x6e,0x65,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x28,0x22,0x63, + 0x61,0x6c,0x6c,0x73,0x22,0x29,0x3b,0x0d,0x0a,0x0d,0x0a,0x09,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x28, + 0x69,0x2c,0x76,0x61,0x6c,0x20,0x69,0x6e,0x20,0x73,0x74,0x61,0x63,0x6b,0x29,0x0d,0x0a,0x09,0x7b,0x0d, + 0x0a,0x0d,0x0a,0x09,0x09,0x62,0x65,0x67,0x69,0x6e,0x65,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x28,0x22,0x63, + 0x61,0x6c,0x6c,0x22,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x28, + 0x22,0x66,0x6e,0x63,0x22,0x2c,0x76,0x61,0x6c,0x2e,0x66,0x75,0x6e,0x63,0x29,0x3b,0x0d,0x0a,0x09,0x09, + 0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x28,0x22,0x73,0x72,0x63,0x22,0x2c,0x76,0x61,0x6c,0x2e, + 0x73,0x72,0x63,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x28,0x22, + 0x6c,0x69,0x6e,0x65,0x22,0x2c,0x76,0x61,0x6c,0x2e,0x6c,0x69,0x6e,0x65,0x2e,0x74,0x6f,0x73,0x74,0x72, + 0x69,0x6e,0x67,0x28,0x29,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x28,0x69, + 0x2c,0x76,0x20,0x69,0x6e,0x20,0x76,0x61,0x6c,0x2e,0x6c,0x6f,0x63,0x61,0x6c,0x73,0x29,0x0d,0x0a,0x09, + 0x09,0x7b,0x0d,0x0a,0x09,0x09,0x09,0x62,0x65,0x67,0x69,0x6e,0x65,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x28, + 0x22,0x6c,0x22,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x09,0x09,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65, + 0x28,0x22,0x6e,0x61,0x6d,0x65,0x22,0x2c,0x67,0x65,0x74,0x76,0x61,0x6c,0x75,0x65,0x28,0x69,0x29,0x2e, + 0x74,0x6f,0x73,0x74,0x72,0x69,0x6e,0x67,0x28,0x29,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x09,0x09,0x65,0x6d, + 0x69,0x74,0x76,0x61,0x6c,0x75,0x65,0x28,0x22,0x74,0x79,0x70,0x65,0x22,0x2c,0x22,0x76,0x61,0x6c,0x22, + 0x2c,0x76,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x09,0x65,0x6e,0x64,0x65,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x28, + 0x22,0x6c,0x22,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x7d,0x0d,0x0a,0x09,0x09,0x69,0x66,0x28,0x22,0x77,0x61, + 0x74,0x63,0x68,0x65,0x73,0x22,0x20,0x69,0x6e,0x20,0x76,0x61,0x6c,0x29,0x20,0x7b,0x0d,0x0a,0x09,0x09, + 0x09,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x28,0x69,0x2c,0x76,0x20,0x69,0x6e,0x20,0x76,0x61,0x6c,0x2e, + 0x77,0x61,0x74,0x63,0x68,0x65,0x73,0x29,0x0d,0x0a,0x09,0x09,0x09,0x7b,0x0d,0x0a,0x09,0x09,0x09,0x09, + 0x62,0x65,0x67,0x69,0x6e,0x65,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x28,0x22,0x77,0x22,0x29,0x3b,0x0d,0x0a, + 0x09,0x09,0x09,0x09,0x09,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x28,0x22,0x69,0x64,0x22,0x2c, + 0x69,0x2e,0x74,0x6f,0x73,0x74,0x72,0x69,0x6e,0x67,0x28,0x29,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x09,0x09, + 0x09,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x28,0x22,0x65,0x78,0x70,0x22,0x2c,0x76,0x2e,0x65, + 0x78,0x70,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x09,0x09,0x09,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65, + 0x28,0x22,0x73,0x74,0x61,0x74,0x75,0x73,0x22,0x2c,0x76,0x2e,0x73,0x74,0x61,0x74,0x75,0x73,0x29,0x3b, + 0x0d,0x0a,0x09,0x09,0x09,0x09,0x09,0x69,0x66,0x28,0x76,0x2e,0x73,0x74,0x61,0x74,0x75,0x73,0x21,0x3d, + 0x22,0x65,0x72,0x72,0x6f,0x72,0x22,0x29,0x20,0x7b,0x0d,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x65,0x6d, + 0x69,0x74,0x76,0x61,0x6c,0x75,0x65,0x28,0x22,0x74,0x79,0x70,0x65,0x22,0x2c,0x22,0x76,0x61,0x6c,0x22, + 0x2c,0x76,0x2e,0x76,0x61,0x6c,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x09,0x09,0x09,0x7d,0x0d,0x0a,0x09,0x09, + 0x09,0x09,0x65,0x6e,0x64,0x65,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x28,0x22,0x77,0x22,0x29,0x3b,0x0d,0x0a, + 0x09,0x09,0x09,0x7d,0x0d,0x0a,0x09,0x09,0x7d,0x0d,0x0a,0x09,0x09,0x65,0x6e,0x64,0x65,0x6c,0x65,0x6d, + 0x65,0x6e,0x74,0x28,0x22,0x63,0x61,0x6c,0x6c,0x22,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x20,0x0d,0x0a,0x09, + 0x7d,0x0d,0x0a,0x09,0x65,0x6e,0x64,0x65,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x28,0x22,0x63,0x61,0x6c,0x6c, + 0x73,0x22,0x29,0x3b,0x0d,0x0a,0x0d,0x0a,0x0d,0x0a,0x09,0x6f,0x62,0x6a,0x73,0x5f,0x72,0x65,0x67,0x20, + 0x3d,0x20,0x6e,0x75,0x6c,0x6c,0x3b,0x0d,0x0a,0x09,0x73,0x74,0x61,0x63,0x6b,0x20,0x3d,0x20,0x6e,0x75, + 0x6c,0x6c,0x3b,0x0d,0x0a,0x09,0x0d,0x0a,0x09,0x69,0x66,0x28,0x22,0x63,0x6f,0x6c,0x6c,0x65,0x63,0x74, + 0x67,0x61,0x72,0x62,0x61,0x67,0x65,0x22,0x20,0x69,0x6e,0x20,0x3a,0x3a,0x67,0x65,0x74,0x72,0x6f,0x6f, + 0x74,0x74,0x61,0x62,0x6c,0x65,0x28,0x29,0x29,0x20,0x3a,0x3a,0x63,0x6f,0x6c,0x6c,0x65,0x63,0x74,0x67, + 0x61,0x72,0x62,0x61,0x67,0x65,0x28,0x29,0x3b,0x0d,0x0a,0x7d,0x63,0x61,0x74,0x63,0x68,0x28,0x65,0x29, + 0x0d,0x0a,0x7b,0x0d,0x0a,0x09,0x3a,0x3a,0x70,0x72,0x69,0x6e,0x74,0x28,0x22,0x45,0x52,0x52,0x4f,0x52, + 0x22,0x2b,0x65,0x2b,0x22,0x5c,0x6e,0x22,0x29,0x3b,0x0d,0x0a,0x7d,0x0d,0x0a,0x0d,0x0a,0x69,0x66,0x20, + 0x28,0x20,0x63,0x75,0x72,0x72,0x65,0x6e,0x74,0x73,0x63,0x6f,0x70,0x65,0x20,0x29,0x0d,0x0a,0x7b,0x0d, + 0x0a,0x09,0x3a,0x3a,0x73,0x65,0x74,0x72,0x6f,0x6f,0x74,0x74,0x61,0x62,0x6c,0x65,0x28,0x20,0x63,0x75, + 0x72,0x72,0x65,0x6e,0x74,0x73,0x63,0x6f,0x70,0x65,0x20,0x29,0x3b,0x0d,0x0a,0x7d,0x0d,0x0a, +}; diff --git a/vscript/languages/squirrel/sqdbg/serialize_state.nut b/vscript/languages/squirrel/sqdbg/serialize_state.nut new file mode 100644 index 00000000..5682be50 --- /dev/null +++ b/vscript/languages/squirrel/sqdbg/serialize_state.nut @@ -0,0 +1,277 @@ +/* + see copyright notice in sqrdbg.h +*/ +local currentscope; +if ( ::getroottable().parent ) +{ + currentscope = ::getroottable(); + ::setroottable( ::getroottable().parent ); +} +try { + +local objs_reg = { maxid=0 ,refs={} } + +complex_types <- { + ["table"] = null, + ["array"] = null, + ["class"] = null, + ["instance"] = null, + ["weakref"] = null, +} + +function build_refs(t):(objs_reg) +{ + if(t == ::getroottable()) + return; + local otype = ::type(t); + if(otype in complex_types) + { + if(!(t in objs_reg.refs)) { + objs_reg.refs[t] <- objs_reg.maxid++; + + iterateobject(t,function(o,i,val):(objs_reg) + { + build_refs(val); + build_refs(i); + }) + } + + } +} + +function getvalue(v):(objs_reg) +{ + switch(::type(v)) + { + case "table": + case "array": + case "class": + case "instance": + return objs_reg.refs[v].tostring(); + case "integer": + case "float": + return v; + case "bool": + return v.tostring(); + case "string": + return v; + case "null": + return "null"; + default: + + return pack_type(::type(v)); + } +} + +local packed_types={ + ["null"]="n", + ["string"]="s", + ["integer"]="i", + ["float"]="f", + ["userdata"]="u", + ["function"]="fn", + ["table"]="t", + ["array"]="a", + ["generator"]="g", + ["thread"]="h", + ["instance"]="x", + ["class"]="y", + ["bool"]="b", + ["weakref"]="w" +} + +function pack_type(type):(packed_types) +{ + if(type in packed_types)return packed_types[type] + return type +} + +function iterateobject(obj,func) +{ + local ty = ::type(obj); + if(ty == "instance") { + try { //TRY TO USE _nexti + foreach(idx,val in obj) + { + func(obj,idx,val); + } + } + catch(e) { + foreach(idx,val in obj.getclass()) + { + func(obj,idx,obj[idx]); + } + } + } + else if(ty == "weakref") { + func(obj,"@ref",obj.ref()); + } + else { + foreach(idx,val in obj) + { + func(obj,idx,val); + } + } + +} + +function build_tree():(objs_reg) +{ + foreach(i,o in objs_reg.refs) + { + beginelement("o"); + attribute("type",(i==::getroottable()?"r":pack_type(::type(i)))); + local _typeof = typeof i; + if(_typeof != ::type(i)) { + attribute("typeof",_typeof); + } + attribute("ref",o.tostring()); + if(i != ::getroottable()){ + iterateobject(i,function (obj,idx,val) { + if(::type(val) == "function") + return; + + if ( ::type(idx) == "string" && idx.find( "__" ) == 0 ) + return; + + beginelement("e"); + emitvalue("kt","kv",idx); + emitvalue("vt","v",obj[idx]); + endelement("e"); + + }) + } + endelement("o"); + } +} + +function evaluate_watch(locals,id,expression) +{ + local func_src="return function (" + local params=[]; + + params.append(locals["this"]) + local first=1; + foreach(i,v in locals){ + if(i!="this" && i[0] != '@'){ //foreach iterators start with @ + if(!first){ + func_src=func_src+"," + + } + first=null + params.append(v) + func_src=func_src+i + } + } + func_src=func_src+"){\n" + func_src=func_src+"return ("+expression+")\n}" + + try { + local func=::compilestring(func_src); + return {status="ok" , val=func().acall(params)}; + } + catch(e) + { + + return {status="error"} + } +} + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +function emitvalue(type_attrib,value_attrib,val) +{ + attribute(type_attrib,pack_type(::type(val))); + attribute(value_attrib,getvalue(val).tostring()); +} + +local stack=[] +local level=3; +local si; + + //ENUMERATE THE STACK WATCHES + while(si=::getstackinfos(level)) + { + stack.append(si); + level++; + } + + //EVALUATE ALL WATCHES + objs_reg.refs[::getroottable()] <- objs_reg.maxid++; + foreach(i,val in stack) + { + if(val.src!="NATIVE") { + if("watches" in this) { + val.watches <- {} + foreach(i,watch in watches) + { + if(val.src!="NATIVE"){ + val.watches[i] <- evaluate_watch(val.locals,i,watch); + if(val.watches[i].status!="error") + build_refs(val.watches[i].val); + } + else{ + val.watches[i] <- {status="error"} + } + val.watches[i].exp <- watch; + } + + } + } + foreach(i,l in val.locals) + build_refs(l); + } + + + beginelement("objs"); + build_tree(); + endelement("objs"); + + beginelement("calls"); + + foreach(i,val in stack) + { + + beginelement("call"); + attribute("fnc",val.func); + attribute("src",val.src); + attribute("line",val.line.tostring()); + foreach(i,v in val.locals) + { + beginelement("l"); + attribute("name",getvalue(i).tostring()); + emitvalue("type","val",v); + endelement("l"); + } + if("watches" in val) { + foreach(i,v in val.watches) + { + beginelement("w"); + attribute("id",i.tostring()); + attribute("exp",v.exp); + attribute("status",v.status); + if(v.status!="error") { + emitvalue("type","val",v.val); + } + endelement("w"); + } + } + endelement("call"); + + } + endelement("calls"); + + + objs_reg = null; + stack = null; + + if("collectgarbage" in ::getroottable()) ::collectgarbage(); +}catch(e) +{ + ::print("ERROR"+e+"\n"); +} + +if ( currentscope ) +{ + ::setroottable( currentscope ); +} diff --git a/vscript/languages/squirrel/sqdbg/sqdbg.cbp b/vscript/languages/squirrel/sqdbg/sqdbg.cbp new file mode 100644 index 00000000..62dfcb6a --- /dev/null +++ b/vscript/languages/squirrel/sqdbg/sqdbg.cbp @@ -0,0 +1,162 @@ + + + + + + + diff --git a/vscript/languages/squirrel/sqdbg/sqdbg.chm b/vscript/languages/squirrel/sqdbg/sqdbg.chm new file mode 100644 index 0000000000000000000000000000000000000000..3f4b25d21b0acbf5c03b05d6d8716a0b99f6dd50 GIT binary patch literal 19006 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 literal 0 HcmV?d00001 diff --git a/vscript/languages/squirrel/sqdbg/sqdbg.pdf b/vscript/languages/squirrel/sqdbg/sqdbg.pdf new file mode 100644 index 00000000..14266017 --- /dev/null +++ b/vscript/languages/squirrel/sqdbg/sqdbg.pdf @@ -0,0 +1,494 @@ +%PDF-1.3 +%ª«¬­ +4 0 obj +<< /Type /Info +/Producer (FOP 0.20.5) >> +endobj +5 0 obj +<< /Length 196 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GaqdY]+0EX&;B(lT41D@*+tSN;/4Ut;R\G?OEDk#&6F++6)>^%qht(5^"An`O:%O/^cqrFJZf5C'FZgXJMj2O1`/_b3XrfU>BYFS9hM,(@3_nF3gBoT9Bc3qXP4mt@uMS5.jO.p#ClaLCf.d3?VEJJ<[f`FTjmgRGAS)Ccn@nXebn8]oeWu"qgWh^iWC>m0t%~> +endstream +endobj +6 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 5 0 R +>> +endobj +7 0 obj +<< /Length 1032 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gasao968i1&AJ$CE(_rr;`u\TDGNtK1[1kLh:`p3KHqH]*!CH`mu*-((.W6uT(0&.o'MVOh.MXI+(H"fnJYuh,!bfF7"P/f.#\3ITJY<\-jii&U@5SKShuXoniO49dM2/YRh4D)V6*SD;n]*>Y%oLMAVbt#oFkf.N5l'T"1[mbHe[m"]Ltb5Dg>*S&d(Z[C`:rl'b09+++Z$SDqFFH40_"A<]A/Art-QNPG01U=6;/UWrG.#,2^ZM^.E;WVq-(C$jTJk3uk.)]'Vq_N^QdDo.BZ6**>d*W4O5OMY/o$W&lcb#d'bWF=/Kbhg7qA%pVZOEP(DXpLI`sUf/WLPn+n"3oN(ZcqaCVE=QR1Gf^S8_NnM)\S#;blp\i1agl%]q,ps5?'9@g582-SVc-qn9mbJs,$E7'g*nL#=so:Y=@)[H&/DQ]!-2g2Sr[G'inYY"eVaU[rhBW8g>L1#X*UbuiN2W(tu\\JID7K'9dtlZ0(o<>D6FW@SnF!+g*2X!#Pqeh83A[9U59+:+jIS<:0hrKS_M0b1+u.`l_55eED8/Z+c)QCq_Ks$[<'!O'6s!gV\K*5-nX(X71TcDeOLO"B)EG`"&ZpM8[t6P7fS_@RIJJ6]YXe3PU19QJ^k\lVYl";#Te`d12]At[%@]l=u=TjIq'E5Gcq(/\-uNcKFU[\/F1;`cU\7\DXMeJ7.bZsdD*C*!@)L'8O:T`Z"eQA0r`>pqBF"<&&:SN(Xnf'UP+cb[8.)<%*['SRURShGgs+,./IB>kiUR#<5h\Q^9dN!:2H#LkOfCDtFUTr-p6%jej'EFOU[qe*&Uo[XC%$P:a;b(6gJgM(,gLVGbMe+")*-1VY"'1eY)BY;c[f3EQG6@\ufcb%;uGCR;d\^?otfbREY^KEbR,`[gm:u/4`kSJlJD9;#G8P8TVFb&.JrZ3l/CnLa#NV#El=i7A-3)+at]KTka-i6>G^BDgQQ([eq*LN+fW*4ROgh2t.Rl-50g&1q"H]<^~> +endstream +endobj +8 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 7 0 R +>> +endobj +9 0 obj +<< /Length 71 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Garg^iGoCd.c`?]8EV`b1=.gR0K1`91K?+0ZOMGdU/Zh'Y!=Te%#&:?HH*JE! +endstream +endobj +10 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 9 0 R +>> +endobj +11 0 obj +<< /Length 500 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb"/h4)]a*&:etR`JnDaMdI=@V@P+]qN/1d6QUtO9qeC?l-HOB8Xr1GUoFN2F^k/oR):!5dpWGA34n<<'k%F4/;PDZ-q*d'TGWM.N`2)J$2PAX6Tl@69b7(o.?[:Q+=sjiiC-o!VPl_*n-&U-VNsIlS&JuGB;NfU@Z_5%BUb;#QUJE0W1T%k>ak1qSt!klKQO7$h9>R6&eYfioViB3kt3uUd59gL.kd@GKrGhDZYU&F\m@<.'%5[1j,RQQGKeEW5^>5eB1:\31c"`I=#9MT%Cb0Dam9TGl$q.OlD;p1n':)d@HqE,^%fBI+X-5P38:Y+p95\Q^;:cXomD3IoRdC4RE?5-7K?$8oo>,qOA:j;VVqc,$(5gPR]Y%34Dd>M6MdNgRVkSAD#:SJC;0$JK(5u[NJ)tsQ/\rgnD=.lDB,PW,n`V`Oep2c(>K,s]g"4eKHH_nFs`9O/La4cKPHc4>PNDk"5=c#SH~> +endstream +endobj +12 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 11 0 R +/Annots 13 0 R +>> +endobj +13 0 obj +[ +14 0 R +16 0 R +18 0 R +20 0 R +22 0 R +24 0 R +26 0 R +] +endobj +14 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 655.001 187.48 645.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 15 0 R +/H /I +>> +endobj +16 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 644.001 183.43 634.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 17 0 R +/H /I +>> +endobj +18 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 633.001 242.31 623.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 19 0 R +/H /I +>> +endobj +20 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 622.001 230.65 612.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 21 0 R +/H /I +>> +endobj +22 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 611.001 189.14 601.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 23 0 R +/H /I +>> +endobj +24 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 600.001 183.43 590.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 25 0 R +/H /I +>> +endobj +26 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 589.001 142.77 579.001 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 27 0 R +/H /I +>> +endobj +28 0 obj +<< /Length 1965 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gatm<>B?Pt'RnB3@(-Z']8csPhKBu]nRgV!g.>!3Th?_b6+1J^&:s5GSc8@)&0QODZIA(57H^=bqfFHR0:\fD:TB(*A6Gqn/<47TH)*tdr"R8k8@MgM1XHgZQa8+'q'!+b6C&a1n54Ff.,Hn,)gTKUg?e+B[!&,+f-ID*(ne=\34NBj#["i':*>NKt`n/8W4Q=!.5ZPW\1$^J6+TRCD@]8/YUp\m,!In[ZRD%9PS`pF`@la>er(^YfTcSW`LVe]Cq"nAd'"CL+iB^A0>7*Z:Aa-IO"L2t_*$cm%9=rSpH[Q%1O"OG(hUJfH(\o$2&pW19+/B\3OLfM?o+E-JSQ][rc9&bljbM0AnD9%XG,K/O,-kGq0%VN&'rPEb3$M1L64^ZTIZWqXdM)lenrTIB27k`]B!@=?$[Fsn.dTkBuAE$5/\15KP?8aB'PKfsM3@"=USt^!MdW*`7LmT#Rh=_NgoSmf-=,42MEHF8ME*l46u8DslKuMbUlLh#H0j&7HpE:_&aUC9.4VMXY6F"=:jTuZkVa",SIu?_K?cZIP3NNk$GP7lQE&Q"I]B1OIgRja'6ipQ?7,bp`5V-R]Jpuir1>WDgq(=b2cB9SHi'eJlbfM9T[WTJi1\>=:bi607+)u@Kpt>*Pu'8j8JEq[7LJ1,mjC3pN=<]4,9iFVC!6RRZ0.,Q8(YLDHr^JjrpXT,joW?gW&2=`c-rmh6pU!c2r?fMH*KG=B\orR<,+'05\::'\2F.ggb8d-d:doqo`jl7\/2s6Jg0hU>M;u)W&e1oNF;]glO8-E[;KeUY:gQP?iNDm'^%?EfWmW%96D\-P[qhAs+YTDO$j0J\X1#>4OrNOaX>V(5NaY%)"oa7)n)(0-&^XLP[&bIHpAXFFh)fM&4;g6@o:,8gUD[]*T1>E])I5I1?]XV8B0&&WQ/11Eic]Y:E([t3hQ*CC9sI]/C;%?@-Kc1(U0m'ocLg)hlJ*9MX0P]8#q'[VqD*1_Xe[EbbFqiG`p%YKpcG#%3HRUuTrJfV>o;J^GmU4$qPPd?Y"+]'rOF_U:>BSj0`j^KMM6WPKe_mU*pO*XWN+dc0KYkecS%KT&fUp[qiITW3-Zbb=m:3e^f<(D0ffdf~> +endstream +endobj +29 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 28 0 R +>> +endobj +30 0 obj +<< /Length 822 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gas1]>u03/'RfGR0MI[.$/@MKj$XOk1c6?g.dc4fP6e0\j-4:).8C3\e,K67-H--nP_[3&\`]R]fb^4970nt_>p-G5$Pj`c>l>dqr'4UEf7OJ4nHA9M/>#)IZVnlBooC`8#NDW^HSpEtH8)!$pmYNRnfqmBkm&7<_gT[q>.iXaqZEW&6\KZZH+M5dX;"%M$8(FV[EP[&EMd`?361Q6d(eq!;r=\`SSYj"k&g=19To<5l(2_1,i)6O)Ld8]D.?dbjs--T/<]GY%q#qD2&KieLNYCMWBqKsAMmE:11-E]U*.N^R,KiD75B4\2$&&Y&7OHS-`ji734*Jao.(p_0DT+sXZ!kgMK?LR+!E5n)d`.rutgk[Iu%d0UL3D>1eqW7cs_#'>=9E*,i6oW_F./(rq_]b(/C_mp"LdP+&GW^s5;8i9\%hbdfT%4(6^>hSF6)1`LVle#+X[-=/LeY/5C!1>t?h`R>5^6cP)^!oO2H6hi>KYXgoLCS48.3DPe<7U>D,noJ'TR0A+]BdDuZ:_$/;>7g`C&7cR*ad.`W9UigRtL*(4UO@MA]#Vt0s``2FMlF[PEF\DV3%F\YdQD>+#d2']]QgufbKX26Jj&!^+)a%,$K4V+Ud[9in?=%@2+G<@d[N0TRS^jl[?=]1TuQ!K_n%;(Y]i$(kZ6^>R$^'Xhm^Kpf7,fi%,:1'Bcd*=d]!s=A34/oTTa`cLmq0bDG?d`Fc01euYig/@U7/m99iIp:~> +endstream +endobj +31 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 30 0 R +>> +endobj +32 0 obj +<< /Length 1571 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatTIgMYb(o\ElJ[jFAWLn_',;q!'tL)/%QmE7U+Zpi_;AC6MfBA(n'OsoikAfM%CJ;!+Tgi[MYj`GN_9cVJLED2neEoK-\$$KSHK:U(NXqSe]$N8&6DOeI;5-='MZJs@opS%p>Z($ElM2-iTa4m(,igq`)_=@akFoHBXJ$g2#'To'>37J]HaRt`tgLiFJ2irq!VdRejE]:P!!`GPeM\(4`<2;A`%McC*1@Q6V7o3snRaS)4i];'uN<\fZYON.DL]i1m?hs?#8E[%G4QfW>BW,_?+:/TN2"dIOGP>0G^J1mq?iJFX'&u,DSkI))(.C+p]dO_=c>'cEDsm(t^ARc+^+.-?c#g6Q"$i-d!Ca$;(YLqt^+jS"$bBcHZHD(KVfh`>9Bq`M0]3q"*Z_9:Jaeb%4-VJh9@@:gUk'Jqh467_q7`ckgU?tc0mZ.BKYt/':"HuAb!>%[e*Y-!Xg+sm@'`)XV.;SW$$h3sW^l`^*q!@XcaQW'E`c*")7rFb=o[;R+(4)1__@j5*uh0_P?!aGCcYYfnJcB(m$d&ce-,qA&*8$sCrmn(e8Ja1L),h]@f^am;dFMtq/1jVlO3*Ml&`P7B3A3lVG0nsJB2EJ1XEA#lj]5-6*opsTPMn>>u/s%j^`OLmb!O704PgQ$uckV2giO8V!I$k*]'C?MoI8qB)f/*-!?*6l6H)(2AREZ,t)L@`EMa7?s8EhE,E(P$@q1]#I`7c+TE`em9FY+=K>-*G692G&%HcfB3=Buc4/d-KYG!!IY&o\;Li;tk;!VO0_7%"<%?&hsK%ukX(VEVH%8tqe:QlD/oX-*KN2=@&r"03AWPJQe3B.gsYu$:KV^r";$+jPAB`'>gK;XA"g[>A?R[)g2NN`V/8bMJfngV123gcpOf[cA]lpLImO8'de_kWM[ie8ceO'2%6U"&?bjnk?+6I]a@7_;a4Y%0#RF)0qaWi^qO2q%/u*km,l*np.'(lu46d:;#(6@[3B)m,I_:od#+ZYk'RQ/Hf%*ia8(neCFpK+4UCJSh[)\RfX2JhK+d3Odbq(Fh(oN=#&WW&t,@?]W*uZ0oVA3(GccWH4LGN-_a"5gYaYN>"EEH==#)p>od\+3^8M!$hP+gSrVX'B#rn\JCnPHG_&,)?5cOT7^8=W'2nXbEraqZLs$ASY![S_*Q[U +endstream +endobj +33 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 32 0 R +>> +endobj +34 0 obj +<< /Length 941 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GatU1hf"u<&:Vr4_.+[3'SCsKHYTs3l[GdJbFY$!EkkMP`2:Og[/KYR`oK6K>A4``]!HhBh0hKESRo.f$P[h6n,kH]nT'eQ`mUC>o-`Z;2AhhEq`+;/e:B;>4$oLU"*b6rm9kI)h::\`B94:)@:^fkW1B"\TTP*c50gdT"O52Q2rOqE`@3BBLJ.a>g*'Ts`gL;3B"r&b>56S-L.dl0+7Hd%^Zub>buY;*CT,`CD-C&P]E27"D9/nflgN1MlCL"?4''t+Yt[T+ja_@&cABm+EB:?Ih'Zgp,s8*-D]hqBo]?tg^%BJB?M`3@4]'KTZD#PjF(@l5>\FWO/RZt*Vj1Jd*+sbdf&>SNe1I4b/(XaBLQN6;UX^]0cgD+24"mEbO4>_Ve/8aWjZK"qpANCOQ8f1.n(>^4Q6c.Gg%F\_Et4q@hM?/dO.\,bM/tC0J?PQNNm5*`a2]">KC4Z7Yd90R5I!$S>jM_p\dWVq3R-qS:NV:mGD-b(VU/=[[n#Z/@>[QUY<&224,V&'="fN)e`,Bm'?DL5/H*Y!FeLd3ZgUFc@9ckdj-h/mX_ZB)"/?+h[:]=p?\*#thc.Nc]=p`FS1L&(JRN5Kau1,5+U^l1m!<8/ikcTJ5D?^N0(Nq>X$e#2(U!WRnCELkQm#7:+!(\+7ClJ?@<@uH?JkRY5-16q~> +endstream +endobj +35 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 34 0 R +>> +endobj +36 0 obj +<< /Length 287 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +GasJM_/@+D%#44r$6MQC-Ae9M>`gpYgns0k9o.14H6=5F&:=>/Q>R*XTj4\os1ZFngl(D1JS'"a^m@C)7OX@4.EF>F0)mWht;E]SO,5b#q412`=ou,c,oV3.-h`4ms=llYUJ~> +endstream +endobj +37 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 36 0 R +/Annots 38 0 R +>> +endobj +38 0 obj +[ +] +endobj +41 0 obj +<< + /Title (\376\377\0\123\0\161\0\165\0\151\0\162\0\162\0\145\0\154\0\40\0\122\0\145\0\155\0\157\0\164\0\145\0\40\0\104\0\145\0\142\0\165\0\147\0\147\0\145\0\162\0\40\0\61\0\56\0\60) + /Parent 39 0 R + /Next 43 0 R + /A 40 0 R +>> endobj +43 0 obj +<< + /Title (\376\377\0\124\0\141\0\142\0\154\0\145\0\40\0\157\0\146\0\40\0\103\0\157\0\156\0\164\0\145\0\156\0\164\0\163) + /Parent 39 0 R + /Prev 41 0 R + /Next 44 0 R + /A 42 0 R +>> endobj +44 0 obj +<< + /Title (\376\377\0\103\0\150\0\141\0\160\0\164\0\145\0\162\0\240\0\61\0\56\0\240\0\124\0\150\0\145\0\40\0\104\0\145\0\142\0\165\0\147\0\147\0\145\0\162) + /Parent 39 0 R + /First 45 0 R + /Last 47 0 R + /Prev 43 0 R + /Next 48 0 R + /Count -3 + /A 15 0 R +>> endobj +45 0 obj +<< + /Title (\376\377\0\117\0\166\0\145\0\162\0\166\0\151\0\145\0\167) + /Parent 44 0 R + /Next 46 0 R + /A 17 0 R +>> endobj +46 0 obj +<< + /Title (\376\377\0\111\0\156\0\164\0\145\0\147\0\162\0\141\0\164\0\151\0\156\0\147\0\40\0\164\0\150\0\145\0\40\0\144\0\145\0\142\0\165\0\147\0\147\0\145\0\162) + /Parent 44 0 R + /Prev 45 0 R + /Next 47 0 R + /A 19 0 R +>> endobj +47 0 obj +<< + /Title (\376\377\0\124\0\150\0\145\0\40\0\156\0\145\0\164\0\167\0\157\0\162\0\153\0\40\0\160\0\162\0\157\0\164\0\157\0\143\0\157\0\154) + /Parent 44 0 R + /Prev 46 0 R + /A 21 0 R +>> endobj +48 0 obj +<< + /Title (\376\377\0\103\0\150\0\141\0\160\0\164\0\145\0\162\0\240\0\62\0\56\0\240\0\101\0\120\0\111\0\40\0\122\0\145\0\146\0\145\0\162\0\145\0\156\0\143\0\145) + /Parent 39 0 R + /First 49 0 R + /Last 49 0 R + /Prev 44 0 R + /Next 50 0 R + /Count -1 + /A 23 0 R +>> endobj +49 0 obj +<< + /Title (\376\377\0\104\0\145\0\142\0\165\0\147\0\147\0\145\0\162) + /Parent 48 0 R + /A 25 0 R +>> endobj +50 0 obj +<< + /Title (\376\377\0\111\0\156\0\144\0\145\0\170) + /Parent 39 0 R + /Prev 48 0 R + /A 27 0 R +>> endobj +51 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F3 +/BaseFont /Helvetica-Bold +/Encoding /WinAnsiEncoding >> +endobj +52 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F5 +/BaseFont /Times-Roman +/Encoding /WinAnsiEncoding >> +endobj +53 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F10 +/BaseFont /Courier-Oblique +/Encoding /WinAnsiEncoding >> +endobj +54 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F6 +/BaseFont /Times-Italic +/Encoding /WinAnsiEncoding >> +endobj +55 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F1 +/BaseFont /Helvetica +/Encoding /WinAnsiEncoding >> +endobj +56 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F11 +/BaseFont /Courier-Bold +/Encoding /WinAnsiEncoding >> +endobj +57 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F9 +/BaseFont /Courier +/Encoding /WinAnsiEncoding >> +endobj +1 0 obj +<< /Type /Pages +/Count 9 +/Kids [6 0 R 8 0 R 10 0 R 12 0 R 29 0 R 31 0 R 33 0 R 35 0 R 37 0 R ] >> +endobj +2 0 obj +<< /Type /Catalog +/Pages 1 0 R + /Outlines 39 0 R + /PageMode /UseOutlines + >> +endobj +3 0 obj +<< +/Font << /F3 51 0 R /F5 52 0 R /F10 53 0 R /F1 55 0 R /F6 54 0 R /F9 57 0 R /F11 56 0 R >> +/ProcSet [ /PDF /ImageC /Text ] >> +endobj +15 0 obj +<< +/S /GoTo +/D [29 0 R /XYZ 115.0 725.0 null] +>> +endobj +17 0 obj +<< +/S /GoTo +/D [29 0 R /XYZ 115.0 666.009 null] +>> +endobj +19 0 obj +<< +/S /GoTo +/D [29 0 R /XYZ 115.0 589.684 null] +>> +endobj +21 0 obj +<< +/S /GoTo +/D [31 0 R /XYZ 115.0 448.64 null] +>> +endobj +23 0 obj +<< +/S /GoTo +/D [33 0 R /XYZ 115.0 725.0 null] +>> +endobj +25 0 obj +<< +/S /GoTo +/D [33 0 R /XYZ 115.0 687.009 null] +>> +endobj +27 0 obj +<< +/S /GoTo +/D [37 0 R /XYZ 67.0 725.0 null] +>> +endobj +39 0 obj +<< + /First 41 0 R + /Last 50 0 R +>> endobj +40 0 obj +<< +/S /GoTo +/D [10 0 R /XYZ 115.0 725.0 null] +>> +endobj +42 0 obj +<< +/S /GoTo +/D [12 0 R /XYZ 115.0 715.0 null] +>> +endobj +xref +0 58 +0000000000 65535 f +0000012880 00000 n +0000012993 00000 n +0000013085 00000 n +0000000015 00000 n +0000000071 00000 n +0000000358 00000 n +0000000464 00000 n +0000001588 00000 n +0000001694 00000 n +0000001855 00000 n +0000001962 00000 n +0000002554 00000 n +0000002677 00000 n +0000002746 00000 n +0000013232 00000 n +0000002882 00000 n +0000013297 00000 n +0000003018 00000 n +0000013364 00000 n +0000003154 00000 n +0000013431 00000 n +0000003290 00000 n +0000013497 00000 n +0000003426 00000 n +0000013562 00000 n +0000003562 00000 n +0000013629 00000 n +0000003698 00000 n +0000005756 00000 n +0000005864 00000 n +0000006778 00000 n +0000006886 00000 n +0000008550 00000 n +0000008658 00000 n +0000009691 00000 n +0000009799 00000 n +0000010178 00000 n +0000010301 00000 n +0000013693 00000 n +0000013744 00000 n +0000010321 00000 n +0000013809 00000 n +0000010565 00000 n +0000010761 00000 n +0000011032 00000 n +0000011162 00000 n +0000011400 00000 n +0000011600 00000 n +0000011877 00000 n +0000011993 00000 n +0000012105 00000 n +0000012218 00000 n +0000012328 00000 n +0000012443 00000 n +0000012554 00000 n +0000012662 00000 n +0000012774 00000 n +trailer +<< +/Size 58 +/Root 2 0 R +/Info 4 0 R +>> +startxref +13874 +%%EOF diff --git a/vscript/languages/squirrel/sqdbg/sqdbg.vcproj b/vscript/languages/squirrel/sqdbg/sqdbg.vcproj new file mode 100644 index 00000000..ecff5411 --- /dev/null +++ b/vscript/languages/squirrel/sqdbg/sqdbg.vcproj @@ -0,0 +1,381 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/sqdbg/sqdbg71.vcproj b/vscript/languages/squirrel/sqdbg/sqdbg71.vcproj new file mode 100644 index 00000000..734f80bc --- /dev/null +++ b/vscript/languages/squirrel/sqdbg/sqdbg71.vcproj @@ -0,0 +1,251 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/sqdbg/sqdbgWithUnicode.vcproj b/vscript/languages/squirrel/sqdbg/sqdbgWithUnicode.vcproj new file mode 100644 index 00000000..695bfcda --- /dev/null +++ b/vscript/languages/squirrel/sqdbg/sqdbgWithUnicode.vcproj @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/sqdbg/sqdbgWithUnicode71.vcproj b/vscript/languages/squirrel/sqdbg/sqdbgWithUnicode71.vcproj new file mode 100644 index 00000000..695bfcda --- /dev/null +++ b/vscript/languages/squirrel/sqdbg/sqdbgWithUnicode71.vcproj @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/sqdbg/sqdbgserver.cpp b/vscript/languages/squirrel/sqdbg/sqdbgserver.cpp new file mode 100644 index 00000000..e14f94b4 --- /dev/null +++ b/vscript/languages/squirrel/sqdbg/sqdbgserver.cpp @@ -0,0 +1,694 @@ + +#include "tier0/basetypes.h" +#include "tier1/strtools.h" +#include "tier0/threadtools.h" + +#include +#include +#include +#include "sqrdbg.h" +#include "sqdbgserver.h" +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#endif + +#ifndef _UNICODE +#define scstrcpy strcpy +#else +#define scstrcpy wcscpy +#endif +struct XMLEscape{ + const SQChar c; + const SQChar *esc; +}; + +#define SQDBG_DEBUG_HOOK _SC("_sqdbg_debug_hook_") +#define SQDBG_ERROR_HANDLER _SC("_sqdbg_error_handler_") + +XMLEscape g_escapes[]={ + {_SC('<'),_SC("<")},{'>',_SC(">")},{_SC('&'),_SC("&")},{_SC('\''),_SC("'")},{_SC('\"'),_SC(""")},{_SC('\n'),_SC(""n")},{_SC('\r'),_SC(""r")},{NULL,NULL} +}; + +const SQChar *IntToString(int n) +{ + static SQChar temp[256]; + scsprintf(temp,_SC("%d"),n); + return temp; +} + +SQInteger debug_hook(HSQUIRRELVM v); +SQInteger error_handler(HSQUIRRELVM v); + +SQInteger beginelement(HSQUIRRELVM v) +{ + SQUserPointer up; + const SQChar *name; + sq_getuserpointer(v,-1,&up); + SQDbgServer *self = (SQDbgServer*)up; + sq_getuserpointer(v,-1,&up); + sq_getstring(v,2,&name); + self->BeginElement(name); + return 0; +} + +SQInteger endelement(HSQUIRRELVM v) +{ + SQUserPointer up; + const SQChar *name; + sq_getuserpointer(v,-1,&up); + SQDbgServer *self = (SQDbgServer*)up; + sq_getuserpointer(v,-1,&up); + sq_getstring(v,2,&name); + self->EndElement(name); + return 0; +} + +SQInteger attribute(HSQUIRRELVM v) +{ + SQUserPointer up; + const SQChar *name,*value; + sq_getuserpointer(v,-1,&up); + SQDbgServer *self = (SQDbgServer*)up; + sq_getuserpointer(v,-1,&up); + sq_getstring(v,2,&name); + sq_getstring(v,3,&value); + self->Attribute(name,value); + return 0; +} + +const SQChar *EscapeXMLString(HSQUIRRELVM v,const SQChar *s) +{ + + SQChar *temp=sq_getscratchpad(v,((int)scstrlen(s)*6) + sizeof (SQChar)); + SQChar *dest=temp; + while(*s!=_SC('\0')){ + int i=0; + bool escaped=false; + while(g_escapes[i].esc!=NULL){ + if(*s==g_escapes[i].c){ + scstrcpy(dest,g_escapes[i].esc); + dest+=scstrlen(g_escapes[i].esc); + escaped=true; + break; + } + i++; + } + if(!escaped){*dest=*s;dest++;} + s++; + } + *dest=_SC('\0'); + return temp; +} + +SQDbgServer::SQDbgServer(HSQUIRRELVM v) +{ + _ready = false; + _nestedcalls = 0; + _autoupdate = false; + _v = v; + _state = eDBG_Running; + _accept = INVALID_SOCKET; + _endpoint = INVALID_SOCKET; + _maxrecursion = 10; + sq_resetobject(&_debugroot); + sq_resetobject(&_serializefunc); +} + +SQDbgServer::~SQDbgServer() +{ + sq_pushnull(_v); + sq_setdebughook(_v); + sq_pushnull(_v); + sq_seterrorhandler(_v); + sq_release(_v,&_debugroot); +#ifndef _X360 + if(_accept != INVALID_SOCKET) + sqdbg_closesocket(_accept); + if(_endpoint != INVALID_SOCKET) + sqdbg_closesocket(_endpoint); +#endif +} + +bool SQDbgServer::Init() +{ + //creates an environment table for the debugger + + sq_newtable(_v); + sq_getstackobj(_v,-1,&_debugroot); + sq_addref(_v,&_debugroot); + + //creates a emptyslot to store the watches + sq_pushstring(_v,_SC("watches"),-1); + sq_pushnull(_v); + sq_createslot(_v,-3); + + sq_pushstring(_v,_SC("beginelement"),-1); + sq_pushuserpointer(_v,this); + sq_newclosure(_v,beginelement,1); + sq_setparamscheck(_v,2,_SC(".s")); + sq_createslot(_v,-3); + + sq_pushstring(_v,_SC("endelement"),-1); + sq_pushuserpointer(_v,this); + sq_newclosure(_v,endelement,1); + sq_setparamscheck(_v,2,_SC(".s")); + sq_createslot(_v,-3); + + sq_pushstring(_v,_SC("attribute"),-1); + sq_pushuserpointer(_v,this); + sq_newclosure(_v,attribute,1); + sq_setparamscheck(_v,3,_SC(".ss")); + sq_createslot(_v,-3); + + sq_pop(_v,1); + + //stores debug hook and error handler in the registry + sq_pushregistrytable(_v); + + sq_pushstring(_v,SQDBG_DEBUG_HOOK,-1); + sq_pushuserpointer(_v,this); + sq_newclosure(_v,debug_hook,1); + sq_createslot(_v,-3); + + sq_pushstring(_v,SQDBG_ERROR_HANDLER,-1); + sq_pushuserpointer(_v,this); + sq_newclosure(_v,error_handler,1); + sq_createslot(_v,-3); + + + sq_pop(_v,1); + + //sets the error handlers + SetErrorHandlers(); + return true; +} + +bool SQDbgServer::IsConnected() +{ +#ifndef _GAMECONSOLE + if ( _endpoint != INVALID_SOCKET ) + { + fd_set set; +#if defined(_WIN32) || defined(_PS3) + set.fd_count = 1; + set.fd_array[0] = _endpoint; +#else + FD_SET( _endpoint, &set ); +#endif + timeval timeVal = { 0,0 }; + if ( select( 0, &set, NULL, NULL, &timeVal ) != SOCKET_ERROR ) + { + return true; + } + DevMsg( "Script debugger disconnected\n" ); + } +#endif + return false; +} + + +bool SQDbgServer::ReadMsg() +{ + return false; +} + +void SQDbgServer::BusyWait() +{ + while( !ReadMsg() ) + ThreadSleep(0); +} + +void SQDbgServer::SendChunk(const SQChar *chunk) +{ +#ifndef _GAMECONSOLE + char *buf=NULL; + int buf_len=0; +#ifdef _UNICODE + buf_len=(int)scstrlen(chunk)+1; + buf=(char *)sq_getscratchpad(_v,(buf_len)*3); + wcstombs((char *)buf,chunk,buf_len); +#else + buf_len=(int)scstrlen(chunk); + buf=(char *)chunk; +#endif + send(_endpoint,(const char*)buf,(int)strlen((const char *)buf),0); +#endif +} + + +void SQDbgServer::Terminated() +{ + BeginElement(_SC("terminated")); + EndElement(_SC("terminated")); + ThreadSleep(200); +} + +void SQDbgServer::Hook(int type,int line,const SQChar *src,const SQChar *func) +{ + switch(_state){ + case eDBG_Running: + if(type==_SC('l') && _breakpoints.size()) { + BreakPointSetItor itr = _breakpoints.find(BreakPoint(line,src)); + if(itr != _breakpoints.end()) { + Break(line,src,_SC("breakpoint")); + BreakExecution(); + } + } + break; + case eDBG_Suspended: + _nestedcalls=0; + case eDBG_StepOver: + switch(type){ + case _SC('l'): + if(_nestedcalls==0) { + Break(line,src,_SC("step")); + BreakExecution(); + } + break; + case _SC('c'): + _nestedcalls++; + break; + case _SC('r'): + if(_nestedcalls==0){ + _nestedcalls=0; + + }else{ + _nestedcalls--; + } + break; + } + break; + case eDBG_StepInto: + switch(type){ + case _SC('l'): + _nestedcalls=0; + Break(line,src,_SC("step")); + BreakExecution(); + break; + + } + break; + case eDBG_StepReturn: + switch(type){ + case _SC('l'): + break; + case _SC('c'): + _nestedcalls++; + break; + case _SC('r'): + if(_nestedcalls==0){ + _nestedcalls=0; + _state=eDBG_StepOver; + }else{ + _nestedcalls--; + } + + break; + } + break; + case eDBG_Disabled: + break; + } +} + + +#define MSG_ID(x,y) ((y<<8)|x) +//ab Add Breakpoint +//rb Remove Breakpoint +//sp Suspend +void SQDbgServer::ParseMsg(const char *msg) +{ + + switch(*((unsigned short *)msg)){ + case MSG_ID('a','b'): { + BreakPoint bp; + if(ParseBreakpoint(msg+3,bp)){ + AddBreakpoint(bp); + scprintf(_SC("added bp %d %s\n"),bp._line,bp._src.c_str()); + } + else + scprintf(_SC("error parsing add breakpoint")); + } + break; + case MSG_ID('r','b'): { + BreakPoint bp; + if(ParseBreakpoint(msg+3,bp)){ + RemoveBreakpoint(bp); + scprintf(_SC("removed bp %d %s\n"),bp._line,bp._src.c_str()); + }else + scprintf(_SC("error parsing remove breakpoint")); + } + break; + case MSG_ID('g','o'): + if(_state!=eDBG_Running){ + _state=eDBG_Running; + BeginDocument(); + BeginElement(_SC("resumed")); + EndElement(_SC("resumed")); + EndDocument(); +// Send(_SC("\r\n")); + scprintf(_SC("go (execution resumed)\n")); + } + break; + case MSG_ID('s','p'): + if(_state!=eDBG_Suspended){ + _state=eDBG_Suspended; + scprintf(_SC("suspend\n")); + } + break; + case MSG_ID('s','o'): + if(_state==eDBG_Suspended){ + _state=eDBG_StepOver; + } + break; + case MSG_ID('s','i'): + if(_state==eDBG_Suspended){ + _state=eDBG_StepInto; + scprintf(_SC("step into\n")); + } + break; + case MSG_ID('s','r'): + if(_state==eDBG_Suspended){ + _state=eDBG_StepReturn; + scprintf(_SC("step return\n")); + } + break; + case MSG_ID('d','i'): + if(_state!=eDBG_Disabled){ + _state=eDBG_Disabled; + scprintf(_SC("disabled\n")); + } + break; + case MSG_ID('a','w'): { + Watch w; + if(ParseWatch(msg+3,w)) + { + AddWatch(w); + scprintf(_SC("added watch %d %s\n"),w._id,w._exp.c_str()); + } + else + scprintf(_SC("error parsing add watch")); + } + break; + case MSG_ID('r','w'): { + int id; + if(ParseRemoveWatch(msg+3,id)) + { + RemoveWatch(id); + scprintf(_SC("added watch %d\n"),id); + } + else + scprintf(_SC("error parsing remove watch")); + } + break; + case MSG_ID('t','r'): + { + scprintf(_SC("terminate from user\n")); +#ifndef _X360 + sqdbg_closesocket(_endpoint); +#endif + _endpoint = INVALID_SOCKET; + } + break; + case MSG_ID('r','d'): + scprintf(_SC("ready\n")); + _ready=true; + break; + default: + scprintf(_SC("unknown packet")); + + } +} + +/* + see copyright notice in sqrdbg.h +*/ +bool SQDbgServer::ParseBreakpoint(const char *msg,BreakPoint &out) +{ + static char stemp[MAX_BP_PATH]; + char *ep=NULL; + out._line=strtoul(msg,&ep,16); + if(ep==msg || (*ep)!=':')return false; + + char *dest=stemp; + ep++; + while((*ep)!='\n' && (*ep)!='\0') + { + *dest=*ep; + dest++;ep++; + } + *dest='\0'; + dest++; + *dest='\0'; +#ifdef _UNICODE + int len=(int)strlen(stemp); + SQChar *p=sq_getscratchpad(_v,(SQInteger)(mbstowcs(NULL,stemp,len)+2)*sizeof(SQChar)); + size_t destlen=mbstowcs(p,stemp,len); + p[destlen]=_SC('\0'); + out._src=( V_strrchr( p, '/' ) ) ? V_strrchr( p, '/' ) + 1 : p; +#else + out._src=( V_strrchr( stemp, '/' ) ) ? V_strrchr( stemp, '/' ) + 1 : stemp; +#endif + return true; +} + +bool SQDbgServer::ParseWatch(const char *msg,Watch &out) +{ + char *ep=NULL; + out._id=strtoul(msg,&ep,16); + if(ep==msg || (*ep)!=':')return false; + + //char *dest=out._src; + ep++; + while((*ep)!='\n' && (*ep)!='\0') + { + out._exp.append(1,*ep); + ep++; + } + return true; +} + +bool SQDbgServer::ParseRemoveWatch(const char *msg,int &id) +{ + char *ep=NULL; + id=strtoul(msg,&ep,16); + if(ep==msg)return false; + return true; +} + + +void SQDbgServer::BreakExecution() +{ + _state=eDBG_Suspended; + while(_state==eDBG_Suspended){ + if(SQ_FAILED(sq_rdbg_update(this))) + { + extern bool g_bSqDbgTerminateScript; + g_bSqDbgTerminateScript = true; + return; + } + ThreadSleep(10); + } +} + +//COMMANDS +void SQDbgServer::AddBreakpoint(BreakPoint &bp) +{ + _breakpoints.insert(bp); + BeginDocument(); + BeginElement(_SC("addbreakpoint")); + Attribute(_SC("line"),IntToString(bp._line)); + Attribute(_SC("src"),bp._src.c_str()); + EndElement(_SC("addbreakpoint")); + EndDocument(); +} + +void SQDbgServer::AddWatch(Watch &w) +{ + _watches.insert(w); +} + +void SQDbgServer::RemoveWatch(int id) +{ + WatchSetItor itor=_watches.find(Watch(id,_SC(""))); + if(itor==_watches.end()){ + BeginDocument(); + BeginElement(_SC("error")); + Attribute(_SC("desc"),_SC("the watch does not exists")); + EndElement(_SC("error")); + EndDocument(); + } + else{ + _watches.erase(itor); + scprintf(_SC("removed watch %d\n"),id); + } +} + +void SQDbgServer::RemoveBreakpoint(BreakPoint &bp) +{ + BreakPointSetItor itor=_breakpoints.find(bp); + if(itor==_breakpoints.end()){ + BeginDocument(); + BeginElement(_SC("break")); + Attribute(_SC("desc"),_SC("the breakpoint doesn't exists")); + EndElement(_SC("break")); + EndDocument(); + } + else{ + BeginDocument(); + BeginElement(_SC("removebreakpoint")); + Attribute(_SC("line"),IntToString(bp._line)); + Attribute(_SC("src"),bp._src.c_str()); + EndElement(_SC("removebreakpoint")); + EndDocument(); + _breakpoints.erase(itor); + } +} + +void SQDbgServer::Break(int line,const SQChar *src,const SQChar *type,const SQChar *error) +{ + if(!error){ + BeginDocument(); + BeginElement(_SC("break")); + Attribute(_SC("line"),IntToString(line)); + Attribute(_SC("src"),src); + Attribute(_SC("type"),type); + SerializeState(); + EndElement(_SC("break")); + EndDocument(); + }else{ + BeginDocument(); + BeginElement(_SC("break")); + Attribute(_SC("line"),IntToString(line)); + Attribute(_SC("src"),src); + Attribute(_SC("type"),type); + Attribute(_SC("error"),error); + SerializeState(); + EndElement(_SC("break")); + EndDocument(); + } +} + +void SQDbgServer::SerializeState() +{ + sq_pushnull(_v); + sq_setdebughook(_v); + sq_pushnull(_v); + sq_seterrorhandler(_v); + const SQChar *sz; + sq_pushobject(_v,_serializefunc); + sq_pushobject(_v,_debugroot); + sq_pushstring(_v,_SC("watches"),-1); + sq_newtable(_v); + for(WatchSetItor i=_watches.begin(); i!=_watches.end(); ++i) + { + sq_pushinteger(_v,i->_id); + sq_pushstring(_v,i->_exp.c_str(),(int)i->_exp.length()); + sq_createslot(_v,-3); + } + sq_rawset(_v,-3); + if(SQ_SUCCEEDED(sq_call(_v,1,SQTrue,SQTrue))){ + if(SQ_SUCCEEDED(sqstd_getblob(_v,-1,(SQUserPointer*)&sz))) + SendChunk(sz); + } + sq_pop(_v,2); + + SetErrorHandlers(); +} + + +void SQDbgServer::SetErrorHandlers() +{ + sq_pushregistrytable(_v); + sq_pushstring(_v,SQDBG_DEBUG_HOOK,-1); + sq_rawget(_v,-2); + sq_setdebughook(_v); + sq_pushstring(_v,SQDBG_ERROR_HANDLER,-1); + sq_rawget(_v,-2); + sq_seterrorhandler(_v); + sq_pop(_v,1); +} + +void SQDbgServer::BeginElement(const SQChar *name) +{ + _xmlcurrentement++; +// for ( int i = 0; i < _xmlcurrentement; i++ ) +// { +// printf(" "); +// } +// printf( "BeginElement( %s )\n", name ); + XMLElementState *self = &xmlstate[_xmlcurrentement]; + scstrcpy(self->name,name); + self->haschildren = false; + if(_xmlcurrentement > 0) { + XMLElementState *parent = &xmlstate[_xmlcurrentement-1]; + if(!parent->haschildren) { + SendChunk(_SC(">")); // closes the parent tag + parent->haschildren = true; + } + } + _scratchstring.resize(2+scstrlen(name)); + scsprintf(&_scratchstring[0],_SC("<%s"),name); + SendChunk(&_scratchstring[0]); +} + +void SQDbgServer::Attribute(const SQChar *name,const SQChar *value) +{ + XMLElementState *self = &xmlstate[_xmlcurrentement]; + Assert(!self->haschildren); //cannot have attributes if already has children + const SQChar *escval = escape_xml(value); + _scratchstring.resize(5+scstrlen(name)+scstrlen(escval)); + scsprintf(&_scratchstring[0],_SC(" %s=\"%s\""),name,escval); + SendChunk(&_scratchstring[0]); +} + +void SQDbgServer::EndElement(const SQChar *name) +{ +// for ( int i = 0; i < _xmlcurrentement; i++ ) +// { +// printf(" "); +// } +// printf( "EndElement( %s )\n", name ); + XMLElementState *self = &xmlstate[_xmlcurrentement]; + Assert(scstrcmp(self->name,name) == 0); + if(self->haschildren) { + _scratchstring.resize(4+scstrlen(name)); + scsprintf(&_scratchstring[0],_SC(""),name); + SendChunk(&_scratchstring[0]); + + } + else { + SendChunk(_SC("/>")); + } + _xmlcurrentement--; +} + +void SQDbgServer::EndDocument() +{ + SendChunk(_SC("\r\n")); +} + +//this can be done much better/faster(do we need that?) +const SQChar *SQDbgServer::escape_xml(const SQChar *s) +{ + SQChar *temp=sq_getscratchpad(_v,((int)scstrlen(s)*6) + sizeof(SQChar)); + SQChar *dest=temp; + while(*s!=_SC('\0')){ + int i=0; + bool escaped=false; + while(g_escapes[i].esc!=NULL){ + if(*s==g_escapes[i].c){ + scstrcpy(dest,g_escapes[i].esc); + dest+=scstrlen(g_escapes[i].esc); + escaped=true; + break; + } + i++; + } + if(!escaped){*dest=*s;dest++;} + s++; + } + *dest=_SC('\0'); + return temp; + +} diff --git a/vscript/languages/squirrel/sqdbg/sqrdbg.cpp b/vscript/languages/squirrel/sqdbg/sqrdbg.cpp new file mode 100644 index 00000000..da87f6d4 --- /dev/null +++ b/vscript/languages/squirrel/sqdbg/sqrdbg.cpp @@ -0,0 +1,186 @@ +/* + see copyright notice in sqrdbg.h +*/ +#include "tier0/basetypes.h" +#include +#if !defined( _X360 ) && !defined( _PS3 ) && !defined( POSIX ) +#include +#endif +#include "sqrdbg.h" +#include "sqdbgserver.h" +SQInteger debug_hook(HSQUIRRELVM v); +SQInteger error_handler(HSQUIRRELVM v); + +#include "serialize_state.inl" +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#endif + +HSQREMOTEDBG sq_rdbg_init(HSQUIRRELVM v,unsigned short port,SQBool autoupdate) +{ +#ifndef _GAMECONSOLE + sockaddr_in bindaddr; +#ifdef _WIN32 + WSADATA wsadata; + if (WSAStartup (MAKEWORD(1,1), &wsadata) != 0){ + return NULL; + } +#endif + SQDbgServer *rdbg = new SQDbgServer(v); + rdbg->_autoupdate = autoupdate?true:false; + rdbg->_accept = socket(AF_INET,SOCK_STREAM,0); + bindaddr.sin_family = AF_INET; + bindaddr.sin_port = htons(port); + bindaddr.sin_addr.s_addr = htonl (INADDR_ANY); + if(bind(rdbg->_accept,(sockaddr*)&bindaddr,sizeof(bindaddr))==SOCKET_ERROR){ + delete rdbg; + sq_throwerror(v,_SC("failed to bind the socket")); + return NULL; + } + if(!rdbg->Init()) { + delete rdbg; + sq_throwerror(v,_SC("failed to initialize the debugger")); + return NULL; + } + + return rdbg; +#else + return NULL; +#endif +} + +SQRESULT sq_rdbg_waitforconnections(HSQREMOTEDBG rdbg) +{ +#ifndef _GAMECONSOLE + if(SQ_FAILED(sq_compilebuffer(rdbg->_v,serialize_state_nut,(SQInteger)scstrlen(serialize_state_nut),_SC("SERIALIZE_STATE"),SQFalse))) { + sq_throwerror(rdbg->_v,_SC("error compiling the serialization function")); + } + sq_getstackobj(rdbg->_v,-1,&rdbg->_serializefunc); + sq_addref(rdbg->_v,&rdbg->_serializefunc); + sq_pop(rdbg->_v,1); + + sockaddr_in cliaddr; + int addrlen=sizeof(cliaddr); + if(listen(rdbg->_accept,0)==SOCKET_ERROR) + return sq_throwerror(rdbg->_v,_SC("error on listen(socket)")); + rdbg->_endpoint = accept(rdbg->_accept,(sockaddr*)&cliaddr,(socklen_t *)&addrlen); + //do not accept any other connection + sqdbg_closesocket(rdbg->_accept); + rdbg->_accept = INVALID_SOCKET; + if(rdbg->_endpoint==INVALID_SOCKET){ + return sq_throwerror(rdbg->_v,_SC("error accept(socket)")); + } + while(!rdbg->_ready){ + sq_rdbg_update(rdbg); + } +#endif + return SQ_OK; +} + +SQRESULT sq_rdbg_update(HSQREMOTEDBG rdbg) +{ +#ifndef _GAMECONSOLE +#ifdef _WIN32 + TIMEVAL time; +#else + struct timeval time; +#endif + time.tv_sec=0; + time.tv_usec=0; + fd_set read_flags; + FD_ZERO(&read_flags); + FD_SET(rdbg->_endpoint, &read_flags); + select(NULL/*ignored*/, &read_flags, NULL, NULL, &time); + + if(FD_ISSET(rdbg->_endpoint,&read_flags)){ + char temp[1024]; + int size=0; + char c,prev=NULL; + memset(&temp,0,sizeof(temp)); + int res; + FD_CLR(rdbg->_endpoint, &read_flags); + while((res = recv(rdbg->_endpoint,&c,1,0))>0){ + + if(c=='\n')break; + if(c!='\r'){ + temp[size]=c; + prev=c; + size++; + } + } + switch(res){ + case 0: + return sq_throwerror(rdbg->_v,_SC("disconnected")); + case SOCKET_ERROR: + return sq_throwerror(rdbg->_v,_SC("socket error")); + } + + temp[size]=NULL; + temp[size+1]=NULL; + rdbg->ParseMsg(temp); + } +#endif + return SQ_OK; +} + +SQInteger debug_hook(HSQUIRRELVM v) +{ + SQUserPointer up; + intp event_type,line; + const SQChar *src,*func; + sq_getinteger(v,2,&event_type); + sq_getstring(v,3,&src); + sq_getinteger(v,4,&line); + sq_getstring(v,5,&func); + sq_getuserpointer(v,-1,&up); + HSQREMOTEDBG rdbg = (HSQREMOTEDBG)up; + rdbg->Hook(event_type,line,src,func); + if(rdbg->_autoupdate) { + if(SQ_FAILED(sq_rdbg_update(rdbg))) + return sq_throwerror(v,_SC("socket failed")); + } + return 0; +} + +SQInteger error_handler(HSQUIRRELVM v) +{ + SQUserPointer up; + const SQChar *sErr=NULL; + const SQChar *fn=_SC("unknown"); + const SQChar *src=_SC("unknown"); + int line=-1; + SQStackInfos si; + sq_getuserpointer(v,-1,&up); + HSQREMOTEDBG rdbg=(HSQREMOTEDBG)up; + if(SQ_SUCCEEDED(sq_stackinfos(v,1,&si))) + { + if(si.funcname)fn=si.funcname; + if(si.source)src=si.source; + line=si.line; + scprintf(_SC("*FUNCTION [%s] %s line [%d]\n"),fn,src,si.line); + } + if(sq_gettop(v)>=1){ + if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) { + scprintf(_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr); + rdbg->Break(si.line,src,_SC("error"),sErr); + } + else{ + scprintf(_SC("\nAN ERROR HAS OCCURED [unknown]\n")); + rdbg->Break(si.line,src,_SC("error"),_SC("unknown")); + } + } + rdbg->BreakExecution(); + return 0; +} + + +SQRESULT sq_rdbg_shutdown(HSQREMOTEDBG rdbg) +{ +#ifndef _GAMECONSOLE + delete rdbg; +#ifdef _WIN32 + WSACleanup(); +#endif +#endif + return SQ_OK; +} diff --git a/vscript/languages/squirrel/sqdbg/test.nut b/vscript/languages/squirrel/sqdbg/test.nut new file mode 100644 index 00000000..6aecb6a5 --- /dev/null +++ b/vscript/languages/squirrel/sqdbg/test.nut @@ -0,0 +1,50 @@ +local x=10; +local y="asd" +local testy = function(){return 0;} + +TestTable <- { + livello2 = { + livello3 = { + ["yooo"]="I'm cool", + ["jaaaa"]=[1,2,3,4,5,6,7,8,9,10], + + } + } +} + +function TestFunc(a,b) +{ + local z=100 + local s="I'm a string" + for(local i=0;i<10;i++) + TestTable.cappero(z,i); + //index_that_desnt_exist=100; //error + return 0; +} + +function TestTable::cappero(a,b) +{ + local ueueueu=100 + local s={x="I'm a string"} + oioioi(1,2) +} + +function TestTable::oioioi(a,b) +{ + local frrrr=100 + local xyz={x="I'm a string"} + +} + + + +local i = 0; +while(1) +{ + local ret; + local testweak = "asdasd"; + local weako = testweak.weakref(); + i++; + ret=TestFunc("param 1","param 2"); +} + diff --git a/vscript/languages/squirrel/sqdbg/testscripts/test.nut b/vscript/languages/squirrel/sqdbg/testscripts/test.nut new file mode 100644 index 00000000..f27a7328 --- /dev/null +++ b/vscript/languages/squirrel/sqdbg/testscripts/test.nut @@ -0,0 +1,15 @@ +//loads an external file +dofile("utils\\coMmons.nut"); + +//declares some locals +local x=10; +local y="asd" +local testy=function(){return 0;} + + +while(1) +{ + local ret; + ret = TestFunc("param 1","param 2"); +} + diff --git a/vscript/languages/squirrel/sqdbg/testscripts/utils/commons.nut b/vscript/languages/squirrel/sqdbg/testscripts/utils/commons.nut new file mode 100644 index 00000000..9d430ade --- /dev/null +++ b/vscript/languages/squirrel/sqdbg/testscripts/utils/commons.nut @@ -0,0 +1,33 @@ +Fagiano <- { + livello2 = { + livello3 = { + [{}]="I'm cool", + [([])]=[1,2,3,4,5,6,7,8,9,10], + + } + } +} + +function TestFunc(a,b) +{ + local z=100 + local s="I'm a string" + for(local i=0;i<10;i++) + Fagiano.cappero(z,i); + //index_that_desnt_exist=100; //error + return 0; +} + +function Fagiano::cappero(a,b) +{ + local ueueueu=100 + local s={x="I'm a string"} + oioioi(1,2) +} + +function Fagiano::oioioi(a,b) +{ + local frrrr=100 + local xyz={x="I'm a string"} + +} diff --git a/vscript/languages/squirrel/sqdbglib/ReadMe.txt b/vscript/languages/squirrel/sqdbglib/ReadMe.txt new file mode 100644 index 00000000..1c13fc10 --- /dev/null +++ b/vscript/languages/squirrel/sqdbglib/ReadMe.txt @@ -0,0 +1,21 @@ +======================================================================== + STATIC LIBRARY : sqdbglib Project Overview +======================================================================== + +AppWizard has created this sqdbglib library project for you. +No source files were created as part of your project. + + +sqdbglib.vcproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/vscript/languages/squirrel/sqdbglib/sqdbglib.cbp b/vscript/languages/squirrel/sqdbglib/sqdbglib.cbp new file mode 100644 index 00000000..64e51ad1 --- /dev/null +++ b/vscript/languages/squirrel/sqdbglib/sqdbglib.cbp @@ -0,0 +1,106 @@ + + + + + + + diff --git a/vscript/languages/squirrel/sqdbglib/sqdbglib.vcproj b/vscript/languages/squirrel/sqdbglib/sqdbglib.vcproj new file mode 100644 index 00000000..ee646e44 --- /dev/null +++ b/vscript/languages/squirrel/sqdbglib/sqdbglib.vcproj @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/sqdbglib/sqdbglib71.vcproj b/vscript/languages/squirrel/sqdbglib/sqdbglib71.vcproj new file mode 100644 index 00000000..36b2bcf2 --- /dev/null +++ b/vscript/languages/squirrel/sqdbglib/sqdbglib71.vcproj @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/sqplus/Makefile b/vscript/languages/squirrel/sqplus/Makefile new file mode 100644 index 00000000..7dd94bd3 --- /dev/null +++ b/vscript/languages/squirrel/sqplus/Makefile @@ -0,0 +1,18 @@ +SQUIRREL= .. + +OUT= $(SQUIRREL)/lib/libsqplus.a +INCDIRS= -I$(SQUIRREL)/include -I. -Iinclude + +ALLSRCS = $(wildcard *.cpp) +WIN32SRCS = $(wildcard *Win32*) +SRCS = $(filter-out $(WIN32SRCS),$(ALLSRCS)) + +sqplus: +# g++ -fno-rtti -c $(SRCS) $(INCDIRS) + g++ -O3 -fno-rtti -Os -c $(SRCS) $(INCDIRS) + ar rc $(OUT) *.o + rm *.o + + +#g++ -O3 -fno-rtti -Os -c $(SRCS) $(INCDIRS) +#g++ -ggdb -fno-rtti -c $(SRCS) $(INCDIRS) diff --git a/vscript/languages/squirrel/sqplus/SqPlus.cpp b/vscript/languages/squirrel/sqplus/SqPlus.cpp new file mode 100644 index 00000000..48adfad6 --- /dev/null +++ b/vscript/languages/squirrel/sqplus/SqPlus.cpp @@ -0,0 +1,298 @@ +#include "sqplus.h" +#ifdef _PS3 +#undef _STD_USING +#endif +#include +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#endif + +namespace SqPlus { + +static int getVarInfo(StackHandler & sa,VarRefPtr & vr) { + HSQOBJECT htable = sa.GetObjectHandle(1); + SquirrelObject table(htable); +#ifdef _DEBUG + SQObjectType type = (SQObjectType)sa.GetType(2); +#endif + const SQChar * el = sa.GetString(2); + ScriptStringVar256 varNameTag; + getVarNameTag(varNameTag,sizeof(varNameTag),el); + SQUserPointer data=0; + if (!table.RawGetUserData(varNameTag,&data)) { +// throw SquirrelError("getVarInfo: Could not retrieve UserData"); + return sa.ThrowError(_T("getVarInfo: Could not retrieve UserData")); // Results in variable not being found error. + } // if + vr = (VarRefPtr)data; + return SQ_OK; +} // getVarInfo + +static int getInstanceVarInfo(StackHandler & sa,VarRefPtr & vr,SQUserPointer & data) { + HSQOBJECT ho = sa.GetObjectHandle(1); + SquirrelObject instance(ho); +#ifdef _DEBUG + SQObjectType type = (SQObjectType)sa.GetType(2); +#endif + const SQChar * el = sa.GetString(2); + ScriptStringVar256 varNameTag; + getVarNameTag(varNameTag,sizeof(varNameTag),el); + SQUserPointer ivrData=0; + if (!instance.RawGetUserData(varNameTag,&ivrData)) { +// throw SquirrelError("getInstanceVarInfo: Could not retrieve UserData"); + return sa.ThrowError(_T("getInstanceVarInfo: Could not retrieve UserData")); // Results in variable not being found error. + } // if + vr = (VarRefPtr)ivrData; + unsigned char * up; + if (!(vr->access & (VAR_ACCESS_STATIC|VAR_ACCESS_CONSTANT))) { +#ifdef SQ_USE_CLASS_INHERITANCE + SQUserPointer typetag; instance.GetTypeTag(&typetag); + if (typetag != vr->instanceType) { + SquirrelObject typeTable = instance.GetValue(SQ_CLASS_OBJECT_TABLE_NAME); + up = (unsigned char *)typeTable.GetUserPointer(INT((size_t)vr->instanceType)); // 64-bit compatible version. + if (!up) { + throw SquirrelError(_T("Invalid Instance Type")); + } // if + } else { + up = (unsigned char *)instance.GetInstanceUP(0); + } // if +#else + up = (unsigned char *)instance.GetInstanceUP(0); +#endif + up += (size_t)vr->offsetOrAddrOrConst; // Offset + } else { + up = (unsigned char *)vr->offsetOrAddrOrConst; // Address + } // if + data = up; + return SQ_OK; +} // getInstanceVarInfo + +static int setVar(StackHandler & sa,VarRef * vr,void * data) { + if (vr->access & (VAR_ACCESS_READ_ONLY|VAR_ACCESS_CONSTANT)) { + ScriptStringVar256 msg; + const SQChar * el = sa.GetString(2); + SCSNPRINTF(msg.s,sizeof(msg),_T("setVar(): Cannot write to constant: %s"),el); + throw SquirrelError(msg.s); + } // if + switch (vr->type) { + case TypeInfo::TypeID: { + INT * val = (INT *)data; // Address + if (val) { + *val = sa.GetInt(3); + return sa.Return(*val); + } // if + break; + } // case + case TypeInfo::TypeID: { + FLOAT * val = (FLOAT *)data; // Address + if (val) { + *val = sa.GetFloat(3); + return sa.Return(*val); + } // if + break; + } // case + case TypeInfo::TypeID: { + bool * val = (bool *)data; // Address + if (val) { + *val = sa.GetBool(3) ? true : false; + return sa.Return(*val); + } // if + break; + } // case + case VAR_TYPE_INSTANCE: { + HSQUIRRELVM v = sa.GetVMPtr(); + // vr->copyFunc is the LHS variable type: the RHS var's type is ClassType<>::type() (both point to ClassType<>::copy()). + // src will be null if the LHS and RHS types don't match. + SQUserPointer src = sa.GetInstanceUp(3,(SQUserPointer)vr->copyFunc); // Effectively performs: ClassType<>::type() == ClassType<>getCopyFunc(). + if (!src) throw SquirrelError(_T("INSTANCE type assignment mismatch")); + vr->copyFunc(data,src); +#if 0 // Return an instance on the stack (allocates memory) + if (!CreateNativeClassInstance(sa.GetVMPtr(),vr->typeName,data,0)) { // data = address + ScriptStringVar256 msg; + SCSNPRINTF(msg.s,sizeof(msg),_T("getVar(): Could not create instance: %s"),vr->typeName); + throw SquirrelError(msg.s); + } // if + return 1; +#else // Don't return on stack. + return 0; +#endif + } + case TypeInfo::TypeID: { + ScriptStringVar256 msg; + const SQChar * el = sa.GetString(2); + SCSNPRINTF(msg.s,sizeof(msg),_T("setVar(): Cannot write to an SQUserPointer: %s"),el); + throw SquirrelError(msg.s); + } // case + case TypeInfo::TypeID: { + ScriptStringVarBase * val = (ScriptStringVarBase *)data; // Address + if (val) { + const SQChar * strVal = sa.GetString(3); + if (strVal) { + *val = strVal; + return sa.Return(val->s); + } // if + } // if + break; + } // case + } // switch + return SQ_ERROR; +} // setVar + +static int getVar(StackHandler & sa,VarRef * vr,void * data) { + switch (vr->type) { + case TypeInfo::TypeID: { + if (!(vr->access & VAR_ACCESS_CONSTANT)) { + INT * val = (INT *)data; // Address + if (val) { + return sa.Return(*val); + } // if + } else { + INT * val = (INT *)&data; // Constant value + return sa.Return(*val); + } // if + break; + } // case + case TypeInfo::TypeID: { + if (!(vr->access & VAR_ACCESS_CONSTANT)) { + FLOAT * val = (FLOAT *)data; // Address + if (val) { + return sa.Return(*val); + } // if + } else { + FLOAT * val = (FLOAT *)&data; // Constant value + return sa.Return(*val); + } // if + break; + } // case + case TypeInfo::TypeID: { + if (!(vr->access & VAR_ACCESS_CONSTANT)) { + bool * val = (bool *)data; // Address + if (val) { + return sa.Return(*val); + } // if + } else { + bool * val = (bool *)&data; // Constant value + return sa.Return(*val); + } // if + break; + } // case + case VAR_TYPE_INSTANCE: + if (!CreateNativeClassInstance(sa.GetVMPtr(),vr->typeName,data,0)) { // data = address. Allocates memory. + ScriptStringVar256 msg; + SCSNPRINTF(msg.s,sizeof(msg),_T("getVar(): Could not create instance: %s"),vr->typeName); + throw SquirrelError(msg.s); + } // if + return 1; + case TypeInfo::TypeID: { + return sa.Return(data); // The address of member variable, not the variable itself. + } // case + case TypeInfo::TypeID: { + if (!(vr->access & VAR_ACCESS_CONSTANT)) { + ScriptStringVarBase * val = (ScriptStringVarBase *)data; // Address + if (val) { + return sa.Return(val->s); + } // if + } else { + throw SquirrelError(_T("getVar(): Invalid type+access: 'ScriptStringVarBase' with VAR_ACCESS_CONSTANT (use VAR_ACCESS_READ_ONLY instead)")); + } // if + break; + } // case + case TypeInfo::TypeID: { + if (!(vr->access & VAR_ACCESS_CONSTANT)) { + throw SquirrelError(_T("getVar(): Invalid type+access: 'const SQChar *' without VAR_ACCESS_CONSTANT")); + } else { + return sa.Return((const SQChar *)data); // Address + } // if + break; + } // case + } // switch + return SQ_ERROR; +} // getVar + +// === Global Vars === + +SQInteger setVarFunc(HSQUIRRELVM v) { + StackHandler sa(v); + if (sa.GetType(1) == OT_TABLE) { + VarRefPtr vr; + int res = getVarInfo(sa,vr); + if (res != SQ_OK) return res; + return setVar(sa,vr,vr->offsetOrAddrOrConst); + } // if + return SQ_ERROR; +} // setVarFunc + +SQInteger getVarFunc(HSQUIRRELVM v) { + StackHandler sa(v); + if (sa.GetType(1) == OT_TABLE) { + VarRefPtr vr; + int res = getVarInfo(sa,vr); + if (res != SQ_OK) return res; + return getVar(sa,vr,vr->offsetOrAddrOrConst); + } // if + return SQ_ERROR; +} // getVarFunc + +// === Instance Vars === + +SQInteger setInstanceVarFunc(HSQUIRRELVM v) { + StackHandler sa(v); + if (sa.GetType(1) == OT_INSTANCE) { + VarRefPtr vr; + void * data; + int res = getInstanceVarInfo(sa,vr,data); + if (res != SQ_OK) return res; + return setVar(sa,vr,data); + } // if + return SQ_ERROR; +} // setInstanceVarFunc + +SQInteger getInstanceVarFunc(HSQUIRRELVM v) { + StackHandler sa(v); + if (sa.GetType(1) == OT_INSTANCE) { + VarRefPtr vr; + void * data; + int res = getInstanceVarInfo(sa,vr,data); + if (res != SQ_OK) return res; + return getVar(sa,vr,data); + } // if + return SQ_ERROR; +} // getInstanceVarFunc + +// === Classes === + +BOOL CreateClass(HSQUIRRELVM v,SquirrelObject & newClass,SQUserPointer classType,const SQChar * name,const SQChar * baseName) { + int n = 0; + int oldtop = sq_gettop(v); + sq_pushroottable(v); + sq_pushstring(v,name,-1); + if (baseName) { + sq_pushstring(v,baseName,-1); + if (SQ_FAILED(sq_get(v,-3))) { // Make sure the base exists if specified by baseName. + sq_settop(v,oldtop); + return FALSE; + } // if + } // if + if (SQ_FAILED(sq_newclass(v,baseName ? 1 : 0))) { // Will inherit from base class on stack from sq_get() above. + sq_settop(v,oldtop); + return FALSE; + } // if + newClass.AttachToStackObject(-1); + sq_settypetag(v,-1,classType); + sq_createslot(v,-3); + sq_pop(v,1); + return TRUE; +} // CreateClass + +SquirrelObject RegisterClassType(HSQUIRRELVM v,const SQChar * scriptClassName,SQUserPointer classType,SQFUNCTION constructor) { + int top = sq_gettop(v); + SquirrelObject newClass; + if (CreateClass(v,newClass,classType,scriptClassName)) { + SquirrelVM::CreateFunction(newClass,constructor,_T("constructor")); + } // if + sq_settop(v,top); + return newClass; +} // RegisterClassType + +}; // namespace SqPlus + +// sqPlus diff --git a/vscript/languages/squirrel/sqplus/SqPlusConst.h b/vscript/languages/squirrel/sqplus/SqPlusConst.h new file mode 100644 index 00000000..d65b30f6 --- /dev/null +++ b/vscript/languages/squirrel/sqplus/SqPlusConst.h @@ -0,0 +1,334 @@ +// SqPlusConst.h +// SqPlus constant type and constant member function support created by Simon Michelmore. +// Modular integration 11/14/05 jcs. + +#ifdef SQPLUS_DECLARE_INSTANCE_TYPE_CONST +#undef SQPLUS_DECLARE_INSTANCE_TYPE_CONST + +// Kamaitati's NULL_INSTANCE support. 5/28/06 jcs + +#ifdef SQPLUS_SUPPORT_NULL_INSTANCES + +#define DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,NAME) \ +DECLARE_INSTANCE_TYPE_NAME_(TYPE,NAME) \ +namespace SqPlus { \ +inline void Push(HSQUIRRELVM v,const TYPE * value) { \ + if (!value) sq_pushnull(v); \ + else if (!CreateNativeClassInstance(v,GetTypeName(*value),(TYPE*)value,0)) \ + throw SquirrelError(_T("Push(): could not create INSTANCE (check registration name)")); } \ +inline void Push(HSQUIRRELVM v,const TYPE & value) { if (!CreateCopyInstance(GetTypeName(value),value)) throw SquirrelError(_T("Push(): could not create INSTANCE copy (check registration name)")); } \ +inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return GetInstance(v,idx) != NULL; } \ +inline const TYPE & Get(TypeWrapper,HSQUIRRELVM v,int idx) { return *GetInstance(v,idx); } \ +} // nameSpace SqPlus + +#else + +#define DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,NAME) \ +DECLARE_INSTANCE_TYPE_NAME_(TYPE,NAME) \ +namespace SqPlus { \ +inline void Push(HSQUIRRELVM v,const TYPE * value) { if (!CreateNativeClassInstance(v,GetTypeName(*value),(TYPE*)value,0)) throw SquirrelError(_T("Push(): could not create INSTANCE (check registration name)")); } \ +inline void Push(HSQUIRRELVM v,const TYPE & value) { if (!CreateCopyInstance(GetTypeName(value),value)) throw SquirrelError(_T("Push(): could not create INSTANCE copy (check registration name)")); } \ +inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return GetInstance(v,idx) != NULL; } \ +inline const TYPE & Get(TypeWrapper,HSQUIRRELVM v,int idx) { return *GetInstance(v,idx); } \ +} // nameSpace SqPlus + +#endif + +#define DECLARE_INSTANCE_TYPE(TYPE) DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,TYPE) +#define DECLARE_INSTANCE_TYPE_NAME(TYPE,NAME) DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,NAME) +#endif + +#ifdef SQPLUS_CALL_CONST_MFUNC_RET0 +#undef SQPLUS_CALL_CONST_MFUNC_RET0 +template +static int Call(Callee & callee,RT (Callee::*func)() const,HSQUIRRELVM v,int /*index*/) { + RT ret = (callee.*func)(); + Push(v,ret); + return 1; +} + +template +static int Call(Callee & callee,RT (Callee::*func)(P1) const,HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + RT ret = (callee.*func)( + Get(TypeWrapper(),v,index + 0) + ); + Push(v,ret); + return 1; +} + +template +static int Call(Callee & callee,RT (Callee::*func)(P1,P2) const,HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + RT ret = (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1) + ); + Push(v,ret); + return 1; +} + +template +static int Call(Callee & callee,RT (Callee::*func)(P1,P2,P3) const,HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + RT ret = (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2) + ); + Push(v,ret); + return 1; +} + +template +static int Call(Callee & callee,RT (Callee::*func)(P1,P2,P3,P4) const,HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + RT ret = (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3) + ); + Push(v,ret); + return 1; +} + +template +static int Call(Callee & callee,RT (Callee::*func)(P1,P2,P3,P4,P5) const,HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + sq_argassert(5,index + 4); + RT ret = (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3), + Get(TypeWrapper(),v,index + 4) + ); + Push(v,ret); + return 1; +} + +template +static int Call(Callee & callee,RT (Callee::*func)(P1,P2,P3,P4,P5,P6) const,HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + sq_argassert(5,index + 4); + sq_argassert(6,index + 5); + RT ret = (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3), + Get(TypeWrapper(),v,index + 4), + Get(TypeWrapper(),v,index + 5) + ); + Push(v,ret); + return 1; +} + +template +static int Call(Callee & callee,RT (Callee::*func)(P1,P2,P3,P4,P5,P6,P7) const,HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + sq_argassert(5,index + 4); + sq_argassert(6,index + 5); + sq_argassert(7,index + 6); + RT ret = (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3), + Get(TypeWrapper(),v,index + 4), + Get(TypeWrapper(),v,index + 5), + Get(TypeWrapper(),v,index + 6) + ); + Push(v,ret); + return 1; +} +#endif + +#ifdef SQPLUS_CALL_CONST_MFUNC_NORET +#undef SQPLUS_CALL_CONST_MFUNC_NORET +template +static int Call(Callee & callee,void (Callee::*func)() const,HSQUIRRELVM,int /*index*/) { + (callee.*func)(); + return 0; +} + +template +static int Call(Callee & callee,void (Callee::*func)(P1) const,HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + (callee.*func)( + Get(TypeWrapper(),v,index + 0) + ); + return 0; +} + +template +static int Call(Callee & callee,void (Callee::*func)(P1,P2) const,HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1) + ); + return 0; +} + +template +static int Call(Callee & callee,void (Callee::*func)(P1,P2,P3) const,HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2) + ); + return 0; +} + +template +static int Call(Callee & callee,void (Callee::*func)(P1,P2,P3,P4) const,HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3) + ); + return 0; +} + +template +static int Call(Callee & callee,void (Callee::*func)(P1,P2,P3,P4,P5) const,HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + sq_argassert(5,index + 4); + (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3), + Get(TypeWrapper(),v,index + 4) + ); + return 0; +} + +template +static int Call(Callee & callee,void (Callee::*func)(P1,P2,P3,P4,P5,P6) const,HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + sq_argassert(5,index + 4); + sq_argassert(6,index + 5); + (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3), + Get(TypeWrapper(),v,index + 4), + Get(TypeWrapper(),v,index + 5) + ); + return 0; +} + +template +static int Call(Callee & callee,void (Callee::*func)(P1,P2,P3,P4,P5,P6,P7) const,HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + sq_argassert(5,index + 4); + sq_argassert(6,index + 5); + sq_argassert(7,index + 6); + (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3), + Get(TypeWrapper(),v,index + 4), + Get(TypeWrapper(),v,index + 5), + Get(TypeWrapper(),v,index + 6) + ); + return 0; +} +#endif + +#ifdef SQPLUS_CALL_CONST_MFUNC_RET1 +#undef SQPLUS_CALL_CONST_MFUNC_RET1 +template +int Call(Callee & callee, RT (Callee::*func)() const,HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); +} + +template +int Call(Callee & callee,RT (Callee::*func)(P1) const,HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); +} + +template +int Call(Callee & callee,RT (Callee::*func)(P1,P2) const,HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); +} + +template +int Call(Callee & callee,RT (Callee::*func)(P1,P2,P3) const,HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); +} + +template +int Call(Callee & callee,RT (Callee::*func)(P1,P2,P3,P4) const,HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); +} + +template +int Call(Callee & callee,RT (Callee::*func)(P1,P2,P3,P4,P5) const,HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); +} + +template +int Call(Callee & callee,RT (Callee::*func)(P1,P2,P3,P4,P5,P6) const,HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); +} + +template +int Call(Callee & callee,RT (Callee::*func)(P1,P2,P3,P4,P5,P6,P7) const,HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); +} +#undef SQPLUS_CALL_CONST_MFUNC_RET1 +#endif + +#ifdef SQ_REG_CONST_STATIC_VAR +#undef SQ_REG_CONST_STATIC_VAR +template +SQClassDefBase & staticVar(const VarType * pvar,const SQChar * name,VarAccessType access=VAR_ACCESS_READ_ONLY) { + struct CV { + const VarType * var; + } cv; // Cast Variable helper. + cv.var = pvar; + RegisterInstanceVariable(newClass,ClassType::type(),*(VarType **)&cv,name,VarAccessType(access|VAR_ACCESS_STATIC)); + return *this; +} // staticVar +#endif + +// SqPlusConst.h diff --git a/vscript/languages/squirrel/sqplus/SquirrelBindingsUtils.cpp b/vscript/languages/squirrel/sqplus/SquirrelBindingsUtils.cpp new file mode 100644 index 00000000..af141616 --- /dev/null +++ b/vscript/languages/squirrel/sqplus/SquirrelBindingsUtils.cpp @@ -0,0 +1,122 @@ +#include "sqplus.h" +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#endif + + + +BOOL CreateStaticNamespace(HSQUIRRELVM v,ScriptNamespaceDecl *sn) +{ + int n = 0; + sq_pushroottable(v); + sq_pushstring(v,sn->name,-1); + sq_newtable(v); + const ScriptClassMemberDecl *members = sn->members; + const ScriptClassMemberDecl *m = NULL; + while(members[n].name) { + m = &members[n]; + sq_pushstring(v,m->name,-1); + sq_newclosure(v,m->func,0); + sq_setparamscheck(v,m->params,m->typemask); + sq_setnativeclosurename(v,-1,m->name); + sq_createslot(v,-3); + n++; + } + const ScriptConstantDecl *consts = sn->constants; + const ScriptConstantDecl *c = NULL; + n = 0; + while(consts[n].name) { + c = &consts[n]; + sq_pushstring(v,c->name,-1); + switch(c->type) { + case OT_STRING: sq_pushstring(v,c->val.s,-1);break; + case OT_INTEGER: sq_pushinteger(v,c->val.i);break; + case OT_FLOAT: sq_pushfloat(v,c->val.f);break; + } + sq_createslot(v,-3); + n++; + } + if(sn->delegate) { + const ScriptClassMemberDecl *members = sn->delegate; + const ScriptClassMemberDecl *m = NULL; + sq_newtable(v); + while(members[n].name) { + m = &members[n]; + sq_pushstring(v,m->name,-1); + sq_newclosure(v,m->func,0); + sq_setparamscheck(v,m->params,m->typemask); + sq_setnativeclosurename(v,-1,m->name); + sq_createslot(v,-3); + n++; + } + sq_setdelegate(v,-2); + } + sq_createslot(v,-3); + sq_pop(v,1); + + return TRUE; +} + +BOOL CreateClass(HSQUIRRELVM v,SquirrelClassDecl *cd) +{ + int n = 0; + int oldtop = sq_gettop(v); + sq_pushroottable(v); + sq_pushstring(v,cd->name,-1); + if(cd->base) { + sq_pushstring(v,cd->base,-1); + if(SQ_FAILED(sq_get(v,-3))) { // Make sure the base exists if specified by cd->base name. + sq_settop(v,oldtop); + return FALSE; + } + } + if(SQ_FAILED(sq_newclass(v,cd->base?1:0))) { // Will inherit from base class on stack from sq_get() above. + sq_settop(v,oldtop); + return FALSE; + } +// sq_settypetag(v,-1,(unsigned int)cd); +#ifdef _WIN32 +#pragma warning(disable : 4311) +#endif + sq_settypetag(v,-1,reinterpret_cast(cd)); + const ScriptClassMemberDecl *members = cd->members; + const ScriptClassMemberDecl *m = NULL; + if (members) { + while(members[n].name) { + m = &members[n]; + sq_pushstring(v,m->name,-1); + sq_newclosure(v,m->func,0); + sq_setparamscheck(v,m->params,m->typemask); + sq_setnativeclosurename(v,-1,m->name); + sq_createslot(v,-3); + n++; + } + } // if + sq_createslot(v,-3); + sq_pop(v,1); + return TRUE; +} + +BOOL CreateNativeClassInstance(HSQUIRRELVM v,const SQChar *classname,SQUserPointer ud,SQRELEASEHOOK hook) +{ + int oldtop = sq_gettop(v); + sq_pushroottable(v); + sq_pushstring(v,classname,-1); + if(SQ_FAILED(sq_rawget(v,-2))){ // Get the class (created with sq_newclass()). + sq_settop(v,oldtop); + return FALSE; + } + //sq_pushroottable(v); + if(SQ_FAILED(sq_createinstance(v,-1))) { + sq_settop(v,oldtop); + return FALSE; + } + sq_remove(v,-3); //removes the root table + sq_remove(v,-2); //removes the class + if(SQ_FAILED(sq_setinstanceup(v,-1,ud))) { + sq_settop(v,oldtop); + return FALSE; + } + sq_setreleasehook(v,-1,hook); + return TRUE; +} diff --git a/vscript/languages/squirrel/sqplus/SquirrelBindingsUtils.h b/vscript/languages/squirrel/sqplus/SquirrelBindingsUtils.h new file mode 100644 index 00000000..a3336f90 --- /dev/null +++ b/vscript/languages/squirrel/sqplus/SquirrelBindingsUtils.h @@ -0,0 +1,151 @@ +#ifndef SQUIRREL_BINDINGS_UTILS_H +#define SQUIRREL_BINDINGS_UTILS_H + +struct ScriptClassMemberDecl { + const SQChar *name; + SQFUNCTION func; + int params; + const SQChar *typemask; +}; + +struct SquirrelClassDecl { + const SQChar *name; + const SQChar *base; + const ScriptClassMemberDecl *members; +}; + +struct ScriptConstantDecl { + const SQChar *name; + SQObjectType type; + union value { + value(float v){ f = v; } + value(int v){ i = v; } + value(long int v){ li = v; } + value(const SQChar *v){ s = v; } + float f; + int i; + long int li; + const SQChar *s; + } val; +}; + +struct ScriptNamespaceDecl { + const SQChar *name; + const ScriptClassMemberDecl *members; + const ScriptConstantDecl *constants; + const ScriptClassMemberDecl *delegate; +}; + +#define _BEGIN_CLASS(classname) \ + int __##classname##__typeof(HSQUIRRELVM v) \ + { \ + sq_pushstring(v,_T(#classname),-1); \ + return 1; \ + } \ + struct ScriptClassMemberDecl __##classname##_members[] = { \ + {_T("_typeof"),__##classname##__typeof,1,NULL}, + +#define _BEGIN_NAMESPACE(xnamespace) struct ScriptClassMemberDecl __##xnamespace##_members[] = { +#define _BEGIN_NAMESPACE_CONSTANTS(xnamespace) {NULL,NULL,0,NULL}}; \ + struct ScriptConstantDecl __##xnamespace##_constants[] = { + +#define _BEGIN_DELEGATE(xnamespace) struct ScriptClassMemberDecl __##xnamespace##_delegate[] = { +#define _DELEGATE(xnamespace) __##xnamespace##_delegate +#define _END_DELEGATE(classname) {NULL,NULL,NULL,NULL}}; + +#define _CONSTANT(name,type,val) {_T(#name),type,val}, +#define _CONSTANT_IMPL(name,type) {_T(#name),type,name}, + +#define _MEMBER_FUNCTION(classname,name,nparams,typemask) \ + {_T(#name),__##classname##_##name,nparams,typemask}, + +#define _END_NAMESPACE(classname,delegate) {NULL,OT_NULL,0}}; \ +struct ScriptNamespaceDecl __##classname##_decl = { \ + _T(#classname), __##classname##_members,__##classname##_constants,delegate }; + +#define _END_CLASS(classname) {NULL,NULL,0,NULL}}; \ +struct SquirrelClassDecl __##classname##_decl = { \ + _T(#classname), NULL, __##classname##_members }; + + +#define _END_CLASS_INHERITANCE(classname,base) {NULL,NULL,NULL,NULL}}; \ +struct SquirrelClassDecl __##classname##_decl = { \ + _T(#classname), _T(#base), __##classname##_members }; + +#define _MEMBER_FUNCTION_IMPL(classname,name) \ + int __##classname##_##name(HSQUIRRELVM v) + +#define _INIT_STATIC_NAMESPACE(classname) CreateStaticNamespace(SquirrelVM::GetVMPtr(),&__##classname##_decl); +#define _INIT_CLASS(classname)CreateClass(SquirrelVM::GetVMPtr(),&__##classname##_decl); + +#define _DECL_STATIC_NAMESPACE(xnamespace) extern struct ScriptNamespaceDecl __##xnamespace##_decl; +#define _DECL_CLASS(classname) extern struct SquirrelClassDecl __##classname##_decl; + +#define _CHECK_SELF(cppclass,scriptclass) \ + cppclass *self = NULL; \ + if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)&__##scriptclass##_decl))) { \ + return sq_throwerror(v,_T("invalid instance type"));\ + } + +#define _CHECK_INST_PARAM(pname,idx,cppclass,scriptclass) \ + cppclass *pname = NULL; \ + if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer*)&pname,(SQUserPointer)&__##scriptclass##_decl))) { \ + return sq_throwerror(v,_T("invalid instance type"));\ + } \ + +#define _CHECK_INST_PARAM_BREAK(pname,idx,cppclass,scriptclass) \ + cppclass *pname = NULL; \ + if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer*)&pname,(SQUserPointer)&__##scriptclass##_decl))) { \ + break; \ + } \ + +#define _CLASS_TAG(classname) ((unsigned int)&__##classname##_decl) + + +#define _DECL_NATIVE_CONSTRUCTION(classname,cppclass) \ + BOOL push_##classname(cppclass &quat); \ + SquirrelObject new_##classname(cppclass &quat); + +#define _IMPL_NATIVE_CONSTRUCTION(classname,cppclass) \ +static int classname##_release_hook(SQUserPointer p, int size) \ +{ \ + if(p) { \ + cppclass *pv = (cppclass *)p; \ + delete pv; \ + } \ + return 0; \ +} \ +BOOL push_##classname(cppclass &quat) \ +{ \ + cppclass *newquat = new cppclass; \ + *newquat = quat; \ + if(!CreateNativeClassInstance(SquirrelVM::GetVMPtr(),_T(#classname),newquat,classname##_release_hook)) { \ + delete newquat; \ + return FALSE; \ + } \ + return TRUE; \ +} \ +SquirrelObject new_##classname(cppclass &quat) \ +{ \ + SquirrelObject ret; \ + if(push_##classname(quat)) { \ + ret.AttachToStackObject(-1); \ + sq_pop(SquirrelVM::GetVMPtr(),1); \ + } \ + return ret; \ +} \ +int construct_##classname(cppclass *p) \ +{ \ + sq_setinstanceup(SquirrelVM::GetVMPtr(),1,p); \ + sq_setreleasehook(SquirrelVM::GetVMPtr(),1,classname##_release_hook); \ + return 1; \ +} + +BOOL CreateStaticClass(HSQUIRRELVM v,SquirrelClassDecl *cd); +BOOL CreateStaticNamespace(HSQUIRRELVM v,ScriptNamespaceDecl *sn); +BOOL CreateClass(HSQUIRRELVM v,SquirrelClassDecl *cd); +BOOL InitScriptClasses(HSQUIRRELVM v); +BOOL CreateNativeClassInstance(HSQUIRRELVM v,const SQChar *classname,SQUserPointer ud,SQRELEASEHOOK hook); + +#endif // SQUIRREL_BINDINGS_UTILS_H + diff --git a/vscript/languages/squirrel/sqplus/SquirrelBindingsUtilsWin32.cpp b/vscript/languages/squirrel/sqplus/SquirrelBindingsUtilsWin32.cpp new file mode 100644 index 00000000..904744da --- /dev/null +++ b/vscript/languages/squirrel/sqplus/SquirrelBindingsUtilsWin32.cpp @@ -0,0 +1,34 @@ +#include "sqplus.h" + +//#include "SquirrelObject.h" +//#include "SquirrelVM.h" +#include "SquirrelBindingsUtilsWin32.h" +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#endif + +SQInteger refcounted_release_hook(SQUserPointer p, SQInteger size) +{ + IUnknown *pRC = (IUnknown*)p; + pRC->Release(); + return 0; +} + +static BOOL __CreateRefCountedInstance(HSQUIRRELVM v,const SQChar *classname,IUnknown *pRC,SQRELEASEHOOK hook) +{ + if(!CreateNativeClassInstance(v,classname,pRC,hook)) return FALSE; + return TRUE; +} + +int construct_RefCounted(IUnknown *p) +{ + sq_setinstanceup(SquirrelVM::GetVMPtr(),1,p); + sq_setreleasehook(SquirrelVM::GetVMPtr(),1,refcounted_release_hook); + return 1; +} + + +BOOL CreateRefCountedInstance(HSQUIRRELVM v,const SQChar *classname,IUnknown *pRC) +{ + return __CreateRefCountedInstance(v,classname,pRC,refcounted_release_hook); +} diff --git a/vscript/languages/squirrel/sqplus/SquirrelBindingsUtilsWin32.h b/vscript/languages/squirrel/sqplus/SquirrelBindingsUtilsWin32.h new file mode 100644 index 00000000..d7e8a312 --- /dev/null +++ b/vscript/languages/squirrel/sqplus/SquirrelBindingsUtilsWin32.h @@ -0,0 +1,43 @@ +#ifndef SQUIRREL_BINDINGS_UTILS_WIN32_H +#define SQUIRREL_BINDINGS_UTILS_WIN32_H + +#ifdef WIN32 +#ifndef _INC_WINDOWS +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include +#endif +#ifndef __IUnknown_INTERFACE_DEFINED__ +#include +#endif +#endif + +#ifndef SQUIRREL_BINDINGS_UTILS_H +#include "SquirrelBindingsUtils.h" +#endif + +#define _DECLARE_REFCOUNTED_NEW(cppclass,classname) \ + SquirrelObject new_##classname(cppclass *ptr) { \ + if(CreateRefCountedInstance(SquirrelVM::GetVMPtr(),_T(#classname),ptr)) { \ + HSQOBJECT o; \ + sq_getstackobj(SquirrelVM::GetVMPtr(),-1,&o); \ + SquirrelObject tmp = o; \ + sq_pop(SquirrelVM::GetVMPtr(),1); \ + return tmp; \ + } \ + return SquirrelObject() ; \ + } + +#define _RETURN_REFCOUNTED_INSTANCE(classname,ptr) \ + if(!CreateRefCountedInstance(SquirrelVM::GetVMPtr(),_T(#classname),ptr)) { \ + return sa.ThrowError(_T("cannot create the class instance")); \ + } \ + return 1; + +BOOL CreateRefCountedInstance(HSQUIRRELVM v,const SQChar *classname,IUnknown *pRC); +BOOL CreateRefCountedInstanceChached(HSQUIRRELVM v,const SQChar *classname,IUnknown *pRC); +SQInteger refcounted_release_hook(SQUserPointer p, SQInteger size); +int construct_RefCounted(IUnknown *p); + +#endif // SQUIRREL_BINDINGS_UTILS_WIN32_H + diff --git a/vscript/languages/squirrel/sqplus/SquirrelObject.cpp b/vscript/languages/squirrel/sqplus/SquirrelObject.cpp new file mode 100644 index 00000000..99a90372 --- /dev/null +++ b/vscript/languages/squirrel/sqplus/SquirrelObject.cpp @@ -0,0 +1,640 @@ +#include "sqplus.h" +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#endif + +SquirrelObject::SquirrelObject(void) +{ + sq_resetobject(&_o); +} + +SquirrelObject::~SquirrelObject() +{ + if(SquirrelVM::_VM) + sq_release(SquirrelVM::_VM,&_o); +} + +SquirrelObject::SquirrelObject(SquirrelObject &o) +{ + _o = o._o; + sq_addref(SquirrelVM::_VM,&_o); +} + +SquirrelObject::SquirrelObject(HSQOBJECT o) +{ + _o = o; + sq_addref(SquirrelVM::_VM,&_o); +} + +void SquirrelObject::Reset(void) { + if(SquirrelVM::_VM) + sq_release(SquirrelVM::_VM,&_o); + sq_resetobject(&_o); +} // SquirrelObject::Reset + +SquirrelObject SquirrelObject::Clone() +{ + SquirrelObject ret; + if(GetType() == OT_TABLE || GetType() == OT_ARRAY) + { + sq_pushobject(SquirrelVM::_VM,_o); + sq_clone(SquirrelVM::_VM,-1); + ret.AttachToStackObject(-1); + sq_pop(SquirrelVM::_VM,2); + } + return ret; + +} + +SquirrelObject & SquirrelObject::operator =(const SquirrelObject &o) +{ + HSQOBJECT t; + t = o._o; + sq_addref(SquirrelVM::_VM,&t); + sq_release(SquirrelVM::_VM,&_o); + _o = t; + return *this; +} + +SquirrelObject & SquirrelObject::operator =(int n) +{ + sq_pushinteger(SquirrelVM::_VM,n); + AttachToStackObject(-1); + sq_pop(SquirrelVM::_VM,1); + return *this; +} + +void SquirrelObject::ArrayAppend(const SquirrelObject &o) +{ + if(sq_isarray(_o)) { + sq_pushobject(SquirrelVM::_VM,_o); + sq_pushobject(SquirrelVM::_VM,o._o); + sq_arrayappend(SquirrelVM::_VM,-2); + sq_pop(SquirrelVM::_VM,1); + } +} + +void SquirrelObject::AttachToStackObject(int idx) +{ + HSQOBJECT t; + sq_getstackobj(SquirrelVM::_VM,idx,&t); + sq_addref(SquirrelVM::_VM,&t); + sq_release(SquirrelVM::_VM,&_o); + _o = t; +} + +BOOL SquirrelObject::SetDelegate(SquirrelObject &obj) +{ + if(obj.GetType() == OT_TABLE || + obj.GetType() == OT_NULL) { + switch(_o._type) { + case OT_USERDATA: + case OT_TABLE: + sq_pushobject(SquirrelVM::_VM,_o); + sq_pushobject(SquirrelVM::_VM,obj._o); + if(SQ_SUCCEEDED(sq_setdelegate(SquirrelVM::_VM,-2))) + return TRUE; + break; + } + } + return FALSE; +} + +SquirrelObject SquirrelObject::GetDelegate() +{ + SquirrelObject ret; + if(_o._type == OT_TABLE || _o._type == OT_USERDATA) + { + int top = sq_gettop(SquirrelVM::_VM); + sq_pushobject(SquirrelVM::_VM,_o); + sq_getdelegate(SquirrelVM::_VM,-1); + ret.AttachToStackObject(-1); + sq_settop(SquirrelVM::_VM,top); +// sq_pop(SquirrelVM::_VM,2); + } + return ret; +} + +BOOL SquirrelObject::IsNull() const +{ + return sq_isnull(_o); +} + +BOOL SquirrelObject::IsNumeric() const +{ + return sq_isnumeric(_o); +} + +int SquirrelObject::Len() const +{ + int ret = 0; + if(sq_isarray(_o) || sq_istable(_o) || sq_isstring(_o)) { + sq_pushobject(SquirrelVM::_VM,_o); + ret = sq_getsize(SquirrelVM::_VM,-1); + sq_pop(SquirrelVM::_VM,1); + } + return ret; +} + +#define _SETVALUE_INT_BEGIN \ + BOOL ret = FALSE; \ + int top = sq_gettop(SquirrelVM::_VM); \ + sq_pushobject(SquirrelVM::_VM,_o); \ + sq_pushinteger(SquirrelVM::_VM,key); + +#define _SETVALUE_INT_END \ + if(SQ_SUCCEEDED(sq_rawset(SquirrelVM::_VM,-3))) { \ + ret = TRUE; \ + } \ + sq_settop(SquirrelVM::_VM,top); \ + return ret; + +BOOL SquirrelObject::SetValue(INT key,const SquirrelObject &val) +{ + _SETVALUE_INT_BEGIN + sq_pushobject(SquirrelVM::_VM,val._o); + _SETVALUE_INT_END +} + +BOOL SquirrelObject::SetValue(INT key,INT n) +{ + _SETVALUE_INT_BEGIN + sq_pushinteger(SquirrelVM::_VM,n); + _SETVALUE_INT_END +} + +BOOL SquirrelObject::SetValue(INT key,FLOAT f) +{ + _SETVALUE_INT_BEGIN + sq_pushfloat(SquirrelVM::_VM,f); + _SETVALUE_INT_END +} + +BOOL SquirrelObject::SetValue(INT key,const SQChar *s) +{ + _SETVALUE_INT_BEGIN + sq_pushstring(SquirrelVM::_VM,s,-1); + _SETVALUE_INT_END +} + +BOOL SquirrelObject::SetValue(INT key,bool b) +{ + _SETVALUE_INT_BEGIN + sq_pushbool(SquirrelVM::_VM,b); + _SETVALUE_INT_END +} + +BOOL SquirrelObject::SetValue(const SquirrelObject &key,const SquirrelObject &val) +{ + BOOL ret = FALSE; + int top = sq_gettop(SquirrelVM::_VM); + sq_pushobject(SquirrelVM::_VM,_o); + sq_pushobject(SquirrelVM::_VM,key._o); + sq_pushobject(SquirrelVM::_VM,val._o); + if(SQ_SUCCEEDED(sq_rawset(SquirrelVM::_VM,-3))) { + ret = TRUE; + } + sq_settop(SquirrelVM::_VM,top); + return ret; +} + +#define _SETVALUE_STR_BEGIN \ + BOOL ret = FALSE; \ + int top = sq_gettop(SquirrelVM::_VM); \ + sq_pushobject(SquirrelVM::_VM,_o); \ + sq_pushstring(SquirrelVM::_VM,key,-1); + +#define _SETVALUE_STR_END \ + if(SQ_SUCCEEDED(sq_rawset(SquirrelVM::_VM,-3))) { \ + ret = TRUE; \ + } \ + sq_settop(SquirrelVM::_VM,top); \ + return ret; + +BOOL SquirrelObject::SetValue(const SQChar *key,const SquirrelObject &val) +{ + _SETVALUE_STR_BEGIN + sq_pushobject(SquirrelVM::_VM,val._o); + _SETVALUE_STR_END +} + +BOOL SquirrelObject::SetValue(const SQChar *key,INT n) +{ + _SETVALUE_STR_BEGIN + sq_pushinteger(SquirrelVM::_VM,n); + _SETVALUE_STR_END +} + +BOOL SquirrelObject::SetValue(const SQChar *key,FLOAT f) +{ + _SETVALUE_STR_BEGIN + sq_pushfloat(SquirrelVM::_VM,f); + _SETVALUE_STR_END +} + +BOOL SquirrelObject::SetValue(const SQChar *key,const SQChar *s) +{ + _SETVALUE_STR_BEGIN + sq_pushstring(SquirrelVM::_VM,s,-1); + _SETVALUE_STR_END +} + +BOOL SquirrelObject::SetValue(const SQChar *key,bool b) +{ + _SETVALUE_STR_BEGIN + sq_pushbool(SquirrelVM::_VM,b); + _SETVALUE_STR_END +} + +// === BEGIN User Pointer, User Data === + +BOOL SquirrelObject::SetUserPointer(const SQChar * key,SQUserPointer up) { + _SETVALUE_STR_BEGIN + sq_pushuserpointer(SquirrelVM::_VM,up); + _SETVALUE_STR_END +} // SquirrelObject::SetUserPointer + +SQUserPointer SquirrelObject::GetUserPointer(const SQChar * key) { + SQUserPointer ret = NULL; + if (GetSlot(key)) { + sq_getuserpointer(SquirrelVM::_VM,-1,&ret); + sq_pop(SquirrelVM::_VM,1); + } // if + sq_pop(SquirrelVM::_VM,1); + return ret; +} // SquirrelObject::GetUserPointer + +BOOL SquirrelObject::SetUserPointer(INT key,SQUserPointer up) { + _SETVALUE_INT_BEGIN + sq_pushuserpointer(SquirrelVM::_VM,up); + _SETVALUE_INT_END +} // SquirrelObject::SetUserPointer + +SQUserPointer SquirrelObject::GetUserPointer(INT key) { + SQUserPointer ret = NULL; + if (GetSlot(key)) { + sq_getuserpointer(SquirrelVM::_VM,-1,&ret); + sq_pop(SquirrelVM::_VM,1); + } // if + sq_pop(SquirrelVM::_VM,1); + return ret; +} // SquirrelObject::GetUserPointer + +// === User Data === + +BOOL SquirrelObject::NewUserData(const SQChar * key,INT size,SQUserPointer * typetag) { + _SETVALUE_STR_BEGIN + sq_newuserdata(SquirrelVM::_VM,size); + if (typetag) { + sq_settypetag(SquirrelVM::_VM,-1,typetag); + } // if + _SETVALUE_STR_END +} // SquirrelObject::NewUserData + +BOOL SquirrelObject::GetUserData(const SQChar * key,SQUserPointer * data,SQUserPointer * typetag) { + BOOL ret = false; + if (GetSlot(key)) { + sq_getuserdata(SquirrelVM::_VM,-1,data,typetag); + sq_pop(SquirrelVM::_VM,1); + ret = true; + } // if + sq_pop(SquirrelVM::_VM,1); + return ret; +} // SquirrelObject::GetUserData + +BOOL SquirrelObject::RawGetUserData(const SQChar * key,SQUserPointer * data,SQUserPointer * typetag) { + BOOL ret = false; + if (RawGetSlot(key)) { + sq_getuserdata(SquirrelVM::_VM,-1,data,typetag); + sq_pop(SquirrelVM::_VM,1); + ret = true; + } // if + sq_pop(SquirrelVM::_VM,1); + return ret; +} // SquirrelObject::RawGetUserData + +// === END User Pointer === + +// === BEGIN Arrays === + +BOOL SquirrelObject::ArrayResize(INT newSize) { +// int top = sq_gettop(SquirrelVM::_VM); + sq_pushobject(SquirrelVM::_VM,GetObjectHandle()); + BOOL res = sq_arrayresize(SquirrelVM::_VM,-1,newSize) == SQ_OK; + sq_pop(SquirrelVM::_VM,1); +// sq_settop(SquirrelVM::_VM,top); + return res; +} // SquirrelObject::ArrayResize + +BOOL SquirrelObject::ArrayExtend(INT amount) { + int newLen = Len()+amount; + return ArrayResize(newLen); +} // SquirrelObject::ArrayExtend + +BOOL SquirrelObject::ArrayReverse(void) { + sq_pushobject(SquirrelVM::_VM,GetObjectHandle()); + BOOL res = sq_arrayreverse(SquirrelVM::_VM,-1) == SQ_OK; + sq_pop(SquirrelVM::_VM,1); + return res; +} // SquirrelObject::ArrayReverse + +SquirrelObject SquirrelObject::ArrayPop(SQBool returnPoppedVal) { + SquirrelObject ret; + int top = sq_gettop(SquirrelVM::_VM); + sq_pushobject(SquirrelVM::_VM,GetObjectHandle()); + if (sq_arraypop(SquirrelVM::_VM,-1,returnPoppedVal) == SQ_OK) { + if (returnPoppedVal) { + ret.AttachToStackObject(-1); + } // if + } // if + sq_settop(SquirrelVM::_VM,top); + return ret; +} // SquirrelObject::ArrayPop + +// === END Arrays === + +SQObjectType SquirrelObject::GetType() +{ + return _o._type; +} + +BOOL SquirrelObject::GetSlot(INT key) const +{ + sq_pushobject(SquirrelVM::_VM,_o); + sq_pushinteger(SquirrelVM::_VM,key); + if(SQ_SUCCEEDED(sq_get(SquirrelVM::_VM,-2))) { + return TRUE; + } + + return FALSE; +} + + +SquirrelObject SquirrelObject::GetValue(INT key)const +{ + SquirrelObject ret; + if(GetSlot(key)) { + ret.AttachToStackObject(-1); + sq_pop(SquirrelVM::_VM,1); + } + sq_pop(SquirrelVM::_VM,1); + return ret; +} + +FLOAT SquirrelObject::GetFloat(INT key) const +{ + SQFloat ret = 0.0f; + if(GetSlot(key)) { + sq_getfloat(SquirrelVM::_VM,-1,&ret); + sq_pop(SquirrelVM::_VM,1); + } + sq_pop(SquirrelVM::_VM,1); + return ret; +} + +INT SquirrelObject::GetInt(INT key) const +{ + intp ret = 0; + if(GetSlot(key)) { + sq_getinteger(SquirrelVM::_VM,-1,&ret); + sq_pop(SquirrelVM::_VM,1); + } + sq_pop(SquirrelVM::_VM,1); + return ret; +} + +const SQChar *SquirrelObject::GetString(INT key) const +{ + const SQChar *ret = NULL; + if(GetSlot(key)) { + sq_getstring(SquirrelVM::_VM,-1,&ret); + sq_pop(SquirrelVM::_VM,1); + } + sq_pop(SquirrelVM::_VM,1); + return ret; +} + +bool SquirrelObject::GetBool(INT key) const +{ + SQBool ret = FALSE; + if(GetSlot(key)) { + sq_getbool(SquirrelVM::_VM,-1,&ret); + sq_pop(SquirrelVM::_VM,1); + } + sq_pop(SquirrelVM::_VM,1); + return ret?true:false; +} + +BOOL SquirrelObject::Exists(const SQChar *key) const +{ + BOOL ret = FALSE; + if(GetSlot(key)) { + ret = TRUE; + } + sq_pop(SquirrelVM::_VM,1); + return ret; +} +//////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +BOOL SquirrelObject::GetSlot(const SQChar *name) const +{ + sq_pushobject(SquirrelVM::_VM,_o); + sq_pushstring(SquirrelVM::_VM,name,-1); + if(SQ_SUCCEEDED(sq_get(SquirrelVM::_VM,-2))) { + return TRUE; + } + + return FALSE; +} + +BOOL SquirrelObject::RawGetSlot(const SQChar *name) const { + sq_pushobject(SquirrelVM::_VM,_o); + sq_pushstring(SquirrelVM::_VM,name,-1); + if(SQ_SUCCEEDED(sq_rawget(SquirrelVM::_VM,-2))) { + return TRUE; + } + return FALSE; +} // SquirrelObject::RawGetSlot + +SquirrelObject SquirrelObject::GetValue(const SQChar *key)const +{ + SquirrelObject ret; + if(GetSlot(key)) { + ret.AttachToStackObject(-1); + sq_pop(SquirrelVM::_VM,1); + } + sq_pop(SquirrelVM::_VM,1); + return ret; +} + +FLOAT SquirrelObject::GetFloat(const SQChar *key) const +{ + SQFloat ret = 0.0f; + if(GetSlot(key)) { + sq_getfloat(SquirrelVM::_VM,-1,&ret); + sq_pop(SquirrelVM::_VM,1); + } + sq_pop(SquirrelVM::_VM,1); + return ret; +} + +INT SquirrelObject::GetInt(const SQChar *key) const +{ + intp ret = 0; + if(GetSlot(key)) { + sq_getinteger(SquirrelVM::_VM,-1,&ret); + sq_pop(SquirrelVM::_VM,1); + } + sq_pop(SquirrelVM::_VM,1); + return ret; +} + +const SQChar *SquirrelObject::GetString(const SQChar *key) const +{ + const SQChar *ret = NULL; + if(GetSlot(key)) { + sq_getstring(SquirrelVM::_VM,-1,&ret); + sq_pop(SquirrelVM::_VM,1); + } + sq_pop(SquirrelVM::_VM,1); + return ret; +} + +bool SquirrelObject::GetBool(const SQChar *key) const +{ + SQBool ret = FALSE; + if(GetSlot(key)) { + sq_getbool(SquirrelVM::_VM,-1,&ret); + sq_pop(SquirrelVM::_VM,1); + } + sq_pop(SquirrelVM::_VM,1); + return ret?true:false; +} + +SQUserPointer SquirrelObject::GetInstanceUP(SQUserPointer tag) const +{ + SQUserPointer up; + sq_pushobject(SquirrelVM::_VM,_o); + if (SQ_FAILED(sq_getinstanceup(SquirrelVM::_VM,-1,(SQUserPointer*)&up,tag))) { + sq_reseterror(SquirrelVM::_VM); + up = NULL; + } // if + sq_pop(SquirrelVM::_VM,1); + return up; +} + +BOOL SquirrelObject::SetInstanceUP(SQUserPointer up) +{ + if(!sq_isinstance(_o)) return FALSE; + sq_pushobject(SquirrelVM::_VM,_o); + sq_setinstanceup(SquirrelVM::_VM,-1,up); + sq_pop(SquirrelVM::_VM,1); + return TRUE; +} + +SquirrelObject SquirrelObject::GetAttributes(const SQChar *key) +{ + SquirrelObject ret; + int top = sq_gettop(SquirrelVM::_VM); + sq_pushobject(SquirrelVM::_VM,_o); + if(key) + sq_pushstring(SquirrelVM::_VM,key,-1); + else + sq_pushnull(SquirrelVM::_VM); + if(SQ_SUCCEEDED(sq_getattributes(SquirrelVM::_VM,-2))) { + ret.AttachToStackObject(-1); + } + sq_settop(SquirrelVM::_VM,top); + return ret; +} + +BOOL SquirrelObject::BeginIteration() +{ + if(!sq_istable(_o) && !sq_isarray(_o) && !sq_isclass(_o)) + return FALSE; + sq_pushobject(SquirrelVM::_VM,_o); + sq_pushnull(SquirrelVM::_VM); + return TRUE; +} + +BOOL SquirrelObject::Next(SquirrelObject &key,SquirrelObject &val) +{ + if(SQ_SUCCEEDED(sq_next(SquirrelVM::_VM,-2))) { + key.AttachToStackObject(-2); + val.AttachToStackObject(-1); + sq_pop(SquirrelVM::_VM,2); + return TRUE; + } + return FALSE; +} + +BOOL SquirrelObject::GetTypeTag(SQUserPointer * typeTag) { + if (SQ_SUCCEEDED(sq_getobjtypetag(&_o,typeTag))) { + return TRUE; + } // if + return FALSE; +} // SquirrelObject::GetTypeTag + +const SQChar * SquirrelObject::GetTypeName(const SQChar * key) { +#if 1 + // This version will work even if SQ_SUPPORT_INSTANCE_TYPE_INFO is not enabled. + SqPlus::ScriptStringVar256 varNameTag; + SqPlus::getVarNameTag(varNameTag,sizeof(varNameTag),key); + SQUserPointer data=0; + if (!RawGetUserData(varNameTag,&data)) { + return NULL; + } // if + SqPlus::VarRefPtr vr = (SqPlus::VarRefPtr)data; + return vr->typeName; +#else // This version will only work if SQ_SUPPORT_INSTANCE_TYPE_INFO is enabled. + SquirrelObject so = GetValue(key); + if (so.IsNull()) return NULL; + return so.GetTypeName(); +#endif +} // SquirrelObject::GetTypeName + +const SQChar * SquirrelObject::GetTypeName(INT key) { + SquirrelObject so = GetValue(key); + if (so.IsNull()) return NULL; + return so.GetTypeName(); +} // SquirrelObject::GetTypeName + +const SQChar * SquirrelObject::GetTypeName(void) { + SQUserPointer typeTag=NULL; + if (SQ_SUCCEEDED(sq_getobjtypetag(&_o,&typeTag))) { + SquirrelObject typeTable = SquirrelVM::GetRootTable().GetValue(SQ_PLUS_TYPE_TABLE); + if (typeTable.IsNull()) { + return NULL; // Not compiled with SQ_SUPPORT_INSTANCE_TYPE_INFO enabled. + } // if + return typeTable.GetString(INT((size_t)typeTag)); + } // if + return NULL; +} // SquirrelObject::GetTypeName + +const SQChar* SquirrelObject::ToString() +{ + return sq_objtostring(&_o); +} + +SQInteger SquirrelObject::ToInteger() +{ + return sq_objtointeger(&_o); +} + +SQFloat SquirrelObject::ToFloat() +{ + return sq_objtofloat(&_o); +} + +bool SquirrelObject::ToBool() +{ + //<> + return _o._unVal.nInteger?true:false; +} + +void SquirrelObject::EndIteration() +{ + sq_pop(SquirrelVM::_VM,2); +} + diff --git a/vscript/languages/squirrel/sqplus/SquirrelObject.h b/vscript/languages/squirrel/sqplus/SquirrelObject.h new file mode 100644 index 00000000..11e1817d --- /dev/null +++ b/vscript/languages/squirrel/sqplus/SquirrelObject.h @@ -0,0 +1,248 @@ +#ifndef _SQUIRREL_OBJECT_H_ +#define _SQUIRREL_OBJECT_H_ + +class SquirrelObject +{ + friend class SquirrelVM; +public: + SquirrelObject(); + virtual ~SquirrelObject(); + SquirrelObject(SquirrelObject & o); + SquirrelObject(HSQOBJECT o); + template + SquirrelObject(const _ty & val) { sq_resetobject(&_o); Set((_ty &)val); } // Cast away const to avoid compiler SqPlus::Push() match issue. + template + SquirrelObject(_ty & val) { sq_resetobject(&_o); Set(val); } + template + SquirrelObject(_ty * val) { sq_resetobject(&_o); SetByValue(val); } // Set() would also be OK here. SetByValue() to save potential compiler overhead. + SquirrelObject & operator =(const SquirrelObject &o); + SquirrelObject & operator =(int n); + void AttachToStackObject(int idx); + void Reset(void); // Release (any) reference and reset _o. + SquirrelObject Clone(); + BOOL SetValue(const SquirrelObject &key,const SquirrelObject &val); + + BOOL SetValue(INT key,const SquirrelObject &val); + BOOL SetValue(INT key,bool b); // Compiler treats SQBool as INT. + BOOL SetValue(INT key,INT n); + BOOL SetValue(INT key,FLOAT f); + BOOL SetValue(INT key,const SQChar *s); + + BOOL SetValue(const SQChar *key,const SquirrelObject &val); + BOOL SetValue(const SQChar *key,bool b); + BOOL SetValue(const SQChar *key,INT n); + BOOL SetValue(const SQChar *key,FLOAT f); + BOOL SetValue(const SQChar *key,const SQChar *s); + + BOOL SetUserPointer(const SQChar * key,SQUserPointer up); + SQUserPointer GetUserPointer(const SQChar * key); + BOOL SetUserPointer(INT key,SQUserPointer up); + SQUserPointer GetUserPointer(INT key); + + BOOL NewUserData(const SQChar * key,INT size,SQUserPointer * typetag=0); + BOOL GetUserData(const SQChar * key,SQUserPointer * data,SQUserPointer * typetag=0); + BOOL RawGetUserData(const SQChar * key,SQUserPointer * data,SQUserPointer * typetag=0); + + // === BEGIN Arrays === + + BOOL ArrayResize(INT newSize); + BOOL ArrayExtend(INT amount); + BOOL ArrayReverse(void); + SquirrelObject ArrayPop(SQBool returnPoppedVal=SQTrue); + + void ArrayAppend(const SquirrelObject &o); + + template + BOOL ArrayAppend(T item); + + // === END Arrays === + + BOOL SetInstanceUP(SQUserPointer up); + BOOL IsNull() const; + int IsNumeric() const; + int Len() const; + BOOL SetDelegate(SquirrelObject &obj); + SquirrelObject GetDelegate(); + const SQChar* ToString(); + bool ToBool(); + SQInteger ToInteger(); + SQFloat ToFloat(); + SQUserPointer GetInstanceUP(SQUserPointer tag) const; + SquirrelObject GetValue(const SQChar *key) const; + BOOL Exists(const SQChar *key) const; + FLOAT GetFloat(const SQChar *key) const; + INT GetInt(const SQChar *key) const; + const SQChar *GetString(const SQChar *key) const; + bool GetBool(const SQChar *key) const; + SquirrelObject GetValue(INT key) const; + FLOAT GetFloat(INT key) const; + INT GetInt(INT key) const; + const SQChar *GetString(INT key) const; + bool GetBool(INT key) const; + SquirrelObject GetAttributes(const SQChar *key = NULL); + SQObjectType GetType(); + HSQOBJECT & GetObjectHandle(){return _o;} + BOOL BeginIteration(); + BOOL Next(SquirrelObject &key,SquirrelObject &value); + void EndIteration(); + + BOOL GetTypeTag(SQUserPointer * typeTag); + + // === Get the type name of item/object through string key in a table or class. Returns NULL if the type name is not set (not an SqPlus registered type). + const SQChar * GetTypeName(const SQChar * key); + // === Get the type name of item/object through INT key in a table or class. Returns NULL if the type name is not set (not an SqPlus registered type). + const SQChar * GetTypeName(INT key); + // === Get the type name of this object, else return NULL if not an SqPlus registered type. + const SQChar * GetTypeName(void); + + // === BEGIN code suggestion from the Wiki === + // Get any bound type from this SquirrelObject. Note that Squirrel's handling of references and pointers still holds here. + template + inline _ty Get(void); + + // Set any bound type to this SquirrelObject. Note that Squirrel's handling of references and pointers still holds here. + template + inline SquirrelObject SetByValue(_ty val); + + // Set any bound type to this SquirrelObject. Note that Squirrel's handling of references and pointers still holds here. + template + SquirrelObject Set(_ty & val); + + // === END code suggestion from the Wiki === + +private: + BOOL GetSlot(const SQChar *name) const; + BOOL RawGetSlot(const SQChar *name) const; + BOOL GetSlot(INT key) const; + HSQOBJECT _o; +}; + +struct StackHandler { + StackHandler(HSQUIRRELVM v) { + _top = sq_gettop(v); + this->v = v; + } + SQFloat GetFloat(int idx) { + SQFloat x = 0.0f; + if(idx > 0 && idx <= _top) { + sq_getfloat(v,idx,&x); + } + return x; + } + SQInteger GetInt(int idx) { + SQInteger x = 0; + if(idx > 0 && idx <= _top) { + sq_getinteger(v,idx,&x); + } + return x; + } + HSQOBJECT GetObjectHandle(int idx) { + HSQOBJECT x; + if(idx > 0 && idx <= _top) { + sq_resetobject(&x); + sq_getstackobj(v,idx,&x); + } + else + { + x._type = OT_NULL; + x._unVal.pUserPointer = 0; + } + return x; + } + const SQChar *GetString(int idx) + { + const SQChar *x = NULL; + if(idx > 0 && idx <= _top) { + sq_getstring(v,idx,&x); + } + return x; + } + SQUserPointer GetUserPointer(int idx) + { + SQUserPointer x = 0; + if(idx > 0 && idx <= _top) { + sq_getuserpointer(v,idx,&x); + } + return x; + } + SQUserPointer GetInstanceUp(int idx,SQUserPointer tag) + { + SQUserPointer self; + if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer*)&self,tag))) + return NULL; + return self; + } + SQUserPointer GetUserData(int idx,SQUserPointer tag=0) + { + SQUserPointer otag; + SQUserPointer up; + if(idx > 0 && idx <= _top) { + if(SQ_SUCCEEDED(sq_getuserdata(v,idx,&up,&otag))) { + if(tag == otag) + return up; + } + } + return NULL; + } + bool GetBool(int idx) + { + SQBool ret; + if(idx > 0 && idx <= _top) { + if(SQ_SUCCEEDED(sq_getbool(v,idx,&ret))) + return !!ret; + } + return false; + } + int GetType(int idx) + { + if(idx > 0 && idx <= _top) { + return sq_gettype(v,idx); + } + return -1; + } + + int GetParamCount() { + return _top; + } + int Return(const SQChar *s) + { + sq_pushstring(v,s,-1); + return 1; + } + int Return(FLOAT f) + { + sq_pushfloat(v,f); + return 1; + } + int Return(INT i) + { + sq_pushinteger(v,i); + return 1; + } + int Return(bool b) + { + sq_pushbool(v,b); + return 1; + } + int Return(SQUserPointer p) { + sq_pushuserpointer(v,p); + return 1; + } + int Return(SquirrelObject &o) + { + sq_pushobject(v,o.GetObjectHandle()); + return 1; + } + int Return() { return 0; } + int ThrowError(const SQChar *error) { + return sq_throwerror(v,error); + } + HSQUIRRELVM GetVMPtr() { return v; } +private: + int _top; + HSQUIRRELVM v; +}; + +#endif //_SQUIRREL_OBJECT_H_ + + diff --git a/vscript/languages/squirrel/sqplus/SquirrelObjectImpl.h b/vscript/languages/squirrel/sqplus/SquirrelObjectImpl.h new file mode 100644 index 00000000..dbf5d7ef --- /dev/null +++ b/vscript/languages/squirrel/sqplus/SquirrelObjectImpl.h @@ -0,0 +1,36 @@ +// This is part of squirrelobject.h that removes circular dependency between sqplus.h and squirrelobject.h: it depends on both + +#ifndef _SQUIRREL_OBJECT_IMPL_H_ +#define _SQUIRREL_OBJECT_IMPL_H_ + +// === BEGIN code suggestion from the Wiki === +// Get any bound type from this SquirrelObject. Note that Squirrel's handling of references and pointers still holds here. +template +inline _ty SquirrelObject::Get(void) { + sq_pushobject(SquirrelVM::_VM,GetObjectHandle()); + _ty val = SqPlus::Get(SqPlus::TypeWrapper<_ty>(),SquirrelVM::_VM,-1); + sq_poptop(SquirrelVM::_VM); + return val; +} + +// Set any bound type to this SquirrelObject. Note that Squirrel's handling of references and pointers still holds here. +template +inline SquirrelObject SquirrelObject::SetByValue(_ty val) { // classes/structs should be passed by ref (below) to avoid an extra copy. + SqPlus::Push(SquirrelVM::_VM,val); + AttachToStackObject(-1); + sq_poptop(SquirrelVM::_VM); + return *this; +} + +// Set any bound type to this SquirrelObject. Note that Squirrel's handling of references and pointers still holds here. +template +inline SquirrelObject SquirrelObject::Set(_ty & val) { + SqPlus::Push(SquirrelVM::_VM,val); + AttachToStackObject(-1); + sq_poptop(SquirrelVM::_VM); + return *this; +} + +// === END code suggestion from the Wiki === + +#endif \ No newline at end of file diff --git a/vscript/languages/squirrel/sqplus/SquirrelVM.cpp b/vscript/languages/squirrel/sqplus/SquirrelVM.cpp new file mode 100644 index 00000000..498b89c5 --- /dev/null +++ b/vscript/languages/squirrel/sqplus/SquirrelVM.cpp @@ -0,0 +1,346 @@ +#include +#include + +#define _DEBUG_DUMP + +#include "sqplus.h" + +#include +#include +#include +#include +#include +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#endif + +#ifdef _MSC_VER +#define STRLEN(n) _tcslen(n) +#else +#define STRLEN(n) strlen(n) +#endif + +HSQUIRRELVM SquirrelVM::_VM = NULL; +int SquirrelVM::_CallState = -1; +SquirrelObject * SquirrelVM::_root = NULL; + +SquirrelError::SquirrelError() +{ + const SQChar *s; + sq_getlasterror(SquirrelVM::_VM); + sq_getstring(SquirrelVM::_VM,-1,&s); + if(s) { + desc = s; + } + else { + desc = _T("unknown error"); + } +} + +void SquirrelVM::Init() +{ + _VM = sq_open(1024); + sq_setprintfunc(_VM,SquirrelVM::PrintFunc); + sq_pushroottable(_VM); + sqstd_register_iolib(_VM); + sqstd_register_bloblib(_VM); + sqstd_register_mathlib(_VM); + sqstd_register_stringlib(_VM); + sqstd_seterrorhandlers(_VM); + _root = new SquirrelObject(); + _root->AttachToStackObject(-1); + sq_pop(_VM,1); + //TODO error handler, compiler error handler +} + +BOOL SquirrelVM::Update() +{ + //update remote debugger + return TRUE; +} + +void SquirrelVM::Cleanup() +{ + //cleans the root table + sq_pushnull(_VM); + sq_setroottable(_VM); +} + +void SquirrelVM::Shutdown() +{ + if (_VM) { + Cleanup(); +#if 0 + sq_release(_VM,&_root->_o); + sq_resetobject(&_root->_o); +#endif + delete _root; + _root = NULL; + HSQUIRRELVM v = _VM; + _VM = NULL; + sq_close(v); + } // if +} + +void SquirrelVM::PrintFunc(HSQUIRRELVM v,const SQChar* s,...) +{ + static SQChar temp[2048]; + va_list vl; + va_start(vl, s); + scvsprintf( temp,s, vl); + SCPUTS(temp); + va_end(vl); +} + +SquirrelObject SquirrelVM::CompileScript(const SQChar *s) +{ +#define MAX_EXPANDED_PATH 1023 + SquirrelObject ret; + if(SQ_SUCCEEDED(sqstd_loadfile(_VM,s,1))) { + ret.AttachToStackObject(-1); + sq_pop(_VM,1); + return ret; + } + throw SquirrelError(); +} + +SquirrelObject SquirrelVM::CompileBuffer(const SQChar *s,const SQChar * debugInfo) +{ + SquirrelObject ret; + if(SQ_SUCCEEDED(sq_compilebuffer(_VM,s,(int)STRLEN(s)*sizeof(SQChar),debugInfo,1))) { + ret.AttachToStackObject(-1); + sq_pop(_VM,1); + return ret; + } + throw SquirrelError(); +} + +SquirrelObject SquirrelVM::RunScript(const SquirrelObject &o,SquirrelObject *_this) +{ + SquirrelObject ret; + sq_pushobject(_VM,o._o); + if(_this) { + sq_pushobject(_VM,_this->_o); + } + else { + sq_pushroottable(_VM); + } + if(SQ_SUCCEEDED(sq_call(_VM,1,SQTrue,SQ_CALL_RAISE_ERROR))) { + ret.AttachToStackObject(-1); + sq_pop(_VM,1); + return ret; + } + sq_pop(_VM,1); + throw SquirrelError(); + +} + + +BOOL SquirrelVM::BeginCall(const SquirrelObject &func) +{ + if(_CallState != -1) + return FALSE; + _CallState = 1; + sq_pushobject(_VM,func._o); + sq_pushroottable(_VM); + return TRUE; +} + +BOOL SquirrelVM::BeginCall(const SquirrelObject &func,SquirrelObject &_this) +{ + if(_CallState != -1) + throw SquirrelError(_T("call already initialized")); + _CallState = 1; + sq_pushobject(_VM,func._o); + sq_pushobject(_VM,_this._o); + return TRUE; +} + +#define _CHECK_CALL_STATE \ + if(_CallState == -1) \ + throw SquirrelError(_T("call not initialized")); + +void SquirrelVM::PushParam(const SquirrelObject &o) +{ + _CHECK_CALL_STATE + sq_pushobject(_VM,o._o); + _CallState++; +} + +void SquirrelVM::PushParam(const SQChar *s) +{ + _CHECK_CALL_STATE + sq_pushstring(_VM,s,-1); + _CallState++; +} + +void SquirrelVM::PushParam(SQInteger n) +{ + _CHECK_CALL_STATE + sq_pushinteger(_VM,n); + _CallState++; +} + +void SquirrelVM::PushParam(SQFloat f) +{ + _CHECK_CALL_STATE + sq_pushfloat(_VM,f); + _CallState++; +} + +void SquirrelVM::PushParamNull() +{ + _CHECK_CALL_STATE + sq_pushnull(_VM); + _CallState++; +} + +void SquirrelVM::PushParam(SQUserPointer up) +{ + _CHECK_CALL_STATE + sq_pushuserpointer(_VM,up); + _CallState++; +} + +SquirrelObject SquirrelVM::EndCall() +{ + SquirrelObject ret; + if(_CallState >= 0) { + int oldtop = sq_gettop(_VM); + int nparams = _CallState; + _CallState = -1; + if(SQ_SUCCEEDED(sq_call(_VM,nparams,SQTrue,SQ_CALL_RAISE_ERROR))) { + ret.AttachToStackObject(-1); + sq_pop(_VM,2); + }else { + sq_settop(_VM,oldtop-(nparams+1)); + throw SquirrelError(); + } + + } + return ret; +} + +SquirrelObject SquirrelVM::CreateInstance(SquirrelObject &oclass) +{ + SquirrelObject ret; + int oldtop = sq_gettop(_VM); + sq_pushobject(_VM,oclass._o); + if(SQ_FAILED(sq_createinstance(_VM,-1))) { + sq_settop(_VM,oldtop); + throw SquirrelError(); + } + ret.AttachToStackObject(-1); + sq_pop(_VM,2); + return ret; +} + +SquirrelObject SquirrelVM::CreateTable() +{ + SquirrelObject ret; + sq_newtable(_VM); + ret.AttachToStackObject(-1); + sq_pop(_VM,1); + return ret; +} + +SquirrelObject SquirrelVM::CreateString(const SQChar *s) +{ + SquirrelObject ret; + sq_pushstring(_VM,s,-1); + ret.AttachToStackObject(-1); + sq_pop(_VM,1); + return ret; +} + + +SquirrelObject SquirrelVM::CreateArray(int size) +{ + SquirrelObject ret; + sq_newarray(_VM,size); + ret.AttachToStackObject(-1); + sq_pop(_VM,1); + return ret; +} + +SquirrelObject SquirrelVM::CreateFunction(SQFUNCTION func) +{ + SquirrelObject ret; + sq_newclosure(_VM,func,0); + ret.AttachToStackObject(-1); + sq_pop(_VM,1); + return ret; +} + +SquirrelObject SquirrelVM::CreateUserData(int size) { + SquirrelObject ret; + sq_newuserdata(_VM,size); + ret.AttachToStackObject(-1); + sq_pop(_VM,1); + return ret; +} + +const SquirrelObject &SquirrelVM::GetRootTable() +{ + return *_root; +} + +void SquirrelVM::PushRootTable(void) { + sq_pushroottable(_VM); +} // SquirrelVM::PushRootTable + +// Creates a function in the table or class currently on the stack. +//void CreateFunction(HSQUIRRELVM v,const SQChar * scriptFuncName,SQFUNCTION func,int numParams=0,const SQChar * typeMask=0) { +SquirrelObject SquirrelVM::CreateFunction(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask) { + sq_pushstring(_VM,scriptFuncName,-1); + sq_newclosure(_VM,func,0); + SquirrelObject ret; + ret.AttachToStackObject(-1); + SQChar tm[64]; + SQChar * ptm = tm; + int numParams = SQ_MATCHTYPEMASKSTRING; + if (typeMask) { + if (typeMask[0] == '*') { + ptm = 0; // Variable args: don't check parameters. + numParams = 0; // Clear SQ_MATCHTYPEMASKSTRING (does not mean match 0 params. See sq_setparamscheck()). + } else { + if (SCSNPRINTF(tm,sizeof(tm),_T("t|y|x%s"),typeMask) < 0) { +// sq_throwerror(_VM,_T("CreateFunction: typeMask string too long.")); + throw SquirrelError(_T("CreateFunction: typeMask string too long.")); + } // if + } // if + } else { // Need to check object type on stack: table, class, instance, etc. + SCSNPRINTF(tm,sizeof(tm),_T("%s"),_T("t|y|x")); // table, class, instance. +// tm[0] = 't'; +// tm[1] = 0; + } // if +#if 0 + sq_setparamscheck(_VM,numParams+1,ptm); // Parameters are table+args (thus, the +1). +#else + if (ptm) { + sq_setparamscheck(_VM,numParams,ptm); // Determine arg count from type string. + } // if +#endif +#ifdef _DEBUG + sq_setnativeclosurename(_VM,-1,scriptFuncName); // For debugging only. +#endif + sq_createslot(_VM,-3); // Create slot in table or class (assigning function to slot at scriptNameFunc). + return ret; +} // SquirrelVM::CreateFunction + +SquirrelObject SquirrelVM::CreateFunction(SquirrelObject & so,SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask) { + PushObject(so); + SquirrelObject ret = CreateFunction(func,scriptFuncName,typeMask); + Pop(1); + return ret; +} // SquirrelVM::CreateFunction + +// Create a Global function on the root table. +//void CreateFunctionGlobal(HSQUIRRELVM v,const SQChar * scriptFuncName,SQFUNCTION func,int numParams=0,const SQChar * typeMask=0) { +SquirrelObject SquirrelVM::CreateFunctionGlobal(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask) { + PushRootTable(); // Push root table. + // CreateFunction(scriptFuncName,func,numParams,typeMask); + SquirrelObject ret = CreateFunction(func,scriptFuncName,typeMask); + Pop(1); // Pop root table. + return ret; +} // SquirrelVM::CreateFunctionGlobal diff --git a/vscript/languages/squirrel/sqplus/SquirrelVM.h b/vscript/languages/squirrel/sqplus/SquirrelVM.h new file mode 100644 index 00000000..decefa66 --- /dev/null +++ b/vscript/languages/squirrel/sqplus/SquirrelVM.h @@ -0,0 +1,112 @@ +#ifndef _SQUIRREL_VM_H_ +#define _SQUIRREL_VM_H_ + +struct SquirrelError { + SquirrelError(); + SquirrelError(const SQChar* s):desc(s){} + const SQChar *desc; +}; + +struct SquirrelVMSys { + HSQUIRRELVM _VM; + SquirrelObject * _root; +}; + +class SquirrelVM +{ + friend class SquirrelObject; + friend struct SquirrelError; +public: + static void Init(); + static BOOL IsInitialized(){return _VM == NULL?FALSE:TRUE;} + static void Shutdown(); + static void Cleanup(); + static BOOL Update(); //debugger and maybe GC later + static SquirrelObject CompileScript(const SQChar *s); + static SquirrelObject CompileBuffer(const SQChar *s,const SQChar * debugInfo=_T("console_buffer")); + static SquirrelObject RunScript(const SquirrelObject &o,SquirrelObject *_this = NULL); + static void PrintFunc(HSQUIRRELVM v,const SQChar* s,...); + static BOOL BeginCall(const SquirrelObject &func); + static BOOL BeginCall(const SquirrelObject &func,SquirrelObject &_this); + static void PushParam(const SquirrelObject &o); + static void PushParam(const SQChar *s); + static void PushParam(SQInteger n); + static void PushParam(SQFloat f); + static void PushParam(SQUserPointer up); + static void PushParamNull(); + static SquirrelObject EndCall(); + static SquirrelObject CreateString(const SQChar *s); + static SquirrelObject CreateTable(); + static SquirrelObject CreateArray(int size); + static SquirrelObject CreateInstance(SquirrelObject &oclass); // oclass is an existing class. Create an 'instance' (OT_INSTANCE) of oclass. + static SquirrelObject CreateFunction(SQFUNCTION func); + static SquirrelObject CreateUserData(int size); + + static const SquirrelObject &GetRootTable(); + static HSQUIRRELVM GetVMPtr() { return _VM; } + +#if 0 + static void SetVMPtr(HSQUIRRELVM v) { + _VM = v; + } // setVMPtr +#endif + + static void GetVMSys(SquirrelVMSys & vmSys) { + vmSys._VM = _VM; + vmSys._root = _root; + } // GetVMSys + + static void SetVMSys(const SquirrelVMSys & vmSys) { + _VM = vmSys._VM; + _root = vmSys._root; + } // SetVMSys + + static void PushValue(INT val) { + sq_pushinteger(_VM,val); + } // PushValue + static void PushValue(FLOAT val) { + sq_pushfloat(_VM,val); + } // PushValue + static void PushValue(bool val) { // Compiler treats SQBool as INT. + sq_pushbool(_VM,val); + } // PushValue + static void PushValue(SQChar * val) { + sq_pushstring(_VM,val,-1); + } // PushValue + static void PushValue(SQUserPointer val) { + sq_pushuserpointer(_VM,val); + } // PushValue + static void PushValue(const SQChar * val) { + sq_pushstring(_VM,val,-1); + } // PushValue + static void PushObject(SquirrelObject & so) { + sq_pushobject(_VM,so._o); + } // PushObject + static void Pop(SQInteger nelemstopop) { + sq_pop(_VM,nelemstopop); + } // Pop + static void PushRootTable(void); + // Create/bind a function on the table currently on the stack. + static SquirrelObject CreateFunction(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask=0); + // Create/bind a function on the table so. typeMask: standard Squirrel types plus: no typemask means no args, "*" means any type of args. + static SquirrelObject CreateFunction(SquirrelObject & so,SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask=0); + // Create/bind a function to the root table. typeMask: standard Squirrel types plus: no typemask means no args, "*" means any type of args. + static SquirrelObject CreateFunctionGlobal(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask=0); + +private: + static HSQUIRRELVM _VM; + static int _CallState; + static SquirrelObject * _root; +}; + +template +inline BOOL SquirrelObject::ArrayAppend(T item) { + sq_pushobject(SquirrelVM::_VM,GetObjectHandle()); + SquirrelVM::PushValue(item); + BOOL res = sq_arrayappend(SquirrelVM::_VM,-2) == SQ_OK; + sq_pop(SquirrelVM::_VM,1); + return res; +} // ArrayAppend + +#endif //_SQUIRREL_VM_H_ + diff --git a/vscript/languages/squirrel/sqplus/sqplus.cbp b/vscript/languages/squirrel/sqplus/sqplus.cbp new file mode 100644 index 00000000..ba10ef10 --- /dev/null +++ b/vscript/languages/squirrel/sqplus/sqplus.cbp @@ -0,0 +1,190 @@ + + + + + + + diff --git a/vscript/languages/squirrel/sqplus/sqplus.h b/vscript/languages/squirrel/sqplus/sqplus.h new file mode 100644 index 00000000..032f413c --- /dev/null +++ b/vscript/languages/squirrel/sqplus/sqplus.h @@ -0,0 +1,2028 @@ +// SqPlus.h +// Created by John Schultz 9/05/05, major update 10/05/05. +// Template function call design from LuaPlusCD by Joshua C. Jensen, +// inspired by luabind which was inspired by boost::python. +// Const argument, const member functions, and Mac OS-X changes by Simon Michelmore. +// DECLARE_INSTANCE_TYPE_NAME changes by Ben (Project5) from http://www.squirrel-lang.org/forums/. +// Added Kamaitati's changes 5/28/06. +// Free for any use. + +#ifndef _SQ_PLUS_H_ +#define _SQ_PLUS_H_ + +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "platform.h" +#include "dbg.h" +#endif + +#include +#include + +#ifdef __APPLE__ + #include +#elif !defined(_PS3) + #include +#endif +#if !defined(_PS3) +#include +#endif +#if defined(_MSC_VER) || defined(__BORLANDC__) + #include + #ifndef UNICODE + #define SCSNPRINTF _snprintf + #define SCPUTS puts + #else + #define SCSNPRINTF _snwprintf + #define SCPUTS _putws + #endif +#else + #ifdef _T + #undef _T + #endif + #define _T(n) n + #define SCSNPRINTF snprintf + #include // for snprintf + #define SCPUTS puts +#endif + +#ifndef _WINDEF_ + typedef int BOOL; + typedef int INT; + typedef float FLOAT; + #undef TRUE + #undef FALSE + #define TRUE 1 + #define FALSE 0 +#endif + +#if 1 +#define SQ_CALL_RAISE_ERROR SQTrue +#else +#define SQ_CALL_RAISE_ERROR SQFalse +#endif + +#include "squirrel.h" + +#include "SquirrelObject.h" +#include "SquirrelVM.h" +#include "SquirrelBindingsUtils.h" + +namespace SqPlus { + +// === Class Inheritance Support === +// Inheritance in Squirrel allows one class to inherit a base class's functions and variables. +// Variables are merged: if Derived has a var name 'val' and Base has a var of the same name, +// the resulting var 'val' will take Derived's initialization value. +// Functions are not merged, and can be called via Squirrel scoping rules. + +// Define SQ_USE_CLASS_INHERITANCE to enable class inheritance support +// (requires slightly more memory and adds some CPU overhead). +// Can also be useful for debugging, as class type information is checked before +// dispatching instance function calls and before accessing instance member variables. +#define SQ_USE_CLASS_INHERITANCE + +// Comment out to turn off instance type info support (to save a small amount of memory). +#define SQ_SUPPORT_INSTANCE_TYPE_INFO + +// === Constant argument and constant member function support === +// Define SQPLUS_CONST_OPT before including SqPlus.h for constant argument + constant member function support. +//#define SQPLUS_CONST_OPT + +// === Uncomment to support std::string === +//#define SQPLUS_SUPPORT_STD_STRING + +// === Uncomment to support typedef std::basic_string sq_std_string === +//#define SQPLUS_SUPPORT_SQ_STD_STRING + +// === Uncomment to support NULL INSTANCE arguments === +//#define SQPLUS_SUPPORT_NULL_INSTANCES + +// === Uncomment to support C++ style inheritance +#define CPP_STYLE_INHERITANCE + +// === Uncomment to skip sq_argassert() === +//#define SQ_SKIP_ARG_ASSERT + +template struct TypeWrapper {}; +struct SquirrelNull {}; +struct SQAnything { void * anything; }; // Needed for binding pointers to variables (cannot dereference void *). +typedef SQAnything * SQAnythingPtr; +typedef SQChar * SQCharPtr; + +// === Do not use directly: use one of the predefined sizes below === + +struct ScriptStringVarBase { + const unsigned char MaxLength; // Real length is MaxLength+1. + SQChar s[1]; + ScriptStringVarBase(int _MaxLength) : MaxLength(_MaxLength) {} + operator SQChar * () { return &s[0]; } + operator void * () { return (void *)&s[0]; } + const SQChar * operator = (const SQChar * _s) { + return safeStringCopy(s,_s,MaxLength); + } + // Special safe string copy where MaxLength is 1 less than true buffer length. + // strncpy() pads out nulls for the full length of the buffer specified by MaxLength. + static inline SQChar * safeStringCopy(SQChar * d,const SQChar * s,int MaxLength) { + int i=0; + while (s[i]) { + d[i] = s[i]; + i++; + if (i == MaxLength) break; + } // while + d[i] = 0; // Null terminate. + return d; + } // safeStringCopy +}; + +// === Do not use directly: use one of the predefined sizes below === + +template // MAXLENGTH is max printable characters (trailing NULL is accounted for in ScriptStringVarBase::s[1]). +struct ScriptStringVar : ScriptStringVarBase { + SQChar ps[MAXLENGTH]; + ScriptStringVar() : ScriptStringVarBase(MAXLENGTH) { + s[0] = 0; + } + ScriptStringVar(const SQChar * _s) : ScriptStringVarBase(MAXLENGTH) { + *this = _s; + } + const SQChar * operator = (const SQChar * _s) { + return safeStringCopy(s,_s,MaxLength); + } + const SQChar * operator = (const ScriptStringVar & _s) { + return safeStringCopy(s,_s.s,MaxLength); + } + bool operator == (const ScriptStringVar & _s) { + //lwss- change _strcmp->strcmp + //return _strcmp(s,_s.s) == 0; + return strcmp(s,_s.s) == 0; + } + bool compareCaseInsensitive(const ScriptStringVar & _s) { + return _stricmp(s,_s.s) == 0; + } +}; + +// === Fixed size strings for scripting === + +typedef ScriptStringVar<8> ScriptStringVar8; +typedef ScriptStringVar<16> ScriptStringVar16; +typedef ScriptStringVar<32> ScriptStringVar32; +typedef ScriptStringVar<64> ScriptStringVar64; +typedef ScriptStringVar<128> ScriptStringVar128; +typedef ScriptStringVar<256> ScriptStringVar256; + +// === Script Variable Types === + +enum ScriptVarType {VAR_TYPE_NONE=-1,VAR_TYPE_INT=0,VAR_TYPE_FLOAT,VAR_TYPE_BOOL,VAR_TYPE_CONST_STRING,VAR_TYPE_STRING,VAR_TYPE_USER_POINTER,VAR_TYPE_INSTANCE}; + +template +struct TypeInfo { + const SQChar * typeName; + enum {TypeID=VAR_TYPE_NONE,Size=0}; +}; + +// === Common Variable Types === + +template<> +struct TypeInfo { + const SQChar * typeName; + TypeInfo() : typeName(_T("int")) {} + enum {TypeID=VAR_TYPE_INT,Size=sizeof(INT)}; + operator ScriptVarType() { return ScriptVarType(TypeID); } +}; + +template<> +struct TypeInfo { + const SQChar * typeName; + TypeInfo() : typeName(_T("float")) {} + enum {TypeID=VAR_TYPE_FLOAT,Size=sizeof(FLOAT)}; + operator ScriptVarType() { return ScriptVarType(TypeID); } +}; + +template<> +struct TypeInfo { + const SQChar * typeName; + TypeInfo() : typeName(_T("bool")) {} + enum {TypeID=VAR_TYPE_BOOL,Size=sizeof(bool)}; + operator ScriptVarType() { return ScriptVarType(TypeID); } +}; + +template<> +struct TypeInfo { + const SQChar * typeName; + TypeInfo() : typeName(_T("SQUserPointer")) {} + enum {TypeID=VAR_TYPE_USER_POINTER,Size=sizeof(SQUserPointer)}; + operator ScriptVarType() { return ScriptVarType(TypeID); } +}; + +template<> +struct TypeInfo { + const SQChar * typeName; + TypeInfo() : typeName(_T("SQUserPointer")) {} + enum {TypeID=VAR_TYPE_USER_POINTER,Size=sizeof(SQUserPointer)}; + operator ScriptVarType() { return ScriptVarType(TypeID); } +}; + +template<> +struct TypeInfo { + const SQChar * typeName; + TypeInfo() : typeName(_T("const SQChar *")) {} + enum {TypeID=VAR_TYPE_CONST_STRING,Size=sizeof(const SQChar *)}; + operator ScriptVarType() { return ScriptVarType(TypeID); } +}; + +template<> +struct TypeInfo { + const SQChar * typeName; + TypeInfo() : typeName(_T("ScriptStringVarBase")) {} + enum {TypeID=VAR_TYPE_STRING,Size=sizeof(ScriptStringVarBase)}; + operator ScriptVarType() { return ScriptVarType(TypeID); } +}; + +// === Fixed String Variants === + +template<> +struct TypeInfo { + const SQChar * typeName; + TypeInfo() : typeName(_T("ScriptStringVar8")) {} + enum {TypeID=VAR_TYPE_STRING,Size=sizeof(ScriptStringVar8)}; + operator ScriptVarType() { return ScriptVarType(TypeID); } +}; + +template<> +struct TypeInfo { + const SQChar * typeName; + TypeInfo() : typeName(_T("ScriptStringVar16")) {} + enum {TypeID=VAR_TYPE_STRING,Size=sizeof(ScriptStringVar16)}; + operator ScriptVarType() { return ScriptVarType(TypeID); } +}; + +template<> +struct TypeInfo { + const SQChar * typeName; + TypeInfo() : typeName(_T("ScriptStringVar32")) {} + enum {TypeID=VAR_TYPE_STRING,Size=sizeof(ScriptStringVar32)}; + operator ScriptVarType() { return ScriptVarType(TypeID); } +}; + +template<> +struct TypeInfo { + const SQChar * typeName; + TypeInfo() : typeName(_T("ScriptStringVar64")) {} + enum {TypeID=VAR_TYPE_STRING,Size=sizeof(ScriptStringVar64)}; + operator ScriptVarType() { return ScriptVarType(TypeID); } +}; + +template<> +struct TypeInfo { + const SQChar * typeName; + TypeInfo() : typeName(_T("ScriptStringVar128")) {} + enum {TypeID=VAR_TYPE_STRING,Size=sizeof(ScriptStringVar128)}; + operator ScriptVarType() { return ScriptVarType(TypeID); } +}; + +template<> +struct TypeInfo { + const SQChar * typeName; + TypeInfo() : typeName(_T("ScriptStringVar256")) {} + enum {TypeID=VAR_TYPE_STRING,Size=sizeof(ScriptStringVar256)}; + operator ScriptVarType() { return ScriptVarType(TypeID); } +}; + +enum VarAccessType {VAR_ACCESS_READ_WRITE=0,VAR_ACCESS_READ_ONLY=1<<0,VAR_ACCESS_CONSTANT=1<<1,VAR_ACCESS_STATIC=1<<2}; + +// See VarRef and ClassType<> below: for instance assignment. +typedef void (*CopyVarFunc)(void * dst,void * src); + +// === Variable references for script access === + +#define SQ_PLUS_TYPE_TABLE _T("__SqTypes") + +struct VarRef { + // In this case 'offsetOrAddrOrConst' is simpler than using an anonymous union. + void * offsetOrAddrOrConst; // Instance member variable offset from 'this' pointer base (as size_t), or address if static variable (void *), or constant value. + ScriptVarType type; // Variable type (from enum above). + SQUserPointer instanceType; // Unique ID for the containing class instance (for instance vars only). When the var is an instance, its type is encoded in copyFunc. + CopyVarFunc copyFunc; // Function pointer to copy variables (for instance variables only). + short size; // Currently for debugging only (size of item when pointer to item is dereferenced). Could be used for variable max string buffer length. + short access; // VarAccessType. + const SQChar * typeName; // Type name string (to create instances by name). + VarRef() : offsetOrAddrOrConst(0), type(VAR_TYPE_NONE), instanceType((SQUserPointer)-1), copyFunc(0), size(0), access(VAR_ACCESS_READ_WRITE) {} + VarRef(void * _offsetOrAddrOrConst, ScriptVarType _type, SQUserPointer _instanceType, CopyVarFunc _copyFunc, int _size,VarAccessType _access,const SQChar * _typeName) : + offsetOrAddrOrConst(_offsetOrAddrOrConst), type(_type), instanceType(_instanceType), copyFunc(_copyFunc), size(_size), access(_access), typeName(_typeName) { +#ifdef SQ_SUPPORT_INSTANCE_TYPE_INFO + SquirrelObject typeTable = SquirrelVM::GetRootTable().GetValue(SQ_PLUS_TYPE_TABLE); + if (typeTable.IsNull()) { + typeTable = SquirrelVM::CreateTable(); + SquirrelObject root = SquirrelVM::GetRootTable(); + root.SetValue(SQ_PLUS_TYPE_TABLE,typeTable); + } // if + typeTable.SetValue(INT((size_t)copyFunc),typeName); +#endif + } +}; + +typedef VarRef * VarRefPtr; + +// Internal use only. +inline void getVarNameTag(SQChar * buff,INT maxSize,const SQChar * scriptName) { +// Assert(maxSize > 3); +#if 1 + SQChar * d = buff; + d[0] = '_'; + d[1] = 'v'; + d = &d[2]; + maxSize -= (2+1); // +1 = space for null. + int pos=0; + while (scriptName[pos] && pos < maxSize) { + d[pos] = scriptName[pos]; + pos++; + } // while + d[pos] = 0; // null terminate. +#else + SCSNPRINTF(buff,maxSize,_T("_v%s"),scriptName); +#endif +} // getVarNameTag + +// Internal use only. +SQInteger setVarFunc(HSQUIRRELVM v); +SQInteger getVarFunc(HSQUIRRELVM v); +SQInteger setInstanceVarFunc(HSQUIRRELVM v); +SQInteger getInstanceVarFunc(HSQUIRRELVM v); + +// === BEGIN Helpers === + +inline void createTableSetGetHandlers(SquirrelObject & so) { + SquirrelObject delegate = so.GetDelegate(); + if (!delegate.Exists(_T("_set"))) { + delegate = SquirrelVM::CreateTable(); + SquirrelVM::CreateFunction(delegate,setVarFunc,_T("_set"),_T("sn|b|s")); // String var name = number(int or float) or bool or string. + SquirrelVM::CreateFunction(delegate,getVarFunc,_T("_get"),_T("s")); // String var name. + so.SetDelegate(delegate); + } // if +} // createTableSetGetHandlers + +inline VarRefPtr createVarRef(SquirrelObject & so,const SQChar * scriptVarName) { + VarRefPtr pvr=0; + ScriptStringVar256 scriptVarTagName; getVarNameTag(scriptVarTagName,sizeof(scriptVarTagName),scriptVarName); + if (!so.GetUserData(scriptVarTagName,(SQUserPointer *)&pvr)) { + so.NewUserData(scriptVarTagName,sizeof(*pvr)); + if (!so.GetUserData(scriptVarTagName,(SQUserPointer *)&pvr)) throw SquirrelError(_T("Could not create UserData.")); + } // if + return pvr; +} // createVarRef + +template +void validateConstantType(T constant) { + switch(TypeInfo()) { + case VAR_TYPE_INT: + case VAR_TYPE_FLOAT: + case VAR_TYPE_BOOL: + case VAR_TYPE_CONST_STRING: + break; + default: + throw SquirrelError(_T("validateConstantType(): type must be INT, FLOAT, BOOL, or CONST CHAR *.")); + } // case +} // validateConstantType + +inline void createInstanceSetGetHandlers(SquirrelObject & so) { + if (!so.Exists(_T("_set"))) { + SquirrelVM::CreateFunction(so,setInstanceVarFunc,_T("_set"),_T("sn|b|s|x")); // String var name = number(int or float) or bool or string or instance. + SquirrelVM::CreateFunction(so,getInstanceVarFunc,_T("_get"),_T("s")); // String var name. + } // if +} // createInstanceSetGetHandlers + +// === END Helpers === + +// === Class Type Helper class: returns a unique number for each class type === + +template +struct ClassType { + static SQUserPointer type(void) { return (SQUserPointer)© } + static CopyVarFunc getCopyFunc(void) { return (CopyVarFunc)© } + static void copy(T * dst,T * src) { + *dst = *src; + } // copy +}; + +// === Bind a global or pre-allocated (not instance) class member variable or constant (for tables only (not classes)) === + +template +void BindVariable(SquirrelObject & so,T * var,const SQChar * scriptVarName,VarAccessType access=VAR_ACCESS_READ_WRITE) { + VarRefPtr pvr = createVarRef(so,scriptVarName); + *pvr = VarRef(var,TypeInfo(),0,ClassType::getCopyFunc(),sizeof(*var),access,TypeInfo().typeName); + createTableSetGetHandlers(so); +} // BindVariable + +// === Bind a constant by value: INT, FLOAT, BOOL, or CONST CHAR * (for tables only (not classes)) === + +template +void BindConstant(SquirrelObject & so,T constant,const SQChar * scriptVarName) { + validateConstantType(constant); + VarRefPtr pvr = createVarRef(so,scriptVarName); + struct CV { + T var; + } cv; // Cast Variable helper. + cv.var = constant; + *pvr = VarRef(*(void **)&cv,TypeInfo(),0,0,sizeof(constant),VAR_ACCESS_CONSTANT,TypeInfo().typeName); + createTableSetGetHandlers(so); +} // BindConstant + +template +void BindVariable(T * var,const SQChar * scriptVarName,VarAccessType access=VAR_ACCESS_READ_WRITE) { + SquirrelObject so = SquirrelVM::GetRootTable(); + BindVariable(so,var,scriptVarName,access); +} // BindVariable + +template +void BindConstant(T constant,const SQChar * scriptVarName) { + SquirrelObject so = SquirrelVM::GetRootTable(); + BindConstant(so,constant,scriptVarName); +} // BindConstant + +// === Register a class instance member variable or constant. var argument provides type and offset ( effectively &((ClassType *)0)->var ) === + +// classType is the type of the member variable's containing class. +template +void RegisterInstanceVariable(SquirrelObject & so,SQUserPointer classType,T * var,const SQChar * scriptVarName,VarAccessType access=VAR_ACCESS_READ_WRITE) { + VarRef * pvr = createVarRef(so,scriptVarName); + void * offsetOrAddrOrConst = (void *)var; // var must be passed in as &obj->var, where obj = 0 (the address is the offset), or as static/global address. + *pvr = VarRef(offsetOrAddrOrConst,TypeInfo(),classType,ClassType::getCopyFunc(),sizeof(*var),access,TypeInfo().typeName); + createInstanceSetGetHandlers(so); +} // RegisterInstanceVariable + +template +void RegisterInstanceConstant(SquirrelObject & so,SQUserPointer classType,T constant,const SQChar * scriptVarName) { + validateConstantType(constant); + VarRef * pvr = createVarRef(so,scriptVarName); + struct CV { + T var; + size_t pad; + } cv; // Cast Variable helper. + cv.var = constant; + *pvr = VarRef(*(void **)&cv,TypeInfo(),classType,0,sizeof(constant),VAR_ACCESS_CONSTANT,TypeInfo().typeName); + createInstanceSetGetHandlers(so); +} // RegisterInstanceConstant + +////////////////////////////////////////////////////////////////////////// +/////////// BEGIN Generalized Class/Struct Instance Support ////////////// +////////////////////////////////////////////////////////////////////////// + +//BOOL CreateNativeClassInstance(HSQUIRRELVM v,const SQChar * classname,SQUserPointer ud,SQRELEASEHOOK hook); // In SquirrelBindingUtils.cpp. + +// Create native class instance and leave on stack. +inline BOOL CreateConstructNativeClassInstance(HSQUIRRELVM v,const SQChar * className) { + int oldtop = sq_gettop(v); + sq_pushroottable(v); + sq_pushstring(v,className,-1); + if (SQ_FAILED(sq_rawget(v,-2))) { // Get the class (created with sq_newclass()). + sq_settop(v,oldtop); + return FALSE; + } // if +#if 0 + sq_remove(v,-3); // Remove the root table. + sq_push(v,1); // Push the 'this'. +#else // Kamaitati's change. 5/28/06 jcs. + sq_remove(v,-2); // Remove the root table. + sq_pushroottable(v); // Push the 'this'. +#endif + if (SQ_FAILED(sq_call(v,1,SQTrue,SQ_CALL_RAISE_ERROR))) { // Call ClassName(): creates new instance and calls constructor (instead of sq_createinstance() where constructor is not called). + sq_settop(v,oldtop); + return FALSE; + } // if + sq_remove(v,-2); // Remove the class. + // int newtop = sq_gettop(v); + return TRUE; +} // CreateConstructNativeClassInstance + +// Create new instance, copy 'classToCopy', and store result on stack. +template +inline BOOL CreateCopyInstance(const SQChar * className,const T & classToCopy) { + HSQUIRRELVM v = SquirrelVM::GetVMPtr(); + if (!CreateConstructNativeClassInstance(v,className)) { + return FALSE; + } // if + SQUserPointer up=0; + sq_getinstanceup(v,-1,&up,ClassType::type()); + if (!up) return FALSE; + T * newClass = (T *)up; + *newClass = classToCopy; // Optimized version that uses the copy constructor. + return TRUE; +} // CreateCopyInstance + +// Create a new copy of type 'className' and copy 'classToCopy', return result via SquirrelObject. +template +inline SquirrelObject NewClassCopy(const SQChar * className,const T & classToCopy) { + SquirrelObject ret; + if (CreateCopyInstance(className,classToCopy)) { + ret.AttachToStackObject(-1); + sq_poptop(SquirrelVM::GetVMPtr()); + } else { + throw SquirrelError(_T("NewClassCopy(): could not create class")); + } // if + return ret; +} // NewClassCopy + +// Return a new class copy on the stack from a varArgs function call. +template +inline int ReturnCopy(HSQUIRRELVM v,const T & classToCopy) { + SquirrelObject so(NewClassCopy(GetTypeName(classToCopy),classToCopy)); + return StackHandler(v).Return(so); +} // ReturnCopy + +// Katsuaki Kawachi's GetInstance<> exception change. 6/27/06 jcs + +// Get an instance of type T from the stack at idx (for function calls). +template +T * GetInstance(HSQUIRRELVM v,SQInteger idx) { + SQUserPointer up=0; + sq_getinstanceup(v,idx,&up,ClassType::type()); + if (ExceptionOnError) { // This code block should be compiled out when ExceptionOnError is false. In any case, the compiler should not generate a test condition (include or exclude the enclosed code block). + if (!up) throw SquirrelError(_T("GetInstance: Invalid argument type")); + } // if + return (T *)up; +} // GetInstance + +// NAME and macro changes from Ben's (Project5) forum post. 2/26/06 jcs +// Kamaitati's NULL_INSTANCE support. 5/28/06 jcs + +#ifdef SQPLUS_SUPPORT_NULL_INSTANCES + +#define DECLARE_INSTANCE_TYPE_NAME_(TYPE,NAME) namespace SqPlus { \ + inline const SQChar * GetTypeName(const TYPE & n) { return _T(#NAME); } \ + inline void Push(HSQUIRRELVM v,TYPE * value) { \ + if (!value) sq_pushnull(v); \ + else if (!CreateNativeClassInstance(v,GetTypeName(*value),value,0)) \ + throw SquirrelError(_T("Push(): could not create INSTANCE (check registration name)")); } \ + inline void Push(HSQUIRRELVM v,TYPE & value) { if (!CreateCopyInstance(GetTypeName(value),value)) throw SquirrelError(_T("Push(): could not create INSTANCE copy (check registration name)")); } \ + inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return GetInstance(v,idx) != NULL; } \ + inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { \ + return (sq_gettype(v,idx)==OT_NULL) || (GetInstance(v,idx) != NULL); } \ + inline TYPE & Get(TypeWrapper,HSQUIRRELVM v,int idx) { return *GetInstance(v,idx); } \ + inline TYPE * Get(TypeWrapper,HSQUIRRELVM v,int idx) { \ + if (sq_gettype(v,idx)==OT_NULL) return NULL; \ + return GetInstance(v,idx); } \ + template<> \ + struct TypeInfo { \ + const SQChar * typeName; \ + TypeInfo() : typeName(_T(#NAME)) {} \ + enum {TypeID=VAR_TYPE_INSTANCE,Size=sizeof(TYPE)}; \ + operator ScriptVarType() { return ScriptVarType(TypeID); } \ + }; \ +} // nameSpace SqPlus + +#else + +#define DECLARE_INSTANCE_TYPE_NAME_(TYPE,NAME) namespace SqPlus { \ + inline const SQChar * GetTypeName(const TYPE & n) { return _T(#NAME); } \ + inline void Push(HSQUIRRELVM v,TYPE * value) { if (!CreateNativeClassInstance(v,GetTypeName(*value),value,0)) throw SquirrelError(_T("Push(): could not create INSTANCE (check registration name)")); } \ + inline void Push(HSQUIRRELVM v,TYPE & value) { if (!CreateCopyInstance(GetTypeName(value),value)) throw SquirrelError(_T("Push(): could not create INSTANCE copy (check registration name)")); } \ + inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return GetInstance(v,idx) != NULL; } \ + inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return GetInstance(v,idx) != NULL; } \ + inline TYPE & Get(TypeWrapper,HSQUIRRELVM v,int idx) { return *GetInstance(v,idx); } \ + inline TYPE * Get(TypeWrapper,HSQUIRRELVM v,int idx) { return GetInstance(v,idx); } \ + template<> \ + struct TypeInfo { \ + const SQChar * typeName; \ + TypeInfo() : typeName(_T(#NAME)) {} \ + enum {TypeID=VAR_TYPE_INSTANCE,Size=sizeof(TYPE)}; \ + operator ScriptVarType() { return ScriptVarType(TypeID); } \ + }; \ +} // nameSpace SqPlus + +#endif + +// TYPE or NAME below must match the string name used in SQClassDef<>, otherwise name lookup won't match and Squirrel will throw a "can't create instance" error. +#ifndef SQPLUS_CONST_OPT +#define DECLARE_INSTANCE_TYPE(TYPE) DECLARE_INSTANCE_TYPE_NAME_(TYPE,TYPE) +#define DECLARE_INSTANCE_TYPE_NAME(TYPE,NAME) DECLARE_INSTANCE_TYPE_NAME_(TYPE,NAME) +#else +#define SQPLUS_DECLARE_INSTANCE_TYPE_CONST +#include "SqPlusConst.h" +#endif + +////////////////////////////////////////////////////////////////////////// +//////////// END Generalized Class/Struct Instance Support /////////////// +////////////////////////////////////////////////////////////////////////// + +#ifndef SQ_SKIP_ARG_ASSERT + #define sq_argassert(arg,_index_) if (!Match(TypeWrapper(),v,_index_)) return sq_throwerror(v,_T("Incorrect function argument")) +#else + #define sq_argassert(arg,_index_) +#endif + +// === Return value variants === + +template +struct ReturnSpecialization { + + // === Standard Function calls === + + static int Call(RT (*func)(),HSQUIRRELVM v,int /*index*/) { + RT ret = func(); + Push(v,ret); + return 1; + } + + template + static int Call(RT (*func)(P1),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + RT ret = func( + Get(TypeWrapper(),v,index + 0) + ); + Push(v,ret); + return 1; + } + + template + static int Call(RT (*func)(P1,P2),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + RT ret = func( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1) + ); + Push(v,ret); + return 1; + } + + template + static int Call(RT (*func)(P1,P2,P3),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + RT ret = func( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2) + ); + Push(v,ret); + return 1; + } + + template + static int Call(RT (*func)(P1,P2,P3,P4),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + RT ret = func( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3) + ); + Push(v,ret); + return 1; + } + + template + static int Call(RT (*func)(P1,P2,P3,P4,P5),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + sq_argassert(5,index + 4); + RT ret = func( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3), + Get(TypeWrapper(),v,index + 4) + ); + Push(v,ret); + return 1; + } + + template + static int Call(RT (*func)(P1,P2,P3,P4,P5,P6),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + sq_argassert(5,index + 4); + sq_argassert(6,index + 5); + RT ret = func( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3), + Get(TypeWrapper(),v,index + 4), + Get(TypeWrapper(),v,index + 5) + ); + Push(v,ret); + return 1; + } + + template + static int Call(RT (*func)(P1,P2,P3,P4,P5,P6,P7),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + sq_argassert(5,index + 4); + sq_argassert(6,index + 5); + sq_argassert(7,index + 6); + RT ret = func( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3), + Get(TypeWrapper(),v,index + 4), + Get(TypeWrapper(),v,index + 5), + Get(TypeWrapper(),v,index + 6) + ); + Push(v,ret); + return 1; + } + + // === Member Function calls === + + template + static int Call(Callee & callee,RT (Callee::*func)(),HSQUIRRELVM v,int /*index*/) { + RT ret = (callee.*func)(); + Push(v,ret); + return 1; + } + + template + static int Call(Callee & callee,RT (Callee::*func)(P1),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + RT ret = (callee.*func)( + Get(TypeWrapper(),v,index + 0) + ); + Push(v,ret); + return 1; + } + + template + static int Call(Callee & callee,RT (Callee::*func)(P1,P2),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + RT ret = (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1) + ); + Push(v,ret); + return 1; + } + + template + static int Call(Callee & callee,RT (Callee::*func)(P1,P2,P3),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + RT ret = (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2) + ); + Push(v,ret); + return 1; + } + + template + static int Call(Callee & callee,RT (Callee::*func)(P1,P2,P3,P4),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + RT ret = (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3) + ); + Push(v,ret); + return 1; + } + + template + static int Call(Callee & callee,RT (Callee::*func)(P1,P2,P3,P4,P5),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + sq_argassert(5,index + 4); + RT ret = (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3), + Get(TypeWrapper(),v,index + 4) + ); + Push(v,ret); + return 1; + } + + template + static int Call(Callee & callee,RT (Callee::*func)(P1,P2,P3,P4,P5,P6),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + sq_argassert(5,index + 4); + sq_argassert(6,index + 5); + RT ret = (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3), + Get(TypeWrapper(),v,index + 4), + Get(TypeWrapper(),v,index + 5) + ); + Push(v,ret); + return 1; + } + + template + static int Call(Callee & callee,RT (Callee::*func)(P1,P2,P3,P4,P5,P6,P7),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + sq_argassert(5,index + 4); + sq_argassert(6,index + 5); + sq_argassert(7,index + 6); + RT ret = (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3), + Get(TypeWrapper(),v,index + 4), + Get(TypeWrapper(),v,index + 5), + Get(TypeWrapper(),v,index + 6) + ); + Push(v,ret); + return 1; + } + +#ifdef SQPLUS_CONST_OPT +#define SQPLUS_CALL_CONST_MFUNC_RET0 +#include "SqPlusConst.h" +#endif +}; + +// === No return value variants === + +template<> +struct ReturnSpecialization { + + // === Standard function calls === + + static int Call(void (*func)(),HSQUIRRELVM v,int /*index*/) { + (void)v; + func(); + return 0; + } + + template + static int Call(void (*func)(P1),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + func( + Get(TypeWrapper(),v,index + 0) + ); + return 0; + } + + template + static int Call(void (*func)(P1,P2),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + func( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1) + ); + return 0; + } + + template + static int Call(void (*func)(P1,P2,P3),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + func( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2) + ); + return 0; + } + + template + static int Call(void (*func)(P1,P2,P3,P4),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + func( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3) + ); + return 0; + } + + template + static int Call(void (*func)(P1,P2,P3,P4,P5),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + sq_argassert(5,index + 4); + func( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3), + Get(TypeWrapper(),v,index + 4) + ); + return 0; + } + + template + static int Call(void (*func)(P1,P2,P3,P4,P5,P6),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + sq_argassert(5,index + 4); + sq_argassert(6,index + 5); + func( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3), + Get(TypeWrapper(),v,index + 4), + Get(TypeWrapper(),v,index + 5) + ); + return 0; + } + + template + static int Call(void (*func)(P1,P2,P3,P4,P5,P6,P7),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + sq_argassert(5,index + 4); + sq_argassert(6,index + 5); + sq_argassert(7,index + 6); + func( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3), + Get(TypeWrapper(),v,index + 4), + Get(TypeWrapper(),v,index + 5), + Get(TypeWrapper(),v,index + 6) + ); + return 0; + } + + // === Member function calls === + + template + static int Call(Callee & callee,void (Callee::*func)(),HSQUIRRELVM,int /*index*/) { + (callee.*func)(); + return 0; + } + + template + static int Call(Callee & callee,void (Callee::*func)(P1),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + (callee.*func)( + Get(TypeWrapper(),v,index + 0) + ); + return 0; + } + + template + static int Call(Callee & callee,void (Callee::*func)(P1,P2),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1) + ); + return 0; + } + + template + static int Call(Callee & callee,void (Callee::*func)(P1,P2,P3),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2) + ); + return 0; + } + + template + static int Call(Callee & callee,void (Callee::*func)(P1,P2,P3,P4),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3) + ); + return 0; + } + + template + static int Call(Callee & callee,void (Callee::*func)(P1,P2,P3,P4,P5),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + sq_argassert(5,index + 4); + (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3), + Get(TypeWrapper(),v,index + 4) + ); + return 0; + } + + template + static int Call(Callee & callee,void (Callee::*func)(P1,P2,P3,P4,P5,P6),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + sq_argassert(5,index + 4); + sq_argassert(6,index + 5); + (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3), + Get(TypeWrapper(),v,index + 4), + Get(TypeWrapper(),v,index + 5) + ); + return 0; + } + + template + static int Call(Callee & callee,void (Callee::*func)(P1,P2,P3,P4,P5,P6,P7),HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + sq_argassert(5,index + 4); + sq_argassert(6,index + 5); + sq_argassert(7,index + 6); + (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2), + Get(TypeWrapper(),v,index + 3), + Get(TypeWrapper(),v,index + 4), + Get(TypeWrapper(),v,index + 5), + Get(TypeWrapper(),v,index + 6) + ); + return 0; + } + +#ifdef SQPLUS_CONST_OPT +#define SQPLUS_CALL_CONST_MFUNC_NORET +#include "SqPlusConst.h" +#endif + +}; + +// === STANDARD Function return value specialized call handlers === + +template +int Call(RT (*func)(),HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(func,v,index); +} + +template +int Call(RT (*func)(P1),HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(func,v,index); +} + +template +int Call(RT (*func)(P1,P2),HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(func,v,index); +} + +template +int Call(RT (*func)(P1,P2,P3),HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(func,v,index); +} + +template +int Call(RT (*func)(P1,P2,P3,P4),HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(func,v,index); +} + +template +int Call(RT (*func)(P1,P2,P3,P4,P5),HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(func,v,index); +} + +template +int Call(RT (*func)(P1,P2,P3,P4,P5,P6),HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(func,v,index); +} + +template +int Call(RT (*func)(P1,P2,P3,P4,P5,P6,P7),HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(func,v,index); +} + +// === MEMBER Function return value specialized call handlers === + +template +int Call(Callee & callee, RT (Callee::*func)(),HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); +} + +template +int Call(Callee & callee,RT (Callee::*func)(P1),HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); +} + +template +int Call(Callee & callee,RT (Callee::*func)(P1,P2),HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); +} + +template +int Call(Callee & callee,RT (Callee::*func)(P1,P2,P3),HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); +} + +template +int Call(Callee & callee,RT (Callee::*func)(P1,P2,P3,P4),HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); +} + +template +int Call(Callee & callee,RT (Callee::*func)(P1,P2,P3,P4,P5),HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); +} + +template +int Call(Callee & callee,RT (Callee::*func)(P1,P2,P3,P4,P5,P6),HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); +} + +template +int Call(Callee & callee,RT (Callee::*func)(P1,P2,P3,P4,P5,P6,P7),HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); +} + +#ifdef SQPLUS_CONST_OPT +#define SQPLUS_CALL_CONST_MFUNC_RET1 +#include "SqPlusConst.h" +#endif + +// === Direct Call Standard Function handler === + +template +struct DirectCallFunction { + static inline int Dispatch(HSQUIRRELVM v) { + StackHandler sa(v); + int paramCount = sa.GetParamCount(); + Func * func = (Func *)sa.GetUserData(paramCount); + return Call(*func,v,2); + } // Dispatch +}; + +// === Direct Call Member Function handler === + +template +class DirectCallMemberFunction { +public: + static inline int Dispatch(HSQUIRRELVM v) { + StackHandler sa(v); + int paramCount = sa.GetParamCount(); + unsigned char * ud = (unsigned char *)sa.GetUserData(paramCount); + return Call(**(Callee**)ud,*(Func*)(ud + sizeof(Callee*)),v,2); + } // Dispatch +}; + +// === Direct Call Instance Member Function handler === + +#define SQ_CLASS_OBJECT_TABLE_NAME _T("__ot") +#define SQ_CLASS_HIER_ARRAY _T("__ca") + +template +class DirectCallInstanceMemberFunction { +public: + static inline int Dispatch(HSQUIRRELVM v) { + StackHandler sa(v); + Callee * instance = (Callee *)sa.GetInstanceUp(1,0); + int paramCount = sa.GetParamCount(); + Func * func = (Func *)sa.GetUserData(paramCount); +#ifdef SQ_USE_CLASS_INHERITANCE + SquirrelObject so(sa.GetObjectHandle(1)); // 'this' + SQUserPointer typetag; so.GetTypeTag(&typetag); + SQUserPointer calleeType = ClassType::type(); + if (typetag != calleeType) { + SquirrelObject typeTable = so.GetValue(SQ_CLASS_OBJECT_TABLE_NAME); + instance = (Callee *)typeTable.GetUserPointer(INT((size_t)ClassType::type())); // 64-bit compatible version. + if (!instance) { + return sq_throwerror(v,_T("Invalid Instance Type")); + } // if + } // if +#endif + return Call(*instance,*func,v,2); + } // Dispatch +}; + +// === Direct Call Instance Member Function Variable Argument handler === + +template +class DirectCallInstanceMemberFunctionVarArgs { +public: + typedef int (Callee::*FuncType)(HSQUIRRELVM); + static inline int Dispatch(HSQUIRRELVM v) { + StackHandler sa(v); + Callee * instance = (Callee *)sa.GetInstanceUp(1,0); + int paramCount = sa.GetParamCount(); + FuncType func = *(FuncType *)sa.GetUserData(paramCount); +#ifdef SQ_USE_CLASS_INHERITANCE + SquirrelObject so(sa.GetObjectHandle(1)); // 'this' + SQUserPointer typetag; so.GetTypeTag(&typetag); + SQUserPointer calleeType = ClassType::type(); + if (typetag != calleeType) { + SquirrelObject typeTable = so.GetValue(SQ_CLASS_OBJECT_TABLE_NAME); + instance = (Callee *)typeTable.GetUserPointer(INT((size_t)ClassType::type())); // 64-bit compatible version. + if (!instance) { + return sq_throwerror(v,_T("Invalid Instance Type")); + } // if + } // if +#endif + sq_poptop(v); // Remove UserData from stack: so sa.GetParamCount() returns actual param count. + return (instance->*func)(v); + } // Dispatch +}; + +// Code fragment useful for debugging new implementations. +#if 0 +HSQOBJECT ho = sa.GetObjectHandle(paramCount); +SquirrelObject so(ho); +SQObjectType sot = so.GetType(); +#endif + +// === Standard function call === + +template +inline void sq_pushdirectclosure(HSQUIRRELVM v,Func func,SQUnsignedInteger nupvalues) { + SQUserPointer up = sq_newuserdata(v,sizeof(func)); // Also pushed on stack. + memcpy(up,&func,sizeof(func)); + sq_newclosure(v,DirectCallFunction::Dispatch,nupvalues+1); +} // sq_pushdirectclosure + +// === Fixed Class pointer call (always calls with object pointer that was registered) === + +template +inline void sq_pushdirectclosure(HSQUIRRELVM v,const Callee & callee,Func func,SQUnsignedInteger nupvalues) { + unsigned char * up = (unsigned char *)sq_newuserdata(v,sizeof(Callee*)+sizeof(func)); // Also pushed on stack. + const SQUserPointer pCallee = (SQUserPointer)&callee; + memcpy(up,&pCallee,sizeof(Callee*)); + memcpy(up + sizeof(Callee*),&func,sizeof(func)); + sq_newclosure(v,DirectCallMemberFunction::Dispatch,nupvalues+1); +} // sq_pushdirectclosure + +// === Class Instance call: class pointer retrieved from script class instance === + +template +inline void sq_pushdirectinstanceclosure(HSQUIRRELVM v,const Callee & callee,Func func,SQUnsignedInteger nupvalues) { + unsigned char * up = (unsigned char *)sq_newuserdata(v,sizeof(func)); // Also pushed on stack. + memcpy(up,&func,sizeof(func)); + sq_newclosure(v,DirectCallInstanceMemberFunction::Dispatch,nupvalues+1); +} // sq_pushdirectinstanceclosure + +// === Class Instance call: class pointer retrieved from script class instance (variable arguments) === + +template +inline void sq_pushdirectinstanceclosurevarargs(HSQUIRRELVM v,const Callee & callee,int (Callee::*func)(HSQUIRRELVM),SQUnsignedInteger nupvalues) { + unsigned char * up = (unsigned char *)sq_newuserdata(v,sizeof(func)); // Also pushed on stack. + memcpy(up,&func,sizeof(func)); + sq_newclosure(v,DirectCallInstanceMemberFunctionVarArgs::Dispatch,nupvalues+1); +} // sq_pushdirectinstanceclosurevarargs + +// === Register a STANDARD function (table or class on stack) === + +template +inline void Register(HSQUIRRELVM v,Func func,const SQChar * name) { + sq_pushstring(v,name,-1); + sq_pushdirectclosure(v,func,0); + sq_createslot(v,-3); // Stack is restored after this call (same state as before Register() call). +} // Register + +// === Register a MEMBER function (table or class on stack) === + +template +inline void Register(HSQUIRRELVM v,Callee & callee,Func func,const SQChar * name) { + sq_pushstring(v,name,-1); + sq_pushdirectclosure(v,callee,func,0); + sq_createslot(v,-3); // Stack is restored after this call (same state as before Register() call). +} // Register + +// === Register a STANDARD global function (root table) === + +template +inline void RegisterGlobal(HSQUIRRELVM v,Func func,const SQChar * name) { + sq_pushroottable(v); + Register(v,func,name); + sq_poptop(v); // Remove root table. +} // RegisterGlobal + +template +inline void RegisterGlobal(Func func,const SQChar * name) { + RegisterGlobal(SquirrelVM::GetVMPtr(),func,name); +} // RegisterGlobal + +// === Register a MEMBER global function (root table) === + +template +inline void RegisterGlobal(HSQUIRRELVM v,Callee & callee,Func func,const SQChar * name) { + sq_pushroottable(v); + Register(v,callee,func,name); + sq_poptop(v); // Remove root table. +} // RegisterGlobal + +template +inline void RegisterGlobal(Callee & callee,Func func,const SQChar * name) { + RegisterGlobal(SquirrelVM::GetVMPtr(),callee,func,name); +} // RegisterGlobal + +// === Register a STANDARD function (hso is table or class) === + +template +inline void Register(HSQUIRRELVM v,HSQOBJECT hso,Func func,const SQChar * name) { + sq_pushobject(v,hso); + Register(v,func,name); + sq_poptop(v); // Remove hso. +} // Register + +// === Register a MEMBER function (hso is table or class) === +// === Fixed Class pointer call (always calls with object pointer that was registered) === + +template +inline void Register(HSQUIRRELVM v,HSQOBJECT hso,Callee & callee,Func func,const SQChar * name) { + sq_pushobject(v,hso); + Register(v,callee,func,name); + sq_poptop(v); // Remove hso. +} // Register + +// === Register an INSTANCE MEMBER function === +// === Class Instance call: class pointer retrieved from script class instance === + +template +inline void RegisterInstance(HSQUIRRELVM v,HSQOBJECT hclass,Callee & callee,Func func,const SQChar * name) { + sq_pushobject(v,hclass); + sq_pushstring(v,name,-1); + sq_pushdirectinstanceclosure(v,callee,func,0); + sq_createslot(v,-3); + sq_poptop(v); // Remove hclass. +} // RegisterInstance + + +#ifdef _MSC_VER +#pragma warning(disable : 4995) // Deprecated _snprintf +#endif + +// === Register an INSTANCE MEMBER function Variable Arguments === +// typeMask: "*" means don't check parameters, typeMask=0 means function takes no arguments (and is type checked for that case). +// All the other Squirrel type-masks are passed normally. + +template +inline void RegisterInstanceVarArgs(HSQUIRRELVM v,HSQOBJECT hclass,Callee & callee,int (Callee::*func)(HSQUIRRELVM),const SQChar * name,const SQChar * typeMask=_T("*")) { + sq_pushobject(v,hclass); + sq_pushstring(v,name,-1); + sq_pushdirectinstanceclosurevarargs(v,callee,func,0); + SQChar tm[64]; + SQChar * ptm = tm; + int numParams = SQ_MATCHTYPEMASKSTRING; + if (typeMask) { + if (typeMask[0] == '*') { + ptm = 0; // Variable args: don't check parameters. +// numParams = 0; // Clear SQ_MATCHTYPEMASKSTRING (does not mean match 0 params. See sq_setparamscheck()). + } else { + if (SCSNPRINTF(tm,sizeof(tm),_T("x%s"),typeMask) < 0) { // Must be an instance. + throw SquirrelError(_T("RegisterInstanceVarArgs: typeMask string too long.")); + } // if + } // if + } else { // Need to check object type on stack: table, class, instance, etc. +// _snprintf(tm,sizeof(tm),"x"); // instance. + tm[0] = 'x'; + tm[1] = 0; + } // if + if (ptm) { // If ptm == 0, don't check type. + sq_setparamscheck(v,numParams,ptm); // Determine arg count from type string. + } // if +#ifdef _DEBUG + sq_setnativeclosurename(v,-1,name); // For debugging only. +#endif + sq_createslot(v,-3); + sq_poptop(v); // Remove hclass. +} // RegisterInstanceVarArgs + +#ifdef _MSC_VER +#pragma warning(default : 4995) +#endif + +// === Call Squirrel Functions from C/C++ === +// No type checking is performed for Squirrel functions as Squirrel types are dynamic: +// Incoming types are passed unchanged to Squirrel functions. The parameter count is checked: an exception is thrown if mismatched. +// Return values must match the RT template argument type, else an exception can be thrown on return. + +template +struct SquirrelFunction { + HSQUIRRELVM v; + SquirrelObject object; // Table or class. + SquirrelObject func; + SquirrelFunction() : v(0) {} + SquirrelFunction(HSQUIRRELVM _v,const SquirrelObject & _object,const SquirrelObject & _func) : v(_v), object(_object), func(_func) {} + SquirrelFunction(const SquirrelObject & _object,const SquirrelObject & _func) : v(SquirrelVM::GetVMPtr()), object(_object), func(_func) {} + SquirrelFunction(const SquirrelObject & _object,const SQChar * name) { + v = SquirrelVM::GetVMPtr(); + object = _object; + func = object.GetValue(name); + } + SquirrelFunction(const SQChar * name) { + v = SquirrelVM::GetVMPtr(); + object = SquirrelVM::GetRootTable(); + func = object.GetValue(name); + } + + // Release references and reset internal objects to null. + void reset(void) { + func.Reset(); + object.Reset(); + } // Reset + +#define SQPLUS_CHECK_FNCALL(res) if (!SQ_SUCCEEDED(res)) throw SquirrelError(_T("SquirrelFunction<> call failed")) + + RT operator()(void) { + sq_pushobject(v,func.GetObjectHandle()); + sq_pushobject(v,object.GetObjectHandle()); + SQPLUS_CHECK_FNCALL(sq_call(v,1,SQTrue,SQ_CALL_RAISE_ERROR)); + return GetRet(TypeWrapper(),v,-1); + } + + template + RT operator()(P1 p1) { + sq_pushobject(v,func.GetObjectHandle()); + sq_pushobject(v,object.GetObjectHandle()); + Push(v,p1); + SQPLUS_CHECK_FNCALL(sq_call(v,2,SQTrue,SQ_CALL_RAISE_ERROR)); + return GetRet(TypeWrapper(),v,-1); + } + + template + RT operator()(P1 p1,P2 p2) { + sq_pushobject(v,func.GetObjectHandle()); + sq_pushobject(v,object.GetObjectHandle()); + Push(v,p1); + Push(v,p2); + SQPLUS_CHECK_FNCALL(sq_call(v,3,SQTrue,SQ_CALL_RAISE_ERROR)); + return GetRet(TypeWrapper(),v,-1); + } + + template + RT operator()(P1 p1,P2 p2,P3 p3) { + sq_pushobject(v,func.GetObjectHandle()); + sq_pushobject(v,object.GetObjectHandle()); + Push(v,p1); + Push(v,p2); + Push(v,p3); + SQPLUS_CHECK_FNCALL(sq_call(v,4,SQTrue,SQ_CALL_RAISE_ERROR)); + return GetRet(TypeWrapper(),v,-1); + } + + template + RT operator()(P1 p1,P2 p2,P3 p3,P4 p4) { + sq_pushobject(v,func.GetObjectHandle()); + sq_pushobject(v,object.GetObjectHandle()); + Push(v,p1); + Push(v,p2); + Push(v,p3); + Push(v,p4); + SQPLUS_CHECK_FNCALL(sq_call(v,5,SQTrue,SQ_CALL_RAISE_ERROR)); + return GetRet(TypeWrapper(),v,-1); + } + + template + RT operator()(P1 p1,P2 p2,P3 p3,P4 p4,P5 p5) { + sq_pushobject(v,func.GetObjectHandle()); + sq_pushobject(v,object.GetObjectHandle()); + Push(v,p1); + Push(v,p2); + Push(v,p3); + Push(v,p4); + Push(v,p5); + SQPLUS_CHECK_FNCALL(sq_call(v,6,SQTrue,SQ_CALL_RAISE_ERROR)); + return GetRet(TypeWrapper(),v,-1); + } + + template + RT operator()(P1 p1,P2 p2,P3 p3,P4 p4,P5 p5,P6 p6) { + sq_pushobject(v,func.GetObjectHandle()); + sq_pushobject(v,object.GetObjectHandle()); + Push(v,p1); + Push(v,p2); + Push(v,p3); + Push(v,p4); + Push(v,p5); + Push(v,p6); + SQPLUS_CHECK_FNCALL(sq_call(v,7,SQTrue,SQ_CALL_RAISE_ERROR)); + return GetRet(TypeWrapper(),v,-1); + } + + template + RT operator()(P1 p1,P2 p2,P3 p3,P4 p4,P5 p5,P6 p6,P7 p7) { + sq_pushobject(v,func.GetObjectHandle()); + sq_pushobject(v,object.GetObjectHandle()); + Push(v,p1); + Push(v,p2); + Push(v,p3); + Push(v,p4); + Push(v,p5); + Push(v,p6); + Push(v,p7); + SQPLUS_CHECK_FNCALL(sq_call(v,8,SQTrue,SQ_CALL_RAISE_ERROR)); + return GetRet(TypeWrapper(),v,-1); + } + +}; + +// === Class/Struct registration === + +#define SQ_DELETE_CLASS(CLASSTYPE) if (up) { CLASSTYPE * self = (CLASSTYPE *)up; delete self;} return 0 +#define SQ_DECLARE_RELEASE(CLASSTYPE) \ + static int release(SQUserPointer up,SQInteger size) { \ + SQ_DELETE_CLASS(CLASSTYPE); \ + } + +template +struct ReleaseClassPtrPtr { + static int release(SQUserPointer up,SQInteger size) { + if (up) { + T ** self = (T **)up; + delete *self; + } // if + return 0; + } // release +}; + +template +struct ReleaseClassPtr { + static int release(SQUserPointer up,SQInteger size) { + if (up) { + T * self = (T *)up; + delete self; + } // if + return 0; + } // release +}; + +BOOL CreateClass(HSQUIRRELVM v,SquirrelObject & newClass,SQUserPointer classType,const SQChar * name,const SQChar * baseName=0); + +#define SQ_ANCESTOR_CLASS_INDEX _T("__ci") + +// Call PostConstruct() at the end of custom constructors. +template +inline int PostConstruct(HSQUIRRELVM v,T * newClass,SQRELEASEHOOK hook) { +#ifdef SQ_USE_CLASS_INHERITANCE + StackHandler sa(v); + HSQOBJECT ho = sa.GetObjectHandle(1); // OT_INSTANCE + SquirrelObject instance(ho); + INT classIndex = instance.GetValue(SQ_ANCESTOR_CLASS_INDEX).ToInteger(); + if (classIndex == -1) { // Is this the most-derived C/C++ class? If so, create all ancestors (if present). + + SquirrelObject newObjectTable = SquirrelVM::CreateTable(); // 11/2/05: Create a new table for this instance. + newObjectTable.SetUserPointer(INT((size_t)ClassType::type()),newClass); // 64-bit compatible version. + instance.SetValue(SQ_CLASS_OBJECT_TABLE_NAME,newObjectTable); + + SquirrelObject classHierArray = instance.GetValue(SQ_CLASS_HIER_ARRAY); + INT count = classHierArray.Len(); + if (count > 1) { // This will be true when more than one C/C++ class is in the hierarchy. + --count; // Skip the most-derived class. + for (INT i=0; i < count; i++) { +#ifdef CPP_STYLE_INHERITANCE // Kamaitati's changes for C++ inheritance support. jcs 5/28/06 + SquirrelObject so = classHierArray.GetValue(i); + sq_pushobject(v,so.GetObjectHandle()); + SQUserPointer typeTag; + sq_gettypetag(v,-1,&typeTag); + newObjectTable.SetUserPointer(INT(size_t(typeTag)),newClass); + sq_poptop(v); +#else + instance.SetValue(SQ_ANCESTOR_CLASS_INDEX,i); // Store ancestor class index for recursive constructor calls to come. + INT top = sq_gettop(v); + SquirrelObject so = classHierArray.GetValue(i); // Need to create UserData struct: store pointer to class, set release hook. + SquirrelObject func = so.GetValue(_T("constructor")); + sq_pushobject(v,func.GetObjectHandle()); + sq_pushobject(v,instance.GetObjectHandle()); // The 'instance' is the real Squirrel 'this' for all ancestors (as opposed to an instance created from the defining class, which does not happen). + sq_call(v,1,SQFalse,SQ_CALL_RAISE_ERROR); // Call constructor: no arguments are passed other than the 'instance'. + sq_settop(v,top); +#endif + } // for + instance.SetValue(SQ_ANCESTOR_CLASS_INDEX,SquirrelObject()); // Store an OT_NULL object to free SQ_ANCESTOR_CLASS_INDEX var. + } // if + } else { // Ancestor: Construct class and set release hook. + + SquirrelObject objectTable = instance.GetValue(SQ_CLASS_OBJECT_TABLE_NAME); // 11/2/05: Get the existing object table. + objectTable.SetUserPointer(INT((size_t)ClassType::type()),newClass); // 64-bit compatible version. + + INT top = sq_gettop(v); + T ** ud = (T **)sq_newuserdata(v,sizeof(T *)); // Create UserData and push onto stack. + *ud = newClass; + sq_setreleasehook(v,-1,ReleaseClassPtrPtr::release); // Set release hook for UserData on stack. + SquirrelObject userData; + userData.AttachToStackObject(-1); + SquirrelObject classHierArray = instance.GetValue(SQ_CLASS_HIER_ARRAY); + classHierArray.SetValue(classIndex,userData); // Replace the class entry with UserData: will be freed during most-derived class destruction. + sq_settop(v,top); + return TRUE; + } // if +#endif + sq_setinstanceup(v,1,newClass); + sq_setreleasehook(v,1,hook); + return 1; +} // PostConstruct + +template +struct ConstructReleaseClass { + static int construct(HSQUIRRELVM v) { + return PostConstruct(v,new T(),release); + } // construct + SQ_DECLARE_RELEASE(T) +}; + +// === Helper for RegisterClassType*() === +inline void setupClassHierarchy(SquirrelObject newClass) { + // New member vars cannot be added to instances (OT_INSTANCE): additions must occur on the defining class (OT_CLASS), before any instances are instantiated. + if (!newClass.Exists(SQ_CLASS_OBJECT_TABLE_NAME)) { // Will always get table from most-derived registered class. + SquirrelObject objectTable = SquirrelVM::CreateTable(); + newClass.SetValue(SQ_CLASS_OBJECT_TABLE_NAME,objectTable); // Constructors must add their 'this' pointer indexed by type to this table. See PostConstruct() above. + // 11/2/05: This table will behave as a static global for each instance unless overwritten during construction (see PostConstruct() above). + } // if + SquirrelObject classHierArray; + if (!newClass.Exists(SQ_CLASS_HIER_ARRAY)) { // Will always get table from most-derived registered class. + classHierArray = SquirrelVM::CreateArray(0); // The only constructor called will be the most-derived class: this array contains all classes in the hierarchy to be constructed. + newClass.SetValue(SQ_CLASS_HIER_ARRAY,classHierArray); + } else { + classHierArray = newClass.GetValue(SQ_CLASS_HIER_ARRAY); + } // if + classHierArray.ArrayAppend(newClass); // Add the class to the hierarchy array. The array values will be released and replaced with UserData to free created ancestor classes. + newClass.SetValue(SQ_ANCESTOR_CLASS_INDEX,-1); // When the class hierarchy is created, this var will be used to help in recursively creating ancestor classes. +} // setupClassHierarchy + +template +inline SquirrelObject RegisterClassType(HSQUIRRELVM v,const SQChar * scriptClassName,const SQChar * baseScriptClassName=0) { + int top = sq_gettop(v); + SquirrelObject newClass; + if (CreateClass(v,newClass,(SQUserPointer)ClassType::type(),scriptClassName,baseScriptClassName)) { + SquirrelVM::CreateFunction(newClass,&ConstructReleaseClass::construct,_T("constructor")); +#ifdef SQ_USE_CLASS_INHERITANCE + setupClassHierarchy(newClass); +#endif + } // if + sq_settop(v,top); + return newClass; +} // RegisterClassType + +template +inline SquirrelObject RegisterClassTypeNoConstructor(HSQUIRRELVM v,const SQChar * scriptClassName,const SQChar * baseScriptClassName=0) { + int top = sq_gettop(v); + SquirrelObject newClass; + if (CreateClass(v,newClass,(SQUserPointer)ClassType::type(),scriptClassName,baseScriptClassName)) { +#ifdef SQ_USE_CLASS_INHERITANCE + setupClassHierarchy(newClass); +#endif + } // if + sq_settop(v,top); + return newClass; +} // RegisterClassTypeNoConstructor + +// === Define and register a C++ class and its members for use with Squirrel === +// Constructors+destructors are automatically created. Custom constructors must use the +// standard SQFUNCTION signature if variable argument types are required (overloads). +// See testSqPlus2.cpp for examples. + +// Do not use SQClassDefBase<> directly, use SQClassDef<> or SQClassDefNoConstructor<>, below. +template +struct SQClassDefBase { + HSQUIRRELVM v; + const SQChar * name; + SquirrelObject newClass; + +#ifdef SQ_USE_CLASS_INHERITANCE + const SQChar * base; + // Optional base arg is the name of a base class to inherit from (must already be defined in the Squirrel VM). + SQClassDefBase(HSQUIRRELVM _v,const SQChar * _name,const SQChar * _base=0) : v(_v), name(_name), base(_base) {} + // Optional base arg is the name of a base class to inherit from (must already be defined in the Squirrel VM). + SQClassDefBase(const SQChar * _name,const SQChar * _base=0) : v(SquirrelVM::GetVMPtr()), name(_name), base(_base) {} +#else + SQClassDefBase(HSQUIRRELVM _v,const SQChar * _name) : v(_v), name(_name) {} + SQClassDefBase(const SQChar * _name) : v(SquirrelVM::GetVMPtr()), name(_name) {} +#endif + + // Register a member function. + template + SQClassDefBase & func(Func pfunc,const SQChar * name) { + RegisterInstance(v,newClass.GetObjectHandle(),*(TClassType *)0,pfunc,name); + return *this; + } // func + + // Register a variable-argument member function (supports variable+multiple return values). + // typeMask: "*" means don't check parameters, typeMask=0 means function takes no arguments (and is type checked for that case). + // All the other Squirrel type-masks are passed normally. + template + SQClassDefBase & funcVarArgs(Func pfunc,const SQChar * name,const SQChar * typeMask=_T("*")) { + RegisterInstanceVarArgs(v,newClass.GetObjectHandle(),*(TClassType *)0,pfunc,name,typeMask); + return *this; + } // funcVarArgs + + // === BEGIN static-member+global function registration === + + // === This version is for static member functions only, such as custom constructors where 'this' is not yet valid === + // typeMask: "*" means don't check parameters, typeMask=0 means function takes no arguments (and is type checked for that case). + // All the other Squirrel type-masks are passed normally. + + template + SQClassDefBase & staticFuncVarArgs(Func pfunc,const SQChar * name,const SQChar * typeMask=_T("*")) { + SquirrelVM::PushObject(newClass); + SquirrelVM::CreateFunction(pfunc,name,typeMask); + SquirrelVM::Pop(1); + return *this; + } // staticFuncVarArgs + + // Register a standard global function (effectively embedding a global function in TClassType's script namespace: does not need or use a 'this' pointer). + template + SQClassDefBase & staticFunc(Func pfunc,const SQChar * name) { + Register(v,newClass.GetObjectHandle(),pfunc,name); + return *this; + } // staticFunc + + // Register a function to a pre-allocated class/struct member function: will use callee's 'this' (effectively embedding a global function in TClassType's script namespace). + template + SQClassDefBase & staticFunc(Callee & callee,Func pfunc,const SQChar * name) { + Register(v,newClass.GetObjectHandle(),callee,pfunc,name); + return *this; + } // staticFunc + + // === END static+global function registration === + + // Register a member variable. + template + SQClassDefBase & var(VarType TClassType::* pvar,const SQChar * name,VarAccessType access=VAR_ACCESS_READ_WRITE) { + struct CV { + VarType TClassType::* var; + } cv; // Cast Variable helper. + cv.var = pvar; + RegisterInstanceVariable(newClass,ClassType::type(),*(VarType **)&cv,name,access); + return *this; + } // var + + // Register a member variable as a UserPointer (read only). + template + SQClassDefBase & varAsUserPointer(VarType TClassType::* pvar,const SQChar * name) { + struct CV { + VarType TClassType::* var; + } cv; // Cast Variable helper. + cv.var = pvar; + RegisterInstanceVariable(newClass,ClassType::type(),*(SQAnything **)&cv,name,VAR_ACCESS_READ_ONLY); + return *this; + } // varAsUserPointer + + template + SQClassDefBase & staticVar(VarType * pvar,const SQChar * name,VarAccessType access=VAR_ACCESS_READ_WRITE) { + struct CV { + VarType * var; + } cv; // Cast Variable helper. + cv.var = pvar; + RegisterInstanceVariable(newClass,ClassType::type(),*(VarType **)&cv,name,VarAccessType(access|VAR_ACCESS_STATIC)); + return *this; + } // staticVar + +#ifdef SQPLUS_CONST_OPT +#define SQ_REG_CONST_STATIC_VAR +#include "SqPlusConst.h" +#endif + + // Register a constant (read-only in script, passed by value (only INT, FLOAT, or BOOL types)). + template + SQClassDefBase & constant(ConstantType constant,const SQChar * name) { + RegisterInstanceConstant(newClass,ClassType::type(),constant,name); + return *this; + } // constant + + // Register an enum as an integer (read-only in script). + SQClassDefBase & enumInt(int constant,const SQChar * name) { + RegisterInstanceConstant(newClass,ClassType::type(),constant,name); + return *this; + } // enumInt + +}; + +template +struct SQClassDef : public SQClassDefBase { +#ifdef SQ_USE_CLASS_INHERITANCE + // Optional base arg is the name of a base class to inherit from (must already be defined in the Squirrel VM). + SQClassDef(HSQUIRRELVM _v,const SQChar * _name,const SQChar * _base=0) : SQClassDefBase(_v,_name,_base) { + this->newClass = RegisterClassType(this->v,this->name,this->base); + } + // Optional base arg is the name of a base class to inherit from (must already be defined in the Squirrel VM). + SQClassDef(const SQChar * _name,const SQChar * _base=0) : SQClassDefBase(_name,_base) { + this->newClass = RegisterClassType(this->v,this->name,this->base); + } +#else + SQClassDef(HSQUIRRELVM _v,const SQChar * _name) : SQClassDefBase(_v,_name) { + this->newClass = RegisterClassType(this->v,this->name); + } + SQClassDef(const SQChar * _name) : SQClassDefBase(_name) { + this->newClass = RegisterClassType(this->v,this->name); + } +#endif +}; + +template +struct SQClassDefNoConstructor : public SQClassDefBase { +#ifdef SQ_USE_CLASS_INHERITANCE + // Optional base arg is the name of a base class to inherit from (must already be defined in the Squirrel VM). + SQClassDefNoConstructor(HSQUIRRELVM _v,const SQChar * _name,const SQChar * _base=0) : SQClassDefBase(_v,_name,_base) { + this->newClass = RegisterClassTypeNoConstructor(this->v,this->name,this->base); + } + // Optional base arg is the name of a base class to inherit from (must already be defined in the Squirrel VM). + SQClassDefNoConstructor(const SQChar * _name,const SQChar * _base=0) : SQClassDefBase(_name,_base) { + this->newClass = RegisterClassTypeNoConstructor(this->v,this->name,this->base); + } +#else + SQClassDefNoConstructor(HSQUIRRELVM _v,const SQChar * _name) : SQClassDefBase(_v,_name) { + this->newClass = RegisterClassTypeNoConstructor(this->v,this->name); + } + SQClassDefNoConstructor(const SQChar * _name) : SQClassDefBase(_name) { + this->newClass = RegisterClassTypeNoConstructor(this->v,this->name); + } +#endif +}; + + +// === BEGIN Function Call Handlers === + +inline void Push(HSQUIRRELVM v,char value) { sq_pushinteger(v,value); } +inline void Push(HSQUIRRELVM v,unsigned char value) { sq_pushinteger(v,value); } +inline void Push(HSQUIRRELVM v,short value) { sq_pushinteger(v,value); } +inline void Push(HSQUIRRELVM v,unsigned short value) { sq_pushinteger(v,value); } +inline void Push(HSQUIRRELVM v,int value) { sq_pushinteger(v,value); } +inline void Push(HSQUIRRELVM v,unsigned int value) { sq_pushinteger(v,value); } +inline void Push(HSQUIRRELVM v,long value) { sq_pushinteger(v,value); } +inline void Push(HSQUIRRELVM v,unsigned long value) { sq_pushinteger(v,value); } +inline void Push(HSQUIRRELVM v,double value) { sq_pushfloat(v,(FLOAT)value); } +inline void Push(HSQUIRRELVM v,float value) { sq_pushfloat(v,(FLOAT)value); } +inline void Push(HSQUIRRELVM v,const SQChar * value) { sq_pushstring(v,value,-1); } +inline void Push(HSQUIRRELVM v,const SquirrelNull &) { sq_pushnull(v); } +inline void Push(HSQUIRRELVM v,SQFUNCTION value) { sq_pushuserpointer(v,(void*)value); } +inline void Push(HSQUIRRELVM v,SQAnythingPtr value) { sq_pushuserpointer(v,(void*)value); } // Cast to SQAnythingPtr instead of void * if USE_ARGUMENT_DEPENDANT_OVERLOADS can't be used by your compiler. +inline void Push(HSQUIRRELVM v,SquirrelObject & so) { sq_pushobject(v,so.GetObjectHandle()); } + + +#define USE_ARGUMENT_DEPENDANT_OVERLOADS +#ifdef USE_ARGUMENT_DEPENDANT_OVERLOADS +#ifdef _MSC_VER +#pragma warning (disable:4675) // Disable warning: "resolved overload was found by argument-dependent lookup" when class/struct pointers are used as function arguments. +#endif +// === BEGIN Argument Dependent Overloads === +inline void Push(HSQUIRRELVM v,bool value) { sq_pushbool(v,value); } // Pass bool as int if USE_ARGUMENT_DEPENDANT_OVERLOADS can't be used by your compiler. +inline void Push(HSQUIRRELVM v,const void * value) { sq_pushuserpointer(v,(void*)value); } // Pass SQAnythingPtr instead of void * " " +inline void Push(HSQUIRRELVM v,const SQUserPointer & value) { sq_pushuserpointer(v,(void*)value); } +// === END Argument Dependent Overloads === +#endif + +#define SQPLUS_CHECK_GET(res) if (!SQ_SUCCEEDED(res)) throw SquirrelError(_T("sq_get*() failed (type error)")) + +inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_BOOL; } +inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } +inline bool Match(TypeWrapper,HSQUIRRELVM v, int idx) { return sq_gettype(v,idx) == OT_INTEGER; } +inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } +inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } +inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } +inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } +inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } +inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } +inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { int type = sq_gettype(v,idx); return type == OT_FLOAT; } +inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { int type = sq_gettype(v,idx); return type == OT_FLOAT; } +inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_STRING; } +inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return true; } // See Get() for HSQUIRRELVM below (v is always present). +inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_USERPOINTER; } +inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return true; } // See sq_getstackobj(): always returns true. + +inline void Get(TypeWrapper,HSQUIRRELVM v,int) {} +inline bool Get(TypeWrapper,HSQUIRRELVM v,int idx) { SQBool b; SQPLUS_CHECK_GET(sq_getbool(v,idx,&b)); return b != 0; } +inline char Get(TypeWrapper,HSQUIRRELVM v,int idx) { intp i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } +inline unsigned char Get(TypeWrapper,HSQUIRRELVM v,int idx) { intp i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } +inline short Get(TypeWrapper,HSQUIRRELVM v,int idx) { intp i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } +inline unsigned short Get(TypeWrapper,HSQUIRRELVM v,int idx) { intp i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } +inline int Get(TypeWrapper,HSQUIRRELVM v,int idx) { intp i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return i; } +inline unsigned int Get(TypeWrapper,HSQUIRRELVM v,int idx) { intp i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } +inline long Get(TypeWrapper,HSQUIRRELVM v,int idx) { intp i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } +inline unsigned long Get(TypeWrapper,HSQUIRRELVM v,int idx) { intp i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } +inline float Get(TypeWrapper,HSQUIRRELVM v,int idx) { SQFloat f; SQPLUS_CHECK_GET(sq_getfloat(v,idx,&f)); return f; } +inline double Get(TypeWrapper,HSQUIRRELVM v,int idx) { SQFloat f; SQPLUS_CHECK_GET(sq_getfloat(v,idx,&f)); return static_cast(f); } +inline const SQChar * Get(TypeWrapper,HSQUIRRELVM v,int idx) { const SQChar * s; SQPLUS_CHECK_GET(sq_getstring(v,idx,&s)); return s; } +inline SquirrelNull Get(TypeWrapper,HSQUIRRELVM v,int idx) { (void)v, (void)idx; return SquirrelNull(); } +inline void * Get(TypeWrapper,HSQUIRRELVM v,int idx) { SQUserPointer p; SQPLUS_CHECK_GET(sq_getuserpointer(v,idx,&p)); return p; } +inline HSQUIRRELVM Get(TypeWrapper,HSQUIRRELVM v,int /*idx*/) { sq_poptop(v); return v; } // sq_poptop(v): remove UserData from stack so GetParamCount() matches normal behavior. +inline SquirrelObject Get(TypeWrapper,HSQUIRRELVM v,int idx) { HSQOBJECT o; SQPLUS_CHECK_GET(sq_getstackobj(v,idx,&o)); return SquirrelObject(o); } + +#ifdef SQPLUS_SUPPORT_STD_STRING +inline void Push(HSQUIRRELVM v,const std::string& value) { sq_pushstring(v,value.c_str(),-1); } +inline bool Match(TypeWrapper, HSQUIRRELVM v, int idx) { return sq_gettype(v,idx) == OT_STRING; } +inline std::string Get(TypeWrapper,HSQUIRRELVM v,int idx) { const SQChar * s; SQPLUS_CHECK_GET(sq_getstring(v,idx,&s)); return std::string(s); } +#endif + +// Added jflanglois suggestion, 8/20/06. jcs +#ifdef SQPLUS_SUPPORT_SQ_STD_STRING +typedef std::basic_string sq_std_string; +inline void Push(HSQUIRRELVM v,const sq_std_string & value) { sq_pushstring(v,value.c_str(),-1); } +inline bool Match(TypeWrapper, HSQUIRRELVM v, int idx) { return sq_gettype(v,idx) == OT_STRING; } +inline sq_std_string Get(TypeWrapper,HSQUIRRELVM v,int idx) { const SQChar * s; SQPLUS_CHECK_GET(sq_getstring(v,idx,&s)); return sq_std_string(s); } +#endif + +// GetRet() restores the stack for SquirrelFunction<>() calls. +template +inline RT GetRet(TypeWrapper,HSQUIRRELVM v,int idx) { RT ret = Get(TypeWrapper(),v,idx); sq_pop(v,2); return ret; } // sq_pop(v,2): restore stack after function call. + +// Specialization to support void return type. +inline void GetRet(TypeWrapper,HSQUIRRELVM v,int idx) { sq_pop(v,2); } + +// === END Function Call Handlers === + +// === Example SQClassDef usage (see testSqPlus2.cpp): === + +#if 0 + SQClassDef sqClass(_T("NewTestObj"); + sqClass.func(NewTestObj::newtestR1,_T("newtestR1")); + sqClass.var(&NewTestObj::val,_T("val")); + sqClass.var(&NewTestObj::s1,_T("s1")); + sqClass.var(&NewTestObj::s2,_T("s2")); + sqClass.funcVarArgs(&NewTestObj::multiArgs,_T("multiArgs")); + +// Shorthand form: + + SQClassDef(_T("NewTestObj"). + func(NewTestObj::newtestR1,_T("newtestR1")). + var(&NewTestObj::val,_T("val")). + var(&NewTestObj::s1,_T("s1")). + var(&NewTestObj::s2,_T("s2")). + funcVarArgs(NewTestObj::multiArgs,_T("multiArgs")); +#endif + +// === Macros for old style registration. SQClassDef registration is now easier to use (SQ_DECLARE_CLASS() is not needed) === + +#define SQ_DECLARE_CLASS(CLASSNAME) \ +static int _##CLASSNAME##_release(SQUserPointer up,SQInteger size) { \ + if (up) { \ + CLASSNAME * self = (CLASSNAME *)up; \ + delete self; \ + } \ + return 0; \ +} \ +static int _##CLASSNAME##_constructor(HSQUIRRELVM v) { \ + CLASSNAME * pc = new CLASSNAME(); \ + sq_setinstanceup(v,1,pc); \ + sq_setreleasehook(v,1,_##CLASSNAME##_release); \ + return 1; \ +} + +#define SQ_REGISTER_CLASS(CLASSNAME) \ + RegisterClassType(SquirrelVM::GetVMPtr(),_T(#CLASSNAME),_##CLASSNAME##_constructor) + +#define SQ_REGISTER_INSTANCE(NEWSQCLASS,CCLASS,FUNCNAME) \ + RegisterInstance(SquirrelVM::GetVMPtr(),NEWSQCLASS.GetObjectHandle(),*(CCLASS *)0,&CCLASS::FUNCNAME,_T(#FUNCNAME)); + +#define SQ_REGISTER_INSTANCE_VARARGS(NEWSQCLASS,CCLASS,FUNCNAME) \ + RegisterInstanceVarArgs(SquirrelVM::GetVMPtr(),NEWSQCLASS.GetObjectHandle(),*(CCLASS *)0,&CCLASS::FUNCNAME,_T(#FUNCNAME)); + +#define SQ_REGISTER_INSTANCE_VARIABLE(NEWSQCLASS,CCLASS,VARNAME) \ + RegisterInstanceVariable(NEWSQCLASS,&((CCLASS *)0)->VARNAME,_T(#VARNAME)); + +#if defined(USE_ARGUMENT_DEPENDANT_OVERLOADS) && defined(_MSC_VER) +#pragma warning (default:4675) +#endif + +}; // namespace SqPlus + + +// this include depends on SqPlus::Push(), and can't compile before that's declared in gcc +#include "SquirrelObjectImpl.h" + +#endif //_SQ_PLUS_H_ diff --git a/vscript/languages/squirrel/sqplus/sqplus.vcproj b/vscript/languages/squirrel/sqplus/sqplus.vcproj new file mode 100644 index 00000000..5e0ba2e8 --- /dev/null +++ b/vscript/languages/squirrel/sqplus/sqplus.vcproj @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/sqplus/sqplus71.vcproj b/vscript/languages/squirrel/sqplus/sqplus71.vcproj new file mode 100644 index 00000000..8a9c5aa4 --- /dev/null +++ b/vscript/languages/squirrel/sqplus/sqplus71.vcproj @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/sqplus/sqplusWin32.h b/vscript/languages/squirrel/sqplus/sqplusWin32.h new file mode 100644 index 00000000..bf46fd6c --- /dev/null +++ b/vscript/languages/squirrel/sqplus/sqplusWin32.h @@ -0,0 +1,7 @@ +#ifndef _SQ_PLUS_WIN32_H_ +#define _SQ_PLUS_WIN32_H_ + +#include "sqplus.h" +#include "SquirrelBindingsUtilsWin32.h" + +#endif //_SQ_PLUS_WIN32_H_ \ No newline at end of file diff --git a/vscript/languages/squirrel/sqstdlib/Makefile b/vscript/languages/squirrel/sqstdlib/Makefile new file mode 100644 index 00000000..c7771169 --- /dev/null +++ b/vscript/languages/squirrel/sqstdlib/Makefile @@ -0,0 +1,30 @@ +SQUIRREL= .. + + +OUT= $(SQUIRREL)/lib/libsqstdlib.a +INCZ= -I$(SQUIRREL)/include -I. -Iinclude + +SRCS= \ + sqstdblob.cpp \ + sqstdio.cpp \ + sqstdstream.cpp \ + sqstdmath.cpp \ + sqstdsystem.cpp \ + sqstdstring.cpp \ + sqstdaux.cpp \ + sqstdrex.cpp + + +sq32: + gcc -O2 -fno-rtti -Wall -c $(SRCS) $(INCZ) + ar rc $(OUT) *.o + rm *.o + +sqprof: + gcc -O2 -pg -fno-rtti -pie -gstabs -g3 -Wall -c $(SRCS) $(INCZ) + ar rc $(OUT) *.o + rm *.o +sq64: + gcc -O2 -D_SQ64 -fno-rtti -Wall -c $(SRCS) $(INCZ) + ar rc $(OUT) *.o + rm *.o diff --git a/vscript/languages/squirrel/sqstdlib/sqstdaux.cpp b/vscript/languages/squirrel/sqstdlib/sqstdaux.cpp new file mode 100644 index 00000000..cde1984b --- /dev/null +++ b/vscript/languages/squirrel/sqstdlib/sqstdaux.cpp @@ -0,0 +1,133 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#endif + +void sqstd_printcallstack(HSQUIRRELVM v) +{ + SQPRINTFUNCTION pf = sq_getprintfunc(v); + if(pf) { + SQStackInfos si; + SQInteger i; + SQBool b; + SQFloat f; + const SQChar *s; + SQInteger level=1; //1 is to skip this function that is level 0 + const SQChar *name=0; + SQInteger seq=0; + pf(v,_SC("\nCALLSTACK\n")); + while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si))) + { + const SQChar *fn=_SC("unknown"); + const SQChar *src=_SC("unknown"); + if(si.funcname)fn=si.funcname; + if(si.source)src=si.source; + pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line); + level++; + } + level=0; + pf(v,_SC("\nLOCALS\n")); + + for(level=0;level<10;level++){ + seq=0; + while((name = sq_getlocal(v,level,seq))) + { + seq++; + switch(sq_gettype(v,-1)) + { + case OT_NULL: + pf(v,_SC("[%s] NULL\n"),name); + break; + case OT_INTEGER: + sq_getinteger(v,-1,&i); + pf(v,_SC("[%s] %d\n"),name,i); + break; + case OT_FLOAT: + sq_getfloat(v,-1,&f); + pf(v,_SC("[%s] %.14g\n"),name,f); + break; + case OT_USERPOINTER: + pf(v,_SC("[%s] USERPOINTER\n"),name); + break; + case OT_STRING: + sq_getstring(v,-1,&s); + pf(v,_SC("[%s] \"%s\"\n"),name,s); + break; + case OT_TABLE: + pf(v,_SC("[%s] TABLE\n"),name); + break; + case OT_ARRAY: + pf(v,_SC("[%s] ARRAY\n"),name); + break; + case OT_CLOSURE: + pf(v,_SC("[%s] CLOSURE\n"),name); + break; + case OT_NATIVECLOSURE: + pf(v,_SC("[%s] NATIVECLOSURE\n"),name); + break; + case OT_GENERATOR: + pf(v,_SC("[%s] GENERATOR\n"),name); + break; + case OT_USERDATA: + pf(v,_SC("[%s] USERDATA\n"),name); + break; + case OT_THREAD: + pf(v,_SC("[%s] THREAD\n"),name); + break; + case OT_CLASS: + pf(v,_SC("[%s] CLASS\n"),name); + break; + case OT_INSTANCE: + pf(v,_SC("[%s] INSTANCE\n"),name); + break; + case OT_WEAKREF: + pf(v,_SC("[%s] WEAKREF\n"),name); + break; + case OT_BOOL:{ + sq_getbool(v,-1,&b); + pf(v,_SC("[%s] %s\n"),name,b?_SC("true"):_SC("false")); + } + break; + default: Assert(0); break; + } + sq_pop(v,1); + } + } + } +} + +static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v) +{ + SQPRINTFUNCTION pf = sq_getprintfunc(v); + if(pf) { + const SQChar *sErr = 0; + if(sq_gettop(v)>=1) { + if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) { + pf(v,_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr); + } + else{ + pf(v,_SC("\nAN ERROR HAS OCCURED [unknown]\n")); + } + sqstd_printcallstack(v); + } + } + return 0; +} + +void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column) +{ + SQPRINTFUNCTION pf = sq_getprintfunc(v); + if(pf) { + pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr); + } +} + +void sqstd_seterrorhandlers(HSQUIRRELVM v) +{ + sq_setcompilererrorhandler(v,_sqstd_compiler_error); + sq_newclosure(v,_sqstd_aux_printerror,0); + sq_seterrorhandler(v); +} diff --git a/vscript/languages/squirrel/sqstdlib/sqstdblob.cpp b/vscript/languages/squirrel/sqstdlib/sqstdblob.cpp new file mode 100644 index 00000000..30268a7f --- /dev/null +++ b/vscript/languages/squirrel/sqstdlib/sqstdblob.cpp @@ -0,0 +1,254 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include +#include "sqstdstream.h" +#include "sqstdblobimpl.h" +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#endif + +#define SQSTD_BLOB_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000002) + +//Blob + + +#define SETUP_BLOB(v) \ + SQBlob *self = NULL; \ + { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \ + return SQ_ERROR; } + + +static SQInteger _blob_resize(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger size; + sq_getinteger(v,2,&size); + if(!self->Resize(size)) + return sq_throwerror(v,_SC("resize failed")); + return 0; +} + +static void __swap_dword(unsigned int *n) +{ + *n=(unsigned int)(((*n&0xFF000000)>>24) | + ((*n&0x00FF0000)>>8) | + ((*n&0x0000FF00)<<8) | + ((*n&0x000000FF)<<24)); +} + +static void __swap_word(unsigned short *n) +{ + *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00); +} + +static SQInteger _blob_swap4(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger num=(self->Len()-(self->Len()%4))>>2; + unsigned int *t=(unsigned int *)self->GetBuf(); + for(SQInteger i = 0; i < num; i++) { + __swap_dword(&t[i]); + } + return 0; +} + +static SQInteger _blob_swap2(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger num=(self->Len()-(self->Len()%2))>>1; + unsigned short *t = (unsigned short *)self->GetBuf(); + for(SQInteger i = 0; i < num; i++) { + __swap_word(&t[i]); + } + return 0; +} + +static SQInteger _blob__set(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger idx,val; + sq_getinteger(v,2,&idx); + sq_getinteger(v,3,&val); + if(idx < 0 || idx >= self->Len()) + return sq_throwerror(v,_SC("index out of range")); + ((unsigned char *)self->GetBuf())[idx] = (unsigned char) val; + sq_push(v,3); + return 1; +} + +static SQInteger _blob__get(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger idx; + sq_getinteger(v,2,&idx); + if(idx < 0 || idx >= self->Len()) + return sq_throwerror(v,_SC("index out of range")); + sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]); + return 1; +} + +static SQInteger _blob__nexti(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + if(sq_gettype(v,2) == OT_NULL) { + sq_pushinteger(v, 0); + return 1; + } + SQInteger idx; + if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) { + if(idx+1 < self->Len()) { + sq_pushinteger(v, idx+1); + return 1; + } + sq_pushnull(v); + return 1; + } + return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type")); +} + +static SQInteger _blob__typeof(HSQUIRRELVM v) +{ + sq_pushstring(v,_SC("blob"),-1); + return 1; +} + +static SQInteger _blob_releasehook(SQUserPointer p, SQInteger size) +{ + SQBlob *self = (SQBlob*)p; + delete self; + return 1; +} + +static SQInteger _blob_constructor(HSQUIRRELVM v) +{ + SQInteger nparam = sq_gettop(v); + SQInteger size = 0; + if(nparam == 2) { + sq_getinteger(v, 2, &size); + } + if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size")); + SQBlob *b = new SQBlob(size); + if(SQ_FAILED(sq_setinstanceup(v,1,b))) { + delete b; + return sq_throwerror(v, _SC("cannot create blob with negative size")); + } + sq_setreleasehook(v,1,_blob_releasehook); + return 0; +} + +#define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck} +static SQRegFunction _blob_methods[] = { + _DECL_BLOB_FUNC(constructor,-1,_SC("xn")), + _DECL_BLOB_FUNC(resize,2,_SC("xn")), + _DECL_BLOB_FUNC(swap2,1,_SC("x")), + _DECL_BLOB_FUNC(swap4,1,_SC("x")), + _DECL_BLOB_FUNC(_set,3,_SC("xnn")), + _DECL_BLOB_FUNC(_get,2,_SC("xn")), + _DECL_BLOB_FUNC(_typeof,1,_SC("x")), + _DECL_BLOB_FUNC(_nexti,2,_SC("x")), + {0,0,0,0} +}; + + + +//GLOBAL FUNCTIONS + +static SQInteger _g_blob_casti2f(HSQUIRRELVM v) +{ + SQInteger i; + sq_getinteger(v,2,&i); + sq_pushfloat(v,*((SQFloat *)&i)); + return 1; +} + +static SQInteger _g_blob_castf2i(HSQUIRRELVM v) +{ + SQFloat f; + sq_getfloat(v,2,&f); + sq_pushinteger(v,*((SQInteger *)&f)); + return 1; +} + +static SQInteger _g_blob_swap2(HSQUIRRELVM v) +{ + SQInteger i; + sq_getinteger(v,2,&i); + short s=(short)i; + sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF)); + return 1; +} + +static SQInteger _g_blob_swap4(HSQUIRRELVM v) +{ + SQInteger i; + sq_getinteger(v,2,&i); + unsigned int t4 = (unsigned int)i; + __swap_dword(&t4); + sq_pushinteger(v,(SQInteger)t4); + return 1; +} + +static SQInteger _g_blob_swapfloat(HSQUIRRELVM v) +{ + SQFloat f; + sq_getfloat(v,2,&f); + __swap_dword((unsigned int *)&f); + sq_pushfloat(v,f); + return 1; +} + +#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck} +static SQRegFunction bloblib_funcs[]={ + _DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")), + _DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")), + _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")), + _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")), + _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")), + {0,0} +}; + +SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr) +{ + SQBlob *blob; + if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) + return -1; + *ptr = blob->GetBuf(); + return SQ_OK; +} + +SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx) +{ + SQBlob *blob; + if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) + return -1; + return blob->Len(); +} + +SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size) +{ + SQInteger top = sq_gettop(v); + sq_pushregistrytable(v); + sq_pushstring(v,_SC("std_blob"),-1); + if(SQ_SUCCEEDED(sq_get(v,-2))) { + sq_remove(v,-2); //removes the registry + sq_push(v,1); // push the this + sq_pushinteger(v,size); //size + SQBlob *blob = NULL; + if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse)) + && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) { + sq_remove(v,-2); + return blob->GetBuf(); + } + } + sq_settop(v,top); + return NULL; +} + +SQRESULT sqstd_register_bloblib(HSQUIRRELVM v) +{ + return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs); +} + diff --git a/vscript/languages/squirrel/sqstdlib/sqstdblobimpl.h b/vscript/languages/squirrel/sqstdlib/sqstdblobimpl.h new file mode 100644 index 00000000..9f22c0ae --- /dev/null +++ b/vscript/languages/squirrel/sqstdlib/sqstdblobimpl.h @@ -0,0 +1,108 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_BLOBIMPL_H_ +#define _SQSTD_BLOBIMPL_H_ + +struct SQBlob : public SQStream +{ + SQBlob(SQInteger size) { + _size = size; + _allocated = size; + _buf = (unsigned char *)sq_malloc(size); + memset(_buf, 0, _size); + _ptr = 0; + _owns = true; + } + virtual ~SQBlob() { + sq_free(_buf, _allocated); + } + SQInteger Write(void *buffer, SQInteger size) { + if(!CanAdvance(size)) { + GrowBufOf(_ptr + size - _size); + } + memcpy(&_buf[_ptr], buffer, size); + _ptr += size; + return size; + } + SQInteger Read(void *buffer,SQInteger size) { + SQInteger n = size; + if(!CanAdvance(size)) { + if((_size - _ptr) > 0) + n = _size - _ptr; + else return 0; + } + memcpy(buffer, &_buf[_ptr], n); + _ptr += n; + return n; + } + bool Resize(SQInteger n) { + if(!_owns) return false; + if(n != _allocated) { + unsigned char *newbuf = (unsigned char *)sq_malloc(n); + memset(newbuf,0,n); + if(_size > n) + memcpy(newbuf,_buf,n); + else + memcpy(newbuf,_buf,_size); + sq_free(_buf,_allocated); + _buf=newbuf; + _allocated = n; + if(_size > _allocated) + _size = _allocated; + if(_ptr > _allocated) + _ptr = _allocated; + } + return true; + } + bool GrowBufOf(SQInteger n) + { + bool ret = true; + if(_size + n > _allocated) { + if(_size + n > _size * 2) + ret = Resize(_size + n); + else + ret = Resize(_size * 2); + } + _size = _size + n; + return ret; + } + bool CanAdvance(SQInteger n) { + if(_ptr+n>_size)return false; + return true; + } + SQInteger Seek(SQInteger offset, SQInteger origin) { + switch(origin) { + case SQ_SEEK_SET: + if(offset > _size || offset < 0) return -1; + _ptr = offset; + break; + case SQ_SEEK_CUR: + if(_ptr + offset > _size || _ptr + offset < 0) return -1; + _ptr += offset; + break; + case SQ_SEEK_END: + if(_size + offset > _size || _size + offset < 0) return -1; + _ptr = _size + offset; + break; + default: return -1; + } + return 0; + } + bool IsValid() { + return _buf?true:false; + } + bool EOS() { + return _ptr == _size; + } + SQInteger Flush() { return 0; } + SQInteger Tell() { return _ptr; } + SQInteger Len() { return _size; } + SQUserPointer GetBuf(){ return _buf; } +private: + SQInteger _size; + SQInteger _allocated; + SQInteger _ptr; + unsigned char *_buf; + bool _owns; +}; + +#endif //_SQSTD_BLOBIMPL_H_ diff --git a/vscript/languages/squirrel/sqstdlib/sqstdio.cpp b/vscript/languages/squirrel/sqstdlib/sqstdio.cpp new file mode 100644 index 00000000..4a0a1840 --- /dev/null +++ b/vscript/languages/squirrel/sqstdlib/sqstdio.cpp @@ -0,0 +1,410 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include "sqstdstream.h" + +#define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001) +//basic API +SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode) +{ +#ifndef SQUNICODE + return (SQFILE)fopen(filename,mode); +#else + return (SQFILE)_wfopen(filename,mode); +#endif +} + +SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file) +{ + return (SQInteger)fread(buffer,size,count,(FILE *)file); +} + +SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file) +{ + return (SQInteger)fwrite(buffer,size,count,(FILE *)file); +} + +SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin) +{ + SQInteger realorigin; + switch(origin) { + case SQ_SEEK_CUR: realorigin = SEEK_CUR; break; + case SQ_SEEK_END: realorigin = SEEK_END; break; + case SQ_SEEK_SET: realorigin = SEEK_SET; break; + default: return -1; //failed + } + return fseek((FILE *)file,(long)offset,(int)realorigin); +} + +SQInteger sqstd_ftell(SQFILE file) +{ + return ftell((FILE *)file); +} + +SQInteger sqstd_fflush(SQFILE file) +{ + return fflush((FILE *)file); +} + +SQInteger sqstd_fclose(SQFILE file) +{ + return fclose((FILE *)file); +} + +SQInteger sqstd_feof(SQFILE file) +{ + return feof((FILE *)file); +} + +//File +struct SQFile : public SQStream { + SQFile() { _handle = NULL; _owns = false;} + SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;} + virtual ~SQFile() { Close(); } + bool Open(const SQChar *filename ,const SQChar *mode) { + Close(); + if( (_handle = sqstd_fopen(filename,mode)) ) { + _owns = true; + return true; + } + return false; + } + void Close() { + if(_handle && _owns) { + sqstd_fclose(_handle); + _handle = NULL; + _owns = false; + } + } + SQInteger Read(void *buffer,SQInteger size) { + return sqstd_fread(buffer,1,size,_handle); + } + SQInteger Write(void *buffer,SQInteger size) { + return sqstd_fwrite(buffer,1,size,_handle); + } + SQInteger Flush() { + return sqstd_fflush(_handle); + } + SQInteger Tell() { + return sqstd_ftell(_handle); + } + SQInteger Len() { + SQInteger prevpos=Tell(); + Seek(0,SQ_SEEK_END); + SQInteger size=Tell(); + Seek(prevpos,SQ_SEEK_SET); + return size; + } + SQInteger Seek(SQInteger offset, SQInteger origin) { + return sqstd_fseek(_handle,offset,origin); + } + bool IsValid() { return _handle?true:false; } + bool EOS() { return Tell()==Len()?true:false;} + SQFILE GetHandle() {return _handle;} +private: + SQFILE _handle; + bool _owns; +}; + +static SQInteger _file__typeof(HSQUIRRELVM v) +{ + sq_pushstring(v,_SC("file"),-1); + return 1; +} + +static SQInteger _file_releasehook(SQUserPointer p, SQInteger size) +{ + SQFile *self = (SQFile*)p; + delete self; + return 1; +} + +static SQInteger _file_constructor(HSQUIRRELVM v) +{ + const SQChar *filename,*mode; + bool owns = true; + SQFile *f; + SQFILE newf; + if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) { + sq_getstring(v, 2, &filename); + sq_getstring(v, 3, &mode); + newf = sqstd_fopen(filename, mode); + if(!newf) return sq_throwerror(v, _SC("cannot open file")); + } else if(sq_gettype(v,2) == OT_USERPOINTER) { + owns = !(sq_gettype(v,3) == OT_NULL); + sq_getuserpointer(v,2,&newf); + } else { + return sq_throwerror(v,_SC("wrong parameter")); + } + f = new SQFile(newf,owns); + if(SQ_FAILED(sq_setinstanceup(v,1,f))) { + delete f; + return sq_throwerror(v, _SC("cannot create blob with negative size")); + } + sq_setreleasehook(v,1,_file_releasehook); + return 0; +} + +//bindings +#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck} +static SQRegFunction _file_methods[] = { + _DECL_FILE_FUNC(constructor,3,_SC("x")), + _DECL_FILE_FUNC(_typeof,1,_SC("x")), + {0,0,0,0}, +}; + + + +SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own) +{ + SQInteger top = sq_gettop(v); + sq_pushregistrytable(v); + sq_pushstring(v,_SC("std_file"),-1); + if(SQ_SUCCEEDED(sq_get(v,-2))) { + sq_remove(v,-2); //removes the registry + sq_pushroottable(v); // push the this + sq_pushuserpointer(v,file); //file + if(own){ + sq_pushinteger(v,1); //true + } + else{ + sq_pushnull(v); //false + } + if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) { + sq_remove(v,-2); + return SQ_OK; + } + } + sq_settop(v,top); + return SQ_OK; +} + +SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file) +{ + SQFile *fileobj = NULL; + if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) { + *file = fileobj->GetHandle(); + return SQ_OK; + } + return sq_throwerror(v,_SC("not a file")); +} + + + +static SQInteger _io_file_lexfeed_ASCII(SQUserPointer file) +{ + SQInteger ret; + char c; + if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) + return c; + return 0; +} + +static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file) +{ +#define READ() \ + if(sqstd_fread(&inchar,sizeof(inchar),1,(FILE *)file) != 1) \ + return 0; + + static const SQInteger utf8_lengths[16] = + { + 1,1,1,1,1,1,1,1, /* 0000 to 0111 : 1 byte (plain ASCII) */ + 0,0,0,0, /* 1000 to 1011 : not valid */ + 2,2, /* 1100, 1101 : 2 bytes */ + 3, /* 1110 : 3 bytes */ + 4 /* 1111 :4 bytes */ + }; + static unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07}; + unsigned char inchar; + SQInteger c = 0; + READ(); + c = inchar; + // + if(c >= 0x80) { + SQInteger tmp; + SQInteger codelen = utf8_lengths[c>>4]; + if(codelen == 0) + return 0; + //"invalid UTF-8 stream"; + tmp = c&byte_masks[codelen]; + for(SQInteger n = 0; n < codelen-1; n++) { + tmp<<=6; + READ(); + tmp |= inchar & 0x3F; + } + c = tmp; + } + return c; +} + +static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer file) +{ + SQInteger ret; + wchar_t c; + if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) + return (SQChar)c; + return 0; +} + +static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer file) +{ + SQInteger ret; + unsigned short c; + if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) { + c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00); + return (SQChar)c; + } + return 0; +} + +SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size) +{ + SQInteger ret; + if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret; + return -1; +} + +SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size) +{ + return sqstd_fwrite(p,1,size,(SQFILE)file); +} + +SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror) +{ + SQFILE file = sqstd_fopen(filename,_SC("rb")); + SQInteger ret; + unsigned short us; + unsigned char uc; + SQLEXREADFUNC func = _io_file_lexfeed_ASCII; + if(file){ + ret = sqstd_fread(&us,1,2,file); + if(ret != 2) { + //probably an empty file + us = 0; + } + if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE + sqstd_fseek(file,0,SQ_SEEK_SET); + if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) { + sqstd_fclose(file); + return SQ_OK; + } + } + else { //SCRIPT + switch(us) + { + //gotta swap the next 2 lines on BIG endian machines + case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian; + case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian; + case 0xBBEF: + if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) { + sqstd_fclose(file); + return sq_throwerror(v,_SC("io error")); + } + if(uc != 0xBF) { + sqstd_fclose(file); + return sq_throwerror(v,_SC("Unrecognozed ecoding")); + } + func = _io_file_lexfeed_UTF8; + break;//UTF-8 ; + default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii + } + + if(SQ_SUCCEEDED(sq_compile(v,func,file,filename,printerror))){ + sqstd_fclose(file); + return SQ_OK; + } + } + sqstd_fclose(file); + return SQ_ERROR; + } + return sq_throwerror(v,_SC("cannot open the file")); +} + +SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror) +{ + if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) { + sq_push(v,-2); + if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) { + sq_remove(v,retval?-2:-1); //removes the closure + return 1; + } + sq_pop(v,1); //removes the closure + } + return SQ_ERROR; +} + +SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename) +{ + SQFILE file = sqstd_fopen(filename,_SC("wb+")); + if(!file) return sq_throwerror(v,_SC("cannot open the file")); + if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) { + sqstd_fclose(file); + return SQ_OK; + } + sqstd_fclose(file); + return SQ_ERROR; //forward the error +} + +SQInteger _g_io_loadfile(HSQUIRRELVM v) +{ + const SQChar *filename; + SQBool printerror = SQFalse; + sq_getstring(v,2,&filename); + if(sq_gettop(v) >= 3) { + sq_getbool(v,3,&printerror); + } + if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) + return 1; + return SQ_ERROR; //propagates the error +} + +SQInteger _g_io_writeclosuretofile(HSQUIRRELVM v) +{ + const SQChar *filename; + sq_getstring(v,2,&filename); + if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename))) + return 1; + return SQ_ERROR; //propagates the error +} + +SQInteger _g_io_dofile(HSQUIRRELVM v) +{ + const SQChar *filename; + SQBool printerror = SQFalse; + sq_getstring(v,2,&filename); + if(sq_gettop(v) >= 3) { + sq_getbool(v,3,&printerror); + } + sq_push(v,1); //repush the this + if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror))) + return 1; + return SQ_ERROR; //propagates the error +} + +#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck} +static SQRegFunction iolib_funcs[]={ + _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")), + _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")), + _DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")), + {0,0} +}; + +SQRESULT sqstd_register_iolib(HSQUIRRELVM v) +{ + SQInteger top = sq_gettop(v); + //create delegate + declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs); + sq_pushstring(v,_SC("stdout"),-1); + sqstd_createfile(v,stdout,SQFalse); + sq_createslot(v,-3); + sq_pushstring(v,_SC("stdin"),-1); + sqstd_createfile(v,stdin,SQFalse); + sq_createslot(v,-3); + sq_pushstring(v,_SC("stderr"),-1); + sqstd_createfile(v,stderr,SQFalse); + sq_createslot(v,-3); + sq_settop(v,top); + return SQ_OK; +} diff --git a/vscript/languages/squirrel/sqstdlib/sqstdlib.cbp b/vscript/languages/squirrel/sqstdlib/sqstdlib.cbp new file mode 100644 index 00000000..903a5c95 --- /dev/null +++ b/vscript/languages/squirrel/sqstdlib/sqstdlib.cbp @@ -0,0 +1,166 @@ + + + + + + + diff --git a/vscript/languages/squirrel/sqstdlib/sqstdlib.vcproj b/vscript/languages/squirrel/sqstdlib/sqstdlib.vcproj new file mode 100644 index 00000000..77a20f95 --- /dev/null +++ b/vscript/languages/squirrel/sqstdlib/sqstdlib.vcproj @@ -0,0 +1,666 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/sqstdlib/sqstdlib71.vcproj b/vscript/languages/squirrel/sqstdlib/sqstdlib71.vcproj new file mode 100644 index 00000000..365c7c91 --- /dev/null +++ b/vscript/languages/squirrel/sqstdlib/sqstdlib71.vcproj @@ -0,0 +1,503 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/sqstdlib/sqstdmath.cpp b/vscript/languages/squirrel/sqstdlib/sqstdmath.cpp new file mode 100644 index 00000000..69c46f51 --- /dev/null +++ b/vscript/languages/squirrel/sqstdlib/sqstdmath.cpp @@ -0,0 +1,106 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include + +#define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \ + SQFloat f; \ + sq_getfloat(v,2,&f); \ + sq_pushfloat(v,(SQFloat)_funcname(f)); \ + return 1; \ +} + +#define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \ + SQFloat p1,p2; \ + sq_getfloat(v,2,&p1); \ + sq_getfloat(v,3,&p2); \ + sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \ + return 1; \ +} + +static SQInteger math_srand(HSQUIRRELVM v) +{ + SQInteger i; + if(SQ_FAILED(sq_getinteger(v,2,&i))) + return sq_throwerror(v,_SC("invalid param")); + srand((unsigned int)i); + return 0; +} + +static SQInteger math_rand(HSQUIRRELVM v) +{ + sq_pushinteger(v,rand()); + return 1; +} + +static SQInteger math_abs(HSQUIRRELVM v) +{ + SQInteger n; + sq_getinteger(v,2,&n); + sq_pushinteger(v,(SQInteger)abs((int)n)); + return 1; +} + +SINGLE_ARG_FUNC(sqrt) +SINGLE_ARG_FUNC(fabs) +SINGLE_ARG_FUNC(sin) +SINGLE_ARG_FUNC(cos) +SINGLE_ARG_FUNC(asin) +SINGLE_ARG_FUNC(acos) +SINGLE_ARG_FUNC(log) +SINGLE_ARG_FUNC(log10) +SINGLE_ARG_FUNC(tan) +SINGLE_ARG_FUNC(atan) +TWO_ARGS_FUNC(atan2) +TWO_ARGS_FUNC(pow) +SINGLE_ARG_FUNC(floor) +SINGLE_ARG_FUNC(ceil) +SINGLE_ARG_FUNC(exp) + +#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck} +static SQRegFunction mathlib_funcs[] = { + _DECL_FUNC(sqrt,2,_SC(".n")), + _DECL_FUNC(sin,2,_SC(".n")), + _DECL_FUNC(cos,2,_SC(".n")), + _DECL_FUNC(asin,2,_SC(".n")), + _DECL_FUNC(acos,2,_SC(".n")), + _DECL_FUNC(log,2,_SC(".n")), + _DECL_FUNC(log10,2,_SC(".n")), + _DECL_FUNC(tan,2,_SC(".n")), + _DECL_FUNC(atan,2,_SC(".n")), + _DECL_FUNC(atan2,3,_SC(".nn")), + _DECL_FUNC(pow,3,_SC(".nn")), + _DECL_FUNC(floor,2,_SC(".n")), + _DECL_FUNC(ceil,2,_SC(".n")), + _DECL_FUNC(exp,2,_SC(".n")), + _DECL_FUNC(srand,2,_SC(".n")), + _DECL_FUNC(rand,1,NULL), + _DECL_FUNC(fabs,2,_SC(".n")), + _DECL_FUNC(abs,2,_SC(".n")), + {0,0}, +}; + +#ifndef M_PI +#define M_PI (3.14159265358979323846) +#endif + +SQRESULT sqstd_register_mathlib(HSQUIRRELVM v) +{ + SQInteger i=0; + while(mathlib_funcs[i].name!=0) { + sq_pushstring(v,mathlib_funcs[i].name,-1); + sq_newclosure(v,mathlib_funcs[i].f,0); + sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask); + sq_setnativeclosurename(v,-1,mathlib_funcs[i].name); + sq_createslot(v,-3); + i++; + } + sq_pushstring(v,_SC("RAND_MAX"),-1); + sq_pushinteger(v,RAND_MAX); + sq_createslot(v,-3); + sq_pushstring(v,_SC("PI"),-1); + sq_pushfloat(v,(SQFloat)M_PI); + sq_createslot(v,-3); + return SQ_OK; +} diff --git a/vscript/languages/squirrel/sqstdlib/sqstdrex.cpp b/vscript/languages/squirrel/sqstdlib/sqstdrex.cpp new file mode 100644 index 00000000..3bbd43c5 --- /dev/null +++ b/vscript/languages/squirrel/sqstdlib/sqstdrex.cpp @@ -0,0 +1,640 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include "sqstdstring.h" +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#endif + +#ifdef _UINCODE +#define scisprint iswprint +#else +#define scisprint isprint +#endif + +#ifdef DEBUG_SQSTDREX +#include + +static const SQChar *g_nnames[] = +{ + _SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"), + _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"), + _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"), + _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB") +}; + +#endif + +#define OP_GREEDY (MAX_CHAR+1) // * + ? {n} +#define OP_OR (MAX_CHAR+2) +#define OP_EXPR (MAX_CHAR+3) //parentesis () +#define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:) +#define OP_DOT (MAX_CHAR+5) +#define OP_CLASS (MAX_CHAR+6) +#define OP_CCLASS (MAX_CHAR+7) +#define OP_NCLASS (MAX_CHAR+8) //negates class the [^ +#define OP_RANGE (MAX_CHAR+9) +#define OP_CHAR (MAX_CHAR+10) +#define OP_EOL (MAX_CHAR+11) +#define OP_BOL (MAX_CHAR+12) +#define OP_WB (MAX_CHAR+13) + +#define SQREX_SYMBOL_ANY_CHAR ('.') +#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE ('+') +#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*') +#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?') +#define SQREX_SYMBOL_BRANCH ('|') +#define SQREX_SYMBOL_END_OF_STRING ('$') +#define SQREX_SYMBOL_BEGINNING_OF_STRING ('^') +#define SQREX_SYMBOL_ESCAPE_CHAR ('\\') + + +typedef int SQRexNodeType; + +typedef struct tagSQRexNode{ + SQRexNodeType type; + SQInteger left; + SQInteger right; + SQInteger next; +}SQRexNode; + +struct SQRex{ + const SQChar *_eol; + const SQChar *_bol; + const SQChar *_p; + SQInteger _first; + SQInteger _op; + SQRexNode *_nodes; + SQInteger _nallocated; + SQInteger _nsize; + SQInteger _nsubexpr; + SQRexMatch *_matches; + SQInteger _currsubexp; + void *_jmpbuf; + const SQChar **_error; +}; + +static SQInteger sqstd_rex_list(SQRex *exp); + +static SQInteger sqstd_rex_newnode(SQRex *exp, SQRexNodeType type) +{ + SQRexNode n; + n.type = type; + n.next = n.right = n.left = -1; + if(type == OP_EXPR) + n.right = exp->_nsubexpr++; + if(exp->_nallocated < (exp->_nsize + 1)) { + SQInteger oldsize = exp->_nallocated; + exp->_nallocated *= 2; + exp->_nodes = (SQRexNode *)sq_realloc(exp->_nodes, oldsize * sizeof(SQRexNode) ,exp->_nallocated * sizeof(SQRexNode)); + } + exp->_nodes[exp->_nsize++] = n; + SQInteger newid = exp->_nsize - 1; + return (SQInteger)newid; +} + +static void sqstd_rex_error(SQRex *exp,const SQChar *error) +{ + if(exp->_error) *exp->_error = error; + longjmp(*((jmp_buf*)exp->_jmpbuf),-1); +} + +static void sqstd_rex_expect(SQRex *exp, SQInteger n){ + if((*exp->_p) != n) + sqstd_rex_error(exp, _SC("expected paren")); + exp->_p++; +} + +static SQChar sqstd_rex_escapechar(SQRex *exp) +{ + if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR){ + exp->_p++; + switch(*exp->_p) { + case 'v': exp->_p++; return '\v'; + case 'n': exp->_p++; return '\n'; + case 't': exp->_p++; return '\t'; + case 'r': exp->_p++; return '\r'; + case 'f': exp->_p++; return '\f'; + default: return (*exp->_p++); + } + } else if(!scisprint(*exp->_p)) sqstd_rex_error(exp,_SC("letter expected")); + return (*exp->_p++); +} + +static SQInteger sqstd_rex_charclass(SQRex *exp,SQInteger classid) +{ + SQInteger n = sqstd_rex_newnode(exp,OP_CCLASS); + exp->_nodes[n].left = classid; + return n; +} + +static SQInteger sqstd_rex_charnode(SQRex *exp,SQBool isclass) +{ + SQChar t; + if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR) { + exp->_p++; + switch(*exp->_p) { + case 'n': exp->_p++; return sqstd_rex_newnode(exp,'\n'); + case 't': exp->_p++; return sqstd_rex_newnode(exp,'\t'); + case 'r': exp->_p++; return sqstd_rex_newnode(exp,'\r'); + case 'f': exp->_p++; return sqstd_rex_newnode(exp,'\f'); + case 'v': exp->_p++; return sqstd_rex_newnode(exp,'\v'); + case 'a': case 'A': case 'w': case 'W': case 's': case 'S': + case 'd': case 'D': case 'x': case 'X': case 'c': case 'C': + case 'p': case 'P': case 'l': case 'u': + { + t = *exp->_p; exp->_p++; + return sqstd_rex_charclass(exp,t); + } + case 'b': + case 'B': + if(!isclass) { + SQInteger node = sqstd_rex_newnode(exp,OP_WB); + exp->_nodes[node].left = *exp->_p; + exp->_p++; + return node; + } //else default + default: + t = *exp->_p; exp->_p++; + return sqstd_rex_newnode(exp,t); + } + } + else if(!scisprint(*exp->_p)) { + + sqstd_rex_error(exp,_SC("letter expected")); + } + t = *exp->_p; exp->_p++; + return sqstd_rex_newnode(exp,t); +} +static SQInteger sqstd_rex_class(SQRex *exp) +{ + SQInteger ret = -1; + SQInteger first = -1,chain; + if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING){ + ret = sqstd_rex_newnode(exp,OP_NCLASS); + exp->_p++; + }else ret = sqstd_rex_newnode(exp,OP_CLASS); + + if(*exp->_p == ']') sqstd_rex_error(exp,_SC("empty class")); + chain = ret; + while(*exp->_p != ']' && exp->_p != exp->_eol) { + if(*exp->_p == '-' && first != -1){ + SQInteger r; + if(*exp->_p++ == ']') sqstd_rex_error(exp,_SC("unfinished range")); + r = sqstd_rex_newnode(exp,OP_RANGE); + if(first>*exp->_p) sqstd_rex_error(exp,_SC("invalid range")); + if(exp->_nodes[first].type == OP_CCLASS) sqstd_rex_error(exp,_SC("cannot use character classes in ranges")); + exp->_nodes[r].left = exp->_nodes[first].type; + SQInteger t = sqstd_rex_escapechar(exp); + exp->_nodes[r].right = t; + exp->_nodes[chain].next = r; + chain = r; + first = -1; + } + else{ + if(first!=-1){ + SQInteger c = first; + exp->_nodes[chain].next = c; + chain = c; + first = sqstd_rex_charnode(exp,SQTrue); + } + else{ + first = sqstd_rex_charnode(exp,SQTrue); + } + } + } + if(first!=-1){ + SQInteger c = first; + exp->_nodes[chain].next = c; + chain = c; + first = -1; + } + /* hack? */ + exp->_nodes[ret].left = exp->_nodes[ret].next; + exp->_nodes[ret].next = -1; + return ret; +} + +static SQInteger sqstd_rex_parsenumber(SQRex *exp) +{ + SQInteger ret = *exp->_p-'0'; + SQInteger positions = 10; + exp->_p++; + while(isdigit(*exp->_p)) { + ret = ret*10+(*exp->_p++-'0'); + if(positions==1000000000) sqstd_rex_error(exp,_SC("overflow in numeric constant")); + positions *= 10; + }; + return ret; +} + +static SQInteger sqstd_rex_element(SQRex *exp) +{ + SQInteger ret = -1; + switch(*exp->_p) + { + case '(': { + SQInteger expr; + exp->_p++; + + + if(*exp->_p =='?') { + exp->_p++; + sqstd_rex_expect(exp,':'); + expr = sqstd_rex_newnode(exp,OP_NOCAPEXPR); + } + else + expr = sqstd_rex_newnode(exp,OP_EXPR); + SQInteger newn = sqstd_rex_list(exp); + exp->_nodes[expr].left = newn; + ret = expr; + sqstd_rex_expect(exp,')'); + } + break; + case '[': + exp->_p++; + ret = sqstd_rex_class(exp); + sqstd_rex_expect(exp,']'); + break; + case SQREX_SYMBOL_END_OF_STRING: exp->_p++; ret = sqstd_rex_newnode(exp,OP_EOL);break; + case SQREX_SYMBOL_ANY_CHAR: exp->_p++; ret = sqstd_rex_newnode(exp,OP_DOT);break; + default: + ret = sqstd_rex_charnode(exp,SQFalse); + break; + } + + + SQInteger op; + SQBool isgreedy = SQFalse; + unsigned short p0 = 0, p1 = 0; + switch(*exp->_p){ + case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break; + case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break; + case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = SQTrue; break; + case '{': + exp->_p++; + if(!isdigit(*exp->_p)) sqstd_rex_error(exp,_SC("number expected")); + p0 = (unsigned short)sqstd_rex_parsenumber(exp); + /*******************************/ + switch(*exp->_p) { + case '}': + p1 = p0; exp->_p++; + break; + case ',': + exp->_p++; + p1 = 0xFFFF; + if(isdigit(*exp->_p)){ + p1 = (unsigned short)sqstd_rex_parsenumber(exp); + } + sqstd_rex_expect(exp,'}'); + break; + default: + sqstd_rex_error(exp,_SC(", or } expected")); + } + /*******************************/ + isgreedy = SQTrue; + break; + + } + if(isgreedy) { + SQInteger nnode = sqstd_rex_newnode(exp,OP_GREEDY); + op = OP_GREEDY; + exp->_nodes[nnode].left = ret; + exp->_nodes[nnode].right = ((p0)<<16)|p1; + ret = nnode; + } + + if((*exp->_p != SQREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != SQREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != SQREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) { + SQInteger nnode = sqstd_rex_element(exp); + exp->_nodes[ret].next = nnode; + } + + return ret; +} + +static SQInteger sqstd_rex_list(SQRex *exp) +{ + SQInteger ret=-1,e; + if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING) { + exp->_p++; + ret = sqstd_rex_newnode(exp,OP_BOL); + } + e = sqstd_rex_element(exp); + if(ret != -1) { + exp->_nodes[ret].next = e; + } + else ret = e; + + if(*exp->_p == SQREX_SYMBOL_BRANCH) { + SQInteger temp,tright; + exp->_p++; + temp = sqstd_rex_newnode(exp,OP_OR); + exp->_nodes[temp].left = ret; + tright = sqstd_rex_list(exp); + exp->_nodes[temp].right = tright; + ret = temp; + } + return ret; +} + +static SQBool sqstd_rex_matchcclass(SQInteger cclass,SQChar c) +{ + switch(cclass) { + case 'a': return isalpha(c)?SQTrue:SQFalse; + case 'A': return !isalpha(c)?SQTrue:SQFalse; + case 'w': return (isalnum(c) || c == '_')?SQTrue:SQFalse; + case 'W': return (!isalnum(c) && c != '_')?SQTrue:SQFalse; + case 's': return isspace(c)?SQTrue:SQFalse; + case 'S': return !isspace(c)?SQTrue:SQFalse; + case 'd': return isdigit(c)?SQTrue:SQFalse; + case 'D': return !isdigit(c)?SQTrue:SQFalse; + case 'x': return isxdigit(c)?SQTrue:SQFalse; + case 'X': return !isxdigit(c)?SQTrue:SQFalse; + case 'c': return iscntrl(c)?SQTrue:SQFalse; + case 'C': return !iscntrl(c)?SQTrue:SQFalse; + case 'p': return ispunct(c)?SQTrue:SQFalse; + case 'P': return !ispunct(c)?SQTrue:SQFalse; + case 'l': return islower(c)?SQTrue:SQFalse; + case 'u': return isupper(c)?SQTrue:SQFalse; + } + return SQFalse; /*cannot happen*/ +} + +static SQBool sqstd_rex_matchclass(SQRex* exp,SQRexNode *node,SQChar c) +{ + do { + switch(node->type) { + case OP_RANGE: + if(c >= node->left && c <= node->right) return SQTrue; + break; + case OP_CCLASS: + if(sqstd_rex_matchcclass(node->left,c)) return SQTrue; + break; + default: + if(c == node->type)return SQTrue; + } + } while((node->next != -1) && (node = &exp->_nodes[node->next])); + return SQFalse; +} + +static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar *str,SQRexNode *next) +{ + + SQRexNodeType type = node->type; + switch(type) { + case OP_GREEDY: { + //SQRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL; + SQRexNode *greedystop = NULL; + SQInteger p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0; + const SQChar *s=str, *good = str; + + if(node->next != -1) { + greedystop = &exp->_nodes[node->next]; + } + else { + greedystop = next; + } + + while((nmaches == 0xFFFF || nmaches < p1)) { + + const SQChar *stop; + if(!(s = sqstd_rex_matchnode(exp,&exp->_nodes[node->left],s,greedystop))) + break; + nmaches++; + good=s; + if(greedystop) { + //checks that 0 matches satisfy the expression(if so skips) + //if not would always stop(for instance if is a '?') + if(greedystop->type != OP_GREEDY || + (greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0)) + { + SQRexNode *gnext = NULL; + if(greedystop->next != -1) { + gnext = &exp->_nodes[greedystop->next]; + }else if(next && next->next != -1){ + gnext = &exp->_nodes[next->next]; + } + stop = sqstd_rex_matchnode(exp,greedystop,s,gnext); + if(stop) { + //if satisfied stop it + if(p0 == p1 && p0 == nmaches) break; + else if(nmaches >= p0 && p1 == 0xFFFF) break; + else if(nmaches >= p0 && nmaches <= p1) break; + } + } + } + + if(s >= exp->_eol) + break; + } + if(p0 == p1 && p0 == nmaches) return good; + else if(nmaches >= p0 && p1 == 0xFFFF) return good; + else if(nmaches >= p0 && nmaches <= p1) return good; + return NULL; + } + case OP_OR: { + const SQChar *asd = str; + SQRexNode *temp=&exp->_nodes[node->left]; + while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) { + if(temp->next != -1) + temp = &exp->_nodes[temp->next]; + else + return asd; + } + asd = str; + temp = &exp->_nodes[node->right]; + while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) { + if(temp->next != -1) + temp = &exp->_nodes[temp->next]; + else + return asd; + } + return NULL; + break; + } + case OP_EXPR: + case OP_NOCAPEXPR:{ + SQRexNode *n = &exp->_nodes[node->left]; + const SQChar *cur = str; + SQInteger capture = -1; + if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) { + capture = exp->_currsubexp; + exp->_matches[capture].begin = cur; + exp->_currsubexp++; + } + + do { + SQRexNode *subnext = NULL; + if(n->next != -1) { + subnext = &exp->_nodes[n->next]; + }else { + subnext = next; + } + if(!(cur = sqstd_rex_matchnode(exp,n,cur,subnext))) { + if(capture != -1){ + exp->_matches[capture].begin = 0; + exp->_matches[capture].len = 0; + } + return NULL; + } + } while((n->next != -1) && (n = &exp->_nodes[n->next])); + + if(capture != -1) + exp->_matches[capture].len = cur - exp->_matches[capture].begin; + return cur; + } + case OP_WB: + if(str == exp->_bol && !isspace(*str) + || (str == exp->_eol && !isspace(*(str-1))) + || (!isspace(*str) && isspace(*(str+1))) + || (isspace(*str) && !isspace(*(str+1))) ) { + return (node->left == 'b')?str:NULL; + } + return (node->left == 'b')?NULL:str; + case OP_BOL: + if(str == exp->_bol) return str; + return NULL; + case OP_EOL: + if(str == exp->_eol) return str; + return NULL; + case OP_DOT:{ + str++; + } + return str; + case OP_NCLASS: + case OP_CLASS: + if(sqstd_rex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?SQTrue:SQFalse):(type == OP_NCLASS?SQTrue:SQFalse)) { + str++; + return str; + } + return NULL; + case OP_CCLASS: + if(sqstd_rex_matchcclass(node->left,*str)) { + str++; + return str; + } + return NULL; + default: /* char */ + if(*str != node->type) return NULL; + str++; + return str; + } + return NULL; +} + +/* public api */ +SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error) +{ + SQRex *exp = (SQRex *)sq_malloc(sizeof(SQRex)); + exp->_eol = exp->_bol = NULL; + exp->_p = pattern; + exp->_nallocated = (SQInteger)scstrlen(pattern) * sizeof(SQChar); + exp->_nodes = (SQRexNode *)sq_malloc(exp->_nallocated * sizeof(SQRexNode)); + exp->_nsize = 0; + exp->_matches = 0; + exp->_nsubexpr = 0; + exp->_first = sqstd_rex_newnode(exp,OP_EXPR); + exp->_error = error; + exp->_jmpbuf = sq_malloc(sizeof(jmp_buf)); + if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) { + SQInteger res = sqstd_rex_list(exp); + exp->_nodes[exp->_first].left = res; + if(*exp->_p!='\0') + sqstd_rex_error(exp,_SC("unexpected character")); +#ifdef DEBUG_SQSTDREX + { + SQInteger nsize,i; + SQRexNode *t; + nsize = exp->_nsize; + t = &exp->_nodes[0]; + scprintf(_SC("\n")); + for(i = 0;i < nsize; i++) { + if(exp->_nodes[i].type>MAX_CHAR) + scprintf(_SC("[%02d] %10s "),i,g_nnames[exp->_nodes[i].type-MAX_CHAR]); + else + scprintf(_SC("[%02d] %10c "),i,exp->_nodes[i].type); + scprintf(_SC("left %02d right %02d next %02d\n"),exp->_nodes[i].left,exp->_nodes[i].right,exp->_nodes[i].next); + } + scprintf(_SC("\n")); + } +#endif + exp->_matches = (SQRexMatch *) sq_malloc(exp->_nsubexpr * sizeof(SQRexMatch)); + memset(exp->_matches,0,exp->_nsubexpr * sizeof(SQRexMatch)); + } + else{ + sqstd_rex_free(exp); + return NULL; + } + return exp; +} + +void sqstd_rex_free(SQRex *exp) +{ + if(exp) { + if(exp->_nodes) sq_free(exp->_nodes,exp->_nallocated * sizeof(SQRexNode)); + if(exp->_jmpbuf) sq_free(exp->_jmpbuf,sizeof(jmp_buf)); + if(exp->_matches) sq_free(exp->_matches,exp->_nsubexpr * sizeof(SQRexMatch)); + sq_free(exp,sizeof(SQRex)); + } +} + +SQBool sqstd_rex_match(SQRex* exp,const SQChar* text) +{ + const SQChar* res = NULL; + exp->_bol = text; + exp->_eol = text + scstrlen(text); + exp->_currsubexp = 0; + res = sqstd_rex_matchnode(exp,exp->_nodes,text,NULL); + if(res == NULL || res != exp->_eol) + return SQFalse; + return SQTrue; +} + +SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end) +{ + const SQChar *cur = NULL; + SQInteger node = exp->_first; + if(text_begin >= text_end) return SQFalse; + exp->_bol = text_begin; + exp->_eol = text_end; + do { + cur = text_begin; + while(node != -1) { + exp->_currsubexp = 0; + cur = sqstd_rex_matchnode(exp,&exp->_nodes[node],cur,NULL); + if(!cur) + break; + node = exp->_nodes[node].next; + } + text_begin++; + } while(cur == NULL && text_begin != text_end); + + if(cur == NULL) + return SQFalse; + + --text_begin; + + if(out_begin) *out_begin = text_begin; + if(out_end) *out_end = cur; + return SQTrue; +} + +SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end) +{ + return sqstd_rex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end); +} + +SQInteger sqstd_rex_getsubexpcount(SQRex* exp) +{ + return exp->_nsubexpr; +} + +SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp) +{ + if( n<0 || n >= exp->_nsubexpr) return SQFalse; + *subexp = exp->_matches[n]; + return SQTrue; +} + diff --git a/vscript/languages/squirrel/sqstdlib/sqstdstream.cpp b/vscript/languages/squirrel/sqstdlib/sqstdstream.cpp new file mode 100644 index 00000000..94db81db --- /dev/null +++ b/vscript/languages/squirrel/sqstdlib/sqstdstream.cpp @@ -0,0 +1,333 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include +#include +#include +#include "sqstdstream.h" +#include "sqstdblobimpl.h" +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#endif + +#define SETUP_STREAM(v) \ + SQStream *self = NULL; \ + if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \ + return sq_throwerror(v,_SC("invalid type tag")); \ + if(!self->IsValid()) \ + return sq_throwerror(v,_SC("the stream is invalid")); + +SQInteger _stream_readblob(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + SQUserPointer data,blobp; + SQInteger size,res; + sq_getinteger(v,2,&size); + if(size > self->Len()) { + size = self->Len(); + } + data = sq_getscratchpad(v,size); + res = self->Read(data,size); + if(res <= 0) + return sq_throwerror(v,_SC("no data left to read")); + blobp = sqstd_createblob(v,res); + memcpy(blobp,data,res); + return 1; +} + +#define SAFE_READN(ptr,len) { \ + if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \ + } +SQInteger _stream_readn(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + SQInteger format; + sq_getinteger(v, 2, &format); + switch(format) { + case 'l': { + SQInteger i; + SAFE_READN(&i, sizeof(i)); + sq_pushinteger(v, i); + } + break; + case 'i': { + SQInt32 i; + SAFE_READN(&i, sizeof(i)); + sq_pushinteger(v, i); + } + break; + case 's': { + short s; + SAFE_READN(&s, sizeof(short)); + sq_pushinteger(v, s); + } + break; + case 'w': { + unsigned short w; + SAFE_READN(&w, sizeof(unsigned short)); + sq_pushinteger(v, w); + } + break; + case 'c': { + char c; + SAFE_READN(&c, sizeof(char)); + sq_pushinteger(v, c); + } + break; + case 'b': { + unsigned char c; + SAFE_READN(&c, sizeof(unsigned char)); + sq_pushinteger(v, c); + } + break; + case 'f': { + float f; + SAFE_READN(&f, sizeof(float)); + sq_pushfloat(v, f); + } + break; + case 'd': { + double d; + SAFE_READN(&d, sizeof(double)); + sq_pushfloat(v, (SQFloat)d); + } + break; + default: + return sq_throwerror(v, _SC("invalid format")); + } + return 1; +} + +SQInteger _stream_writeblob(HSQUIRRELVM v) +{ + SQUserPointer data; + SQInteger size; + SETUP_STREAM(v); + if(SQ_FAILED(sqstd_getblob(v,2,&data))) + return sq_throwerror(v,_SC("invalid parameter")); + size = sqstd_getblobsize(v,2); + if(self->Write(data,size) != size) + return sq_throwerror(v,_SC("io error")); + sq_pushinteger(v,size); + return 1; +} + +SQInteger _stream_writen(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + SQInteger format, ti; + SQFloat tf; + sq_getinteger(v, 3, &format); + switch(format) { + case 'l': { + SQInteger i; + sq_getinteger(v, 2, &ti); + i = ti; + self->Write(&i, sizeof(SQInteger)); + } + break; + case 'i': { + SQInt32 i; + sq_getinteger(v, 2, &ti); + i = (SQInt32)ti; + self->Write(&i, sizeof(SQInt32)); + } + break; + case 's': { + short s; + sq_getinteger(v, 2, &ti); + s = (short)ti; + self->Write(&s, sizeof(short)); + } + break; + case 'w': { + unsigned short w; + sq_getinteger(v, 2, &ti); + w = (unsigned short)ti; + self->Write(&w, sizeof(unsigned short)); + } + break; + case 'c': { + char c; + sq_getinteger(v, 2, &ti); + c = (char)ti; + self->Write(&c, sizeof(char)); + } + break; + case 'b': { + unsigned char b; + sq_getinteger(v, 2, &ti); + b = (unsigned char)ti; + self->Write(&b, sizeof(unsigned char)); + } + break; + case 'f': { + float f; + sq_getfloat(v, 2, &tf); + f = (float)tf; + self->Write(&f, sizeof(float)); + } + break; + case 'd': { + double d; + sq_getfloat(v, 2, &tf); + d = tf; + self->Write(&d, sizeof(double)); + } + break; + default: + return sq_throwerror(v, _SC("invalid format")); + } + return 0; +} + +SQInteger _stream_seek(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + SQInteger offset, origin = SQ_SEEK_SET; + sq_getinteger(v, 2, &offset); + if(sq_gettop(v) > 2) { + SQInteger t; + sq_getinteger(v, 3, &t); + switch(t) { + case 'b': origin = SQ_SEEK_SET; break; + case 'c': origin = SQ_SEEK_CUR; break; + case 'e': origin = SQ_SEEK_END; break; + default: return sq_throwerror(v,_SC("invalid origin")); + } + } + sq_pushinteger(v, self->Seek(offset, origin)); + return 1; +} + +SQInteger _stream_tell(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + sq_pushinteger(v, self->Tell()); + return 1; +} + +SQInteger _stream_len(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + sq_pushinteger(v, self->Len()); + return 1; +} + +SQInteger _stream_flush(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + if(!self->Flush()) + sq_pushinteger(v, 1); + else + sq_pushnull(v); + return 1; +} + +SQInteger _stream_eos(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + if(self->EOS()) + sq_pushinteger(v, 1); + else + sq_pushnull(v); + return 1; +} + +static SQRegFunction _stream_methods[] = { + _DECL_STREAM_FUNC(readblob,2,_SC("xn")), + _DECL_STREAM_FUNC(readn,2,_SC("xn")), + _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")), + _DECL_STREAM_FUNC(writen,3,_SC("xnn")), + _DECL_STREAM_FUNC(seek,-2,_SC("xnn")), + _DECL_STREAM_FUNC(tell,1,_SC("x")), + _DECL_STREAM_FUNC(len,1,_SC("x")), + _DECL_STREAM_FUNC(eos,1,_SC("x")), + _DECL_STREAM_FUNC(flush,1,_SC("x")), + {0,0} +}; + +void init_streamclass(HSQUIRRELVM v) +{ + sq_pushregistrytable(v); + sq_pushstring(v,_SC("std_stream"),-1); + if(SQ_FAILED(sq_get(v,-2))) { + sq_pushstring(v,_SC("std_stream"),-1); + sq_newclass(v,SQFalse); + sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG); + SQInteger i = 0; + while(_stream_methods[i].name != 0) { + SQRegFunction &f = _stream_methods[i]; + sq_pushstring(v,f.name,-1); + sq_newclosure(v,f.f,0); + sq_setparamscheck(v,f.nparamscheck,f.typemask); + sq_createslot(v,-3); + i++; + } + sq_createslot(v,-3); + sq_pushroottable(v); + sq_pushstring(v,_SC("stream"),-1); + sq_pushstring(v,_SC("std_stream"),-1); + sq_get(v,-4); + sq_createslot(v,-3); + sq_pop(v,1); + } + else { + sq_pop(v,1); //result + } + sq_pop(v,1); +} + +SQRESULT declare_stream(HSQUIRRELVM v,SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals) +{ + if(sq_gettype(v,-1) != OT_TABLE) + return sq_throwerror(v,_SC("table expected")); + SQInteger top = sq_gettop(v); + //create delegate + init_streamclass(v); + sq_pushregistrytable(v); + sq_pushstring(v,reg_name,-1); + sq_pushstring(v,_SC("std_stream"),-1); + if(SQ_SUCCEEDED(sq_get(v,-3))) { + sq_newclass(v,SQTrue); + sq_settypetag(v,-1,typetag); + SQInteger i = 0; + while(methods[i].name != 0) { + SQRegFunction &f = methods[i]; + sq_pushstring(v,f.name,-1); + sq_newclosure(v,f.f,0); + sq_setparamscheck(v,f.nparamscheck,f.typemask); + sq_setnativeclosurename(v,-1,f.name); + sq_createslot(v,-3); + i++; + } + sq_createslot(v,-3); + sq_pop(v,1); + + i = 0; + while(globals[i].name!=0) + { + SQRegFunction &f = globals[i]; + sq_pushstring(v,f.name,-1); + sq_newclosure(v,f.f,0); + sq_setparamscheck(v,f.nparamscheck,f.typemask); + sq_setnativeclosurename(v,-1,f.name); + sq_createslot(v,-3); + i++; + } + //register the class in the target table + sq_pushstring(v,name,-1); + sq_pushregistrytable(v); + sq_pushstring(v,reg_name,-1); + sq_get(v,-2); + sq_remove(v,-2); + sq_createslot(v,-3); + + sq_settop(v,top); + return SQ_OK; + } + sq_settop(v,top); + return SQ_ERROR; +} diff --git a/vscript/languages/squirrel/sqstdlib/sqstdstream.h b/vscript/languages/squirrel/sqstdlib/sqstdstream.h new file mode 100644 index 00000000..2763ccb1 --- /dev/null +++ b/vscript/languages/squirrel/sqstdlib/sqstdstream.h @@ -0,0 +1,18 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_STREAM_H_ +#define _SQSTD_STREAM_H_ + +SQInteger _stream_readblob(HSQUIRRELVM v); +SQInteger _stream_readline(HSQUIRRELVM v); +SQInteger _stream_readn(HSQUIRRELVM v); +SQInteger _stream_writeblob(HSQUIRRELVM v); +SQInteger _stream_writen(HSQUIRRELVM v); +SQInteger _stream_seek(HSQUIRRELVM v); +SQInteger _stream_tell(HSQUIRRELVM v); +SQInteger _stream_len(HSQUIRRELVM v); +SQInteger _stream_eos(HSQUIRRELVM v); +SQInteger _stream_flush(HSQUIRRELVM v); + +#define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck} +SQRESULT declare_stream(HSQUIRRELVM v,SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals); +#endif /*_SQSTD_STREAM_H_*/ diff --git a/vscript/languages/squirrel/sqstdlib/sqstdstring.cpp b/vscript/languages/squirrel/sqstdlib/sqstdstring.cpp new file mode 100644 index 00000000..5abe3d4b --- /dev/null +++ b/vscript/languages/squirrel/sqstdlib/sqstdstring.cpp @@ -0,0 +1,372 @@ +/* see copyright notice in squirrel.h */ +#ifdef _PS3 +#include +#include +#undef _STD_USING +#endif + +#include +#include +#include +#include +#include +#include +#include +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#endif + +#ifdef SQUNICODE +#define scstrchr wcschr +#define scsnprintf wsnprintf +#define scatoi _wtoi +#define scstrtok wcstok +#else +#define scstrchr strchr +#define scsnprintf snprintf +#define scatoi atoi +#define scstrtok strtok +#endif +#define MAX_FORMAT_LEN 20 +#define MAX_WFORMAT_LEN 3 +#define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar)) + +static SQInteger validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src, SQInteger n,SQInteger &width) +{ + SQChar swidth[MAX_WFORMAT_LEN]; + SQInteger wc = 0; + SQInteger start = n; + fmt[0] = '%'; + while (scstrchr(_SC("-+ #0"), src[n])) n++; + while (scisdigit(src[n])) { + swidth[wc] = src[n]; + n++; + wc++; + if(wc>=MAX_WFORMAT_LEN) + return sq_throwerror(v,_SC("width format too long")); + } + swidth[wc] = '\0'; + if(wc > 0) { + width = scatoi(swidth); + } + else + width = 0; + if (src[n] == '.') { + n++; + + wc = 0; + while (scisdigit(src[n])) { + swidth[wc] = src[n]; + n++; + wc++; + if(wc>=MAX_WFORMAT_LEN) + return sq_throwerror(v,_SC("precision format too long")); + } + swidth[wc] = '\0'; + if(wc > 0) { + width += scatoi(swidth); + } + } + if (n-start > MAX_FORMAT_LEN ) + return sq_throwerror(v,_SC("format too long")); + memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar)); + fmt[(n-start)+2] = '\0'; + return n; +} + + +SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output) +{ + const SQChar *format; + SQChar *dest; + SQChar fmt[MAX_FORMAT_LEN]; + sq_getstring(v,nformatstringidx,&format); + SQInteger allocated = (sq_getsize(v,nformatstringidx)+2)*sizeof(SQChar); + dest = sq_getscratchpad(v,allocated); + SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0; + while(format[n] != '\0') { + if(format[n] != '%') { + assert(i < allocated); + dest[i++] = format[n]; + n++; + } + else if(format[n+1] == '%') { //handles %% + dest[i++] = '%'; + n += 2; + } + else { + n++; + if( nparam > sq_gettop(v) ) + return sq_throwerror(v,_SC("not enough paramters for the given format string")); + n = validate_format(v,fmt,format,n,w); + if(n < 0) return -1; + SQInteger addlen = 0; + SQInteger valtype = 0; + const SQChar *ts; + SQInteger ti; + SQFloat tf; + switch(format[n]) { + case 's': + if(SQ_FAILED(sq_getstring(v,nparam,&ts))) + return sq_throwerror(v,_SC("string expected for the specified format")); + addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar)); + valtype = 's'; + break; + case 'i': case 'd': case 'c':case 'o': case 'u': case 'x': case 'X': + if(SQ_FAILED(sq_getinteger(v,nparam,&ti))) + return sq_throwerror(v,_SC("integer expected for the specified format")); + addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar)); + valtype = 'i'; + break; + case 'f': case 'g': case 'G': case 'e': case 'E': + if(SQ_FAILED(sq_getfloat(v,nparam,&tf))) + return sq_throwerror(v,_SC("float expected for the specified format")); + addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar)); + valtype = 'f'; + break; + default: + return sq_throwerror(v,_SC("invalid format")); + } + n++; + allocated += addlen + sizeof(SQChar); + dest = sq_getscratchpad(v,allocated); + switch(valtype) { + case 's': i += scsprintf(&dest[i],fmt,ts); break; + case 'i': i += scsprintf(&dest[i],fmt,ti); break; + case 'f': i += scsprintf(&dest[i],fmt,tf); break; + }; + nparam ++; + } + } + *outlen = i; + dest[i] = '\0'; + *output = dest; + return SQ_OK; +} + +static SQInteger _string_format(HSQUIRRELVM v) +{ + SQChar *dest = NULL; + SQInteger length = 0; + if(SQ_FAILED(sqstd_format(v,2,&length,&dest))) + return -1; + sq_pushstring(v,dest,length); + return 1; +} + +static void __strip_l(const SQChar *str,const SQChar **start) +{ + const SQChar *t = str; + while(((*t) != '\0') && scisspace(*t)){ t++; } + *start = t; +} + +static void __strip_r(const SQChar *str,SQInteger len,const SQChar **end) +{ + if(len == 0) { + *end = str; + return; + } + const SQChar *t = &str[len-1]; + while(t != str && scisspace(*t)) { t--; } + *end = t+1; +} + +static SQInteger _string_strip(HSQUIRRELVM v) +{ + const SQChar *str,*start,*end; + sq_getstring(v,2,&str); + SQInteger len = sq_getsize(v,2); + __strip_l(str,&start); + __strip_r(str,len,&end); + sq_pushstring(v,start,end - start); + return 1; +} + +static SQInteger _string_lstrip(HSQUIRRELVM v) +{ + const SQChar *str,*start; + sq_getstring(v,2,&str); + __strip_l(str,&start); + sq_pushstring(v,start,-1); + return 1; +} + +static SQInteger _string_rstrip(HSQUIRRELVM v) +{ + const SQChar *str,*end; + sq_getstring(v,2,&str); + SQInteger len = sq_getsize(v,2); + __strip_r(str,len,&end); + sq_pushstring(v,str,end - str); + return 1; +} + +static SQInteger _string_split(HSQUIRRELVM v) +{ + const SQChar *str,*seps; + SQChar *stemp,*tok; + sq_getstring(v,2,&str); + sq_getstring(v,3,&seps); + if(sq_getsize(v,3) == 0) return sq_throwerror(v,_SC("empty separators string")); + SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar); + stemp = sq_getscratchpad(v,memsize); + memcpy(stemp,str,memsize); + tok = scstrtok(stemp,seps); + sq_newarray(v,0); + while( tok != NULL ) { + sq_pushstring(v,tok,-1); + sq_arrayappend(v,-2); + tok = scstrtok( NULL, seps ); + } + return 1; +} + +#define SETUP_REX(v) \ + SQRex *self = NULL; \ + sq_getinstanceup(v,1,(SQUserPointer *)&self,0); + +static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger size) +{ + SQRex *self = ((SQRex *)p); + sqstd_rex_free(self); + return 1; +} + +static SQInteger _regexp_match(HSQUIRRELVM v) +{ + SETUP_REX(v); + const SQChar *str; + sq_getstring(v,2,&str); + if(sqstd_rex_match(self,str) == SQTrue) + { + sq_pushbool(v,SQTrue); + return 1; + } + sq_pushbool(v,SQFalse); + return 1; +} + +static void _addrexmatch(HSQUIRRELVM v,const SQChar *str,const SQChar *begin,const SQChar *end) +{ + sq_newtable(v); + sq_pushstring(v,_SC("begin"),-1); + sq_pushinteger(v,begin - str); + sq_rawset(v,-3); + sq_pushstring(v,_SC("end"),-1); + sq_pushinteger(v,end - str); + sq_rawset(v,-3); +} + +static SQInteger _regexp_search(HSQUIRRELVM v) +{ + SETUP_REX(v); + const SQChar *str,*begin,*end; + SQInteger start = 0; + sq_getstring(v,2,&str); + if(sq_gettop(v) > 2) sq_getinteger(v,3,&start); + if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) { + _addrexmatch(v,str,begin,end); + return 1; + } + return 0; +} + +static SQInteger _regexp_capture(HSQUIRRELVM v) +{ + SETUP_REX(v); + const SQChar *str,*begin,*end; + SQInteger start = 0; + sq_getstring(v,2,&str); + if(sq_gettop(v) > 2) sq_getinteger(v,3,&start); + if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) { + SQInteger n = sqstd_rex_getsubexpcount(self); + SQRexMatch match; + sq_newarray(v,0); + for(SQInteger i = 0;i < n; i++) { + sqstd_rex_getsubexp(self,i,&match); + if(match.len > 0) + _addrexmatch(v,str,match.begin,match.begin+match.len); + else + _addrexmatch(v,str,str,str); //empty match + sq_arrayappend(v,-2); + } + return 1; + } + return 0; +} + +static SQInteger _regexp_subexpcount(HSQUIRRELVM v) +{ + SETUP_REX(v); + sq_pushinteger(v,sqstd_rex_getsubexpcount(self)); + return 1; +} + +static SQInteger _regexp_constructor(HSQUIRRELVM v) +{ + const SQChar *error,*pattern; + sq_getstring(v,2,&pattern); + SQRex *rex = sqstd_rex_compile(pattern,&error); + if(!rex) return sq_throwerror(v,error); + sq_setinstanceup(v,1,rex); + sq_setreleasehook(v,1,_rexobj_releasehook); + return 0; +} + +static SQInteger _regexp__typeof(HSQUIRRELVM v) +{ + sq_pushstring(v,_SC("regexp"),-1); + return 1; +} + +#define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask} +static SQRegFunction rexobj_funcs[]={ + _DECL_REX_FUNC(constructor,2,_SC(".s")), + _DECL_REX_FUNC(search,-2,_SC("xsn")), + _DECL_REX_FUNC(match,2,_SC("xs")), + _DECL_REX_FUNC(capture,-2,_SC("xsn")), + _DECL_REX_FUNC(subexpcount,1,_SC("x")), + _DECL_REX_FUNC(_typeof,1,_SC("x")), + {0,0} +}; + +#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask} +static SQRegFunction stringlib_funcs[]={ + _DECL_FUNC(format,-2,_SC(".s")), + _DECL_FUNC(strip,2,_SC(".s")), + _DECL_FUNC(lstrip,2,_SC(".s")), + _DECL_FUNC(rstrip,2,_SC(".s")), + _DECL_FUNC(split,3,_SC(".ss")), + {0,0} +}; + + +SQInteger sqstd_register_stringlib(HSQUIRRELVM v) +{ + sq_pushstring(v,_SC("regexp"),-1); + sq_newclass(v,SQFalse); + SQInteger i = 0; + while(rexobj_funcs[i].name != 0) { + SQRegFunction &f = rexobj_funcs[i]; + sq_pushstring(v,f.name,-1); + sq_newclosure(v,f.f,0); + sq_setparamscheck(v,f.nparamscheck,f.typemask); + sq_setnativeclosurename(v,-1,f.name); + sq_createslot(v,-3); + i++; + } + sq_createslot(v,-3); + + i = 0; + while(stringlib_funcs[i].name!=0) + { + sq_pushstring(v,stringlib_funcs[i].name,-1); + sq_newclosure(v,stringlib_funcs[i].f,0); + sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask); + sq_setnativeclosurename(v,-1,stringlib_funcs[i].name); + sq_createslot(v,-3); + i++; + } + return 1; +} diff --git a/vscript/languages/squirrel/sqstdlib/sqstdsystem.cpp b/vscript/languages/squirrel/sqstdlib/sqstdsystem.cpp new file mode 100644 index 00000000..7d4200c8 --- /dev/null +++ b/vscript/languages/squirrel/sqstdlib/sqstdsystem.cpp @@ -0,0 +1,147 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include + +#ifdef SQUNICODE +#include +#define scgetenv _wgetenv +#define scsystem _wsystem +#define scasctime _wasctime +#define scremove _wremove +#define screname _wrename +#else +#define scgetenv getenv +#define scsystem system +#define scasctime asctime +#define scremove remove +#define screname rename +#endif + +static SQInteger _system_getenv(HSQUIRRELVM v) +{ + const SQChar *s; + if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){ + sq_pushstring(v,scgetenv(s),-1); + return 1; + } + return 0; +} + + +static SQInteger _system_system(HSQUIRRELVM v) +{ + const SQChar *s; + if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){ + sq_pushinteger(v,scsystem(s)); + return 1; + } + return sq_throwerror(v,_SC("wrong param")); +} + + +static SQInteger _system_clock(HSQUIRRELVM v) +{ + sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC); + return 1; +} + +static SQInteger _system_time(HSQUIRRELVM v) +{ + time_t t; + time(&t); + sq_pushinteger(v,*((SQInteger *)&t)); + return 1; +} + +static SQInteger _system_remove(HSQUIRRELVM v) +{ + const SQChar *s; + sq_getstring(v,2,&s); + if(scremove(s)==-1) + return sq_throwerror(v,_SC("remove() failed")); + return 0; +} + +static SQInteger _system_rename(HSQUIRRELVM v) +{ + const SQChar *oldn,*newn; + sq_getstring(v,2,&oldn); + sq_getstring(v,3,&newn); + if(screname(oldn,newn)==-1) + return sq_throwerror(v,_SC("rename() failed")); + return 0; +} + +static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val) +{ + sq_pushstring(v,name,-1); + sq_pushinteger(v,val); + sq_rawset(v,-3); +} + +static SQInteger _system_date(HSQUIRRELVM v) +{ + time_t t; + SQInteger it; + SQInteger format = 'l'; + if(sq_gettop(v) > 1) { + sq_getinteger(v,2,&it); + t = it; + if(sq_gettop(v) > 2) { + sq_getinteger(v,3,(SQInteger*)&format); + } + } + else { + time(&t); + } + tm *date; + if(format == 'u') + date = gmtime(&t); + else + date = localtime(&t); + if(!date) + return sq_throwerror(v,_SC("crt api failure")); + sq_newtable(v); + _set_integer_slot(v, _SC("sec"), date->tm_sec); + _set_integer_slot(v, _SC("min"), date->tm_min); + _set_integer_slot(v, _SC("hour"), date->tm_hour); + _set_integer_slot(v, _SC("day"), date->tm_mday); + _set_integer_slot(v, _SC("month"), date->tm_mon); + _set_integer_slot(v, _SC("year"), date->tm_year+1900); + _set_integer_slot(v, _SC("wday"), date->tm_wday); + _set_integer_slot(v, _SC("yday"), date->tm_yday); + return 1; +} + + + +#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask} +static SQRegFunction systemlib_funcs[]={ + _DECL_FUNC(getenv,2,_SC(".s")), + _DECL_FUNC(system,2,_SC(".s")), + _DECL_FUNC(clock,1,NULL), + _DECL_FUNC(time,1,NULL), + _DECL_FUNC(date,-1,_SC(".nn")), + _DECL_FUNC(remove,2,_SC(".s")), + _DECL_FUNC(rename,3,_SC(".ss")), + {0,0} +}; + + +SQInteger sqstd_register_systemlib(HSQUIRRELVM v) +{ + SQInteger i=0; + while(systemlib_funcs[i].name!=0) + { + sq_pushstring(v,systemlib_funcs[i].name,-1); + sq_newclosure(v,systemlib_funcs[i].f,0); + sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask); + sq_setnativeclosurename(v,-1,systemlib_funcs[i].name); + sq_createslot(v,-3); + i++; + } + return 1; +} diff --git a/vscript/languages/squirrel/squirrel.workspace b/vscript/languages/squirrel/squirrel.workspace new file mode 100644 index 00000000..923f5efa --- /dev/null +++ b/vscript/languages/squirrel/squirrel.workspace @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/squirrel/Makefile b/vscript/languages/squirrel/squirrel/Makefile new file mode 100644 index 00000000..8d556f61 --- /dev/null +++ b/vscript/languages/squirrel/squirrel/Makefile @@ -0,0 +1,52 @@ +SQUIRREL= .. + + +OUT= $(SQUIRREL)/lib/libsquirrel.a +INCZ= -I$(SQUIRREL)/include -I. -Iinclude +DEFS= +LIB= + +OBJS= \ + sqapi.o \ + sqbaselib.o \ + sqcompiler.o \ + sqdebug.o \ + sqlexer.o \ + sqobject.o \ + sqparser.o \ + sqstate.o \ + sqtable.o \ + sqvm.o \ + sqmem.o \ + sqclass.o + +SRCS= \ + sqapi.cpp \ + sqbaselib.cpp \ + sqfuncstate.cpp \ + sqdebug.cpp \ + sqlexer.cpp \ + sqobject.cpp \ + sqcompiler.cpp \ + sqstate.cpp \ + sqtable.cpp \ + sqmem.cpp \ + sqvm.cpp \ + sqclass.cpp + + + +sq32: + gcc -O2 -fno-rtti -Wall -c $(SRCS) $(INCZ) $(DEFS) + ar rc $(OUT) *.o + rm *.o + +sqprof: + gcc -O2 -pg -fno-rtti -pie -gstabs -g3 -Wall -c $(SRCS) $(INCZ) $(DEFS) + ar rc $(OUT) *.o + rm *.o + +sq64: + gcc -O2 -D_SQ64 -fno-rtti -Wall -c $(SRCS) $(INCZ) $(DEFS) + ar rc $(OUT) *.o + rm *.o diff --git a/vscript/languages/squirrel/squirrel/sqapi.cpp b/vscript/languages/squirrel/squirrel/sqapi.cpp new file mode 100644 index 00000000..3892852f --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqapi.cpp @@ -0,0 +1,1274 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqstring.h" +#include "sqtable.h" +#include "sqarray.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "squserdata.h" +#include "sqcompiler.h" +#include "sqfuncstate.h" +#include "sqclass.h" +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#undef new // allow placement new +#endif + +bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr **o) +{ + *o = &stack_get(v,idx); + if(type(**o) != type){ + SQObjectPtr oval = v->PrintObjVal(**o); + v->Raise_Error(_SC("wrong argument type, expected '%s' got '%.50s'"),IdType2Name(type),_stringval(oval)); + return false; + } + return true; +} + +#define _GETSAFE_OBJ(v,idx,type,o) { if(!sq_aux_gettypedarg(v,idx,type,&o)) return SQ_ERROR; } + +#define sq_aux_paramscheck(v,count) \ +{ \ + if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\ +} + +SQInteger sq_aux_throwobject(HSQUIRRELVM v,SQObjectPtr &e) +{ + v->_lasterror = e; + return SQ_ERROR; +} + +SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type) +{ + scsprintf(_ss(v)->GetScratchPad(100), _SC("unexpected type %s"), IdType2Name(type)); + return sq_throwerror(v, _ss(v)->GetScratchPad(-1)); +} + +HSQUIRRELVM sq_open(SQInteger initialstacksize) +{ + SQSharedState *ss; + SQVM *v; + sq_new(ss, SQSharedState); + ss->Init(); + v = (SQVM *)SQ_MALLOC(sizeof(SQVM)); + new (v) SQVM(ss); + ss->_root_vm = v; + if(v->Init(NULL, initialstacksize)) { + return v; + } else { + sq_delete(v, SQVM); + return NULL; + } + return v; +} + +HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize) +{ + SQSharedState *ss; + SQVM *v; + ss=_ss(friendvm); + + v= (SQVM *)SQ_MALLOC(sizeof(SQVM)); + new (v) SQVM(ss); + + if(v->Init(friendvm, initialstacksize)) { + friendvm->Push(v); + return v; + } else { + sq_delete(v, SQVM); + return NULL; + } +} + +SQInteger sq_getvmstate(HSQUIRRELVM v) +{ + if(v->_suspended) + return SQ_VMSTATE_SUSPENDED; + else { + if(v->_callsstacksize != 0) return SQ_VMSTATE_RUNNING; + else return SQ_VMSTATE_IDLE; + } +} + +void sq_seterrorhandler(HSQUIRRELVM v) +{ + SQObject o = stack_get(v, -1); + if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) { + v->_errorhandler = o; + v->Pop(); + } +} + +void sq_setdebughook(HSQUIRRELVM v) +{ + SQObject o = stack_get(v,-1); + if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) { + v->_debughook = o; + v->Pop(); + } +} + +void sq_close(HSQUIRRELVM v) +{ + SQSharedState *ss = _ss(v); + _thread(ss->_root_vm)->Finalize(); + sq_delete(ss, SQSharedState); +} + +SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror) +{ + SQObjectPtr o; + if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) { + v->Push(SQClosure::Create(_ss(v), _funcproto(o))); + return SQ_OK; + } + return SQ_ERROR; +} + +void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable) +{ + _ss(v)->_debuginfo = enable?true:false; +} + +void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable) +{ + _ss(v)->_notifyallexceptions = enable?true:false; +} + +void sq_addref(HSQUIRRELVM v,HSQOBJECT *po) +{ + if(!ISREFCOUNTED(type(*po))) return; +#ifdef NO_GARBAGE_COLLECTOR + __AddRef(po->_type,po->_unVal); +#else + _ss(v)->_refs_table.AddRef(*po); +#endif +} + +SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po) +{ + if(!ISREFCOUNTED(type(*po))) return SQTrue; +#ifdef NO_GARBAGE_COLLECTOR + __Release(po->_type,po->_unVal); + return SQFalse; //the ret val doesn't work(and cannot be fixed) +#else + return _ss(v)->_refs_table.Release(*po); +#endif +} + +const SQChar *sq_objtostring(HSQOBJECT *o) +{ + if(sq_type(*o) == OT_STRING) { + return _stringval(*o); + } + return NULL; +} + +SQInteger sq_objtointeger(HSQOBJECT *o) +{ + if(sq_isnumeric(*o)) { + return tointeger(*o); + } + return 0; +} + +SQFloat sq_objtofloat(HSQOBJECT *o) +{ + if(sq_isnumeric(*o)) { + return tofloat(*o); + } + return 0; +} + +SQBool sq_objtobool(HSQOBJECT *o) +{ + if(sq_isbool(*o)) { + return _integer(*o); + } + return SQFalse; +} + +void sq_pushnull(HSQUIRRELVM v) +{ + v->Push(_null_); +} + +void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len) +{ + if(s) + v->Push(SQObjectPtr(SQString::Create(_ss(v), s, len))); + else v->Push(_null_); +} + +void sq_pushinteger(HSQUIRRELVM v,SQInteger n) +{ + v->Push(n); +} + +void sq_pushbool(HSQUIRRELVM v,SQBool b) +{ + v->Push(b?true:false); +} + +void sq_pushfloat(HSQUIRRELVM v,SQFloat n) +{ + v->Push(n); +} + +void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p) +{ + v->Push(p); +} + +SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size) +{ + SQUserData *ud = SQUserData::Create(_ss(v), size); + v->Push(ud); + return ud->_val; +} + +void sq_newtable(HSQUIRRELVM v) +{ + v->Push(SQTable::Create(_ss(v), 0)); +} + +void sq_newarray(HSQUIRRELVM v,SQInteger size) +{ + v->Push(SQArray::Create(_ss(v), size)); +} + +SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase) +{ + SQClass *baseclass = NULL; + if(hasbase) { + SQObjectPtr &base = stack_get(v,-1); + if(type(base) != OT_CLASS) + return sq_throwerror(v,_SC("invalid base type")); + baseclass = _class(base); + } + SQClass *newclass = SQClass::Create(_ss(v), baseclass); + if(baseclass) v->Pop(); + v->Push(newclass); + return SQ_OK; +} + +SQBool sq_instanceof(HSQUIRRELVM v) +{ + SQObjectPtr &inst = stack_get(v,-1); + SQObjectPtr &cl = stack_get(v,-2); + if(type(inst) != OT_INSTANCE || type(cl) != OT_CLASS) + return sq_throwerror(v,_SC("invalid param type")); + return _instance(inst)->InstanceOf(_class(cl))?SQTrue:SQFalse; +} + +SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx) +{ + sq_aux_paramscheck(v,2); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + _array(*arr)->Append(v->GetUp(-1)); + v->Pop(1); + return SQ_OK; +} + +SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + if(_array(*arr)->Size() > 0) { + if(pushval != 0){ v->Push(_array(*arr)->Top()); } + _array(*arr)->Pop(); + return SQ_OK; + } + return sq_throwerror(v, _SC("empty array")); +} + +SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize) +{ + sq_aux_paramscheck(v,1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + if(newsize >= 0) { + _array(*arr)->Resize(newsize); + return SQ_OK; + } + return sq_throwerror(v,_SC("negative size")); +} + + +SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *o; + _GETSAFE_OBJ(v, idx, OT_ARRAY,o); + SQArray *arr = _array(*o); + if(arr->Size() > 0) { + SQObjectPtr t; + SQInteger size = arr->Size(); + SQInteger n = size >> 1; size -= 1; + for(SQInteger i = 0; i < n; i++) { + t = arr->_values[i]; + arr->_values[i] = arr->_values[size-i]; + arr->_values[size-i] = t; + } + return SQ_OK; + } + return SQ_OK; +} + +SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + return _array(*arr)->Remove(itemidx) ? SQ_OK : sq_throwerror(v,_SC("index out of range")); +} + +SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + SQRESULT ret = _array(*arr)->Insert(destpos, v->GetUp(-1)) ? SQ_OK : sq_throwerror(v,_SC("index out of range")); + v->Pop(); + return ret; +} + + +void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars) +{ + SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func); + nc->_nparamscheck = 0; + for(SQUnsignedInteger i = 0; i < nfreevars; i++) { + nc->_outervalues.push_back(v->Top()); + v->Pop(); + } + v->Push(SQObjectPtr(nc)); +} + +SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars) +{ + SQObject o = stack_get(v, idx); + if(sq_isclosure(o)) { + SQClosure *c = _closure(o); + SQFunctionProto *proto = _funcproto(c->_function); + *nparams = (SQUnsignedInteger)proto->_nparameters; + *nfreevars = (SQUnsignedInteger)c->_outervalues.size(); + return SQ_OK; + } + return sq_throwerror(v,_SC("the object is not a closure")); +} + +SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name) +{ + SQObject o = stack_get(v, idx); + if(sq_isnativeclosure(o)) { + SQNativeClosure *nc = _nativeclosure(o); + nc->_name = SQString::Create(_ss(v),name); + return SQ_OK; + } + return sq_throwerror(v,_SC("the object is not a nativeclosure")); +} + +SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask) +{ + SQObject o = stack_get(v, -1); + if(!sq_isnativeclosure(o)) + return sq_throwerror(v, _SC("native closure expected")); + SQNativeClosure *nc = _nativeclosure(o); + nc->_nparamscheck = nparamscheck; + if(typemask) { + SQIntVec res; + if(!CompileTypemask(res, typemask)) + return sq_throwerror(v, _SC("invalid typemask")); + nc->_typecheck.copy(res); + } + else { + nc->_typecheck.resize(0); + } + if(nparamscheck == SQ_MATCHTYPEMASKSTRING) { + nc->_nparamscheck = nc->_typecheck.size(); + } + return SQ_OK; +} + +SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v,idx); + if(!sq_isnativeclosure(o) && + !sq_isclosure(o)) + return sq_throwerror(v,_SC("the target is not a closure")); + SQObjectPtr &env = stack_get(v,-1); + if(!sq_istable(env) && + !sq_isclass(env) && + !sq_isinstance(env)) + return sq_throwerror(v,_SC("invalid environment")); + SQObjectPtr w = _refcounted(env)->GetWeakRef(type(env)); + SQObjectPtr ret; + if(sq_isclosure(o)) { + SQClosure *c = _closure(o)->Clone(); + c->_env = w; + ret = c; + } + else { //then must be a native closure + SQNativeClosure *c = _nativeclosure(o)->Clone(); + c->_env = w; + ret = c; + } + v->Pop(); + v->Push(ret); + return SQ_OK; +} + +SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx) +{ + SQObject &o=stack_get(v,idx); + switch(type(o)) { + case OT_TABLE: _table(o)->Clear(); break; + case OT_ARRAY: _array(o)->Resize(0); break; + default: + return sq_throwerror(v, _SC("clear only works on table and array")); + break; + + } + return SQ_OK; +} + +void sq_pushroottable(HSQUIRRELVM v) +{ + v->Push(v->_roottable); +} + +void sq_pushregistrytable(HSQUIRRELVM v) +{ + v->Push(_ss(v)->_registry); +} + +void sq_pushconsttable(HSQUIRRELVM v) +{ + v->Push(_ss(v)->_consts); +} + +SQRESULT sq_setroottable(HSQUIRRELVM v) +{ + SQObject o = stack_get(v, -1); + if(sq_istable(o) || sq_isnull(o)) { + v->_roottable = o; + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v, _SC("ivalid type")); +} + +SQRESULT sq_setconsttable(HSQUIRRELVM v) +{ + SQObject o = stack_get(v, -1); + if(sq_istable(o)) { + _ss(v)->_consts = o; + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v, _SC("ivalid type, expected table")); +} + +void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p) +{ + v->_foreignptr = p; +} + +SQUserPointer sq_getforeignptr(HSQUIRRELVM v) +{ + return v->_foreignptr; +} + +void sq_push(HSQUIRRELVM v,SQInteger idx) +{ + v->Push(stack_get(v, idx)); +} + +SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx) +{ + return type(stack_get(v, idx)); +} + + +void sq_tostring(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v, idx); + SQObjectPtr res; + v->ToString(o,res); + v->Push(res); +} + +void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b) +{ + SQObjectPtr &o = stack_get(v, idx); + *b = v->IsFalse(o)?SQFalse:SQTrue; +} + +SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i) +{ + SQObjectPtr &o = stack_get(v, idx); + if(sq_isnumeric(o)) { + *i = tointeger(o); + return SQ_OK; + } + return SQ_ERROR; +} + +SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f) +{ + SQObjectPtr &o = stack_get(v, idx); + if(sq_isnumeric(o)) { + *f = tofloat(o); + return SQ_OK; + } + return SQ_ERROR; +} + +SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b) +{ + SQObjectPtr &o = stack_get(v, idx); + if(sq_isbool(o)) { + *b = _integer(o); + return SQ_OK; + } + return SQ_ERROR; +} + +SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_STRING,o); + *c = _stringval(*o); + return SQ_OK; +} + +SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_THREAD,o); + *thread = _thread(*o); + return SQ_OK; +} + +SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v,idx); + v->Push(_null_); + if(!v->Clone(o, stack_get(v, -1))){ + v->Pop(); + return sq_aux_invalidtype(v, type(o)); + } + return SQ_OK; +} + +SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx) +{ + SQObjectPtr &o = stack_get(v, idx); + SQObjectType type = type(o); + switch(type) { + case OT_STRING: return _string(o)->_len; + case OT_TABLE: return _table(o)->CountUsed(); + case OT_ARRAY: return _array(o)->Size(); + case OT_USERDATA: return _userdata(o)->_size; + default: + return sq_aux_invalidtype(v, type); + } +} + +SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_USERDATA,o); + (*p) = _userdataval(*o); + if(typetag) *typetag = _userdata(*o)->_typetag; + return SQ_OK; +} + +SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag) +{ + SQObjectPtr &o = stack_get(v,idx); + switch(type(o)) { + case OT_USERDATA: _userdata(o)->_typetag = typetag; break; + case OT_CLASS: _class(o)->_typetag = typetag; break; + default: return sq_throwerror(v,_SC("invalid object type")); + } + return SQ_OK; +} + +SQRESULT sq_getobjtypetag(HSQOBJECT *o,SQUserPointer * typetag) +{ + switch(type(*o)) { + case OT_INSTANCE: *typetag = _instance(*o)->_class->_typetag; break; + case OT_USERDATA: *typetag = _userdata(*o)->_typetag; break; + case OT_CLASS: *typetag = _class(*o)->_typetag; break; + default: return SQ_ERROR; + } + return SQ_OK; +} + +SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag) +{ + SQObjectPtr &o = stack_get(v,idx); + if(SQ_FAILED(sq_getobjtypetag(&o,typetag))) + return sq_throwerror(v,_SC("invalid object type")); + return SQ_OK; +} + +SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_USERPOINTER,o); + (*p) = _userpointer(*o); + return SQ_OK; +} + +SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p) +{ + SQObjectPtr &o = stack_get(v,idx); + if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance")); + _instance(o)->_userpointer = p; + return SQ_OK; +} + +SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize) +{ + SQObjectPtr &o = stack_get(v,idx); + if(type(o) != OT_CLASS) return sq_throwerror(v,_SC("the object is not a class")); + if(_class(o)->_locked) return sq_throwerror(v,_SC("the class is locked")); + _class(o)->_udsize = udsize; + return SQ_OK; +} + + +SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag) +{ + SQObjectPtr &o = stack_get(v,idx); + if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance")); + (*p) = _instance(o)->_userpointer; + if(typetag != 0) { + SQClass *cl = _instance(o)->_class; + do{ + if(cl->_typetag == typetag) + return SQ_OK; + cl = cl->_base; + }while(cl != NULL); + return sq_throwerror(v,_SC("invalid type tag")); + } + return SQ_OK; +} + +SQInteger sq_gettop(HSQUIRRELVM v) +{ + return (v->_top) - v->_stackbase; +} + +void sq_settop(HSQUIRRELVM v, SQInteger newtop) +{ + SQInteger top = sq_gettop(v); + if(top > newtop) + sq_pop(v, top - newtop); + else + while(top++ < newtop) sq_pushnull(v); +} + +void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop) +{ + Assert(v->_top >= nelemstopop); + v->Pop(nelemstopop); +} + +void sq_poptop(HSQUIRRELVM v) +{ + Assert(v->_top >= 1); + v->Pop(); +} + + +void sq_remove(HSQUIRRELVM v, SQInteger idx) +{ + v->Remove(idx); +} + +SQInteger sq_cmp(HSQUIRRELVM v) +{ + SQInteger res; + v->ObjCmp(stack_get(v, -1), stack_get(v, -2),res); + return res; +} + +SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic) +{ + sq_aux_paramscheck(v, 3); + SQObjectPtr &self = stack_get(v, idx); + if(type(self) == OT_TABLE || type(self) == OT_CLASS) { + SQObjectPtr &key = v->GetUp(-2); + if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key")); + v->NewSlot(self, key, v->GetUp(-1),bstatic?true:false); + v->Pop(2); + } + return SQ_OK; +} + +SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval) +{ + sq_aux_paramscheck(v, 2); + SQObjectPtr *self; + _GETSAFE_OBJ(v, idx, OT_TABLE,self); + SQObjectPtr &key = v->GetUp(-1); + if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key")); + SQObjectPtr res; + if(!v->DeleteSlot(*self, key, res)){ + return SQ_ERROR; + } + if(pushval) v->GetUp(-1) = res; + else v->Pop(1); + return SQ_OK; +} + +SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self = stack_get(v, idx); + if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) { + v->Pop(2); + return SQ_OK; + } + v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR; +} + +SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self = stack_get(v, idx); + if(type(v->GetUp(-2)) == OT_NULL) return sq_throwerror(v, _SC("null key")); + switch(type(self)) { + case OT_TABLE: + _table(self)->NewSlot(v->GetUp(-2), v->GetUp(-1)); + v->Pop(2); + return SQ_OK; + break; + case OT_CLASS: + _class(self)->NewSlot(_ss(v), v->GetUp(-2), v->GetUp(-1),false); + v->Pop(2); + return SQ_OK; + break; + case OT_INSTANCE: + if(_instance(self)->Set(v->GetUp(-2), v->GetUp(-1))) { + v->Pop(2); + return SQ_OK; + } + break; + case OT_ARRAY: + if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) { + v->Pop(2); + return SQ_OK; + } + break; + default: + v->Pop(2); + return sq_throwerror(v, _SC("rawset works only on array/table/class and instance")); + } + v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR; +} + +SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self = stack_get(v, idx); + SQObjectPtr &mt = v->GetUp(-1); + SQObjectType type = type(self); + switch(type) { + case OT_TABLE: + if(type(mt) == OT_TABLE) { + if(!_table(self)->SetDelegate(_table(mt))) return sq_throwerror(v, _SC("delagate cycle")); v->Pop();} + else if(type(mt)==OT_NULL) { + _table(self)->SetDelegate(NULL); v->Pop(); } + else return sq_aux_invalidtype(v,type); + break; + case OT_USERDATA: + if(type(mt)==OT_TABLE) { + _userdata(self)->SetDelegate(_table(mt)); v->Pop(); } + else if(type(mt)==OT_NULL) { + _userdata(self)->SetDelegate(NULL); v->Pop(); } + else return sq_aux_invalidtype(v, type); + break; + default: + return sq_aux_invalidtype(v, type); + break; + } + return SQ_OK; +} + +SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval) +{ + sq_aux_paramscheck(v, 2); + SQObjectPtr *self; + _GETSAFE_OBJ(v, idx, OT_TABLE,self); + SQObjectPtr &key = v->GetUp(-1); + SQObjectPtr t; + if(_table(*self)->Get(key,t)) { + _table(*self)->Remove(key); + } + if(pushval != 0) + if(pushval) v->GetUp(-1) = t; + else + v->Pop(1); + return SQ_OK; +} + +SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self=stack_get(v,idx); + switch(type(self)){ + case OT_TABLE: + case OT_USERDATA: + if(!_delegable(self)->_delegate){ + v->Push(_null_); + break; + } + v->Push(SQObjectPtr(_delegable(self)->_delegate)); + break; + default: return sq_throwerror(v,_SC("wrong type")); break; + } + return SQ_OK; + +} + +SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self=stack_get(v,idx); + if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false)) + return SQ_OK; + v->Pop(1); + return sq_throwerror(v,_SC("the index doesn't exist")); +} + +SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self=stack_get(v,idx); + switch(type(self)) { + case OT_TABLE: + if(_table(self)->Get(v->GetUp(-1),v->GetUp(-1))) + return SQ_OK; + break; + case OT_CLASS: + if(_class(self)->Get(v->GetUp(-1),v->GetUp(-1))) + return SQ_OK; + break; + case OT_INSTANCE: + if(_instance(self)->Get(v->GetUp(-1),v->GetUp(-1))) + return SQ_OK; + break; + case OT_ARRAY: + if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false)) + return SQ_OK; + break; + default: + v->Pop(1); + return sq_throwerror(v,_SC("rawget works only on array/table/instance and class")); + } + v->Pop(1); + return sq_throwerror(v,_SC("the index doesn't exist")); +} + +SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po) +{ + *po=stack_get(v,idx); + return SQ_OK; +} + +const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx) +{ + SQUnsignedInteger cstksize=v->_callsstacksize; + SQUnsignedInteger lvl=(cstksize-level)-1; + SQInteger stackbase=v->_stackbase; + if(lvl_callsstack[(cstksize-i)-1]; + stackbase-=ci._prevstkbase; + } + SQVM::CallInfo &ci=v->_callsstack[lvl]; + if(type(ci._closure)!=OT_CLOSURE) + return NULL; + SQClosure *c=_closure(ci._closure); + SQFunctionProto *func=_funcproto(c->_function); + if(func->_noutervalues > (SQInteger)idx) { + v->Push(c->_outervalues[idx]); + return _stringval(func->_outervalues[idx]._name); + } + idx -= func->_noutervalues; + return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions)-1); + } + return NULL; +} + +void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj) +{ + v->Push(SQObjectPtr(obj)); +} + +void sq_resetobject(HSQOBJECT *po) +{ + po->_unVal.pUserPointer=NULL;po->_type=OT_NULL; +} + +SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err) +{ + v->_lasterror=SQString::Create(_ss(v),err); + return -1; +} + +void sq_reseterror(HSQUIRRELVM v) +{ + v->_lasterror = _null_; +} + +void sq_getlasterror(HSQUIRRELVM v) +{ + v->Push(v->_lasterror); +} + +void sq_reservestack(HSQUIRRELVM v,SQInteger nsize) +{ + if (((SQUnsignedInteger)v->_top + nsize) > v->_stack.size()) { + v->_stack.resize(v->_stack.size() + ((v->_top + nsize) - v->_stack.size())); + } +} + +SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror) +{ + if(type(v->GetUp(-1))==OT_GENERATOR){ + v->Push(_null_); //retval + if(!v->Execute(v->GetUp(-2),v->_top,0,v->_top,v->GetUp(-1),raiseerror,SQVM::ET_RESUME_GENERATOR)) + {v->Raise_Error(v->_lasterror); return SQ_ERROR;} + if(!retval) + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v,_SC("only generators can be resumed")); +} + +SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror) +{ + SQObjectPtr res; + if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){ + if(!v->_suspended) { + v->Pop(params);//pop closure and args + } + if(retval){ + v->Push(res); return SQ_OK; + } + return SQ_OK; + } + else { + v->Pop(params); + return SQ_ERROR; + } + if(!v->_suspended) + v->Pop(params); + return sq_throwerror(v,_SC("call failed")); +} + +SQRESULT sq_suspendvm(HSQUIRRELVM v) +{ + return v->Suspend(); +} + +SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror,SQBool throwerror) +{ + SQObjectPtr ret; + if(!v->_suspended) + return sq_throwerror(v,_SC("cannot resume a vm that is not running any code")); + if(wakeupret) { + v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval + v->Pop(); + } else v->GetAt(v->_stackbase+v->_suspended_target)=_null_; + if(!v->Execute(_null_,v->_top,-1,-1,ret,raiseerror,throwerror?SQVM::ET_RESUME_THROW_VM : SQVM::ET_RESUME_VM)) + return SQ_ERROR; + if(sq_getvmstate(v) == SQ_VMSTATE_IDLE) { + while (v->_top > 1) v->_stack[--v->_top] = _null_; + } + if(retval) + v->Push(ret); + return SQ_OK; +} + +void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook) +{ + if(sq_gettop(v) >= 1){ + SQObjectPtr &ud=stack_get(v,idx); + switch( type(ud) ) { + case OT_USERDATA: _userdata(ud)->_hook = hook; break; + case OT_INSTANCE: _instance(ud)->_hook = hook; break; + case OT_CLASS: _class(ud)->_hook = hook; break; + default: break; //shutup compiler + } + } +} + +void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f) +{ + _ss(v)->_compilererrorhandler = f; +} + +SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, -1, OT_CLOSURE,o); + unsigned short tag = SQ_BYTECODE_STREAM_TAG; + if(w(up,&tag,2) != 2) + return sq_throwerror(v,_SC("io error")); + if(!_closure(*o)->Save(v,up,w)) + return SQ_ERROR; + return SQ_OK; +} + +SQRESULT sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up) +{ + SQObjectPtr closure; + + unsigned short tag; + if(r(up,&tag,2) != 2) + return sq_throwerror(v,_SC("io error")); + if(tag != SQ_BYTECODE_STREAM_TAG) + return sq_throwerror(v,_SC("invalid stream")); + if(!SQClosure::Load(v,up,r,closure)) + return SQ_ERROR; + v->Push(closure); + return SQ_OK; +} + +SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize) +{ + return _ss(v)->GetScratchPad(minsize); +} + +SQInteger sq_collectgarbage(HSQUIRRELVM v) +{ +#ifndef NO_GARBAGE_COLLECTOR + return _ss(v)->CollectGarbage(v); +#else + return -1; +#endif +} + +const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval) +{ + SQObjectPtr &self = stack_get(v,idx); + const SQChar *name = NULL; + if(type(self) == OT_CLOSURE) { + if(_closure(self)->_outervalues.size()>nval) { + v->Push(_closure(self)->_outervalues[nval]); + SQFunctionProto *fp = _funcproto(_closure(self)->_function); + SQOuterVar &ov = fp->_outervalues[nval]; + name = _stringval(ov._name); + } + } + return name; +} + +SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval) +{ + SQObjectPtr &self=stack_get(v,idx); + switch(type(self)) + { + case OT_CLOSURE: + if(_closure(self)->_outervalues.size()>nval){ + _closure(self)->_outervalues[nval]=stack_get(v,-1); + } + else return sq_throwerror(v,_SC("invalid free var index")); + break; + case OT_NATIVECLOSURE: + if(_nativeclosure(self)->_outervalues.size()>nval){ + _nativeclosure(self)->_outervalues[nval]=stack_get(v,-1); + } + else return sq_throwerror(v,_SC("invalid free var index")); + break; + default: + return sq_aux_invalidtype(v,type(self)); + } + v->Pop(1); + return SQ_OK; +} + +SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + SQObjectPtr &key = stack_get(v,-2); + SQObjectPtr &val = stack_get(v,-1); + SQObjectPtr attrs; + if(type(key) == OT_NULL) { + attrs = _class(*o)->_attributes; + _class(*o)->_attributes = val; + v->Pop(2); + v->Push(attrs); + return SQ_OK; + }else if(_class(*o)->GetAttributes(key,attrs)) { + _class(*o)->SetAttributes(key,val); + v->Pop(2); + v->Push(attrs); + return SQ_OK; + } + return sq_throwerror(v,_SC("wrong index")); +} + +SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + SQObjectPtr &key = stack_get(v,-1); + SQObjectPtr attrs; + if(type(key) == OT_NULL) { + attrs = _class(*o)->_attributes; + v->Pop(); + v->Push(attrs); + return SQ_OK; + } + else if(_class(*o)->GetAttributes(key,attrs)) { + v->Pop(); + v->Push(attrs); + return SQ_OK; + } + return sq_throwerror(v,_SC("wrong index")); +} + +SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + if(_class(*o)->_base) + v->Push(SQObjectPtr(_class(*o)->_base)); + else + v->Push(_null_); + return SQ_OK; +} + +SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_INSTANCE,o); + v->Push(SQObjectPtr(_instance(*o)->_class)); + return SQ_OK; +} + +SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + v->Push(_class(*o)->CreateInstance()); + return SQ_OK; +} + +void sq_weakref(HSQUIRRELVM v,SQInteger idx) +{ + SQObject &o=stack_get(v,idx); + if(ISREFCOUNTED(type(o))) { + v->Push(_refcounted(o)->GetWeakRef(type(o))); + return; + } + v->Push(o); +} + +SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v,idx); + if(type(o) != OT_WEAKREF) { + return sq_throwerror(v,_SC("the object must be a weakref")); + } + v->Push(_weakref(o)->_obj); + return SQ_OK; +} + +SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t) +{ + SQSharedState *ss = _ss(v); + switch(t) { + case OT_TABLE: v->Push(ss->_table_default_delegate); break; + case OT_ARRAY: v->Push(ss->_array_default_delegate); break; + case OT_STRING: v->Push(ss->_string_default_delegate); break; + case OT_INTEGER: case OT_FLOAT: v->Push(ss->_number_default_delegate); break; + case OT_GENERATOR: v->Push(ss->_generator_default_delegate); break; + case OT_CLOSURE: case OT_NATIVECLOSURE: v->Push(ss->_closure_default_delegate); break; + case OT_THREAD: v->Push(ss->_thread_default_delegate); break; + case OT_CLASS: v->Push(ss->_class_default_delegate); break; + case OT_INSTANCE: v->Push(ss->_instance_default_delegate); break; + case OT_WEAKREF: v->Push(ss->_weakref_default_delegate); break; + default: return sq_throwerror(v,_SC("the type doesn't have a default delegate")); + } + return SQ_OK; +} + +SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val; + if(type(o) == OT_GENERATOR) { + return sq_throwerror(v,_SC("cannot iterate a generator")); + } + int faketojump; + if(!v->FOREACH_OP(o,realkey,val,refpos,0,666,faketojump)) + return SQ_ERROR; + if(faketojump != 666) { + v->Push(realkey); + v->Push(val); + return SQ_OK; + } + return SQ_ERROR; +} + +struct BufState{ + const SQChar *buf; + SQInteger ptr; + SQInteger size; +}; + +SQInteger buf_lexfeed(SQUserPointer file) +{ + BufState *buf=(BufState*)file; + if(buf->size<(buf->ptr+1)) + return 0; + return buf->buf[buf->ptr++]; +} + +SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror) { + BufState buf; + buf.buf = s; + buf.size = size; + buf.ptr = 0; + return sq_compile(v, buf_lexfeed, &buf, sourcename, raiseerror); +} + +void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx) +{ + dest->Push(stack_get(src,idx)); +} + +void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc) +{ + _ss(v)->_printfunc = printfunc; +} + +SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v) +{ + return _ss(v)->_printfunc; +} + +#if !(defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST)) +void *sq_malloc(SQUnsignedInteger size) +{ + return SQ_MALLOC(size); +} + +void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize) +{ + return SQ_REALLOC(p,oldsize,newsize); +} + +void sq_free(void *p,SQUnsignedInteger size) +{ + SQ_FREE(p,size); +} +#endif \ No newline at end of file diff --git a/vscript/languages/squirrel/squirrel/sqarray.h b/vscript/languages/squirrel/squirrel/sqarray.h new file mode 100644 index 00000000..d6f10072 --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqarray.h @@ -0,0 +1,98 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQARRAY_H_ +#define _SQARRAY_H_ + +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#undef new // allow placement new +#endif + +struct SQArray : public CHAINABLE_OBJ +{ +private: + SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);} + ~SQArray() + { + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); + } +public: + static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){ + SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray)); + new (newarray) SQArray(ss,nInitialSize); + return newarray; + } +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); +#endif + void Iterate( CSQStateIterator *pIterator ); + + void Finalize(){ + _values.resize(0); + } + bool Get(const SQInteger nidx,SQObjectPtr &val) + { + if(nidx>=0 && nidx<(SQInteger)_values.size()){ + SQObjectPtr &o = _values[nidx]; + val = _realval(o); + return true; + } + else return false; + } + bool Set(const SQInteger nidx,const SQObjectPtr &val) + { + if(nidx>=0 && nidx<(SQInteger)_values.size()){ + _values[nidx]=val; + return true; + } + else return false; + } + SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval) + { + SQUnsignedInteger idx=TranslateIndex(refpos); + while(idx<_values.size()){ + //first found + outkey=(SQInteger)idx; + SQObjectPtr &o = _values[idx]; + outval = _realval(o); + //return idx for the next iteration + return ++idx; + } + //nothing to iterate anymore + return -1; + } + SQArray *Clone(){SQArray *anew=Create(_opt_ss(this),Size()); anew->_values.copy(_values); return anew; } + SQInteger Size() const {return _values.size();} + void Resize(SQInteger size,SQObjectPtr &fill = _null_) { _values.resize(size,fill); ShrinkIfNeeded(); } + void Reserve(SQInteger size) { _values.reserve(size); } + void Append(const SQObject &o){_values.push_back(o);} + void Extend(const SQArray *a); + SQObjectPtr &Top(){return _values.top();} + void Pop(){_values.pop_back(); ShrinkIfNeeded(); } + bool Insert(SQInteger idx,const SQObject &val){ + if(idx < 0 || idx > (SQInteger)_values.size()) + return false; + _values.insert(idx,val); + return true; + } + void ShrinkIfNeeded() { + if(_values.size() <= _values.capacity()>>2) //shrink the array + _values.shrinktofit(); + } + bool Remove(SQInteger idx){ + if(idx < 0 || idx >= (SQInteger)_values.size()) + return false; + _values.remove(idx); + ShrinkIfNeeded(); + return true; + } + void Release() + { + sq_delete(this,SQArray); + } + SQObjectPtrVec _values; +}; + +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgoff.h" +#endif +#endif //_SQARRAY_H_ diff --git a/vscript/languages/squirrel/squirrel/sqbaselib.cpp b/vscript/languages/squirrel/squirrel/sqbaselib.cpp new file mode 100644 index 00000000..3bede2d6 --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqbaselib.cpp @@ -0,0 +1,917 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqstring.h" +#include "sqtable.h" +#include "sqarray.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "sqclass.h" +#include +#include +#include +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#endif + +bool str2num(const SQChar *s,SQObjectPtr &res) +{ + SQChar *end; + if(scstrstr(s,_SC("."))){ + SQFloat r = SQFloat(scstrtod(s,&end)); + if(s == end) return false; + res = r; + return true; + } + else{ + SQInteger r = SQInteger(scstrtol(s,&end,10)); + if(s == end) return false; + res = r; + return true; + } +} + +static SQInteger base_dummy(HSQUIRRELVM v) +{ + return 0; +} + +#ifndef NO_GARBAGE_COLLECTOR +static SQInteger base_collectgarbage(HSQUIRRELVM v) +{ + sq_pushinteger(v, sq_collectgarbage(v)); + return 1; +} +#endif + +static SQInteger base_getroottable(HSQUIRRELVM v) +{ + v->Push(v->_roottable); + return 1; +} + +static SQInteger base_getconsttable(HSQUIRRELVM v) +{ + v->Push(_ss(v)->_consts); + return 1; +} + + +static SQInteger base_setroottable(HSQUIRRELVM v) +{ + SQObjectPtr &o=stack_get(v,2); + if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR; + v->Push(o); + return 1; +} + +static SQInteger base_setconsttable(HSQUIRRELVM v) +{ + SQObjectPtr &o=stack_get(v,2); + if(SQ_FAILED(sq_setconsttable(v))) return SQ_ERROR; + v->Push(o); + return 1; +} + +static SQInteger base_seterrorhandler(HSQUIRRELVM v) +{ + sq_seterrorhandler(v); + return 0; +} + +static SQInteger base_setdebughook(HSQUIRRELVM v) +{ + sq_setdebughook(v); + return 0; +} + +static SQInteger base_enabledebuginfo(HSQUIRRELVM v) +{ + SQObjectPtr &o=stack_get(v,2); + sq_enabledebuginfo(v,(type(o) != OT_NULL)?1:0); + return 0; +} + +static SQInteger base_getstackinfos(HSQUIRRELVM v) +{ + SQInteger level; + SQStackInfos si; + SQInteger seq = 0; + const SQChar *name = NULL; + sq_getinteger(v, -1, &level); + if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si))) + { + const SQChar *fn = _SC("unknown"); + const SQChar *src = _SC("unknown"); + if(si.funcname)fn = si.funcname; + if(si.source)src = si.source; + sq_newtable(v); + sq_pushstring(v, _SC("func"), -1); + sq_pushstring(v, fn, -1); + sq_createslot(v, -3); + sq_pushstring(v, _SC("src"), -1); + sq_pushstring(v, src, -1); + sq_createslot(v, -3); + sq_pushstring(v, _SC("line"), -1); + sq_pushinteger(v, si.line); + sq_createslot(v, -3); + sq_pushstring(v, _SC("locals"), -1); + sq_newtable(v); + seq=0; + while ((name = sq_getlocal(v, level, seq))) { + sq_pushstring(v, name, -1); + sq_push(v, -2); + sq_createslot(v, -4); + sq_pop(v, 1); + seq++; + } + sq_createslot(v, -3); + return 1; + } + + return 0; +} + +static SQInteger base_assert(HSQUIRRELVM v) +{ + if(v->IsFalse(stack_get(v,2))){ + return sq_throwerror(v,_SC("assertion failed")); + } + return 0; +} + +static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,SQObjectPtr &o) +{ + SQInteger top = sq_gettop(v); + sidx=0; + eidx=0; + o=stack_get(v,1); + SQObjectPtr &start=stack_get(v,2); + if(type(start)!=OT_NULL && sq_isnumeric(start)){ + sidx=tointeger(start); + } + if(top>2){ + SQObjectPtr &end=stack_get(v,3); + if(sq_isnumeric(end)){ + eidx=tointeger(end); + } + } + else { + eidx = sq_getsize(v,1); + } + return 1; +} + +static SQInteger base_print(HSQUIRRELVM v) +{ + const SQChar *str; + sq_tostring(v,2); + sq_getstring(v,-1,&str); + if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),str); + return 0; +} + +static SQInteger base_compilestring(HSQUIRRELVM v) +{ + SQInteger nargs=sq_gettop(v); + const SQChar *src=NULL,*name=_SC("unnamedbuffer"); + SQInteger size; + sq_getstring(v,2,&src); + size=sq_getsize(v,2); + if(nargs>2){ + sq_getstring(v,3,&name); + } + if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse))) + return 1; + else + return SQ_ERROR; +} + +static SQInteger base_newthread(HSQUIRRELVM v) +{ + SQObjectPtr &func = stack_get(v,2); + SQInteger stksize = (_funcproto(_closure(func)->_function)->_stacksize << 1) +2; + HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize); + sq_move(newv,v,-2); + return 1; +} + +static SQInteger base_suspend(HSQUIRRELVM v) +{ + return sq_suspendvm(v); +} + +static SQInteger base_array(HSQUIRRELVM v) +{ + SQArray *a; + SQObject &size = stack_get(v,2); + if(sq_gettop(v) > 2) { + a = SQArray::Create(_ss(v),0); + a->Resize(tointeger(size),stack_get(v,3)); + } + else { + a = SQArray::Create(_ss(v),tointeger(size)); + } + v->Push(a); + return 1; +} + +static SQInteger base_type(HSQUIRRELVM v) +{ + SQObjectPtr &o = stack_get(v,2); + v->Push(SQString::Create(_ss(v),GetTypeName(o),-1)); + return 1; +} + +static SQRegFunction base_funcs[]={ + //generic + {_SC("seterrorhandler"),base_seterrorhandler,2, NULL}, + {_SC("setdebughook"),base_setdebughook,2, NULL}, + {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL}, + {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")}, + {_SC("getroottable"),base_getroottable,1, NULL}, + {_SC("setroottable"),base_setroottable,2, NULL}, + {_SC("getconsttable"),base_getconsttable,1, NULL}, + {_SC("setconsttable"),base_setconsttable,2, NULL}, + {_SC("assert"),base_assert,2, NULL}, + {_SC("print"),base_print,2, NULL}, + {_SC("compilestring"),base_compilestring,-2, _SC(".ss")}, + {_SC("newthread"),base_newthread,2, _SC(".c")}, + {_SC("suspend"),base_suspend,-1, NULL}, + {_SC("array"),base_array,-2, _SC(".n")}, + {_SC("type"),base_type,2, NULL}, + {_SC("dummy"),base_dummy,0,NULL}, +#ifndef NO_GARBAGE_COLLECTOR + {_SC("collectgarbage"),base_collectgarbage,1, _SC("t")}, +#endif + {0,0} +}; + +void sq_base_register(HSQUIRRELVM v) +{ + SQInteger i=0; + sq_pushroottable(v); + while(base_funcs[i].name!=0) { + sq_pushstring(v,base_funcs[i].name,-1); + sq_newclosure(v,base_funcs[i].f,0); + sq_setnativeclosurename(v,-1,base_funcs[i].name); + sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask); + sq_createslot(v,-3); + i++; + } + sq_pushstring(v,_SC("_version_"),-1); + sq_pushstring(v,SQUIRREL_VERSION,-1); + sq_createslot(v,-3); + sq_pushstring(v,_SC("_charsize_"),-1); + sq_pushinteger(v,sizeof(SQChar)); + sq_createslot(v,-3); + sq_pushstring(v,_SC("_intsize_"),-1); + sq_pushinteger(v,sizeof(SQInteger)); + sq_createslot(v,-3); + sq_pushstring(v,_SC("_floatsize_"),-1); + sq_pushinteger(v,sizeof(SQFloat)); + sq_createslot(v,-3); + sq_pop(v,1); +} + +static SQInteger default_delegate_len(HSQUIRRELVM v) +{ + v->Push(SQInteger(sq_getsize(v,1))); + return 1; +} + +static SQInteger default_delegate_tofloat(HSQUIRRELVM v) +{ + SQObjectPtr &o=stack_get(v,1); + switch(type(o)){ + case OT_STRING:{ + SQObjectPtr res; + if(str2num(_stringval(o),res)){ + v->Push(SQObjectPtr(tofloat(res))); + break; + }} + return sq_throwerror(v, _SC("cannot convert the string")); + break; + case OT_INTEGER:case OT_FLOAT: + v->Push(SQObjectPtr(tofloat(o))); + break; + case OT_BOOL: + v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0))); + break; + default: + v->Push(_null_); + break; + } + return 1; +} + +static SQInteger default_delegate_tointeger(HSQUIRRELVM v) +{ + SQObjectPtr &o=stack_get(v,1); + switch(type(o)){ + case OT_STRING:{ + SQObjectPtr res; + if(str2num(_stringval(o),res)){ + v->Push(SQObjectPtr(tointeger(res))); + break; + }} + return sq_throwerror(v, _SC("cannot convert the string")); + break; + case OT_INTEGER:case OT_FLOAT: + v->Push(SQObjectPtr(tointeger(o))); + break; + case OT_BOOL: + v->Push(SQObjectPtr(_integer(o)?(SQInteger)1:(SQInteger)0)); + break; + default: + v->Push(_null_); + break; + } + return 1; +} + +static SQInteger default_delegate_tostring(HSQUIRRELVM v) +{ + sq_tostring(v,1); + return 1; +} + +static SQInteger obj_delegate_weakref(HSQUIRRELVM v) +{ + sq_weakref(v,1); + return 1; +} + +static SQInteger obj_clear(HSQUIRRELVM v) +{ + return sq_clear(v,-1); +} + + +static SQInteger number_delegate_tochar(HSQUIRRELVM v) +{ + SQObject &o=stack_get(v,1); + SQChar c = (SQChar)tointeger(o); + v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1)); + return 1; +} + + +///////////////////////////////////////////////////////////////// +//TABLE DEFAULT DELEGATE + +static SQInteger table_rawdelete(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue))) + return SQ_ERROR; + return 1; +} + + +static SQInteger container_rawexists(HSQUIRRELVM v) +{ + if(SQ_SUCCEEDED(sq_rawget(v,-2))) { + sq_pushbool(v,SQTrue); + return 1; + } + sq_pushbool(v,SQFalse); + return 1; +} + +static SQInteger table_rawset(HSQUIRRELVM v) +{ + return sq_rawset(v,-3); +} + + +static SQInteger table_rawget(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR; +} + + +SQRegFunction SQSharedState::_table_default_delegate_funcz[]={ + {_SC("len"),default_delegate_len,1, _SC("t")}, + {_SC("rawget"),table_rawget,2, _SC("t")}, + {_SC("rawset"),table_rawset,3, _SC("t")}, + {_SC("rawdelete"),table_rawdelete,2, _SC("t")}, + {_SC("rawin"),container_rawexists,2, _SC("t")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("clear"),obj_clear,1, _SC(".")}, + {0,0} +}; + +//ARRAY DEFAULT DELEGATE/////////////////////////////////////// + +static SQInteger array_append(HSQUIRRELVM v) +{ + return sq_arrayappend(v,-2); +} + +static SQInteger array_extend(HSQUIRRELVM v) +{ + _array(stack_get(v,1))->Extend(_array(stack_get(v,2))); + return 0; +} + +static SQInteger array_reverse(HSQUIRRELVM v) +{ + return sq_arrayreverse(v,-1); +} + +static SQInteger array_pop(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR; +} + +static SQInteger array_top(HSQUIRRELVM v) +{ + SQObject &o=stack_get(v,1); + if(_array(o)->Size()>0){ + v->Push(_array(o)->Top()); + return 1; + } + else return sq_throwerror(v,_SC("top() on a empty array")); +} + +static SQInteger array_insert(HSQUIRRELVM v) +{ + SQObject &o=stack_get(v,1); + SQObject &idx=stack_get(v,2); + SQObject &val=stack_get(v,3); + if(!_array(o)->Insert(tointeger(idx),val)) + return sq_throwerror(v,_SC("index out of range")); + return 0; +} + +static SQInteger array_remove(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v, 1); + SQObject &idx = stack_get(v, 2); + if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type")); + SQObjectPtr val; + if(_array(o)->Get(tointeger(idx), val)) { + _array(o)->Remove(tointeger(idx)); + v->Push(val); + return 1; + } + return sq_throwerror(v, _SC("idx out of range")); +} + +static SQInteger array_resize(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v, 1); + SQObject &nsize = stack_get(v, 2); + SQObjectPtr fill; + if(sq_isnumeric(nsize)) { + if(sq_gettop(v) > 2) + fill = stack_get(v, 3); + _array(o)->Resize(tointeger(nsize),fill); + return 0; + } + return sq_throwerror(v, _SC("size must be a number")); +} + + +//QSORT ala Sedgewick +bool _qsort_compare(HSQUIRRELVM v,SQObjectPtr &arr,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret) +{ + if(func < 0) { + if(!v->ObjCmp(a,b,ret)) return false; + } + else { + SQInteger top = sq_gettop(v); + sq_push(v, func); + sq_pushroottable(v); + v->Push(a); + v->Push(b); + if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) { + if(!sq_isstring( v->_lasterror)) + v->Raise_Error(_SC("compare func failed")); + return false; + } + sq_getinteger(v, -1, &ret); + sq_settop(v, top); + return true; + } + return true; +} +//QSORT ala Sedgewick +bool _qsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger func) +{ + SQInteger i, j; + SQArray *a=_array(arr); + SQObjectPtr pivot,t; + if( l < r ){ + pivot = a->_values[l]; + i = l; j = r+1; + while(1){ + SQInteger ret; + do { + ++i; + if(i > r) break; + if(!_qsort_compare(v,arr,a->_values[i],pivot,func,ret)) + return false; + } while( ret <= 0); + do { + --j; + if ( j < 0 ) { + v->Raise_Error( _SC("Invalid qsort, probably compare function defect") ); + return false; + } + if(!_qsort_compare(v,arr,a->_values[j],pivot,func,ret)) + return false; + } + while( ret > 0 ); + if( i >= j ) break; + t = a->_values[i]; a->_values[i] = a->_values[j]; a->_values[j] = t; + } + t = a->_values[l]; a->_values[l] = a->_values[j]; a->_values[j] = t; + if(!_qsort( v, arr, l, j-1,func)) return false; + if(!_qsort( v, arr, j+1, r,func)) return false; + } + return true; +} + +static SQInteger array_sort(HSQUIRRELVM v) +{ + SQInteger func = -1; + SQObjectPtr &o = stack_get(v,1); + SQObject &funcobj = stack_get(v,2); + if(_array(o)->Size() > 1) { + if(type(funcobj) == OT_CLOSURE || type(funcobj) == OT_NATIVECLOSURE) func = 2; + if(!_qsort(v, o, 0, _array(o)->Size()-1, func)) + return SQ_ERROR; + + } + return 0; +} +static SQInteger array_slice(HSQUIRRELVM v) +{ + SQInteger sidx,eidx; + SQObjectPtr o; + if(get_slice_params(v,sidx,eidx,o)==-1)return -1; + SQInteger alen = _array(o)->Size(); + if(sidx < 0)sidx = alen + sidx; + if(eidx < 0)eidx = alen + eidx; + if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes")); + if(eidx > alen)return sq_throwerror(v,_SC("slice out of range")); + SQArray *arr=SQArray::Create(_ss(v),eidx-sidx); + SQObjectPtr t; + SQInteger count=0; + for(SQInteger i=sidx;iGet(i,t); + arr->Set(count++,t); + } + v->Push(arr); + return 1; + +} + +SQRegFunction SQSharedState::_array_default_delegate_funcz[]={ + {_SC("len"),default_delegate_len,1, _SC("a")}, + {_SC("append"),array_append,2, _SC("a")}, + {_SC("extend"),array_extend,2, _SC("aa")}, + {_SC("push"),array_append,2, _SC("a")}, + {_SC("pop"),array_pop,1, _SC("a")}, + {_SC("top"),array_top,1, _SC("a")}, + {_SC("insert"),array_insert,3, _SC("an")}, + {_SC("remove"),array_remove,2, _SC("an")}, + {_SC("resize"),array_resize,-2, _SC("an")}, + {_SC("reverse"),array_reverse,1, _SC("a")}, + {_SC("sort"),array_sort,-1, _SC("ac")}, + {_SC("slice"),array_slice,-1, _SC("ann")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("clear"),obj_clear,1, _SC(".")}, + {0,0} +}; + +//STRING DEFAULT DELEGATE////////////////////////// +static SQInteger string_slice(HSQUIRRELVM v) +{ + SQInteger sidx,eidx; + SQObjectPtr o; + if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1; + SQInteger slen = _string(o)->_len; + if(sidx < 0)sidx = slen + sidx; + if(eidx < 0)eidx = slen + eidx; + if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes")); + if(eidx > slen) return sq_throwerror(v,_SC("slice out of range")); + v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx)); + return 1; +} + +static SQInteger string_find(HSQUIRRELVM v) +{ + SQInteger top,start_idx=0; + const SQChar *str,*substr,*ret; + if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){ + if(top>2)sq_getinteger(v,3,&start_idx); + if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){ + ret=scstrstr(&str[start_idx],substr); + if(ret){ + sq_pushinteger(v,(SQInteger)(ret-str)); + return 1; + } + } + return 0; + } + return sq_throwerror(v,_SC("invalid param")); +} + +#define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \ +{ \ + SQObject str=stack_get(v,1); \ + SQInteger len=_string(str)->_len; \ + const SQChar *sThis=_stringval(str); \ + SQChar *sNew=(_ss(v)->GetScratchPad(rsl(len))); \ + for(SQInteger i=0;iPush(SQString::Create(_ss(v),sNew,len)); \ + return 1; \ +} + + +STRING_TOFUNCZ(tolower) +STRING_TOFUNCZ(toupper) + +SQRegFunction SQSharedState::_string_default_delegate_funcz[]={ + {_SC("len"),default_delegate_len,1, _SC("s")}, + {_SC("tointeger"),default_delegate_tointeger,1, _SC("s")}, + {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")}, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("slice"),string_slice,-1, _SC(" s n n")}, + {_SC("find"),string_find,-2, _SC("s s n ")}, + {_SC("tolower"),string_tolower,1, _SC("s")}, + {_SC("toupper"),string_toupper,1, _SC("s")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {0,0} +}; + +//INTEGER DEFAULT DELEGATE////////////////////////// +SQRegFunction SQSharedState::_number_default_delegate_funcz[]={ + {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")}, + {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")}, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {0,0} +}; + +//CLOSURE DEFAULT DELEGATE////////////////////////// +static SQInteger closure_pcall(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQFalse))?1:SQ_ERROR; +} + +static SQInteger closure_call(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQTrue))?1:SQ_ERROR; +} + +static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror) +{ + SQArray *aparams=_array(stack_get(v,2)); + SQInteger nparams=aparams->Size(); + v->Push(stack_get(v,1)); + for(SQInteger i=0;iPush(aparams->_values[i]); + return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR; +} + +static SQInteger closure_acall(HSQUIRRELVM v) +{ + return _closure_acall(v,SQTrue); +} + +static SQInteger closure_pacall(HSQUIRRELVM v) +{ + return _closure_acall(v,SQFalse); +} + +static SQInteger closure_bindenv(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_bindenv(v,1))) + return SQ_ERROR; + return 1; +} + +static SQInteger closure_getinfos(HSQUIRRELVM v) { + SQObject o = stack_get(v,1); + SQTable *res = SQTable::Create(_ss(v),4); + if(type(o) == OT_CLOSURE) { + SQFunctionProto *f = _funcproto(_closure(o)->_function); + SQInteger nparams = f->_nparameters + (f->_varparams?1:0); + SQObjectPtr params = SQArray::Create(_ss(v),nparams); + for(SQInteger n = 0; n_nparameters; n++) { + _array(params)->Set((SQInteger)n,f->_parameters[n]); + } + if(f->_varparams) { + _array(params)->Set(nparams-1,SQString::Create(_ss(v),_SC("..."),-1)); + } + res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),false); + res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),f->_name); + res->NewSlot(SQString::Create(_ss(v),_SC("src"),-1),f->_sourcename); + res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params); + res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams); + } + else { //OT_NATIVECLOSURE + SQNativeClosure *nc = _nativeclosure(o); + res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true); + res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name); + res->NewSlot(SQString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck); + SQObjectPtr typecheck; + if(nc->_typecheck.size() > 0) { + typecheck = + SQArray::Create(_ss(v), nc->_typecheck.size()); + for(SQUnsignedInteger n = 0; n_typecheck.size(); n++) { + _array(typecheck)->Set((SQInteger)n,nc->_typecheck[n]); + } + } + res->NewSlot(SQString::Create(_ss(v),_SC("typecheck"),-1),typecheck); + } + v->Push(res); + return 1; +} + + +SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={ + {_SC("call"),closure_call,-1, _SC("c")}, + {_SC("pcall"),closure_pcall,-1, _SC("c")}, + {_SC("acall"),closure_acall,2, _SC("ca")}, + {_SC("pacall"),closure_pacall,2, _SC("ca")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")}, + {_SC("getinfos"),closure_getinfos,1, _SC("c")}, + {0,0} +}; + +//GENERATOR DEFAULT DELEGATE +static SQInteger generator_getstatus(HSQUIRRELVM v) +{ + SQObject &o=stack_get(v,1); + switch(_generator(o)->_state){ + case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break; + case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break; + case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break; + } + return 1; +} + +SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={ + {_SC("getstatus"),generator_getstatus,1, _SC("g")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {0,0} +}; + +//THREAD DEFAULT DELEGATE + +static SQInteger thread_call(HSQUIRRELVM v) +{ + + SQObjectPtr o = stack_get(v,1); + if(type(o) == OT_THREAD) { + SQInteger nparams = sq_gettop(v); + _thread(o)->Push(_thread(o)->_roottable); + for(SQInteger i = 2; i<(nparams+1); i++) + sq_move(_thread(o),v,i); + if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQFalse))) { + sq_move(v,_thread(o),-1); + sq_pop(_thread(o),1); + return 1; + } + v->_lasterror = _thread(o)->_lasterror; + return SQ_ERROR; + } + return sq_throwerror(v,_SC("wrong parameter")); +} + +static SQInteger thread_wakeup(HSQUIRRELVM v) +{ + SQObjectPtr o = stack_get(v,1); + if(type(o) == OT_THREAD) { + SQVM *thread = _thread(o); + SQInteger state = sq_getvmstate(thread); + if(state != SQ_VMSTATE_SUSPENDED) { + switch(state) { + case SQ_VMSTATE_IDLE: + return sq_throwerror(v,_SC("cannot wakeup a idle thread")); + break; + case SQ_VMSTATE_RUNNING: + return sq_throwerror(v,_SC("cannot wakeup a running thread")); + break; + } + } + + SQInteger wakeupret = sq_gettop(v)>1?1:0; + if(wakeupret) { + sq_move(thread,v,2); + } + if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,SQTrue,SQTrue,SQFalse))) { + sq_move(v,thread,-1); + sq_pop(thread,1); //pop retval + if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) { + sq_settop(thread,1); //pop roottable + } + return 1; + } + sq_settop(thread,1); + v->_lasterror = thread->_lasterror; + return SQ_ERROR; + } + return sq_throwerror(v,_SC("wrong parameter")); +} + +static SQInteger thread_getstatus(HSQUIRRELVM v) +{ + SQObjectPtr &o = stack_get(v,1); + switch(sq_getvmstate(_thread(o))) { + case SQ_VMSTATE_IDLE: + sq_pushstring(v,_SC("idle"),-1); + break; + case SQ_VMSTATE_RUNNING: + sq_pushstring(v,_SC("running"),-1); + break; + case SQ_VMSTATE_SUSPENDED: + sq_pushstring(v,_SC("suspended"),-1); + break; + default: + return sq_throwerror(v,_SC("internal VM error")); + } + return 1; +} + +SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = { + {_SC("call"), thread_call, -1, _SC("v")}, + {_SC("wakeup"), thread_wakeup, -1, _SC("v")}, + {_SC("getstatus"), thread_getstatus, 1, _SC("v")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {0,0}, +}; + +static SQInteger class_getattributes(HSQUIRRELVM v) +{ + if(SQ_SUCCEEDED(sq_getattributes(v,-2))) + return 1; + return SQ_ERROR; +} + +static SQInteger class_setattributes(HSQUIRRELVM v) +{ + if(SQ_SUCCEEDED(sq_setattributes(v,-3))) + return 1; + return SQ_ERROR; +} + +static SQInteger class_instance(HSQUIRRELVM v) +{ + if(SQ_SUCCEEDED(sq_createinstance(v,-1))) + return 1; + return SQ_ERROR; +} + +SQRegFunction SQSharedState::_class_default_delegate_funcz[] = { + {_SC("getattributes"), class_getattributes, 2, _SC("y.")}, + {_SC("setattributes"), class_setattributes, 3, _SC("y..")}, + {_SC("rawin"),container_rawexists,2, _SC("y")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("instance"),class_instance,1, _SC("y")}, + {0,0} +}; + +static SQInteger instance_getclass(HSQUIRRELVM v) +{ + if(SQ_SUCCEEDED(sq_getclass(v,1))) + return 1; + return SQ_ERROR; +} + +SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = { + {_SC("getclass"), instance_getclass, 1, _SC("x")}, + {_SC("rawin"),container_rawexists,2, _SC("x")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {0,0} +}; + +static SQInteger weakref_ref(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_getweakrefval(v,1))) + return SQ_ERROR; + return 1; +} + +SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = { + {_SC("ref"),weakref_ref,1, _SC("r")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {0,0} +}; + + diff --git a/vscript/languages/squirrel/squirrel/sqclass.cpp b/vscript/languages/squirrel/squirrel/sqclass.cpp new file mode 100644 index 00000000..3b67fadf --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqclass.cpp @@ -0,0 +1,198 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqtable.h" +#include "sqclass.h" +#include "sqclosure.h" +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#undef new // allow placement new +#endif + +SQClass::SQClass(SQSharedState *ss,SQClass *base) +{ + _base = base; + _typetag = 0; + _hook = NULL; + _udsize = 0; + _metamethods.resize(MT_LAST); //size it to max size + if(_base) { + _defaultvalues.copy(base->_defaultvalues); + _methods.copy(base->_methods); + _metamethods.copy(base->_metamethods); + __ObjAddRef(_base); + } + _members = base?base->_members->Clone() : SQTable::Create(ss,0); + __ObjAddRef(_members); + _locked = false; + INIT_CHAIN(); + ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); +} + +void SQClass::Finalize() { + _attributes = _null_; + _defaultvalues.resize(0); + _methods.resize(0); + _metamethods.resize(0); + __ObjRelease(_members); + if(_base) { + __ObjRelease(_base); + } +} + +SQClass::~SQClass() +{ + REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); + Finalize(); +} + +bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic) +{ + SQObjectPtr temp; + if(_locked) + return false; //the class already has an instance so cannot be modified + if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value + { + _defaultvalues[_member_idx(temp)].val = val; + return true; + } + if(type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic) { + SQInteger mmidx; + if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) && + (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) { + _metamethods[mmidx] = val; + } + else { + if(type(temp) == OT_NULL) { + SQClassMember m; + m.val = val; + _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size()))); + _methods.push_back(m); + } + else { + _methods[_member_idx(temp)].val = val; + } + } + return true; + } + SQClassMember m; + m.val = val; + _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size()))); + _defaultvalues.push_back(m); + return true; +} + +SQInstance *SQClass::CreateInstance() +{ + if(!_locked) Lock(); + return SQInstance::Create(_opt_ss(this),this); +} + +SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) +{ + SQObjectPtr oval; + SQInteger idx = _members->Next(false,refpos,outkey,oval); + if(idx != -1) { + if(_ismethod(oval)) { + outval = _methods[_member_idx(oval)].val; + } + else { + SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val; + outval = _realval(o); + } + } + return idx; +} + +bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val) +{ + SQObjectPtr idx; + if(_members->Get(key,idx)) { + if(_isfield(idx)) + _defaultvalues[_member_idx(idx)].attrs = val; + else + _methods[_member_idx(idx)].attrs = val; + return true; + } + return false; +} + +bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval) +{ + SQObjectPtr idx; + if(_members->Get(key,idx)) { + outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs); + return true; + } + return false; +} + +/////////////////////////////////////////////////////////////////////// +void SQInstance::Init(SQSharedState *ss) +{ + _userpointer = NULL; + _hook = NULL; + __ObjAddRef(_class); + _delegate = _class->_members; + INIT_CHAIN(); + ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); +} + +SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize) +{ + _memsize = memsize; + _class = c; + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + for(SQUnsignedInteger n = 0; n < nvalues; n++) { + new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val); + } + Init(ss); +} + +SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize) +{ + _memsize = memsize; + _class = i->_class; + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + for(SQUnsignedInteger n = 0; n < nvalues; n++) { + new (&_values[n]) SQObjectPtr(i->_values[n]); + } + Init(ss); +} + +void SQInstance::Finalize() +{ + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + __ObjRelease(_class); + for(SQUnsignedInteger i = 0; i < nvalues; i++) { + _values[i] = _null_; + } +} + +SQInstance::~SQInstance() +{ + REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); + if(_class){ Finalize(); } //if _class is null it was already finalized by the GC +} + +bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) +{ + if(type(_class->_metamethods[mm]) != OT_NULL) { + res = _class->_metamethods[mm]; + return true; + } + return false; +} + +bool SQInstance::InstanceOf(SQClass *trg) +{ + SQClass *parent = _class; + while(parent != NULL) { + if(parent == trg) + return true; + parent = parent->_base; + } + return false; +} diff --git a/vscript/languages/squirrel/squirrel/sqclass.h b/vscript/languages/squirrel/squirrel/sqclass.h new file mode 100644 index 00000000..fd1361e3 --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqclass.h @@ -0,0 +1,165 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQCLASS_H_ +#define _SQCLASS_H_ +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#undef new // allow placement new +#endif + +struct SQInstance; + +struct SQClassMember { + SQClassMember(){} + SQClassMember(const SQClassMember &o) { + val = o.val; + attrs = o.attrs; + } + SQObjectPtr val; + SQObjectPtr attrs; +}; + +typedef sqvector SQClassMemberVec; + +#define MEMBER_TYPE_METHOD 0x01000000 +#define MEMBER_TYPE_FIELD 0x02000000 + +#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD) +#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD) +#define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i)) +#define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i)) +#define _member_type(o) (_integer(o)&0xFF000000) +#define _member_idx(o) (_integer(o)&0x00FFFFFF) + +struct SQClass : public CHAINABLE_OBJ +{ + SQClass(SQSharedState *ss,SQClass *base); +public: + static SQClass* Create(SQSharedState *ss,SQClass *base) { + SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass)); + new (newclass) SQClass(ss, base); + return newclass; + } + ~SQClass(); + bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic); + bool Get(const SQObjectPtr &key,SQObjectPtr &val) { + if(_members->Get(key,val)) { + if(_isfield(val)) { + SQObjectPtr &o = _defaultvalues[_member_idx(val)].val; + val = _realval(o); + } + else { + val = _methods[_member_idx(val)].val; + } + return true; + } + return false; + } + bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val); + bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval); + void Lock() { _locked = true; if(_base) _base->Lock(); } + void Release() { + if (_hook) { _hook(_typetag,0);} + sq_delete(this, SQClass); + } + void Finalize(); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable ** ); +#endif + void Iterate( CSQStateIterator *pIterator ); + + SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); + SQInstance *CreateInstance(); + SQTable *_members; + SQClass *_base; + SQClassMemberVec _defaultvalues; + SQClassMemberVec _methods; + SQObjectPtrVec _metamethods; + SQObjectPtr _attributes; + SQUserPointer _typetag; + SQRELEASEHOOK _hook; + bool _locked; + SQInteger _udsize; +}; + +#define calcinstancesize(_theclass_) \ + (_theclass_->_udsize + sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0))) + +struct SQInstance : public SQDelegable +{ + void Init(SQSharedState *ss); + SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize); + SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize); +public: + static SQInstance* Create(SQSharedState *ss,SQClass *theclass) { + + SQInteger size = calcinstancesize(theclass); + SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); + new (newinst) SQInstance(ss, theclass,size); + if(theclass->_udsize) { + newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize); + } + return newinst; + } + SQInstance *Clone(SQSharedState *ss) + { + SQInteger size = calcinstancesize(_class); + SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); + new (newinst) SQInstance(ss, this,size); + if(_class->_udsize) { + newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize); + } + return newinst; + } + ~SQInstance(); + bool Get(const SQObjectPtr &key,SQObjectPtr &val) { + if(_class->_members->Get(key,val)) { + if(_isfield(val)) { + SQObjectPtr &o = _values[_member_idx(val)]; + val = _realval(o); + } + else { + val = _class->_methods[_member_idx(val)].val; + } + return true; + } + return false; + } + bool Set(const SQObjectPtr &key,const SQObjectPtr &val) { + SQObjectPtr idx; + if(_class->_members->Get(key,idx) && _isfield(idx)) { + _values[_member_idx(idx)] = val; + return true; + } + return false; + } + void Release() { + SQ_VALIDATE_REF_COUNT( this ); + _uiRef++; + if (_hook) { _hook(_userpointer,0);} + _uiRef--; + SQ_VALIDATE_REF_COUNT( this ); + if(_uiRef > 0) return; + SQInteger size = _memsize; + this->~SQInstance(); + SQ_FREE(this, size); + } + void Finalize(); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable ** ); +#endif + void Iterate( CSQStateIterator *pIterator ); + + bool InstanceOf(SQClass *trg); + bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res); + + SQClass *_class; + SQUserPointer _userpointer; + SQRELEASEHOOK _hook; + SQInteger _memsize; + SQObjectPtr _values[1]; +}; + +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgoff.h" +#endif +#endif //_SQCLASS_H_ diff --git a/vscript/languages/squirrel/squirrel/sqclosure.h b/vscript/languages/squirrel/squirrel/sqclosure.h new file mode 100644 index 00000000..732b3dd7 --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqclosure.h @@ -0,0 +1,139 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQCLOSURE_H_ +#define _SQCLOSURE_H_ +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#undef new // allow placement new +#endif + +#ifdef _X360 +#if defined Yield +#undef Yield +#endif +#endif + +struct SQFunctionProto; + +struct SQClosure : public CHAINABLE_OBJ +{ +private: + SQClosure(SQSharedState *ss,SQFunctionProto *func){_function=func; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);} +public: + static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func){ + SQClosure *nc=(SQClosure*)SQ_MALLOC(sizeof(SQClosure)); + new (nc) SQClosure(ss,func); + return nc; + } + void Release(){ + sq_delete(this,SQClosure); + } + SQClosure *Clone() + { + SQClosure * ret = SQClosure::Create(_opt_ss(this),_funcproto(_function)); + ret->_env = _env; + ret->_outervalues.copy(_outervalues); + ret->_defaultparams.copy(_defaultparams); + return ret; + } + ~SQClosure() + { + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); + } + bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write); + static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize(){_outervalues.resize(0); } +#endif + void Iterate( CSQStateIterator *pIterator ); + + SQObjectPtr _env; + SQObjectPtr _function; + SQObjectPtrVec _outervalues; + SQObjectPtrVec _defaultparams; +}; +////////////////////////////////////////////// +struct SQGenerator : public CHAINABLE_OBJ +{ + enum SQGeneratorState{eRunning,eSuspended,eDead}; +private: + SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);} +public: + static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){ + SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator)); + new (nc) SQGenerator(ss,closure); + return nc; + } + ~SQGenerator() + { + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); + } + void Kill(){ + _state=eDead; + _stack.resize(0); + _closure=_null_;} + void Release(){ + sq_delete(this,SQGenerator); + } + bool Yield(SQVM *v); + bool Resume(SQVM *v,SQInteger target); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize(){_stack.resize(0);_closure=_null_;} +#endif + void Iterate( CSQStateIterator *pIterator ); + + SQObjectPtr _closure; + SQObjectPtrVec _stack; + SQObjectPtrVec _vargsstack; + SQVM::CallInfo _ci; + ExceptionsTraps _etraps; + SQGeneratorState _state; +}; + +struct SQNativeClosure : public CHAINABLE_OBJ +{ +private: + SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); } +public: + static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func) + { + SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(sizeof(SQNativeClosure)); + new (nc) SQNativeClosure(ss,func); + return nc; + } + SQNativeClosure *Clone() + { + SQNativeClosure * ret = SQNativeClosure::Create(_opt_ss(this),_function); + ret->_env = _env; + ret->_name = _name; + ret->_outervalues.copy(_outervalues); + ret->_typecheck.copy(_typecheck); + ret->_nparamscheck = _nparamscheck; + return ret; + } + ~SQNativeClosure() + { + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); + } + void Release(){ + sq_delete(this,SQNativeClosure); + } +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize(){_outervalues.resize(0);} +#endif + void Iterate( CSQStateIterator *pIterator ); + + SQInteger _nparamscheck; + SQIntVec _typecheck; + SQObjectPtrVec _outervalues; + SQObjectPtr _env; + SQFUNCTION _function; + SQObjectPtr _name; +}; + +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgoff.h" +#endif +#endif //_SQCLOSURE_H_ diff --git a/vscript/languages/squirrel/squirrel/sqcompiler.cpp b/vscript/languages/squirrel/squirrel/sqcompiler.cpp new file mode 100644 index 00000000..2ab4cff9 --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqcompiler.cpp @@ -0,0 +1,1358 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include +#include +#include "sqopcodes.h" +#include "sqstring.h" +#include "sqfuncproto.h" +#include "sqcompiler.h" +#include "sqfuncstate.h" +#include "sqlexer.h" +#include "sqvm.h" +#include "sqtable.h" +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#endif + +#define DEREF_NO_DEREF -1 +#define DEREF_FIELD -2 + +struct ExpState +{ + ExpState() + { + _deref = DEREF_NO_DEREF; + _freevar = false; + _class_or_delete = false; + _funcarg = false; + } + bool _class_or_delete; + bool _funcarg; + bool _freevar; + SQInteger _deref; +}; + +typedef sqvector ExpStateVec; + +#define _exst (_expstates.top()) + +#define BEGIN_BREAKBLE_BLOCK() SQInteger __nbreaks__=_fs->_unresolvedbreaks.size(); \ + SQInteger __ncontinues__=_fs->_unresolvedcontinues.size(); \ + _fs->_breaktargets.push_back(0);_fs->_continuetargets.push_back(0); + +#define END_BREAKBLE_BLOCK(continue_target) {__nbreaks__=_fs->_unresolvedbreaks.size()-__nbreaks__; \ + __ncontinues__=_fs->_unresolvedcontinues.size()-__ncontinues__; \ + if(__ncontinues__>0)ResolveContinues(_fs,__ncontinues__,continue_target); \ + if(__nbreaks__>0)ResolveBreaks(_fs,__nbreaks__); \ + _fs->_breaktargets.pop_back();_fs->_continuetargets.pop_back();} + +class SQCompiler +{ +public: + SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo) + { + _vm=v; + _lex.Init(_ss(v), rg, up,ThrowError,this); + _sourcename = SQString::Create(_ss(v), sourcename); + _lineinfo = lineinfo;_raiseerror = raiseerror; + compilererror = NULL; + } + static void ThrowError(void *ud, const SQChar *s) { + SQCompiler *c = (SQCompiler *)ud; + c->Error(s); + } + void Error(const SQChar *s, ...) + { + static SQChar temp[256]; + va_list vl; + va_start(vl, s); + scvsprintf(temp, s, vl); + va_end(vl); + compilererror = temp; + longjmp(_errorjmp,1); + } + void Lex(){ _token = _lex.Lex();} + void PushExpState(){ _expstates.push_back(ExpState()); } + bool IsDerefToken(SQInteger tok) + { + switch(tok){ + case _SC('='): case _SC('('): case TK_NEWSLOT: + case TK_MODEQ: case TK_MULEQ: case TK_DIVEQ: case TK_MINUSEQ: case TK_PLUSEQ: case TK_PLUSPLUS: case TK_MINUSMINUS: return true; + } + return false; + } + ExpState PopExpState() + { + ExpState ret = _expstates.top(); + _expstates.pop_back(); + return ret; + } + SQObject Expect(SQInteger tok) + { + + if(_token != tok) { + if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) { + //ret = SQString::Create(_ss(_vm),_SC("constructor")); + //do nothing + } + else { + const SQChar *etypename; + if(tok > 255) { + switch(tok) + { + case TK_IDENTIFIER: + etypename = _SC("IDENTIFIER"); + break; + case TK_STRING_LITERAL: + etypename = _SC("STRING_LITERAL"); + break; + case TK_INTEGER: + etypename = _SC("INTEGER"); + break; + case TK_FLOAT: + etypename = _SC("FLOAT"); + break; + default: + etypename = _lex.Tok2Str(tok); + } + Error(_SC("expected '%s'"), etypename); + } + Error(_SC("expected '%c'"), tok); + } + } + SQObjectPtr ret; + switch(tok) + { + case TK_IDENTIFIER: + ret = _fs->CreateString(_lex._svalue); + break; + case TK_STRING_LITERAL: + ret = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1); + break; + case TK_INTEGER: + ret = SQObjectPtr(_lex._nvalue); + break; + case TK_FLOAT: + ret = SQObjectPtr(_lex._fvalue); + break; + } + Lex(); + return ret; + } + bool IsEndOfStatement() { return ((_lex._prevtoken == _SC('\n')) || (_token == SQUIRREL_EOB) || (_token == _SC('}')) || (_token == _SC(';'))); } + void OptionalSemicolon() + { + if(_token == _SC(';')) { Lex(); return; } + if(!IsEndOfStatement()) { + Error(_SC("end of statement expected (; or lf)")); + } + } + void MoveIfCurrentTargetIsLocal() { + SQInteger trg = _fs->TopTarget(); + if(_fs->IsLocal(trg)) { + trg = _fs->PopTarget(); //no pops the target and move it + _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), trg); + } + } + bool Compile(SQObjectPtr &o) + { + _debugline = 1; + _debugop = 0; + + SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this); + funcstate._name = SQString::Create(_ss(_vm), _SC("main")); + _fs = &funcstate; + _fs->AddParameter(_fs->CreateString(_SC("this"))); + _fs->_sourcename = _sourcename; + SQInteger stacksize = _fs->GetStackSize(); + if(setjmp(_errorjmp) == 0) { + Lex(); + while(_token > 0){ + Statement(); + if(_lex._prevtoken != _SC('}')) OptionalSemicolon(); + } + CleanStack(stacksize); + _fs->AddLineInfos(_lex._currentline, _lineinfo, true); + _fs->AddInstruction(_OP_RETURN, 0xFF); + _fs->SetStackSize(0); + o =_fs->BuildProto(); +#ifdef _DEBUG_DUMP + _fs->Dump(_funcproto(o)); +#endif + } + else { + if(_raiseerror && _ss(_vm)->_compilererrorhandler) { + _ss(_vm)->_compilererrorhandler(_vm, compilererror, type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"), + _lex._currentline, _lex._currentcolumn); + } + _vm->_lasterror = SQString::Create(_ss(_vm), compilererror, -1); + return false; + } + return true; + } + void Statements() + { + while(_token != _SC('}') && _token != TK_DEFAULT && _token != TK_CASE) { + Statement(); + if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon(); + } + } + void Statement() + { + _fs->AddLineInfos(_lex._currentline, _lineinfo); + switch(_token){ + case _SC(';'): Lex(); break; + case TK_IF: IfStatement(); break; + case TK_WHILE: WhileStatement(); break; + case TK_DO: DoWhileStatement(); break; + case TK_FOR: ForStatement(); break; + case TK_FOREACH: ForEachStatement(); break; + case TK_SWITCH: SwitchStatement(); break; + case TK_LOCAL: LocalDeclStatement(); break; + case TK_RETURN: + case TK_YIELD: { + SQOpcode op; + if(_token == TK_RETURN) { + op = _OP_RETURN; + + } + else { + op = _OP_YIELD; + _fs->_bgenerator = true; + } + Lex(); + if(!IsEndOfStatement()) { + SQInteger retexp = _fs->GetCurrentPos()+1; + CommaExpr(); + if(op == _OP_RETURN && _fs->_traps > 0) + _fs->AddInstruction(_OP_POPTRAP, _fs->_traps, 0); + _fs->_returnexp = retexp; + _fs->AddInstruction(op, 1, _fs->PopTarget()); + } + else{ + if(op == _OP_RETURN && _fs->_traps > 0) + _fs->AddInstruction(_OP_POPTRAP, _fs->_traps ,0); + _fs->_returnexp = -1; + _fs->AddInstruction(op, 0xFF); + } + break;} + case TK_BREAK: + if(_fs->_breaktargets.size() <= 0)Error(_SC("'break' has to be in a loop block")); + if(_fs->_breaktargets.top() > 0){ + _fs->AddInstruction(_OP_POPTRAP, _fs->_breaktargets.top(), 0); + } + _fs->AddInstruction(_OP_JMP, 0, -1234); + _fs->_unresolvedbreaks.push_back(_fs->GetCurrentPos()); + Lex(); + break; + case TK_CONTINUE: + if(_fs->_continuetargets.size() <= 0)Error(_SC("'continue' has to be in a loop block")); + if(_fs->_continuetargets.top() > 0) { + _fs->AddInstruction(_OP_POPTRAP, _fs->_continuetargets.top(), 0); + } + _fs->AddInstruction(_OP_JMP, 0, -1234); + _fs->_unresolvedcontinues.push_back(_fs->GetCurrentPos()); + Lex(); + break; + case TK_FUNCTION: + FunctionStatement(); + break; + case TK_CLASS: + ClassStatement(); + break; + case TK_ENUM: + EnumStatement(); + break; + case _SC('{'):{ + SQInteger stacksize = _fs->GetStackSize(); + Lex(); + Statements(); + Expect(_SC('}')); + _fs->SetStackSize(stacksize); + } + break; + case TK_TRY: + TryCatchStatement(); + break; + case TK_THROW: + Lex(); + CommaExpr(); + _fs->AddInstruction(_OP_THROW, _fs->PopTarget()); + break; + case TK_CONST: + { + Lex(); + SQObject id = Expect(TK_IDENTIFIER); + Expect('='); + SQObject val = ExpectScalar(); + OptionalSemicolon(); + SQTable *enums = _table(_ss(_vm)->_consts); + SQObjectPtr strongid = id; + enums->NewSlot(strongid,SQObjectPtr(val)); + strongid.Null(); + } + break; + default: + CommaExpr(); + _fs->PopTarget(); + break; + } + _fs->SnoozeOpt(); + } + void EmitDerefOp(SQOpcode op) + { + SQInteger val = _fs->PopTarget(); + SQInteger key = _fs->PopTarget(); + SQInteger src = _fs->PopTarget(); + _fs->AddInstruction(op,_fs->PushTarget(),src,key,val); + } + void Emit2ArgsOP(SQOpcode op, SQInteger p3 = 0) + { + SQInteger p2 = _fs->PopTarget(); //src in OP_GET + SQInteger p1 = _fs->PopTarget(); //key in OP_GET + _fs->AddInstruction(op,_fs->PushTarget(), p1, p2, p3); + } + void EmitCompoundArith(SQInteger tok,bool deref) + { + SQInteger oper; + switch(tok){ + case TK_MINUSEQ: oper = '-'; break; + case TK_PLUSEQ: oper = '+'; break; + case TK_MULEQ: oper = '*'; break; + case TK_DIVEQ: oper = '/'; break; + case TK_MODEQ: oper = '%'; break; + default: oper = 0; //shut up compiler + Assert(0); break; + }; + if(deref) { + SQInteger val = _fs->PopTarget(); + SQInteger key = _fs->PopTarget(); + SQInteger src = _fs->PopTarget(); + //mixes dest obj and source val in the arg1(hack?) + _fs->AddInstruction(_OP_COMPARITH,_fs->PushTarget(),(src<<16)|val,key,oper); + } + else { + Emit2ArgsOP(_OP_COMPARITHL, oper); + } + } + void CommaExpr() + { + for(Expression();_token == ',';_fs->PopTarget(), Lex(), CommaExpr()); + } + ExpState Expression(bool funcarg = false) + { + PushExpState(); + _exst._class_or_delete = false; + _exst._funcarg = funcarg; + LogicalOrExp(); + switch(_token) { + case _SC('='): + case TK_NEWSLOT: + case TK_MINUSEQ: + case TK_PLUSEQ: + case TK_MULEQ: + case TK_DIVEQ: + case TK_MODEQ: + { + SQInteger op = _token; + SQInteger ds = _exst._deref; + bool freevar = _exst._freevar; + if(ds == DEREF_NO_DEREF) Error(_SC("can't assign expression")); + Lex(); Expression(); + + switch(op){ + case TK_NEWSLOT: + if(freevar) Error(_SC("free variables cannot be modified")); + if(ds == DEREF_FIELD) + EmitDerefOp(_OP_NEWSLOT); + else //if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local + Error(_SC("can't 'create' a local slot")); + break; + case _SC('='): //ASSIGN + if(freevar) Error(_SC("free variables cannot be modified")); + if(ds == DEREF_FIELD) + EmitDerefOp(_OP_SET); + else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local + SQInteger p2 = _fs->PopTarget(); //src in OP_GET + SQInteger p1 = _fs->TopTarget(); //key in OP_GET + _fs->AddInstruction(_OP_MOVE, p1, p2); + } + break; + case TK_MINUSEQ: + case TK_PLUSEQ: + case TK_MULEQ: + case TK_DIVEQ: + case TK_MODEQ: + EmitCompoundArith(op,ds == DEREF_FIELD); + break; + } + } + break; + case _SC('?'): { + Lex(); + _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); + SQInteger jzpos = _fs->GetCurrentPos(); + SQInteger trg = _fs->PushTarget(); + Expression(); + SQInteger first_exp = _fs->PopTarget(); + if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); + SQInteger endfirstexp = _fs->GetCurrentPos(); + _fs->AddInstruction(_OP_JMP, 0, 0); + Expect(_SC(':')); + SQInteger jmppos = _fs->GetCurrentPos(); + Expression(); + SQInteger second_exp = _fs->PopTarget(); + if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); + _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos); + _fs->SetIntructionParam(jzpos, 1, endfirstexp - jzpos + 1); + _fs->SnoozeOpt(); + } + break; + } + return PopExpState(); + } + void BIN_EXP(SQOpcode op, void (SQCompiler::*f)(void),SQInteger op3 = 0) + { + Lex(); (this->*f)(); + SQInteger op1 = _fs->PopTarget();SQInteger op2 = _fs->PopTarget(); + _fs->AddInstruction(op, _fs->PushTarget(), op1, op2, op3); + } + void LogicalOrExp() + { + LogicalAndExp(); + for(;;) if(_token == TK_OR) { + SQInteger first_exp = _fs->PopTarget(); + SQInteger trg = _fs->PushTarget(); + _fs->AddInstruction(_OP_OR, trg, 0, first_exp, 0); + SQInteger jpos = _fs->GetCurrentPos(); + if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); + Lex(); LogicalOrExp(); + _fs->SnoozeOpt(); + SQInteger second_exp = _fs->PopTarget(); + if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); + _fs->SnoozeOpt(); + _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos)); + break; + }else return; + } + void LogicalAndExp() + { + BitwiseOrExp(); + for(;;) switch(_token) { + case TK_AND: { + SQInteger first_exp = _fs->PopTarget(); + SQInteger trg = _fs->PushTarget(); + _fs->AddInstruction(_OP_AND, trg, 0, first_exp, 0); + SQInteger jpos = _fs->GetCurrentPos(); + if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); + Lex(); LogicalAndExp(); + _fs->SnoozeOpt(); + SQInteger second_exp = _fs->PopTarget(); + if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); + _fs->SnoozeOpt(); + _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos)); + break; + } + case TK_IN: BIN_EXP(_OP_EXISTS, &SQCompiler::BitwiseOrExp); break; + case TK_INSTANCEOF: BIN_EXP(_OP_INSTANCEOF, &SQCompiler::BitwiseOrExp); break; + default: + return; + } + } + void BitwiseOrExp() + { + BitwiseXorExp(); + for(;;) if(_token == _SC('|')) + {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseXorExp,BW_OR); + }else return; + } + void BitwiseXorExp() + { + BitwiseAndExp(); + for(;;) if(_token == _SC('^')) + {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseAndExp,BW_XOR); + }else return; + } + void BitwiseAndExp() + { + CompExp(); + for(;;) if(_token == _SC('&')) + {BIN_EXP(_OP_BITW, &SQCompiler::CompExp,BW_AND); + }else return; + } + void CompExp() + { + ShiftExp(); + for(;;) switch(_token) { + case TK_EQ: BIN_EXP(_OP_EQ, &SQCompiler::ShiftExp); break; + case _SC('>'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_G); break; + case _SC('<'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_L); break; + case TK_GE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_GE); break; + case TK_LE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_LE); break; + case TK_NE: BIN_EXP(_OP_NE, &SQCompiler::ShiftExp); break; + default: return; + } + } + void ShiftExp() + { + PlusExp(); + for(;;) switch(_token) { + case TK_USHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_USHIFTR); break; + case TK_SHIFTL: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTL); break; + case TK_SHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTR); break; + default: return; + } + } + void PlusExp() + { + MultExp(); + for(;;) switch(_token) { + case _SC('+'): case _SC('-'): + BIN_EXP(_OP_ARITH, &SQCompiler::MultExp,_token); break; + default: return; + } + } + + void MultExp() + { + PrefixedExpr(); + for(;;) switch(_token) { + case _SC('*'): case _SC('/'): case _SC('%'): + BIN_EXP(_OP_ARITH, &SQCompiler::PrefixedExpr,_token); break; + default: return; + } + } + //if 'pos' != -1 the previous variable is a local variable + void PrefixedExpr() + { + SQInteger pos = Factor(); + for(;;) { + switch(_token) { + case _SC('.'): { + pos = -1; + Lex(); + if(_token == TK_PARENT) { + Lex(); + if(!NeedGet()) + Error(_SC("parent cannot be set")); + SQInteger src = _fs->PopTarget(); + _fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), src); + } + else { + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER))); + if(NeedGet()) Emit2ArgsOP(_OP_GET); + } + _exst._deref = DEREF_FIELD; + _exst._freevar = false; + } + break; + case _SC('['): + if(_lex._prevtoken == _SC('\n')) Error(_SC("cannot brake deref/or comma needed after [exp]=exp slot declaration")); + Lex(); Expression(); Expect(_SC(']')); + pos = -1; + if(NeedGet()) Emit2ArgsOP(_OP_GET); + _exst._deref = DEREF_FIELD; + _exst._freevar = false; + break; + case TK_MINUSMINUS: + case TK_PLUSPLUS: + if(_exst._deref != DEREF_NO_DEREF && !IsEndOfStatement()) { + SQInteger tok = _token; Lex(); + if(pos < 0) + Emit2ArgsOP(_OP_PINC,tok == TK_MINUSMINUS?-1:1); + else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local + SQInteger src = _fs->PopTarget(); + _fs->AddInstruction(_OP_PINCL, _fs->PushTarget(), src, 0, tok == TK_MINUSMINUS?-1:1); + } + + } + return; + break; + case _SC('('): + { + if(_exst._deref != DEREF_NO_DEREF) { + if(pos<0) { + SQInteger key = _fs->PopTarget(); //key + SQInteger table = _fs->PopTarget(); //table etc... + SQInteger closure = _fs->PushTarget(); + SQInteger ttarget = _fs->PushTarget(); + _fs->AddInstruction(_OP_PREPCALL, closure, key, table, ttarget); + } + else{ + _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0); + } + } + else + _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0); + _exst._deref = DEREF_NO_DEREF; + Lex(); + FunctionCallArgs(); + } + break; + default: return; + } + } + } + SQInteger Factor() + { + switch(_token) + { + case TK_STRING_LITERAL: { + //SQObjectPtr id(SQString::Create(_ss(_vm), _lex._svalue,_lex._longstr.size()-1)); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1))); + Lex(); + } + break; + case TK_VARGC: Lex(); _fs->AddInstruction(_OP_VARGC, _fs->PushTarget()); break; + case TK_VARGV: { Lex(); + Expect(_SC('[')); + Expression(); + Expect(_SC(']')); + SQInteger src = _fs->PopTarget(); + _fs->AddInstruction(_OP_GETVARGV, _fs->PushTarget(), src); + } + break; + case TK_IDENTIFIER: + case TK_CONSTRUCTOR: + case TK_THIS:{ + _exst._freevar = false; + SQObject id; + SQObject constant; + switch(_token) { + case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break; + case TK_THIS: id = _fs->CreateString(_SC("this")); break; + case TK_CONSTRUCTOR: id = _fs->CreateString(_SC("constructor")); break; + } + SQInteger pos = -1; + Lex(); + if((pos = _fs->GetLocalVariable(id)) == -1) { + //checks if is a free variable + if((pos = _fs->GetOuterVariable(id)) != -1) { + _exst._deref = _fs->PushTarget(); + _fs->AddInstruction(_OP_LOADFREEVAR, _exst._deref ,pos); + _exst._freevar = true; + } + else if(_fs->IsConstant(id,constant)) { //line 634 + SQObjectPtr constval; + SQObject constid; + if(type(constant) == OT_TABLE) { + Expect('.'); constid = Expect(TK_IDENTIFIER); + if(!_table(constant)->Get(constid,constval)) { + constval.Null(); + Error(_SC("invalid constant [%s.%s]"), _stringval(id),_stringval(constid)); + } + } + else { + constval = constant; + } + _exst._deref = _fs->PushTarget(); + SQObjectType ctype = type(constval); + if(ctype == OT_INTEGER && (_integer(constval) & (~0x7FFFFFFF)) == 0) { + _fs->AddInstruction(_OP_LOADINT, _exst._deref,_integer(constval)); + } + else if(ctype == OT_FLOAT && sizeof(SQFloat) == sizeof(SQInt32)) { + SQFloat f = _float(constval); + _fs->AddInstruction(_OP_LOADFLOAT, _exst._deref,*((SQInt32 *)&f)); + } + else { + _fs->AddInstruction(_OP_LOAD, _exst._deref, _fs->GetConstant(constval)); + } + + _exst._freevar = true; + } + else { + _fs->PushTarget(0); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); + if(NeedGet()) Emit2ArgsOP(_OP_GET); + _exst._deref = DEREF_FIELD; + } + } + + else{ + _fs->PushTarget(pos); + _exst._deref = pos; + } + return _exst._deref; + } + break; + case TK_PARENT: Lex();_fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), 0); break; + case TK_DOUBLE_COLON: // "::" + _fs->AddInstruction(_OP_LOADROOTTABLE, _fs->PushTarget()); + _exst._deref = DEREF_FIELD; + _token = _SC('.'); //hack + return -1; + break; + case TK_NULL: + _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1); + Lex(); + break; + case TK_INTEGER: { + if((_lex._nvalue & (~0x7FFFFFFF)) == 0) { //does it fit in 32 bits? + _fs->AddInstruction(_OP_LOADINT, _fs->PushTarget(),_lex._nvalue); + } + else { + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._nvalue)); + } + Lex(); + } + break; + case TK_FLOAT: + if(sizeof(SQFloat) == sizeof(SQInt32)) { + _fs->AddInstruction(_OP_LOADFLOAT, _fs->PushTarget(),*((SQInt32 *)&_lex._fvalue)); + } + else { + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._fvalue)); + } + Lex(); + break; + case TK_TRUE: case TK_FALSE: + _fs->AddInstruction(_OP_LOADBOOL, _fs->PushTarget(),_token == TK_TRUE?1:0); + Lex(); + break; + case _SC('['): { + _fs->AddInstruction(_OP_NEWARRAY, _fs->PushTarget()); + SQInteger apos = _fs->GetCurrentPos(),key = 0; + Lex(); + while(_token != _SC(']')) { + Expression(); + if(_token == _SC(',')) Lex(); + SQInteger val = _fs->PopTarget(); + SQInteger array = _fs->TopTarget(); + _fs->AddInstruction(_OP_APPENDARRAY, array, val); + key++; + } + _fs->SetIntructionParam(apos, 1, key); + Lex(); + } + break; + case _SC('{'):{ + _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget()); + Lex();ParseTableOrClass(_SC(',')); + } + break; + case TK_FUNCTION: FunctionExp(_token);break; + case TK_CLASS: Lex(); ClassExp();break; + case _SC('-'): UnaryOP(_OP_NEG); break; + case _SC('!'): UnaryOP(_OP_NOT); break; + case _SC('~'): UnaryOP(_OP_BWNOT); break; + case TK_TYPEOF : UnaryOP(_OP_TYPEOF); break; + case TK_RESUME : UnaryOP(_OP_RESUME); break; + case TK_CLONE : UnaryOP(_OP_CLONE); break; + case TK_MINUSMINUS : + case TK_PLUSPLUS :PrefixIncDec(_token); break; + case TK_DELETE : DeleteExpr(); break; + case TK_DELEGATE : DelegateExpr(); break; + case _SC('('): Lex(); CommaExpr(); Expect(_SC(')')); + break; + default: Error(_SC("expression expected")); + } + return -1; + } + void UnaryOP(SQOpcode op) + { + Lex(); PrefixedExpr(); + SQInteger src = _fs->PopTarget(); + _fs->AddInstruction(op, _fs->PushTarget(), src); + } + bool NeedGet() + { + switch(_token) { + case _SC('='): case _SC('('): case TK_NEWSLOT: case TK_PLUSPLUS: case TK_MINUSMINUS: + case TK_PLUSEQ: case TK_MINUSEQ: case TK_MULEQ: case TK_DIVEQ: case TK_MODEQ: + return false; + } + return (!_exst._class_or_delete) || (_exst._class_or_delete && (_token == _SC('.') || _token == _SC('['))); + } + + void FunctionCallArgs() + { + SQInteger nargs = 1;//this + while(_token != _SC(')')) { + Expression(true); + MoveIfCurrentTargetIsLocal(); + nargs++; + if(_token == _SC(',')){ + Lex(); + if(_token == ')') Error(_SC("expression expected, found ')'")); + } + } + Lex(); + for(SQInteger i = 0; i < (nargs - 1); i++) _fs->PopTarget(); + SQInteger stackbase = _fs->PopTarget(); + SQInteger closure = _fs->PopTarget(); + _fs->AddInstruction(_OP_CALL, _fs->PushTarget(), closure, stackbase, nargs); + } + void ParseTableOrClass(SQInteger separator,SQInteger terminator = '}') + { + SQInteger tpos = _fs->GetCurrentPos(),nkeys = 0; + + while(_token != terminator) { + bool hasattrs = false; + bool isstatic = false; + //check if is an attribute + if(separator == ';') { + if(_token == TK_ATTR_OPEN) { + _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget()); Lex(); + ParseTableOrClass(',',TK_ATTR_CLOSE); + hasattrs = true; + } + if(_token == TK_STATIC) { + isstatic = true; + Lex(); + } + } + switch(_token) { + case TK_FUNCTION: + case TK_CONSTRUCTOR:{ + SQInteger tk = _token; + Lex(); + SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor")); + Expect(_SC('(')); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); + CreateFunction(id); + _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0); + } + break; + case _SC('['): + Lex(); CommaExpr(); Expect(_SC(']')); + Expect(_SC('=')); Expression(); + break; + default : + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER))); + Expect(_SC('=')); Expression(); + } + + if(_token == separator) Lex();//optional comma/semicolon + nkeys++; + SQInteger val = _fs->PopTarget(); + SQInteger key = _fs->PopTarget(); + SQInteger attrs = hasattrs ? _fs->PopTarget():-1; + Assert(hasattrs && attrs == key-1 || !hasattrs); + unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0); + SQInteger table = _fs->TopTarget(); //<AddInstruction(_OP_NEWSLOTA, flags, table, key, val); + //_fs->PopTarget(); + } + if(separator == _SC(',')) //hack recognizes a table from the separator + _fs->SetIntructionParam(tpos, 1, nkeys); + Lex(); + } + void LocalDeclStatement() + { + SQObject varname; + do { + Lex(); varname = Expect(TK_IDENTIFIER); + if(_token == _SC('=')) { + Lex(); Expression(); + SQInteger src = _fs->PopTarget(); + SQInteger dest = _fs->PushTarget(); + if(dest != src) _fs->AddInstruction(_OP_MOVE, dest, src); + } + else{ + _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1); + } + _fs->PopTarget(); + _fs->PushLocalVariable(varname); + + } while(_token == _SC(',')); + } + void IfStatement() + { + SQInteger jmppos; + bool haselse = false; + Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); + _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); + SQInteger jnepos = _fs->GetCurrentPos(); + SQInteger stacksize = _fs->GetStackSize(); + + Statement(); + // + if(_token != _SC('}') && _token != TK_ELSE) OptionalSemicolon(); + + CleanStack(stacksize); + SQInteger endifblock = _fs->GetCurrentPos(); + if(_token == TK_ELSE){ + haselse = true; + stacksize = _fs->GetStackSize(); + _fs->AddInstruction(_OP_JMP); + jmppos = _fs->GetCurrentPos(); + Lex(); + Statement(); OptionalSemicolon(); + CleanStack(stacksize); + _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos); + } + _fs->SetIntructionParam(jnepos, 1, endifblock - jnepos + (haselse?1:0)); + } + void WhileStatement() + { + SQInteger jzpos, jmppos; + SQInteger stacksize = _fs->GetStackSize(); + jmppos = _fs->GetCurrentPos(); + Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); + + BEGIN_BREAKBLE_BLOCK(); + _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); + jzpos = _fs->GetCurrentPos(); + stacksize = _fs->GetStackSize(); + + Statement(); + + CleanStack(stacksize); + _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1); + _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos); + + END_BREAKBLE_BLOCK(jmppos); + } + void DoWhileStatement() + { + Lex(); + SQInteger jzpos = _fs->GetCurrentPos(); + SQInteger stacksize = _fs->GetStackSize(); + BEGIN_BREAKBLE_BLOCK() + Statement(); + CleanStack(stacksize); + Expect(TK_WHILE); + SQInteger continuetrg = _fs->GetCurrentPos(); + Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); + _fs->AddInstruction(_OP_JNZ, _fs->PopTarget(), jzpos - _fs->GetCurrentPos() - 1); + END_BREAKBLE_BLOCK(continuetrg); + } + void ForStatement() + { + Lex(); + SQInteger stacksize = _fs->GetStackSize(); + Expect(_SC('(')); + if(_token == TK_LOCAL) LocalDeclStatement(); + else if(_token != _SC(';')){ + CommaExpr(); + _fs->PopTarget(); + } + Expect(_SC(';')); + _fs->SnoozeOpt(); + SQInteger jmppos = _fs->GetCurrentPos(); + SQInteger jzpos = -1; + if(_token != _SC(';')) { CommaExpr(); _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); jzpos = _fs->GetCurrentPos(); } + Expect(_SC(';')); + _fs->SnoozeOpt(); + SQInteger expstart = _fs->GetCurrentPos() + 1; + if(_token != _SC(')')) { + CommaExpr(); + _fs->PopTarget(); + } + Expect(_SC(')')); + _fs->SnoozeOpt(); + SQInteger expend = _fs->GetCurrentPos(); + SQInteger expsize = (expend - expstart) + 1; + SQInstructionVec exp; + if(expsize > 0) { + for(SQInteger i = 0; i < expsize; i++) + exp.push_back(_fs->GetInstruction(expstart + i)); + _fs->PopInstructions(expsize); + } + BEGIN_BREAKBLE_BLOCK() + Statement(); + SQInteger continuetrg = _fs->GetCurrentPos(); + if(expsize > 0) { + for(SQInteger i = 0; i < expsize; i++) + _fs->AddInstruction(exp[i]); + } + _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1, 0); + if(jzpos> 0) _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos); + CleanStack(stacksize); + + END_BREAKBLE_BLOCK(continuetrg); + } + void ForEachStatement() + { + SQObject idxname, valname; + Lex(); Expect(_SC('(')); valname = Expect(TK_IDENTIFIER); + if(_token == _SC(',')) { + idxname = valname; + Lex(); valname = Expect(TK_IDENTIFIER); + } + else{ + idxname = _fs->CreateString(_SC("@INDEX@")); + } + Expect(TK_IN); + + //save the stack size + SQInteger stacksize = _fs->GetStackSize(); + //put the table in the stack(evaluate the table expression) + Expression(); Expect(_SC(')')); + SQInteger container = _fs->TopTarget(); + //push the index local var + SQInteger indexpos = _fs->PushLocalVariable(idxname); + _fs->AddInstruction(_OP_LOADNULLS, indexpos,1); + //push the value local var + SQInteger valuepos = _fs->PushLocalVariable(valname); + _fs->AddInstruction(_OP_LOADNULLS, valuepos,1); + //push reference index + SQInteger itrpos = _fs->PushLocalVariable(_fs->CreateString(_SC("@ITERATOR@"))); //use invalid id to make it inaccessible + _fs->AddInstruction(_OP_LOADNULLS, itrpos,1); + SQInteger jmppos = _fs->GetCurrentPos(); + _fs->AddInstruction(_OP_FOREACH, container, 0, indexpos); + SQInteger foreachpos = _fs->GetCurrentPos(); + _fs->AddInstruction(_OP_POSTFOREACH, container, 0, indexpos); + //generate the statement code + BEGIN_BREAKBLE_BLOCK() + Statement(); + _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1); + _fs->SetIntructionParam(foreachpos, 1, _fs->GetCurrentPos() - foreachpos); + _fs->SetIntructionParam(foreachpos + 1, 1, _fs->GetCurrentPos() - foreachpos); + //restore the local variable stack(remove index,val and ref idx) + CleanStack(stacksize); + END_BREAKBLE_BLOCK(foreachpos - 1); + } + void SwitchStatement() + { + Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); + Expect(_SC('{')); + SQInteger expr = _fs->TopTarget(); + bool bfirst = true; + SQInteger tonextcondjmp = -1; + SQInteger skipcondjmp = -1; + SQInteger __nbreaks__ = _fs->_unresolvedbreaks.size(); + _fs->_breaktargets.push_back(0); + while(_token == TK_CASE) { + //_fs->AddLineInfos(_lex._currentline, _lineinfo); think about this one + if(!bfirst) { + _fs->AddInstruction(_OP_JMP, 0, 0); + skipcondjmp = _fs->GetCurrentPos(); + _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp); + } + //condition + Lex(); Expression(); Expect(_SC(':')); + SQInteger trg = _fs->PopTarget(); + _fs->AddInstruction(_OP_EQ, trg, trg, expr); + _fs->AddInstruction(_OP_JZ, trg, 0); + //end condition + if(skipcondjmp != -1) { + _fs->SetIntructionParam(skipcondjmp, 1, (_fs->GetCurrentPos() - skipcondjmp)); + } + tonextcondjmp = _fs->GetCurrentPos(); + SQInteger stacksize = _fs->GetStackSize(); + Statements(); + _fs->SetStackSize(stacksize); + bfirst = false; + } + if(tonextcondjmp != -1) + _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp); + if(_token == TK_DEFAULT) { + // _fs->AddLineInfos(_lex._currentline, _lineinfo); + Lex(); Expect(_SC(':')); + SQInteger stacksize = _fs->GetStackSize(); + Statements(); + _fs->SetStackSize(stacksize); + } + Expect(_SC('}')); + _fs->PopTarget(); + __nbreaks__ = _fs->_unresolvedbreaks.size() - __nbreaks__; + if(__nbreaks__ > 0)ResolveBreaks(_fs, __nbreaks__); + _fs->_breaktargets.pop_back(); + + } + void FunctionStatement() + { + SQObject id; + Lex(); id = Expect(TK_IDENTIFIER); + _fs->PushTarget(0); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); + if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET); + + while(_token == TK_DOUBLE_COLON) { + Lex(); + id = Expect(TK_IDENTIFIER); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); + if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET); + } + Expect(_SC('(')); + CreateFunction(id); + _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0); + EmitDerefOp(_OP_NEWSLOT); + _fs->PopTarget(); + } + void ClassStatement() + { + ExpState es; + Lex(); PushExpState(); + _exst._class_or_delete = true; + _exst._funcarg = false; + PrefixedExpr(); + es = PopExpState(); + if(es._deref == DEREF_NO_DEREF) Error(_SC("invalid class name")); + if(es._deref == DEREF_FIELD) { + ClassExp(); + EmitDerefOp(_OP_NEWSLOT); + _fs->PopTarget(); + } + else Error(_SC("cannot create a class in a local with the syntax(class )")); + } + SQObject ExpectScalar() + { + SQObject val; + switch(_token) { + case TK_INTEGER: + val._type = OT_INTEGER; + val._unVal.nInteger = _lex._nvalue; + break; + case TK_FLOAT: + val._type = OT_FLOAT; + val._unVal.fFloat = _lex._fvalue; + break; + case TK_STRING_LITERAL: + val = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1); + break; + case '-': + Lex(); + switch(_token) + { + case TK_INTEGER: + val._type = OT_INTEGER; + val._unVal.nInteger = -_lex._nvalue; + break; + case TK_FLOAT: + val._type = OT_FLOAT; + val._unVal.fFloat = -_lex._fvalue; + break; + default: + Error(_SC("scalar expected : integer,float")); + } + break; + default: + Error(_SC("scalar expected : integer,float or string")); + } + Lex(); + return val; + } + void EnumStatement() + { + + Lex(); + SQObject id = Expect(TK_IDENTIFIER); + Expect(_SC('{')); + + SQObject table = _fs->CreateTable(); + SQInteger nval = 0; + while(_token != _SC('}')) { + SQObject key = Expect(TK_IDENTIFIER); + SQObject val; + if(_token == _SC('=')) { + Lex(); + val = ExpectScalar(); + } + else { + val._type = OT_INTEGER; + val._unVal.nInteger = nval++; + } + _table(table)->NewSlot(SQObjectPtr(key),SQObjectPtr(val)); + if(_token == ',') Lex(); + } + SQTable *enums = _table(_ss(_vm)->_consts); + SQObjectPtr strongid = id; + /*SQObjectPtr dummy; + if(enums->Get(strongid,dummy)) { + dummy.Null(); strongid.Null(); + Error(_SC("enumeration already exists")); + }*/ + enums->NewSlot(SQObjectPtr(strongid),SQObjectPtr(table)); + strongid.Null(); + Lex(); + + } + void TryCatchStatement() + { + SQObject exid; + Lex(); + _fs->AddInstruction(_OP_PUSHTRAP,0,0); + _fs->_traps++; + if(_fs->_breaktargets.size()) _fs->_breaktargets.top()++; + if(_fs->_continuetargets.size()) _fs->_continuetargets.top()++; + SQInteger trappos = _fs->GetCurrentPos(); + Statement(); + _fs->_traps--; + _fs->AddInstruction(_OP_POPTRAP, 1, 0); + if(_fs->_breaktargets.size()) _fs->_breaktargets.top()--; + if(_fs->_continuetargets.size()) _fs->_continuetargets.top()--; + _fs->AddInstruction(_OP_JMP, 0, 0); + SQInteger jmppos = _fs->GetCurrentPos(); + _fs->SetIntructionParam(trappos, 1, (_fs->GetCurrentPos() - trappos)); + Expect(TK_CATCH); Expect(_SC('(')); exid = Expect(TK_IDENTIFIER); Expect(_SC(')')); + SQInteger stacksize = _fs->GetStackSize(); + SQInteger ex_target = _fs->PushLocalVariable(exid); + _fs->SetIntructionParam(trappos, 0, ex_target); + Statement(); + _fs->SetIntructionParams(jmppos, 0, (_fs->GetCurrentPos() - jmppos), 0); + CleanStack(stacksize); + } + void FunctionExp(SQInteger ftype) + { + Lex(); Expect(_SC('(')); + CreateFunction(_null_); + _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, ftype == TK_FUNCTION?0:1); + } + void ClassExp() + { + SQInteger base = -1; + SQInteger attrs = -1; + if(_token == TK_EXTENDS) { + Lex(); Expression(); + base = _fs->TopTarget(); + } + if(_token == TK_ATTR_OPEN) { + Lex(); + _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget()); + ParseTableOrClass(_SC(','),TK_ATTR_CLOSE); + attrs = _fs->TopTarget(); + } + Expect(_SC('{')); + if(attrs != -1) _fs->PopTarget(); + if(base != -1) _fs->PopTarget(); + _fs->AddInstruction(_OP_CLASS, _fs->PushTarget(), base, attrs); + ParseTableOrClass(_SC(';')); + } + void DelegateExpr() + { + Lex(); CommaExpr(); + Expect(_SC(':')); + CommaExpr(); + SQInteger table = _fs->PopTarget(), delegate = _fs->PopTarget(); + _fs->AddInstruction(_OP_DELEGATE, _fs->PushTarget(), table, delegate); + } + void DeleteExpr() + { + ExpState es; + Lex(); PushExpState(); + _exst._class_or_delete = true; + _exst._funcarg = false; + PrefixedExpr(); + es = PopExpState(); + if(es._deref == DEREF_NO_DEREF) Error(_SC("can't delete an expression")); + if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_DELETE); + else Error(_SC("cannot delete a local")); + } + void PrefixIncDec(SQInteger token) + { + ExpState es; + Lex(); PushExpState(); + _exst._class_or_delete = true; + _exst._funcarg = false; + PrefixedExpr(); + es = PopExpState(); + if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_INC,token == TK_MINUSMINUS?-1:1); + else { + SQInteger src = _fs->PopTarget(); + _fs->AddInstruction(_OP_INCL, _fs->PushTarget(), src, 0, token == TK_MINUSMINUS?-1:1); + } + } + void CreateFunction(SQObject &name) + { + + SQFuncState *funcstate = _fs->PushChildState(_ss(_vm)); + funcstate->_name = name; + SQObject paramname; + funcstate->AddParameter(_fs->CreateString(_SC("this"))); + funcstate->_sourcename = _sourcename; + SQInteger defparams = 0; + while(_token!=_SC(')')) { + if(_token == TK_VARPARAMS) { + if(defparams > 0) Error(_SC("function with default parameters cannot have variable number of parameters")); + funcstate->_varparams = true; + Lex(); + if(_token != _SC(')')) Error(_SC("expected ')'")); + break; + } + else { + paramname = Expect(TK_IDENTIFIER); + funcstate->AddParameter(paramname); + if(_token == _SC('=')) { + Lex(); + Expression(); + funcstate->AddDefaultParam(_fs->TopTarget()); + defparams++; + } + else { + if(defparams > 0) Error(_SC("expected '='")); + } + if(_token == _SC(',')) Lex(); + else if(_token != _SC(')')) Error(_SC("expected ')' or ','")); + } + } + Expect(_SC(')')); + for(SQInteger n = 0; n < defparams; n++) { + _fs->PopTarget(); + } + //outer values + if(_token == _SC(':')) { + Lex(); Expect(_SC('(')); + while(_token != _SC(')')) { + paramname = Expect(TK_IDENTIFIER); + //outers are treated as implicit local variables + funcstate->AddOuterValue(paramname); + if(_token == _SC(',')) Lex(); + else if(_token != _SC(')')) Error(_SC("expected ')' or ','")); + } + Lex(); + } + + SQFuncState *currchunk = _fs; + _fs = funcstate; + Statement(); + funcstate->AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true); + funcstate->AddInstruction(_OP_RETURN, -1); + funcstate->SetStackSize(0); + //_fs->->_stacksize = _fs->_stacksize; + SQFunctionProto *func = funcstate->BuildProto(); +#ifdef _DEBUG_DUMP + funcstate->Dump(func); +#endif + _fs = currchunk; + _fs->_functions.push_back(func); + _fs->PopChildState(); + } + void CleanStack(SQInteger stacksize) + { + if(_fs->GetStackSize() != stacksize) + _fs->SetStackSize(stacksize); + } + void ResolveBreaks(SQFuncState *funcstate, SQInteger ntoresolve) + { + while(ntoresolve > 0) { + SQInteger pos = funcstate->_unresolvedbreaks.back(); + funcstate->_unresolvedbreaks.pop_back(); + //set the jmp instruction + funcstate->SetIntructionParams(pos, 0, funcstate->GetCurrentPos() - pos, 0); + ntoresolve--; + } + } + void ResolveContinues(SQFuncState *funcstate, SQInteger ntoresolve, SQInteger targetpos) + { + while(ntoresolve > 0) { + SQInteger pos = funcstate->_unresolvedcontinues.back(); + funcstate->_unresolvedcontinues.pop_back(); + //set the jmp instruction + funcstate->SetIntructionParams(pos, 0, targetpos - pos, 0); + ntoresolve--; + } + } +private: + SQInteger _token; + SQFuncState *_fs; + SQObjectPtr _sourcename; + SQLexer _lex; + bool _lineinfo; + bool _raiseerror; + SQInteger _debugline; + SQInteger _debugop; + ExpStateVec _expstates; + SQChar *compilererror; + jmp_buf _errorjmp; + SQVM *_vm; +}; + +bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo) +{ + SQCompiler p(vm, rg, up, sourcename, raiseerror, lineinfo); + return p.Compile(out); +} diff --git a/vscript/languages/squirrel/squirrel/sqcompiler.h b/vscript/languages/squirrel/squirrel/sqcompiler.h new file mode 100644 index 00000000..dd55888b --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqcompiler.h @@ -0,0 +1,77 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQCOMPILER_H_ +#define _SQCOMPILER_H_ + +struct SQVM; + +#define TK_IDENTIFIER 258 +#define TK_STRING_LITERAL 259 +#define TK_INTEGER 260 +#define TK_FLOAT 261 +#define TK_DELEGATE 262 +#define TK_DELETE 263 +#define TK_EQ 264 +#define TK_NE 265 +#define TK_LE 266 +#define TK_GE 267 +#define TK_SWITCH 268 +#define TK_ARROW 269 +#define TK_AND 270 +#define TK_OR 271 +#define TK_IF 272 +#define TK_ELSE 273 +#define TK_WHILE 274 +#define TK_BREAK 275 +#define TK_FOR 276 +#define TK_DO 277 +#define TK_NULL 278 +#define TK_FOREACH 279 +#define TK_IN 280 +#define TK_NEWSLOT 281 +#define TK_MODULO 282 +#define TK_LOCAL 283 +#define TK_CLONE 284 +#define TK_FUNCTION 285 +#define TK_RETURN 286 +#define TK_TYPEOF 287 +#define TK_UMINUS 288 +#define TK_PLUSEQ 289 +#define TK_MINUSEQ 290 +#define TK_CONTINUE 291 +#define TK_YIELD 292 +#define TK_TRY 293 +#define TK_CATCH 294 +#define TK_THROW 295 +#define TK_SHIFTL 296 +#define TK_SHIFTR 297 +#define TK_RESUME 298 +#define TK_DOUBLE_COLON 299 +#define TK_CASE 300 +#define TK_DEFAULT 301 +#define TK_THIS 302 +#define TK_PLUSPLUS 303 +#define TK_MINUSMINUS 304 +#define TK_PARENT 305 +#define TK_USHIFTR 306 +#define TK_CLASS 307 +#define TK_EXTENDS 308 +#define TK_CONSTRUCTOR 310 +#define TK_INSTANCEOF 311 +#define TK_VARPARAMS 312 +#define TK_VARGC 313 +#define TK_VARGV 314 +#define TK_TRUE 315 +#define TK_FALSE 316 +#define TK_MULEQ 317 +#define TK_DIVEQ 318 +#define TK_MODEQ 319 +#define TK_ATTR_OPEN 320 +#define TK_ATTR_CLOSE 321 +#define TK_STATIC 322 +#define TK_ENUM 323 +#define TK_CONST 324 + + +typedef void(*CompilerErrorFunc)(void *ud, const SQChar *s); +bool Compile(SQVM *vm, SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo); +#endif //_SQCOMPILER_H_ diff --git a/vscript/languages/squirrel/squirrel/sqdebug.cpp b/vscript/languages/squirrel/squirrel/sqdebug.cpp new file mode 100644 index 00000000..46b058de --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqdebug.cpp @@ -0,0 +1,119 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include +#include "sqvm.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "sqstring.h" +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#endif + +SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger level,SQFunctionInfo *fi) +{ + SQInteger cssize = v->_callsstacksize; + if (cssize > level) { + SQVM::CallInfo &ci = v->_callsstack[cssize-level-1]; + if(sq_isclosure(ci._closure)) { + SQClosure *c = _closure(ci._closure); + SQFunctionProto *proto = _funcproto(c->_function); + fi->funcid = proto; + fi->name = type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown"); + fi->source = type(proto->_name) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown"); + return SQ_OK; + } + } + return sq_throwerror(v,_SC("the object is not a closure")); +} + +SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si) +{ + SQInteger cssize = v->_callsstacksize; + if (cssize > level) { + memset(si, 0, sizeof(SQStackInfos)); + SQVM::CallInfo &ci = v->_callsstack[cssize-level-1]; + switch (type(ci._closure)) { + case OT_CLOSURE:{ + SQFunctionProto *func = _funcproto(_closure(ci._closure)->_function); + if (type(func->_name) == OT_STRING) + si->funcname = _stringval(func->_name); + if (type(func->_sourcename) == OT_STRING) + si->source = _stringval(func->_sourcename); + si->line = func->GetLine(ci._ip); + } + break; + case OT_NATIVECLOSURE: + si->source = _SC("NATIVE"); + si->funcname = _SC("unknown"); + if(type(_nativeclosure(ci._closure)->_name) == OT_STRING) + si->funcname = _stringval(_nativeclosure(ci._closure)->_name); + si->line = -1; + break; + default: break; //shutup compiler + } + return SQ_OK; + } + return SQ_ERROR; +} + +void SQVM::Raise_Error(const SQChar *s, ...) +{ + va_list vl; + va_start(vl, s); + scvsprintf(_sp(rsl((SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2))), s, vl); + va_end(vl); + _lasterror = SQString::Create(_ss(this),_spval,-1); +} + +void SQVM::Raise_Error(SQObjectPtr &desc) +{ + _lasterror = desc; +} + +SQString *SQVM::PrintObjVal(const SQObject &o) +{ + switch(type(o)) { + case OT_STRING: return _string(o); + case OT_INTEGER: + scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%d"), _integer(o)); + return SQString::Create(_ss(this), _spval); + break; + case OT_FLOAT: + scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%.14g"), _float(o)); + return SQString::Create(_ss(this), _spval); + break; + default: + return SQString::Create(_ss(this), GetTypeName(o)); + } +} + +void SQVM::Raise_IdxError(SQObject &o) +{ + SQObjectPtr oval = PrintObjVal(o); + Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval)); +} + +void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2) +{ + SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2); + Raise_Error(_SC("comparsion between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2)); +} + + +void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type) +{ + SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1); + SQInteger found = 0; + for(SQInteger i=0; i<16; i++) + { + SQInteger mask = 0x00000001 << i; + if(typemask & (mask)) { + if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes); + found ++; + StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes); + } + } + Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes)); +} diff --git a/vscript/languages/squirrel/squirrel/sqfuncproto.h b/vscript/languages/squirrel/squirrel/sqfuncproto.h new file mode 100644 index 00000000..c6e06239 --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqfuncproto.h @@ -0,0 +1,169 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQFUNCTION_H_ +#define _SQFUNCTION_H_ + +#include "sqopcodes.h" + +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#undef new // allow placement new +#endif + +enum SQOuterType { + otLOCAL = 0, + otSYMBOL = 1, + otOUTER = 2 +}; + +struct SQOuterVar +{ + + SQOuterVar(){} + SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t) + { + _name = name; + _src=src; + _type=t; + } + SQOuterVar(const SQOuterVar &ov) + { + _type=ov._type; + _src=ov._src; + _name=ov._name; + } + SQOuterType _type; + SQObjectPtr _name; + SQObjectPtr _src; +}; + +struct SQLocalVarInfo +{ + SQLocalVarInfo():_start_op(0),_end_op(0){} + SQLocalVarInfo(const SQLocalVarInfo &lvi) + { + _name=lvi._name; + _start_op=lvi._start_op; + _end_op=lvi._end_op; + _pos=lvi._pos; + } + SQObjectPtr _name; + SQUnsignedInteger _start_op; + SQUnsignedInteger _end_op; + SQUnsignedInteger _pos; +}; + +struct SQLineInfo { SQInteger _line;SQInteger _op; }; + +typedef sqvector SQOuterVarVec; +typedef sqvector SQLocalVarInfoVec; +typedef sqvector SQLineInfoVec; + +#define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf,defparams) (sizeof(SQFunctionProto) \ + +((ni-1)*sizeof(SQInstruction))+(nl*sizeof(SQObjectPtr)) \ + +(nparams*sizeof(SQObjectPtr))+(nfuncs*sizeof(SQObjectPtr)) \ + +(nouters*sizeof(SQOuterVar))+(nlineinf*sizeof(SQLineInfo)) \ + +(localinf*sizeof(SQLocalVarInfo))+(defparams*sizeof(SQInteger))) + +#define _CONSTRUCT_VECTOR(type,size,ptr) { \ + for(SQInteger n = 0; n < size; n++) { \ + new (&ptr[n]) type(); \ + } \ +} + +#define _DESTRUCT_VECTOR(type,size,ptr) { \ + for(SQInteger nl = 0; nl < size; nl++) { \ + ptr[nl].~type(); \ + } \ +} +struct SQFunctionProto : public SQRefCounted +{ +private: + SQFunctionProto(){ + _stacksize=0; + _bgenerator=false;} +public: + static SQFunctionProto *Create(SQInteger ninstructions, + SQInteger nliterals,SQInteger nparameters, + SQInteger nfunctions,SQInteger noutervalues, + SQInteger nlineinfos,SQInteger nlocalvarinfos,SQInteger ndefaultparams) + { + SQFunctionProto *f; + //I compact the whole class and members in a single memory allocation + f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams)); + new (f) SQFunctionProto; + f->_ninstructions = ninstructions; + f->_literals = (SQObjectPtr*)&f->_instructions[ninstructions]; + f->_nliterals = nliterals; + f->_parameters = (SQObjectPtr*)&f->_literals[nliterals]; + f->_nparameters = nparameters; + f->_functions = (SQObjectPtr*)&f->_parameters[nparameters]; + f->_nfunctions = nfunctions; + f->_outervalues = (SQOuterVar*)&f->_functions[nfunctions]; + f->_noutervalues = noutervalues; + f->_lineinfos = (SQLineInfo *)&f->_outervalues[noutervalues]; + f->_nlineinfos = nlineinfos; + f->_localvarinfos = (SQLocalVarInfo *)&f->_lineinfos[nlineinfos]; + f->_nlocalvarinfos = nlocalvarinfos; + f->_defaultparams = (SQInteger *)&f->_localvarinfos[nlocalvarinfos]; + f->_ndefaultparams = ndefaultparams; + + _CONSTRUCT_VECTOR(SQObjectPtr,f->_nliterals,f->_literals); + _CONSTRUCT_VECTOR(SQObjectPtr,f->_nparameters,f->_parameters); + _CONSTRUCT_VECTOR(SQObjectPtr,f->_nfunctions,f->_functions); + _CONSTRUCT_VECTOR(SQOuterVar,f->_noutervalues,f->_outervalues); + //_CONSTRUCT_VECTOR(SQLineInfo,f->_nlineinfos,f->_lineinfos); //not required are 2 integers + _CONSTRUCT_VECTOR(SQLocalVarInfo,f->_nlocalvarinfos,f->_localvarinfos); + return f; + } + void Release(){ + _DESTRUCT_VECTOR(SQObjectPtr,_nliterals,_literals); + _DESTRUCT_VECTOR(SQObjectPtr,_nparameters,_parameters); + _DESTRUCT_VECTOR(SQObjectPtr,_nfunctions,_functions); + _DESTRUCT_VECTOR(SQOuterVar,_noutervalues,_outervalues); + //_DESTRUCT_VECTOR(SQLineInfo,_nlineinfos,_lineinfos); //not required are 2 integers + _DESTRUCT_VECTOR(SQLocalVarInfo,_nlocalvarinfos,_localvarinfos); + SQInteger size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos,_ndefaultparams); + this->~SQFunctionProto(); + sq_vm_free(this,size); + } + const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop); + SQInteger GetLine(SQInstruction *curr); + bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write); + static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret); + + SQObjectPtr _sourcename; + SQObjectPtr _name; + SQInteger _stacksize; + bool _bgenerator; + bool _varparams; + + SQInteger _nlocalvarinfos; + SQLocalVarInfo *_localvarinfos; + + SQInteger _nlineinfos; + SQLineInfo *_lineinfos; + + SQInteger _nliterals; + SQObjectPtr *_literals; + + SQInteger _nparameters; + SQObjectPtr *_parameters; + + SQInteger _nfunctions; + SQObjectPtr *_functions; + + SQInteger _noutervalues; + SQOuterVar *_outervalues; + + SQInteger _ndefaultparams; + SQInteger *_defaultparams; + + SQInteger _ninstructions; + SQInstruction _instructions[1]; +}; + +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgoff.h" +#endif + +#endif //_SQFUNCTION_H_ diff --git a/vscript/languages/squirrel/squirrel/sqfuncstate.cpp b/vscript/languages/squirrel/squirrel/sqfuncstate.cpp new file mode 100644 index 00000000..25e897e1 --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqfuncstate.cpp @@ -0,0 +1,571 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqcompiler.h" +#include "sqfuncproto.h" +#include "sqstring.h" +#include "sqtable.h" +#include "sqopcodes.h" +#include "sqfuncstate.h" +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#undef new // allow placement new +#endif + +#ifdef _DEBUG_DUMP +SQInstructionDesc g_InstrDesc[]={ + {_SC("_OP_LINE")}, + {_SC("_OP_LOAD")}, + {_SC("_OP_LOADINT")}, + {_SC("_OP_LOADFLOAT")}, + {_SC("_OP_DLOAD")}, + {_SC("_OP_TAILCALL")}, + {_SC("_OP_CALL")}, + {_SC("_OP_PREPCALL")}, + {_SC("_OP_PREPCALLK")}, + {_SC("_OP_GETK")}, + {_SC("_OP_MOVE")}, + {_SC("_OP_NEWSLOT")}, + {_SC("_OP_DELETE")}, + {_SC("_OP_SET")}, + {_SC("_OP_GET")}, + {_SC("_OP_EQ")}, + {_SC("_OP_NE")}, + {_SC("_OP_ARITH")}, + {_SC("_OP_BITW")}, + {_SC("_OP_RETURN")}, + {_SC("_OP_LOADNULLS")}, + {_SC("_OP_LOADROOTTABLE")}, + {_SC("_OP_LOADBOOL")}, + {_SC("_OP_DMOVE")}, + {_SC("_OP_JMP")}, + {_SC("_OP_JNZ")}, + {_SC("_OP_JZ")}, + {_SC("_OP_LOADFREEVAR")}, + {_SC("_OP_VARGC")}, + {_SC("_OP_GETVARGV")}, + {_SC("_OP_NEWTABLE")}, + {_SC("_OP_NEWARRAY")}, + {_SC("_OP_APPENDARRAY")}, + {_SC("_OP_GETPARENT")}, + {_SC("_OP_COMPARITH")}, + {_SC("_OP_COMPARITHL")}, + {_SC("_OP_INC")}, + {_SC("_OP_INCL")}, + {_SC("_OP_PINC")}, + {_SC("_OP_PINCL")}, + {_SC("_OP_CMP")}, + {_SC("_OP_EXISTS")}, + {_SC("_OP_INSTANCEOF")}, + {_SC("_OP_AND")}, + {_SC("_OP_OR")}, + {_SC("_OP_NEG")}, + {_SC("_OP_NOT")}, + {_SC("_OP_BWNOT")}, + {_SC("_OP_CLOSURE")}, + {_SC("_OP_YIELD")}, + {_SC("_OP_RESUME")}, + {_SC("_OP_FOREACH")}, + {_SC("_OP_POSTFOREACH")}, + {_SC("_OP_DELEGATE")}, + {_SC("_OP_CLONE")}, + {_SC("_OP_TYPEOF")}, + {_SC("_OP_PUSHTRAP")}, + {_SC("_OP_POPTRAP")}, + {_SC("_OP_THROW")}, + {_SC("_OP_CLASS")}, + {_SC("_OP_NEWSLOTA")} +}; +#endif +void DumpLiteral(SQObjectPtr &o) +{ + switch(type(o)){ + case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break; + case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break; + case OT_INTEGER: scprintf(_SC("{%d}"),_integer(o));break; + case OT_BOOL: scprintf(_SC("%s"),_integer(o)?_SC("true"):_SC("false"));break; + default: scprintf(_SC("(%s %p)"),GetTypeName(o),(void*)_rawval(o));break; break; //shut up compiler + } +} + +SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed) +{ + _nliterals = 0; + _literals = SQTable::Create(ss,0); + _strings = SQTable::Create(ss,0); + _sharedstate = ss; + _lastline = 0; + _optimization = true; + _parent = parent; + _stacksize = 0; + _traps = 0; + _returnexp = 0; + _varparams = false; + _errfunc = efunc; + _errtarget = ed; + _bgenerator = false; + +} + +void SQFuncState::Error(const SQChar *err) +{ + _errfunc(_errtarget,err); +} + +#ifdef _DEBUG_DUMP +void SQFuncState::Dump(SQFunctionProto *func) +{ + SQUnsignedInteger n=0,i; + SQInteger si; + scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction)); + scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject)); + scprintf(_SC("--------------------------------------------------------------------\n")); + scprintf(_SC("*****FUNCTION [%s]\n"),type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown")); + scprintf(_SC("-----LITERALS\n")); + SQObjectPtr refidx,key,val; + SQInteger idx; + SQObjectPtrVec templiterals; + templiterals.resize(_nliterals); + while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) { + refidx=idx; + templiterals[_integer(val)]=key; + } + for(i=0;i>\n")); + n=0; + for(i=0;i<_parameters.size();i++){ + scprintf(_SC("[%d] "),n); + DumpLiteral(_parameters[i]); + scprintf(_SC("\n")); + n++; + } + scprintf(_SC("-----LOCALS\n")); + for(si=0;si_nlocalvarinfos;si++){ + SQLocalVarInfo lvi=func->_localvarinfos[si]; + scprintf(_SC("[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op); + n++; + } + scprintf(_SC("-----LINE INFO\n")); + for(i=0;i<_lineinfos.size();i++){ + SQLineInfo li=_lineinfos[i]; + scprintf(_SC("op [%d] line [%d] \n"),li._op,li._line); + n++; + } + scprintf(_SC("-----dump\n")); + n=0; + for(i=0;i<_instructions.size();i++){ + SQInstruction &inst=_instructions[i]; + if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){ + + SQInteger lidx = inst._arg1; + scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0); + if(lidx >= 0xFFFFFFFF) + scprintf(_SC("null")); + else { + SQInteger refidx; + SQObjectPtr val,key,refo; + while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { + refo = refidx; + } + DumpLiteral(key); + } + if(inst.op != _OP_DLOAD) { + scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3); + } + else { + scprintf(_SC(" %d "),inst._arg2); + lidx = inst._arg3; + if(lidx >= 0xFFFFFFFF) + scprintf(_SC("null")); + else { + SQInteger refidx; + SQObjectPtr val,key,refo; + while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { + refo = refidx; + } + DumpLiteral(key); + scprintf(_SC("\n")); + } + } + } + else if(inst.op==_OP_LOADFLOAT) { + scprintf(_SC("[%03d] %15s %d %f %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3); + } + else if(inst.op==_OP_ARITH){ + scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); + } + else + scprintf(_SC("[%03d] %15s %d %d %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); + n++; + } + scprintf(_SC("-----\n")); + scprintf(_SC("stack size[%d]\n"),func->_stacksize); + scprintf(_SC("--------------------------------------------------------------------\n\n")); +} +#endif + +SQInteger SQFuncState::GetNumericConstant(const SQInteger cons) +{ + return GetConstant(SQObjectPtr(cons)); +} + +SQInteger SQFuncState::GetNumericConstant(const SQFloat cons) +{ + return GetConstant(SQObjectPtr(cons)); +} + +SQInteger SQFuncState::GetConstant(const SQObject &cons) +{ + SQObjectPtr val; + if(!_table(_literals)->Get(cons,val)) + { + val = _nliterals; + _table(_literals)->NewSlot(cons,val); + _nliterals++; + if(_nliterals > MAX_LITERALS) { + val.Null(); + Error(_SC("internal compiler error: too many literals")); + } + } + return _integer(val); +} + +void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3) +{ + _instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0); + _instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1); + _instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&arg2); + _instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3); +} + +void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val) +{ + switch(arg){ + case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break; + case 1:case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);break; + case 2:_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&val);break; + case 3:_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&val);break; + }; +} + +SQInteger SQFuncState::AllocStackPos() +{ + SQInteger npos=_vlocals.size(); + _vlocals.push_back(SQLocalVarInfo()); + if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) { + if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals")); + _stacksize=_vlocals.size(); + } + return npos; +} + +SQInteger SQFuncState::PushTarget(SQInteger n) +{ + if(n!=-1){ + _targetstack.push_back(n); + return n; + } + n=AllocStackPos(); + _targetstack.push_back(n); + return n; +} + +SQInteger SQFuncState::GetUpTarget(SQInteger n){ + return _targetstack[((_targetstack.size()-1)-n)]; +} + +SQInteger SQFuncState::TopTarget(){ + return _targetstack.back(); +} +SQInteger SQFuncState::PopTarget() +{ + SQInteger npos=_targetstack.back(); + SQLocalVarInfo t=_vlocals[_targetstack.back()]; + if(type(t._name)==OT_NULL){ + _vlocals.pop_back(); + } + _targetstack.pop_back(); + return npos; +} + +SQInteger SQFuncState::GetStackSize() +{ + return _vlocals.size(); +} + +void SQFuncState::SetStackSize(SQInteger n) +{ + SQInteger size=_vlocals.size(); + while(size>n){ + size--; + SQLocalVarInfo lvi=_vlocals.back(); + if(type(lvi._name)!=OT_NULL){ + lvi._end_op=GetCurrentPos(); + _localvarinfos.push_back(lvi); + } + _vlocals.pop_back(); + } +} + +bool SQFuncState::IsConstant(const SQObject &name,SQObject &e) +{ + SQObjectPtr val; + if(_table(_sharedstate->_consts)->Get(name,val)) { + e = val; + return true; + } + return false; +} + +bool SQFuncState::IsLocal(SQUnsignedInteger stkpos) +{ + if(stkpos>=_vlocals.size())return false; + else if(type(_vlocals[stkpos]._name)!=OT_NULL)return true; + return false; +} + +SQInteger SQFuncState::PushLocalVariable(const SQObject &name) +{ + SQInteger pos=_vlocals.size(); + SQLocalVarInfo lvi; + lvi._name=name; + lvi._start_op=GetCurrentPos()+1; + lvi._pos=_vlocals.size(); + _vlocals.push_back(lvi); + if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size(); + + return pos; +} + +SQInteger SQFuncState::GetLocalVariable(const SQObject &name) +{ + SQInteger locals=_vlocals.size(); + while(locals>=1){ + if(type(_vlocals[locals-1]._name)==OT_STRING && _string(_vlocals[locals-1]._name)==_string(name)){ + return locals-1; + } + locals--; + } + return -1; +} + +SQInteger SQFuncState::GetOuterVariable(const SQObject &name) +{ + SQInteger outers = _outervalues.size(); + for(SQInteger i = 0; iGetLocalVariable(name); + if(pos == -1) { + pos = _parent->GetOuterVariable(name); + if(pos != -1) { + _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otOUTER)); //local + return; + } + } + else { + _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local + return; + } + } + _outervalues.push_back(SQOuterVar(name,name,otSYMBOL)); //global +} + +void SQFuncState::AddParameter(const SQObject &name) +{ + PushLocalVariable(name); + _parameters.push_back(name); +} + +void SQFuncState::AddLineInfos(SQInteger line,bool lineop,bool force) +{ + if(_lastline!=line || force){ + SQLineInfo li; + li._line=line;li._op=(GetCurrentPos()+1); + if(lineop)AddInstruction(_OP_LINE,0,line); + _lineinfos.push_back(li); + _lastline=line; + } +} + +void SQFuncState::AddInstruction(SQInstruction &i) +{ + SQInteger size = _instructions.size(); + if(size > 0 && _optimization){ //simple optimizer + SQInstruction &pi = _instructions[size-1];//previous instruction + switch(i.op) { + case _OP_RETURN: + if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) { + pi.op = _OP_TAILCALL; + } + break; + case _OP_GET: + if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!IsLocal(pi._arg0))){ + pi._arg1 = pi._arg1; + pi._arg2 = (unsigned char)i._arg1; + pi.op = _OP_GETK; + pi._arg0 = i._arg0; + + return; + } + break; + case _OP_PREPCALL: + if( pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){ + pi.op = _OP_PREPCALLK; + pi._arg0 = i._arg0; + pi._arg1 = pi._arg1; + pi._arg2 = i._arg2; + pi._arg3 = i._arg3; + return; + } + break; + case _OP_APPENDARRAY: + if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){ + pi.op = _OP_APPENDARRAY; + pi._arg0 = i._arg0; + pi._arg1 = pi._arg1; + pi._arg2 = MAX_FUNC_STACKSIZE; + pi._arg3 = MAX_FUNC_STACKSIZE; + return; + } + break; + case _OP_MOVE: + if((pi.op == _OP_GET || pi.op == _OP_ARITH || pi.op == _OP_BITW) && (pi._arg0 == i._arg1)) + { + pi._arg0 = i._arg0; + _optimization = false; + return; + } + + if(pi.op == _OP_MOVE) + { + pi.op = _OP_DMOVE; + pi._arg2 = i._arg0; + pi._arg3 = (unsigned char)i._arg1; + return; + } + break; + case _OP_LOAD: + if(pi.op == _OP_LOAD && i._arg1 < 256) { + pi.op = _OP_DLOAD; + pi._arg2 = i._arg0; + pi._arg3 = (unsigned char)i._arg1; + return; + } + break; + case _OP_EQ:case _OP_NE: + if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) )) + { + pi.op = i.op; + pi._arg0 = i._arg0; + pi._arg1 = pi._arg1; + pi._arg2 = i._arg2; + pi._arg3 = MAX_FUNC_STACKSIZE; + return; + } + break; + case _OP_LOADNULLS: + if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) { + + pi._arg1 = pi._arg1 + 1; + pi.op = _OP_LOADNULLS; + return; + } + break; + case _OP_LINE: + if(pi.op == _OP_LINE) { + _instructions.pop_back(); + _lineinfos.pop_back(); + } + break; + } + } + _optimization = true; + _instructions.push_back(i); +} + +SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len) +{ + SQObjectPtr ns(SQString::Create(_sharedstate,s,len)); + _table(_strings)->NewSlot(ns,(SQInteger)1); + return ns; +} + +SQObject SQFuncState::CreateTable() +{ + SQObjectPtr nt(SQTable::Create(_sharedstate,0)); + _table(_strings)->NewSlot(nt,(SQInteger)1); + return nt; +} + +SQFunctionProto *SQFuncState::BuildProto() +{ + SQFunctionProto *f=SQFunctionProto::Create(_instructions.size(), + _nliterals,_parameters.size(),_functions.size(),_outervalues.size(), + _lineinfos.size(),_localvarinfos.size(),_defaultparams.size()); + + SQObjectPtr refidx,key,val; + SQInteger idx; + + f->_stacksize = _stacksize; + f->_sourcename = _sourcename; + f->_bgenerator = _bgenerator; + f->_name = _name; + + while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) { + f->_literals[_integer(val)]=key; + refidx=idx; + } + + for(SQUnsignedInteger nf = 0; nf < _functions.size(); nf++) f->_functions[nf] = _functions[nf]; + for(SQUnsignedInteger np = 0; np < _parameters.size(); np++) f->_parameters[np] = _parameters[np]; + for(SQUnsignedInteger no = 0; no < _outervalues.size(); no++) f->_outervalues[no] = _outervalues[no]; + for(SQUnsignedInteger no = 0; no < _localvarinfos.size(); no++) f->_localvarinfos[no] = _localvarinfos[no]; + for(SQUnsignedInteger no = 0; no < _lineinfos.size(); no++) f->_lineinfos[no] = _lineinfos[no]; + for(SQUnsignedInteger no = 0; no < _defaultparams.size(); no++) f->_defaultparams[no] = _defaultparams[no]; + + memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction)); + + f->_varparams = _varparams; + + return f; +} + +SQFuncState *SQFuncState::PushChildState(SQSharedState *ss) +{ + SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState)); + new (child) SQFuncState(ss,this,_errfunc,_errtarget); + _childstates.push_back(child); + return child; +} + +void SQFuncState::PopChildState() +{ + SQFuncState *child = _childstates.back(); + sq_delete(child,SQFuncState); + _childstates.pop_back(); +} + +SQFuncState::~SQFuncState() +{ + while(_childstates.size() > 0) + { + PopChildState(); + } +} diff --git a/vscript/languages/squirrel/squirrel/sqfuncstate.h b/vscript/languages/squirrel/squirrel/sqfuncstate.h new file mode 100644 index 00000000..c0bf1e5e --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqfuncstate.h @@ -0,0 +1,85 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQFUNCSTATE_H_ +#define _SQFUNCSTATE_H_ +/////////////////////////////////// +#include "squtils.h" + +struct SQFuncState +{ + SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed); + ~SQFuncState(); +#ifdef _DEBUG_DUMP + void Dump(SQFunctionProto *func); +#endif + void Error(const SQChar *err); + SQFuncState *PushChildState(SQSharedState *ss); + void PopChildState(); + void AddInstruction(SQOpcode _op,SQInteger arg0=0,SQInteger arg1=0,SQInteger arg2=0,SQInteger arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);} + void AddInstruction(SQInstruction &i); + void SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0); + void SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val); + SQInstruction &GetInstruction(SQInteger pos){return _instructions[pos];} + void PopInstructions(SQInteger size){for(SQInteger i=0;i _childstates; + SQInteger GetConstant(const SQObject &cons); +private: + CompilerErrorFunc _errfunc; + void *_errtarget; +}; + + +#endif //_SQFUNCSTATE_H_ + diff --git a/vscript/languages/squirrel/squirrel/sqlexer.cpp b/vscript/languages/squirrel/squirrel/sqlexer.cpp new file mode 100644 index 00000000..2afd6859 --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqlexer.cpp @@ -0,0 +1,479 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include +#include +#include "sqtable.h" +#include "sqstring.h" +#include "sqcompiler.h" +#include "sqlexer.h" +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#endif + +#define CUR_CHAR (_currdata) +#define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;} +#define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB) +#define NEXT() {Next();_currentcolumn++;} +#define INIT_TEMP_STRING() { _longstr.resize(0);} +#define APPEND_CHAR(c) { _longstr.push_back(c);} +#define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));} +#define ADD_KEYWORD(key,id) _keywords->NewSlot( SQString::Create(ss, _SC(#key)) ,SQInteger(id)) + +SQLexer::SQLexer(){} +SQLexer::~SQLexer() +{ + _keywords->Release(); +} + +void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed) +{ + _errfunc = efunc; + _errtarget = ed; + _sharedstate = ss; + _keywords = SQTable::Create(ss, 26); + ADD_KEYWORD(while, TK_WHILE); + ADD_KEYWORD(do, TK_DO); + ADD_KEYWORD(if, TK_IF); + ADD_KEYWORD(else, TK_ELSE); + ADD_KEYWORD(break, TK_BREAK); + ADD_KEYWORD(continue, TK_CONTINUE); + ADD_KEYWORD(return, TK_RETURN); + ADD_KEYWORD(null, TK_NULL); + ADD_KEYWORD(function, TK_FUNCTION); + ADD_KEYWORD(local, TK_LOCAL); + ADD_KEYWORD(for, TK_FOR); + ADD_KEYWORD(foreach, TK_FOREACH); + ADD_KEYWORD(in, TK_IN); + ADD_KEYWORD(typeof, TK_TYPEOF); + ADD_KEYWORD(delegate, TK_DELEGATE); + ADD_KEYWORD(delete, TK_DELETE); + ADD_KEYWORD(try, TK_TRY); + ADD_KEYWORD(catch, TK_CATCH); + ADD_KEYWORD(throw, TK_THROW); + ADD_KEYWORD(clone, TK_CLONE); + ADD_KEYWORD(yield, TK_YIELD); + ADD_KEYWORD(resume, TK_RESUME); + ADD_KEYWORD(switch, TK_SWITCH); + ADD_KEYWORD(case, TK_CASE); + ADD_KEYWORD(default, TK_DEFAULT); + ADD_KEYWORD(this, TK_THIS); + ADD_KEYWORD(parent,TK_PARENT); + ADD_KEYWORD(class,TK_CLASS); + ADD_KEYWORD(extends,TK_EXTENDS); + ADD_KEYWORD(constructor,TK_CONSTRUCTOR); + ADD_KEYWORD(instanceof,TK_INSTANCEOF); + ADD_KEYWORD(vargc,TK_VARGC); + ADD_KEYWORD(vargv,TK_VARGV); + ADD_KEYWORD(true,TK_TRUE); + ADD_KEYWORD(false,TK_FALSE); + ADD_KEYWORD(static,TK_STATIC); + ADD_KEYWORD(enum,TK_ENUM); + ADD_KEYWORD(const,TK_CONST); + + _readf = rg; + _up = up; + _lasttokenline = _currentline = 1; + _currentcolumn = 0; + _prevtoken = -1; + Next(); +} + +void SQLexer::Error(const SQChar *err) +{ + _errfunc(_errtarget,err); +} + +void SQLexer::Next() +{ + SQInteger t = _readf(_up); + if(t > MAX_CHAR) Error(_SC("Invalid character")); + if(t != 0) { + _currdata = (LexChar)t; + return; + } + _currdata = SQUIRREL_EOB; +} + +const SQChar *SQLexer::Tok2Str(SQInteger tok) +{ + SQObjectPtr itr, key, val; + SQInteger nitr; + while((nitr = _keywords->Next(false,itr, key, val)) != -1) { + itr = (SQInteger)nitr; + if(((SQInteger)_integer(val)) == tok) + return _stringval(key); + } + return NULL; +} + +void SQLexer::LexBlockComment() +{ + bool done = false; + while(!done) { + switch(CUR_CHAR) { + case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue; + case _SC('\n'): _currentline++; NEXT(); continue; + case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment")); + default: NEXT(); + } + } +} + +SQInteger SQLexer::Lex() +{ + _lasttokenline = _currentline; + while(CUR_CHAR != SQUIRREL_EOB) { + switch(CUR_CHAR){ + case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue; + case _SC('\n'): + _currentline++; + _prevtoken=_curtoken; + _curtoken=_SC('\n'); + NEXT(); + _currentcolumn=1; + continue; + case _SC('/'): + NEXT(); + switch(CUR_CHAR){ + case _SC('*'): + NEXT(); + LexBlockComment(); + continue; + case _SC('/'): + do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB())); + continue; + case _SC('='): + NEXT(); + RETURN_TOKEN(TK_DIVEQ); + continue; + case _SC('>'): + NEXT(); + RETURN_TOKEN(TK_ATTR_CLOSE); + continue; + default: + RETURN_TOKEN('/'); + } + case _SC('='): + NEXT(); + if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') } + else { NEXT(); RETURN_TOKEN(TK_EQ); } + case _SC('<'): + NEXT(); + if ( CUR_CHAR == _SC('=') ) { NEXT(); RETURN_TOKEN(TK_LE) } + else if ( CUR_CHAR == _SC('-') ) { NEXT(); RETURN_TOKEN(TK_NEWSLOT); } + else if ( CUR_CHAR == _SC('<') ) { NEXT(); RETURN_TOKEN(TK_SHIFTL); } + else if ( CUR_CHAR == _SC('/') ) { NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); } + //else if ( CUR_CHAR == _SC('[') ) { NEXT(); ReadMultilineString(); RETURN_TOKEN(TK_STRING_LITERAL); } + else { RETURN_TOKEN('<') } + case _SC('>'): + NEXT(); + if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);} + else if(CUR_CHAR == _SC('>')){ + NEXT(); + if(CUR_CHAR == _SC('>')){ + NEXT(); + RETURN_TOKEN(TK_USHIFTR); + } + RETURN_TOKEN(TK_SHIFTR); + } + else { RETURN_TOKEN('>') } + case _SC('!'): + NEXT(); + if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')} + else { NEXT(); RETURN_TOKEN(TK_NE); } + case _SC('@'): { + SQInteger stype; + NEXT(); + if(CUR_CHAR != _SC('"')) + Error(_SC("string expected")); + if((stype=ReadString('"',true))!=-1) { + RETURN_TOKEN(stype); + } + Error(_SC("error parsing the string")); + } + case _SC('"'): + case _SC('\''): { + SQInteger stype; + if((stype=ReadString(CUR_CHAR,false))!=-1){ + RETURN_TOKEN(stype); + } + Error(_SC("error parsing the string")); + } + case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'): + case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'): + {SQInteger ret = CUR_CHAR; + NEXT(); RETURN_TOKEN(ret); } + case _SC('.'): + NEXT(); + if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') } + NEXT(); + if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); } + NEXT(); + RETURN_TOKEN(TK_VARPARAMS); + case _SC('&'): + NEXT(); + if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') } + else { NEXT(); RETURN_TOKEN(TK_AND); } + case _SC('|'): + NEXT(); + if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') } + else { NEXT(); RETURN_TOKEN(TK_OR); } + case _SC(':'): + NEXT(); + if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') } + else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); } + case _SC('*'): + NEXT(); + if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);} + else RETURN_TOKEN('*'); + case _SC('%'): + NEXT(); + if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);} + else RETURN_TOKEN('%'); + case _SC('-'): + NEXT(); + if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);} + else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);} + else RETURN_TOKEN('-'); + case _SC('+'): + NEXT(); + if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);} + else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);} + else RETURN_TOKEN('+'); + case SQUIRREL_EOB: + return 0; + default:{ + if (scisdigit(CUR_CHAR)) { + SQInteger ret = ReadNumber(); + RETURN_TOKEN(ret); + } + else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) { + SQInteger t = ReadID(); + RETURN_TOKEN(t); + } + else { + SQInteger c = CUR_CHAR; + if (sciscntrl((int)c)) Error(_SC("unexpected character(control)")); + NEXT(); + RETURN_TOKEN(c); + } + RETURN_TOKEN(0); + } + } + } + return 0; +} + +SQInteger SQLexer::GetIDType(SQChar *s) +{ + SQObjectPtr t; + if(_keywords->Get(SQString::Create(_sharedstate, s), t)) { + return SQInteger(_integer(t)); + } + return TK_IDENTIFIER; +} + + +SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim) +{ + INIT_TEMP_STRING(); + NEXT(); + if(IS_EOB()) return -1; + for(;;) { + while(CUR_CHAR != ndelim) { + switch(CUR_CHAR) { + case SQUIRREL_EOB: + Error(_SC("unfinished string")); + return -1; + case _SC('\n'): + if(!verbatim) Error(_SC("newline in a constant")); + APPEND_CHAR(CUR_CHAR); NEXT(); + _currentline++; + break; + case _SC('\\'): + if(verbatim) { + APPEND_CHAR('\\'); NEXT(); + } + else { + NEXT(); + switch(CUR_CHAR) { + case _SC('x'): NEXT(); { + if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected")); + const SQInteger maxdigits = 4; + SQChar temp[maxdigits+1]; + SQInteger n = 0; + while(isxdigit(CUR_CHAR) && n < maxdigits) { + temp[n] = CUR_CHAR; + n++; + NEXT(); + } + temp[n] = 0; + SQChar *sTemp; + APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16)); + } + break; + case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break; + case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break; + case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break; + case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break; + case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break; + case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break; + case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break; + case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break; + case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break; + case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break; + case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break; + default: + Error(_SC("unrecognised escaper char")); + break; + } + } + break; + default: + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + } + NEXT(); + if(verbatim && CUR_CHAR == '"') { //double quotation + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + else { + break; + } + } + TERMINATE_BUFFER(); + SQInteger len = _longstr.size()-1; + if(ndelim == _SC('\'')) { + if(len == 0) Error(_SC("empty constant")); + if(len > 1) Error(_SC("constant too long")); + _nvalue = _longstr[0]; + return TK_INTEGER; + } + _svalue = &_longstr[0]; + return TK_STRING_LITERAL; +} + +void LexHexadecimal(const SQChar *s,SQUnsignedInteger *res) +{ + *res = 0; + while(*s != 0) + { + if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0'); + else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10); + else { Assert(0); } + } +} + +void LexInteger(const SQChar *s,SQUnsignedInteger *res) +{ + *res = 0; + while(*s != 0) + { + *res = (*res)*10+((*s++)-'0'); + } +} + +SQInteger scisodigit(SQInteger c) { return c >= _SC('0') && c <= _SC('7'); } + +void LexOctal(const SQChar *s,SQUnsignedInteger *res) +{ + *res = 0; + while(*s != 0) + { + if(scisodigit(*s)) *res = (*res)*8+((*s++)-'0'); + else { assert(0); } + } +} + +SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; } + + +#define MAX_HEX_DIGITS (sizeof(SQInteger)*2) +SQInteger SQLexer::ReadNumber() +{ +#define TINT 1 +#define TFLOAT 2 +#define THEX 3 +#define TSCIENTIFIC 4 +#define TOCTAL 5 + SQInteger type = TINT, firstchar = CUR_CHAR; + SQChar *sTemp; + INIT_TEMP_STRING(); + NEXT(); + if(firstchar == _SC('0') && (toupper(CUR_CHAR) == _SC('X') || scisodigit(CUR_CHAR)) ) { + if(scisodigit(CUR_CHAR)) { + type = TOCTAL; + while(scisodigit(CUR_CHAR)) { + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + if(scisdigit(CUR_CHAR)) Error(_SC("invalid octal number")); + } + else { + NEXT(); + type = THEX; + while(isxdigit(CUR_CHAR)) { + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number")); + } + } + else { + APPEND_CHAR((int)firstchar); + while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) { + if(CUR_CHAR == _SC('.')) type = TFLOAT; + if(isexponent(CUR_CHAR)) { + if(type != TFLOAT) Error(_SC("invalid numeric format")); + type = TSCIENTIFIC; + APPEND_CHAR(CUR_CHAR); + NEXT(); + if(CUR_CHAR == '+' || CUR_CHAR == '-'){ + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected")); + } + + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + } + TERMINATE_BUFFER(); + switch(type) { + case TSCIENTIFIC: + case TFLOAT: + _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp); + return TK_FLOAT; + case TINT: + LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue); + return TK_INTEGER; + case THEX: + LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); + return TK_INTEGER; + case TOCTAL: + LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); + return TK_INTEGER; + } + return 0; +} + +SQInteger SQLexer::ReadID() +{ + SQInteger res; + INIT_TEMP_STRING(); + do { + APPEND_CHAR(CUR_CHAR); + NEXT(); + } while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_')); + TERMINATE_BUFFER(); + res = GetIDType(&_longstr[0]); + if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) { + _svalue = &_longstr[0]; + } + return res; +} diff --git a/vscript/languages/squirrel/squirrel/sqlexer.h b/vscript/languages/squirrel/squirrel/sqlexer.h new file mode 100644 index 00000000..eb3bc873 --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqlexer.h @@ -0,0 +1,45 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQLEXER_H_ +#define _SQLEXER_H_ + +#ifdef SQUNICODE +typedef SQChar LexChar; +#else +typedef unsigned char LexChar; +#endif + +struct SQLexer +{ + SQLexer(); + ~SQLexer(); + void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed); + void Error(const SQChar *err); + SQInteger Lex(); + const SQChar *Tok2Str(SQInteger tok); +private: + SQInteger GetIDType(SQChar *s); + SQInteger ReadString(SQInteger ndelim,bool verbatim); + SQInteger ReadNumber(); + void LexBlockComment(); + SQInteger ReadID(); + void Next(); + SQInteger _curtoken; + SQTable *_keywords; +public: + SQInteger _prevtoken; + SQInteger _currentline; + SQInteger _lasttokenline; + SQInteger _currentcolumn; + const SQChar *_svalue; + SQInteger _nvalue; + SQFloat _fvalue; + SQLEXREADFUNC _readf; + SQUserPointer _up; + LexChar _currdata; + SQSharedState *_sharedstate; + sqvector _longstr; + CompilerErrorFunc _errfunc; + void *_errtarget; +}; + +#endif diff --git a/vscript/languages/squirrel/squirrel/sqmem.cpp b/vscript/languages/squirrel/squirrel/sqmem.cpp new file mode 100644 index 00000000..9b39de06 --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqmem.cpp @@ -0,0 +1,11 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#if !(defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST)) +void *sq_vm_malloc(SQUnsignedInteger size){ return malloc(size); } + +void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size){ return realloc(p, size); } + +void sq_vm_free(void *p, SQUnsignedInteger size){ free(p); } +#endif diff --git a/vscript/languages/squirrel/squirrel/sqobject.cpp b/vscript/languages/squirrel/squirrel/sqobject.cpp new file mode 100644 index 00000000..51249cef --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqobject.cpp @@ -0,0 +1,712 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqstring.h" +#include "sqarray.h" +#include "sqtable.h" +#include "squserdata.h" +#include "sqfuncproto.h" +#include "sqclass.h" +#include "sqclosure.h" +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#undef new // allow placement new +#endif + + +const SQChar *IdType2Name(SQObjectType type) +{ + switch(_RAW_TYPE(type)) + { + case _RT_NULL:return _SC("null"); + case _RT_INTEGER:return _SC("integer"); + case _RT_FLOAT:return _SC("float"); + case _RT_BOOL:return _SC("bool"); + case _RT_STRING:return _SC("string"); + case _RT_TABLE:return _SC("table"); + case _RT_ARRAY:return _SC("array"); + case _RT_GENERATOR:return _SC("generator"); + case _RT_CLOSURE: + return _SC("function"); + case _RT_NATIVECLOSURE: + return _SC("native function"); + case _RT_USERDATA: + case _RT_USERPOINTER: + return _SC("userdata"); + case _RT_THREAD: return _SC("thread"); + case _RT_FUNCPROTO: return _SC("function"); + case _RT_CLASS: return _SC("class"); + case _RT_INSTANCE: return _SC("instance"); + case _RT_WEAKREF: return _SC("weakref"); + default: + return NULL; + } +} + +const SQChar *GetTypeName(const SQObjectPtr &obj1) +{ + return IdType2Name(type(obj1)); +} + +SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len) +{ + SQString *str=ADD_STRING(ss,s,len); + str->_sharedstate=ss; + return str; +} + +void SQString::Release() +{ + REMOVE_STRING(_sharedstate,this); +} + +SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) +{ + SQInteger idx = (SQInteger)TranslateIndex(refpos); + while(idx < _len){ + outkey = (SQInteger)idx; + outval = SQInteger(_val[idx]); + //return idx for the next iteration + return ++idx; + } + //nothing to iterate anymore + return -1; +} + +SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx) +{ + switch(type(idx)){ + case OT_NULL: + return 0; + case OT_INTEGER: + return (SQUnsignedInteger)_integer(idx); + default: Assert(0); break; + } + return 0; +} + +SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type) +{ + if(!_weakref) { + sq_new(_weakref,SQWeakRef); + _weakref->_obj._type = type; + _weakref->_obj._unVal.pRefCounted = this; + } + return _weakref; +} + +SQRefCounted::~SQRefCounted() +{ + if(_weakref) { + _weakref->_obj._type = OT_NULL; + _weakref->_obj._unVal.pRefCounted = NULL; + } +} + +void SQWeakRef::Release() { + if(ISREFCOUNTED(_obj._type)) { + _obj._unVal.pRefCounted->_weakref = NULL; + } + sq_delete(this,SQWeakRef); +} + +bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) { + if(_delegate) { + return _delegate->Get((*_ss(v)->_metamethods)[mm],res); + } + return false; +} + +bool SQDelegable::SetDelegate(SQTable *mt) +{ + SQTable *temp = mt; + if(temp == this) return false; + while (temp) { + if (temp->_delegate == this) return false; //cycle detected + temp = temp->_delegate; + } + if (mt) __ObjAddRef(mt); + __ObjRelease(_delegate); + _delegate = mt; + return true; +} + +bool SQGenerator::Yield(SQVM *v) +{ + if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator")); return false;} + if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; } + SQInteger size = v->_top-v->_stackbase; + _ci=*v->ci; + _stack.resize(size); + for(SQInteger n =0; n_stack[v->_stackbase+n]; + v->_stack[v->_stackbase+n] = _null_; + } + SQInteger nvargs = v->ci->_vargs.size; + SQInteger vargsbase = v->ci->_vargs.base; + for(SQInteger j = nvargs - 1; j >= 0; j--) { + _vargsstack.push_back(v->_vargsstack[vargsbase+j]); + } + _ci._generator=NULL; + for(SQInteger i=0;i<_ci._etraps;i++) { + _etraps.push_back(v->_etraps.top()); + v->_etraps.pop_back(); + } + _state=eSuspended; + return true; +} + +bool SQGenerator::Resume(SQVM *v,SQInteger target) +{ + SQInteger size=_stack.size(); + if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; } + if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; } + SQInteger prevtop=v->_top-v->_stackbase; + PUSH_CALLINFO(v,_ci); + SQInteger oldstackbase=v->_stackbase; + v->_stackbase = v->_top; + v->ci->_target = (SQInt32)target; + v->ci->_generator = this; + v->ci->_vargs.size = (unsigned short)_vargsstack.size(); + + for(SQInteger i=0;i<_ci._etraps;i++) { + v->_etraps.push_back(_etraps.top()); + _etraps.pop_back(); + } + for(SQInteger n =0; n_stack[v->_stackbase+n] = _stack._vals[n]; + _stack._vals[0] = _null_; + } + while(_vargsstack.size()) { + v->_vargsstack.push_back(_vargsstack.back()); + _vargsstack.pop_back(); + } + v->ci->_vargs.base = (unsigned short)(v->_vargsstack.size() - v->ci->_vargs.size); + v->_top=v->_stackbase+size; + v->ci->_prevtop = (SQInt32)prevtop; + v->ci->_prevstkbase = (SQInt32)(v->_stackbase - oldstackbase); + _state=eRunning; + if (type(v->_debughook) != OT_NULL && _rawval(v->_debughook) != _rawval(v->ci->_closure)) + v->CallDebugHook(_SC('c')); + + return true; +} + +void SQArray::Extend(const SQArray *a){ + SQInteger xlen; + if((xlen=a->Size())) + for(SQInteger i=0;i_values[i]); +} + +const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop) +{ + SQUnsignedInteger nvars=_nlocalvarinfos; + const SQChar *res=NULL; + if(nvars>=nseq){ + for(SQUnsignedInteger i=0;i=nop) + { + if(nseq==0){ + vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]); + res=_stringval(_localvarinfos[i]._name); + break; + } + nseq--; + } + } + } + return res; +} + +SQInteger SQFunctionProto::GetLine(SQInstruction *curr) +{ + SQInteger op = (SQInteger)(curr-_instructions); + SQInteger line=_lineinfos[0]._line; + for(SQInteger i=1;i<_nlineinfos;i++){ + if(_lineinfos[i]._op>=op) + return line; + line=_lineinfos[i]._line; + } + return line; +} + +#define _CHECK_IO(exp) { if(!exp)return false; } +bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size) +{ + if(write(up,dest,size) != size) { + v->Raise_Error(_SC("io error (write function failure)")); + return false; + } + return true; +} + +bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size) +{ + if(size && read(up,dest,size) != size) { + v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated")); + return false; + } + return true; +} + +bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQInteger tag) +{ + return SafeWrite(v,write,up,&tag,sizeof(tag)); +} + +bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQInteger tag) +{ + SQInteger t; + _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t))); + if(t != tag){ + v->Raise_Error(_SC("invalid or corrupted closure stream")); + return false; + } + return true; +} + +bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o) +{ + _CHECK_IO(SafeWrite(v,write,up,&type(o),sizeof(SQObjectType))); + switch(type(o)){ + case OT_STRING: + _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger))); + _CHECK_IO(SafeWrite(v,write,up,_stringval(o),rsl(_string(o)->_len))); + break; + case OT_INTEGER: + _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break; + case OT_FLOAT: + _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break; + case OT_NULL: + break; + default: + v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o)); + return false; + } + return true; +} + +bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o) +{ + SQObjectType t; + _CHECK_IO(SafeRead(v,read,up,&t,sizeof(SQObjectType))); + switch(t){ + case OT_STRING:{ + SQInteger len; + _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger))); + _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(rsl(len)),rsl(len))); + o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len); + } + break; + case OT_INTEGER:{ + SQInteger i; + _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break; + } + case OT_FLOAT:{ + SQFloat f; + _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break; + } + case OT_NULL: + o=_null_; + break; + default: + v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t)); + return false; + } + return true; +} + +bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) +{ + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD)); + _CHECK_IO(WriteTag(v,write,up,sizeof(SQChar))); + _CHECK_IO(_funcproto(_function)->Save(v,up,write)); + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL)); + return true; +} + +bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret) +{ + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD)); + _CHECK_IO(CheckTag(v,read,up,sizeof(SQChar))); + SQObjectPtr func; + _CHECK_IO(SQFunctionProto::Load(v,up,read,func)); + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL)); + ret = SQClosure::Create(_ss(v),_funcproto(func)); + return true; +} + +bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) +{ + SQInteger i,nliterals = _nliterals,nparameters = _nparameters; + SQInteger noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos; + SQInteger nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions; + SQInteger ndefaultparams = _ndefaultparams; + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(WriteObject(v,up,write,_sourcename)); + _CHECK_IO(WriteObject(v,up,write,_name)); + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeWrite(v,write,up,&nliterals,sizeof(nliterals))); + _CHECK_IO(SafeWrite(v,write,up,&nparameters,sizeof(nparameters))); + _CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues))); + _CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos))); + _CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos))); + _CHECK_IO(SafeWrite(v,write,up,&ndefaultparams,sizeof(ndefaultparams))); + _CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions))); + _CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions))); + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); + for(i=0;iSave(v,up,write)); + } + _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize))); + _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator))); + _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams))); + return true; +} + +bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret) +{ + SQInteger i, nliterals,nparameters; + SQInteger noutervalues ,nlocalvarinfos ; + SQInteger nlineinfos,ninstructions ,nfunctions,ndefaultparams ; + SQObjectPtr sourcename, name; + SQObjectPtr o; + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(ReadObject(v, up, read, sourcename)); + _CHECK_IO(ReadObject(v, up, read, name)); + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeRead(v,read,up, &nliterals, sizeof(nliterals))); + _CHECK_IO(SafeRead(v,read,up, &nparameters, sizeof(nparameters))); + _CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues))); + _CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos))); + _CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos))); + _CHECK_IO(SafeRead(v,read,up, &ndefaultparams, sizeof(ndefaultparams))); + _CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions))); + _CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions))); + + + SQFunctionProto *f = SQFunctionProto::Create(ninstructions,nliterals,nparameters, + nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams); + SQObjectPtr proto = f; //gets a ref in case of failure + f->_sourcename = sourcename; + f->_name = name; + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + + for(i = 0;i < nliterals; i++){ + _CHECK_IO(ReadObject(v, up, read, o)); + f->_literals[i] = o; + } + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + + for(i = 0; i < nparameters; i++){ + _CHECK_IO(ReadObject(v, up, read, o)); + f->_parameters[i] = o; + } + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + + for(i = 0; i < noutervalues; i++){ + SQUnsignedInteger type; + SQObjectPtr name; + _CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger))); + _CHECK_IO(ReadObject(v, up, read, o)); + _CHECK_IO(ReadObject(v, up, read, name)); + f->_outervalues[i] = SQOuterVar(name,o, (SQOuterType)type); + } + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + + for(i = 0; i < nlocalvarinfos; i++){ + SQLocalVarInfo lvi; + _CHECK_IO(ReadObject(v, up, read, lvi._name)); + _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(SQUnsignedInteger))); + _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(SQUnsignedInteger))); + _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(SQUnsignedInteger))); + f->_localvarinfos[i] = lvi; + } + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(SQLineInfo)*nlineinfos)); + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeRead(v,read,up, f->_defaultparams, sizeof(SQInteger)*ndefaultparams)); + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(SQInstruction)*ninstructions)); + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + for(i = 0; i < nfunctions; i++){ + _CHECK_IO(_funcproto(o)->Load(v, up, read, o)); + f->_functions[i] = o; + } + _CHECK_IO(SafeRead(v,read,up, &f->_stacksize, sizeof(f->_stacksize))); + _CHECK_IO(SafeRead(v,read,up, &f->_bgenerator, sizeof(f->_bgenerator))); + _CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams))); + + ret = f; + return true; +} + +#ifndef NO_GARBAGE_COLLECTOR + +#define START_MARK() if(!(_uiRef&MARK_FLAG)){ \ + _uiRef|=MARK_FLAG; + +#define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \ + AddToChain(chain, this); } + +void SQVM::Mark(SQCollectable **chain) +{ + START_MARK() + SQSharedState::MarkObject(_lasterror,chain); + SQSharedState::MarkObject(_errorhandler,chain); + SQSharedState::MarkObject(_debughook,chain); + SQSharedState::MarkObject(_roottable, chain); + SQSharedState::MarkObject(temp_reg, chain); + for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain); + for(SQUnsignedInteger j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain); + for(SQInteger k = 0; k < _callsstacksize; k++) SQSharedState::MarkObject(_callsstack[k]._closure, chain); + END_MARK() +} + +void SQArray::Mark(SQCollectable **chain) +{ + START_MARK() + SQInteger len = _values.size(); + for(SQInteger i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain); + END_MARK() +} +void SQTable::Mark(SQCollectable **chain) +{ + START_MARK() + if(_delegate) _delegate->Mark(chain); + SQInteger len = _numofnodes; + for(SQInteger i = 0; i < len; i++){ + SQSharedState::MarkObject(_nodes[i].key, chain); + SQSharedState::MarkObject(_nodes[i].val, chain); + } + END_MARK() +} + +void SQClass::Mark(SQCollectable **chain) +{ + START_MARK() + _members->Mark(chain); + if(_base) _base->Mark(chain); + SQSharedState::MarkObject(_attributes, chain); + for(SQUnsignedInteger i =0; i< _defaultvalues.size(); i++) { + SQSharedState::MarkObject(_defaultvalues[i].val, chain); + SQSharedState::MarkObject(_defaultvalues[i].attrs, chain); + } + for(SQUnsignedInteger j =0; j< _methods.size(); j++) { + SQSharedState::MarkObject(_methods[j].val, chain); + SQSharedState::MarkObject(_methods[j].attrs, chain); + } + for(SQUnsignedInteger k =0; k< _metamethods.size(); k++) { + SQSharedState::MarkObject(_metamethods[k], chain); + } + END_MARK() +} + +void SQInstance::Mark(SQCollectable **chain) +{ + START_MARK() + _class->Mark(chain); + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + for(SQUnsignedInteger i =0; i< nvalues; i++) { + SQSharedState::MarkObject(_values[i], chain); + } + END_MARK() +} + +void SQGenerator::Mark(SQCollectable **chain) +{ + START_MARK() + for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain); + for(SQUnsignedInteger j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain); + SQSharedState::MarkObject(_closure, chain); + END_MARK() +} + +void SQClosure::Mark(SQCollectable **chain) +{ + START_MARK() + for(SQUnsignedInteger i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain); + for(SQUnsignedInteger i = 0; i < _defaultparams.size(); i++) SQSharedState::MarkObject(_defaultparams[i], chain); + END_MARK() +} + +void SQNativeClosure::Mark(SQCollectable **chain) +{ + START_MARK() + for(SQUnsignedInteger i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain); + END_MARK() +} + +void SQUserData::Mark(SQCollectable **chain){ + START_MARK() + if(_delegate) _delegate->Mark(chain); + END_MARK() +} + +void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; } + +#endif + +void SQVM::Iterate( CSQStateIterator *pIterator ) +{ + SQSharedState::IterateObject(pIterator,_lasterror,"_lasterror"); + SQSharedState::IterateObject(pIterator,_errorhandler,"_errorhandler"); + SQSharedState::IterateObject(pIterator,_debughook,"_debughook"); + SQSharedState::IterateObject(pIterator,_roottable,"_roottable"); + SQSharedState::IterateObject(pIterator,temp_reg,"temp_reg"); + pIterator->PsuedoKey( "_stack" ); + if ( pIterator->BeginContained() ) + { + for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::IterateObject(pIterator,_stack[i]); + pIterator->EndContained(); + } + pIterator->PsuedoKey( "_vargsstack" ); + if ( pIterator->BeginContained() ) + { + for(SQUnsignedInteger j = 0; j < _vargsstack.size(); j++) SQSharedState::IterateObject(pIterator,_vargsstack[j]); + pIterator->EndContained(); + } +} + +void SQArray::Iterate( CSQStateIterator *pIterator ) +{ + SQInteger len = _values.size(); + for(SQInteger i = 0;i < len; i++) SQSharedState::IterateObject(pIterator,_values[i]); +} + +void SQTable::Iterate( CSQStateIterator *pIterator ) +{ + if(_delegate) + { + SQObject d = { OT_TABLE, _delegate }; + pIterator->PsuedoKey( "_delegate " ); + SQObjectPtr tmp(d); + pIterator->Value( tmp ); + } + SQInteger len = _numofnodes; + for(SQInteger i = 0; i < len; i++){ + pIterator->Key(_nodes[i].key); + SQSharedState::IterateObject(pIterator,_nodes[i].val); + } +} + +void SQClass::Iterate( CSQStateIterator *pIterator ) +{ + SQObject m = { OT_TABLE, _members }; + SQObjectPtr tmpObjectPtr_m( m ); + SQSharedState::IterateObject(pIterator, tmpObjectPtr_m, "_members" ); + if(_base) + { + SQObject b = { OT_CLASS, (SQTable *)_base }; + pIterator->PsuedoKey( "_base " ); + SQObjectPtr tmpObjectPtr_b(b); + pIterator->Value( tmpObjectPtr_b ); + } + SQSharedState::IterateObject(pIterator,_attributes, "_attributes"); + pIterator->PsuedoKey( "_defaultvalues" ); + pIterator->BeginContained(); + for(SQUnsignedInteger i =0; i< _defaultvalues.size(); i++) { + SQSharedState::IterateObject(pIterator,_defaultvalues[i].val); + SQSharedState::IterateObject(pIterator,_defaultvalues[i].attrs); + } + pIterator->EndContained(); + pIterator->PsuedoKey( "_methods" ); + pIterator->BeginContained(); + for(SQUnsignedInteger j =0; j< _methods.size(); j++) { + SQSharedState::IterateObject(pIterator,_methods[j].val); + SQSharedState::IterateObject(pIterator,_methods[j].attrs); + } + pIterator->EndContained(); + pIterator->PsuedoKey( "_metamethods" ); + pIterator->BeginContained(); + for(SQUnsignedInteger k =0; k< _metamethods.size(); k++) { + SQSharedState::IterateObject(pIterator,_metamethods[k]); + } + pIterator->EndContained(); +} + +void SQInstance::Iterate( CSQStateIterator *pIterator ) +{ + SQObject c = { OT_CLASS, (SQTable *)_class }; + pIterator->PsuedoKey( "_class " ); + SQObjectPtr tmpObjectPtr_c( c ); + pIterator->Value( tmpObjectPtr_c ); + + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + for(SQUnsignedInteger i =0; i< nvalues; i++) { + SQSharedState::IterateObject(pIterator,_values[i]); + } +} + +void SQGenerator::Iterate( CSQStateIterator *pIterator ) +{ + for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::IterateObject(pIterator,_stack[i]); + for(SQUnsignedInteger j = 0; j < _vargsstack.size(); j++) SQSharedState::IterateObject(pIterator,_vargsstack[j]); + SQSharedState::IterateObject(pIterator,_closure); +} + +void SQClosure::Iterate( CSQStateIterator *pIterator ) +{ + for(SQUnsignedInteger i = 0; i < _outervalues.size(); i++) SQSharedState::IterateObject(pIterator,_outervalues[i]); + for(SQUnsignedInteger i = 0; i < _defaultparams.size(); i++) SQSharedState::IterateObject(pIterator,_defaultparams[i]); +} + +void SQNativeClosure::Iterate( CSQStateIterator *pIterator ) +{ + for(SQUnsignedInteger i = 0; i < _outervalues.size(); i++) SQSharedState::IterateObject(pIterator,_outervalues[i]); +} + +void SQUserData::Iterate( CSQStateIterator *pIterator ) +{ + if(_delegate) + { + SQObject d = { OT_TABLE, _delegate }; + pIterator->PsuedoKey( "_delegate " ); + SQObjectPtr tmpObjectPtr_d(d); + pIterator->Value( tmpObjectPtr_d ); + } +} + diff --git a/vscript/languages/squirrel/squirrel/sqobject.h b/vscript/languages/squirrel/squirrel/sqobject.h new file mode 100644 index 00000000..81035058 --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqobject.h @@ -0,0 +1,384 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQOBJECT_H_ +#define _SQOBJECT_H_ + +#include "squtils.h" + +#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R')) +#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T')) +#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L')) + +struct SQSharedState; +class CSQStateIterator; + +enum SQMetaMethod{ + MT_ADD=0, + MT_SUB=1, + MT_MUL=2, + MT_DIV=3, + MT_UNM=4, + MT_MODULO=5, + MT_SET=6, + MT_GET=7, + MT_TYPEOF=8, + MT_NEXTI=9, + MT_CMP=10, + MT_CALL=11, + MT_CLONED=12, + MT_NEWSLOT=13, + MT_DELSLOT=14, + MT_TOSTRING=15, + MT_NEWMEMBER=16, + MT_INHERITED=17, + MT_LAST = 18 +}; + +#define MM_ADD _SC("_add") +#define MM_SUB _SC("_sub") +#define MM_MUL _SC("_mul") +#define MM_DIV _SC("_div") +#define MM_UNM _SC("_unm") +#define MM_MODULO _SC("_modulo") +#define MM_SET _SC("_set") +#define MM_GET _SC("_get") +#define MM_TYPEOF _SC("_typeof") +#define MM_NEXTI _SC("_nexti") +#define MM_CMP _SC("_cmp") +#define MM_CALL _SC("_call") +#define MM_CLONED _SC("_cloned") +#define MM_NEWSLOT _SC("_newslot") +#define MM_DELSLOT _SC("_delslot") +#define MM_TOSTRING _SC("_tostring") +#define MM_NEWMEMBER _SC("_newmember") +#define MM_INHERITED _SC("_inherited") + +#define MINPOWER2 4 + +#ifdef _DEBUG +#define SQ_VALIDATE_REF_COUNT( pObj ) if ( (pObj)->_uiRef < 0 ) { DebuggerBreak(); } +#else +#define SQ_VALIDATE_REF_COUNT( pObj ) +#endif + +struct SQRefCounted +{ + SQRefCounted() { _uiRef = 0; _weakref = NULL; } + virtual ~SQRefCounted(); + virtual void Iterate( CSQStateIterator *pIterator ) {}; + SQWeakRef *GetWeakRef(SQObjectType type); + SQInteger _uiRef; // this should be signed to catch bugs + struct SQWeakRef *_weakref; + virtual void Release()=0; +}; + +struct SQWeakRef : SQRefCounted +{ + void Release(); + SQObject _obj; +}; + +#define _realval(o) (type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj) + +struct SQObjectPtr; + +#define __AddRef(type,unval) if(ISREFCOUNTED(type)) \ + { \ + SQ_VALIDATE_REF_COUNT( unval.pRefCounted ); \ + unval.pRefCounted->_uiRef++; \ + } + +#define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)<=0)) \ + { \ + SQ_VALIDATE_REF_COUNT( unval.pRefCounted ); \ + unval.pRefCounted->Release(); \ + } + +#define __ObjRelease(obj) { \ + if((obj)) { \ + if( ( -- ((obj)->_uiRef) ) <= 0 ) \ + { \ + SQ_VALIDATE_REF_COUNT( obj ); \ + (obj)->Release(); \ + } \ + (obj) = NULL; \ + } \ +} + +#define __ObjAddRef(obj) { \ + SQ_VALIDATE_REF_COUNT( obj ); \ + (obj)->_uiRef++; \ +} + +#define type(obj) ((obj)._type) +// VALVE_BUILD -- define a version of 'type' that is less name-space polluting so that we can #undef +// and redef type around VS 2013 STL header files. +#define SQ_TYPE(obj) ((obj)._type) +#define is_delegable(t) (type(t)&SQOBJECT_DELEGABLE) +#define raw_type(obj) _RAW_TYPE((obj)._type) + +#define _integer(obj) ((obj)._unVal.nInteger) +#define _float(obj) ((obj)._unVal.fFloat) +#define _string(obj) ((obj)._unVal.pString) +#define _table(obj) ((obj)._unVal.pTable) +#define _array(obj) ((obj)._unVal.pArray) +#define _closure(obj) ((obj)._unVal.pClosure) +#define _generator(obj) ((obj)._unVal.pGenerator) +#define _nativeclosure(obj) ((obj)._unVal.pNativeClosure) +#define _userdata(obj) ((obj)._unVal.pUserData) +#define _userpointer(obj) ((obj)._unVal.pUserPointer) +#define _thread(obj) ((obj)._unVal.pThread) +#define _funcproto(obj) ((obj)._unVal.pFunctionProto) +#define _class(obj) ((obj)._unVal.pClass) +#define _instance(obj) ((obj)._unVal.pInstance) +#define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable) +#define _weakref(obj) ((obj)._unVal.pWeakRef) +#define _refcounted(obj) ((obj)._unVal.pRefCounted) +#define _rawval(obj) ((obj)._unVal.raw) + +#define _stringval(obj) (obj)._unVal.pString->_val +#define _userdataval(obj) (obj)._unVal.pUserData->_val + +#define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num)) +#define tointeger(num) ((type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num)) +///////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////// +struct SQObjectPtr : public SQObject +{ + SQObjectPtr() + { + SQ_OBJECT_RAWINIT() + _type=OT_NULL; + _unVal.pUserPointer=NULL; + } + SQObjectPtr(const SQObjectPtr &o) + { + SQ_OBJECT_RAWINIT() + _type=o._type; + _unVal=o._unVal; + __AddRef(_type,_unVal); + } + SQObjectPtr(const SQObject &o) + { + SQ_OBJECT_RAWINIT() + _type=o._type; + _unVal=o._unVal; + __AddRef(_type,_unVal); + } + SQObjectPtr(SQTable *pTable) + { + SQ_OBJECT_RAWINIT() + _type=OT_TABLE; + _unVal.pTable=pTable; + Assert(_unVal.pTable); + __AddRef(_type,_unVal); + } + SQObjectPtr(SQClass *pClass) + { + SQ_OBJECT_RAWINIT() + _type=OT_CLASS; + _unVal.pClass=pClass; + Assert(_unVal.pClass); + __AddRef(_type,_unVal); + } + SQObjectPtr(SQInstance *pInstance) + { + SQ_OBJECT_RAWINIT() + _type=OT_INSTANCE; + _unVal.pInstance=pInstance; + Assert(_unVal.pInstance); + __AddRef(_type,_unVal); + } + SQObjectPtr(SQArray *pArray) + { + SQ_OBJECT_RAWINIT() + _type=OT_ARRAY; + _unVal.pArray=pArray; + Assert(_unVal.pArray); + __AddRef(_type,_unVal); + } + SQObjectPtr(SQClosure *pClosure) + { + SQ_OBJECT_RAWINIT() + _type=OT_CLOSURE; + _unVal.pClosure=pClosure; + Assert(_unVal.pClosure); + __AddRef(_type,_unVal); + } + SQObjectPtr(SQGenerator *pGenerator) + { + SQ_OBJECT_RAWINIT() + _type=OT_GENERATOR; + _unVal.pGenerator=pGenerator; + Assert(_unVal.pGenerator); + __AddRef(_type,_unVal); + } + SQObjectPtr(SQNativeClosure *pNativeClosure) + { + SQ_OBJECT_RAWINIT() + _type=OT_NATIVECLOSURE; + _unVal.pNativeClosure=pNativeClosure; + Assert(_unVal.pNativeClosure); + __AddRef(_type,_unVal); + } + SQObjectPtr(SQString *pString) + { + SQ_OBJECT_RAWINIT() + _type=OT_STRING; + _unVal.pString=pString; + Assert(_unVal.pString); + __AddRef(_type,_unVal); + } + SQObjectPtr(SQUserData *pUserData) + { + SQ_OBJECT_RAWINIT() + _type=OT_USERDATA; + _unVal.pUserData=pUserData; + Assert(_unVal.pUserData); + __AddRef(_type,_unVal); + } + SQObjectPtr(SQVM *pThread) + { + SQ_OBJECT_RAWINIT() + _type=OT_THREAD; + _unVal.pThread=pThread; + Assert(_unVal.pThread); + __AddRef(_type,_unVal); + } + SQObjectPtr(SQWeakRef *pWeakRef) + { + SQ_OBJECT_RAWINIT() + _type=OT_WEAKREF; + _unVal.pWeakRef=pWeakRef; + Assert(_unVal.pWeakRef); + __AddRef(_type,_unVal); + } + SQObjectPtr(SQFunctionProto *pFunctionProto) + { + SQ_OBJECT_RAWINIT() + _type=OT_FUNCPROTO; + _unVal.pFunctionProto=pFunctionProto; + Assert(_unVal.pFunctionProto); + __AddRef(_type,_unVal); + } + SQObjectPtr(SQInteger nInteger) + { + SQ_OBJECT_RAWINIT() + _type=OT_INTEGER; + _unVal.nInteger=nInteger; + } + SQObjectPtr(SQFloat fFloat) + { + SQ_OBJECT_RAWINIT() + _type=OT_FLOAT; + _unVal.fFloat=fFloat; + } + SQObjectPtr(bool bBool) + { + SQ_OBJECT_RAWINIT() + _type = OT_BOOL; + _unVal.nInteger = bBool?1:0; + } + SQObjectPtr(SQUserPointer pUserPointer) + { + SQ_OBJECT_RAWINIT() + _type=OT_USERPOINTER; + _unVal.pUserPointer=pUserPointer; + } + ~SQObjectPtr() + { + __Release(_type,_unVal); + } + inline void Null() + { + SQObjectType tOldType; + SQObjectValue unOldVal; + tOldType = _type; + unOldVal = _unVal; + _type = OT_NULL; + _unVal.pUserPointer = NULL; + __Release(tOldType,unOldVal); + } + inline SQObjectPtr& operator=(SQInteger i) + { + __Release(_type,_unVal); + _unVal.nInteger = i; + _type = OT_INTEGER; + return *this; + } + inline SQObjectPtr& operator=(SQFloat f) + { + __Release(_type,_unVal); + _unVal.fFloat = f; + _type = OT_FLOAT; + return *this; + } + inline SQObjectPtr& operator=(const SQObjectPtr& obj) + { + SQObjectType tOldType; + SQObjectValue unOldVal; + tOldType=_type; + unOldVal=_unVal; + _unVal = obj._unVal; + _type = obj._type; + __AddRef(_type,_unVal); + __Release(tOldType,unOldVal); + return *this; + } + inline SQObjectPtr& operator=(const SQObject& obj) + { + SQObjectType tOldType; + SQObjectValue unOldVal; + tOldType=_type; + unOldVal=_unVal; + _unVal = obj._unVal; + _type = obj._type; + __AddRef(_type,_unVal); + __Release(tOldType,unOldVal); + return *this; + } + private: + SQObjectPtr(const SQChar *){} //safety +}; +///////////////////////////////////////////////////////////////////////////////////// +#ifndef NO_GARBAGE_COLLECTOR +#define MARK_FLAG 0x40000000 +struct SQCollectable : public SQRefCounted { + SQCollectable *_next; + SQCollectable *_prev; + SQSharedState *_sharedstate; + virtual void Release()=0; + virtual void Mark(SQCollectable **chain)=0; + void UnMark(); + virtual void Finalize()=0; + static void AddToChain(SQCollectable **chain,SQCollectable *c); + static void RemoveFromChain(SQCollectable **chain,SQCollectable *c); +}; + + +#define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj) +#define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);} +#define CHAINABLE_OBJ SQCollectable +#define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;} +#else + +#define ADD_TO_CHAIN(chain,obj) ((void)0) +#define REMOVE_FROM_CHAIN(chain,obj) ((void)0) +#define CHAINABLE_OBJ SQRefCounted +#define INIT_CHAIN() ((void)0) +#endif + +struct SQDelegable : public CHAINABLE_OBJ { + bool SetDelegate(SQTable *m); + virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res); + SQTable *_delegate; +}; + +SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx); +typedef sqvector SQObjectPtrVec; +typedef sqvector SQIntVec; +const SQChar *GetTypeName(const SQObjectPtr &obj1); +const SQChar *IdType2Name(SQObjectType type); + + + +#endif //_SQOBJECT_H_ diff --git a/vscript/languages/squirrel/squirrel/sqopcodes.h b/vscript/languages/squirrel/squirrel/sqopcodes.h new file mode 100644 index 00000000..a05788bf --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqopcodes.h @@ -0,0 +1,115 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQOPCODES_H_ +#define _SQOPCODES_H_ + +#define MAX_FUNC_STACKSIZE 0xFF +#define MAX_LITERALS ((SQInteger)0x7FFFFFFF) + +enum BitWiseOP { + BW_AND = 0, + BW_OR = 2, + BW_XOR = 3, + BW_SHIFTL = 4, + BW_SHIFTR = 5, + BW_USHIFTR = 6 +}; + +enum CmpOP { + CMP_G = 0, + CMP_GE = 2, + CMP_L = 3, + CMP_LE = 4 +}; +enum SQOpcode +{ + _OP_LINE= 0x00, + _OP_LOAD= 0x01, + _OP_LOADINT= 0x02, + _OP_LOADFLOAT= 0x03, + _OP_DLOAD= 0x04, + _OP_TAILCALL= 0x05, + _OP_CALL= 0x06, + _OP_PREPCALL= 0x07, + _OP_PREPCALLK= 0x08, + _OP_GETK= 0x09, + _OP_MOVE= 0x0A, + _OP_NEWSLOT= 0x0B, + _OP_DELETE= 0x0C, + _OP_SET= 0x0D, + _OP_GET= 0x0E, + _OP_EQ= 0x0F, + _OP_NE= 0x10, + _OP_ARITH= 0x11, + _OP_BITW= 0x12, + _OP_RETURN= 0x13, + _OP_LOADNULLS= 0x14, + _OP_LOADROOTTABLE= 0x15, + _OP_LOADBOOL= 0x16, + _OP_DMOVE= 0x17, + _OP_JMP= 0x18, + _OP_JNZ= 0x19, + _OP_JZ= 0x1A, + _OP_LOADFREEVAR= 0x1B, + _OP_VARGC= 0x1C, + _OP_GETVARGV= 0x1D, + _OP_NEWTABLE= 0x1E, + _OP_NEWARRAY= 0x1F, + _OP_APPENDARRAY= 0x20, + _OP_GETPARENT= 0x21, + _OP_COMPARITH= 0x22, + _OP_COMPARITHL= 0x23, + _OP_INC= 0x24, + _OP_INCL= 0x25, + _OP_PINC= 0x26, + _OP_PINCL= 0x27, + _OP_CMP= 0x28, + _OP_EXISTS= 0x29, + _OP_INSTANCEOF= 0x2A, + _OP_AND= 0x2B, + _OP_OR= 0x2C, + _OP_NEG= 0x2D, + _OP_NOT= 0x2E, + _OP_BWNOT= 0x2F, + _OP_CLOSURE= 0x30, + _OP_YIELD= 0x31, + _OP_RESUME= 0x32, + _OP_FOREACH= 0x33, + _OP_POSTFOREACH= 0x34, + _OP_DELEGATE= 0x35, + _OP_CLONE= 0x36, + _OP_TYPEOF= 0x37, + _OP_PUSHTRAP= 0x38, + _OP_POPTRAP= 0x39, + _OP_THROW= 0x3A, + _OP_CLASS= 0x3B, + _OP_NEWSLOTA= 0x3C, +}; + +struct SQInstructionDesc { + const SQChar *name; +}; + +struct SQInstruction +{ + SQInstruction(){}; + SQInstruction(SQOpcode _op,SQInteger a0=0,SQInteger a1=0,SQInteger a2=0,SQInteger a3=0) + { op = _op; + _arg0 = (unsigned char)a0;_arg1 = (SQInt32)a1; + _arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3; + } + + + SQInt32 _arg1; + unsigned char op; + unsigned char _arg0; + unsigned char _arg2; + unsigned char _arg3; +}; + +#include "squtils.h" +typedef sqvector SQInstructionVec; + +#define NEW_SLOT_ATTRIBUTES_FLAG 0x01 +#define NEW_SLOT_STATIC_FLAG 0x02 + +#endif // _SQOPCODES_H_ diff --git a/vscript/languages/squirrel/squirrel/sqpcheader.h b/vscript/languages/squirrel/squirrel/sqpcheader.h new file mode 100644 index 00000000..a3fb037e --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqpcheader.h @@ -0,0 +1,19 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQPCHEADER_H_ +#define _SQPCHEADER_H_ + +#if defined(_MSC_VER) && defined(_DEBUG) +#include +#endif + +#include +#include +#include +#include +#include +//squirrel stuff +#include +#include "sqobject.h" +#include "sqstate.h" + +#endif //_SQPCHEADER_H_ diff --git a/vscript/languages/squirrel/squirrel/sqstate.cpp b/vscript/languages/squirrel/squirrel/sqstate.cpp new file mode 100644 index 00000000..ecc741b9 --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqstate.cpp @@ -0,0 +1,725 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqopcodes.h" +#include "sqvm.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "sqstring.h" +#include "sqtable.h" +#include "sqarray.h" +#include "squserdata.h" +#include "sqclass.h" + +#ifdef DEBUG_SQSTRING_LEAKS +#include "tier1/utldict.h" +#endif + +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#undef new // allow placement new +#endif + +SQObjectPtr _null_; +SQObjectPtr _true_(true); +SQObjectPtr _false_(false); +SQObjectPtr _one_((SQInteger)1); +SQObjectPtr _minusone_((SQInteger)-1); + +SQSharedState::SQSharedState() +{ + _compilererrorhandler = NULL; + _printfunc = NULL; + _debuginfo = false; + _notifyallexceptions = false; + m_pOwnerData = NULL; + _gc_disableDepth = 0; +} + +#define newsysstring(s) { \ + _systemstrings->push_back(SQString::Create(this,s)); \ + } + +#define newmetamethod(s) { \ + _metamethods->push_back(SQString::Create(this,s)); \ + _table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \ + } + +bool CompileTypemask(SQIntVec &res,const SQChar *typemask) +{ + SQInteger i = 0; + + SQInteger mask = 0; + while(typemask[i] != 0) { + + switch(typemask[i]){ + case 'o': mask |= _RT_NULL; break; + case 'i': mask |= _RT_INTEGER; break; + case 'f': mask |= _RT_FLOAT; break; + case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break; + case 's': mask |= _RT_STRING; break; + case 't': mask |= _RT_TABLE; break; + case 'a': mask |= _RT_ARRAY; break; + case 'u': mask |= _RT_USERDATA; break; + case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break; + case 'b': mask |= _RT_BOOL; break; + case 'g': mask |= _RT_GENERATOR; break; + case 'p': mask |= _RT_USERPOINTER; break; + case 'v': mask |= _RT_THREAD; break; + case 'x': mask |= _RT_INSTANCE; break; + case 'y': mask |= _RT_CLASS; break; + case 'r': mask |= _RT_WEAKREF; break; + case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue; + case ' ': i++; continue; //ignores spaces + default: + return false; + } + i++; + if(typemask[i] == '|') { + i++; + if(typemask[i] == 0) + return false; + continue; + } + res.push_back(mask); + mask = 0; + + } + return true; +} + +SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz) +{ + SQInteger i=0; + SQTable *t=SQTable::Create(ss,0); + while(funcz[i].name!=0){ + SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f); + nc->_nparamscheck = funcz[i].nparamscheck; + nc->_name = SQString::Create(ss,funcz[i].name); + if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask)) + return NULL; + t->NewSlot(SQString::Create(ss,funcz[i].name),nc); + i++; + } + return t; +} + +void SQSharedState::Init() +{ + _scratchpad=NULL; + _scratchpadsize=0; +#ifndef NO_GARBAGE_COLLECTOR + _gc_chain=NULL; +#endif + sq_new(_stringtable,StringTable); + sq_new(_metamethods,SQObjectPtrVec); + sq_new(_systemstrings,SQObjectPtrVec); + sq_new(_types,SQObjectPtrVec); + _metamethodsmap = SQTable::Create(this,MT_LAST-1); + //adding type strings to avoid memory trashing + //types names + newsysstring(_SC("null")); + newsysstring(_SC("table")); + newsysstring(_SC("array")); + newsysstring(_SC("closure")); + newsysstring(_SC("string")); + newsysstring(_SC("userdata")); + newsysstring(_SC("integer")); + newsysstring(_SC("float")); + newsysstring(_SC("userpointer")); + newsysstring(_SC("function")); + newsysstring(_SC("generator")); + newsysstring(_SC("thread")); + newsysstring(_SC("class")); + newsysstring(_SC("instance")); + newsysstring(_SC("bool")); + //meta methods + newmetamethod(MM_ADD); + newmetamethod(MM_SUB); + newmetamethod(MM_MUL); + newmetamethod(MM_DIV); + newmetamethod(MM_UNM); + newmetamethod(MM_MODULO); + newmetamethod(MM_SET); + newmetamethod(MM_GET); + newmetamethod(MM_TYPEOF); + newmetamethod(MM_NEXTI); + newmetamethod(MM_CMP); + newmetamethod(MM_CALL); + newmetamethod(MM_CLONED); + newmetamethod(MM_NEWSLOT); + newmetamethod(MM_DELSLOT); + newmetamethod(MM_TOSTRING); + newmetamethod(MM_NEWMEMBER); + newmetamethod(MM_INHERITED); + + _constructoridx = SQString::Create(this,_SC("constructor")); + _registry = SQTable::Create(this,0); + _consts = SQTable::Create(this,0); + _table_default_delegate = CreateDefaultDelegate(this,_table_default_delegate_funcz); + _array_default_delegate = CreateDefaultDelegate(this,_array_default_delegate_funcz); + _string_default_delegate = CreateDefaultDelegate(this,_string_default_delegate_funcz); + _number_default_delegate = CreateDefaultDelegate(this,_number_default_delegate_funcz); + _closure_default_delegate = CreateDefaultDelegate(this,_closure_default_delegate_funcz); + _generator_default_delegate = CreateDefaultDelegate(this,_generator_default_delegate_funcz); + _thread_default_delegate = CreateDefaultDelegate(this,_thread_default_delegate_funcz); + _class_default_delegate = CreateDefaultDelegate(this,_class_default_delegate_funcz); + _instance_default_delegate = CreateDefaultDelegate(this,_instance_default_delegate_funcz); + _weakref_default_delegate = CreateDefaultDelegate(this,_weakref_default_delegate_funcz); + +} + +SQSharedState::~SQSharedState() +{ + _constructoridx = _null_; + _table(_registry)->Finalize(); + _table(_consts)->Finalize(); + _table(_metamethodsmap)->Finalize(); + _registry = _null_; + _consts = _null_; + _metamethodsmap = _null_; + while(!_systemstrings->empty()) { + _systemstrings->back()=_null_; + _systemstrings->pop_back(); + } + _thread(_root_vm)->Finalize(); + _root_vm = _null_; + _table_default_delegate = _null_; + _array_default_delegate = _null_; + _string_default_delegate = _null_; + _number_default_delegate = _null_; + _closure_default_delegate = _null_; + _generator_default_delegate = _null_; + _thread_default_delegate = _null_; + _class_default_delegate = _null_; + _instance_default_delegate = _null_; + _weakref_default_delegate = _null_; + _refs_table.Finalize(); +#ifndef NO_GARBAGE_COLLECTOR + SQCollectable *t = _gc_chain; + SQCollectable *nx = NULL; + while(t) { + SQ_VALIDATE_REF_COUNT( t ); + t->_uiRef++; + t->Finalize(); + nx = t->_next; + if(--t->_uiRef <= 0) + { + SQ_VALIDATE_REF_COUNT( t ); + t->Release(); + } + t=nx; + } + Assert(_gc_chain==NULL); //just to prove a theory + while(_gc_chain){ + _gc_chain->_uiRef++; + SQ_VALIDATE_REF_COUNT( _gc_chain ); + _gc_chain->Release(); + } +#endif + + sq_delete(_types,SQObjectPtrVec); + sq_delete(_systemstrings,SQObjectPtrVec); + sq_delete(_metamethods,SQObjectPtrVec); + sq_delete(_stringtable,StringTable); + if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize); +} + + +SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name) +{ + if(type(name) != OT_STRING) + return -1; + SQObjectPtr ret; + if(_table(_metamethodsmap)->Get(name,ret)) { + return _integer(ret); + } + return -1; +} + +inline bool IsContainer( SQObjectType type ) +{ + switch(type){ + case OT_TABLE: + case OT_ARRAY: + case OT_USERDATA: + case OT_CLOSURE: + case OT_NATIVECLOSURE: + case OT_GENERATOR: + case OT_THREAD: + case OT_CLASS: + case OT_INSTANCE: + return true; + default: + return false; + } +} + +void SQSharedState::Iterate( SQVM *vm, CSQStateIterator *pIterator ) +{ +#ifndef NO_GARBAGE_COLLECTOR + CollectGarbage( vm ); + SQInteger n=0; + SQCollectable *tchain=NULL; + SQVM *vms = _thread(_root_vm); + + vms->Iterate( pIterator ); + SQInteger x = _table(_thread(_root_vm)->_roottable)->CountUsed(); + // _refs_table.Mark(&tchain); + IterateObject(pIterator,_registry,"_registry"); + IterateObject(pIterator,_consts,"_consts"); + IterateObject(pIterator,_metamethodsmap,"_metamethodsmap"); + IterateObject(pIterator,_table_default_delegate,"_table_default_delegate"); + IterateObject(pIterator,_array_default_delegate,"_array_default_delegate"); + IterateObject(pIterator,_string_default_delegate,"_string_default_delegate"); + IterateObject(pIterator,_number_default_delegate,"_number_default_delegate"); + IterateObject(pIterator,_generator_default_delegate,"_generator_default_delegate"); + IterateObject(pIterator,_thread_default_delegate,"_thread_default_delegate"); + IterateObject(pIterator,_closure_default_delegate,"_closure_default_delegate"); + IterateObject(pIterator,_class_default_delegate,"_class_default_delegate"); + IterateObject(pIterator,_instance_default_delegate,"_instance_default_delegate"); + IterateObject(pIterator,_weakref_default_delegate,"_weakref_default_delegate"); + + _refcounted(_registry)->_uiRef &= ~MARK_FLAG; + _refcounted(_consts)->_uiRef &= ~MARK_FLAG; + _refcounted(_metamethodsmap)->_uiRef &= ~MARK_FLAG; + _refcounted(_table_default_delegate)->_uiRef &= ~MARK_FLAG; + _refcounted(_array_default_delegate)->_uiRef &= ~MARK_FLAG; + _refcounted(_string_default_delegate)->_uiRef &= ~MARK_FLAG; + _refcounted(_number_default_delegate)->_uiRef &= ~MARK_FLAG; + _refcounted(_generator_default_delegate)->_uiRef &= ~MARK_FLAG; + _refcounted(_thread_default_delegate)->_uiRef &= ~MARK_FLAG; + _refcounted(_closure_default_delegate)->_uiRef &= ~MARK_FLAG; + _refcounted(_class_default_delegate)->_uiRef &= ~MARK_FLAG; + _refcounted(_instance_default_delegate)->_uiRef &= ~MARK_FLAG; + _refcounted(_weakref_default_delegate)->_uiRef &= ~MARK_FLAG; + + SQCollectable *t = _gc_chain; + while(t) + { + t->UnMark(); + t = t->_next; + } +#endif +} + +void SQSharedState::IterateObject( CSQStateIterator *pIterator, SQObjectPtr &value, const char *pszName ) +{ +#ifndef NO_GARBAGE_COLLECTOR + if ( pszName ) + { + pIterator->PsuedoKey( pszName ); + } + + pIterator->Value( value ); + if ( IsContainer( type(value) ) ) + { + if ( !( value._unVal.pRefCounted->_uiRef & MARK_FLAG ) ) + { + if ( pIterator->BeginContained() ) + { + value._unVal.pRefCounted->_uiRef |= MARK_FLAG; + value._unVal.pRefCounted->Iterate( pIterator ); + pIterator->EndContained(); + } + } + } +#endif +} + + +#ifndef NO_GARBAGE_COLLECTOR + +void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain) +{ + switch(type(o)){ + case OT_TABLE:_table(o)->Mark(chain);break; + case OT_ARRAY:_array(o)->Mark(chain);break; + case OT_USERDATA:_userdata(o)->Mark(chain);break; + case OT_CLOSURE:_closure(o)->Mark(chain);break; + case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break; + case OT_GENERATOR:_generator(o)->Mark(chain);break; + case OT_THREAD:_thread(o)->Mark(chain);break; + case OT_CLASS:_class(o)->Mark(chain);break; + case OT_INSTANCE:_instance(o)->Mark(chain);break; + default: break; //shutup compiler + } +} + + +SQInteger SQSharedState::CollectGarbage(SQVM *vm) +{ + Assert( _gc_disableDepth >=0 ); + if ( _gc_disableDepth > 0 ) + { + return 0; + } + SQInteger n=0; + SQCollectable *tchain=NULL; + SQVM *vms = _thread(_root_vm); + + vms->Mark(&tchain); + SQInteger x = _table(_thread(_root_vm)->_roottable)->CountUsed(); + _refs_table.Mark(&tchain); + MarkObject(_registry,&tchain); + MarkObject(_consts,&tchain); + MarkObject(_metamethodsmap,&tchain); + MarkObject(_table_default_delegate,&tchain); + MarkObject(_array_default_delegate,&tchain); + MarkObject(_string_default_delegate,&tchain); + MarkObject(_number_default_delegate,&tchain); + MarkObject(_generator_default_delegate,&tchain); + MarkObject(_thread_default_delegate,&tchain); + MarkObject(_closure_default_delegate,&tchain); + MarkObject(_class_default_delegate,&tchain); + MarkObject(_instance_default_delegate,&tchain); + MarkObject(_weakref_default_delegate,&tchain); + + SQCollectable *t = _gc_chain; + SQCollectable *nx = NULL; + while(t) { + SQ_VALIDATE_REF_COUNT( t ); + t->_uiRef++; + t->Finalize(); + nx = t->_next; + if(--t->_uiRef <= 0) + { + SQ_VALIDATE_REF_COUNT( t ); + t->Release(); + } + t = nx; + n++; + } + + t = tchain; + while(t) { + t->UnMark(); + t = t->_next; + } + _gc_chain = tchain; + SQInteger z = _table(_thread(_root_vm)->_roottable)->CountUsed(); + Assert(z == x); + return n; +} +#endif + +#ifndef NO_GARBAGE_COLLECTOR +void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c) +{ + c->_prev = NULL; + c->_next = *chain; + if(*chain) (*chain)->_prev = c; + *chain = c; +} + +void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c) +{ + if(c->_prev) c->_prev->_next = c->_next; + else *chain = c->_next; + if(c->_next) + c->_next->_prev = c->_prev; + c->_next = NULL; + c->_prev = NULL; +} +#endif + +SQChar* SQSharedState::GetScratchPad(SQInteger size) +{ + SQInteger newsize; + if(size>0) { + if(_scratchpadsize < size) { + newsize = size + (size>>1); + _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); + _scratchpadsize = newsize; + + }else if(_scratchpadsize >= (size<<5)) { + newsize = _scratchpadsize >> 1; + _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); + _scratchpadsize = newsize; + } + } + return _scratchpad; +} + +RefTable::RefTable() +{ + AllocNodes(4); +} + +void RefTable::Finalize() +{ + RefNode *nodes = _nodes; + for(SQUnsignedInteger n = 0; n < _numofslots; n++) { + nodes->obj = _null_; + nodes++; + } +} + +RefTable::~RefTable() +{ + SQ_FREE(_buckets,(_numofslots * sizeof(RefNode *)) + (_numofslots * sizeof(RefNode))); +} + +#ifndef NO_GARBAGE_COLLECTOR +void RefTable::Mark(SQCollectable **chain) +{ + RefNode *nodes = (RefNode *)_nodes; + for(SQUnsignedInteger n = 0; n < _numofslots; n++) { + if(type(nodes->obj) != OT_NULL) { + SQSharedState::MarkObject(nodes->obj,chain); + } + nodes++; + } +} +#endif + +void RefTable::AddRef(SQObject &obj) +{ + SQHash mainpos; + RefNode *prev; + RefNode *ref = Get(obj,mainpos,&prev,true); + ref->refs++; +} + +SQBool RefTable::Release(SQObject &obj) +{ + SQHash mainpos; + RefNode *prev; + RefNode *ref = Get(obj,mainpos,&prev,false); + if(ref) { + if(--ref->refs == 0) { + SQObjectPtr o = ref->obj; + if(prev) { + prev->next = ref->next; + } + else { + _buckets[mainpos] = ref->next; + } + ref->next = _freelist; + _freelist = ref; + _slotused--; + ref->obj = _null_; + //<>test for shrink? + return SQTrue; + } + } + else { + Assert(0); + } + return SQFalse; +} + +void RefTable::Resize(SQUnsignedInteger size) +{ + RefNode **oldbucks = _buckets; + RefNode *t = _nodes; + SQUnsignedInteger oldnumofslots = _numofslots; + AllocNodes(size); + //rehash + SQUnsignedInteger nfound = 0; + for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) { + if(type(t->obj) != OT_NULL) { + //add back; + Assert(t->refs != 0); + RefNode *nn = Add(::HashObj(t->obj)&(_numofslots-1),t->obj); + nn->refs = t->refs; + t->obj = _null_; + nfound++; + } + t++; + } + Assert(nfound == oldnumofslots); + SQ_FREE(oldbucks,(oldnumofslots * sizeof(RefNode *)) + (oldnumofslots * sizeof(RefNode))); +} + +RefTable::RefNode *RefTable::Add(SQHash mainpos,SQObject &obj) +{ + RefNode *t = _buckets[mainpos]; + RefNode *newnode = _freelist; + newnode->obj = obj; + _buckets[mainpos] = newnode; + _freelist = _freelist->next; + newnode->next = t; + Assert(newnode->refs == 0); + _slotused++; + return newnode; +} + +RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add) +{ + RefNode *ref; + mainpos = ::HashObj(obj)&(_numofslots-1); + *prev = NULL; + for (ref = _buckets[mainpos]; ref; ) { + if(_rawval(ref->obj) == _rawval(obj) && type(ref->obj) == type(obj)) + break; + *prev = ref; + ref = ref->next; + } + if(ref == NULL && add) { + if(_numofslots == _slotused) { + Assert(_freelist == 0); + Resize(_numofslots*2); + mainpos = ::HashObj(obj)&(_numofslots-1); + } + ref = Add(mainpos,obj); + } + return ref; +} + +void RefTable::AllocNodes(SQUnsignedInteger size) +{ + RefNode **bucks; + RefNode *nodes; + bucks = (RefNode **)SQ_MALLOC((size * sizeof(RefNode *)) + (size * sizeof(RefNode))); + nodes = (RefNode *)&bucks[size]; + RefNode *temp = nodes; + SQUnsignedInteger n; + for(n = 0; n < size - 1; n++) { + bucks[n] = NULL; + temp->refs = 0; + new (&temp->obj) SQObjectPtr; + temp->next = temp+1; + temp++; + } + bucks[n] = NULL; + temp->refs = 0; + new (&temp->obj) SQObjectPtr; + temp->next = NULL; + _freelist = nodes; + _nodes = nodes; + _buckets = bucks; + _slotused = 0; + _numofslots = size; +} +////////////////////////////////////////////////////////////////////////// +//StringTable +/* +* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.) +* http://www.lua.org/copyright.html#4 +* http://www.lua.org/source/4.0.1/src_lstring.c.html +*/ + +StringTable::StringTable() +{ + AllocNodes(4); + _slotused = 0; +} + +StringTable::~StringTable() +{ + SQ_FREE(_strings,sizeof(SQString*)*_numofslots); + _strings = NULL; +} + +void StringTable::AllocNodes(SQInteger size) +{ + _numofslots = size; + _strings = (SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots); + memset(_strings,0,sizeof(SQString*)*_numofslots); +} + +#ifdef DEBUG_SQSTRING_LEAKS +bool g_bDumpSQStrings; +#endif + +SQString *StringTable::Add(const SQChar *news,SQInteger len) +{ + if(len<0) + len = (SQInteger)scstrlen(news); + SQHash h = ::_hashstr(news,len)&(_numofslots-1); + SQString *s; + for (s = _strings[h]; s; s = s->_next){ + if(s->_len == len && (!memcmp(news,s->_val,rsl(len)))) + return s; //found + } + + SQString *t=(SQString *)SQ_MALLOC(rsl(len)+sizeof(SQString)); + new (t) SQString; + memcpy(t->_val,news,rsl(len)); + t->_val[len] = _SC('\0'); + t->_len = len; + t->_hash = ::_hashstr(news,len); + t->_next = _strings[h]; + _strings[h] = t; + _slotused++; + if (_slotused > _numofslots) /* too crowded? */ + Resize(_numofslots*2); + +#ifdef DEBUG_SQSTRING_LEAKS + if ( g_bDumpSQStrings ) + { + g_bDumpSQStrings = false; + CUtlDict< CCopyableUtlVector, int > sorter; + Msg( "{\n"); + for (SQInteger i=0; i<(int)_numofslots; i++){ + SQString *p = _strings[i]; + while(p){ + int i = sorter.Find( p->_val ); + if ( i == -1 ) + { + i = sorter.Insert( p->_val ); + } + sorter[i].AddToTail( p ); + SQString *next = p->_next; + p = next; + } + } + int ii = sorter.First(); + while ( ii != -1 ) + { + for ( int j = 0; j < sorter[ii].Count(); j++ ) + { + Msg( "0x%x/%2d: %s\n", sorter[ii][j], sorter[ii][j]->_uiRef, sorter[ii][j]->_val ); + } + ii = sorter.Next( ii ); + } + Msg( "}\n"); + } +#endif + + return t; +} + +void StringTable::Resize(SQInteger size) +{ + SQInteger oldsize=_numofslots; + SQString **oldtable=_strings; + AllocNodes(size); + for (SQInteger i=0; i_next; + SQHash h = p->_hash&(_numofslots-1); + p->_next = _strings[h]; + _strings[h] = p; + p = next; + } + } + SQ_FREE(oldtable,oldsize*sizeof(SQString*)); +} + +void StringTable::Remove(SQString *bs) +{ + SQString *s; + SQString *prev=NULL; + SQHash h = bs->_hash&(_numofslots - 1); + + for (s = _strings[h]; s; ){ + if(s == bs){ + if(prev) + prev->_next = s->_next; + else + _strings[h] = s->_next; + _slotused--; + SQInteger slen = s->_len; + s->~SQString(); + SQ_FREE(s,sizeof(SQString) + rsl(slen)); + return; + } + prev = s; + s = s->_next; + } + Assert(0);//if this fail something is wrong +} diff --git a/vscript/languages/squirrel/squirrel/sqstate.h b/vscript/languages/squirrel/squirrel/sqstate.h new file mode 100644 index 00000000..04de870a --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqstate.h @@ -0,0 +1,172 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTATE_H_ +#define _SQSTATE_H_ + +#include "squtils.h" +#include "sqobject.h" +struct SQString; +struct SQTable; +//max number of character for a printed number +#define NUMBER_MAX_CHAR 50 + +struct StringTable +{ + StringTable(); + ~StringTable(); + SQString *Add(const SQChar *,SQInteger len); + void Remove(SQString *); +private: + void Resize(SQInteger size); + void AllocNodes(SQInteger size); + SQString **_strings; + SQUnsignedInteger _numofslots; + SQUnsignedInteger _slotused; +}; + +struct RefTable { + struct RefNode { + SQObjectPtr obj; + SQUnsignedInteger refs; + struct RefNode *next; + }; + RefTable(); + ~RefTable(); + void AddRef(SQObject &obj); + SQBool Release(SQObject &obj); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); +#endif + void Iterate( CSQStateIterator *pIterator ); + + void Finalize(); +private: + RefNode *Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add); + RefNode *Add(SQHash mainpos,SQObject &obj); + void Resize(SQUnsignedInteger size); + void AllocNodes(SQUnsignedInteger size); + SQUnsignedInteger _numofslots; + SQUnsignedInteger _slotused; + RefNode *_nodes; + RefNode *_freelist; + RefNode **_buckets; +}; + +#define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len) +#define REMOVE_STRING(ss,bstr) ss->_stringtable->Remove(bstr) + +struct SQObjectPtr; + +class CSQStateIterator +{ +public: + // Simple objects + virtual void PsuedoKey( const char *pszPsuedoKey ) = 0; + virtual void Key( SQObjectPtr &key ) = 0; + virtual void Value( SQObjectPtr &value ) = 0; + + virtual bool BeginContained() = 0; + virtual void EndContained() = 0; +}; + +struct SQSharedState +{ + SQSharedState(); + ~SQSharedState(); + void Init(); +public: + SQChar* GetScratchPad(SQInteger size); + SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name); +#ifndef NO_GARBAGE_COLLECTOR + SQInteger CollectGarbage(SQVM *vm); + static void MarkObject(SQObjectPtr &o,SQCollectable **chain); +#endif + + void Iterate( SQVM *vm, CSQStateIterator *pIterator ); + static void IterateObject( CSQStateIterator *pIterator, SQObjectPtr &value, const char *pszName = NULL ); + + SQObjectPtrVec *_metamethods; + SQObjectPtr _metamethodsmap; + SQObjectPtrVec *_systemstrings; + SQObjectPtrVec *_types; + StringTable *_stringtable; + RefTable _refs_table; + SQObjectPtr _registry; + SQObjectPtr _consts; + SQObjectPtr _constructoridx; +#ifndef NO_GARBAGE_COLLECTOR + SQCollectable *_gc_chain; +#endif + SQObjectPtr _root_vm; + SQObjectPtr _table_default_delegate; + static SQRegFunction _table_default_delegate_funcz[]; + SQObjectPtr _array_default_delegate; + static SQRegFunction _array_default_delegate_funcz[]; + SQObjectPtr _string_default_delegate; + static SQRegFunction _string_default_delegate_funcz[]; + SQObjectPtr _number_default_delegate; + static SQRegFunction _number_default_delegate_funcz[]; + SQObjectPtr _generator_default_delegate; + static SQRegFunction _generator_default_delegate_funcz[]; + SQObjectPtr _closure_default_delegate; + static SQRegFunction _closure_default_delegate_funcz[]; + SQObjectPtr _thread_default_delegate; + static SQRegFunction _thread_default_delegate_funcz[]; + SQObjectPtr _class_default_delegate; + static SQRegFunction _class_default_delegate_funcz[]; + SQObjectPtr _instance_default_delegate; + static SQRegFunction _instance_default_delegate_funcz[]; + SQObjectPtr _weakref_default_delegate; + static SQRegFunction _weakref_default_delegate_funcz[]; + + SQCOMPILERERROR _compilererrorhandler; + SQPRINTFUNCTION _printfunc; + bool _debuginfo; + bool _notifyallexceptions; + void *m_pOwnerData; + + int _gc_disableDepth; +private: + SQChar *_scratchpad; + SQInteger _scratchpadsize; +}; + +#define _sp(s) (_sharedstate->GetScratchPad(s)) +#define _spval (_sharedstate->GetScratchPad(-1)) + +#define _table_ddel _table(_sharedstate->_table_default_delegate) +#define _array_ddel _table(_sharedstate->_array_default_delegate) +#define _string_ddel _table(_sharedstate->_string_default_delegate) +#define _number_ddel _table(_sharedstate->_number_default_delegate) +#define _generator_ddel _table(_sharedstate->_generator_default_delegate) +#define _closure_ddel _table(_sharedstate->_closure_default_delegate) +#define _thread_ddel _table(_sharedstate->_thread_default_delegate) +#define _class_ddel _table(_sharedstate->_class_default_delegate) +#define _instance_ddel _table(_sharedstate->_instance_default_delegate) +#define _weakref_ddel _table(_sharedstate->_weakref_default_delegate) + +#ifdef SQUNICODE //rsl REAL STRING LEN +#define rsl(l) ((l)<<1) +#else +#define rsl(l) (l) +#endif + +extern SQObjectPtr _null_; +extern SQObjectPtr _true_; +extern SQObjectPtr _false_; +extern SQObjectPtr _one_; +extern SQObjectPtr _minusone_; + +bool CompileTypemask(SQIntVec &res,const SQChar *typemask); + +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#ifndef sq_vm_malloc +#define sq_vm_malloc malloc +#define sq_vm_realloc(p,oldsize,size) realloc(p, size) +#define sq_vm_free(p,size) free(p) +#endif +#else +void *sq_vm_malloc(SQUnsignedInteger size); +void *sq_vm_realloc(void *p,SQUnsignedInteger oldsize,SQUnsignedInteger size); +void sq_vm_free(void *p,SQUnsignedInteger size); +#endif +#endif //_SQSTATE_H_ diff --git a/vscript/languages/squirrel/squirrel/sqstring.h b/vscript/languages/squirrel/squirrel/sqstring.h new file mode 100644 index 00000000..14f09e1b --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqstring.h @@ -0,0 +1,31 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTRING_H_ +#define _SQSTRING_H_ + +inline SQHash _hashstr (const SQChar *s, size_t l) +{ + SQHash h = (SQHash)l; /* seed */ + size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */ + for (; l>=step; l-=step) + h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++)); + return h; +} + +struct SQString : public SQRefCounted +{ + SQString(){} + ~SQString(){} +public: + static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 ); + SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); + void Release(); + SQSharedState *_sharedstate; + SQString *_next; //chain for the string table + SQInteger _len; + SQHash _hash; + SQChar _val[1]; +}; + + + +#endif //_SQSTRING_H_ diff --git a/vscript/languages/squirrel/squirrel/sqtable.cpp b/vscript/languages/squirrel/squirrel/sqtable.cpp new file mode 100644 index 00000000..51ed85fa --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqtable.cpp @@ -0,0 +1,201 @@ +/* +see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqtable.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#undef new // allow placement new +#endif + +SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize) +{ + SQInteger pow2size=MINPOWER2; + while(nInitialSize>pow2size)pow2size=pow2size<<1; + AllocNodes(pow2size); + _usednodes = 0; + _delegate = NULL; + INIT_CHAIN(); + ADD_TO_CHAIN(&_sharedstate->_gc_chain,this); +} + +void SQTable::Remove(const SQObjectPtr &key) +{ + + _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); + if (n) { + n->val = n->key = _null_; + _usednodes--; + Rehash(false); + } +} + +void SQTable::AllocNodes(SQInteger nSize) +{ + _HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize); + for(SQInteger i=0;i= oldsize-oldsize/4) /* using more than 3/4? */ + AllocNodes(oldsize*2); + else if (nelems <= oldsize/4 && /* less than 1/4? */ + oldsize > MINPOWER2) + AllocNodes(oldsize/2); + else if(force) + AllocNodes(oldsize); + else + return; + _usednodes = 0; + for (SQInteger i=0; ikey) != OT_NULL) + NewSlot(old->key,old->val); + } + for(SQInteger k=0;kNewSlot(key,val); + } + nt->SetDelegate(_delegate); + return nt; +} + +bool SQTable::Get(const SQObjectPtr &key,SQObjectPtr &val) +{ + if(type(key) == OT_NULL) + return false; + _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); + if (n) { + val = _realval(n->val); + return true; + } + return false; +} +bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val) +{ + Assert(type(key) != OT_NULL); + SQHash h = HashObj(key) & (_numofnodes - 1); + _HashNode *n = _Get(key, h); + if (n) { + n->val = val; + return false; + } + _HashNode *mp = &_nodes[h]; + n = mp; + + + //key not found I'll insert it + //main pos is not free + + if(type(mp->key) != OT_NULL) { + n = _firstfree; /* get a free place */ + SQHash mph = HashObj(mp->key) & (_numofnodes - 1); + _HashNode *othern; /* main position of colliding node */ + + if (mp > n && (othern = &_nodes[mph]) != mp){ + /* yes; move colliding node into free position */ + while (othern->next != mp){ + Assert(othern->next != NULL); + othern = othern->next; /* find previous */ + } + othern->next = n; /* redo the chain with `n' in place of `mp' */ + n->key = mp->key; + n->val = mp->val;/* copy colliding node into free pos. (mp->next also goes) */ + n->next = mp->next; + mp->key = _null_; + mp->val = _null_; + mp->next = NULL; /* now `mp' is free */ + } + else{ + /* new node will go into free position */ + n->next = mp->next; /* chain new position */ + mp->next = n; + mp = n; + } + } + mp->key = key; + + for (;;) { /* correct `firstfree' */ + if (type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) { + mp->val = val; + _usednodes++; + return true; /* OK; table still has a free place */ + } + else if (_firstfree == _nodes) break; /* cannot decrement from here */ + else (_firstfree)--; + } + Rehash(true); + return NewSlot(key, val); +} + +SQInteger SQTable::Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) +{ + SQInteger idx = (SQInteger)TranslateIndex(refpos); + while (idx < _numofnodes) { + if(type(_nodes[idx].key) != OT_NULL) { + //first found + _HashNode &n = _nodes[idx]; + outkey = n.key; + outval = getweakrefs?(SQObject)n.val:_realval(n.val); + //return idx for the next iteration + return ++idx; + } + ++idx; + } + //nothing to iterate anymore + return -1; +} + + +bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val) +{ + _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); + if (n) { + n->val = val; + return true; + } + return false; +} + +void SQTable::_ClearNodes() +{ + for(SQInteger i = 0;i < _numofnodes; i++) { _nodes[i].key = _null_; _nodes[i].val = _null_; } +} + +void SQTable::Finalize() +{ + _ClearNodes(); + SetDelegate(NULL); +} + +void SQTable::Clear() +{ + _ClearNodes(); + _usednodes = 0; + Rehash(true); +} diff --git a/vscript/languages/squirrel/squirrel/sqtable.h b/vscript/languages/squirrel/squirrel/sqtable.h new file mode 100644 index 00000000..e7516d2a --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqtable.h @@ -0,0 +1,102 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQTABLE_H_ +#define _SQTABLE_H_ +/* +* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.) +* http://www.lua.org/copyright.html#4 +* http://www.lua.org/source/4.0.1/src_ltable.c.html +*/ + +#include "sqstring.h" + +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#undef new // allow placement new +#endif + +#define hashptr(p) ((SQHash)(((SQInteger)((intp)p)) >> 3)) + +inline SQHash HashObj(const SQObjectPtr &key) +{ + switch(type(key)) { + case OT_STRING: return _string(key)->_hash; + case OT_FLOAT: return (SQHash)((SQInteger)_float(key)); + case OT_BOOL: case OT_INTEGER: return (SQHash)((SQInteger)_integer(key)); + default: return hashptr(key._unVal.pRefCounted); + } +} + +struct SQTable : public SQDelegable +{ + friend class CSquirrelVM; +private: + struct _HashNode + { + _HashNode() { next = NULL; } + SQObjectPtr val; + SQObjectPtr key; + _HashNode *next; + }; + _HashNode *_firstfree; + _HashNode *_nodes; + SQInteger _numofnodes; + SQInteger _usednodes; + +/////////////////////////// + void AllocNodes(SQInteger nSize); + void Rehash(bool force); + SQTable(SQSharedState *ss, SQInteger nInitialSize); + void _ClearNodes(); +public: + static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize) + { + SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable)); + new (newtable) SQTable(ss, nInitialSize); + newtable->_delegate = NULL; + return newtable; + } + void Finalize(); + SQTable *Clone(); + ~SQTable() + { + SetDelegate(NULL); + REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); + for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode(); + SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode)); + } +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); +#endif + void Iterate( CSQStateIterator *pIterator ); + + inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash) + { + _HashNode *n = &_nodes[hash]; + do{ + if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){ + return n; + } + }while((n = n->next)); + return NULL; + } + bool Get(const SQObjectPtr &key,SQObjectPtr &val); + void Remove(const SQObjectPtr &key); + bool Set(const SQObjectPtr &key, const SQObjectPtr &val); + //returns true if a new slot has been created false if it was already present + bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val); + SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); + + SQInteger CountUsed(){ return _usednodes;} + void Clear(); + void Release() + { + sq_delete(this, SQTable); + } + +}; + +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgoff.h" +#endif + +#endif //_SQTABLE_H_ diff --git a/vscript/languages/squirrel/squirrel/squirrel.cbp b/vscript/languages/squirrel/squirrel/squirrel.cbp new file mode 100644 index 00000000..5ecb4c38 --- /dev/null +++ b/vscript/languages/squirrel/squirrel/squirrel.cbp @@ -0,0 +1,324 @@ + + + + + + + diff --git a/vscript/languages/squirrel/squirrel/squirrel.vcproj b/vscript/languages/squirrel/squirrel/squirrel.vcproj new file mode 100644 index 00000000..44bbf731 --- /dev/null +++ b/vscript/languages/squirrel/squirrel/squirrel.vcproj @@ -0,0 +1,971 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/squirrel/squirrel71.vcproj b/vscript/languages/squirrel/squirrel/squirrel71.vcproj new file mode 100644 index 00000000..87d7cf6e --- /dev/null +++ b/vscript/languages/squirrel/squirrel/squirrel71.vcproj @@ -0,0 +1,750 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/squirrel/squirrellib.cbp b/vscript/languages/squirrel/squirrel/squirrellib.cbp new file mode 100644 index 00000000..428333f9 --- /dev/null +++ b/vscript/languages/squirrel/squirrel/squirrellib.cbp @@ -0,0 +1,20 @@ + + + + + + + diff --git a/vscript/languages/squirrel/squirrel/squserdata.h b/vscript/languages/squirrel/squirrel/squserdata.h new file mode 100644 index 00000000..e2dfb305 --- /dev/null +++ b/vscript/languages/squirrel/squirrel/squserdata.h @@ -0,0 +1,47 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQUSERDATA_H_ +#define _SQUSERDATA_H_ + +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#undef new // allow placement new +#endif +struct SQUserData : SQDelegable +{ + SQUserData(SQSharedState *ss){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); } + ~SQUserData() + { + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this); + SetDelegate(NULL); + } + static SQUserData* Create(SQSharedState *ss, SQInteger size) + { + SQUserData* ud = (SQUserData*)SQ_MALLOC(sizeof(SQUserData)+(size-1)); + new (ud) SQUserData(ss); + ud->_size = size; + ud->_typetag = 0; + return ud; + } +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize(){SetDelegate(NULL);} +#endif + void Iterate( CSQStateIterator *pIterator ); + + void Release() { + if (_hook) _hook(_val,_size); + SQInteger tsize = _size - 1; + this->~SQUserData(); + SQ_FREE(this, sizeof(SQUserData) + tsize); + } + + SQInteger _size; + SQRELEASEHOOK _hook; + SQUserPointer _typetag; + SQChar _val[1]; +}; + +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgoff.h" +#endif +#endif //_SQUSERDATA_H_ diff --git a/vscript/languages/squirrel/squirrel/squtils.h b/vscript/languages/squirrel/squirrel/squtils.h new file mode 100644 index 00000000..a1b2be58 --- /dev/null +++ b/vscript/languages/squirrel/squirrel/squtils.h @@ -0,0 +1,122 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQUTILS_H_ +#define _SQUTILS_H_ + +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#ifndef sq_vm_malloc +#define sq_vm_malloc malloc +#define sq_vm_realloc(p,oldsize,size) realloc(p, size) +#define sq_vm_free(p,size) do { ((void)size); free(p); } while (0) +#endif +#define SQ_MALLOC(__size) sq_vm_malloc((__size)); +#define SQ_FREE(__ptr,__size) sq_vm_free((__ptr),(__size)); +#define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc((__ptr),(__oldsize),(__size)); +#else +#define SQ_MALLOC(__size) sq_vm_malloc((__size)); +#define SQ_FREE(__ptr,__size) sq_vm_free((__ptr),(__size)); +#define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc((__ptr),(__oldsize),(__size)); +#endif +#define sq_new(__ptr,__type) {__ptr=(__type *)sq_vm_malloc(sizeof(__type));new (__ptr) __type;} +#define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));} + +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#undef new // allow placement new +#endif +//sqvector mini vector class, supports objects by value +template class sqvector +{ +public: + sqvector() + { + _vals = NULL; + _size = 0; + _allocated = 0; + } + sqvector(const sqvector& v) + { + copy(v); + } + void copy(const sqvector& v) + { + resize(v._size); + for(SQUnsignedInteger i = 0; i < v._size; i++) { + new ((void *)&_vals[i]) T(v._vals[i]); + } + _size = v._size; + } + ~sqvector() + { + if(_allocated) { + for(SQUnsignedInteger i = 0; i < _size; i++) + _vals[i].~T(); + SQ_FREE(_vals, (_allocated * sizeof(T))); + } + } + void reserve(SQUnsignedInteger newsize) { _realloc(newsize); } + void resize(SQUnsignedInteger newsize, const T& fill = T()) + { + if(newsize > _allocated) + _realloc(newsize); + if(newsize > _size) { + while(_size < newsize) { + new ((void *)&_vals[_size]) T(fill); + _size++; + } + } + else{ + for(SQUnsignedInteger i = newsize; i < _size; i++) { + _vals[i].~T(); + } + _size = newsize; + } + } + void shrinktofit() { if(_size > 4) { _realloc(_size); } } + T& top() const { return _vals[_size - 1]; } + inline SQUnsignedInteger size() const { return _size; } + bool empty() const { return (_size <= 0); } + inline T &push_back(const T& val = T()) + { + if(_allocated <= _size) + _realloc(_size * 2); + return *(new ((void *)&_vals[_size++]) T(val)); + } + inline void pop_back() + { + _size--; _vals[_size].~T(); + } + void insert(SQUnsignedInteger idx, const T& val) + { + resize(_size + 1); + for(SQUnsignedInteger i = _size - 1; i > idx; i--) { + _vals[i] = _vals[i - 1]; + } + _vals[idx] = val; + } + void remove(SQUnsignedInteger idx) + { + _vals[idx].~T(); + if(idx < (_size - 1)) { + memmove(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1)); + } + _size--; + } + SQUnsignedInteger capacity() { return _allocated; } + inline T &back() const { return _vals[_size - 1]; } + inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; } + T* _vals; +private: + void _realloc(SQUnsignedInteger newsize) + { + newsize = (newsize > 0)?newsize:4; + _vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T)); + _allocated = newsize; + } + SQUnsignedInteger _size; + SQUnsignedInteger _allocated; +}; + +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgoff.h" +#endif +#endif //_SQUTILS_H_ diff --git a/vscript/languages/squirrel/squirrel/sqvm.cpp b/vscript/languages/squirrel/squirrel/sqvm.cpp new file mode 100644 index 00000000..0bc9956f --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqvm.cpp @@ -0,0 +1,1572 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include +#include +#include "sqopcodes.h" +#include "sqfuncproto.h" +#include "sqvm.h" +#include "sqclosure.h" +#include "sqstring.h" +#include "sqtable.h" +#include "squserdata.h" +#include "sqarray.h" +#include "sqclass.h" +#if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST) +#include "memdbgon.h" +#endif + +#define TOP() (_stack._vals[_top-1]) + +#define CLEARSTACK(_last_top) { if((_last_top) >= _top) ClearStack(_last_top); } +void SQVM::ClearStack(SQInteger last_top) +{ + SQObjectType tOldType; + SQObjectValue unOldVal; + while (last_top >= _top) { + SQObjectPtr &o = _stack._vals[last_top--]; + tOldType = o._type; + unOldVal = o._unVal; + o._type = OT_NULL; + o._unVal.pUserPointer = NULL; + __Release(tOldType,unOldVal); + } +} + +bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2) +{ + SQInteger res; + SQInteger i1 = _integer(o1), i2 = _integer(o2); + if((type(o1)==OT_INTEGER) && (type(o2)==OT_INTEGER)) + { + switch(op) { + case BW_AND: res = i1 & i2; break; + case BW_OR: res = i1 | i2; break; + case BW_XOR: res = i1 ^ i2; break; + case BW_SHIFTL: res = i1 << i2; break; + case BW_SHIFTR: res = i1 >> i2; break; + case BW_USHIFTR:res = (SQInteger)(*((SQUnsignedInteger*)&i1) >> i2); break; + default: { Raise_Error(_SC("internal vm error bitwise op failed")); return false; } + } + } + else { Raise_Error(_SC("bitwise op between '%s' and '%s'"),GetTypeName(o1),GetTypeName(o2)); return false;} + trg = res; + return true; +} + +bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2) +{ + if(sq_isnumeric(o1) && sq_isnumeric(o2)) { + if((type(o1)==OT_INTEGER) && (type(o2)==OT_INTEGER)) { + SQInteger res, i1 = _integer(o1), i2 = _integer(o2); + switch(op) { + case '+': res = i1 + i2; break; + case '-': res = i1 - i2; break; + case '/': if(i2 == 0) { Raise_Error(_SC("division by zero")); return false; } + res = i1 / i2; + break; + case '*': res = i1 * i2; break; + case '%': if(i2 == 0) { Raise_Error(_SC("modulo by zero")); return false; } + res = i1 % i2; + break; + default: res = 0xDEADBEEF; + } + trg = res; + }else{ + SQFloat res, f1 = tofloat(o1), f2 = tofloat(o2); + switch(op) { + case '+': res = f1 + f2; break; + case '-': res = f1 - f2; break; + case '/': res = f1 / f2; break; + case '*': res = f1 * f2; break; + case '%': res = SQFloat(fmod((double)f1,(double)f2)); break; + default: res = 0x0f; + } + trg = res; + } + } else { + if(op == '+' && (type(o1) == OT_STRING || type(o2) == OT_STRING)){ + if(!StringCat(o1, o2, trg)) return false; + } + else if(!ArithMetaMethod(op,o1,o2,trg)) + { + if( _lasterror._unVal.pString != NULL ) + // Already something in _lasterror. Don't lose it, just append it. + Raise_Error(_SC("arith op %c on between '%s' and '%s' (%s)"),op,GetTypeName(o1),GetTypeName(o2),_lasterror._unVal.pString->_val); + else + Raise_Error(_SC("arith op %c on between '%s' and '%s'"),op,GetTypeName(o1),GetTypeName(o2)); + + return false; + } + } + return true; +} + +SQVM::SQVM(SQSharedState *ss) +{ + _sharedstate=ss; + _suspended = SQFalse; + _suspended_target=-1; + _suspended_root = SQFalse; + _suspended_traps=-1; + _foreignptr=NULL; + _nnativecalls=0; + _lasterror = _null_; + _errorhandler = _null_; + _debughook = _null_; + ci = NULL; + INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); + + _qs_cnt = 0; + _qs_fn = 0; +} + +void SQVM::Finalize() +{ + _roottable = _null_; + _lasterror = _null_; + _errorhandler = _null_; + _debughook = _null_; + temp_reg = _null_; + _callstackdata.resize(0); + SQInteger size=_stack.size(); + for(SQInteger i=0;i_gc_chain,this); +} + +bool SQVM::ArithMetaMethod(SQInteger op,const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &dest) +{ + SQMetaMethod mm; + switch(op){ + case _SC('+'): mm=MT_ADD; break; + case _SC('-'): mm=MT_SUB; break; + case _SC('/'): mm=MT_DIV; break; + case _SC('*'): mm=MT_MUL; break; + case _SC('%'): mm=MT_MODULO; break; + default: mm = MT_ADD; Assert(0); break; //shutup compiler + } + if(is_delegable(o1) && _delegable(o1)->_delegate) { + Push(o1);Push(o2); + return CallMetaMethod(_delegable(o1),mm,2,dest); + } + return false; +} + +bool SQVM::NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o) +{ + + switch(type(o)) { + case OT_INTEGER: + trg = -_integer(o); + return true; + case OT_FLOAT: + trg = -_float(o); + return true; + case OT_TABLE: + case OT_USERDATA: + case OT_INSTANCE: + if(_delegable(o)->_delegate) { + Push(o); + if(CallMetaMethod(_delegable(o), MT_UNM, 1, temp_reg)) { + trg = temp_reg; + return true; + } + } + default:break; //shutup compiler + } + Raise_Error(_SC("attempt to negate a %s"), GetTypeName(o)); + return false; +} + +#define _RET_SUCCEED(exp) { result = (exp); return true; } +bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result) +{ + if(type(o1)==type(o2)){ + if(_userpointer(o1)==_userpointer(o2))_RET_SUCCEED(0); + SQObjectPtr res; + switch(type(o1)){ + case OT_STRING: + _RET_SUCCEED(scstrcmp(_stringval(o1),_stringval(o2))); + case OT_INTEGER: + _RET_SUCCEED(_integer(o1)-_integer(o2)); + case OT_FLOAT: + _RET_SUCCEED((_float(o1)<_float(o2))?-1:1); + case OT_TABLE: + case OT_USERDATA: + case OT_INSTANCE: + if(_delegable(o1)->_delegate) { + Push(o1);Push(o2); + if(CallMetaMethod(_delegable(o1),MT_CMP,2,res)) break; + } + //continues through (no break needed) + default: + _RET_SUCCEED( _userpointer(o1) < _userpointer(o2)?-1:1 ); + } + if(type(res)!=OT_INTEGER) { Raise_CompareError(o1,o2); return false; } + _RET_SUCCEED(_integer(res)); + + } + else{ + if(sq_isnumeric(o1) && sq_isnumeric(o2)){ + if((type(o1)==OT_INTEGER) && (type(o2)==OT_FLOAT)) { + if( _integer(o1)==_float(o2) ) { _RET_SUCCEED(0); } + else if( _integer(o1)<_float(o2) ) { _RET_SUCCEED(-1); } + _RET_SUCCEED(1); + } + else{ + if( _float(o1)==_integer(o2) ) { _RET_SUCCEED(0); } + else if( _float(o1)<_integer(o2) ) { _RET_SUCCEED(-1); } + _RET_SUCCEED(1); + } + } + else if(type(o1)==OT_NULL) {_RET_SUCCEED(-1);} + else if(type(o2)==OT_NULL) {_RET_SUCCEED(1);} + else { Raise_CompareError(o1,o2); return false; } + + } + Assert(0); + _RET_SUCCEED(0); //cannot happen +} + +bool SQVM::CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res) +{ + SQInteger r; + if(ObjCmp(o1,o2,r)) { + switch(op) { + case CMP_G: res = (r > 0)?_true_:_false_; return true; + case CMP_GE: res = (r >= 0)?_true_:_false_; return true; + case CMP_L: res = (r < 0)?_true_:_false_; return true; + case CMP_LE: res = (r <= 0)?_true_:_false_; return true; + + } + Assert(0); + } + return false; +} + +void SQVM::ToString(const SQObjectPtr &o,SQObjectPtr &res) +{ + switch(type(o)) { + case OT_STRING: + res = o; + return; + case OT_FLOAT: + scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_SC("%g"),_float(o)); + break; + case OT_INTEGER: + scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_SC("%d"),_integer(o)); + break; + case OT_BOOL: + scsprintf(_sp(rsl(6)),_integer(o)?_SC("true"):_SC("false")); + break; + case OT_WEAKREF: + { + if ( ISREFCOUNTED(o._unVal.pWeakRef->_obj._type) ) + { + SQ_VALIDATE_REF_COUNT( o._unVal.pWeakRef->_obj._unVal.pRefCounted ); + o._unVal.pWeakRef->_obj._unVal.pRefCounted->_uiRef++; + } + ToString( o._unVal.pWeakRef->_obj, res ); + if ( ISREFCOUNTED(o._unVal.pWeakRef->_obj._type) ) + { + o._unVal.pWeakRef->_obj._unVal.pRefCounted->_uiRef--; + SQ_VALIDATE_REF_COUNT( o._unVal.pWeakRef->_obj._unVal.pRefCounted ); + } + scsprintf(_sp(rsl(sizeof(void*)+24+strlen(res._unVal.pString->_val))),_SC("(weakref : 0x%p [%s] )"),(void*)_rawval(o), res._unVal.pString->_val); + break; + } + case OT_TABLE: + case OT_USERDATA: + case OT_INSTANCE: + if(_delegable(o)->_delegate) { + Push(o); + if(CallMetaMethod(_delegable(o),MT_TOSTRING,1,res)) { + if(type(res) == OT_STRING) + return; + //else keeps going to the default + } + } + default: + scsprintf(_sp(rsl(sizeof(void*)+20)),_SC("(%s : 0x%p)"),GetTypeName(o),(void*)_rawval(o)); + } + res = SQString::Create(_ss(this),_spval); +} + + +bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr &dest) +{ + SQObjectPtr a, b; + ToString(str, a); + ToString(obj, b); + SQInteger l = _string(a)->_len , ol = _string(b)->_len; + SQChar *s = _sp(rsl(l + ol + 1)); + memcpy(s, _stringval(a), rsl(l)); + memcpy(s + l, _stringval(b), rsl(ol)); + dest = SQString::Create(_ss(this), _spval, l + ol); + return true; +} + +void SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest) +{ + if(is_delegable(obj1) && _delegable(obj1)->_delegate) { + Push(obj1); + if(CallMetaMethod(_delegable(obj1),MT_TYPEOF,1,dest)) + return; + } + dest = SQString::Create(_ss(this),GetTypeName(obj1)); +} + +bool SQVM::Init(SQVM *friendvm, SQInteger stacksize) +{ + _stack.resize(stacksize); + _alloccallsstacksize = 4; + _callstackdata.resize(_alloccallsstacksize); + _callsstacksize = 0; + _callsstack = &_callstackdata[0]; + _stackbase = 0; + _top = 0; + if(!friendvm) + _roottable = SQTable::Create(_ss(this), 0); + else { + _roottable = friendvm->_roottable; + _errorhandler = friendvm->_errorhandler; + _debughook = friendvm->_debughook; + } + + sq_base_register(this); + return true; +} + +extern SQInstructionDesc g_InstrDesc[]; + +bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQInteger stackbase,bool tailcall) +{ + SQFunctionProto *func = _funcproto(closure->_function); + + const SQInteger paramssize = func->_nparameters; + const SQInteger newtop = stackbase + func->_stacksize; + SQInteger nargs = args; + if (paramssize != nargs) { + SQInteger ndef = func->_ndefaultparams; + if(ndef && nargs < paramssize) { + SQInteger diff = paramssize - nargs; + for(SQInteger n = ndef - diff; n < ndef; n++) { + _stack._vals[stackbase + (nargs++)] = closure->_defaultparams[n]; + } + } + else if(func->_varparams) + { + if (nargs < paramssize) { + Raise_Error(_SC("wrong number of parameters")); + return false; + } + for(SQInteger n = 0; n < nargs - paramssize; n++) { + _vargsstack.push_back(_stack._vals[stackbase+paramssize+n]); + _stack._vals[stackbase+paramssize+n] = _null_; + } + } + else { + Raise_Error(_SC("wrong number of parameters")); + return false; + } + } + + if(type(closure->_env) == OT_WEAKREF) { + _stack._vals[stackbase] = _weakref(closure->_env)->_obj; + } + + if (!tailcall) { + CallInfo lc; + lc._generator = NULL; + lc._etraps = 0; + lc._prevstkbase = (SQInt32) ( stackbase - _stackbase ); + lc._target = (SQInt32) target; + lc._prevtop = (SQInt32) (_top - _stackbase); + lc._ncalls = 1; + lc._root = SQFalse; + PUSH_CALLINFO(this, lc); + } + else { + ci->_ncalls++; + } + ci->_vargs.size = (SQInt32)(nargs - paramssize); + ci->_vargs.base = (SQInt32)(_vargsstack.size()-(ci->_vargs.size)); + ci->_closure = closure; + ci->_literals = func->_literals; + ci->_ip = func->_instructions; + //grows the stack if needed + if (((SQUnsignedInteger)newtop + (func->_stacksize<<1)) > _stack.size()) { + _stack.resize(_stack.size() + (func->_stacksize<<1)); + } + + _top = newtop; + _stackbase = stackbase; + if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure)) + CallDebugHook(_SC('c')); + return true; +} + +bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval) +{ + if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure)) + for(SQInteger i=0;i_ncalls;i++) + CallDebugHook(_SC('r')); + + SQBool broot = ci->_root; + SQInteger last_top = _top; + SQInteger target = ci->_target; + SQInteger oldstackbase = _stackbase; + _stackbase -= ci->_prevstkbase; + _top = _stackbase + ci->_prevtop; + if(ci->_vargs.size) PopVarArgs(ci->_vargs); + POP_CALLINFO(this); + if (broot) { + if (_arg0 != MAX_FUNC_STACKSIZE) retval = _stack._vals[oldstackbase+_arg1]; + else retval = _null_; + } + else { + if(target != -1) { //-1 is when a class contructor ret value has to be ignored + if (_arg0 != MAX_FUNC_STACKSIZE) + STK(target) = _stack._vals[oldstackbase+_arg1]; + else + STK(target) = _null_; + } + } + + CLEARSTACK(last_top); + Assert(oldstackbase >= _stackbase); + return broot?true:false; +} + +#define _RET_ON_FAIL(exp) { if(!exp) return false; } + +bool SQVM::LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr) +{ + _RET_ON_FAIL(ARITH_OP( op , target, a, incr)); + a = target; + return true; +} + +bool SQVM::PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr) +{ + SQObjectPtr trg; + _RET_ON_FAIL(ARITH_OP( op , trg, a, incr)); + target = a; + a = trg; + return true; +} + +bool SQVM::DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix) +{ + SQObjectPtr tmp, tself = self, tkey = key; + if (!Get(tself, tkey, tmp, false, true)) { Raise_IdxError(tkey); return false; } + _RET_ON_FAIL(ARITH_OP( op , target, tmp, incr)) + Set(tself, tkey, target,true); + if (postfix) target = tmp; + return true; +} + +#define arg0 (_i_._arg0) +#define arg1 (_i_._arg1) +#define sarg1 (*((SQInt32 *)&_i_._arg1)) +#define arg2 (_i_._arg2) +#define arg3 (_i_._arg3) +#define sarg3 ((SQInteger)*((signed char *)&_i_._arg3)) + +SQRESULT SQVM::Suspend() +{ + if (_suspended) + return sq_throwerror(this, _SC("cannot suspend an already suspended vm")); + if (_nnativecalls!=2) + return sq_throwerror(this, _SC("cannot suspend through native calls/metamethods")); + return SQ_SUSPEND_FLAG; +} + +void SQVM::PopVarArgs(VarArgs &vargs) +{ + for(SQInteger n = 0; n< vargs.size; n++) + _vargsstack.pop_back(); +} + +#define _FINISH(howmuchtojump) {jump = howmuchtojump; return true; } +bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr +&o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump) +{ + SQInteger nrefidx; + switch(type(o1)) { + case OT_TABLE: + if((nrefidx = _table(o1)->Next(false,o4, o2, o3)) == -1) _FINISH(exitpos); + o4 = (SQInteger)nrefidx; _FINISH(1); + case OT_ARRAY: + if((nrefidx = _array(o1)->Next(o4, o2, o3)) == -1) _FINISH(exitpos); + o4 = (SQInteger) nrefidx; _FINISH(1); + case OT_STRING: + if((nrefidx = _string(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos); + o4 = (SQInteger)nrefidx; _FINISH(1); + case OT_CLASS: + if((nrefidx = _class(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos); + o4 = (SQInteger)nrefidx; _FINISH(1); + case OT_USERDATA: + case OT_INSTANCE: + if(_delegable(o1)->_delegate) { + SQObjectPtr itr; + Push(o1); + Push(o4); + if(CallMetaMethod(_delegable(o1), MT_NEXTI, 2, itr)){ + o4 = o2 = itr; + if(type(itr) == OT_NULL) _FINISH(exitpos); + if(!Get(o1, itr, o3, false,false)) { + Raise_Error(_SC("_nexti returned an invalid idx")); + return false; + } + _FINISH(1); + } + Raise_Error(_SC("_nexti failed")); + return false; + } + break; + case OT_GENERATOR: + if(_generator(o1)->_state == SQGenerator::eDead) _FINISH(exitpos); + if(_generator(o1)->_state == SQGenerator::eSuspended) { + SQInteger idx = 0; + if(type(o4) == OT_INTEGER) { + idx = _integer(o4) + 1; + } + o2 = idx; + o4 = idx; + _generator(o1)->Resume(this, arg_2+1); + _FINISH(0); + } + default: + Raise_Error(_SC("cannot iterate %s"), GetTypeName(o1)); + } + return false; //cannot be hit(just to avoid warnings) +} + +bool SQVM::DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2) +{ + if(type(o1) != OT_TABLE) { Raise_Error(_SC("delegating a '%s'"), GetTypeName(o1)); return false; } + switch(type(o2)) { + case OT_TABLE: + if(!_table(o1)->SetDelegate(_table(o2))){ + Raise_Error(_SC("delegate cycle detected")); + return false; + } + break; + case OT_NULL: + _table(o1)->SetDelegate(NULL); + break; + default: + Raise_Error(_SC("using '%s' as delegate"), GetTypeName(o2)); + return false; + break; + } + trg = o1; + return true; +} +#define COND_LITERAL (arg3!=0?ci->_literals[arg1]:STK(arg1)) + +#define _GUARD(exp) { if(!exp) { Raise_Error(_lasterror); SQ_THROW();} } + +#define SQ_THROW() { goto exception_trap; } + +bool SQVM::CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func) +{ + SQInteger nouters; + SQClosure *closure = SQClosure::Create(_ss(this), func); + if((nouters = func->_noutervalues)) { + closure->_outervalues.reserve(nouters); + for(SQInteger i = 0; i_outervalues[i]; + switch(v._type){ + case otSYMBOL: + closure->_outervalues.push_back(_null_); + if(!Get(_stack._vals[_stackbase]/*STK(0)*/, v._src, closure->_outervalues.top(), false,true)) + {Raise_IdxError(v._src); return false; } + break; + case otLOCAL: + closure->_outervalues.push_back(_stack._vals[_stackbase+_integer(v._src)]); + break; + case otOUTER: + closure->_outervalues.push_back(_closure(ci->_closure)->_outervalues[_integer(v._src)]); + break; + } + } + } + SQInteger ndefparams; + if((ndefparams = func->_ndefaultparams)) { + closure->_defaultparams.reserve(ndefparams); + for(SQInteger i = 0; i < ndefparams; i++) { + SQInteger spos = func->_defaultparams[i]; + closure->_defaultparams.push_back(_stack._vals[_stackbase + spos]); + } + } + target = closure; + return true; + +} + +bool SQVM::GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &index,CallInfo *ci) +{ + if(ci->_vargs.size == 0) { + Raise_Error(_SC("the function doesn't have var args")); + return false; + } + if(!sq_isnumeric(index)){ + Raise_Error(_SC("indexing 'vargv' with %s"),GetTypeName(index)); + return false; + } + SQInteger idx = tointeger(index); + if(idx < 0 || idx >= ci->_vargs.size){ Raise_Error(_SC("vargv index out of range")); return false; } + target = _vargsstack[ci->_vargs.base+idx]; + return true; +} + +bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes) +{ + SQClass *base = NULL; + SQObjectPtr attrs; + if(baseclass != -1) { + if(type(_stack._vals[_stackbase+baseclass]) != OT_CLASS) { Raise_Error(_SC("trying to inherit from a %s"),GetTypeName(_stack._vals[_stackbase+baseclass])); return false; } + base = _class(_stack._vals[_stackbase + baseclass]); + } + if(attributes != MAX_FUNC_STACKSIZE) { + attrs = _stack._vals[_stackbase+attributes]; + } + target = SQClass::Create(_ss(this),base); + if(type(_class(target)->_metamethods[MT_INHERITED]) != OT_NULL) { + int nparams = 2; + SQObjectPtr ret; + Push(target); Push(attrs); + Call(_class(target)->_metamethods[MT_INHERITED],nparams,_top - nparams, ret, false); + Pop(nparams); + } + _class(target)->_attributes = attrs; + return true; +} + + + +bool SQVM::IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res) +{ + if(type(o1) == type(o2)) { + res = ((_userpointer(o1) == _userpointer(o2)?true:false)); + } + else { + if(sq_isnumeric(o1) && sq_isnumeric(o2)) { + SQInteger cmpres; + if(!ObjCmp(o1, o2,cmpres)) return false; + res = (cmpres == 0); + } + else { + res = false; + } + } + return true; +} + +bool SQVM::IsFalse(SQObjectPtr &o) +{ + if((type(o) & SQOBJECT_CANBEFALSE) && ( (type(o) == OT_FLOAT) && (_float(o) == SQFloat(0.0)) ) + || (_integer(o) == 0) ) { //OT_NULL|OT_INTEGER|OT_BOOL + return true; + } + return false; +} + +bool SQVM::GETPARENT_OP(SQObjectPtr &o,SQObjectPtr &target) +{ + switch(type(o)) { + case OT_TABLE: target = _table(o)->_delegate?SQObjectPtr(_table(o)->_delegate):_null_; + break; + case OT_CLASS: target = _class(o)->_base?_class(o)->_base:_null_; + break; + default: + Raise_Error(_SC("the %s type doesn't have a parent slot"), GetTypeName(o)); + return false; + } + return true; +} + +bool g_bSqDbgTerminateScript; +bool SQVM::Execute(SQObjectPtr &closure, SQInteger target, SQInteger nargs, SQInteger stackbase,SQObjectPtr &outres, SQBool raiseerror,ExecutionType et) +{ + if ((_nnativecalls + 1) > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; } + _nnativecalls++; + AutoDec ad(&_nnativecalls); + SQInteger traps = 0; + //temp_reg vars for OP_CALL + SQInteger ct_target = 0; + SQInteger ct_stackbase; + bool ct_tailcall; + + switch(et) { + case ET_CALL: { + SQInteger last_top = _top; + temp_reg = closure; + if(!StartCall(_closure(temp_reg), _top - nargs, nargs, stackbase, false)) { + //call the handler if there are no calls in the stack, if not relies on the previous node + if(ci == NULL) CallErrorHandler(_lasterror); + return false; + } + if (_funcproto(_closure(temp_reg)->_function)->_bgenerator) { + SQFunctionProto *f = _funcproto(_closure(temp_reg)->_function); + SQGenerator *gen = SQGenerator::Create(_ss(this), _closure(temp_reg)); + _GUARD(gen->Yield(this)); + Return(1, ci->_target, temp_reg); + outres = gen; + CLEARSTACK(last_top); + return true; + } + ci->_root = SQTrue; + } + break; + case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, target); ci->_root = SQTrue; traps += ci->_etraps; break; + case ET_RESUME_VM: + case ET_RESUME_THROW_VM: + traps = _suspended_traps; + ci->_root = _suspended_root; + ci->_vargs = _suspend_varargs; + _suspended = SQFalse; + if(et == ET_RESUME_THROW_VM) { SQ_THROW(); } + break; + } + +exception_restore: + // + { + for(;;) + { + const SQInstruction &_i_ = *ci->_ip++; + switch(_i_.op) + { + case _OP_LINE: + if(type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure)) + { + g_bSqDbgTerminateScript = false; + CallDebugHook(_SC('l'),arg1); + if ( g_bSqDbgTerminateScript ) + { + sq_throwerror( this, "terminated by debugger" ); + SQ_THROW(); + } + } + continue; + case _OP_LOAD: TARGET = ci->_literals[arg1]; continue; + case _OP_LOADINT: TARGET = (SQInteger)arg1; continue; + case _OP_LOADFLOAT: TARGET = *((SQFloat *)&arg1); continue; + case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue; + case _OP_TAILCALL: + temp_reg = STK(arg1); + if (type(temp_reg) == OT_CLOSURE && !_funcproto(_closure(temp_reg)->_function)->_bgenerator){ + ct_tailcall = true; + if(ci->_vargs.size) PopVarArgs(ci->_vargs); + for (SQInteger i = 0; i < arg3; i++) STK(i) = STK(arg2 + i); + ct_target = ci->_target; + ct_stackbase = _stackbase; + goto common_call; + } + case _OP_CALL: { + ct_tailcall = false; + ct_target = arg0; + temp_reg = STK(arg1); + ct_stackbase = _stackbase+arg2; + +common_call: + SQObjectPtr clo = temp_reg; + SQInteger last_top = _top; + switch (type(clo)) { + case OT_CLOSURE:{ + _GUARD(StartCall(_closure(clo), ct_target, arg3, ct_stackbase, ct_tailcall)); + if (_funcproto(_closure(clo)->_function)->_bgenerator) { + SQGenerator *gen = SQGenerator::Create(_ss(this), _closure(clo)); + _GUARD(gen->Yield(this)); + Return(1, ct_target, clo); + STK(ct_target) = gen; + CLEARSTACK(last_top); + continue; + } + } + continue; + case OT_NATIVECLOSURE: { + bool suspend; + _GUARD(CallNative(_nativeclosure(clo), arg3, ct_stackbase, clo,suspend)); + if(suspend){ + _suspended = SQTrue; + _suspended_target = ct_target; + _suspended_root = ci->_root; + _suspended_traps = traps; + _suspend_varargs = ci->_vargs; + outres = clo; + return true; + } + if(ct_target != -1) { //skip return value for constructors + STK(ct_target) = clo; + } + } + continue; + case OT_CLASS:{ + SQObjectPtr inst; + _GUARD(CreateClassInstance(_class(clo),inst,temp_reg)); + STK(ct_target) = inst; + ct_target = -1; //fakes return value target so that is not overwritten by the constructor + if(type(temp_reg) != OT_NULL) { + _stack._vals[ct_stackbase] = inst; + goto common_call; //hard core spaghetti code(reissues the OP_CALL to invoke the constructor) + } + } + break; + case OT_TABLE: + case OT_USERDATA: + case OT_INSTANCE: + { + Push(clo); + for (SQInteger i = 0; i < arg3; i++) Push(STK(arg2 + i)); + if (_delegable(clo) && CallMetaMethod(_delegable(clo), MT_CALL, arg3+1, clo)){ + STK(ct_target) = clo; + break; + } + Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo)); + SQ_THROW(); + } + default: + Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo)); + SQ_THROW(); + } + } + continue; + case _OP_PREPCALL: + case _OP_PREPCALLK: + { + SQObjectPtr &key = _i_.op == _OP_PREPCALLK?(ci->_literals)[arg1]:STK(arg1); + SQObjectPtr &o = STK(arg2); + if (!Get(o, key, temp_reg,false,true)) { + if(type(o) == OT_CLASS) { //hack? + if(_class_ddel->Get(key,temp_reg)) { + STK(arg3) = o; + TARGET = temp_reg; + continue; + } + } + { Raise_IdxError(key); SQ_THROW();} + } + + STK(arg3) = type(o) == OT_CLASS?STK(0):o; + TARGET = temp_reg; + } + continue; + case _OP_GETK: + if (!Get(STK(arg2), ci->_literals[arg1], temp_reg, false,true)) { Raise_IdxError(ci->_literals[arg1]); SQ_THROW();} + TARGET = temp_reg; + continue; + case _OP_MOVE: TARGET = STK(arg1); continue; + case _OP_NEWSLOT: + _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),false)); + if(arg0 != arg3) TARGET = STK(arg3); + continue; + case _OP_DELETE: _GUARD(DeleteSlot(STK(arg1), STK(arg2), TARGET)); continue; + case _OP_SET: + if (!Set(STK(arg1), STK(arg2), STK(arg3),true)) { Raise_IdxError(STK(arg2)); SQ_THROW(); } + if (arg0 != arg3) TARGET = STK(arg3); + continue; + case _OP_GET: + if (!Get(STK(arg1), STK(arg2), temp_reg, false,true)) { Raise_IdxError(STK(arg2)); SQ_THROW(); } + TARGET = temp_reg; + continue; + case _OP_EQ:{ + bool res; + if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); } + TARGET = res?_true_:_false_; + }continue; + case _OP_NE:{ + bool res; + if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); } + TARGET = (!res)?_true_:_false_; + } continue; + case _OP_ARITH: _GUARD(ARITH_OP( arg3 , temp_reg, STK(arg2), STK(arg1))); TARGET = temp_reg; continue; + case _OP_BITW: _GUARD(BW_OP( arg3,TARGET,STK(arg2),STK(arg1))); continue; + case _OP_RETURN: + if(ci->_generator) { + ci->_generator->Kill(); + } + if(Return(arg0, arg1, temp_reg)){ + Assert(traps==0); + outres = temp_reg; + return true; + } + if( _qs_fn && --_qs_cnt<0 ){ +query_suspend: + _qs_cnt = SQ_QUERY_COUNT_START; + int r = _qs_fn(this); + if( r==SQ_QUERY_BREAK ){ + Raise_Error(_SC("Script terminated by SQQuerySuspend"), NULL); + SQ_THROW(); + } + else if( r==SQ_QUERY_SUSPEND ){ + // This code path is not tested very much + _suspended = SQTrue; + _suspended_target = ct_target; + _suspended_root = ci->_root; + _suspended_traps = traps; + _suspend_varargs = ci->_vargs; + return true; + } + } + continue; + case _OP_LOADNULLS:{ for(SQInt32 n=0; n < arg1; n++) STK(arg0+n) = _null_; }continue; + case _OP_LOADROOTTABLE: TARGET = _roottable; continue; + case _OP_LOADBOOL: TARGET = arg1?_true_:_false_; continue; + case _OP_DMOVE: STK(arg0) = STK(arg1); STK(arg2) = STK(arg3); continue; + case _OP_JMP: ci->_ip += (sarg1); + if( _qs_fn && --_qs_cnt<0 ) goto query_suspend; + continue; + case _OP_JNZ: if(!IsFalse(STK(arg0))) ci->_ip+=(sarg1); + if( _qs_fn && --_qs_cnt<0 ) goto query_suspend; + continue; + case _OP_JZ: if(IsFalse(STK(arg0))) ci->_ip+=(sarg1); + if( _qs_fn && --_qs_cnt<0 ) goto query_suspend; + continue; + case _OP_LOADFREEVAR: TARGET = _closure(ci->_closure)->_outervalues[arg1]; continue; + case _OP_VARGC: TARGET = SQInteger(ci->_vargs.size); continue; + case _OP_GETVARGV: + if(!GETVARGV_OP(TARGET,STK(arg1),ci)) { SQ_THROW(); } + continue; + case _OP_NEWTABLE: TARGET = SQTable::Create(_ss(this), arg1); continue; + case _OP_NEWARRAY: TARGET = SQArray::Create(_ss(this), 0); _array(TARGET)->Reserve(arg1); continue; + case _OP_APPENDARRAY: _array(STK(arg0))->Append(COND_LITERAL); continue; + case _OP_GETPARENT: _GUARD(GETPARENT_OP(STK(arg1),TARGET)); continue; + case _OP_COMPARITH: _GUARD(DerefInc(arg3, TARGET, STK((((SQUnsignedInteger)arg1&0xFFFF0000)>>16)), STK(arg2), STK(arg1&0x0000FFFF), false)); continue; + case _OP_COMPARITHL: _GUARD(LOCAL_INC(arg3, TARGET, STK(arg1), STK(arg2))); continue; + case _OP_INC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, false));} continue; + case _OP_INCL: {SQObjectPtr o(sarg3); _GUARD(LOCAL_INC('+',TARGET, STK(arg1), o));} continue; + case _OP_PINC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, true));} continue; + case _OP_PINCL: {SQObjectPtr o(sarg3); _GUARD(PLOCAL_INC('+',TARGET, STK(arg1), o));} continue; + case _OP_CMP: _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg1),TARGET)) continue; + case _OP_EXISTS: TARGET = Get(STK(arg1), STK(arg2), temp_reg, true,false)?_true_:_false_;continue; + case _OP_INSTANCEOF: + if(type(STK(arg1)) != OT_CLASS || type(STK(arg2)) != OT_INSTANCE) + {Raise_Error(_SC("cannot apply instanceof between a %s and a %s"),GetTypeName(STK(arg1)),GetTypeName(STK(arg2))); SQ_THROW();} + TARGET = _instance(STK(arg2))->InstanceOf(_class(STK(arg1)))?_true_:_false_; + continue; + case _OP_AND: + if(IsFalse(STK(arg2))) { + TARGET = STK(arg2); + ci->_ip += (sarg1); + } + continue; + case _OP_OR: + if(!IsFalse(STK(arg2))) { + TARGET = STK(arg2); + ci->_ip += (sarg1); + } + continue; + case _OP_NEG: _GUARD(NEG_OP(TARGET,STK(arg1))); continue; + case _OP_NOT: TARGET = (IsFalse(STK(arg1))?_true_:_false_); continue; + case _OP_BWNOT: + if(type(STK(arg1)) == OT_INTEGER) { + SQInteger t = _integer(STK(arg1)); + TARGET = SQInteger(~t); + continue; + } + Raise_Error(_SC("attempt to perform a bitwise op on a %s"), GetTypeName(STK(arg1))); + SQ_THROW(); + case _OP_CLOSURE: { + SQClosure *c = ci->_closure._unVal.pClosure; + SQFunctionProto *fp = c->_function._unVal.pFunctionProto; + if(!CLOSURE_OP(TARGET,fp->_functions[arg1]._unVal.pFunctionProto)) { SQ_THROW(); } + continue; + } + case _OP_YIELD:{ + if(ci->_generator) { + if(sarg1 != MAX_FUNC_STACKSIZE) temp_reg = STK(arg1); + _GUARD(ci->_generator->Yield(this)); + traps -= ci->_etraps; + if(sarg1 != MAX_FUNC_STACKSIZE) STK(arg1) = temp_reg; + } + else { Raise_Error(_SC("trying to yield a '%s',only genenerator can be yielded"), GetTypeName(ci->_generator)); SQ_THROW();} + if(Return(arg0, arg1, temp_reg)){ + Assert(traps == 0); + outres = temp_reg; + return true; + } + + } + continue; + case _OP_RESUME: + if(type(STK(arg1)) != OT_GENERATOR){ Raise_Error(_SC("trying to resume a '%s',only genenerator can be resumed"), GetTypeName(STK(arg1))); SQ_THROW();} + _GUARD(_generator(STK(arg1))->Resume(this, arg0)); + traps += ci->_etraps; + continue; + case _OP_FOREACH:{ int tojump; + _GUARD(FOREACH_OP(STK(arg0),STK(arg2),STK(arg2+1),STK(arg2+2),arg2,sarg1,tojump)); + ci->_ip += tojump; } + continue; + case _OP_POSTFOREACH: + Assert(type(STK(arg0)) == OT_GENERATOR); + if(_generator(STK(arg0))->_state == SQGenerator::eDead) + ci->_ip += (sarg1 - 1); + continue; + case _OP_DELEGATE: _GUARD(DELEGATE_OP(TARGET,STK(arg1),STK(arg2))); continue; + case _OP_CLONE: + if(!Clone(STK(arg1), TARGET)) + { Raise_Error(_SC("cloning a %s"), GetTypeName(STK(arg1))); SQ_THROW();} + continue; + case _OP_TYPEOF: TypeOf(STK(arg1), TARGET); continue; + case _OP_PUSHTRAP:{ + SQInstruction *_iv = _funcproto(_closure(ci->_closure)->_function)->_instructions; + _etraps.push_back(SQExceptionTrap(_top,_stackbase, &_iv[(ci->_ip-_iv)+arg1], arg0)); traps++; + ci->_etraps++; + } + continue; + case _OP_POPTRAP: { + for(SQInteger i = 0; i < arg0; i++) { + _etraps.pop_back(); traps--; + ci->_etraps--; + } + } + continue; + case _OP_THROW: Raise_Error(TARGET); SQ_THROW(); continue; + case _OP_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue; + case _OP_NEWSLOTA: + bool bstatic = (arg0&NEW_SLOT_STATIC_FLAG)?true:false; + if(type(STK(arg1)) == OT_CLASS) { + if(type(_class(STK(arg1))->_metamethods[MT_NEWMEMBER]) != OT_NULL ) { + Push(STK(arg1)); Push(STK(arg2)); Push(STK(arg3)); + Push((arg0&NEW_SLOT_ATTRIBUTES_FLAG) ? STK(arg2-1) : _null_); + int nparams = 4; + if(Call(_class(STK(arg1))->_metamethods[MT_NEWMEMBER], nparams, _top - nparams, temp_reg,SQFalse)) { + Pop(nparams); + continue; + } + } + } + _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),bstatic)); + if((arg0&NEW_SLOT_ATTRIBUTES_FLAG)) { + _class(STK(arg1))->SetAttributes(STK(arg2),STK(arg2-1)); + } + continue; + } + + } + } +exception_trap: + { + SQObjectPtr currerror = _lasterror; +// dumpstack(_stackbase); + SQInteger n = 0; + SQInteger last_top = _top; + if(ci) { + if(_ss(this)->_notifyallexceptions) CallErrorHandler(currerror); + + if(traps) { + do { + if(ci->_etraps > 0) { + SQExceptionTrap &et = _etraps.top(); + ci->_ip = et._ip; + _top = et._stacksize; + _stackbase = et._stackbase; + _stack._vals[_stackbase+et._extarget] = currerror; + _etraps.pop_back(); traps--; ci->_etraps--; + CLEARSTACK(last_top); + goto exception_restore; + } + //if is a native closure + if(type(ci->_closure) != OT_CLOSURE && n) + break; + if(ci->_generator) ci->_generator->Kill(); + PopVarArgs(ci->_vargs); + POP_CALLINFO(this); + n++; + } while(_callsstacksize); + } + else { + //call the hook + if(raiseerror && !_ss(this)->_notifyallexceptions) + CallErrorHandler(currerror); + } + //remove call stack until a C function is found or the cstack is empty + if(ci) do { + SQBool exitafterthisone = ci->_root; + if(ci->_generator) ci->_generator->Kill(); + _stackbase -= ci->_prevstkbase; + _top = _stackbase + ci->_prevtop; + PopVarArgs(ci->_vargs); + POP_CALLINFO(this); + if( (ci && type(ci->_closure) != OT_CLOSURE) || exitafterthisone) break; + } while(_callsstacksize); + + CLEARSTACK(last_top); + } + _lasterror = currerror; + return false; + } + Assert(0); + return false; +} + +bool SQVM::CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor) +{ + inst = theclass->CreateInstance(); + if(!theclass->Get(_ss(this)->_constructoridx,constructor)) { + constructor = _null_; + } + return true; +} + +void SQVM::CallErrorHandler(SQObjectPtr &error) +{ + if(type(_errorhandler) != OT_NULL) { + SQObjectPtr out; + Push(_roottable); Push(error); + Call(_errorhandler, 2, _top-2, out,SQFalse); + Pop(2); + } +} + +void SQVM::CallDebugHook(SQInteger type,SQInteger forcedline) +{ + SQObjectPtr temp_reg; + SQInteger nparams=5; + SQFunctionProto *func=_funcproto(_closure(ci->_closure)->_function); + Push(_roottable); Push(type); Push(func->_sourcename); Push(forcedline?forcedline:func->GetLine(ci->_ip)); Push(func->_name); + Call(_debughook,nparams,_top-nparams,temp_reg,SQFalse); + Pop(nparams); +} + +bool SQVM::CallNative(SQNativeClosure *nclosure,SQInteger nargs,SQInteger stackbase,SQObjectPtr &retval,bool &suspend) +{ + if (_nnativecalls + 1 > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; } + SQInteger nparamscheck = nclosure->_nparamscheck; + if(((nparamscheck > 0) && (nparamscheck != nargs)) + || ((nparamscheck < 0) && (nargs < (-nparamscheck)))) { + Raise_Error(_SC("wrong number of parameters")); + return false; + } + + SQInteger tcs; + if((tcs = nclosure->_typecheck.size())) { + for(SQInteger i = 0; i < nargs && i < tcs; i++) + if((nclosure->_typecheck._vals[i] != -1) && !(type(_stack._vals[stackbase+i]) & nclosure->_typecheck[i])) { + Raise_ParamTypeError(i,nclosure->_typecheck._vals[i],type(_stack._vals[stackbase+i])); + return false; + } + } + _nnativecalls++; + if ((_top + MIN_STACK_OVERHEAD) > (SQInteger)_stack.size()) { + _stack.resize(_stack.size() + (MIN_STACK_OVERHEAD<<1)); + } + SQInteger oldtop = _top; + SQInteger oldstackbase = _stackbase; + _top = stackbase + nargs; + CallInfo lci; + lci._closure = nclosure; + lci._generator = NULL; + lci._etraps = 0; + lci._prevstkbase = (SQInt32) (stackbase - _stackbase); + lci._ncalls = 1; + lci._prevtop = (SQInt32) (oldtop - oldstackbase); + PUSH_CALLINFO(this, lci); + _stackbase = stackbase; + //push free variables + SQInteger outers = nclosure->_outervalues.size(); + for (SQInteger i = 0; i < outers; i++) { + Push(nclosure->_outervalues[i]); + } + + if(type(nclosure->_env) == OT_WEAKREF) { + _stack[stackbase] = _weakref(nclosure->_env)->_obj; + } + + + SQInteger ret = (nclosure->_function)(this); + _nnativecalls--; + suspend = false; + if( ret == SQ_SUSPEND_FLAG) suspend = true; + else if (ret < 0) { + _stackbase = oldstackbase; + _top = oldtop; + POP_CALLINFO(this); + Raise_Error(_lasterror); + return false; + } + + if (ret != 0){ retval = TOP(); TOP().Null(); } + else { retval = _null_; } + _stackbase = oldstackbase; + _top = oldtop; + POP_CALLINFO(this); + return true; +} + +bool SQVM::Get(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw, bool fetchroot) +{ + switch(type(self)){ + case OT_TABLE: + if(_table(self)->Get(key,dest))return true; + break; + case OT_ARRAY: + if(sq_isnumeric(key)){ + return _array(self)->Get(tointeger(key),dest); + } + break; + case OT_INSTANCE: + if(_instance(self)->Get(key,dest)) return true; + break; + default:break; //shut up compiler + } + if(FallBackGet(self,key,dest,raw)) return true; + + if(fetchroot) { + if(_rawval(STK(0)) == _rawval(self) && + type(STK(0)) == type(self)) { + return _table(_roottable)->Get(key,dest); + } + } + return false; +} + +bool SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw) +{ + switch(type(self)){ + case OT_CLASS: + return _class(self)->Get(key,dest); + break; + case OT_TABLE: + case OT_USERDATA: + //delegation + if(_delegable(self)->_delegate) { + if(Get(SQObjectPtr(_delegable(self)->_delegate),key,dest,raw,false)) + return true; + if(raw)return false; + Push(self);Push(key); + if(CallMetaMethod(_delegable(self),MT_GET,2,dest)) + return true; + } + if(type(self) == OT_TABLE) { + if(raw) return false; + return _table_ddel->Get(key,dest); + } + return false; + break; + case OT_ARRAY: + if(raw)return false; + return _array_ddel->Get(key,dest); + case OT_STRING: + if(sq_isnumeric(key)){ + SQInteger n=tointeger(key); + if(abs((int)n)<_string(self)->_len){ + if(n<0)n=_string(self)->_len-n; + dest=SQInteger(_stringval(self)[n]); + return true; + } + return false; + } + else { + if(raw)return false; + return _string_ddel->Get(key,dest); + } + break; + case OT_INSTANCE: + if(raw)return false; + Push(self);Push(key); + if(!CallMetaMethod(_delegable(self),MT_GET,2,dest)) { + return _instance_ddel->Get(key,dest); + } + return true; + case OT_INTEGER:case OT_FLOAT:case OT_BOOL: + if(raw)return false; + return _number_ddel->Get(key,dest); + case OT_GENERATOR: + if(raw)return false; + return _generator_ddel->Get(key,dest); + case OT_CLOSURE: case OT_NATIVECLOSURE: + if(raw)return false; + return _closure_ddel->Get(key,dest); + case OT_THREAD: + if(raw)return false; + return _thread_ddel->Get(key,dest); + case OT_WEAKREF: + if(raw)return false; + return _weakref_ddel->Get(key,dest); + default:return false; + } + return false; +} + +bool SQVM::Set(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool fetchroot) +{ + switch(type(self)){ + case OT_TABLE: + if(_table(self)->Set(key,val)) + return true; + if(_table(self)->_delegate) { + if(Set(_table(self)->_delegate,key,val,false)) { + return true; + } + } + //keeps going + case OT_USERDATA: + if(_delegable(self)->_delegate) { + SQObjectPtr t; + Push(self);Push(key);Push(val); + if(CallMetaMethod(_delegable(self),MT_SET,3,t)) return true; + } + break; + case OT_INSTANCE:{ + if(_instance(self)->Set(key,val)) + return true; + SQObjectPtr t; + Push(self);Push(key);Push(val); + if(CallMetaMethod(_delegable(self),MT_SET,3,t)) return true; + } + break; + case OT_ARRAY: + if(!sq_isnumeric(key)) {Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); return false; } + return _array(self)->Set(tointeger(key),val); + default: + Raise_Error(_SC("trying to set '%s'"),GetTypeName(self)); + return false; + } + if(fetchroot) { + if(_rawval(STK(0)) == _rawval(self) && + type(STK(0)) == type(self)) { + return _table(_roottable)->Set(key,val); + } + } + return false; +} + +bool SQVM::Clone(const SQObjectPtr &self,SQObjectPtr &target) +{ + SQObjectPtr temp_reg; + SQObjectPtr newobj; + switch(type(self)){ + case OT_TABLE: + newobj = _table(self)->Clone(); + goto cloned_mt; + case OT_INSTANCE: + newobj = _instance(self)->Clone(_ss(this)); +cloned_mt: + if(_delegable(newobj)->_delegate){ + Push(newobj); + Push(self); + CallMetaMethod(_delegable(newobj),MT_CLONED,2,temp_reg); + } + target = newobj; + return true; + case OT_ARRAY: + target = _array(self)->Clone(); + return true; + default: return false; + } +} + +bool SQVM::NewSlot(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic) +{ + if(type(key) == OT_NULL) { Raise_Error(_SC("null cannot be used as index")); return false; } + switch(type(self)) { + case OT_TABLE: { + bool rawcall = true; + if(_table(self)->_delegate) { + SQObjectPtr res; + if(!_table(self)->Get(key,res)) { + Push(self);Push(key);Push(val); + rawcall = !CallMetaMethod(_table(self),MT_NEWSLOT,3,res); + } + } + if(rawcall) _table(self)->NewSlot(key,val); //cannot fail + + break;} + case OT_INSTANCE: { + SQObjectPtr res; + Push(self);Push(key);Push(val); + if(!CallMetaMethod(_instance(self),MT_NEWSLOT,3,res)) { + Raise_Error(_SC("class instances do not support the new slot operator")); + return false; + } + break;} + case OT_CLASS: + if(!_class(self)->NewSlot(_ss(this),key,val,bstatic)) { + if(_class(self)->_locked) { + Raise_Error(_SC("trying to modify a class that has already been instantiated")); + return false; + } + else { + SQObjectPtr oval = PrintObjVal(key); + Raise_Error(_SC("the property '%s' already exists"),_stringval(oval)); + return false; + } + } + break; + default: + Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); + return false; + break; + } + return true; +} + +bool SQVM::DeleteSlot(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &res) +{ + switch(type(self)) { + case OT_TABLE: + case OT_INSTANCE: + case OT_USERDATA: { + SQObjectPtr t; + bool handled = false; + if(_delegable(self)->_delegate) { + Push(self);Push(key); + handled = CallMetaMethod(_delegable(self),MT_DELSLOT,2,t); + } + + if(!handled) { + if(type(self) == OT_TABLE) { + if(_table(self)->Get(key,t)) { + _table(self)->Remove(key); + } + else { + Raise_IdxError((SQObject &)key); + return false; + } + } + else { + Raise_Error(_SC("cannot delete a slot from %s"),GetTypeName(self)); + return false; + } + } + res = t; + } + break; + default: + Raise_Error(_SC("attempt to delete a slot from a %s"),GetTypeName(self)); + return false; + } + return true; +} + +bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObjectPtr &outres,SQBool raiseerror) +{ +#ifdef _DEBUG +SQInteger prevstackbase = _stackbase; +#endif + switch(type(closure)) { + case OT_CLOSURE: + return Execute(closure, _top - nparams, nparams, stackbase,outres,raiseerror); + break; + case OT_NATIVECLOSURE:{ + bool suspend; + return CallNative(_nativeclosure(closure), nparams, stackbase, outres,suspend); + + } + break; + case OT_CLASS: { + SQObjectPtr constr; + SQObjectPtr temp; + CreateClassInstance(_class(closure),outres,constr); + if(type(constr) != OT_NULL) { + _stack[stackbase] = outres; + return Call(constr,nparams,stackbase,temp,raiseerror); + } + return true; + } + break; + default: + return false; + } +#ifdef _DEBUG + if(!_suspended) { + Assert(_stackbase == prevstackbase); + } +#endif + return true; +} + +bool SQVM::CallMetaMethod(SQDelegable *del,SQMetaMethod mm,SQInteger nparams,SQObjectPtr &outres) +{ + SQObjectPtr closure; + if(del->GetMetaMethod(this, mm, closure)) { + if(Call(closure, nparams, _top - nparams, outres, SQFalse)) { + Pop(nparams); + return true; + } + } + Pop(nparams); + return false; +} + +void SQVM::Remove(SQInteger n) { + n = (n >= 0)?n + _stackbase - 1:_top + n; + for(SQInteger i = n; i < _top; i++){ + _stack[i] = _stack[i+1]; + } + _stack[_top] = _null_; + _top--; +} + +void SQVM::Pop() { + _stack[--_top] = _null_; +} + +void SQVM::Pop(SQInteger n) { + for(SQInteger i = 0; i < n; i++){ + _stack[--_top] = _null_; + } +} + +void SQVM::Push(const SQObjectPtr &o) { _stack[_top++] = o; } +SQObjectPtr &SQVM::Top() { return _stack[_top-1]; } +SQObjectPtr &SQVM::PopGet() { return _stack[--_top]; } +SQObjectPtr &SQVM::GetUp(SQInteger n) { return _stack[_top+n]; } +SQObjectPtr &SQVM::GetAt(SQInteger n) { return _stack[n]; } + +#ifdef _DEBUG_DUMP +void SQVM::dumpstack(SQInteger stackbase,bool dumpall) +{ + SQInteger size=dumpall?_stack.size():_top; + SQInteger n=0; + scprintf(_SC("\n>>>>stack dump<<<<\n")); + CallInfo &ci=_callsstack[_callsstacksize-1]; + scprintf(_SC("IP: %p\n"),ci._ip); + scprintf(_SC("prev stack base: %d\n"),ci._prevstkbase); + scprintf(_SC("prev top: %d\n"),ci._prevtop); + for(SQInteger i=0;i"));else scprintf(_SC(" ")); + scprintf(_SC("[%d]:"),n); + switch(type(obj)){ + case OT_FLOAT: scprintf(_SC("FLOAT %.3f"),_float(obj));break; + case OT_INTEGER: scprintf(_SC("INTEGER %d"),_integer(obj));break; + case OT_BOOL: scprintf(_SC("BOOL %s"),_integer(obj)?"true":"false");break; + case OT_STRING: scprintf(_SC("STRING %s"),_stringval(obj));break; + case OT_NULL: scprintf(_SC("NULL")); break; + case OT_TABLE: scprintf(_SC("TABLE %p[%p]"),_table(obj),_table(obj)->_delegate);break; + case OT_ARRAY: scprintf(_SC("ARRAY %p"),_array(obj));break; + case OT_CLOSURE: scprintf(_SC("CLOSURE [%p]"),_closure(obj));break; + case OT_NATIVECLOSURE: scprintf(_SC("NATIVECLOSURE"));break; + case OT_USERDATA: scprintf(_SC("USERDATA %p[%p]"),_userdataval(obj),_userdata(obj)->_delegate);break; + case OT_GENERATOR: scprintf(_SC("GENERATOR %p"),_generator(obj));break; + case OT_THREAD: scprintf(_SC("THREAD [%p]"),_thread(obj));break; + case OT_USERPOINTER: scprintf(_SC("USERPOINTER %p"),_userpointer(obj));break; + case OT_CLASS: scprintf(_SC("CLASS %p"),_class(obj));break; + case OT_INSTANCE: scprintf(_SC("INSTANCE %p"),_instance(obj));break; + case OT_WEAKREF: scprintf(_SC("WEAKERF %p"),_weakref(obj));break; + default: + Assert(0); + break; + }; + scprintf(_SC("\n")); + ++n; + } +} + + + +#endif diff --git a/vscript/languages/squirrel/squirrel/sqvm.h b/vscript/languages/squirrel/squirrel/sqvm.h new file mode 100644 index 00000000..8d8eebd9 --- /dev/null +++ b/vscript/languages/squirrel/squirrel/sqvm.h @@ -0,0 +1,223 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQVM_H_ +#define _SQVM_H_ + +#include "sqopcodes.h" +#include "sqobject.h" +#define MAX_NATIVE_CALLS 100 +#define MIN_STACK_OVERHEAD 10 + +#define SQ_SUSPEND_FLAG -666 +//base lib +void sq_base_register(HSQUIRRELVM v); + +struct SQExceptionTrap{ + SQExceptionTrap() {} + SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;} + SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et; } + SQInteger _stackbase; + SQInteger _stacksize; + SQInstruction *_ip; + SQInteger _extarget; +}; + + +///////////////////////////////////////////////////////////// +// Feature to suspend / break script that runs a long time +// Right now SQ_QUERY_COUNT_START tuned for runaway scripts, not preemption +#define SQ_QUERY_COUNT_START 100000 // Number of skipped query times +#define SQ_QUERY_CONTINUE 0 +#define SQ_QUERY_BREAK 1 +#define SQ_QUERY_SUSPEND 2 + +typedef int (*SQQuerySuspendFn)( HSQUIRRELVM ); + + +#define _INLINE + +#define STK(a) _stack._vals[_stackbase+(a)] +#define TARGET _stack._vals[_stackbase+arg0] + +typedef sqvector ExceptionsTraps; + +struct SQVM : public CHAINABLE_OBJ +{ + struct VarArgs { + VarArgs() { size = 0; base = 0; } + unsigned short size; + unsigned short base; + }; + + struct CallInfo{ + //CallInfo() { _generator._type = OT_NULL;} + SQInstruction *_ip; + SQObjectPtr *_literals; + SQObjectPtr _closure; + SQGenerator *_generator; + SQInt32 _etraps; + SQInt32 _prevstkbase; + SQInt32 _prevtop; + SQInt32 _target; + SQInt32 _ncalls; + SQBool _root; + VarArgs _vargs; + }; + +typedef sqvector CallInfoVec; +public: + enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM, ET_RESUME_THROW_VM }; + SQVM(SQSharedState *ss); + ~SQVM(); + bool Init(SQVM *friendvm, SQInteger stacksize); + bool Execute(SQObjectPtr &func, SQInteger target, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL); + //starts a native call return when the NATIVE closure returns + bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger stackbase, SQObjectPtr &retval,bool &suspend); + //starts a SQUIRREL call in the same "Execution loop" + bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall); + bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor); + //call a generic closure pure SQUIRREL or NATIVE + bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror); + SQRESULT Suspend(); + + void CallDebugHook(SQInteger type,SQInteger forcedline=0); + void CallErrorHandler(SQObjectPtr &e); + bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, bool raw, bool fetchroot); + bool FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw); + bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, bool fetchroot); + bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic); + bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res); + bool Clone(const SQObjectPtr &self, SQObjectPtr &target); + bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res); + bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest); + bool IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res); + void ToString(const SQObjectPtr &o,SQObjectPtr &res); + SQString *PrintObjVal(const SQObject &o); + + + void Raise_Error(const SQChar *s, ...); + void Raise_Error(SQObjectPtr &desc); + void Raise_IdxError(SQObject &o); + void Raise_CompareError(const SQObject &o1, const SQObject &o2); + void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type); + + void TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest); + bool CallMetaMethod(SQDelegable *del, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres); + bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest); + bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval); + //new stuff + _INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2); + _INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2); + _INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1); + _INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res); + bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func); + bool GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &idx,CallInfo *ci); + bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs); + bool GETPARENT_OP(SQObjectPtr &o,SQObjectPtr &target); + //return true if the loop is finished + bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump); + bool DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2); + _INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr); + _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr); + _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix); + void PopVarArgs(VarArgs &vargs); + void ClearStack(SQInteger last_top); +#ifdef _DEBUG_DUMP + void dumpstack(SQInteger stackbase=-1, bool dumpall = false); +#endif + +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); +#endif + void Iterate( CSQStateIterator *pIterator ); + + void Finalize(); + void GrowCallStack() { + SQInteger newsize = _alloccallsstacksize*2; + _callstackdata.resize(newsize); + _callsstack = &_callstackdata[0]; + _alloccallsstacksize = newsize; + } + void Release(){ sq_delete(this,SQVM); } //does nothing +//////////////////////////////////////////////////////////////////////////// + //stack functions for the api + void Remove(SQInteger n); + + bool IsFalse(SQObjectPtr &o); + + void Pop(); + void Pop(SQInteger n); + void Push(const SQObjectPtr &o); + SQObjectPtr &Top(); + SQObjectPtr &PopGet(); + SQObjectPtr &GetUp(SQInteger n); + SQObjectPtr &GetAt(SQInteger n); + + void SetQuerySuspendFn( SQQuerySuspendFn qs_fn ){ _qs_fn=qs_fn; } + int _qs_cnt; + SQQuerySuspendFn _qs_fn; + + SQObjectPtrVec _stack; + SQObjectPtrVec _vargsstack; + SQInteger _top; + SQInteger _stackbase; + SQObjectPtr _roottable; + SQObjectPtr _lasterror; + SQObjectPtr _errorhandler; + SQObjectPtr _debughook; + + SQObjectPtr temp_reg; + + + CallInfo* _callsstack; + SQInteger _callsstacksize; + SQInteger _alloccallsstacksize; + sqvector _callstackdata; + + ExceptionsTraps _etraps; + CallInfo *ci; + void *_foreignptr; + //VMs sharing the same state + SQSharedState *_sharedstate; + SQInteger _nnativecalls; + //suspend infos + SQBool _suspended; + SQBool _suspended_root; + SQInteger _suspended_target; + SQInteger _suspended_traps; + VarArgs _suspend_varargs; +}; + +struct AutoDec{ + AutoDec(SQInteger *n) { _n = n; } + ~AutoDec() { (*_n)--; } + SQInteger *_n; +}; + +inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));} + +#define _ss(_vm_) (_vm_)->_sharedstate + +#ifndef NO_GARBAGE_COLLECTOR +#define _opt_ss(_vm_) (_vm_)->_sharedstate +#else +#define _opt_ss(_vm_) NULL +#endif + +#define PUSH_CALLINFO(v,nci){ \ + if(v->_callsstacksize == v->_alloccallsstacksize) { \ + v->GrowCallStack(); \ + } \ + v->ci = &v->_callsstack[v->_callsstacksize]; \ + *(v->ci) = nci; \ + v->_callsstacksize++; \ +} + +#define POP_CALLINFO(v){ \ + v->_callsstacksize--; \ + v->ci->_closure.Null(); \ + if(v->_callsstacksize) \ + v->ci = &v->_callsstack[v->_callsstacksize-1] ; \ + else \ + v->ci = NULL; \ +} +#endif //_SQVM_H_ diff --git a/vscript/languages/squirrel/testSqPlus/Makefile b/vscript/languages/squirrel/testSqPlus/Makefile new file mode 100644 index 00000000..ad51f4f7 --- /dev/null +++ b/vscript/languages/squirrel/testSqPlus/Makefile @@ -0,0 +1,16 @@ +SQUIRREL= .. + +OUT= ./testSqPlus +INCDIRS= -I$(SQUIRREL)/include -I. -I$(SQUIRREL)/sqlibs -I$(SQUIRREL)/sqplus +LIBDIR= -L$(SQUIRREL)/lib +LIBS= -lsqplus -lsquirrel -lsqstdlib + +SRCS= testSqPlus.cpp + +all: testSqPlus + +FORCE: ; + +testSqPlus: FORCE + #g++ -fno-rtti -o $(OUT) $(SRCS) $(INCDIRS) $(LIBDIR) $(LIBS) + g++ -O3 -fno-rtti -Os -o $(OUT) $(SRCS) $(INCDIRS) $(LIBDIR) $(LIBS) diff --git a/vscript/languages/squirrel/testSqPlus/testSqPlus.cbp b/vscript/languages/squirrel/testSqPlus/testSqPlus.cbp new file mode 100644 index 00000000..6cdfb7f2 --- /dev/null +++ b/vscript/languages/squirrel/testSqPlus/testSqPlus.cbp @@ -0,0 +1,126 @@ + + + + + + + diff --git a/vscript/languages/squirrel/testSqPlus/testSqPlus.cpp b/vscript/languages/squirrel/testSqPlus/testSqPlus.cpp new file mode 100644 index 00000000..2a91ee25 --- /dev/null +++ b/vscript/languages/squirrel/testSqPlus/testSqPlus.cpp @@ -0,0 +1,804 @@ +// testSqPlus.cpp +// Created by John Schultz 9/5/2005 +// Free for any use. + +#include +#include +#include "sqplus.h" + +using namespace SqPlus; + +struct CTestObj { + float x; + float y; + float z; + CTestObj() { + x = y = z = 0.f; + } + void update(float t) { + x += t; + } // update + void print(void) { + SQChar buff[256]; + scsprintf(buff,_T("x: %f\n"),x); +// OutputDebugString(buff); + SCPUTS(buff); + } // print +}; + +_DECL_CLASS(TestObj); + +_IMPL_NATIVE_CONSTRUCTION(TestObj,CTestObj); + +_MEMBER_FUNCTION_IMPL(TestObj,constructor) { + CTestObj * newv = NULL; + StackHandler sa(v); + int nparams = sa.GetParamCount(); + newv = new CTestObj(); + return construct_TestObj(newv); +} + +_MEMBER_FUNCTION_IMPL(TestObj,_set) { + StackHandler sa(v); + _CHECK_SELF(CTestObj,TestObj); + const SQChar *s = sa.GetString(2); + int index = s?s[0]:sa.GetInt(2); + switch(index) { + case 0: case 'x': case 'r': + return sa.Return(self->x = sa.GetFloat(3)); + break; + case 1: case 'y': case 'g': + return sa.Return(self->y = sa.GetFloat(3)); + break; + case 2: case 'z': case 'b': + return sa.Return(self->z = sa.GetFloat(3)); + break; + } // switch + return SQ_ERROR; +} + +_MEMBER_FUNCTION_IMPL(TestObj,_get) { + StackHandler sa(v); + _CHECK_SELF(CTestObj,TestObj); + const SQChar *s = sa.GetString(2); + if(s && (s[1] != 0)) return SQ_ERROR; + int index = s && (s[1] == 0)?s[0]:sa.GetInt(2); + switch(index) { + case 0: case 'x': case 'r': return sa.Return(self->x); break; + case 1: case 'y': case 'g': return sa.Return(self->y); break; + case 2: case 'z': case 'b': return sa.Return(self->z); break; + } // switch + return SQ_ERROR; +} + +_MEMBER_FUNCTION_IMPL(TestObj,update) { + StackHandler sa(v); + _CHECK_SELF(CTestObj,TestObj); + SQObjectType type = (SQObjectType)sa.GetType(2); + if (type == OT_FLOAT || type == OT_INTEGER) { + float t = sa.GetFloat(2); + self->update(t); + } else { + SQChar buff[256]; + scsprintf(buff,_T("Invalid type for CTestObj::update(float): type %d\n"),type); +// OutputDebugString(buff); + SCPUTS(buff); + } // if + return SQ_OK;; +} + +_MEMBER_FUNCTION_IMPL(TestObj,print) { + StackHandler sa(v); + _CHECK_SELF(CTestObj,TestObj); + SQChar buff[256]; + scsprintf(buff,_T("x: %f y: %f z: %f\n"),self->x,self->y,self->z); +// OutputDebugString(buff); + SCPUTS(buff); +// return sa.ThrowError(_SC("Error initializing the device")); + return SQ_OK;; +} + +_MEMBER_FUNCTION_IMPL(TestObj,_print) { + _CHECK_SELF(CTestObj,TestObj); + SCPUTS(_T("_print: ")); + return __TestObj_print(v); +} + +_BEGIN_CLASS(TestObj) +_MEMBER_FUNCTION(TestObj,constructor,1,_T("x")) // x = instance ('self/this' not yet created), no arguments. +_MEMBER_FUNCTION(TestObj,_set,3,_T("xs|n")) // x = instance, string, or int/float, as .x, .y, .z, or [0], [1], [2]. +_MEMBER_FUNCTION(TestObj,_get,2,_T("xs|n")) // x = instance, string, or int/float, as .x, .y, .z, or [0], [1], [2]. +_MEMBER_FUNCTION(TestObj,update,2,_T("xn")) // x = instance (this), n = int or float. +_MEMBER_FUNCTION(TestObj,print,1,_T("x")) // x = instance (this). +_MEMBER_FUNCTION(TestObj,_print,1,_T("x")) // x = instance (this). +_END_CLASS(TestObj) + +#ifdef SQUNICODE +#define scvprintf vwprintf +#else +#define scvprintf vprintf +#endif + +void printfunc(HSQUIRRELVM v,const SQChar *s,...) { + va_list arglist; + va_start(arglist, s); + scvprintf(s, arglist); + va_end(arglist); +} + +int testFunc(HSQUIRRELVM v) { + StackHandler sa(v); + int paramCount = sa.GetParamCount(); + scprintf(_T("testFunc: numParams[%d]\n"),paramCount); + for (int i=1; i <= paramCount; i++) { + scprintf(_T("param[%d]: "),i); + switch(sa.GetType(i)) { + case OT_TABLE: scprintf(_T("OT_TABLE[0x%x]\n"),sa.GetObjectHandle(i)); break; + case OT_INTEGER: scprintf(_T("OT_INTEGER[%d]\n"),sa.GetInt(i)); break; + case OT_FLOAT: scprintf(_T("OT_FLOAT[%f]\n"),sa.GetFloat(i)); break; + case OT_STRING: scprintf(_T("OT_STRING[%s]\n"),sa.GetString(i)); break; + default: + scprintf(_T("TYPEID[%d]\n"),sa.GetType(i)); + } // switch + } // for + return SQ_OK; +} // testFunc + +// === BEGIN User Pointer version === +#if 0 + +int setVarFunc2(HSQUIRRELVM v) { + StackHandler sa(v); + if (sa.GetType(1) == OT_TABLE) { + HSQOBJECT htable = sa.GetObjectHandle(1); + SquirrelObject table(htable); + const SQChar * el = sa.GetString(2); + SquirrelObject upValMapPtr = table.GetValue(_T("_uvp")); + SquirrelObject upValMapType = table.GetValue(_T("_uvt")); + if (!upValMapType.Exists(el)) { + return SQ_ERROR; + } // if + int vType = upValMapType.GetInt(el); + switch (vType) { + case TypeInfo::TypeID: { + int * val = (int *)upValMapPtr.GetUserPointer(el); + if (val) { + *val = sa.GetInt(3); + return sa.Return(*val); + } else { + return sa.Return(-1); + } // if + } // case + case TypeInfo::TypeID: { + float * val = (float *)upValMapPtr.GetUserPointer(el); + if (val) { + *val = sa.GetFloat(3); + return sa.Return(*val); + } else { + return sa.Return(-1); + } // if + } // case + case TypeInfo::TypeID: { + bool * val = (bool *)upValMapPtr.GetUserPointer(el); + if (val) { + *val = sa.GetBool(3) ? true : false; + return sa.Return(*val); + } else { + return sa.Return(-1); + } // if + } // case + } // switch + } // if + return SQ_ERROR; +} // setVarFunc2 + +int getVarFunc2(HSQUIRRELVM v) { + StackHandler sa(v); + if (sa.GetType(1) == OT_TABLE) { + HSQOBJECT htable = sa.GetObjectHandle(1); + SquirrelObject table(htable); + int type = sa.GetType(2); + const SQChar * el = sa.GetString(2); + SquirrelObject upValMap = table.GetValue(_T("_uvp")); + SquirrelObject upValMapType = table.GetValue(_T("_uvt")); + if (!upValMapType.Exists(el)) { + return SQ_ERROR; + } // if + int vType = upValMapType.GetInt(el); + switch (vType) { + case TypeInfo::TypeID: { + int * val = (int *)upValMap.GetUserPointer(el); + if (val) { + return sa.Return(*val); + } else { + return sa.Return(-1); + } // if + } // case + case TypeInfo::TypeID: { + float * val = (float *)upValMap.GetUserPointer(el); + if (val) { + return sa.Return(*val); + } else { + return sa.Return(-1); + } // if + } // case + case TypeInfo::TypeID: { + bool * val = (bool *)upValMap.GetUserPointer(el); + if (val) { + return sa.Return(*val); + } else { + return sa.Return(-1); + } // if + } // case + } // switch + } // if + return SQ_ERROR; +} // getVarFunc2 + +template +void bindVariable2(SquirrelObject & so,T & var,const SQChar * scriptVarName) { + SquirrelObject __upValMapPtr; + SquirrelObject __upValMapType; + + if (so.Exists(_T("_uvp"))) { + __upValMapPtr = so.GetValue(_T("_uvp")); + __upValMapType = so.GetValue(_T("_uvt")); + } else { + __upValMapPtr = SquirrelVM::CreateTable(); + __upValMapType = SquirrelVM::CreateTable(); + } // if + + int varType = TypeInfo::TypeID; + __upValMapPtr.SetUserPointer(scriptVarName,&var); + __upValMapType.SetValue(scriptVarName,varType); + + so.SetValue(_T("_uvp"),__upValMapPtr); + so.SetValue(_T("_uvt"),__upValMapType); + + SquirrelObject delegate = so.GetDelegate(); + if (!delegate.Exists(_T("_set"))) { + delegate = SquirrelVM::CreateTable(); + SquirrelVM::CreateFunction(delegate,"_set",setVarFunc2,_T("sn|b")); // String var name = number(int or float) or bool. + SquirrelVM::CreateFunction(delegate,"_get",getVarFunc2,_T("s")); // String var name. + so.SetDelegate(delegate); + } // if + +} // bindVariable2 +#endif + +// === BEGIN Old, initial test versions. === + +int setIntFunc(HSQUIRRELVM v) { + StackHandler sa(v); + if (sa.GetType(1) == OT_TABLE) { + HSQOBJECT htable = sa.GetObjectHandle(1); + SquirrelObject table(htable); + const SQChar * el = sa.GetString(2); + SquirrelObject upValMap = table.GetValue(_T("upValMap")); + int * val = (int *)upValMap.GetUserPointer(el); + if (val) { + *val = sa.GetInt(3); + return sa.Return(*val); + } else { + return sa.Return(-1); + } // if + } // if + return SQ_ERROR; +} // setIntFunc + +int getIntFunc(HSQUIRRELVM v) { + StackHandler sa(v); + if (sa.GetType(1) == OT_TABLE) { + HSQOBJECT htable = sa.GetObjectHandle(1); + SquirrelObject table(htable); + int type = sa.GetType(2); + const SQChar * el = sa.GetString(2); + SquirrelObject upValMap = table.GetValue(_T("upValMap")); + int * val = (int *)upValMap.GetUserPointer(el); + if (val) { + return sa.Return(*val); + } else { + return sa.Return(-1); + } // if + } // if + return SQ_ERROR; +} // getIntFunc + +// === END Old, initial tests versions. === + +_DECL_STATIC_NAMESPACE(GB); // Globals + +_MEMBER_FUNCTION_IMPL(GB,Update) { + StackHandler sa(v); + scprintf(_T("GB.Update()\n")); + return sa.Return(true); +} + +enum {TEST_CONST=123}; + +_BEGIN_NAMESPACE(GB) +_MEMBER_FUNCTION(GB,Update,0,0) +_BEGIN_NAMESPACE_CONSTANTS(GB) +_CONSTANT_IMPL(TEST_CONST,OT_INTEGER) +_END_NAMESPACE(GB,NULL) + +#if 0 +int getVarName(HSQUIRRELVM v) { + StackHandler sa(v); + const SQChar * varName = sq_getlocal(v,1,0); + return sa.Return(varName); +} // getVarName +#endif + +void newtest(void) { + scprintf(_T("NewTest\n")); +} + +SQChar * newtestR1(const SQChar * inString) { + scprintf(_T("NewTestR1: %s\n"),inString); + return _T("Returned String"); +} + +struct NewTestObj { + ScriptStringVar64 s1; + ScriptStringVar32 s2; + int pad; + int val; + int c1; + ScriptStringVar8 c2; // 8 char plus null (max string is 8 printable chars). + NewTestObj() : val(777) { + s1 = _T("s1"); + s2 = _T("s2"); + c1 = 996; + c2 = _T("It's a 997"); // Prints: "It's a 9", as only 8 chars in static buffer (plus null). + } + void newtest(void) { + scprintf(_T("NewTest: %d\n"),val); + } + SQChar * newtestR1(const SQChar * inString) { + scprintf(_T("NewTestR1: Member var val is %d, function arg is %s\n"),val,inString); + return _T("Returned String"); + } + + int multiArgs(HSQUIRRELVM v) { + StackHandler sa(v); + int paramCount = sa.GetParamCount(); + int p1 = sa.GetInt(2); + int p2 = sa.GetInt(3); + int p3 = sa.GetInt(4); + return 0; + } // multiArgs + + int _set(HSQUIRRELVM v) { + StackHandler sa(v); + int paramCount = sa.GetParamCount(); + const SQChar * el = sa.GetString(2); + val = sa.GetInt(3); + return sa.Return(val); +// return setInstanceVarFunc(v); + } + + int _get(HSQUIRRELVM v) { + StackHandler sa(v); + int paramCount = sa.GetParamCount(); +// return getInstanceVarFunc(v); + return sa.Return(val); + } + +}; + +struct CustomTestObj { + ScriptStringVar128 name; + int val; + bool state; + CustomTestObj() : val(0), state(false) { name = _T("empty"); } + CustomTestObj(const SQChar * _name,int _val,bool _state) : val(_val), state(_state) { + name = _name; + } + static int construct(HSQUIRRELVM v) { + StackHandler sa(v); + int paramCount = sa.GetParamCount(); + if (paramCount == 1) { + return PostConstruct(v,new CustomTestObj(),release); + } if (paramCount == 4) { + return PostConstruct(v,new CustomTestObj(sa.GetString(2),sa.GetInt(3),sa.GetBool(4)?true:false),release); + } // if + return sq_throwerror(v,_T("Invalid Constructor arguments")); + } // construct + + SQ_DECLARE_RELEASE(CustomTestObj) + + // Member function that handles variable types. + int varArgTypes(HSQUIRRELVM v) { + StackHandler sa(v); + int paramCount = sa.GetParamCount(); + if (sa.GetType(2) == OT_INTEGER) { + val = sa.GetInt(2); + } // if + if (sa.GetType(2) == OT_STRING) { + name = sa.GetString(2); + } // if + if (sa.GetType(3) == OT_INTEGER) { + val = sa.GetInt(3); + } // if + if (sa.GetType(3) == OT_STRING) { + name = sa.GetString(3); + } // if + return 0; + } // varArgTypes + + // Member function that handles variable types and has variable return types+count. + int varArgTypesAndCount(HSQUIRRELVM v) { + StackHandler sa(v); + int paramCount = sa.GetParamCount(); + SQObjectType type1 = (SQObjectType)sa.GetType(1); // Always OT_INSTANCE + SQObjectType type2 = (SQObjectType)sa.GetType(2); + SQObjectType type3 = (SQObjectType)sa.GetType(3); + SQObjectType type4 = (SQObjectType)sa.GetType(4); + int returnCount = 0; + if (paramCount == 3) { + sq_pushinteger(v,val); + returnCount = 1; + } else if (paramCount == 4) { + sq_pushinteger(v,val); + sq_pushstring(v,name,-1); + returnCount = 2; + } // if + return returnCount; + } // + + int noArgsVariableReturn(HSQUIRRELVM v) { + if (val == 123) { + val++; + return 0; // This will print (null). + } else if (val == 124) { + sq_pushinteger(v,val); // Will return int:124. + val++; + return 1; + } else if (val == 125) { + sq_pushinteger(v,val); + name = _T("Case 125"); + sq_pushstring(v,name,-1); + val = 123; // reset + return 2; + } // if + return 0; + } // noArgsVariableReturn + + // Registered with func() instead of funcVarArgs(): fixed (single) return type. + const SQChar * variableArgsFixedReturnType(HSQUIRRELVM v) { + StackHandler sa(v); + int paramCount = sa.GetParamCount(); + SQObjectType type1 = (SQObjectType)sa.GetType(1); // Always OT_INSTANCE + SQObjectType type2 = (SQObjectType)sa.GetType(2); + SQObjectType type3 = (SQObjectType)sa.GetType(3); + if (paramCount == 1) { + return _T("No Args"); + } else if (paramCount == 2) { + return _T("One Arg"); + } else if (paramCount == 3) { + return _T("Two Args"); + } // if + return _T("More than two args"); + } // variableArgsFixedReturnType + + void manyArgs(int i,float f,bool b,const SQChar * s) { + scprintf(_T("i: %d, f: %f, b: %s, s: %s\n"),i,f,b?_T("true"):_T("false"),s); + } // manyArgs + + float manyArgsR1(int i,float f,bool b,const SQChar * s) { + manyArgs(i,f,b,s); + return i+f; + } // manyArgsR1 + +}; + +#if 0 +struct Base { + int val1; + ScriptStringVar16 nameBase; + Base() : nameBase(_T("Base")) { + val1 = 123; + } + void funcBase(void) { + scprintf(_T("Val1: %d, Name: %s\n"),val1,nameBase.s); + } +}; + +struct Derived { + int val2; + ScriptStringVar16 nameDerived; + Derived() : nameDerived(_T("Derived")), val2(456) { + val2 = 456; + } + void funcDerived(void) { + scprintf(_T("Val2: %d, Name: %s\n"),val2,nameDerived.s); + } +}; +#endif + +//SQ_DECLARE_CLASS(NewTestObj); + +class TestSqPlus { +public: + void init(void) { + SquirrelVM::Init(); +// sq_setprintfunc(SquirrelVM::GetVMPtr(),printfunc); //sets the print function. + _INIT_CLASS(TestObj); + _INIT_STATIC_NAMESPACE(GB); + } // if + + TestSqPlus() { + init(); + + try { + HSQUIRRELVM v = SquirrelVM::GetVMPtr(); + + // === BEGIN Global Function binding tests === + + // Implemented as SquirrelVM::CreateFunction(rootTable,func,name,typeMask); + SquirrelVM::CreateFunctionGlobal(&testFunc,_T("testFunc0")); + SquirrelVM::CreateFunctionGlobal(&testFunc,_T("testFuncN"),_T("n")); + SquirrelVM::CreateFunctionGlobal(&testFunc,_T("testFuncS"),_T("s")); + + // === Register Standard Functions === + + RegisterGlobal(v,&newtest,_T("test")); + RegisterGlobal(v,&newtestR1,_T("testR1")); + + // === Register Member Functions to existing classes (as opposed to instances of classes) === + + NewTestObj t1,t2,t3; + t1.val = 123; + t2.val = 456; + t3.val = 789; + RegisterGlobal(v,t1,&NewTestObj::newtest,_T("testObj_newtest1")); + RegisterGlobal(v,t2,&NewTestObj::newtest,_T("testObj_newtest2")); // Register newtest() again with different name and object pointer. + SquirrelObject tr = SquirrelVM::GetRootTable(); // Can be any object supporting closures (functions). + Register(v,tr.GetObjectHandle(),t3,&NewTestObj::newtestR1,_T("testObj_newtestR1")); // Return value version. + + // === END Global Function binding tests === + + // === BEGIN Class Instance tests === + +#if 0 + SQClassDef sqClass(_T("NewTestObj")); + sqClass.func(&NewTestObj::newtestR1,_T("newtestR1")); + sqClass.var(&NewTestObj::val,_T("val")); + sqClass.var(&NewTestObj::s1,_T("s1")); + sqClass.var(&NewTestObj::s2,_T("s2")); + sqClass.var(&NewTestObj::c1,_T("c1"),VAR_ACCESS_READ_ONLY); + sqClass.var(&NewTestObj::c2,_T("c2"),VAR_ACCESS_READ_ONLY); + sqClass.funcVarArgs(&NewTestObj::multiArgs,_T("multiArgs")); +#else + SQClassDef(_T("NewTestObj")). + func(&NewTestObj::newtestR1,_T("newtestR1")). + var(&NewTestObj::val,_T("val")). + var(&NewTestObj::s1,_T("s1")). + var(&NewTestObj::s2,_T("s2")). + var(&NewTestObj::c1,_T("c1"),VAR_ACCESS_READ_ONLY). + var(&NewTestObj::c2,_T("c2"),VAR_ACCESS_READ_ONLY). + funcVarArgs(&NewTestObj::multiArgs,_T("multiArgs")); +#endif + + SQClassDef customClass(_T("CustomTestObj")); + customClass.staticFuncVarArgs(&CustomTestObj::construct,_T("constructor"),_T("snb")); // string, number, bool (all types must match). + customClass.funcVarArgs(&CustomTestObj::varArgTypes,_T("varArgTypes"),_T("s|ns|ns|ns|n")); // string or number + string or number. + customClass.funcVarArgs(&CustomTestObj::varArgTypesAndCount,_T("varArgTypesAndCount"),_T("*")); // "*"): no type or count checking. + customClass.funcVarArgs(&CustomTestObj::noArgsVariableReturn,_T("noArgsVariableReturn")); // No type string means no arguments allowed. + customClass.func(&CustomTestObj::variableArgsFixedReturnType,_T("variableArgsFixedReturnType")); // Variables args, fixed return type. + customClass.func(&CustomTestObj::manyArgs,_T("manyArgs")); // Many args, type checked. + customClass.func(&CustomTestObj::manyArgsR1,_T("manyArgsR1")); // Many args, type checked, one return value. + +// Old macro-based method. Must use SQ_DECLARE_CLASS() macro above. +#if 0 + SquirrelObject newClass = SQ_REGISTER_CLASS(NewTestObj); + SQ_REGISTER_INSTANCE(newClass,NewTestObj,newtestR1); +// Currently, can use either automatic variable handling OR manual handling (but not both at once). +#if 1 + SQ_REGISTER_INSTANCE_VARIABLE(newClass,NewTestObj,val); // _set/_get will be defined to use automatic methods for val. +#else + SQ_REGISTER_INSTANCE_VARARGS(newClass,NewTestObj,_set); // _set is now defined and won't be overridden. + SQ_REGISTER_INSTANCE_VARARGS(newClass,NewTestObj,_get); + SQ_REGISTER_INSTANCE_VARIABLE(newClass,NewTestObj,val); // Access will be through _set/_get member functions above, not automatic methods. +#endif + +#if 1 + // With an HSQUIRRELVM argument, can handle variable args, and when registered this way can return multiple values. + SQ_REGISTER_INSTANCE_VARARGS(newClass,NewTestObj,multiArgs); +#else + // With an HSQUIRRELVM argument, can handle variable args, but can only return one value (defined by the function definition). + SQ_REGISTER_INSTANCE(newClass,NewTestObj,multiArgs); +#endif +#endif + +#if 1 + SquirrelObject testReg0 = SquirrelVM::CompileBuffer(_T(" co <- CustomTestObj(\"hello\",123,true); co.varArgTypes(\"str\",123,123,\"str\"); co.varArgTypes(123,\"str\",\"str\",123); ")); + SquirrelVM::RunScript(testReg0); + + SquirrelObject testReg0a = SquirrelVM::CompileBuffer(_T(" print(co.varArgTypesAndCount(1,true)); print(co.varArgTypesAndCount(2,false,3.)); print(\"\\n\"); ")); + SquirrelVM::RunScript(testReg0a); + + SquirrelObject testReg0b = SquirrelVM::CompileBuffer(_T(" print(co.noArgsVariableReturn()); print(co.noArgsVariableReturn()); print(co.noArgsVariableReturn()); print(\"\\n\"); ")); + SquirrelVM::RunScript(testReg0b); + + SquirrelObject testReg0c = SquirrelVM::CompileBuffer(_T(" print(co.variableArgsFixedReturnType(1)); print(co.variableArgsFixedReturnType(1,2)); print(co.variableArgsFixedReturnType(1,2,3)); print(\"\\n\"); ")); + SquirrelVM::RunScript(testReg0c); + + SquirrelObject testReg0d = SquirrelVM::CompileBuffer(_T(" co.manyArgs(111,222.2,true,\"Hello\"); print(co.manyArgsR1(333,444.3,false,\"World\")); print(\"\\n\"); ")); + SquirrelVM::RunScript(testReg0d); +#endif + +// Inheriting from an existing base class in this way is not currently supported. +// Requires either a Squirrel language/behavior change, or extra code at the interface +// layer to allocate memory and call constructor of parent class (and perhaps +// handle constructor args) store pointer in UserData, and handle proper variable access +// (get correct class/struct pointer) and member function calls (store class +// type/id in function up-var and search/hash for actual 'this' pointer for function call). +#if 0 + SQClassDef(_T("Base")). + var(&Base::nameBase,_T("nameBase")). + func(&Base::funcBase,_T("funcBase")); + + SQClassDef("Derived",_T("Base")). + var(&Derived::nameDerived,_T("nameDerived")). + func(&Derived::funcDerived,_T("funcDerived")); + +// SquirrelObject testBaseDerived = SquirrelVM::CompileBuffer(_T(" local base = Base(); print(base.nameBase); local derived = Derived(); print(\"NameBase: \"+derived.nameBase+\" NameDerived: \"+derived.nameDerived); derived.funcBase(); ")); + SquirrelObject testBaseDerived = SquirrelVM::CompileBuffer(_T(" local derived = Derived(); print(\"NameBase: \"+derived.nameBase+\" NameDerived: \"+derived.nameDerived); derived.funcBase(); ")); + SquirrelVM::RunScript(testBaseDerived); +#endif + +#if 1 + SquirrelObject testReg1a = SquirrelVM::CompileBuffer(_T(" co <- CustomTestObj(\"hello\",123,true); co.noArgsVariableReturn(); local t = NewTestObj(); print(\"C1: \"+t.c1); print(\"C2: \"+t.c2); // t.c1 = 123; ")); + SquirrelVM::RunScript(testReg1a); + + // Constant test (read only var). Var can change on C++ side, but not on script side. + try { + SquirrelObject testRegConstant = SquirrelVM::CompileBuffer(_T(" local t = NewTestObj(); t.c1 = 123; ")); + SquirrelVM::RunScript(testRegConstant); + } // try + catch (SquirrelError & e) { + SQChar buff[256]; + scsprintf(buff,_T("Error: %s, %s\n"),e.desc,_T("Squirrel::TestConstant")); + // OutputDebugString(buff); + SCPUTS(buff); + } // catch + + SquirrelObject testReg1 = SquirrelVM::CompileBuffer(_T(" local t = NewTestObj(); t.newtestR1(\"Hello\"); t.val = 789; print(t.val); print(t.s1); print(t.s2); t.s1 = \"New S1\"; print(t.s1); ")); + SquirrelVM::RunScript(testReg1); + + SquirrelObject testReg2 = SquirrelVM::CompileBuffer(_T(" local t = NewTestObj(); t.val = 789; print(t.val); t.val = 876; print(t.val); t.multiArgs(1,2,3); t.multiArgs(1,2,3,4); ")); + SquirrelVM::RunScript(testReg2); + SquirrelObject testReg3 = SquirrelVM::CompileBuffer(_T(" test(); local rv = testR1(\"Hello\"); print(rv); ")); + SquirrelVM::RunScript(testReg3); + SquirrelObject testReg4 = SquirrelVM::CompileBuffer(_T(" print(\"\\nMembers:\"); testObj_newtest1(); testObj_newtest2(); print(testObj_newtestR1(\"Hello Again\")); ")); + SquirrelVM::RunScript(testReg4); + + SquirrelObject defCallFunc = SquirrelVM::CompileBuffer(_T(" function callMe(var) { print(\"I was called by: \"+var); return 123; }")); + SquirrelVM::RunScript(defCallFunc); + + SquirrelObject root = SquirrelVM::GetRootTable(); + + // Get a function from the root table and call it. + SquirrelFunction callFunc(_T("callMe")); + int ival = callFunc(_T("Squirrel")); + scprintf(_T("IVal: %d\n"),ival); + ival = 0; + // Get a function from any table. + SquirrelFunction callFunc2(root.GetObjectHandle(),_T("callMe")); + ival = callFunc(456); // Argument count is checked; type is not. + + // === END Class Instance tests === + + // === BEGIN macro-only class-registrated tests === +// SquirrelVM::CreateFunctionGlobal(_T("getName",getVarName,"*")); // * = any type. +// SquirrelObject main = SquirrelVM::CompileBuffer(_T("local testObj = TestObj(); testObj.print(); testObj.update(\"ab\"); testObj.print()")); +// SquirrelObject main = SquirrelVM::CompileBuffer(_T("local LF = \"\\n\"; local testObj = TestObj(); testObj.print(); testObj.update(1.5); testObj.print(); testObj.y += 10.; testObj.z = -1.; print(testObj.y+LF); print(\"Array: \"+testObj[0]+LF); print(testObj); print(LF); ")); +// SquirrelObject main = SquirrelVM::CompileBuffer(_T("local testObj = TestObj(); testObj.z = -1.; print(testObj); testFunc(); testFunc0(); testFuncN(1.); testFuncS(\"Hello\"); ")); +// SquirrelObject main = SquirrelVM::CompileBuffer(_T("testFunc0(); testFuncN(1); testFuncN(1.23); testFuncS(\"Hello\");")); + + SquirrelObject main = SquirrelVM::CompileBuffer(_T("table1 <- {key1=\"keyVal\",key2 = 123};\n if (\"key1\" in table1)\n print(\"Sq: Found it\");\n else\n print(\"Sq: Not found\");")); + SquirrelVM::RunScript(main); + SquirrelObject table1 = root.GetValue(_T("table1")); + if (table1.Exists(_T("key1"))) { + scprintf(_T("C++: Found it.\n")); + } else { + scprintf(_T("C++: Did not find it.\n")); + } // if + + // === BEGIN Simple variable binding tests === + + int iVar = 777; + float fVar = 88.99f; + bool bVar = true; + BindVariable(root,&iVar,_T("iVar")); + BindVariable(root,&fVar,_T("fVar")); + BindVariable(root,&bVar,_T("bVar")); + + static ScriptStringVar128 testString; + scsprintf(testString,_T("This is a test string")); + BindVariable(root,&testString,_T("testString")); + + // === END Simple variable binding tests === + + // === BEGIN Array Tests === + + SquirrelObject array = SquirrelVM::CreateArray(10); + int i; + for (i = 0; i < 10; i++) array.SetValue(i,i); + array.ArrayAppend(123); // int + array.ArrayAppend(true); // bool (must use bool and not SQBool (SQBool is treated as INT by compiler). + array.ArrayAppend(false); // bool (must use bool and not SQBool (SQBool is treated as INT by compiler). + array.ArrayAppend(123.456f); // float + array.ArrayAppend(_T("string")); // string + array.ArrayAppend(456); // Will be popped and thrown away (below). + + // Pop 3 items from array: + array.ArrayPop(SQFalse); // Don't retrieve the popped value (int:123). + SquirrelObject so1 = array.ArrayPop(); // Retrieve the popped value. + const SQChar * val1 = so1.ToString(); // Get string. + float val2 = array.ArrayPop().ToFloat(); // Pop and get float. + scprintf(_T("[Popped values] Val1: %s, Val2: %f\n"),val1,val2); + + int startIndex = array.Len(); + array.ArrayExtend(10); // Implemented as: ArrayResize(Len()+amount). + for (i = startIndex; i < array.Len(); i++) array.SetValue(i,i*10); + root.SetValue(_T("array"),array); + + SquirrelObject arrayr = array.Clone(); // Get a copy as opposed to another reference. + arrayr.ArrayReverse(); + root.SetValue(_T("arrayr"),arrayr); + + // === END Array Tests === + +// SquirrelObject test = SquirrelVM::CompileBuffer(_T(" print(iVar); print(fVar); print(bVar); iVar += 1; fVar += 100.; bVar = false; print(iVar); print(fVar); print(bVar); xVar = 1; ")); // Test for xVar error. +// SquirrelObject test = SquirrelVM::CompileBuffer(_T(" print(iVar); print(fVar); print(bVar); iVar += 1; fVar += 100.; bVar = false; print(iVar); print(fVar); print(bVar); print(testString); testString = \"New string value\"; print(testString);")); + SquirrelObject define_printArray = SquirrelVM::CompileBuffer(_T(" function printArray(name,array) { print(name+\".len() = \"+array.len()); foreach(i, v in array) if (v != null) { if (typeof v == \"bool\") v = v ? \"true\" : \"false\"; print(\"[\"+i+\"]: \"+v); } } ")); + SquirrelVM::RunScript(define_printArray); + SquirrelObject test = SquirrelVM::CompileBuffer(_T(" printArray(\"array\",array); printArray(\"arrayr\",arrayr); ")); + +// SquirrelObject test = SquirrelVM::CompileBuffer(_T(" iVar = 1; print(iVar); ")); +// SquirrelObject test = SquirrelVM::CompileBuffer(_T(" print(\"GB:\"+GB.TEST_CONST); GB.TEST_CONST += 1; GB.Update(); print(\"GB2:\"+GB.TEST_CONST); \n")); + + SquirrelVM::RunScript(test); +#endif + + } // try + catch (SquirrelError & e) { +// SquirrelVM::DumpStack(); + SQChar buff[256]; + scsprintf(buff,_T("Error: %s, %s\n"),e.desc,_T("Squirrel::TestObj")); +// OutputDebugString(buff); + SCPUTS(buff); + } // catch + + } + + ~TestSqPlus() { + SquirrelVM::Shutdown(); + } + +}; + +void doTest(void) { + TestSqPlus testSqPlus; +} // doTest + +int main(int argc,char * argv[]) { + + // Run twice to make sure cleanup/shutdown works OK. + SCPUTS(_T("Start Pass 1\n")); + doTest(); +#if 0 + SCPUTS(_T("Start Pass 2\n")); + doTest(); +#endif + SCPUTS(_T("Done.\n")); + + scprintf(_T("Press RETURN to exit.")); + getchar(); + + return 0; +} + diff --git a/vscript/languages/squirrel/testSqPlus/testSqPlus.vcproj b/vscript/languages/squirrel/testSqPlus/testSqPlus.vcproj new file mode 100644 index 00000000..7c5a612e --- /dev/null +++ b/vscript/languages/squirrel/testSqPlus/testSqPlus.vcproj @@ -0,0 +1,352 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/testSqPlus/testSqPlus71.vcproj b/vscript/languages/squirrel/testSqPlus/testSqPlus71.vcproj new file mode 100644 index 00000000..af8ea1c4 --- /dev/null +++ b/vscript/languages/squirrel/testSqPlus/testSqPlus71.vcproj @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/testSqPlus2/Makefile b/vscript/languages/squirrel/testSqPlus2/Makefile new file mode 100644 index 00000000..ebc149b1 --- /dev/null +++ b/vscript/languages/squirrel/testSqPlus2/Makefile @@ -0,0 +1,16 @@ +SQUIRREL= .. + +OUT= ./testSqPlus2 +INCDIRS= -I$(SQUIRREL)/include -I. -I$(SQUIRREL)/sqlibs -I$(SQUIRREL)/sqplus +LIBDIR= -L$(SQUIRREL)/lib +#LIBS= -lsquirrel -lsqstdlib -lsqplus +LIBS= -lsqplus -lsquirrel -lsqstdlib + +SRCS= testSqPlus2.cpp + +all: testSqPlus2 + +FORCE: ; + +testSqPlus2: FORCE + g++ -O3 -fno-rtti -Os -o $(OUT) $(SRCS) $(INCDIRS) $(LIBDIR) $(LIBS) diff --git a/vscript/languages/squirrel/testSqPlus2/testSqPlus2.cbp b/vscript/languages/squirrel/testSqPlus2/testSqPlus2.cbp new file mode 100644 index 00000000..d715d640 --- /dev/null +++ b/vscript/languages/squirrel/testSqPlus2/testSqPlus2.cbp @@ -0,0 +1,138 @@ + + + + + + + diff --git a/vscript/languages/squirrel/testSqPlus2/testSqPlus2.cpp b/vscript/languages/squirrel/testSqPlus2/testSqPlus2.cpp new file mode 100644 index 00000000..3f23dde8 --- /dev/null +++ b/vscript/languages/squirrel/testSqPlus2/testSqPlus2.cpp @@ -0,0 +1,1250 @@ +// testSqPlus2.cpp +// Created by John Schultz 9/21/2005 +// Free for any use. + +// Step through the code with a debugger (setting breakpoints in functions) +// to get an idea how everything works. + +#include +#include +#if 0 +#include +//#define SQPLUS_SUPPORT_STD_STRING +#define SQPLUS_SUPPORT_SQ_STD_STRING +#endif +//#define SQPLUS_CONST_OPT +#include "sqplus.h" + +using namespace SqPlus; + +void scprintfunc(HSQUIRRELVM v,const SQChar *s,...) { + static SQChar temp[2048]; + va_list vl; + va_start(vl,s); + scvsprintf( temp,s,vl); + SCPUTS(temp); + va_end(vl); +} + +void newtest(void) { + scprintf(_T("NewTest\n")); +} + +SQChar * newtestR1(const SQChar * inString) { + scprintf(_T("NewTestR1: %s\n"),inString); + return _T("Returned String"); +} + +struct Vector3 { + static float staticVar; + float x,y,z; + Vector3() { + x = 1.f; + y = 2.f; + z = 3.f; + } + Vector3(float _x,float _y,float _z) : x(_x), y(_y), z(_z) {} + ~Vector3() { + scprintf(_T("~Vector()\n")); + } + Vector3 Inc(Vector3 & v) { + x += v.x; + y += v.y; + z += v.z; + return *this; + } // Inc + Vector3 operator+(Vector3 & v) { + return Vector3(x+v.x,y+v.y,z+v.z); + } +}; + + +float Vector3::staticVar = 898.434f; + +#if 0 // It may be possible to make this method work in the future. If so, the DECLARE_INSTANCE_FUNCS() macro + // would not be needed. The issue is duplicate compiler matching for const SQChar * and Push(): + // Push(const SQChar * &) and Push(const SQChar *) both match. + // The typeid() compiler function may not be portable to other compilers. +#include +template +inline const SQChar * GetTypeName(const TYPE & n) { return typeid(TYPE).name(); } +template +inline void Push(HSQUIRRELVM v,const TYPE & value) { CreateCopyInstance(GetTypeName(value),value); } +template +inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return GetInstance(v,idx) != NULL; } +template +inline TYPE & Get(TypeWrapper,HSQUIRRELVM v,int idx) { return *GetInstance(v,idx); } +#endif + +DECLARE_INSTANCE_TYPE(Vector3) + +Vector3 Add2(Vector3 & a,Vector3 & b) { + Vector3 c; + c.x = a.x + b.x; + c.y = a.y + b.y; + c.z = a.z + b.z; + return c; +} // Add2 + +int Add(HSQUIRRELVM v) { +// StackHandler sa(v); + Vector3 * self = GetInstance(v,1); + Vector3 * arg = GetInstance(v,2); +// SquirrelObject so = sa.GetObjectHandle(1); +#if 0 + SQUserPointer type=0; + so.GetTypeTag(&type); + SQUserPointer reqType = ClassType::type(); + if (type != reqType) { + throw SquirrelError(_T("Invalid class type")); + } // if +#endif +// Vector3 * self = (Vector3 *)so.GetInstanceUP(ClassType::type()); +// if (!self) throw SquirrelError(_T("Invalid class type")); + Vector3 tv; + tv.x = arg->x + self->x; + tv.y = arg->y + self->y; + tv.z = arg->z + self->z; + return ReturnCopy(v,tv); +} + +struct NewTestObj { + ScriptStringVar64 s1; + ScriptStringVar32 s2; + bool b; + int val; + int c1; + ScriptStringVar8 c2; // 8 char plus null (max string is 8 printable chars). + NewTestObj() : val(777) { + s1 = _T("s1=s1"); + s2 = _T("s2=s2"); + c1 = 996; + c2 = _T("It's a 997"); // Prints: "It's a 9", as only 8 chars in static buffer (plus null). + } + + NewTestObj(const SQChar * _s1,int _val,bool _b) { + s1 = _s1; + val = _val; + b = _b; + s2 = _T("s2=s2"); + c1 = 993; + c2 = _T("It's a 998"); // Prints: "It's a 9", as only 8 chars in static buffer (plus null). + } + + static int construct(HSQUIRRELVM v) { +// StackHandler sa(v); +// SquirrelObject so = sa.GetObjectHandle(1); + return PostConstruct(v,new NewTestObj(),release); + } // construct + + SQ_DECLARE_RELEASE(NewTestObj) // Required when using a custom constructor. + + void newtest(void) { + scprintf(_T("NewTest: %d\n"),val); + } + SQChar * newtestR1(const SQChar * inString) { + scprintf(_T("NewTestR1: Member var val is %d, function arg is %s\n"),val,inString); + return _T("Returned String"); + } + + int multiArgs(HSQUIRRELVM v) { + StackHandler sa(v); + SquirrelObject so = sa.GetObjectHandle(1); + int paramCount = sa.GetParamCount(); + int p1 = sa.GetInt(2); + int p2 = sa.GetInt(3); + int p3 = sa.GetInt(4); + return 0; + } // multiArgs + + int _set(HSQUIRRELVM v) { + StackHandler sa(v); + int paramCount = sa.GetParamCount(); + const SQChar * el = sa.GetString(2); + val = sa.GetInt(3); + return sa.Return(val); + } + + int _get(HSQUIRRELVM v) { + StackHandler sa(v); + int paramCount = sa.GetParamCount(); + return sa.Return(val); + } + +}; + +// Using global functions to construct and release classes. +int releaseNewTestObj(SQUserPointer up,SQInteger size) { + SQ_DELETE_CLASS(NewTestObj); +} // releaseNewTestObj + +int constructNewTestObj(HSQUIRRELVM v) { + StackHandler sa(v); + int paramCount = sa.GetParamCount(); + if (paramCount == 1) { + return PostConstruct(v,new NewTestObj(),releaseNewTestObj); + } else if (paramCount == 4) { + return PostConstruct(v,new NewTestObj(sa.GetString(2),sa.GetInt(3),sa.GetBool(4)?true:false),releaseNewTestObj); + } // if + return sq_throwerror(v,_T("Invalid Constructor arguments")); +} // constructNewTestObj + +// Using fixed args with auto-marshaling. Note that the HSQUIRRELVM must be last in the argument list (and must be present to send to PostConstruct). +// SquirrelVM::GetVMPtr() could also be used with PostConstruct(): no HSQUIRRELVM argument would be required. +int constructNewTestObjFixedArgs(const SQChar * s,int val,bool b,HSQUIRRELVM v) { + StackHandler sa(v); + int paramCount = sa.GetParamCount(); + return PostConstruct(v,new NewTestObj(s,val,b),releaseNewTestObj); +} // constructNewTestObj + +// Will be registered in a class namespace. +void globalFunc(const SQChar * s,int val) { + scprintf(_T("globalFunc: s: %s val: %d\n"),s,val); +} // globalFunc + +class GlobalClass { +public: + void func(const SQChar * s,int val) { + scprintf(_T("globalClassFunc: s: %s val: %d\n"),s,val); + } // func +} globalClass; + +struct CustomTestObj { + ScriptStringVar128 name; + int val; + bool state; + CustomTestObj() : val(0), state(false) { name = _T("empty"); } + CustomTestObj(const SQChar * _name,int _val,bool _state) : val(_val), state(_state) { + name = _name; + } + + // Custom variable argument constructor + static int construct(HSQUIRRELVM v) { + StackHandler sa(v); + int paramCount = sa.GetParamCount(); + if (paramCount == 1) { + return PostConstruct(v,new CustomTestObj(),release); + } if (paramCount == 4) { + return PostConstruct(v,new CustomTestObj(sa.GetString(2),sa.GetInt(3),sa.GetBool(4)?true:false),release); + } // if + return sq_throwerror(v,_T("Invalid Constructor arguments")); + } // construct + + SQ_DECLARE_RELEASE(CustomTestObj) // Required when using a custom constructor. + + // Member function that handles variable types. + int varArgTypes(HSQUIRRELVM v) { + StackHandler sa(v); + int paramCount = sa.GetParamCount(); + if (sa.GetType(2) == OT_INTEGER) { + val = sa.GetInt(2); + } // if + if (sa.GetType(2) == OT_STRING) { + name = sa.GetString(2); + } // if + if (sa.GetType(3) == OT_INTEGER) { + val = sa.GetInt(3); + } // if + if (sa.GetType(3) == OT_STRING) { + name = sa.GetString(3); + } // if +// return sa.ThrowError(_T("varArgTypes() error")); + return 0; + } // varArgTypes + + // Member function that handles variable types and has variable return types+count. + int varArgTypesAndCount(HSQUIRRELVM v) { + StackHandler sa(v); + int paramCount = sa.GetParamCount(); + SQObjectType type1 = (SQObjectType)sa.GetType(1); // Always OT_INSTANCE + SQObjectType type2 = (SQObjectType)sa.GetType(2); + SQObjectType type3 = (SQObjectType)sa.GetType(3); + SQObjectType type4 = (SQObjectType)sa.GetType(4); + int returnCount = 0; + if (paramCount == 3) { + sq_pushinteger(v,val); + returnCount = 1; + } else if (paramCount == 4) { + sq_pushinteger(v,val); + sq_pushstring(v,name,-1); + returnCount = 2; + } // if + return returnCount; + } // + + int noArgsVariableReturn(HSQUIRRELVM v) { + if (val == 123) { + val++; + return 0; // This will print (null). + } else if (val == 124) { + sq_pushinteger(v,val); // Will return int:124. + val++; + return 1; + } else if (val == 125) { + sq_pushinteger(v,val); + name = _T("Case 125"); + sq_pushstring(v,name,-1); + val = 123; // reset + return 2; + } // if + return 0; + } // noArgsVariableReturn + + // Registered with func() instead of funcVarArgs(): fixed (single) return type. + const SQChar * variableArgsFixedReturnType(HSQUIRRELVM v) { + StackHandler sa(v); + int paramCount = sa.GetParamCount(); + SQObjectType type1 = (SQObjectType)sa.GetType(1); // Always OT_INSTANCE + SQObjectType type2 = (SQObjectType)sa.GetType(2); + SQObjectType type3 = (SQObjectType)sa.GetType(3); + if (paramCount == 1) { + return _T("No Args"); + } else if (paramCount == 2) { + return _T("One Arg"); + } else if (paramCount == 3) { + return _T("Two Args"); + } // if + return _T("More than two args"); + } // variableArgsFixedReturnType + + void manyArgs(int i,float f,bool b,const SQChar * s) { + scprintf(_T("i: %d, f: %f, b: %s, s: %s\n"),i,f,b?_T("true"):_T("false"),s); + } // manyArgs + + float manyArgsR1(int i,float f,bool b,const SQChar * s) { + manyArgs(i,f,b,s); + return i+f; + } // manyArgsR1 + +}; + +// === Standard (non member) function === +int testFunc(HSQUIRRELVM v) { + StackHandler sa(v); + int paramCount = sa.GetParamCount(); + scprintf(_T("testFunc: numParams[%d]\n"),paramCount); + for (int i=1; i <= paramCount; i++) { + scprintf(_T("param[%d]: "),i); + switch(sa.GetType(i)) { + case OT_TABLE: scprintf(_T("OT_TABLE[0x%x]\n"),sa.GetObjectHandle(i)); break; + case OT_INTEGER: scprintf(_T("OT_INTEGER[%d]\n"),sa.GetInt(i)); break; + case OT_FLOAT: scprintf(_T("OT_FLOAT[%f]\n"),sa.GetFloat(i)); break; + case OT_STRING: scprintf(_T("OT_STRING[%s]\n"),sa.GetString(i)); break; + default: + scprintf(_T("TYPEID[%d]\n"),sa.GetType(i)); + } // switch + } // for + return SQ_OK; +} // testFunc + +int globalVar = 5551234; + +class Creature { + int health; +public: + enum {MaxHealth=100}; + Creature() : health(MaxHealth) {} + int GetMaxHealth(void) { + return MaxHealth; + } + int GetHealth(void) { + return health; + } + void SetHealth(int newHealth) { + health = newHealth; + } +}; + +DECLARE_INSTANCE_TYPE(Creature) + +// === BEGIN Class Instance Test === + +class PlayerManager { +public: + struct Player { + ScriptStringVar64 name; + void printName(void) { + scprintf(_T("Player.name = %s\n"),name.s); + } + }; + Player playerVar; // Will be accessed directly. + Player players[2]; + Player * GetPlayer(int player) { // Must return pointer: a returned reference will behave the same as return by value. + return &players[player]; + } + PlayerManager() { + players[0].name = _T("Player1"); + players[1].name = _T("Player2"); + playerVar.name = _T("PlayerVar"); + } +} playerManager; + +DECLARE_INSTANCE_TYPE(PlayerManager) +DECLARE_INSTANCE_TYPE(PlayerManager::Player) + +PlayerManager * getPlayerManager(void) { // Must return pointer: a returned reference will behave the same as return by value. + return &playerManager; +} + +// Example from forum post question: +class STestScripts {}; // Proxy class +class TestScripts { +public: + int Var_ToBind1,Var_ToBind2; + + void InitScript1(void) { + Var_ToBind1 = 808; + RegisterGlobal(*this,&TestScripts::Test1,_T("Test1")); + RegisterGlobal(*this,&TestScripts::Test2,_T("Test2")); + BindVariable(&Var_ToBind1,_T("Var_ToBind1")); + } // InitScript1 + + void InitScript2(void) { + Var_ToBind2 = 909; + SQClassDef(_T("STestScripts")). + staticFunc(*this,&TestScripts::Test1,_T("Test1")). + staticFunc(*this,&TestScripts::Test2,_T("Test2")). + staticVar(&Var_ToBind2,_T("Var_ToBind2")); + } // InitScript2 + + void Test1(void) { + scprintf(_T("Test1 called.\n")); + } + void Test2(void) { + scprintf(_T("Test2 called.\n")); + } +} testScripts; + +// From forum questions + +#if 1 + +template +struct Point { + Point() {} + Point(T X, T Y) : X(X), Y(Y) {} + T X, Y; +}; + +template +struct Box { + Box() {} + Box(Point UpperLeft, Point LowerRight) : UpperLeft(UpperLeft), LowerRight(LowerRight) {} + Point UpperLeft, LowerRight; + void print(void) { + scprintf(_T("UL.X %f UL.Y %f LR.X %f LR.Y %f\n"),UpperLeft.X,UpperLeft.Y,LowerRight.X,LowerRight.Y); + } +}; + +template +struct Window { + int id; + Box box; +}; + +typedef Point Pointf; +typedef Box Boxf; +typedef Window Windowf; + +#else + +struct Pointf { + float X,Y; + Pointf() {} + Pointf(float _X, float _Y) : X(_X), Y(_Y) {} +}; + +struct Boxf { + Pointf UpperLeft,LowerRight; + Boxf() {} + Boxf(Pointf _UpperLeft,Pointf _LowerRight) : UpperLeft(_UpperLeft), LowerRight(_LowerRight) {} + void print(void) { + scprintf(_T("UL.X %f UL.Y %f LR.X %f LR.Y %f\n"),UpperLeft.X,UpperLeft.Y,LowerRight.X,LowerRight.Y); + } +}; + +struct Windowf { + int id; + Boxf box; +}; + +#endif + +DECLARE_INSTANCE_TYPE(Pointf) +DECLARE_INSTANCE_TYPE(Boxf) +DECLARE_INSTANCE_TYPE(Windowf) + +int constructPointf(float X,float Y,HSQUIRRELVM v) { + return PostConstruct(v,new Pointf(X,Y),ReleaseClassPtr::release); +} // constructPointf + +// Must pass by reference or pointer (not copy) +int constructBoxf(Pointf & UpperLeft,Pointf & LowerRight,HSQUIRRELVM v) { + return PostConstruct(v,new Boxf(UpperLeft,LowerRight),ReleaseClassPtr::release); +} // constructBoxf + +struct WindowHolder { + static Windowf * currentWindow; + static Windowf * getWindow(void) { + return currentWindow; + } // getWindow +}; +Windowf * WindowHolder::currentWindow = 0; + +// From forum post: compiler works OK. +void testCompiler(void) { + SquirrelObject test = SquirrelVM::CompileBuffer(_T("\ + local SceneManager = getSceneManager() ; \n\ +\n\ + SceneManager.AddScene(\"Scene1\") ; \n\ + SceneManager.AddScene(\"Scene4\") ; \n\ + SceneManager.ActivateScene(\"Scene1\") ; \n\ + ")); + SquirrelVM::RunScript(test); +} + +void testPointfBoxf(void) { + +// testCompiler(); + + SQClassDef(_T("Pointf")). + staticFunc(constructPointf,_T("constructor")). + var(&Pointf::X,_T("X")). + var(&Pointf::Y,_T("Y")); + + SQClassDef(_T("Boxf")). + staticFunc(constructBoxf,_T("constructor")). + func(&Boxf::print,_T("print")). + var(&Boxf::UpperLeft,_T("UpperLeft")). + var(&Boxf::LowerRight,_T("LowerRight")); + + SQClassDef(_T("Windowf")). + var(&Windowf::id,_T("Id")). + var(&Windowf::box,_T("Box")); + + RegisterGlobal(WindowHolder::getWindow,_T("getWindow")); + Windowf myWindow; + myWindow.id = 42; + myWindow.box = Boxf(Pointf(1.f,2.f),Pointf(3.f,4.f)); + WindowHolder::currentWindow = &myWindow; + + // The createWindow() function below creates a new instance on the root table. + // The instance data is a pointer to the C/C++ instance, and will not be freed + // or otherwise managed. + + SquirrelObject test = SquirrelVM::CompileBuffer(_T("\ + local MyWindow = Windowf(); \n\ + MyWindow.Box = Boxf(Pointf(11.,22.),Pointf(33.,44.)); \n\ + print(MyWindow.Box.LowerRight.Y); \n\ + MyWindow.Box.LowerRight.Y += 1.; \n\ + local MyWindow2 = Windowf(); \n\ + MyWindow2 = MyWindow; \n\ + print(MyWindow2.Box.LowerRight.Y); \n\ + local MyBox = Boxf(Pointf(10.,20.),Pointf(30.,40.)); \n\ + MyBox.UpperLeft = Pointf(1000.,1000.); \n\ + MyBox.UpperLeft.X = 5000. \n\ + print(MyBox.UpperLeft.X) \n\ + print(MyBox.UpperLeft.Y) \n\ + MyWindow2.Box = MyBox; \n\ + MyWindow2.Box.print(); \n\ + MyWindow2 = getWindow(); \n\ + print(\"MyWindow2: \"+MyWindow2.Id); \n\ + MyWindow2.Box.print(); \n\ + function createWindow(name,instance) { \n\ + ::rawset(name,instance); \n\ + } \n\ + ")); + SquirrelVM::RunScript(test); + + Windowf window = myWindow; + window.id = 54; + window.box.UpperLeft.X += 1; + window.box.UpperLeft.Y += 1; + window.box.LowerRight.X += 1; + window.box.LowerRight.Y += 1; + // Create a new Window instance "NewWindow" on the root table. + SquirrelFunction(_T("createWindow"))(_T("NewWindow"),&window); + + SquirrelObject test2 = SquirrelVM::CompileBuffer(_T("\ + print(\"NewWindow: \"+NewWindow.Id); \n\ + NewWindow.Box.print(); \n\ + ")); + SquirrelVM::RunScript(test2); + +} // testPointfBoxf + +// Example debug hook: called back during script execution. +SQInteger debug_hook(HSQUIRRELVM v) { + SQUserPointer up; + int event_type,line; + const SQChar *src,*func; + sq_getinteger(v,2,&event_type); + sq_getstring(v,3,&src); + sq_getinteger(v,4,&line); + sq_getstring(v,5,&func); + sq_getuserpointer(v,-1,&up); + return 0; +} // debug_hook + +// You can add functions/vars here, as well as bind globals to be accessed through this class as shown in the NameSpace example. +// If the class is instantiated in script, the instance is "locked", preventing accidental changes to elements. +// Thus using an instance as the namespace can be a better design for development. +// If variables/constants are bound to the class and/or non-static/non-global functions, the class must be instantiated before use. +struct NamespaceClass { +}; + +// === END Class Instance Test === + +class TestBase { +public: + int x; + TestBase() : x(0) { + printf("Constructing TestBase[0x%x]\n",(size_t)this); + } + void print(void) { + printf("TestBase[0x%x], x[%d]\n",(size_t)this,x); + } +}; + +DECLARE_INSTANCE_TYPE(TestBase) + +class TestDerivedCPP : public TestBase { +public: + int y; + TestDerivedCPP() { + x = 121; + } +}; + +typedef void (TestDerivedCPP::*TestDerivedCPP_print)(void); + +void testInhertianceCase(void) { + + SQClassDef(_T("TestBase")). + var(&TestBase::x,_T("x")). + func(&TestBase::print,_T("print")); + + SQClassDef(_T("TestDerivedCPP")). + func((TestDerivedCPP_print)&TestDerivedCPP::print,_T("print")); + + // Note that the constructor definition and call below is not required for this example. + // (The C/C++ constructor will be called automatically). + + SquirrelObject testInheritance2 = SquirrelVM::CompileBuffer(_T("\ + class TestDerived extends TestBase { \n\ + function print() { \n\ + ::TestBase.print(); \n\ + ::print(\"Derived: \"+x); \n\ + } \n\ + constructor() { \n\ + TestBase.constructor(); \n\ + } \n\ + } \n\ + local a = TestDerived(); \n\ + local b = TestDerived(); \n\ + a.x = 1; \n\ + b.x = 2; \n\ + print(\"a.x = \"+a.x); \n\ + print(\"b.x = \"+b.x); \n\ + a.print(); \n\ + b.print(); \n\ + local c = TestDerivedCPP(); \n\ + c.print(); \n\ + ")); + SquirrelVM::RunScript(testInheritance2); +} + +// === BEGIN from a forum post by jkleinecke. 8/23/06 jcs === + +namespace Scripting { + class ScriptEntity { + public: + ScriptEntity() { + Bind(); + } + static void Bind() { + SqPlus::SQClassDef(_T("ScriptEntity")). + var(&ScriptEntity::m_strName,_T("name")); + } // Bind + SqPlus::ScriptStringVar64 m_strName; + }; +} + +DECLARE_INSTANCE_TYPE_NAME(Scripting::ScriptEntity,ScriptEntity) + +void testScriptingTypeName(void) { + try { + Scripting::ScriptEntity entity ; + SqPlus::BindVariable(&entity,_T("instance")); + SquirrelObject sqObj = SquirrelVM::CompileBuffer(_T("instance.name = \"Testing an instance variable bind: member assignment.\"; print(instance.name);")); + SquirrelVM::RunScript(sqObj); + } // try + catch (SquirrelError e) { + scprintf(_T("testScriptingTypeName: %s\n"),e.desc); + } // catch +} + +// === END from a forum post by jkleinecke. 8/23/06 jcs === + + +// === BEGIN Interface Test === + +class PureInterface { +public: + virtual void pureFunc1(void)=0; + virtual void pureFunc2(void)=0; +}; + +class MyImp : public PureInterface { +public: + PureInterface * getInterface(void) { return (PureInterface *)this; } + void pureFunc1(void) { + scprintf(_T("PureFunc1 called [0x%p].\n"),this); + } + void pureFunc2(void) { + scprintf(_T("PureFunc2 called [0x%p].\n"),this); + } +}; + +class InterfaceHolder { +public: + PureInterface * theInterface; + void setInterface(PureInterface * pureInterface) { + theInterface = pureInterface; + } + PureInterface * getInterface(void) { + return theInterface; + } +}; + +DECLARE_INSTANCE_TYPE(PureInterface) +DECLARE_INSTANCE_TYPE(MyImp) +DECLARE_INSTANCE_TYPE(InterfaceHolder) + +void testPureVirtualInterface(void) { + SQClassDefNoConstructor(_T("PureInterface")). + func(&PureInterface::pureFunc1,_T("pureFunc1")). + func(&PureInterface::pureFunc2,_T("pureFunc2")); + + SQClassDef(_T("InterfaceHolder")). + func(&InterfaceHolder::setInterface,_T("setInterface")). + func(&InterfaceHolder::getInterface,_T("getInterface")); + + SQClassDef(_T("MyImp")). + func(&MyImp::getInterface,_T("getInterface")); + + MyImp myImp; + + SquirrelObject test = SquirrelVM::CompileBuffer(_T("ih <- InterfaceHolder();")); + SquirrelVM::RunScript(test); + + SquirrelObject root = SquirrelVM::GetRootTable(); + SquirrelObject ih = root.GetValue(_T("ih")); + InterfaceHolder * ihp = (InterfaceHolder * )ih.GetInstanceUP(ClassType::type()); + ihp->setInterface(&myImp); + + test = SquirrelVM::CompileBuffer(_T("\ + ih.getInterface().pureFunc1(); \n\ + ih.getInterface().pureFunc2(); \n\ + ihp <- ih.getInterface(); \n\ + ihp.pureFunc1(); \n\ + ihp.pureFunc2(); \n\ + myIh <- MyImp(); \n\ + ih.setInterface(myIh.getInterface()); \n\ + ih.getInterface().pureFunc1(); \n\ + ih.getInterface().pureFunc2(); \n\ + ")); + SquirrelVM::RunScript(test); + +} // testPureVirtualInterface + +// === END Interface Test === + +void testSquirrelObjectSetGet(void) { + // We can pass in arguments: + // by value ('true' arg, required for constant float, int, etc., or when a copy is desired), + // by reference (data will be copied to SquirrelObject and memory managed), + // by pointer (no data copying: pointer is used directly in SquirrelObject; the memory will not be managed). + + SquirrelObject tc(5.678f); // constant argument is passed by value (even though declaration is by ref: const & results in by-value in this case), memory will be allocated and managed for the copy. + float valc = tc.Get(); + + scprintf(_T("Valc is: %f\n"),valc); + + float val = 1.234f; + SquirrelObject t(val); // val is passed by reference, memory will be allocated, and the value copied once. + + float val2 = t.Get(); + + scprintf(_T("Val2 is: %f\n"),val2); + + if (1) { + SquirrelObject v(Vector3(1.f,2.f,3.f)); // Pass in by reference: will be copied once, with memory for new copy managed by Squirrel. + + Vector3 * pv = v.Get(); + scprintf(_T("Vector3 is: %f %f %f\n"),pv->x,pv->y,pv->z); + pv->z += 1.f; + + if (1) { + SquirrelObject v2p(pv); // This is a pointer to v's instance (passed in by pointer: see SquirrelObject.h). + // A new Squirrel Instance will be created, but the C++ instance pointer will not get freed when v2p goes out of scope (release hook will be null). + pv = v2p.Get(); + scprintf(_T("Vector3 is: %f %f %f\n"),pv->x,pv->y,pv->z); + } // if + + } // if + + scprintf(_T("Vector3() instance has been released.\n\n")); + +} // testSquirrelObjectSetGet + + +#define SQDBG_DEBUG_HOOK _T("_sqdebughook_") + +class TestSqPlus { +public: + + enum {SQ_ENUM_TEST=1234321}; + + void init(void) { + SquirrelVM::Init(); + HSQUIRRELVM _v = SquirrelVM::GetVMPtr(); + +#if 1 + sq_pushregistrytable(_v); + sq_pushstring(_v,SQDBG_DEBUG_HOOK,-1); + sq_pushuserpointer(_v,this); + sq_newclosure(_v,debug_hook,1); + sq_createslot(_v,-3); +// sq_pop(_v,1); + +// sq_pushregistrytable(_v); + sq_pushstring(_v,SQDBG_DEBUG_HOOK,-1); + sq_rawget(_v,-2); + sq_setdebughook(_v); + sq_pop(_v,1); + +#endif + + sq_enabledebuginfo(_v,SQTrue); + + } // init + + TestSqPlus() { + init(); + + testPureVirtualInterface(); + + testScriptingTypeName(); + + try { + HSQUIRRELVM v = SquirrelVM::GetVMPtr(); + SquirrelObject root = SquirrelVM::GetRootTable(); + + testPointfBoxf(); + + // Example from forum question: + testScripts.InitScript1(); + testScripts.InitScript2(); + SquirrelObject testScriptBinding = SquirrelVM::CompileBuffer(_T("\ + local testScripts = STestScripts(); \n\ + testScripts.Test1(); \n\ + testScripts.Test2(); \n\ + print(testScripts.Var_ToBind2); \n\ + Test1(); \n\ + Test2(); \n\ + print(Var_ToBind1); \n\ + ")); + SquirrelVM::RunScript(testScriptBinding); + + // === BEGIN Global Function binding tests === + + // Implemented as SquirrelVM::CreateFunction(rootTable,func,name,typeMask). CreateFunctionGlobal() binds a standard SQFUNCTION (stack args). + SquirrelVM::CreateFunctionGlobal(testFunc,_T("testFunc0")); + SquirrelVM::CreateFunctionGlobal(testFunc,_T("testFuncN"),_T("n")); + SquirrelVM::CreateFunctionGlobal(testFunc,_T("testFuncS"),_T("s")); +#if 0 + SquirrelObject testStandardFuncs = SquirrelVM::CompileBuffer(_T(" testFunc0(); testFuncN(1.); testFuncS(\"Hello\"); ")); + SquirrelVM::RunScript(testStandardFuncs); +#endif + // === Register Standard Functions using template system (function will be directly called with argument auto-marshaling) === + + RegisterGlobal(v,newtest,_T("test")); + RegisterGlobal(v,newtestR1,_T("testR1")); + + // === Register Member Functions to existing classes (as opposed to instances of classes) === + + NewTestObj t1,t2,t3; + t1.val = 123; + t2.val = 456; + t3.val = 789; + RegisterGlobal(v,t1,&NewTestObj::newtest,_T("testObj_newtest1")); + RegisterGlobal(v,t2,&NewTestObj::newtest,_T("testObj_newtest2")); // Register newtest() again with different name and object pointer. + SquirrelObject tr = SquirrelVM::GetRootTable(); // Can be any object supporting closures (functions). + Register(v,tr.GetObjectHandle(),t3,&NewTestObj::newtestR1,_T("testObj_newtestR1")); // Return value version. + + // === END Global Function binding tests === + + // === BEGIN Namespace examples === + + // Create a namespace using a table. + SquirrelObject nameSpaceTable = SquirrelVM::CreateTable(); + root.SetValue(_T("Namespace1"),nameSpaceTable); + Register(v,nameSpaceTable.GetObjectHandle(),globalFunc,_T("namespaceFunc")); + + // Create a namespace using a class. If an instance is created from the class, using the instance will prevent accidental changes to the instance members. + // Using the class/instance form also allows extra information to be added to the proxy class, if desired (such as vars/funcs). + // NOTE: If any variables/static-variables/constants are registered to the class, it must be instantiated before use. + SQClassDef(_T("Namespace2")). + staticFunc(globalFunc,_T("namespaceFunc")); + + SquirrelObject testNameSpace = SquirrelVM::CompileBuffer(_T("\ + Namespace1.namespaceFunc(\"Hello Namespace1 (table),\",321); \n\ + Namespace2.namespaceFunc(\"Hello Namespace2 (class),\",654); \n\ + local Namespace3 = Namespace2(); \n\ + Namespace3.namespaceFunc(\"Hello Namespace3 (instance),\",987); \n\ + ")); + + SquirrelVM::RunScript(testNameSpace); + + // === END Namespace examples === + + // === BEGIN Class Instance tests === + + // Example showing two methods for registration. +#if 0 + SQClassDef sqClass(_T("NewTestObj")); + sqClass.func(NewTestObj::newtestR1,_T("newtestR1")); + sqClass.var(&NewTestObj::val,_T("val")); + sqClass.var(&NewTestObj::s1,_T("s1")); + sqClass.var(&NewTestObj::s2,_T("s2")); + sqClass.var(&NewTestObj::c1,_T("c1"),VAR_ACCESS_READ_ONLY); + sqClass.var(&NewTestObj::c2,_T("c2"),VAR_ACCESS_READ_ONLY); + sqClass.funcVarArgs(NewTestObj::multiArgs,_T("multiArgs")); +#else + SQClassDef(_T("NewTestObj")). // If a special constructor+destructor are not needed, the auto-generated versions can be used. + // Example methods for custom constructors: + staticFuncVarArgs(constructNewTestObj,_T("constructor"),_T("*")). // Using a global constructor: useful in cases where a custom constructor/destructor are required and the original class is not to be modified. +// staticFunc(constructNewTestObjFixedArgs,_T("constructor")). // Using a global constructor: useful in cases where a custom constructor/destructor are required and the original class is not to be modified. +// staticFuncVarArgs(NewTestObj::construct,_T("constructor")). // Using a static member constructor. + staticFunc(globalFunc,_T("globalFunc")). // Any global function can be registered in a class namespace (no 'this' pointer will be passed to the function). + staticFunc(globalClass,&GlobalClass::func,_T("globalClassFunc")). + func(&NewTestObj::newtestR1,_T("newtestR1")). + var(&NewTestObj::val,_T("val")). + var(&NewTestObj::s1,_T("s1")). + var(&NewTestObj::s2,_T("s2")). + var(&NewTestObj::c1,_T("c1"),VAR_ACCESS_READ_ONLY). + var(&NewTestObj::c2,_T("c2"),VAR_ACCESS_READ_ONLY). + funcVarArgs(&NewTestObj::multiArgs,_T("multiArgs")); + +#define SQ_10 10 +#define SQ_E 2.71828182845904523536f +#define SQ_PI 3.14159265358979323846264338327950288f +#define SQ_CONST_STRING _T("A constant string") + const int intConstant = 7; + const float floatConstant = 8.765f; + const bool boolConstant = true; +#if 1 + SQClassDef(_T("Vector3")). + var(&Vector3::x,_T("x")). + var(&Vector3::y,_T("y")). + var(&Vector3::z,_T("z")). + func(&Vector3::Inc,_T("Inc")). + func(&Vector3::operator+,_T("_add")). + staticFunc(&Add2,_T("Add2")). + staticFuncVarArgs(&Add,_T("Add")). +#if 1 + staticVar(&Vector3::staticVar,_T("staticVar")). +#else + staticVar(&Vector3::staticVar,_T("staticVar"),VAR_ACCESS_READ_ONLY). +#endif + staticVar(&globalVar,_T("globalVar")). + constant(SQ_10,_T("SQ_10")). + constant(SQ_E,_T("SQ_E")). + constant(SQ_PI,_T("SQ_PI")). + constant(SQ_CONST_STRING,_T("SQ_CONST_STRING")). + enumInt(SQ_ENUM_TEST,_T("SQ_ENUM_TEST")). + constant(intConstant,_T("intConstant")). + constant(floatConstant,_T("floatConstant")). + constant(true,_T("boolTrue")). + constant(false,_T("boolFalse")). + constant(boolConstant,_T("boolConstant")); +#endif + +#endif + + testSquirrelObjectSetGet(); // Uses Vector3(). + + BindConstant(SQ_PI*2,_T("SQ_PI_2")); + BindConstant(SQ_10*2,_T("SQ_10_2")); + BindConstant(_T("Global String"),_T("GLOBAL_STRING")); + + SquirrelObject testStaticVars = SquirrelVM::CompileBuffer(_T(" local v = Vector3(); local v2 = Vector3(); local v3 = v+v2; v3 += v2; print(\"v3.x: \"+v3.x); print(\"Vector3::staticVar: \"+v.staticVar+\" Vector3::globalVar: \"+v.globalVar); v.staticVar = 0; ")); + SquirrelVM::RunScript(testStaticVars); + + SquirrelObject testConstants0 = SquirrelVM::CompileBuffer(_T(" print(\"SQ_PI*2: \"+SQ_PI_2+\" SQ_10_2: \"+SQ_10_2+\" GLOBAL_STRING: \"+GLOBAL_STRING); ")); + SquirrelVM::RunScript(testConstants0); + + SquirrelObject testConstants1 = SquirrelVM::CompileBuffer(_T("local v = Vector3(); print(\"SQ_10: \"+v.SQ_10+\" SQ_E: \"+v.SQ_E+\" SQ_PI: \"+v.SQ_PI+\" SQ_CONST_STRING: \"+v.SQ_CONST_STRING+\" SQ_ENUM_TEST: \"+v.SQ_ENUM_TEST);" )); + SquirrelVM::RunScript(testConstants1); + SquirrelObject testConstants2 = SquirrelVM::CompileBuffer(_T("local v = Vector3(); print(\"intConstant: \"+v.intConstant+\" floatConstant: \"+v.floatConstant+\" boolTrue: \"+(v.boolTrue?\"True\":\"False\")+\" boolFalse: \"+(v.boolFalse?\"True\":\"False\")+\" boolConstant: \"+(v.boolConstant?\"True\":\"False\"));" )); + SquirrelVM::RunScript(testConstants2); + + SquirrelObject scriptedBase = SquirrelVM::CompileBuffer(_T(" class ScriptedBase { sbval = 5551212; function multiArgs(a,...) { print(\"SBase: \"+a+val); } \n } \n ")); // Note val does not exist in base. + SquirrelVM::RunScript(scriptedBase); + + // === BEGIN Instance Test === + + SQClassDef(_T("PlayerManager::Player")). + func(&PlayerManager::Player::printName,_T("printName")). + var(&PlayerManager::Player::name,_T("name")); + + SQClassDef(_T("PlayerManager")). + func(&PlayerManager::GetPlayer,_T("GetPlayer")). + var(&PlayerManager::playerVar,_T("playerVar")); + + RegisterGlobal(getPlayerManager,_T("getPlayerManager")); + BindVariable(&playerManager,_T("playerManagerVar")); + + SquirrelObject testGetInstance = SquirrelVM::CompileBuffer(_T("\ + local PlayerManager = getPlayerManager(); \n\ + local oPlayer = PlayerManager.GetPlayer(0); \n\ + print(typeof oPlayer); \n\ + oPlayer.printName(); \n\ + PlayerManager.playerVar.printName(); \n\ + print(PlayerManager.playerVar.name); \n\ + oPlayer = PlayerManager.playerVar; \n\ + oPlayer.name = \"New_Name1\"; \n\ + playerManagerVar.playerVar.printName(); \n\ + oPlayer.name = \"New_Name2\"; \n\ + ")); + SquirrelVM::RunScript(testGetInstance); + scprintf(_T("playerManager.playerVar.name: %s\n"),playerManager.playerVar.name.s); + + // === END Instance Test === + + // === BEGIN example from forum post === + + SQClassDef(_T("Creature")). + func(&Creature::GetMaxHealth,_T("GetMaxHealth")). + func(&Creature::GetHealth,_T("GetHealth")). + func(&Creature::SetHealth,_T("SetHealth")); + + SquirrelObject testClass = SquirrelVM::CompileBuffer( _T("function HealthPotionUse(Target) { \n\ + local curHealth = Target.GetHealth(); \n\ + local maxHealth = Target.GetMaxHealth(); \n\ + if ((maxHealth - curHealth) > 15) { \n\ + curHealth += 15; \n\ + } else { \n\ + curHealth = maxHealth; \n\ + } \n\ + Target.SetHealth(curHealth); \n\ + print(typeof Target); \n\ + return Target; \n\ + }")); + Creature frodo; + frodo.SetHealth(frodo.GetMaxHealth()/2); + + SquirrelVM::RunScript(testClass); + + Creature newFrodo = SquirrelFunction(_T("HealthPotionUse"))(frodo); // Pass by value and return a copy (Must return by reference due to template system design). + SquirrelFunction(_T("HealthPotionUse"))(&frodo); // Pass the address to directly modify frodo. + scprintf(_T("Frodo's health: %d %d\n"),frodo.GetHealth(),newFrodo.GetHealth()); + + // === END example from forum post === + +#ifdef SQ_USE_CLASS_INHERITANCE + // Base class constructors, if registered, must use this form: static int construct(HSQUIRRELVM v). +// SQClassDef customClass(_T("CustomTestObj")); + SQClassDef customClass(_T("CustomTestObj"),_T("ScriptedBase")); +// SQClassDef customClass(_T("CustomTestObj"),_T("NewTestObj")); + customClass.staticFuncVarArgs(&CustomTestObj::construct,_T("constructor"),_T("*")); // MUST use this form (or no args) if CustomTestObj will be used as a base class. + // Using the "*" form will allow a single constructor to be used for all cases. +// customClass.staticFuncVarArgs(CustomTestObj::construct,_T("constructor")); // (this form is also OK if used as a base class) + customClass.funcVarArgs(&CustomTestObj::varArgTypesAndCount,_T("multiArgs"),_T("*")); // "*": no type or count checking. + customClass.funcVarArgs(&CustomTestObj::varArgTypesAndCount,_T("varArgTypesAndCount"),_T("*")); // "*": no type or count checking. +#else + SQClassDef customClass(_T("CustomTestObj")); + customClass.staticFuncVarArgs(&CustomTestObj::construct,_T("constructor"),_T("snb")); // string, number, bool (all types must match). + customClass.funcVarArgs(&CustomTestObj::varArgTypesAndCount,_T("varArgTypesAndCount"),_T("*")); // "*": no type or count checking. +#endif + customClass.funcVarArgs(&CustomTestObj::varArgTypes,_T("varArgTypes"),_T("s|ns|ns|ns|n")); // string or number + string or number. + customClass.funcVarArgs(&CustomTestObj::noArgsVariableReturn,_T("noArgsVariableReturn")); // No type string means no arguments allowed. + customClass.func(&CustomTestObj::variableArgsFixedReturnType,_T("variableArgsFixedReturnType")); // Variables args, fixed return type. + customClass.func(&CustomTestObj::manyArgs,_T("manyArgs")); // Many args, type checked. + customClass.func(&CustomTestObj::manyArgsR1,_T("manyArgsR1")); // Many args, type checked, one return value. + +#ifdef SQ_USE_CLASS_INHERITANCE +// SquirrelObject testInheritance = SquirrelVM::CompileBuffer(_T(" class Derived extends NewTestObj { s1 = 123; \n constructor() { NewTestObj.constructor(this); }; function getParentS2() return s2; \n }; \n local t = Derived(); \n print(\"DerS2: \"+t.getParentS2()); t.multiArgs(); //t.newtestR1(\"R1in\"); ")); +// SquirrelObject testInheritance = SquirrelVM::CompileBuffer(_T(" local t = CustomTestObj(\"sa\",321,true); \n t.val = 444; print(t.val); t.variableArgsFixedReturnType(4,5.5); t.multiArgs(1,2,3); t.newtestR1(\"R1in\"); ")); +// SquirrelObject testInheritance = SquirrelVM::CompileBuffer(_T(" class Derived extends CustomTestObj { val = 888; \n function func(a) print(a+dVal);\n } \n local x = Derived(); print(\"x.val \"+x.val); local t = CustomTestObj(\"sa\",321,true); \n t.val = 444; print(t.val); t.variableArgsFixedReturnType(4,5.5); t.multiArgs(1,2,3); t.newtestR1(\"R1in\"); ")); + SquirrelObject testInheritance = SquirrelVM::CompileBuffer(_T(" class Derived extends CustomTestObj { val = 888; \n function multiArgs(a,...) { print(a+val); \n print(sbval); ::CustomTestObj.multiArgs(4); ::ScriptedBase.multiArgs(5,6,7); \n }\n } \n local x = Derived(); print(\"x.val \"+x.val); x.multiArgs(1,2,3); ")); +// SquirrelObject testInheritance = SquirrelVM::CompileBuffer(_T(" class Derived extends CustomTestObj { val = 888; \n function multiArgs(a,...) print(a+val);\n } \n local x = Derived(); print(\"x.val \"+x.val); x.multiArgs(1,2,3); //local t = CustomTestObj(); \n t.val = 444; print(t.val); t.variableArgsFixedReturnType(4,5.5); t.multiArgs(1,2,3); t.newtestR1(\"R1in\"); ")); + printf("=== BEGIN INHERITANCE ===\n"); + testInhertianceCase(); + SquirrelVM::RunScript(testInheritance); + printf("=== END INHERITANCE ===\n"); +#endif + + SquirrelObject testRegV = SquirrelVM::CompileBuffer(_T(" local vec = Vector3(); print(vec.x); vec = vec.Add(vec); print(vec.x); vec = vec.Add(vec); print(vec.x); vec = vec.Add2(vec,vec); print(vec.x); local v2 = Vector3(); vec = v2.Inc(vec); print(vec.x); print(v2.x); ")); + SquirrelVM::RunScript(testRegV); + + +#ifdef SQ_USE_CLASS_INHERITANCE + SquirrelObject testReg0 = SquirrelVM::CompileBuffer(_T(" co <- CustomTestObj(\"hello\",123,true); co.varArgTypes(\"str\",123,123,\"str\"); co.varArgTypes(123,\"str\",\"str\",123); ")); + SquirrelVM::RunScript(testReg0); + + SquirrelObject testReg0a = SquirrelVM::CompileBuffer(_T(" print(co.varArgTypesAndCount(1,true)); print(co.varArgTypesAndCount(2,false,3.)); print(\"\\n\"); ")); + SquirrelVM::RunScript(testReg0a); + + SquirrelObject testReg0b = SquirrelVM::CompileBuffer(_T(" print(co.noArgsVariableReturn()); print(co.noArgsVariableReturn()); print(co.noArgsVariableReturn()); print(\"\\n\"); ")); + SquirrelVM::RunScript(testReg0b); + + SquirrelObject testReg0c = SquirrelVM::CompileBuffer(_T(" print(co.variableArgsFixedReturnType(1)); print(co.variableArgsFixedReturnType(1,2)); print(co.variableArgsFixedReturnType(1,2,3)); print(\"\\n\"); ")); + SquirrelVM::RunScript(testReg0c); + + SquirrelObject testReg0d = SquirrelVM::CompileBuffer(_T(" co.manyArgs(111,222.2,true,\"Hello\"); print(co.manyArgsR1(333,444.3,false,\"World\")); print(\"\\n\"); ")); + SquirrelVM::RunScript(testReg0d); + + SquirrelObject testReg1a = SquirrelVM::CompileBuffer(_T(" co <- CustomTestObj(\"hello\",123,true); co.noArgsVariableReturn(); local t = NewTestObj(\"S1in\",369,true); print(\"C1: \"+t.c1); print(\"C2: \"+t.c2); // t.c1 = 123; ")); + SquirrelVM::RunScript(testReg1a); + + // Constant test (read only var). Var can change on C++ side, but not on script side. + try { + SquirrelObject testRegConstant = SquirrelVM::CompileBuffer(_T(" local t = NewTestObj(); t.c1 = 123; ")); + SquirrelVM::RunScript(testRegConstant); + } // try + catch (SquirrelError & e) { + scprintf(_T("Error: %s, %s\n"),e.desc,_T("Squirrel::TestConstant")); + } // catch + + SquirrelObject testReg1 = SquirrelVM::CompileBuffer(_T(" local t = NewTestObj(); t.newtestR1(\"Hello\"); t.val = 789; print(t.val); print(t.s1); print(t.s2); t.s1 = \"New S1\"; print(t.s1); ")); + SquirrelVM::RunScript(testReg1); + + SquirrelObject testReg2 = SquirrelVM::CompileBuffer(_T(" local t = NewTestObj(); t.val = 789; print(t.val); t.val = 876; print(t.val); t.multiArgs(1,2,3); t.multiArgs(1,2,3,4); t.globalFunc(\"Hola\",5150,false); t.globalClassFunc(\"Bueno\",5151,true); ")); + SquirrelVM::RunScript(testReg2); + SquirrelObject testReg3 = SquirrelVM::CompileBuffer(_T(" test(); local rv = testR1(\"Hello\"); print(rv); ")); + SquirrelVM::RunScript(testReg3); + SquirrelObject testReg4 = SquirrelVM::CompileBuffer(_T(" print(\"\\nMembers:\"); testObj_newtest1(); testObj_newtest2(); print(testObj_newtestR1(\"Hello Again\")); ")); + SquirrelVM::RunScript(testReg4); + + SquirrelObject defCallFunc = SquirrelVM::CompileBuffer(_T(" function callMe(var) { print(\"I was called by: \"+var); return 123; }")); + SquirrelVM::RunScript(defCallFunc); + + SquirrelObject defCallFuncStrRet = SquirrelVM::CompileBuffer(_T(" function callMeStrRet(var) { print(\"I was called by: \"+var); return var; }")); + SquirrelVM::RunScript(defCallFuncStrRet); + + SquirrelFunction(_T("callMe"))(_T("Squirrel 1")); + + // Get a function from the root table and call it. +#if 1 + SquirrelFunction callFunc(_T("callMe")); + int ival = callFunc(_T("Squirrel")); + scprintf(_T("IVal: %d\n"),ival); + + SquirrelFunction callFuncStrRet(_T("callMeStrRet")); + const SQChar * sval = callFuncStrRet(_T("Squirrel StrRet")); + scprintf(_T("SVal: %s\n"),sval); +#endif + ival = 0; + // Get a function from any table. + SquirrelFunction callFunc2(root.GetObjectHandle(),_T("callMe")); + ival = callFunc(456); // Argument count is checked; type is not. + + // === END Class Instance tests === + + SquirrelObject main = SquirrelVM::CompileBuffer(_T("table1 <- {key1=\"keyVal\",key2 = 123};\n if (\"key1\" in table1)\n print(\"Sq: Found it\");\n else\n print(\"Sq: Not found\");")); + SquirrelVM::RunScript(main); + SquirrelObject table1 = root.GetValue(_T("table1")); + if (table1.Exists(_T("key1"))) { + scprintf(_T("C++: Found it.\n")); + } else { + scprintf(_T("C++: Did not find it.\n")); + } // if + + // === BEGIN Simple variable binding tests === + + int iVar = 777; + float fVar = 88.99f; + bool bVar = true; + BindVariable(root,&iVar,_T("iVar")); + BindVariable(root,&fVar,_T("fVar")); + BindVariable(root,&bVar,_T("bVar")); + + static ScriptStringVar128 testString; + scsprintf(testString,_T("This is a test string")); + BindVariable(root,&testString,_T("testString")); + + // === END Simple variable binding tests === + + // === BEGIN Array Tests === + + SquirrelObject array = SquirrelVM::CreateArray(10); + int i; + for (i = 0; i < 10; i++) array.SetValue(i,i); + array.ArrayAppend(123); // int + array.ArrayAppend(true); // bool (must use bool and not SQBool (SQBool is treated as INT by compiler). + array.ArrayAppend(false); // bool (must use bool and not SQBool (SQBool is treated as INT by compiler). + array.ArrayAppend(123.456f); // float + array.ArrayAppend(_T("string")); // string + array.ArrayAppend(456); // Will be popped and thrown away (below). + array.ArrayAppend((SQUserPointer)0); + + // Pop 3 items from array: + array.ArrayPop(SQFalse); // Don't retrieve the popped value (int:123). + SquirrelObject so1 = array.ArrayPop(); // Retrieve the popped value. + const SQChar * val1 = so1.ToString(); // Get string. + float val2 = array.ArrayPop().ToFloat(); // Pop and get float. + scprintf(_T("[Popped values] Val1: %s, Val2: %f\n"),val1,val2); + + int startIndex = array.Len(); + array.ArrayExtend(10); // Implemented as: ArrayResize(Len()+amount). + for (i = startIndex; i < array.Len(); i++) array.SetValue(i,i*10); + root.SetValue(_T("array"),array); + + SquirrelObject arrayr = array.Clone(); // Get a copy as opposed to another reference. + arrayr.ArrayReverse(); + root.SetValue(_T("arrayr"),arrayr); + + // === END Array Tests === + + SquirrelObject define_printArray = SquirrelVM::CompileBuffer(_T(" function printArray(name,array) { print(name+\".len() = \"+array.len()); foreach(i, v in array) if (v != null) { if (typeof v == \"bool\") v = v ? \"true\" : \"false\"; print(\"[\"+i+\"]: \"+v); } } ")); + SquirrelVM::RunScript(define_printArray); + SquirrelObject test = SquirrelVM::CompileBuffer(_T(" printArray(\"array\",array); printArray(\"arrayr\",arrayr); ")); + + SquirrelVM::RunScript(test); +#endif + } // try + catch (SquirrelError & e) { + scprintf(_T("Error: %s, in %s\n"),e.desc,_T("TestSqPlus")); + } // catch + + } + + ~TestSqPlus() { + SquirrelVM::Shutdown(); + } + +}; + +void doTest(void) { + TestSqPlus testSqPlus; +} // doTest + +int main(int argc,char * argv[]) { + + // Run twice to make sure cleanup/shutdown works OK. + SCPUTS(_T("Start Pass 1\n")); + doTest(); +#if 0 + SCPUTS(_T("Start Pass 2\n")); + doTest(); +#endif + SCPUTS(_T("Done.\n")); + + scprintf(_T("Press RETURN to exit.")); + getchar(); + + return 0; +} + diff --git a/vscript/languages/squirrel/testSqPlus2/testSqPlus2.vcproj b/vscript/languages/squirrel/testSqPlus2/testSqPlus2.vcproj new file mode 100644 index 00000000..0320a545 --- /dev/null +++ b/vscript/languages/squirrel/testSqPlus2/testSqPlus2.vcproj @@ -0,0 +1,351 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/testSqPlus2/testSqPlus271.vcproj b/vscript/languages/squirrel/testSqPlus2/testSqPlus271.vcproj new file mode 100644 index 00000000..7bf91e26 --- /dev/null +++ b/vscript/languages/squirrel/testSqPlus2/testSqPlus271.vcproj @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vscript/languages/squirrel/vsquirrel/init.nut b/vscript/languages/squirrel/vsquirrel/init.nut new file mode 100644 index 00000000..219cf579 --- /dev/null +++ b/vscript/languages/squirrel/vsquirrel/init.nut @@ -0,0 +1,655 @@ +//=== ======= Copyright © 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: Script initially run after squirrel VM is initialized +// +//============================================================================= + +//----------------------------------------------------------------------------- +// General +//----------------------------------------------------------------------------- + +function printl( text ) +{ + return print( text + "\n" ); +} + +function Msg( text ) +{ + return print( text ); +} + +function Assert( b, msg = null ) +{ + if ( b ) + return; + + if ( msg != null ) + { + throw "Assertion failed: " + msg; + } + else + { + throw "Assertion failed"; + } +} + +//----------------------------------------------------------------------------- +// Documentation table +//----------------------------------------------------------------------------- + +if ( developer() > 0 ) +{ + Documentation <- + { + classes = {} + functions = {} + instances = {} + } + + + function RetrieveNativeSignature( nativeFunction ) + { + if ( nativeFunction in NativeFunctionSignatures ) + { + return NativeFunctionSignatures[nativeFunction] + } + return "" + } + + function RegisterFunctionDocumentation( func, name, signature, description ) + { + if ( description.len() ) + { + local b = ( description[0] == '#' ); + if ( description[0] == '#' ) + { + local colon = description.find( ":" ); + if ( colon == null ) + { + colon = description.len(); + } + local alias = description.slice( 1, colon ); + description = description.slice( colon + 1 ); + name = alias; + signature = "#"; + } + } + Documentation.functions[name] <- [ signature, description ] + } + + function Document( symbolOrTable, itemIfSymbol = null, descriptionIfSymbol = null ) + { + if ( typeof( symbolOrTable ) == "table" ) + { + foreach( symbol, itemDescription in symbolOrTable ) + { + Assert( typeof(symbol) == "string" ) + + Document( symbol, itemDescription[0], itemDescription[1] ); + } + } + else + { + printl( symbolOrTable + ":" + itemIfSymbol.tostring() + "/" + descriptionIfSymbol ); + } + } + + function PrintHelp( string = "*", exact = false ) + { + local matches = [] + + if ( string == "*" || !exact ) + { + foreach( name, documentation in Documentation.functions ) + { + if ( string != "*" && name.tolower().find( string.tolower() ) == null ) + { + continue; + } + + matches.append( name ); + } + } + else if ( exact ) + { + if ( string in Documentation.functions ) + matches.append( string ) + } + + if ( matches.len() == 0 ) + { + printl( "Symbol " + string + " not found" ); + return; + } + + matches.sort(); + + foreach( name in matches ) + { + local result = name; + local documentation = Documentation.functions[name]; + + printl( "Function: " + name ); + local signature; + if ( documentation[0] != "#" ) + { + signature = documentation[0]; + } + else + { + signature = GetFunctionSignature( this[name], name ); + } + + printl( "Signature: " + signature ); + if ( documentation[1].len() ) + printl( "Description: " + documentation[1] ); + print( "\n" ); + } + } +} +else +{ + function RetrieveNativeSignature( nativeFunction ) { return ""; } + function Document( symbolOrTable, itemIfSymbol = null, descriptionIfSymbol = null ) {} + function PrintHelp( string = "*", exact = false ) {} +} + +//----------------------------------------------------------------------------- +// VSquirrel support functions +//----------------------------------------------------------------------------- + +function VSquirrel_OnCreateScope( name, outer ) +{ + local result; + if ( !(name in outer) ) + { + result = outer[name] <- { __vname=name, __vrefs = 1 }; + delegate outer : result; + } + else + { + result = outer[name]; + result.__vrefs += 1; + } + return result; +} + +function VSquirrel_OnReleaseScope( scope ) +{ + scope.__vrefs -= 1; + if ( scope.__vrefs < 0 ) + { + throw "Bad reference counting on scope " + scope.__vname; + } + else if ( scope.__vrefs == 0 ) + { + delete scope.parent[scope.__vname]; + scope.__vname = null; + delegate null : scope; + } +} + + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +class CCallChainer +{ + constructor( prefixString, scopeForThis = null ) + { + prefix = prefixString; + if ( scopeForThis != null ) + scope = scopeForThis; + else + scope = ::getroottable(); + chains = {}; + + // Expose a bound global function to dispatch to this object + scope[ "Dispatch" + prefixString ] <- Call.bindenv( this ); + } + + function PostScriptExecute() + { + foreach( key, value in scope ) + { + if ( typeof( value ) == "function" ) + { + if ( key.find( prefix ) == 0 ) + { + key = key.slice( prefix.len() ); + + if ( !(key in chains) ) + { + //::print( "Creating new call chain " + key + "\n"); + chains[key] <- []; + } + + local chain = chains[key]; + + if ( !chain.len() || chain.top() != value ) + { + chain.push( value ); + //::print( "Added " + value + " to call chain " + key + "\n" ); + } + } + } + } + } + + function Call( event, ... ) + { + if ( event in chains ) + { + local chain = chains[event]; + if ( chain.len() ) + { + local i; + local args = []; + if ( vargc > 0 ) + { + args.push( scope ); + for ( i = 0; i < vargc; i++ ) + { + args.push( vargv[i] ); + } + } + for ( i = chain.len() - 1; i >= 0; i -= 1 ) + { + local func = chain[i]; + local result; + if ( !args.len() ) + { + result = func(); + } + else + { + result = func.acall( args ); + } + if ( result != null && !result ) + return false; + } + } + } + + return true; + } + + scope = null; + prefix = null; + chains = null; +}; + + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +class CSimpleCallChainer +{ + constructor( prefixString, scopeForThis = null, exactNameMatch = false ) + { + prefix = prefixString; + if ( scopeForThis != null ) + scope = scopeForThis; + else + scope = ::getroottable(); + chain = []; + + // Expose a bound global function to dispatch to this object + scope[ "Dispatch" + prefixString ] <- Call.bindenv( this ); + + exactMatch = exactNameMatch + } + + function PostScriptExecute() + { + foreach( key, value in scope ) + { + if ( typeof( value ) == "function" ) + { + local foundMatch = false; + if ( exactMatch ) + { + foundMatch = ( prefix == key ); + } + else + { + foundMatch = ( key.find( prefix ) == 0 ) + } + + if ( foundMatch ) + { + if ( !exactMatch ) + key = key.slice( prefix.len() ); + + if ( !(chain) ) + { + //::print( "Creating new call simple chain\n"); + chain <- []; + } + + if ( !chain.len() || chain != value ) + { + chain.push( value ); + //::print( "Added " + value + " to call chain.\n" ); + } + } + } + } + } + + function Call( ... ) + { + if ( chain.len() ) + { + local i; + local args = []; + if ( vargc > 0 ) + { + args.push( scope ); + for ( i = 0; i < vargc; i++ ) + { + args.push( vargv[i] ); + } + } + for ( i = chain.len() - 1; i >= 0; i -= 1 ) + { + local func = chain[i]; + local result; + if ( !args.len() ) + { + result = func.pcall( scope ); + } + else + { + result = func.pacall( scope, args ); + } + if ( result != null && !result ) + return false; + } + } + + return true; + } + + exactMatch = false + scope = null; + prefix = null; + chain = null; +}; + +//----------------------------------------------------------------------------- +// Late binding: allows a table to refer to parts of itself, it's children, +// it's owner, and then have the references fixed up after it's fully parsed +// +// Usage: +// lateBinder <- LateBinder(); +// lateBinder.Begin( this ); +// +// Test1 <- +// { +// Foo=1 +// } +// +// Test2 <- +// { +// FooFoo = "I'm foo foo" +// BarBar="@Test1.Foo" +// SubTable = { boo=[bah, "@Test2.FooFoo", "@Test1.Foo"], booboo2={one=bah, two="@Test2.FooFoo", three="@Test1.Foo"} } +// booboo=[bah, "@Test2.FooFoo", "@Test1.Foo"] +// booboo2={one=bah, two="@Test2.FooFoo", three="@Test1.Foo"} +// bah=wha +// } +// +// lateBinder.End(); +// delete lateBinder; +// +// When End() is called, all of the unresolved symbols in the tables and arrays will be resolved, +// any left unresolved will become a string prepended with '~', which later code can deal with +//----------------------------------------------------------------------------- + +class LateBinder +{ + // public: + function Begin( target, log = false ) + { + m_log = log; + + HookRootMetamethod( "_get", function( key ) { return "^" + key; } ); + HookRootMetamethod( "_newslot", function( key, value ) { if ( typeof value == "table" ) { m_fixupSet.push( [ key, value ] ); this.rawset( key, value ); }; }.bindenv(this) ); + m_targetTable = target; + + Log( "Begin late bind on table " + m_targetTable ); + } + + function End() + { + UnhookRootMetamethod( "_get" ); + UnhookRootMetamethod( "_newslot" ); + + Log( "End late bind on table " + m_targetTable ); + + foreach( subTablePair in m_fixupSet ) + { + EstablishDelegation( m_targetTable, subTablePair[1] ); + } + + Log( "Begin resolution... " ) + m_logIndent++; + + local found = true; + + while ( found ) + { + foreach( subTablePair in m_fixupSet ) + { + Log( subTablePair[0] + " = " ); + Log( "{" ); + if ( !Resolve( subTablePair[1], subTablePair[1], false ) ) + { + found = false; + } + Log( "}" ); + } + } + + m_logIndent--; + + foreach( subTablePair in m_fixupSet ) + { + RemoveDelegation( subTablePair[1] ); + } + + Log( "...end resolution" ); + } + + // private: + function HookRootMetamethod( name, value ) + { + local saved = null; + local roottable = getroottable(); + if ( name in roottable ) + { + saved = roottable[name]; + } + roottable[name] <- value; + roottable["__saved" + name] <- saved; + } + + function UnhookRootMetamethod( name ) + { + local saveSlot = "__saved" + name; + local roottable = getroottable(); + local saved = roottable[saveSlot]; + if ( saved != null ) + { + roottable[name] = saved; + } + else + { + delete roottable[name]; + } + delete roottable[saveSlot]; + } + + function EstablishDelegation( parentTable, childTable ) + { + delegate parentTable : childTable; + + foreach( key, value in childTable ) + { + local type = typeof value; + if ( type == "table" ) + { + EstablishDelegation( childTable, value ); + } + } + } + + function RemoveDelegation( childTable ) + { + delegate null : childTable; + + foreach( key, value in childTable ) + { + local type = typeof value; + if ( type == "table" ) + { + RemoveDelegation( value ); + } + } + } + + function Resolve( lookupTable, subTableOrArray, throwException = false ) + { + m_logIndent++; + local found = false; + + foreach( key, value in subTableOrArray ) + { + local type = typeof value; + if ( type == "string" ) + { + if ( value.len() ) + { + local unresolvedId = null; + local controlChar = value[0] + if ( controlChar == '^' ) + { + found = true; + value = value.slice( 1 ); + if ( value in lookupTable ) + { + subTableOrArray[key] = lookupTable[value]; + Log( key + " = " + lookupTable[value] + " <-- " + value ); + } + else + { + subTableOrArray[key] = "~" + value; + unresolvedId = value; + Log( key + " = \"" + "~" + value + "\" (unresolved)" ); + } + } + else if ( controlChar == '@' ) + { + found = true; + local identifiers = []; + local iLast = 1; + local iNext; + while ( ( iNext = value.find( ".", iLast ) ) != null ) + { + identifiers.push( value.slice( iLast, iNext ) ); + iLast = iNext + 1; + } + identifiers.push( value.slice( iLast ) ); + + local depthSuccess = 0; + local result = lookupTable; + foreach( identifier in identifiers ) + { + if ( identifier in result ) + { + depthSuccess++; + result = result[identifier]; + } + else + { + break; + } + } + if ( depthSuccess == identifiers.len() ) + { + subTableOrArray[key] = result; + Log( key + " = " + result + " <-- " + value ); + } + else + { + subTableOrArray[key] = "~" + value.slice( 1 ); + unresolvedId = value; + Log( key + " = \"" + "~" + value + "\" (unresolved)" ); + } + } + + if ( unresolvedId != null ) + { + if ( throwException ) + { + local exception = "Unresolved symbol: " + bind + " in "; + foreach ( entry in m_bindNamesStack ) + { + exception += entry; + exception += "." + } + exception += unresolvedId; + + throw exception; + } + } + } + } + } + + foreach( key, value in subTableOrArray ) + { + local type = typeof value; + local isTable = ( type == "table" ); + local isArray = ( type == "array" ) + if ( isTable || isArray ) + { + Log( key + " =" ); + Log( isTable ? "{" : "[" ); + + m_bindNamesStack.push( key ); + if ( Resolve( ( isTable ) ? value : lookupTable, value, throwException ) ) + { + found = true; + } + m_bindNamesStack.pop(); + + Log( isTable ? "}" : "]" ); + } + } + m_logIndent--; + return found; + } + + function Log( string ) + { + if ( m_log ) + { + for ( local i = 0; i < m_logIndent; i++ ) + { + print( " " ); + } + + printl( string ); + } + } + + m_targetTable = null; + m_fixupSet = []; + m_bindNamesStack = []; + m_log = false; + m_logIndent = 0; +} + + diff --git a/vscript/languages/squirrel/vsquirrel/init_nut.h b/vscript/languages/squirrel/vsquirrel/init_nut.h new file mode 100644 index 00000000..c0897c1d --- /dev/null +++ b/vscript/languages/squirrel/vsquirrel/init_nut.h @@ -0,0 +1,688 @@ +static unsigned char g_Script_init[] = { + 0x2f,0x2f,0x3d,0x3d,0x3d,0x09,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x20,0x43,0x6f,0x70,0x79,0x72,0x69, + 0x67,0x68,0x74,0x20,0xa9,0x20,0x32,0x30,0x30,0x38,0x2c,0x20,0x56,0x61,0x6c,0x76,0x65,0x20,0x43,0x6f, + 0x72,0x70,0x6f,0x72,0x61,0x74,0x69,0x6f,0x6e,0x2c,0x20,0x41,0x6c,0x6c,0x20,0x72,0x69,0x67,0x68,0x74, + 0x73,0x20,0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x64,0x2e,0x20,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d, + 0x0a,0x2f,0x2f,0x0a,0x2f,0x2f,0x20,0x50,0x75,0x72,0x70,0x6f,0x73,0x65,0x3a,0x20,0x53,0x63,0x72,0x69, + 0x70,0x74,0x20,0x69,0x6e,0x69,0x74,0x69,0x61,0x6c,0x6c,0x79,0x20,0x72,0x75,0x6e,0x20,0x61,0x66,0x74, + 0x65,0x72,0x20,0x73,0x71,0x75,0x69,0x72,0x72,0x65,0x6c,0x20,0x56,0x4d,0x20,0x69,0x73,0x20,0x69,0x6e, + 0x69,0x74,0x69,0x61,0x6c,0x69,0x7a,0x65,0x64,0x0a,0x2f,0x2f,0x0a,0x2f,0x2f,0x3d,0x3d,0x3d,0x3d,0x3d, + 0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d, + 0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d, + 0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d, + 0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x0a,0x0a,0x2f,0x2f,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x0a,0x2f,0x2f,0x20,0x47,0x65,0x6e, + 0x65,0x72,0x61,0x6c,0x0a,0x2f,0x2f,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x0a,0x0a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x70,0x72,0x69,0x6e,0x74, + 0x6c,0x28,0x20,0x74,0x65,0x78,0x74,0x20,0x29,0x0a,0x7b,0x0a,0x09,0x72,0x65,0x74,0x75,0x72,0x6e,0x20, + 0x70,0x72,0x69,0x6e,0x74,0x28,0x20,0x74,0x65,0x78,0x74,0x20,0x2b,0x20,0x22,0x5c,0x6e,0x22,0x20,0x29, + 0x3b,0x0a,0x7d,0x0a,0x0a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x4d,0x73,0x67,0x28,0x20,0x74, + 0x65,0x78,0x74,0x20,0x29,0x0a,0x7b,0x0a,0x09,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x72,0x69,0x6e, + 0x74,0x28,0x20,0x74,0x65,0x78,0x74,0x20,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x66,0x75,0x6e,0x63,0x74,0x69, + 0x6f,0x6e,0x20,0x41,0x73,0x73,0x65,0x72,0x74,0x28,0x20,0x62,0x2c,0x20,0x6d,0x73,0x67,0x20,0x3d,0x20, + 0x6e,0x75,0x6c,0x6c,0x20,0x29,0x0a,0x7b,0x0a,0x09,0x69,0x66,0x20,0x28,0x20,0x62,0x20,0x29,0x0a,0x09, + 0x09,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x09,0x09,0x0a,0x09,0x69,0x66,0x20,0x28,0x20,0x6d,0x73, + 0x67,0x20,0x21,0x3d,0x20,0x6e,0x75,0x6c,0x6c,0x20,0x29,0x0a,0x09,0x7b,0x0a,0x09,0x09,0x74,0x68,0x72, + 0x6f,0x77,0x20,0x22,0x41,0x73,0x73,0x65,0x72,0x74,0x69,0x6f,0x6e,0x20,0x66,0x61,0x69,0x6c,0x65,0x64, + 0x3a,0x20,0x22,0x20,0x2b,0x20,0x6d,0x73,0x67,0x3b,0x0a,0x09,0x7d,0x0a,0x09,0x65,0x6c,0x73,0x65,0x0a, + 0x09,0x7b,0x0a,0x09,0x09,0x74,0x68,0x72,0x6f,0x77,0x20,0x22,0x41,0x73,0x73,0x65,0x72,0x74,0x69,0x6f, + 0x6e,0x20,0x66,0x61,0x69,0x6c,0x65,0x64,0x22,0x3b,0x0a,0x09,0x7d,0x0a,0x7d,0x0a,0x0a,0x2f,0x2f,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x0a,0x2f,0x2f,0x20, + 0x44,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x74,0x61,0x62,0x6c,0x65,0x0a, + 0x2f,0x2f,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x0a, + 0x0a,0x69,0x66,0x20,0x28,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x28,0x29,0x20,0x3e,0x20, + 0x30,0x20,0x29,0x0a,0x7b,0x0a,0x09,0x44,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e, + 0x20,0x3c,0x2d,0x0a,0x09,0x7b,0x0a,0x09,0x09,0x63,0x6c,0x61,0x73,0x73,0x65,0x73,0x20,0x3d,0x20,0x7b, + 0x7d,0x0a,0x09,0x09,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x73,0x20,0x3d,0x20,0x7b,0x7d,0x0a,0x09, + 0x09,0x69,0x6e,0x73,0x74,0x61,0x6e,0x63,0x65,0x73,0x20,0x3d,0x20,0x7b,0x7d,0x0a,0x09,0x7d,0x0a,0x0a, + 0x0a,0x09,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x52,0x65,0x74,0x72,0x69,0x65,0x76,0x65,0x4e, + 0x61,0x74,0x69,0x76,0x65,0x53,0x69,0x67,0x6e,0x61,0x74,0x75,0x72,0x65,0x28,0x20,0x6e,0x61,0x74,0x69, + 0x76,0x65,0x46,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x29,0x0a,0x09,0x7b,0x0a,0x09,0x09,0x69,0x66, + 0x20,0x28,0x20,0x6e,0x61,0x74,0x69,0x76,0x65,0x46,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x69,0x6e, + 0x20,0x4e,0x61,0x74,0x69,0x76,0x65,0x46,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x53,0x69,0x67,0x6e,0x61, + 0x74,0x75,0x72,0x65,0x73,0x20,0x29,0x0a,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x72,0x65,0x74,0x75,0x72, + 0x6e,0x20,0x4e,0x61,0x74,0x69,0x76,0x65,0x46,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x53,0x69,0x67,0x6e, + 0x61,0x74,0x75,0x72,0x65,0x73,0x5b,0x6e,0x61,0x74,0x69,0x76,0x65,0x46,0x75,0x6e,0x63,0x74,0x69,0x6f, + 0x6e,0x5d,0x0a,0x09,0x09,0x7d,0x0a,0x09,0x09,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x22,0x3c,0x75,0x6e, + 0x6e,0x61,0x6d,0x65,0x64,0x3e,0x22,0x0a,0x09,0x7d,0x0a,0x09,0x0a,0x09,0x66,0x75,0x6e,0x63,0x74,0x69, + 0x6f,0x6e,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x46,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x44, + 0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x28,0x20,0x66,0x75,0x6e,0x63,0x2c,0x20, + 0x6e,0x61,0x6d,0x65,0x2c,0x20,0x73,0x69,0x67,0x6e,0x61,0x74,0x75,0x72,0x65,0x2c,0x20,0x64,0x65,0x73, + 0x63,0x72,0x69,0x70,0x74,0x69,0x6f,0x6e,0x20,0x29,0x0a,0x09,0x7b,0x0a,0x09,0x09,0x69,0x66,0x20,0x28, + 0x20,0x64,0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x69,0x6f,0x6e,0x2e,0x6c,0x65,0x6e,0x28,0x29,0x20,0x29, + 0x0a,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x62,0x20,0x3d,0x20,0x28,0x20, + 0x64,0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x69,0x6f,0x6e,0x5b,0x30,0x5d,0x20,0x3d,0x3d,0x20,0x27,0x23, + 0x27,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x64,0x65,0x73,0x63,0x72,0x69,0x70, + 0x74,0x69,0x6f,0x6e,0x5b,0x30,0x5d,0x20,0x3d,0x3d,0x20,0x27,0x23,0x27,0x20,0x29,0x0a,0x09,0x09,0x09, + 0x7b,0x0a,0x09,0x09,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x63,0x6f,0x6c,0x6f,0x6e,0x20,0x3d,0x20, + 0x64,0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x69,0x6f,0x6e,0x2e,0x66,0x69,0x6e,0x64,0x28,0x20,0x22,0x3a, + 0x22,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x63,0x6f,0x6c,0x6f,0x6e,0x20, + 0x3d,0x3d,0x20,0x6e,0x75,0x6c,0x6c,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09, + 0x09,0x63,0x6f,0x6c,0x6f,0x6e,0x20,0x3d,0x20,0x64,0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x69,0x6f,0x6e, + 0x2e,0x6c,0x65,0x6e,0x28,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x6c,0x6f, + 0x63,0x61,0x6c,0x20,0x61,0x6c,0x69,0x61,0x73,0x20,0x3d,0x20,0x64,0x65,0x73,0x63,0x72,0x69,0x70,0x74, + 0x69,0x6f,0x6e,0x2e,0x73,0x6c,0x69,0x63,0x65,0x28,0x20,0x31,0x2c,0x20,0x63,0x6f,0x6c,0x6f,0x6e,0x20, + 0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x64,0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x69,0x6f,0x6e,0x20,0x3d, + 0x20,0x64,0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x69,0x6f,0x6e,0x2e,0x73,0x6c,0x69,0x63,0x65,0x28,0x20, + 0x63,0x6f,0x6c,0x6f,0x6e,0x20,0x2b,0x20,0x31,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x6e,0x61,0x6d, + 0x65,0x20,0x3d,0x20,0x61,0x6c,0x69,0x61,0x73,0x3b,0x0a,0x09,0x09,0x09,0x09,0x73,0x69,0x67,0x6e,0x61, + 0x74,0x75,0x72,0x65,0x20,0x3d,0x20,0x22,0x23,0x22,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x7d, + 0x0a,0x09,0x09,0x44,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x2e,0x66,0x75,0x6e, + 0x63,0x74,0x69,0x6f,0x6e,0x73,0x5b,0x6e,0x61,0x6d,0x65,0x5d,0x20,0x3c,0x2d,0x20,0x5b,0x20,0x73,0x69, + 0x67,0x6e,0x61,0x74,0x75,0x72,0x65,0x2c,0x20,0x64,0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x69,0x6f,0x6e, + 0x20,0x5d,0x0a,0x09,0x7d,0x0a,0x0a,0x09,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x44,0x6f,0x63, + 0x75,0x6d,0x65,0x6e,0x74,0x28,0x20,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x4f,0x72,0x54,0x61,0x62,0x6c,0x65, + 0x2c,0x20,0x69,0x74,0x65,0x6d,0x49,0x66,0x53,0x79,0x6d,0x62,0x6f,0x6c,0x20,0x3d,0x20,0x6e,0x75,0x6c, + 0x6c,0x2c,0x20,0x64,0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x69,0x6f,0x6e,0x49,0x66,0x53,0x79,0x6d,0x62, + 0x6f,0x6c,0x20,0x3d,0x20,0x6e,0x75,0x6c,0x6c,0x20,0x29,0x0a,0x09,0x7b,0x0a,0x09,0x09,0x69,0x66,0x20, + 0x28,0x20,0x74,0x79,0x70,0x65,0x6f,0x66,0x28,0x20,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x4f,0x72,0x54,0x61, + 0x62,0x6c,0x65,0x20,0x29,0x20,0x3d,0x3d,0x20,0x22,0x74,0x61,0x62,0x6c,0x65,0x22,0x20,0x29,0x0a,0x09, + 0x09,0x7b,0x0a,0x09,0x09,0x09,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x28,0x20,0x73,0x79,0x6d,0x62,0x6f, + 0x6c,0x2c,0x20,0x69,0x74,0x65,0x6d,0x44,0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x69,0x6f,0x6e,0x20,0x69, + 0x6e,0x20,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x4f,0x72,0x54,0x61,0x62,0x6c,0x65,0x20,0x29,0x0a,0x09,0x09, + 0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x41,0x73,0x73,0x65,0x72,0x74,0x28,0x20,0x74,0x79,0x70,0x65,0x6f, + 0x66,0x28,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x29,0x20,0x3d,0x3d,0x20,0x22,0x73,0x74,0x72,0x69,0x6e,0x67, + 0x22,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x0a,0x09,0x09,0x09,0x09,0x44,0x6f,0x63,0x75,0x6d,0x65,0x6e, + 0x74,0x28,0x20,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x2c,0x20,0x69,0x74,0x65,0x6d,0x44,0x65,0x73,0x63,0x72, + 0x69,0x70,0x74,0x69,0x6f,0x6e,0x5b,0x30,0x5d,0x2c,0x20,0x69,0x74,0x65,0x6d,0x44,0x65,0x73,0x63,0x72, + 0x69,0x70,0x74,0x69,0x6f,0x6e,0x5b,0x31,0x5d,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09, + 0x7d,0x0a,0x09,0x09,0x65,0x6c,0x73,0x65,0x0a,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x70,0x72,0x69,0x6e, + 0x74,0x6c,0x28,0x20,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x4f,0x72,0x54,0x61,0x62,0x6c,0x65,0x20,0x2b,0x20, + 0x22,0x3a,0x22,0x20,0x2b,0x20,0x69,0x74,0x65,0x6d,0x49,0x66,0x53,0x79,0x6d,0x62,0x6f,0x6c,0x2e,0x74, + 0x6f,0x73,0x74,0x72,0x69,0x6e,0x67,0x28,0x29,0x20,0x2b,0x20,0x22,0x2f,0x22,0x20,0x2b,0x20,0x64,0x65, + 0x73,0x63,0x72,0x69,0x70,0x74,0x69,0x6f,0x6e,0x49,0x66,0x53,0x79,0x6d,0x62,0x6f,0x6c,0x20,0x29,0x3b, + 0x0a,0x09,0x09,0x7d,0x0a,0x09,0x7d,0x0a,0x09,0x0a,0x09,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20, + 0x50,0x72,0x69,0x6e,0x74,0x48,0x65,0x6c,0x70,0x28,0x20,0x73,0x74,0x72,0x69,0x6e,0x67,0x20,0x3d,0x20, + 0x22,0x2a,0x22,0x2c,0x20,0x65,0x78,0x61,0x63,0x74,0x20,0x3d,0x20,0x66,0x61,0x6c,0x73,0x65,0x20,0x29, + 0x0a,0x09,0x7b,0x0a,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x6d,0x61,0x74,0x63,0x68,0x65,0x73,0x20, + 0x3d,0x20,0x5b,0x5d,0x0a,0x09,0x09,0x0a,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x73,0x74,0x72,0x69,0x6e, + 0x67,0x20,0x3d,0x3d,0x20,0x22,0x2a,0x22,0x20,0x7c,0x7c,0x20,0x21,0x65,0x78,0x61,0x63,0x74,0x20,0x29, + 0x0a,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x28,0x20,0x6e,0x61,0x6d, + 0x65,0x2c,0x20,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x69,0x6e,0x20, + 0x44,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x2e,0x66,0x75,0x6e,0x63,0x74,0x69, + 0x6f,0x6e,0x73,0x20,0x29,0x0a,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20, + 0x73,0x74,0x72,0x69,0x6e,0x67,0x20,0x21,0x3d,0x20,0x22,0x2a,0x22,0x20,0x26,0x26,0x20,0x6e,0x61,0x6d, + 0x65,0x2e,0x74,0x6f,0x6c,0x6f,0x77,0x65,0x72,0x28,0x29,0x2e,0x66,0x69,0x6e,0x64,0x28,0x20,0x73,0x74, + 0x72,0x69,0x6e,0x67,0x2e,0x74,0x6f,0x6c,0x6f,0x77,0x65,0x72,0x28,0x29,0x20,0x29,0x20,0x3d,0x3d,0x20, + 0x6e,0x75,0x6c,0x6c,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x63,0x6f, + 0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x0a,0x09, + 0x09,0x09,0x09,0x6d,0x61,0x74,0x63,0x68,0x65,0x73,0x2e,0x61,0x70,0x70,0x65,0x6e,0x64,0x28,0x20,0x6e, + 0x61,0x6d,0x65,0x20,0x29,0x3b,0x20,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x7d,0x20,0x0a,0x09,0x09, + 0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x20,0x65,0x78,0x61,0x63,0x74,0x20,0x29,0x0a,0x09,0x09, + 0x7b,0x0a,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x73,0x74,0x72,0x69,0x6e,0x67,0x20,0x69,0x6e,0x20, + 0x44,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x2e,0x66,0x75,0x6e,0x63,0x74,0x69, + 0x6f,0x6e,0x73,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x6d,0x61,0x74,0x63,0x68,0x65,0x73,0x2e,0x61,0x70, + 0x70,0x65,0x6e,0x64,0x28,0x20,0x73,0x74,0x72,0x69,0x6e,0x67,0x20,0x29,0x0a,0x09,0x09,0x7d,0x0a,0x09, + 0x09,0x0a,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x6d,0x61,0x74,0x63,0x68,0x65,0x73,0x2e,0x6c,0x65,0x6e, + 0x28,0x29,0x20,0x3d,0x3d,0x20,0x30,0x20,0x29,0x0a,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x70,0x72,0x69, + 0x6e,0x74,0x6c,0x28,0x20,0x22,0x53,0x79,0x6d,0x62,0x6f,0x6c,0x20,0x22,0x20,0x2b,0x20,0x73,0x74,0x72, + 0x69,0x6e,0x67,0x20,0x2b,0x20,0x22,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x22,0x20,0x29, + 0x3b,0x0a,0x09,0x09,0x09,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x09,0x09,0x7d,0x0a,0x09,0x09,0x0a, + 0x09,0x09,0x6d,0x61,0x74,0x63,0x68,0x65,0x73,0x2e,0x73,0x6f,0x72,0x74,0x28,0x29,0x3b,0x0a,0x09,0x09, + 0x0a,0x09,0x09,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x28,0x20,0x6e,0x61,0x6d,0x65,0x20,0x69,0x6e,0x20, + 0x6d,0x61,0x74,0x63,0x68,0x65,0x73,0x20,0x29,0x0a,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x6c,0x6f,0x63, + 0x61,0x6c,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x6e,0x61,0x6d,0x65,0x3b,0x0a,0x09,0x09, + 0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e, + 0x20,0x3d,0x20,0x44,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x2e,0x66,0x75,0x6e, + 0x63,0x74,0x69,0x6f,0x6e,0x73,0x5b,0x6e,0x61,0x6d,0x65,0x5d,0x3b,0x0a,0x09,0x09,0x09,0x0a,0x09,0x09, + 0x09,0x70,0x72,0x69,0x6e,0x74,0x6c,0x28,0x20,0x22,0x46,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20, + 0x20,0x20,0x20,0x22,0x20,0x2b,0x20,0x6e,0x61,0x6d,0x65,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x6c,0x6f, + 0x63,0x61,0x6c,0x20,0x73,0x69,0x67,0x6e,0x61,0x74,0x75,0x72,0x65,0x3b,0x0a,0x09,0x09,0x09,0x69,0x66, + 0x20,0x28,0x20,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x5b,0x30,0x5d,0x20, + 0x21,0x3d,0x20,0x22,0x23,0x22,0x20,0x29,0x0a,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x73,0x69, + 0x67,0x6e,0x61,0x74,0x75,0x72,0x65,0x20,0x3d,0x20,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x61,0x74, + 0x69,0x6f,0x6e,0x5b,0x30,0x5d,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x65,0x6c,0x73,0x65, + 0x0a,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x73,0x69,0x67,0x6e,0x61,0x74,0x75,0x72,0x65,0x20, + 0x3d,0x20,0x47,0x65,0x74,0x46,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x53,0x69,0x67,0x6e,0x61,0x74,0x75, + 0x72,0x65,0x28,0x20,0x74,0x68,0x69,0x73,0x5b,0x6e,0x61,0x6d,0x65,0x5d,0x2c,0x20,0x6e,0x61,0x6d,0x65, + 0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x0a,0x09,0x09,0x09,0x70,0x72,0x69,0x6e, + 0x74,0x6c,0x28,0x20,0x22,0x53,0x69,0x67,0x6e,0x61,0x74,0x75,0x72,0x65,0x3a,0x20,0x20,0x20,0x22,0x20, + 0x2b,0x20,0x73,0x69,0x67,0x6e,0x61,0x74,0x75,0x72,0x65,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x69,0x66, + 0x20,0x28,0x20,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x5b,0x31,0x5d,0x2e, + 0x6c,0x65,0x6e,0x28,0x29,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x70,0x72,0x69,0x6e,0x74,0x6c,0x28,0x20, + 0x22,0x44,0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x22,0x20,0x2b,0x20,0x64,0x6f, + 0x63,0x75,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x5b,0x31,0x5d,0x20,0x29,0x3b,0x0a,0x09,0x09, + 0x09,0x70,0x72,0x69,0x6e,0x74,0x28,0x20,0x22,0x5c,0x6e,0x22,0x20,0x29,0x3b,0x20,0x0a,0x09,0x09,0x7d, + 0x0a,0x09,0x7d,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x09,0x66,0x75,0x6e,0x63,0x74,0x69, + 0x6f,0x6e,0x20,0x52,0x65,0x74,0x72,0x69,0x65,0x76,0x65,0x4e,0x61,0x74,0x69,0x76,0x65,0x53,0x69,0x67, + 0x6e,0x61,0x74,0x75,0x72,0x65,0x28,0x20,0x6e,0x61,0x74,0x69,0x76,0x65,0x46,0x75,0x6e,0x63,0x74,0x69, + 0x6f,0x6e,0x20,0x29,0x20,0x7b,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x22,0x3c,0x75,0x6e,0x6e,0x61, + 0x6d,0x65,0x64,0x3e,0x22,0x3b,0x20,0x7d,0x0a,0x09,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x44, + 0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x28,0x20,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x4f,0x72,0x54,0x61,0x62, + 0x6c,0x65,0x2c,0x20,0x69,0x74,0x65,0x6d,0x49,0x66,0x53,0x79,0x6d,0x62,0x6f,0x6c,0x20,0x3d,0x20,0x6e, + 0x75,0x6c,0x6c,0x2c,0x20,0x64,0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x69,0x6f,0x6e,0x49,0x66,0x53,0x79, + 0x6d,0x62,0x6f,0x6c,0x20,0x3d,0x20,0x6e,0x75,0x6c,0x6c,0x20,0x29,0x20,0x7b,0x7d,0x0a,0x09,0x66,0x75, + 0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x50,0x72,0x69,0x6e,0x74,0x48,0x65,0x6c,0x70,0x28,0x20,0x73,0x74, + 0x72,0x69,0x6e,0x67,0x20,0x3d,0x20,0x22,0x2a,0x22,0x2c,0x20,0x65,0x78,0x61,0x63,0x74,0x20,0x3d,0x20, + 0x66,0x61,0x6c,0x73,0x65,0x20,0x29,0x20,0x7b,0x7d,0x0a,0x7d,0x0a,0x0a,0x2f,0x2f,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x0a,0x2f,0x2f,0x20,0x56,0x53,0x71, + 0x75,0x69,0x72,0x72,0x65,0x6c,0x20,0x73,0x75,0x70,0x70,0x6f,0x72,0x74,0x20,0x66,0x75,0x6e,0x63,0x74, + 0x69,0x6f,0x6e,0x73,0x0a,0x2f,0x2f,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x0a,0x0a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x56,0x53,0x71,0x75,0x69, + 0x72,0x72,0x65,0x6c,0x5f,0x4f,0x6e,0x43,0x72,0x65,0x61,0x74,0x65,0x53,0x63,0x6f,0x70,0x65,0x28,0x20, + 0x6e,0x61,0x6d,0x65,0x2c,0x20,0x6f,0x75,0x74,0x65,0x72,0x20,0x29,0x0a,0x7b,0x0a,0x09,0x6c,0x6f,0x63, + 0x61,0x6c,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x09,0x69,0x66,0x20,0x28,0x20,0x21,0x28,0x6e, + 0x61,0x6d,0x65,0x20,0x69,0x6e,0x20,0x6f,0x75,0x74,0x65,0x72,0x29,0x20,0x29,0x0a,0x09,0x7b,0x0a,0x09, + 0x09,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x65,0x72,0x5b,0x6e,0x61,0x6d,0x65, + 0x5d,0x20,0x3c,0x2d,0x20,0x7b,0x20,0x5f,0x5f,0x76,0x6e,0x61,0x6d,0x65,0x3d,0x6e,0x61,0x6d,0x65,0x2c, + 0x20,0x5f,0x5f,0x76,0x72,0x65,0x66,0x73,0x20,0x3d,0x20,0x31,0x20,0x7d,0x3b,0x0a,0x09,0x09,0x64,0x65, + 0x6c,0x65,0x67,0x61,0x74,0x65,0x20,0x6f,0x75,0x74,0x65,0x72,0x20,0x3a,0x20,0x72,0x65,0x73,0x75,0x6c, + 0x74,0x3b,0x0a,0x09,0x7d,0x0a,0x09,0x65,0x6c,0x73,0x65,0x0a,0x09,0x7b,0x0a,0x09,0x09,0x72,0x65,0x73, + 0x75,0x6c,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x65,0x72,0x5b,0x6e,0x61,0x6d,0x65,0x5d,0x3b,0x0a,0x09, + 0x09,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x5f,0x5f,0x76,0x72,0x65,0x66,0x73,0x20,0x2b,0x3d,0x20,0x31, + 0x3b,0x0a,0x09,0x7d,0x0a,0x09,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b, + 0x0a,0x7d,0x0a,0x0a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x56,0x53,0x71,0x75,0x69,0x72,0x72, + 0x65,0x6c,0x5f,0x4f,0x6e,0x52,0x65,0x6c,0x65,0x61,0x73,0x65,0x53,0x63,0x6f,0x70,0x65,0x28,0x20,0x73, + 0x63,0x6f,0x70,0x65,0x20,0x29,0x0a,0x7b,0x0a,0x09,0x73,0x63,0x6f,0x70,0x65,0x2e,0x5f,0x5f,0x76,0x72, + 0x65,0x66,0x73,0x20,0x2d,0x3d,0x20,0x31,0x3b,0x0a,0x09,0x69,0x66,0x20,0x28,0x20,0x73,0x63,0x6f,0x70, + 0x65,0x2e,0x5f,0x5f,0x76,0x72,0x65,0x66,0x73,0x20,0x3c,0x20,0x30,0x20,0x29,0x0a,0x09,0x7b,0x0a,0x09, + 0x09,0x74,0x68,0x72,0x6f,0x77,0x20,0x22,0x42,0x61,0x64,0x20,0x72,0x65,0x66,0x65,0x72,0x65,0x6e,0x63, + 0x65,0x20,0x63,0x6f,0x75,0x6e,0x74,0x69,0x6e,0x67,0x20,0x6f,0x6e,0x20,0x73,0x63,0x6f,0x70,0x65,0x20, + 0x22,0x20,0x2b,0x20,0x73,0x63,0x6f,0x70,0x65,0x2e,0x5f,0x5f,0x76,0x6e,0x61,0x6d,0x65,0x3b,0x0a,0x09, + 0x7d,0x0a,0x09,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x20,0x73,0x63,0x6f,0x70,0x65,0x2e,0x5f, + 0x5f,0x76,0x72,0x65,0x66,0x73,0x20,0x3d,0x3d,0x20,0x30,0x20,0x29,0x0a,0x09,0x7b,0x0a,0x09,0x09,0x64, + 0x65,0x6c,0x65,0x74,0x65,0x20,0x73,0x63,0x6f,0x70,0x65,0x2e,0x70,0x61,0x72,0x65,0x6e,0x74,0x5b,0x73, + 0x63,0x6f,0x70,0x65,0x2e,0x5f,0x5f,0x76,0x6e,0x61,0x6d,0x65,0x5d,0x3b,0x0a,0x09,0x09,0x73,0x63,0x6f, + 0x70,0x65,0x2e,0x5f,0x5f,0x76,0x6e,0x61,0x6d,0x65,0x20,0x3d,0x20,0x6e,0x75,0x6c,0x6c,0x3b,0x0a,0x09, + 0x09,0x64,0x65,0x6c,0x65,0x67,0x61,0x74,0x65,0x20,0x6e,0x75,0x6c,0x6c,0x20,0x3a,0x20,0x73,0x63,0x6f, + 0x70,0x65,0x3b,0x0a,0x09,0x7d,0x0a,0x7d,0x0a,0x0a,0x0a,0x2f,0x2f,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x0a,0x2f,0x2f,0x0a,0x2f,0x2f,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x0a,0x63,0x6c,0x61,0x73,0x73,0x20, + 0x43,0x43,0x61,0x6c,0x6c,0x43,0x68,0x61,0x69,0x6e,0x65,0x72,0x0a,0x7b,0x0a,0x09,0x63,0x6f,0x6e,0x73, + 0x74,0x72,0x75,0x63,0x74,0x6f,0x72,0x28,0x20,0x70,0x72,0x65,0x66,0x69,0x78,0x53,0x74,0x72,0x69,0x6e, + 0x67,0x2c,0x20,0x73,0x63,0x6f,0x70,0x65,0x46,0x6f,0x72,0x54,0x68,0x69,0x73,0x20,0x3d,0x20,0x6e,0x75, + 0x6c,0x6c,0x20,0x29,0x0a,0x09,0x7b,0x0a,0x09,0x09,0x70,0x72,0x65,0x66,0x69,0x78,0x20,0x3d,0x20,0x70, + 0x72,0x65,0x66,0x69,0x78,0x53,0x74,0x72,0x69,0x6e,0x67,0x3b,0x0a,0x09,0x09,0x69,0x66,0x20,0x28,0x20, + 0x73,0x63,0x6f,0x70,0x65,0x46,0x6f,0x72,0x54,0x68,0x69,0x73,0x20,0x21,0x3d,0x20,0x6e,0x75,0x6c,0x6c, + 0x20,0x29,0x0a,0x09,0x09,0x09,0x73,0x63,0x6f,0x70,0x65,0x20,0x3d,0x20,0x73,0x63,0x6f,0x70,0x65,0x46, + 0x6f,0x72,0x54,0x68,0x69,0x73,0x3b,0x0a,0x09,0x09,0x65,0x6c,0x73,0x65,0x0a,0x09,0x09,0x09,0x73,0x63, + 0x6f,0x70,0x65,0x20,0x3d,0x20,0x3a,0x3a,0x67,0x65,0x74,0x72,0x6f,0x6f,0x74,0x74,0x61,0x62,0x6c,0x65, + 0x28,0x29,0x3b,0x0a,0x09,0x09,0x63,0x68,0x61,0x69,0x6e,0x73,0x20,0x3d,0x20,0x7b,0x7d,0x3b,0x0a,0x09, + 0x09,0x0a,0x09,0x09,0x2f,0x2f,0x20,0x45,0x78,0x70,0x6f,0x73,0x65,0x20,0x61,0x20,0x62,0x6f,0x75,0x6e, + 0x64,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x74,0x6f, + 0x20,0x64,0x69,0x73,0x70,0x61,0x74,0x63,0x68,0x20,0x74,0x6f,0x20,0x74,0x68,0x69,0x73,0x20,0x6f,0x62, + 0x6a,0x65,0x63,0x74,0x0a,0x09,0x09,0x73,0x63,0x6f,0x70,0x65,0x5b,0x20,0x22,0x44,0x69,0x73,0x70,0x61, + 0x74,0x63,0x68,0x22,0x20,0x2b,0x20,0x70,0x72,0x65,0x66,0x69,0x78,0x53,0x74,0x72,0x69,0x6e,0x67,0x20, + 0x5d,0x20,0x3c,0x2d,0x20,0x43,0x61,0x6c,0x6c,0x2e,0x62,0x69,0x6e,0x64,0x65,0x6e,0x76,0x28,0x20,0x74, + 0x68,0x69,0x73,0x20,0x29,0x3b,0x0a,0x09,0x7d,0x0a,0x09,0x0a,0x09,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f, + 0x6e,0x20,0x50,0x6f,0x73,0x74,0x53,0x63,0x72,0x69,0x70,0x74,0x45,0x78,0x65,0x63,0x75,0x74,0x65,0x28, + 0x29,0x20,0x0a,0x09,0x7b,0x0a,0x09,0x09,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x28,0x20,0x6b,0x65,0x79, + 0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x69,0x6e,0x20,0x73,0x63,0x6f,0x70,0x65,0x20,0x29,0x0a,0x09, + 0x09,0x7b,0x0a,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x74,0x79,0x70,0x65,0x6f,0x66,0x28,0x20,0x76, + 0x61,0x6c,0x75,0x65,0x20,0x29,0x20,0x3d,0x3d,0x20,0x22,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x22, + 0x20,0x29,0x20,0x0a,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x6b,0x65, + 0x79,0x2e,0x66,0x69,0x6e,0x64,0x28,0x20,0x70,0x72,0x65,0x66,0x69,0x78,0x20,0x29,0x20,0x3d,0x3d,0x20, + 0x30,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x6b,0x65,0x79,0x20,0x3d, + 0x20,0x6b,0x65,0x79,0x2e,0x73,0x6c,0x69,0x63,0x65,0x28,0x20,0x70,0x72,0x65,0x66,0x69,0x78,0x2e,0x6c, + 0x65,0x6e,0x28,0x29,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x0a,0x09,0x09,0x09,0x09,0x09,0x69, + 0x66,0x20,0x28,0x20,0x21,0x28,0x6b,0x65,0x79,0x20,0x69,0x6e,0x20,0x63,0x68,0x61,0x69,0x6e,0x73,0x29, + 0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x2f,0x2f,0x3a,0x3a, + 0x70,0x72,0x69,0x6e,0x74,0x28,0x20,0x22,0x43,0x72,0x65,0x61,0x74,0x69,0x6e,0x67,0x20,0x6e,0x65,0x77, + 0x20,0x63,0x61,0x6c,0x6c,0x20,0x63,0x68,0x61,0x69,0x6e,0x20,0x22,0x20,0x2b,0x20,0x6b,0x65,0x79,0x20, + 0x2b,0x20,0x22,0x5c,0x6e,0x22,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x63,0x68,0x61,0x69,0x6e, + 0x73,0x5b,0x6b,0x65,0x79,0x5d,0x20,0x3c,0x2d,0x20,0x5b,0x5d,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x7d, + 0x0a,0x09,0x09,0x09,0x09,0x09,0x0a,0x09,0x09,0x09,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x63,0x68, + 0x61,0x69,0x6e,0x20,0x3d,0x20,0x63,0x68,0x61,0x69,0x6e,0x73,0x5b,0x6b,0x65,0x79,0x5d,0x3b,0x0a,0x09, + 0x09,0x09,0x09,0x09,0x0a,0x09,0x09,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x21,0x63,0x68,0x61,0x69, + 0x6e,0x2e,0x6c,0x65,0x6e,0x28,0x29,0x20,0x7c,0x7c,0x20,0x63,0x68,0x61,0x69,0x6e,0x2e,0x74,0x6f,0x70, + 0x28,0x29,0x20,0x21,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x09,0x7b, + 0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x63,0x68,0x61,0x69,0x6e,0x2e,0x70,0x75,0x73,0x68,0x28,0x20,0x76, + 0x61,0x6c,0x75,0x65,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x2f,0x2f,0x3a,0x3a,0x70,0x72, + 0x69,0x6e,0x74,0x28,0x20,0x22,0x41,0x64,0x64,0x65,0x64,0x20,0x22,0x20,0x2b,0x20,0x76,0x61,0x6c,0x75, + 0x65,0x20,0x2b,0x20,0x22,0x20,0x74,0x6f,0x20,0x63,0x61,0x6c,0x6c,0x20,0x63,0x68,0x61,0x69,0x6e,0x20, + 0x22,0x20,0x2b,0x20,0x6b,0x65,0x79,0x20,0x2b,0x20,0x22,0x5c,0x6e,0x22,0x20,0x29,0x3b,0x0a,0x09,0x09, + 0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x7d,0x0a, + 0x09,0x7d,0x0a,0x09,0x0a,0x09,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x43,0x61,0x6c,0x6c,0x28, + 0x20,0x65,0x76,0x65,0x6e,0x74,0x2c,0x20,0x2e,0x2e,0x2e,0x20,0x29,0x0a,0x09,0x7b,0x0a,0x09,0x09,0x69, + 0x66,0x20,0x28,0x20,0x65,0x76,0x65,0x6e,0x74,0x20,0x69,0x6e,0x20,0x63,0x68,0x61,0x69,0x6e,0x73,0x20, + 0x29,0x0a,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x63,0x68,0x61,0x69,0x6e, + 0x20,0x3d,0x20,0x63,0x68,0x61,0x69,0x6e,0x73,0x5b,0x65,0x76,0x65,0x6e,0x74,0x5d,0x3b,0x0a,0x09,0x09, + 0x09,0x69,0x66,0x20,0x28,0x20,0x63,0x68,0x61,0x69,0x6e,0x2e,0x6c,0x65,0x6e,0x28,0x29,0x20,0x29,0x0a, + 0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x3b,0x0a,0x09,0x09, + 0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x61,0x72,0x67,0x73,0x20,0x3d,0x20,0x5b,0x5d,0x3b,0x0a,0x09, + 0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x76,0x61,0x72,0x67,0x63,0x20,0x3e,0x20,0x30,0x20,0x29,0x0a, + 0x09,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x61,0x72,0x67,0x73,0x2e,0x70,0x75,0x73,0x68, + 0x28,0x20,0x73,0x63,0x6f,0x70,0x65,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x66,0x6f,0x72,0x20, + 0x28,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x76,0x61,0x72,0x67,0x63,0x3b,0x20, + 0x69,0x2b,0x2b,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x61, + 0x72,0x67,0x73,0x2e,0x70,0x75,0x73,0x68,0x28,0x20,0x76,0x61,0x72,0x67,0x76,0x5b,0x69,0x5d,0x20,0x29, + 0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x66, + 0x6f,0x72,0x20,0x28,0x20,0x69,0x20,0x3d,0x20,0x63,0x68,0x61,0x69,0x6e,0x2e,0x6c,0x65,0x6e,0x28,0x29, + 0x20,0x2d,0x20,0x31,0x3b,0x20,0x69,0x20,0x3e,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x2d,0x3d,0x20,0x31, + 0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20, + 0x66,0x75,0x6e,0x63,0x20,0x3d,0x20,0x63,0x68,0x61,0x69,0x6e,0x5b,0x69,0x5d,0x3b,0x0a,0x09,0x09,0x09, + 0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x09,0x09,0x09,0x09, + 0x09,0x69,0x66,0x20,0x28,0x20,0x21,0x61,0x72,0x67,0x73,0x2e,0x6c,0x65,0x6e,0x28,0x29,0x20,0x29,0x0a, + 0x09,0x09,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x72,0x65,0x73,0x75,0x6c,0x74,0x20, + 0x3d,0x20,0x66,0x75,0x6e,0x63,0x28,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09, + 0x09,0x09,0x65,0x6c,0x73,0x65,0x0a,0x09,0x09,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09, + 0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x66,0x75,0x6e,0x63,0x2e,0x61,0x63,0x61,0x6c,0x6c,0x28, + 0x20,0x61,0x72,0x67,0x73,0x20,0x29,0x3b,0x20,0x0a,0x09,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09, + 0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x21,0x3d,0x20,0x6e,0x75,0x6c, + 0x6c,0x20,0x26,0x26,0x20,0x21,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x09, + 0x09,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x09,0x09,0x09,0x09,0x7d, + 0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x7d,0x0a,0x09,0x09,0x0a,0x09,0x09,0x72,0x65,0x74,0x75,0x72, + 0x6e,0x20,0x74,0x72,0x75,0x65,0x3b,0x0a,0x09,0x7d,0x0a,0x09,0x0a,0x09,0x73,0x63,0x6f,0x70,0x65,0x20, + 0x3d,0x20,0x6e,0x75,0x6c,0x6c,0x3b,0x0a,0x09,0x70,0x72,0x65,0x66,0x69,0x78,0x20,0x3d,0x20,0x6e,0x75, + 0x6c,0x6c,0x3b,0x0a,0x09,0x63,0x68,0x61,0x69,0x6e,0x73,0x20,0x3d,0x20,0x6e,0x75,0x6c,0x6c,0x3b,0x0a, + 0x7d,0x3b,0x0a,0x0a,0x0a,0x2f,0x2f,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x0a,0x2f,0x2f,0x0a,0x2f,0x2f,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x0a,0x63,0x6c,0x61,0x73,0x73,0x20,0x43,0x53,0x69,0x6d,0x70,0x6c, + 0x65,0x43,0x61,0x6c,0x6c,0x43,0x68,0x61,0x69,0x6e,0x65,0x72,0x0a,0x7b,0x0a,0x09,0x63,0x6f,0x6e,0x73, + 0x74,0x72,0x75,0x63,0x74,0x6f,0x72,0x28,0x20,0x70,0x72,0x65,0x66,0x69,0x78,0x53,0x74,0x72,0x69,0x6e, + 0x67,0x2c,0x20,0x73,0x63,0x6f,0x70,0x65,0x46,0x6f,0x72,0x54,0x68,0x69,0x73,0x20,0x3d,0x20,0x6e,0x75, + 0x6c,0x6c,0x2c,0x20,0x65,0x78,0x61,0x63,0x74,0x4e,0x61,0x6d,0x65,0x4d,0x61,0x74,0x63,0x68,0x20,0x3d, + 0x20,0x66,0x61,0x6c,0x73,0x65,0x20,0x29,0x0a,0x09,0x7b,0x0a,0x09,0x09,0x70,0x72,0x65,0x66,0x69,0x78, + 0x20,0x3d,0x20,0x70,0x72,0x65,0x66,0x69,0x78,0x53,0x74,0x72,0x69,0x6e,0x67,0x3b,0x0a,0x09,0x09,0x69, + 0x66,0x20,0x28,0x20,0x73,0x63,0x6f,0x70,0x65,0x46,0x6f,0x72,0x54,0x68,0x69,0x73,0x20,0x21,0x3d,0x20, + 0x6e,0x75,0x6c,0x6c,0x20,0x29,0x0a,0x09,0x09,0x09,0x73,0x63,0x6f,0x70,0x65,0x20,0x3d,0x20,0x73,0x63, + 0x6f,0x70,0x65,0x46,0x6f,0x72,0x54,0x68,0x69,0x73,0x3b,0x0a,0x09,0x09,0x65,0x6c,0x73,0x65,0x0a,0x09, + 0x09,0x09,0x73,0x63,0x6f,0x70,0x65,0x20,0x3d,0x20,0x3a,0x3a,0x67,0x65,0x74,0x72,0x6f,0x6f,0x74,0x74, + 0x61,0x62,0x6c,0x65,0x28,0x29,0x3b,0x0a,0x09,0x09,0x63,0x68,0x61,0x69,0x6e,0x20,0x3d,0x20,0x5b,0x5d, + 0x3b,0x0a,0x09,0x09,0x0a,0x09,0x09,0x2f,0x2f,0x20,0x45,0x78,0x70,0x6f,0x73,0x65,0x20,0x61,0x20,0x62, + 0x6f,0x75,0x6e,0x64,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, + 0x20,0x74,0x6f,0x20,0x64,0x69,0x73,0x70,0x61,0x74,0x63,0x68,0x20,0x74,0x6f,0x20,0x74,0x68,0x69,0x73, + 0x20,0x6f,0x62,0x6a,0x65,0x63,0x74,0x0a,0x09,0x09,0x73,0x63,0x6f,0x70,0x65,0x5b,0x20,0x22,0x44,0x69, + 0x73,0x70,0x61,0x74,0x63,0x68,0x22,0x20,0x2b,0x20,0x70,0x72,0x65,0x66,0x69,0x78,0x53,0x74,0x72,0x69, + 0x6e,0x67,0x20,0x5d,0x20,0x3c,0x2d,0x20,0x43,0x61,0x6c,0x6c,0x2e,0x62,0x69,0x6e,0x64,0x65,0x6e,0x76, + 0x28,0x20,0x74,0x68,0x69,0x73,0x20,0x29,0x3b,0x0a,0x09,0x09,0x0a,0x09,0x09,0x65,0x78,0x61,0x63,0x74, + 0x4d,0x61,0x74,0x63,0x68,0x20,0x3d,0x20,0x65,0x78,0x61,0x63,0x74,0x4e,0x61,0x6d,0x65,0x4d,0x61,0x74, + 0x63,0x68,0x0a,0x09,0x7d,0x0a,0x09,0x0a,0x09,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x50,0x6f, + 0x73,0x74,0x53,0x63,0x72,0x69,0x70,0x74,0x45,0x78,0x65,0x63,0x75,0x74,0x65,0x28,0x29,0x20,0x0a,0x09, + 0x7b,0x0a,0x09,0x09,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x28,0x20,0x6b,0x65,0x79,0x2c,0x20,0x76,0x61, + 0x6c,0x75,0x65,0x20,0x69,0x6e,0x20,0x73,0x63,0x6f,0x70,0x65,0x20,0x29,0x0a,0x09,0x09,0x7b,0x0a,0x09, + 0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x74,0x79,0x70,0x65,0x6f,0x66,0x28,0x20,0x76,0x61,0x6c,0x75,0x65, + 0x20,0x29,0x20,0x3d,0x3d,0x20,0x22,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x22,0x20,0x29,0x20,0x0a, + 0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x66,0x6f,0x75,0x6e,0x64, + 0x4d,0x61,0x74,0x63,0x68,0x20,0x3d,0x20,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x09,0x09,0x09,0x09,0x69, + 0x66,0x20,0x28,0x20,0x65,0x78,0x61,0x63,0x74,0x4d,0x61,0x74,0x63,0x68,0x20,0x29,0x0a,0x09,0x09,0x09, + 0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x66,0x6f,0x75,0x6e,0x64,0x4d,0x61,0x74,0x63,0x68,0x20,0x3d, + 0x20,0x28,0x20,0x70,0x72,0x65,0x66,0x69,0x78,0x20,0x3d,0x3d,0x20,0x6b,0x65,0x79,0x20,0x29,0x3b,0x0a, + 0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x65,0x6c,0x73,0x65,0x0a,0x09,0x09,0x09,0x09,0x7b, + 0x0a,0x09,0x09,0x09,0x09,0x09,0x66,0x6f,0x75,0x6e,0x64,0x4d,0x61,0x74,0x63,0x68,0x20,0x3d,0x20,0x28, + 0x20,0x6b,0x65,0x79,0x2e,0x66,0x69,0x6e,0x64,0x28,0x20,0x70,0x72,0x65,0x66,0x69,0x78,0x20,0x29,0x20, + 0x3d,0x3d,0x20,0x30,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x0a, + 0x09,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x66,0x6f,0x75,0x6e,0x64,0x4d,0x61,0x74,0x63,0x68,0x20, + 0x29,0x0a,0x09,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x21,0x65, + 0x78,0x61,0x63,0x74,0x4d,0x61,0x74,0x63,0x68,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x6b,0x65, + 0x79,0x20,0x3d,0x20,0x6b,0x65,0x79,0x2e,0x73,0x6c,0x69,0x63,0x65,0x28,0x20,0x70,0x72,0x65,0x66,0x69, + 0x78,0x2e,0x6c,0x65,0x6e,0x28,0x29,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x0a,0x09,0x09,0x09, + 0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x21,0x28,0x63,0x68,0x61,0x69,0x6e,0x29,0x20,0x29,0x0a,0x09,0x09, + 0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x2f,0x2f,0x3a,0x3a,0x70,0x72,0x69,0x6e,0x74, + 0x28,0x20,0x22,0x43,0x72,0x65,0x61,0x74,0x69,0x6e,0x67,0x20,0x6e,0x65,0x77,0x20,0x63,0x61,0x6c,0x6c, + 0x20,0x73,0x69,0x6d,0x70,0x6c,0x65,0x20,0x63,0x68,0x61,0x69,0x6e,0x5c,0x6e,0x22,0x29,0x3b,0x0a,0x09, + 0x09,0x09,0x09,0x09,0x09,0x63,0x68,0x61,0x69,0x6e,0x20,0x3c,0x2d,0x20,0x5b,0x5d,0x3b,0x0a,0x09,0x09, + 0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x09,0x0a,0x09,0x09,0x09,0x09,0x09,0x69,0x66,0x20,0x28, + 0x20,0x21,0x63,0x68,0x61,0x69,0x6e,0x2e,0x6c,0x65,0x6e,0x28,0x29,0x20,0x7c,0x7c,0x20,0x63,0x68,0x61, + 0x69,0x6e,0x20,0x21,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x09,0x7b, + 0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x63,0x68,0x61,0x69,0x6e,0x2e,0x70,0x75,0x73,0x68,0x28,0x20,0x76, + 0x61,0x6c,0x75,0x65,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x2f,0x2f,0x3a,0x3a,0x70,0x72, + 0x69,0x6e,0x74,0x28,0x20,0x22,0x41,0x64,0x64,0x65,0x64,0x20,0x22,0x20,0x2b,0x20,0x76,0x61,0x6c,0x75, + 0x65,0x20,0x2b,0x20,0x22,0x20,0x74,0x6f,0x20,0x63,0x61,0x6c,0x6c,0x20,0x63,0x68,0x61,0x69,0x6e,0x2e, + 0x5c,0x6e,0x22,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x7d,0x0a, + 0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x7d,0x0a,0x09,0x7d,0x0a,0x09,0x0a,0x09,0x66,0x75,0x6e,0x63,0x74, + 0x69,0x6f,0x6e,0x20,0x43,0x61,0x6c,0x6c,0x28,0x20,0x2e,0x2e,0x2e,0x20,0x29,0x0a,0x09,0x7b,0x0a,0x09, + 0x09,0x69,0x66,0x20,0x28,0x20,0x63,0x68,0x61,0x69,0x6e,0x2e,0x6c,0x65,0x6e,0x28,0x29,0x20,0x29,0x0a, + 0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x3b,0x0a,0x09,0x09,0x09,0x6c, + 0x6f,0x63,0x61,0x6c,0x20,0x61,0x72,0x67,0x73,0x20,0x3d,0x20,0x5b,0x5d,0x3b,0x0a,0x09,0x09,0x09,0x69, + 0x66,0x20,0x28,0x20,0x76,0x61,0x72,0x67,0x63,0x20,0x3e,0x20,0x30,0x20,0x29,0x0a,0x09,0x09,0x09,0x7b, + 0x0a,0x09,0x09,0x09,0x09,0x61,0x72,0x67,0x73,0x2e,0x70,0x75,0x73,0x68,0x28,0x20,0x73,0x63,0x6f,0x70, + 0x65,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x66,0x6f,0x72,0x20,0x28,0x20,0x69,0x20,0x3d,0x20,0x30, + 0x3b,0x20,0x69,0x20,0x3c,0x20,0x76,0x61,0x72,0x67,0x63,0x3b,0x20,0x69,0x2b,0x2b,0x20,0x29,0x0a,0x09, + 0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x61,0x72,0x67,0x73,0x2e,0x70,0x75,0x73,0x68,0x28, + 0x20,0x76,0x61,0x72,0x67,0x76,0x5b,0x69,0x5d,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09, + 0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x66,0x6f,0x72,0x20,0x28,0x20,0x69,0x20,0x3d,0x20,0x63,0x68,0x61, + 0x69,0x6e,0x2e,0x6c,0x65,0x6e,0x28,0x29,0x20,0x2d,0x20,0x31,0x3b,0x20,0x69,0x20,0x3e,0x3d,0x20,0x30, + 0x3b,0x20,0x69,0x20,0x2d,0x3d,0x20,0x31,0x20,0x29,0x0a,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09, + 0x6c,0x6f,0x63,0x61,0x6c,0x20,0x66,0x75,0x6e,0x63,0x20,0x3d,0x20,0x63,0x68,0x61,0x69,0x6e,0x5b,0x69, + 0x5d,0x3b,0x0a,0x09,0x09,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b, + 0x0a,0x09,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x21,0x61,0x72,0x67,0x73,0x2e,0x6c,0x65,0x6e,0x28, + 0x29,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x72,0x65,0x73,0x75,0x6c, + 0x74,0x20,0x3d,0x20,0x66,0x75,0x6e,0x63,0x2e,0x70,0x63,0x61,0x6c,0x6c,0x28,0x20,0x73,0x63,0x6f,0x70, + 0x65,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x65,0x6c,0x73,0x65,0x0a, + 0x09,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20, + 0x66,0x75,0x6e,0x63,0x2e,0x70,0x61,0x63,0x61,0x6c,0x6c,0x28,0x20,0x73,0x63,0x6f,0x70,0x65,0x2c,0x20, + 0x61,0x72,0x67,0x73,0x20,0x29,0x3b,0x20,0x0a,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x69, + 0x66,0x20,0x28,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x21,0x3d,0x20,0x6e,0x75,0x6c,0x6c,0x20,0x26, + 0x26,0x20,0x21,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x09,0x72,0x65,0x74, + 0x75,0x72,0x6e,0x20,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x7d,0x0a, + 0x09,0x09,0x0a,0x09,0x09,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x72,0x75,0x65,0x3b,0x0a,0x09,0x7d, + 0x0a,0x09,0x0a,0x09,0x65,0x78,0x61,0x63,0x74,0x4d,0x61,0x74,0x63,0x68,0x20,0x3d,0x20,0x66,0x61,0x6c, + 0x73,0x65,0x0a,0x09,0x73,0x63,0x6f,0x70,0x65,0x20,0x3d,0x20,0x6e,0x75,0x6c,0x6c,0x3b,0x0a,0x09,0x70, + 0x72,0x65,0x66,0x69,0x78,0x20,0x3d,0x20,0x6e,0x75,0x6c,0x6c,0x3b,0x0a,0x09,0x63,0x68,0x61,0x69,0x6e, + 0x20,0x3d,0x20,0x6e,0x75,0x6c,0x6c,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x2f,0x2f,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x0a,0x2f,0x2f,0x20,0x4c,0x61,0x74,0x65, + 0x20,0x62,0x69,0x6e,0x64,0x69,0x6e,0x67,0x3a,0x20,0x61,0x6c,0x6c,0x6f,0x77,0x73,0x20,0x61,0x20,0x74, + 0x61,0x62,0x6c,0x65,0x20,0x74,0x6f,0x20,0x72,0x65,0x66,0x65,0x72,0x20,0x74,0x6f,0x20,0x70,0x61,0x72, + 0x74,0x73,0x20,0x6f,0x66,0x20,0x69,0x74,0x73,0x65,0x6c,0x66,0x2c,0x20,0x69,0x74,0x27,0x73,0x20,0x63, + 0x68,0x69,0x6c,0x64,0x72,0x65,0x6e,0x2c,0x0a,0x2f,0x2f,0x20,0x69,0x74,0x27,0x73,0x20,0x6f,0x77,0x6e, + 0x65,0x72,0x2c,0x20,0x61,0x6e,0x64,0x20,0x74,0x68,0x65,0x6e,0x20,0x68,0x61,0x76,0x65,0x20,0x74,0x68, + 0x65,0x20,0x72,0x65,0x66,0x65,0x72,0x65,0x6e,0x63,0x65,0x73,0x20,0x66,0x69,0x78,0x65,0x64,0x20,0x75, + 0x70,0x20,0x61,0x66,0x74,0x65,0x72,0x20,0x69,0x74,0x27,0x73,0x20,0x66,0x75,0x6c,0x6c,0x79,0x20,0x70, + 0x61,0x72,0x73,0x65,0x64,0x0a,0x2f,0x2f,0x0a,0x2f,0x2f,0x20,0x55,0x73,0x61,0x67,0x65,0x3a,0x0a,0x2f, + 0x2f,0x20,0x20,0x20,0x20,0x6c,0x61,0x74,0x65,0x42,0x69,0x6e,0x64,0x65,0x72,0x20,0x3c,0x2d,0x20,0x4c, + 0x61,0x74,0x65,0x42,0x69,0x6e,0x64,0x65,0x72,0x28,0x29,0x3b,0x0a,0x2f,0x2f,0x20,0x20,0x20,0x20,0x6c, + 0x61,0x74,0x65,0x42,0x69,0x6e,0x64,0x65,0x72,0x2e,0x42,0x65,0x67,0x69,0x6e,0x28,0x20,0x74,0x68,0x69, + 0x73,0x20,0x29,0x3b,0x0a,0x2f,0x2f,0x20,0x20,0x20,0x20,0x0a,0x2f,0x2f,0x20,0x20,0x20,0x20,0x54,0x65, + 0x73,0x74,0x31,0x20,0x3c,0x2d,0x0a,0x2f,0x2f,0x20,0x20,0x20,0x20,0x7b,0x20,0x20,0x20,0x0a,0x2f,0x2f, + 0x20,0x09,0x20,0x20,0x20,0x46,0x6f,0x6f,0x3d,0x31,0x0a,0x2f,0x2f,0x20,0x20,0x20,0x20,0x7d,0x20,0x20, + 0x20,0x0a,0x2f,0x2f,0x20,0x20,0x20,0x20,0x0a,0x2f,0x2f,0x20,0x20,0x20,0x20,0x54,0x65,0x73,0x74,0x32, + 0x20,0x3c,0x2d,0x0a,0x2f,0x2f,0x20,0x20,0x20,0x20,0x7b,0x20,0x20,0x20,0x0a,0x2f,0x2f,0x20,0x09,0x20, + 0x20,0x20,0x46,0x6f,0x6f,0x46,0x6f,0x6f,0x20,0x3d,0x20,0x22,0x49,0x27,0x6d,0x20,0x66,0x6f,0x6f,0x20, + 0x66,0x6f,0x6f,0x22,0x0a,0x2f,0x2f,0x20,0x09,0x20,0x20,0x20,0x42,0x61,0x72,0x42,0x61,0x72,0x3d,0x22, + 0x40,0x54,0x65,0x73,0x74,0x31,0x2e,0x46,0x6f,0x6f,0x22,0x0a,0x2f,0x2f,0x20,0x09,0x20,0x20,0x20,0x53, + 0x75,0x62,0x54,0x61,0x62,0x6c,0x65,0x20,0x3d,0x20,0x7b,0x20,0x62,0x6f,0x6f,0x3d,0x5b,0x62,0x61,0x68, + 0x2c,0x20,0x22,0x40,0x54,0x65,0x73,0x74,0x32,0x2e,0x46,0x6f,0x6f,0x46,0x6f,0x6f,0x22,0x2c,0x20,0x22, + 0x40,0x54,0x65,0x73,0x74,0x31,0x2e,0x46,0x6f,0x6f,0x22,0x5d,0x2c,0x20,0x62,0x6f,0x6f,0x62,0x6f,0x6f, + 0x32,0x3d,0x7b,0x6f,0x6e,0x65,0x3d,0x62,0x61,0x68,0x2c,0x20,0x74,0x77,0x6f,0x3d,0x22,0x40,0x54,0x65, + 0x73,0x74,0x32,0x2e,0x46,0x6f,0x6f,0x46,0x6f,0x6f,0x22,0x2c,0x20,0x74,0x68,0x72,0x65,0x65,0x3d,0x22, + 0x40,0x54,0x65,0x73,0x74,0x31,0x2e,0x46,0x6f,0x6f,0x22,0x7d,0x20,0x7d,0x0a,0x2f,0x2f,0x20,0x09,0x20, + 0x20,0x20,0x62,0x6f,0x6f,0x62,0x6f,0x6f,0x3d,0x5b,0x62,0x61,0x68,0x2c,0x20,0x22,0x40,0x54,0x65,0x73, + 0x74,0x32,0x2e,0x46,0x6f,0x6f,0x46,0x6f,0x6f,0x22,0x2c,0x20,0x22,0x40,0x54,0x65,0x73,0x74,0x31,0x2e, + 0x46,0x6f,0x6f,0x22,0x5d,0x0a,0x2f,0x2f,0x20,0x09,0x20,0x20,0x20,0x62,0x6f,0x6f,0x62,0x6f,0x6f,0x32, + 0x3d,0x7b,0x6f,0x6e,0x65,0x3d,0x62,0x61,0x68,0x2c,0x20,0x74,0x77,0x6f,0x3d,0x22,0x40,0x54,0x65,0x73, + 0x74,0x32,0x2e,0x46,0x6f,0x6f,0x46,0x6f,0x6f,0x22,0x2c,0x20,0x74,0x68,0x72,0x65,0x65,0x3d,0x22,0x40, + 0x54,0x65,0x73,0x74,0x31,0x2e,0x46,0x6f,0x6f,0x22,0x7d,0x0a,0x2f,0x2f,0x20,0x09,0x20,0x20,0x20,0x62, + 0x61,0x68,0x3d,0x77,0x68,0x61,0x0a,0x2f,0x2f,0x20,0x20,0x20,0x20,0x7d,0x20,0x20,0x20,0x0a,0x2f,0x2f, + 0x20,0x20,0x20,0x20,0x0a,0x2f,0x2f,0x20,0x20,0x20,0x20,0x6c,0x61,0x74,0x65,0x42,0x69,0x6e,0x64,0x65, + 0x72,0x2e,0x45,0x6e,0x64,0x28,0x29,0x3b,0x0a,0x2f,0x2f,0x20,0x20,0x20,0x20,0x64,0x65,0x6c,0x65,0x74, + 0x65,0x20,0x6c,0x61,0x74,0x65,0x42,0x69,0x6e,0x64,0x65,0x72,0x3b,0x0a,0x2f,0x2f,0x0a,0x2f,0x2f,0x20, + 0x57,0x68,0x65,0x6e,0x20,0x45,0x6e,0x64,0x28,0x29,0x20,0x69,0x73,0x20,0x63,0x61,0x6c,0x6c,0x65,0x64, + 0x2c,0x20,0x61,0x6c,0x6c,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x75,0x6e,0x72,0x65,0x73,0x6f,0x6c, + 0x76,0x65,0x64,0x20,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,0x20,0x69,0x6e,0x20,0x74,0x68,0x65,0x20,0x74, + 0x61,0x62,0x6c,0x65,0x73,0x20,0x61,0x6e,0x64,0x20,0x61,0x72,0x72,0x61,0x79,0x73,0x20,0x77,0x69,0x6c, + 0x6c,0x20,0x62,0x65,0x20,0x72,0x65,0x73,0x6f,0x6c,0x76,0x65,0x64,0x2c,0x0a,0x2f,0x2f,0x20,0x61,0x6e, + 0x79,0x20,0x6c,0x65,0x66,0x74,0x20,0x75,0x6e,0x72,0x65,0x73,0x6f,0x6c,0x76,0x65,0x64,0x20,0x77,0x69, + 0x6c,0x6c,0x20,0x62,0x65,0x63,0x6f,0x6d,0x65,0x20,0x61,0x20,0x73,0x74,0x72,0x69,0x6e,0x67,0x20,0x70, + 0x72,0x65,0x70,0x65,0x6e,0x64,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x27,0x7e,0x27,0x2c,0x20,0x77, + 0x68,0x69,0x63,0x68,0x20,0x6c,0x61,0x74,0x65,0x72,0x20,0x63,0x6f,0x64,0x65,0x20,0x63,0x61,0x6e,0x20, + 0x64,0x65,0x61,0x6c,0x20,0x77,0x69,0x74,0x68,0x0a,0x2f,0x2f,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x0a,0x0a,0x63,0x6c,0x61,0x73,0x73,0x20,0x4c,0x61,0x74, + 0x65,0x42,0x69,0x6e,0x64,0x65,0x72,0x0a,0x7b,0x0a,0x09,0x2f,0x2f,0x20,0x70,0x75,0x62,0x6c,0x69,0x63, + 0x3a,0x0a,0x09,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x42,0x65,0x67,0x69,0x6e,0x28,0x20,0x74, + 0x61,0x72,0x67,0x65,0x74,0x2c,0x20,0x6c,0x6f,0x67,0x20,0x3d,0x20,0x66,0x61,0x6c,0x73,0x65,0x20,0x29, + 0x0a,0x09,0x7b,0x0a,0x09,0x09,0x6d,0x5f,0x6c,0x6f,0x67,0x20,0x3d,0x20,0x6c,0x6f,0x67,0x3b,0x0a,0x09, + 0x09,0x0a,0x09,0x09,0x48,0x6f,0x6f,0x6b,0x52,0x6f,0x6f,0x74,0x4d,0x65,0x74,0x61,0x6d,0x65,0x74,0x68, + 0x6f,0x64,0x28,0x20,0x22,0x5f,0x67,0x65,0x74,0x22,0x2c,0x20,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, + 0x28,0x20,0x6b,0x65,0x79,0x20,0x29,0x20,0x7b,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x22,0x5e,0x22, + 0x20,0x2b,0x20,0x6b,0x65,0x79,0x3b,0x20,0x7d,0x20,0x29,0x3b,0x0a,0x09,0x09,0x48,0x6f,0x6f,0x6b,0x52, + 0x6f,0x6f,0x74,0x4d,0x65,0x74,0x61,0x6d,0x65,0x74,0x68,0x6f,0x64,0x28,0x20,0x22,0x5f,0x6e,0x65,0x77, + 0x73,0x6c,0x6f,0x74,0x22,0x2c,0x20,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x20,0x6b,0x65,0x79, + 0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x29,0x20,0x7b,0x20,0x69,0x66,0x20,0x28,0x20,0x74,0x79,0x70, + 0x65,0x6f,0x66,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x3d,0x20,0x22,0x74,0x61,0x62,0x6c,0x65,0x22, + 0x20,0x29,0x20,0x7b,0x20,0x6d,0x5f,0x66,0x69,0x78,0x75,0x70,0x53,0x65,0x74,0x2e,0x70,0x75,0x73,0x68, + 0x28,0x20,0x5b,0x20,0x6b,0x65,0x79,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x5d,0x20,0x29,0x3b,0x20, + 0x74,0x68,0x69,0x73,0x2e,0x72,0x61,0x77,0x73,0x65,0x74,0x28,0x20,0x6b,0x65,0x79,0x2c,0x20,0x76,0x61, + 0x6c,0x75,0x65,0x20,0x29,0x3b,0x20,0x7d,0x3b,0x20,0x20,0x7d,0x2e,0x62,0x69,0x6e,0x64,0x65,0x6e,0x76, + 0x28,0x74,0x68,0x69,0x73,0x29,0x20,0x29,0x3b,0x0a,0x09,0x09,0x6d,0x5f,0x74,0x61,0x72,0x67,0x65,0x74, + 0x54,0x61,0x62,0x6c,0x65,0x20,0x3d,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x3b,0x0a,0x09,0x09,0x0a,0x09, + 0x09,0x4c,0x6f,0x67,0x28,0x20,0x22,0x42,0x65,0x67,0x69,0x6e,0x20,0x6c,0x61,0x74,0x65,0x20,0x62,0x69, + 0x6e,0x64,0x20,0x6f,0x6e,0x20,0x74,0x61,0x62,0x6c,0x65,0x20,0x22,0x20,0x2b,0x20,0x6d,0x5f,0x74,0x61, + 0x72,0x67,0x65,0x74,0x54,0x61,0x62,0x6c,0x65,0x20,0x29,0x3b,0x0a,0x09,0x7d,0x0a,0x09,0x0a,0x09,0x66, + 0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x45,0x6e,0x64,0x28,0x29,0x0a,0x09,0x7b,0x0a,0x09,0x09,0x55, + 0x6e,0x68,0x6f,0x6f,0x6b,0x52,0x6f,0x6f,0x74,0x4d,0x65,0x74,0x61,0x6d,0x65,0x74,0x68,0x6f,0x64,0x28, + 0x20,0x22,0x5f,0x67,0x65,0x74,0x22,0x20,0x29,0x3b,0x0a,0x09,0x09,0x55,0x6e,0x68,0x6f,0x6f,0x6b,0x52, + 0x6f,0x6f,0x74,0x4d,0x65,0x74,0x61,0x6d,0x65,0x74,0x68,0x6f,0x64,0x28,0x20,0x22,0x5f,0x6e,0x65,0x77, + 0x73,0x6c,0x6f,0x74,0x22,0x20,0x29,0x3b,0x0a,0x0a,0x09,0x09,0x4c,0x6f,0x67,0x28,0x20,0x22,0x45,0x6e, + 0x64,0x20,0x6c,0x61,0x74,0x65,0x20,0x62,0x69,0x6e,0x64,0x20,0x6f,0x6e,0x20,0x74,0x61,0x62,0x6c,0x65, + 0x20,0x22,0x20,0x2b,0x20,0x6d,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x54,0x61,0x62,0x6c,0x65,0x20,0x29, + 0x3b,0x0a,0x09,0x09,0x0a,0x09,0x09,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x28,0x20,0x73,0x75,0x62,0x54, + 0x61,0x62,0x6c,0x65,0x50,0x61,0x69,0x72,0x20,0x69,0x6e,0x20,0x6d,0x5f,0x66,0x69,0x78,0x75,0x70,0x53, + 0x65,0x74,0x20,0x29,0x0a,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x45,0x73,0x74,0x61,0x62,0x6c,0x69,0x73, + 0x68,0x44,0x65,0x6c,0x65,0x67,0x61,0x74,0x69,0x6f,0x6e,0x28,0x20,0x6d,0x5f,0x74,0x61,0x72,0x67,0x65, + 0x74,0x54,0x61,0x62,0x6c,0x65,0x2c,0x20,0x73,0x75,0x62,0x54,0x61,0x62,0x6c,0x65,0x50,0x61,0x69,0x72, + 0x5b,0x31,0x5d,0x20,0x29,0x3b,0x0a,0x09,0x09,0x7d,0x0a,0x0a,0x09,0x09,0x4c,0x6f,0x67,0x28,0x20,0x22, + 0x42,0x65,0x67,0x69,0x6e,0x20,0x72,0x65,0x73,0x6f,0x6c,0x75,0x74,0x69,0x6f,0x6e,0x2e,0x2e,0x2e,0x20, + 0x22,0x20,0x29,0x0a,0x09,0x09,0x6d,0x5f,0x6c,0x6f,0x67,0x49,0x6e,0x64,0x65,0x6e,0x74,0x2b,0x2b,0x3b, + 0x0a,0x09,0x09,0x0a,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x66,0x6f,0x75,0x6e,0x64,0x20,0x3d,0x20, + 0x74,0x72,0x75,0x65,0x3b,0x0a,0x09,0x09,0x0a,0x09,0x09,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x20,0x66, + 0x6f,0x75,0x6e,0x64,0x20,0x29,0x0a,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x66,0x6f,0x72,0x65,0x61,0x63, + 0x68,0x28,0x20,0x73,0x75,0x62,0x54,0x61,0x62,0x6c,0x65,0x50,0x61,0x69,0x72,0x20,0x69,0x6e,0x20,0x6d, + 0x5f,0x66,0x69,0x78,0x75,0x70,0x53,0x65,0x74,0x20,0x29,0x0a,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09, + 0x09,0x4c,0x6f,0x67,0x28,0x20,0x73,0x75,0x62,0x54,0x61,0x62,0x6c,0x65,0x50,0x61,0x69,0x72,0x5b,0x30, + 0x5d,0x20,0x2b,0x20,0x22,0x20,0x3d,0x20,0x22,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x4c,0x6f,0x67, + 0x28,0x20,0x22,0x7b,0x22,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x21,0x52, + 0x65,0x73,0x6f,0x6c,0x76,0x65,0x28,0x20,0x73,0x75,0x62,0x54,0x61,0x62,0x6c,0x65,0x50,0x61,0x69,0x72, + 0x5b,0x31,0x5d,0x2c,0x20,0x73,0x75,0x62,0x54,0x61,0x62,0x6c,0x65,0x50,0x61,0x69,0x72,0x5b,0x31,0x5d, + 0x2c,0x20,0x66,0x61,0x6c,0x73,0x65,0x20,0x29,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09, + 0x09,0x09,0x09,0x66,0x6f,0x75,0x6e,0x64,0x20,0x3d,0x20,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x09,0x09, + 0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x4c,0x6f,0x67,0x28,0x20,0x22,0x7d,0x22,0x20,0x29,0x3b,0x0a, + 0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x0a,0x09,0x09,0x6d,0x5f,0x6c,0x6f,0x67, + 0x49,0x6e,0x64,0x65,0x6e,0x74,0x2d,0x2d,0x3b,0x0a,0x09,0x09,0x0a,0x09,0x09,0x66,0x6f,0x72,0x65,0x61, + 0x63,0x68,0x28,0x20,0x73,0x75,0x62,0x54,0x61,0x62,0x6c,0x65,0x50,0x61,0x69,0x72,0x20,0x69,0x6e,0x20, + 0x6d,0x5f,0x66,0x69,0x78,0x75,0x70,0x53,0x65,0x74,0x20,0x29,0x0a,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09, + 0x52,0x65,0x6d,0x6f,0x76,0x65,0x44,0x65,0x6c,0x65,0x67,0x61,0x74,0x69,0x6f,0x6e,0x28,0x20,0x73,0x75, + 0x62,0x54,0x61,0x62,0x6c,0x65,0x50,0x61,0x69,0x72,0x5b,0x31,0x5d,0x20,0x29,0x3b,0x0a,0x09,0x09,0x7d, + 0x0a,0x09,0x09,0x0a,0x09,0x09,0x4c,0x6f,0x67,0x28,0x20,0x22,0x2e,0x2e,0x2e,0x65,0x6e,0x64,0x20,0x72, + 0x65,0x73,0x6f,0x6c,0x75,0x74,0x69,0x6f,0x6e,0x22,0x20,0x29,0x3b,0x0a,0x09,0x7d,0x0a,0x09,0x09,0x0a, + 0x09,0x2f,0x2f,0x20,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x3a,0x0a,0x09,0x66,0x75,0x6e,0x63,0x74,0x69, + 0x6f,0x6e,0x20,0x48,0x6f,0x6f,0x6b,0x52,0x6f,0x6f,0x74,0x4d,0x65,0x74,0x61,0x6d,0x65,0x74,0x68,0x6f, + 0x64,0x28,0x20,0x6e,0x61,0x6d,0x65,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x29,0x0a,0x09,0x7b,0x0a, + 0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x73,0x61,0x76,0x65,0x64,0x20,0x3d,0x20,0x6e,0x75,0x6c,0x6c, + 0x3b,0x0a,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x72,0x6f,0x6f,0x74,0x74,0x61,0x62,0x6c,0x65,0x20, + 0x3d,0x20,0x67,0x65,0x74,0x72,0x6f,0x6f,0x74,0x74,0x61,0x62,0x6c,0x65,0x28,0x29,0x3b,0x0a,0x09,0x09, + 0x69,0x66,0x20,0x28,0x20,0x6e,0x61,0x6d,0x65,0x20,0x69,0x6e,0x20,0x72,0x6f,0x6f,0x74,0x74,0x61,0x62, + 0x6c,0x65,0x20,0x29,0x0a,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x73,0x61,0x76,0x65,0x64,0x20,0x3d,0x20, + 0x72,0x6f,0x6f,0x74,0x74,0x61,0x62,0x6c,0x65,0x5b,0x6e,0x61,0x6d,0x65,0x5d,0x3b,0x0a,0x09,0x09,0x7d, + 0x0a,0x09,0x09,0x72,0x6f,0x6f,0x74,0x74,0x61,0x62,0x6c,0x65,0x5b,0x6e,0x61,0x6d,0x65,0x5d,0x20,0x3c, + 0x2d,0x20,0x76,0x61,0x6c,0x75,0x65,0x3b,0x0a,0x09,0x09,0x72,0x6f,0x6f,0x74,0x74,0x61,0x62,0x6c,0x65, + 0x5b,0x22,0x5f,0x5f,0x73,0x61,0x76,0x65,0x64,0x22,0x20,0x2b,0x20,0x6e,0x61,0x6d,0x65,0x5d,0x20,0x3c, + 0x2d,0x20,0x73,0x61,0x76,0x65,0x64,0x3b,0x0a,0x09,0x7d,0x0a,0x0a,0x09,0x66,0x75,0x6e,0x63,0x74,0x69, + 0x6f,0x6e,0x20,0x55,0x6e,0x68,0x6f,0x6f,0x6b,0x52,0x6f,0x6f,0x74,0x4d,0x65,0x74,0x61,0x6d,0x65,0x74, + 0x68,0x6f,0x64,0x28,0x20,0x6e,0x61,0x6d,0x65,0x20,0x29,0x0a,0x09,0x7b,0x0a,0x09,0x09,0x6c,0x6f,0x63, + 0x61,0x6c,0x20,0x73,0x61,0x76,0x65,0x53,0x6c,0x6f,0x74,0x20,0x3d,0x20,0x22,0x5f,0x5f,0x73,0x61,0x76, + 0x65,0x64,0x22,0x20,0x2b,0x20,0x6e,0x61,0x6d,0x65,0x3b,0x0a,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20, + 0x72,0x6f,0x6f,0x74,0x74,0x61,0x62,0x6c,0x65,0x20,0x3d,0x20,0x67,0x65,0x74,0x72,0x6f,0x6f,0x74,0x74, + 0x61,0x62,0x6c,0x65,0x28,0x29,0x3b,0x0a,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x73,0x61,0x76,0x65, + 0x64,0x20,0x3d,0x20,0x72,0x6f,0x6f,0x74,0x74,0x61,0x62,0x6c,0x65,0x5b,0x73,0x61,0x76,0x65,0x53,0x6c, + 0x6f,0x74,0x5d,0x3b,0x0a,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x73,0x61,0x76,0x65,0x64,0x20,0x21,0x3d, + 0x20,0x6e,0x75,0x6c,0x6c,0x20,0x29,0x0a,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x72,0x6f,0x6f,0x74,0x74, + 0x61,0x62,0x6c,0x65,0x5b,0x6e,0x61,0x6d,0x65,0x5d,0x20,0x3d,0x20,0x73,0x61,0x76,0x65,0x64,0x3b,0x0a, + 0x09,0x09,0x7d,0x0a,0x09,0x09,0x65,0x6c,0x73,0x65,0x0a,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x64,0x65, + 0x6c,0x65,0x74,0x65,0x20,0x72,0x6f,0x6f,0x74,0x74,0x61,0x62,0x6c,0x65,0x5b,0x6e,0x61,0x6d,0x65,0x5d, + 0x3b,0x0a,0x09,0x09,0x7d,0x0a,0x09,0x09,0x64,0x65,0x6c,0x65,0x74,0x65,0x20,0x72,0x6f,0x6f,0x74,0x74, + 0x61,0x62,0x6c,0x65,0x5b,0x73,0x61,0x76,0x65,0x53,0x6c,0x6f,0x74,0x5d,0x3b,0x0a,0x09,0x7d,0x0a,0x0a, + 0x09,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x45,0x73,0x74,0x61,0x62,0x6c,0x69,0x73,0x68,0x44, + 0x65,0x6c,0x65,0x67,0x61,0x74,0x69,0x6f,0x6e,0x28,0x20,0x70,0x61,0x72,0x65,0x6e,0x74,0x54,0x61,0x62, + 0x6c,0x65,0x2c,0x20,0x63,0x68,0x69,0x6c,0x64,0x54,0x61,0x62,0x6c,0x65,0x20,0x29,0x0a,0x09,0x7b,0x0a, + 0x09,0x09,0x64,0x65,0x6c,0x65,0x67,0x61,0x74,0x65,0x20,0x70,0x61,0x72,0x65,0x6e,0x74,0x54,0x61,0x62, + 0x6c,0x65,0x20,0x3a,0x20,0x63,0x68,0x69,0x6c,0x64,0x54,0x61,0x62,0x6c,0x65,0x3b,0x0a,0x09,0x09,0x0a, + 0x09,0x09,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x28,0x20,0x6b,0x65,0x79,0x2c,0x20,0x76,0x61,0x6c,0x75, + 0x65,0x20,0x69,0x6e,0x20,0x63,0x68,0x69,0x6c,0x64,0x54,0x61,0x62,0x6c,0x65,0x20,0x29,0x0a,0x09,0x09, + 0x7b,0x0a,0x09,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x74,0x79,0x70,0x65,0x20,0x3d,0x20,0x74,0x79, + 0x70,0x65,0x6f,0x66,0x20,0x76,0x61,0x6c,0x75,0x65,0x3b,0x0a,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20, + 0x74,0x79,0x70,0x65,0x20,0x3d,0x3d,0x20,0x22,0x74,0x61,0x62,0x6c,0x65,0x22,0x20,0x29,0x0a,0x09,0x09, + 0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x45,0x73,0x74,0x61,0x62,0x6c,0x69,0x73,0x68,0x44,0x65,0x6c,0x65, + 0x67,0x61,0x74,0x69,0x6f,0x6e,0x28,0x20,0x63,0x68,0x69,0x6c,0x64,0x54,0x61,0x62,0x6c,0x65,0x2c,0x20, + 0x76,0x61,0x6c,0x75,0x65,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x7d,0x0a,0x09,0x7d, + 0x0a,0x09,0x0a,0x09,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x52,0x65,0x6d,0x6f,0x76,0x65,0x44, + 0x65,0x6c,0x65,0x67,0x61,0x74,0x69,0x6f,0x6e,0x28,0x20,0x63,0x68,0x69,0x6c,0x64,0x54,0x61,0x62,0x6c, + 0x65,0x20,0x29,0x0a,0x09,0x7b,0x0a,0x09,0x09,0x64,0x65,0x6c,0x65,0x67,0x61,0x74,0x65,0x20,0x6e,0x75, + 0x6c,0x6c,0x20,0x3a,0x20,0x63,0x68,0x69,0x6c,0x64,0x54,0x61,0x62,0x6c,0x65,0x3b,0x0a,0x09,0x09,0x0a, + 0x09,0x09,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x28,0x20,0x6b,0x65,0x79,0x2c,0x20,0x76,0x61,0x6c,0x75, + 0x65,0x20,0x69,0x6e,0x20,0x63,0x68,0x69,0x6c,0x64,0x54,0x61,0x62,0x6c,0x65,0x20,0x29,0x0a,0x09,0x09, + 0x7b,0x0a,0x09,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x74,0x79,0x70,0x65,0x20,0x3d,0x20,0x74,0x79, + 0x70,0x65,0x6f,0x66,0x20,0x76,0x61,0x6c,0x75,0x65,0x3b,0x0a,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20, + 0x74,0x79,0x70,0x65,0x20,0x3d,0x3d,0x20,0x22,0x74,0x61,0x62,0x6c,0x65,0x22,0x20,0x29,0x0a,0x09,0x09, + 0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x52,0x65,0x6d,0x6f,0x76,0x65,0x44,0x65,0x6c,0x65,0x67,0x61,0x74, + 0x69,0x6f,0x6e,0x28,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09, + 0x09,0x7d,0x0a,0x09,0x7d,0x0a,0x0a,0x09,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x52,0x65,0x73, + 0x6f,0x6c,0x76,0x65,0x28,0x20,0x6c,0x6f,0x6f,0x6b,0x75,0x70,0x54,0x61,0x62,0x6c,0x65,0x2c,0x20,0x73, + 0x75,0x62,0x54,0x61,0x62,0x6c,0x65,0x4f,0x72,0x41,0x72,0x72,0x61,0x79,0x2c,0x20,0x74,0x68,0x72,0x6f, + 0x77,0x45,0x78,0x63,0x65,0x70,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x66,0x61,0x6c,0x73,0x65,0x20,0x29, + 0x0a,0x09,0x7b,0x0a,0x09,0x09,0x6d,0x5f,0x6c,0x6f,0x67,0x49,0x6e,0x64,0x65,0x6e,0x74,0x2b,0x2b,0x3b, + 0x0a,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x66,0x6f,0x75,0x6e,0x64,0x20,0x3d,0x20,0x66,0x61,0x6c, + 0x73,0x65,0x3b,0x0a,0x09,0x0a,0x09,0x09,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x28,0x20,0x6b,0x65,0x79, + 0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x69,0x6e,0x20,0x73,0x75,0x62,0x54,0x61,0x62,0x6c,0x65,0x4f, + 0x72,0x41,0x72,0x72,0x61,0x79,0x20,0x29,0x0a,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x6c,0x6f,0x63,0x61, + 0x6c,0x20,0x74,0x79,0x70,0x65,0x20,0x3d,0x20,0x74,0x79,0x70,0x65,0x6f,0x66,0x20,0x76,0x61,0x6c,0x75, + 0x65,0x3b,0x0a,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x74,0x79,0x70,0x65,0x20,0x3d,0x3d,0x20,0x22, + 0x73,0x74,0x72,0x69,0x6e,0x67,0x22,0x20,0x29,0x0a,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x69, + 0x66,0x20,0x28,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x6c,0x65,0x6e,0x28,0x29,0x20,0x29,0x0a,0x09,0x09, + 0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x6e,0x72,0x65,0x73, + 0x6f,0x6c,0x76,0x65,0x64,0x49,0x64,0x20,0x3d,0x20,0x6e,0x75,0x6c,0x6c,0x3b,0x0a,0x09,0x09,0x09,0x09, + 0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x74,0x72,0x6f,0x6c,0x43,0x68,0x61,0x72,0x20,0x3d, + 0x20,0x76,0x61,0x6c,0x75,0x65,0x5b,0x30,0x5d,0x0a,0x09,0x09,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20, + 0x63,0x6f,0x6e,0x74,0x72,0x6f,0x6c,0x43,0x68,0x61,0x72,0x20,0x3d,0x3d,0x20,0x27,0x5e,0x27,0x20,0x29, + 0x0a,0x09,0x09,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x66,0x6f,0x75,0x6e,0x64,0x20, + 0x3d,0x20,0x74,0x72,0x75,0x65,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x76,0x61,0x6c,0x75,0x65,0x20, + 0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x73,0x6c,0x69,0x63,0x65,0x28,0x20,0x31,0x20,0x29,0x3b,0x0a, + 0x09,0x09,0x09,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x69,0x6e,0x20, + 0x6c,0x6f,0x6f,0x6b,0x75,0x70,0x54,0x61,0x62,0x6c,0x65,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x09,0x09, + 0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x73,0x75,0x62,0x54,0x61,0x62,0x6c,0x65,0x4f,0x72,0x41, + 0x72,0x72,0x61,0x79,0x5b,0x6b,0x65,0x79,0x5d,0x20,0x3d,0x20,0x6c,0x6f,0x6f,0x6b,0x75,0x70,0x54,0x61, + 0x62,0x6c,0x65,0x5b,0x76,0x61,0x6c,0x75,0x65,0x5d,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x4c, + 0x6f,0x67,0x28,0x20,0x6b,0x65,0x79,0x20,0x2b,0x20,0x22,0x20,0x3d,0x20,0x22,0x20,0x2b,0x20,0x6c,0x6f, + 0x6f,0x6b,0x75,0x70,0x54,0x61,0x62,0x6c,0x65,0x5b,0x76,0x61,0x6c,0x75,0x65,0x5d,0x20,0x2b,0x20,0x22, + 0x20,0x3c,0x2d,0x2d,0x20,0x22,0x20,0x2b,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x29,0x3b,0x0a,0x09,0x09, + 0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x65,0x6c,0x73,0x65,0x0a,0x09,0x09,0x09, + 0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x73,0x75,0x62,0x54,0x61,0x62,0x6c,0x65, + 0x4f,0x72,0x41,0x72,0x72,0x61,0x79,0x5b,0x6b,0x65,0x79,0x5d,0x20,0x3d,0x20,0x22,0x7e,0x22,0x20,0x2b, + 0x20,0x76,0x61,0x6c,0x75,0x65,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x75,0x6e,0x72,0x65,0x73, + 0x6f,0x6c,0x76,0x65,0x64,0x49,0x64,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x3b,0x0a,0x09,0x09,0x09, + 0x09,0x09,0x09,0x09,0x4c,0x6f,0x67,0x28,0x20,0x6b,0x65,0x79,0x20,0x2b,0x20,0x22,0x20,0x3d,0x20,0x5c, + 0x22,0x22,0x20,0x2b,0x20,0x22,0x7e,0x22,0x20,0x2b,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x2b,0x20,0x22, + 0x5c,0x22,0x20,0x28,0x75,0x6e,0x72,0x65,0x73,0x6f,0x6c,0x76,0x65,0x64,0x29,0x22,0x20,0x29,0x3b,0x0a, + 0x09,0x09,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x09, + 0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x20,0x63,0x6f,0x6e,0x74,0x72,0x6f,0x6c,0x43,0x68,0x61, + 0x72,0x20,0x3d,0x3d,0x20,0x27,0x40,0x27,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09, + 0x09,0x09,0x09,0x09,0x66,0x6f,0x75,0x6e,0x64,0x20,0x3d,0x20,0x74,0x72,0x75,0x65,0x3b,0x0a,0x09,0x09, + 0x09,0x09,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x64,0x65,0x6e,0x74,0x69,0x66,0x69,0x65,0x72, + 0x73,0x20,0x3d,0x20,0x5b,0x5d,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20, + 0x69,0x4c,0x61,0x73,0x74,0x20,0x3d,0x20,0x31,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x6c,0x6f,0x63, + 0x61,0x6c,0x20,0x69,0x4e,0x65,0x78,0x74,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x77,0x68,0x69,0x6c, + 0x65,0x20,0x28,0x20,0x28,0x20,0x69,0x4e,0x65,0x78,0x74,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e, + 0x66,0x69,0x6e,0x64,0x28,0x20,0x22,0x2e,0x22,0x2c,0x20,0x69,0x4c,0x61,0x73,0x74,0x20,0x29,0x20,0x29, + 0x20,0x21,0x3d,0x20,0x6e,0x75,0x6c,0x6c,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x7b,0x0a,0x09, + 0x09,0x09,0x09,0x09,0x09,0x09,0x69,0x64,0x65,0x6e,0x74,0x69,0x66,0x69,0x65,0x72,0x73,0x2e,0x70,0x75, + 0x73,0x68,0x28,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x73,0x6c,0x69,0x63,0x65,0x28,0x20,0x69,0x4c,0x61, + 0x73,0x74,0x2c,0x20,0x69,0x4e,0x65,0x78,0x74,0x20,0x29,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09, + 0x09,0x09,0x69,0x4c,0x61,0x73,0x74,0x20,0x3d,0x20,0x69,0x4e,0x65,0x78,0x74,0x20,0x2b,0x20,0x31,0x3b, + 0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x69,0x64,0x65,0x6e,0x74, + 0x69,0x66,0x69,0x65,0x72,0x73,0x2e,0x70,0x75,0x73,0x68,0x28,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x73, + 0x6c,0x69,0x63,0x65,0x28,0x20,0x69,0x4c,0x61,0x73,0x74,0x20,0x29,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09, + 0x09,0x09,0x09,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x64,0x65,0x70,0x74, + 0x68,0x53,0x75,0x63,0x63,0x65,0x73,0x73,0x20,0x3d,0x20,0x30,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09, + 0x6c,0x6f,0x63,0x61,0x6c,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x6c,0x6f,0x6f,0x6b,0x75, + 0x70,0x54,0x61,0x62,0x6c,0x65,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x66,0x6f,0x72,0x65,0x61,0x63, + 0x68,0x28,0x20,0x69,0x64,0x65,0x6e,0x74,0x69,0x66,0x69,0x65,0x72,0x20,0x69,0x6e,0x20,0x69,0x64,0x65, + 0x6e,0x74,0x69,0x66,0x69,0x65,0x72,0x73,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x7b,0x0a,0x09, + 0x09,0x09,0x09,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x69,0x64,0x65,0x6e,0x74,0x69,0x66,0x69,0x65, + 0x72,0x20,0x69,0x6e,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x09,0x09, + 0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x64,0x65,0x70,0x74,0x68,0x53,0x75,0x63,0x63, + 0x65,0x73,0x73,0x2b,0x2b,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x72,0x65,0x73,0x75,0x6c, + 0x74,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x69,0x64,0x65,0x6e,0x74,0x69,0x66,0x69,0x65, + 0x72,0x5d,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x09, + 0x65,0x6c,0x73,0x65,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09, + 0x09,0x09,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09, + 0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x64,0x65,0x70, + 0x74,0x68,0x53,0x75,0x63,0x63,0x65,0x73,0x73,0x20,0x3d,0x3d,0x20,0x69,0x64,0x65,0x6e,0x74,0x69,0x66, + 0x69,0x65,0x72,0x73,0x2e,0x6c,0x65,0x6e,0x28,0x29,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x7b, + 0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x73,0x75,0x62,0x54,0x61,0x62,0x6c,0x65,0x4f,0x72,0x41,0x72, + 0x72,0x61,0x79,0x5b,0x6b,0x65,0x79,0x5d,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x09, + 0x09,0x09,0x09,0x09,0x09,0x09,0x4c,0x6f,0x67,0x28,0x20,0x6b,0x65,0x79,0x20,0x2b,0x20,0x22,0x20,0x3d, + 0x20,0x22,0x20,0x2b,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x2b,0x20,0x22,0x20,0x3c,0x2d,0x2d,0x20, + 0x22,0x20,0x2b,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x7d, + 0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x65,0x6c,0x73,0x65,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x7b,0x0a, + 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x73,0x75,0x62,0x54,0x61,0x62,0x6c,0x65,0x4f,0x72,0x41,0x72,0x72, + 0x61,0x79,0x5b,0x6b,0x65,0x79,0x5d,0x20,0x3d,0x20,0x22,0x7e,0x22,0x20,0x2b,0x20,0x76,0x61,0x6c,0x75, + 0x65,0x2e,0x73,0x6c,0x69,0x63,0x65,0x28,0x20,0x31,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09, + 0x09,0x75,0x6e,0x72,0x65,0x73,0x6f,0x6c,0x76,0x65,0x64,0x49,0x64,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75, + 0x65,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x4c,0x6f,0x67,0x28,0x20,0x6b,0x65,0x79,0x20,0x2b, + 0x20,0x22,0x20,0x3d,0x20,0x5c,0x22,0x22,0x20,0x2b,0x20,0x22,0x7e,0x22,0x20,0x2b,0x20,0x76,0x61,0x6c, + 0x75,0x65,0x20,0x2b,0x20,0x22,0x5c,0x22,0x20,0x28,0x75,0x6e,0x72,0x65,0x73,0x6f,0x6c,0x76,0x65,0x64, + 0x29,0x22,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x09,0x7d, + 0x0a,0x09,0x09,0x09,0x09,0x09,0x0a,0x09,0x09,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x75,0x6e,0x72, + 0x65,0x73,0x6f,0x6c,0x76,0x65,0x64,0x49,0x64,0x20,0x21,0x3d,0x20,0x6e,0x75,0x6c,0x6c,0x20,0x29,0x0a, + 0x09,0x09,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x74,0x68, + 0x72,0x6f,0x77,0x45,0x78,0x63,0x65,0x70,0x74,0x69,0x6f,0x6e,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x09, + 0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x65,0x78,0x63,0x65, + 0x70,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x22,0x55,0x6e,0x72,0x65,0x73,0x6f,0x6c,0x76,0x65,0x64,0x20, + 0x73,0x79,0x6d,0x62,0x6f,0x6c,0x3a,0x20,0x22,0x20,0x2b,0x20,0x62,0x69,0x6e,0x64,0x20,0x2b,0x20,0x22, + 0x20,0x69,0x6e,0x20,0x22,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x66,0x6f,0x72,0x65,0x61,0x63, + 0x68,0x20,0x28,0x20,0x65,0x6e,0x74,0x72,0x79,0x20,0x69,0x6e,0x20,0x6d,0x5f,0x62,0x69,0x6e,0x64,0x4e, + 0x61,0x6d,0x65,0x73,0x53,0x74,0x61,0x63,0x6b,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x7b, + 0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x65,0x78,0x63,0x65,0x70,0x74,0x69,0x6f,0x6e,0x20,0x2b, + 0x3d,0x20,0x65,0x6e,0x74,0x72,0x79,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x65,0x78,0x63, + 0x65,0x70,0x74,0x69,0x6f,0x6e,0x20,0x2b,0x3d,0x20,0x22,0x2e,0x22,0x0a,0x09,0x09,0x09,0x09,0x09,0x09, + 0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x65,0x78,0x63,0x65,0x70,0x74,0x69,0x6f,0x6e,0x20, + 0x2b,0x3d,0x20,0x75,0x6e,0x72,0x65,0x73,0x6f,0x6c,0x76,0x65,0x64,0x49,0x64,0x3b,0x0a,0x09,0x09,0x09, + 0x09,0x09,0x09,0x09,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x74,0x68,0x72,0x6f,0x77,0x20,0x65,0x78, + 0x63,0x65,0x70,0x74,0x69,0x6f,0x6e,0x3b,0x20,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09, + 0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x7d,0x0a, + 0x0a,0x09,0x09,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x28,0x20,0x6b,0x65,0x79,0x2c,0x20,0x76,0x61,0x6c, + 0x75,0x65,0x20,0x69,0x6e,0x20,0x73,0x75,0x62,0x54,0x61,0x62,0x6c,0x65,0x4f,0x72,0x41,0x72,0x72,0x61, + 0x79,0x20,0x29,0x0a,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x74,0x79,0x70, + 0x65,0x20,0x3d,0x20,0x74,0x79,0x70,0x65,0x6f,0x66,0x20,0x76,0x61,0x6c,0x75,0x65,0x3b,0x0a,0x09,0x09, + 0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x73,0x54,0x61,0x62,0x6c,0x65,0x20,0x3d,0x20,0x28,0x20,0x74, + 0x79,0x70,0x65,0x20,0x3d,0x3d,0x20,0x22,0x74,0x61,0x62,0x6c,0x65,0x22,0x20,0x29,0x3b,0x0a,0x09,0x09, + 0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x73,0x41,0x72,0x72,0x61,0x79,0x20,0x3d,0x20,0x28,0x20,0x74, + 0x79,0x70,0x65,0x20,0x3d,0x3d,0x20,0x22,0x61,0x72,0x72,0x61,0x79,0x22,0x20,0x29,0x0a,0x09,0x09,0x09, + 0x69,0x66,0x20,0x28,0x20,0x69,0x73,0x54,0x61,0x62,0x6c,0x65,0x20,0x7c,0x7c,0x20,0x69,0x73,0x41,0x72, + 0x72,0x61,0x79,0x20,0x29,0x0a,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x4c,0x6f,0x67,0x28,0x20, + 0x6b,0x65,0x79,0x20,0x2b,0x20,0x22,0x20,0x3d,0x22,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x4c,0x6f, + 0x67,0x28,0x20,0x69,0x73,0x54,0x61,0x62,0x6c,0x65,0x20,0x3f,0x20,0x22,0x7b,0x22,0x20,0x3a,0x20,0x22, + 0x5b,0x22,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x0a,0x09,0x09,0x09,0x09,0x6d,0x5f,0x62,0x69,0x6e, + 0x64,0x4e,0x61,0x6d,0x65,0x73,0x53,0x74,0x61,0x63,0x6b,0x2e,0x70,0x75,0x73,0x68,0x28,0x20,0x6b,0x65, + 0x79,0x20,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x52,0x65,0x73,0x6f,0x6c,0x76, + 0x65,0x28,0x20,0x28,0x20,0x69,0x73,0x54,0x61,0x62,0x6c,0x65,0x20,0x29,0x20,0x3f,0x20,0x76,0x61,0x6c, + 0x75,0x65,0x20,0x3a,0x20,0x6c,0x6f,0x6f,0x6b,0x75,0x70,0x54,0x61,0x62,0x6c,0x65,0x2c,0x20,0x76,0x61, + 0x6c,0x75,0x65,0x2c,0x20,0x74,0x68,0x72,0x6f,0x77,0x45,0x78,0x63,0x65,0x70,0x74,0x69,0x6f,0x6e,0x20, + 0x29,0x20,0x29,0x0a,0x09,0x09,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x66,0x6f,0x75,0x6e,0x64, + 0x20,0x3d,0x20,0x74,0x72,0x75,0x65,0x3b,0x0a,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x6d, + 0x5f,0x62,0x69,0x6e,0x64,0x4e,0x61,0x6d,0x65,0x73,0x53,0x74,0x61,0x63,0x6b,0x2e,0x70,0x6f,0x70,0x28, + 0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x0a,0x09,0x09,0x09,0x09,0x4c,0x6f,0x67,0x28,0x20,0x69,0x73,0x54, + 0x61,0x62,0x6c,0x65,0x20,0x3f,0x20,0x22,0x7d,0x22,0x20,0x3a,0x20,0x22,0x5d,0x22,0x20,0x29,0x3b,0x0a, + 0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x7d,0x0a,0x09,0x09,0x6d,0x5f,0x6c,0x6f,0x67,0x49,0x6e,0x64,0x65, + 0x6e,0x74,0x2d,0x2d,0x3b,0x0a,0x09,0x09,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x66,0x6f,0x75,0x6e,0x64, + 0x3b,0x0a,0x09,0x7d,0x0a,0x09,0x0a,0x09,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x4c,0x6f,0x67, + 0x28,0x20,0x73,0x74,0x72,0x69,0x6e,0x67,0x20,0x29,0x0a,0x09,0x7b,0x0a,0x09,0x09,0x69,0x66,0x20,0x28, + 0x20,0x6d,0x5f,0x6c,0x6f,0x67,0x20,0x29,0x0a,0x09,0x09,0x7b,0x0a,0x09,0x09,0x09,0x66,0x6f,0x72,0x20, + 0x28,0x20,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6d, + 0x5f,0x6c,0x6f,0x67,0x49,0x6e,0x64,0x65,0x6e,0x74,0x3b,0x20,0x69,0x2b,0x2b,0x20,0x29,0x0a,0x09,0x09, + 0x09,0x7b,0x0a,0x09,0x09,0x09,0x09,0x70,0x72,0x69,0x6e,0x74,0x28,0x20,0x22,0x20,0x20,0x22,0x20,0x29, + 0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x0a,0x09,0x09,0x09,0x70,0x72,0x69,0x6e,0x74,0x6c, + 0x28,0x20,0x73,0x74,0x72,0x69,0x6e,0x67,0x20,0x29,0x3b,0x0a,0x09,0x09,0x7d,0x0a,0x09,0x7d,0x0a,0x0a, + 0x09,0x6d,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x54,0x61,0x62,0x6c,0x65,0x20,0x3d,0x20,0x6e,0x75,0x6c, + 0x6c,0x3b,0x0a,0x09,0x6d,0x5f,0x66,0x69,0x78,0x75,0x70,0x53,0x65,0x74,0x20,0x3d,0x20,0x5b,0x5d,0x3b, + 0x0a,0x09,0x6d,0x5f,0x62,0x69,0x6e,0x64,0x4e,0x61,0x6d,0x65,0x73,0x53,0x74,0x61,0x63,0x6b,0x20,0x3d, + 0x20,0x5b,0x5d,0x3b,0x0a,0x09,0x6d,0x5f,0x6c,0x6f,0x67,0x20,0x3d,0x20,0x66,0x61,0x6c,0x73,0x65,0x3b, + 0x0a,0x09,0x6d,0x5f,0x6c,0x6f,0x67,0x49,0x6e,0x64,0x65,0x6e,0x74,0x20,0x3d,0x20,0x30,0x3b,0x0a,0x7d, + 0x0a,0x0a,0x0a,0x00 +}; diff --git a/vscript/languages/squirrel/vsquirrel/test.nut b/vscript/languages/squirrel/vsquirrel/test.nut new file mode 100644 index 00000000..7885eb57 --- /dev/null +++ b/vscript/languages/squirrel/vsquirrel/test.nut @@ -0,0 +1,44 @@ +print( "Test\n" ); + +local value = TestReturn(); +print("My value = " + value + "\n"); + +temp <- [ 1, 2, 3, 4 ]; + +foreach(idx,val in temp) +{ + print("index="+idx+" value="+val+"\n"); +} + +temp[0] = 33; +temp[1] = 34; +temp[2] = 35; +temp[3] = 36; + +foreach(idx,val in temp) +{ + print("index="+idx+" value="+val+"\n"); +} + +foreach(idx,val in mytable) +{ + print("index="+idx+" value="+val+"\n"); +} + + print("x = " + mytable.controlpoint_1_vector.x + "\n"); + print("y = " + mytable.controlpoint_1_vector.y + "\n"); + print("z = " + mytable.controlpoint_1_vector.z + "\n"); + + + + local string = "controlpoint_" + 1; + local vectortable = string + "_vector"; + local vector = Vector(0,0,0); + if ( vectortable in mytable ) + { + print("here\n"); + vector = Vector( mytable[vectortable].x, mytable[vectortable].y, mytable[vectortable].z ); + } + + print("Vector = " + vector + "\n" ); + \ No newline at end of file diff --git a/vscript/languages/squirrel/vsquirrel/vsquirrel.cpp b/vscript/languages/squirrel/vsquirrel/vsquirrel.cpp new file mode 100644 index 00000000..9b35fbd7 --- /dev/null +++ b/vscript/languages/squirrel/vsquirrel/vsquirrel.cpp @@ -0,0 +1,3548 @@ + //========== Copyright (c) Valve Corporation, All rights reserved. ======== +// +// Purpose: +// +//========================================================================== + +//------------------------------------- +// Work around one of the headers below including crtdbg.h +#include "memdbgon.h" +#include "memdbgoff.h" +//------------------------------------- + +#include +#if defined( _PS3 ) || defined( POSIX ) +#include +#include +#undef _STD_USING +#elif defined( _WIN32 ) +#include +#include +#include +#endif // _PS3 + +#ifdef _HAS_EXCEPTIONS +#undef _HAS_EXCEPTIONS +#endif + +#define _HAS_EXCEPTIONS 0 +#include + +#include "platform.h" + +#include "tier1/utlmap.h" +#include "datamap.h" +#include "tier1/functors.h" +#include "tier1/utlvector.h" +#include "tier1/utlhash.h" +#include "tier1/utlbuffer.h" +#include "tier1/fmtstr.h" +#include "tier1/convar.h" +#include "mathlib/vector.h" +#include "vstdlib/random.h" + +#pragma warning(push, 3) +#include "squirrel.h" +#include "sqstdaux.h" +#include "sqstdstring.h" +#include "sqstdmath.h" +#include "sqplus.h" +#include "sqrdbg.h" +#include "../squirrel/sqstate.h" +#include "../squirrel/sqvm.h" +#include "../squirrel/sqobject.h" +#include "../squirrel/sqstring.h" +#include "../squirrel/sqarray.h" +#include "../squirrel/sqtable.h" +#include "../squirrel/squserdata.h" +#include "../squirrel/sqfuncproto.h" +#include "../squirrel/sqclass.h" +#include "../squirrel/sqclosure.h" +#include "sqdbgserver.h" +#pragma warning(pop) + +#include "vscript/ivscript.h" +//#include "tier0/vprof.h" + +#include "init_nut.h" + +#include "memdbgon.h" + +#ifdef VSQUIRREL_DEBUG_SERIALIZATION +static SQObjectType lastType; +#endif + +#if defined( _PS3 ) || defined( POSIX ) +inline int64 max( int64 a, int64 b) +{ + return a > b ? a : b; +} + +#endif +//----------------------------------------------------------------------------- +// Stub out unwanted features +//----------------------------------------------------------------------------- +extern "C" +{ + +SQRESULT sqstd_register_iolib(HSQUIRRELVM) +{ + return SQ_OK; +} + +SQRESULT sqstd_loadfile(HSQUIRRELVM,const SQChar *,SQBool) +{ + return SQ_ERROR; +} + +} + +//------------------------------------------------------------------------- +// Helpers +//------------------------------------------------------------------------- + +const char *FieldTypeToString( int type ) +{ + switch( type ) + { + case FIELD_VOID: return "void"; + case FIELD_FLOAT: return "float"; + case FIELD_CSTRING: return "string"; + case FIELD_VECTOR: return "Vector"; + case FIELD_INTEGER: return "int"; + case FIELD_BOOLEAN: return "bool"; + case FIELD_CHARACTER: return "char"; + case FIELD_HSCRIPT: return "handle"; + default: return ""; + } +} + +static const char *SQTypeToString( SQObjectType sqType ) +{ + switch( sqType ) + { + case OT_FLOAT: return "FLOAT"; + case OT_INTEGER: return "INTEGER"; + case OT_BOOL: return "BOOL"; + case OT_STRING: return "STRING"; + case OT_NULL: return "NULL"; + case OT_TABLE: return "TABLE"; + case OT_ARRAY: return "ARRAY"; + case OT_CLOSURE: return "CLOSURE"; + case OT_NATIVECLOSURE: return "NATIVECLOSURE"; + case OT_USERDATA: return "USERDATA"; + case OT_GENERATOR: return "GENERATOR"; + case OT_THREAD: return "THREAD"; + case OT_USERPOINTER: return "USERPOINTER"; + case OT_CLASS: return "CLASS"; + case OT_INSTANCE: return "INSTANCE"; + case OT_WEAKREF: return "WEAKREF"; + } + return ""; +} + + +//------------------------------------------------------------------------- +// Vector +//------------------------------------------------------------------------- +#define TYPETAG_VECTOR ((SQUserPointer)1) +SQInteger VectorRelease( SQUserPointer p, SQInteger size ) +{ + delete (Vector *)p; + return 0; +} + +SQInteger VectorConstruct( HSQUIRRELVM hVM ) +{ + StackHandler sa(hVM); + Vector *pVector = new Vector; + + int i; + for ( i = 0; i < 3 && i < sa.GetParamCount() - 1; i++ ) + { + (*pVector)[i] = sa.GetFloat(i + 2); + } + + for ( ; i < 3 ; i++ ) + { + (*pVector)[i] = 0; + } + + sq_setinstanceup(hVM, 1, pVector); + sq_setreleasehook( hVM, 1, &VectorRelease ); + return 0; +} + +SQInteger VectorGet( HSQUIRRELVM hVM ) +{ + StackHandler sa(hVM); + Vector *pVector = (Vector *)sa.GetInstanceUp(1,0); + if ( !pVector ) + { + sq_throwerror( hVM, "null vector" ); + return SQ_ERROR; + } + + const char *pszKey = sa.GetString( 2 ); + if ( pszKey && *pszKey && !*(pszKey + 1) ) + { + int index = *pszKey - 'x'; + if ( index >=0 && index <= 2) + { + sq_pushfloat( hVM, (*pVector)[index] ); + return 1; + } + } + return SQ_ERROR; +} + +SQInteger VectorSet( HSQUIRRELVM hVM ) +{ + StackHandler sa(hVM); + Vector *pVector = (Vector *)sa.GetInstanceUp(1,0); + if ( !pVector ) + { + sq_throwerror( hVM, "null vector" ); + return SQ_ERROR; + } + + const char *pszKey = sa.GetString( 2 ); + if ( pszKey && *pszKey && !*(pszKey + 1) ) + { + int index = *pszKey - 'x'; + if ( index >=0 && index <= 2) + { + (*pVector)[index] = sa.GetFloat(3); + sq_pushfloat( hVM, (*pVector)[index] ); + return 0; + } + } + return SQ_ERROR; +} + +SQInteger VectorIterate( HSQUIRRELVM hVM ) +{ + StackHandler sa(hVM); + static const char *results[] = + { + "x", "y", "z" + }; + const char *pszKey = (sa.GetType( 2 ) == OT_NULL ) ? "w" : sa.GetString( 2 ); + if ( pszKey && *pszKey && !*(pszKey + 1) ) + { + int index = (*pszKey - 'x' ) + 1; + if ( index >=0 && index <= 2) + { + sa.Return( results[index] ); + return 1; + } + sq_pushnull( hVM ); + return 1; + } + return SQ_ERROR; +} + +SQInteger VectorToString( HSQUIRRELVM hVM ) +{ + StackHandler sa(hVM); + Vector *pVector = (Vector *)sa.GetInstanceUp(1,0); + if ( !pVector ) + { + sq_throwerror( hVM, "null vector" ); + return SQ_ERROR; + } + + sa.Return( (static_cast(CFmtStr("(vector : (%f, %f, %f))", pVector->x, pVector->y, pVector->z))) ); + return 1; +} + +SQInteger VectorTypeOf( HSQUIRRELVM hVM ) +{ + StackHandler sa(hVM); + sa.Return( "Vector" ); + return 1; +} + +SQInteger VectorToKeyValueString( HSQUIRRELVM hVM ) +{ + StackHandler sa(hVM); + Vector *pVector = (Vector *)sa.GetInstanceUp(1,0); + if ( !pVector ) + { + sq_throwerror( hVM, "null vector" ); + return SQ_ERROR; + } + + sa.Return( (static_cast(CFmtStr("%f %f %f))", pVector->x, pVector->y, pVector->z))) ); + return 1; +} + +SQInteger VectorAdd( HSQUIRRELVM hVM ) +{ + StackHandler sa(hVM); + Vector *pVectorSrc = (Vector *)sa.GetInstanceUp(1,0); + Vector *pVectorAdd = (Vector *)sa.GetInstanceUp(2,0); + + if ( !pVectorSrc || !pVectorAdd ) + { + sq_throwerror( hVM, "null vector" ); + return SQ_ERROR; + } + + Vector *pResult = new Vector; + + *pResult = *pVectorSrc + *pVectorAdd; + + sq_getclass( hVM, -1 ); + sq_createinstance( hVM, -1 ); + sq_setinstanceup( hVM, -1, (SQUserPointer)pResult ); + sq_setreleasehook( hVM, -1, &VectorRelease ); + sq_remove( hVM, -2 ); + + return 1; +} + +SQInteger VectorSubtract( HSQUIRRELVM hVM ) +{ + StackHandler sa(hVM); + Vector *pVectorSrc = (Vector *)sa.GetInstanceUp(1,0); + Vector *pVectorAdd = (Vector *)sa.GetInstanceUp(2,0); + + if ( !pVectorSrc || !pVectorAdd ) + { + sq_throwerror( hVM, "null vector" ); + return SQ_ERROR; + } + + Vector *pResult = new Vector; + + *pResult = *pVectorSrc - *pVectorAdd; + + sq_getclass( hVM, -1 ); + sq_createinstance( hVM, -1 ); + sq_setinstanceup( hVM, -1, (SQUserPointer)pResult ); + sq_setreleasehook( hVM, -1, &VectorRelease ); + sq_remove( hVM, -2 ); + + return 1; +} + +SQInteger VectorScale( HSQUIRRELVM hVM ) +{ + StackHandler sa(hVM); + Vector *pVectorSrc = (Vector *)sa.GetInstanceUp(1,0); + + if ( !pVectorSrc ) + { + sq_throwerror( hVM, "null vector" ); + return SQ_ERROR; + } + + float scale = sa.GetFloat( 2 ); + Vector *pResult = new Vector; + + *pResult = *pVectorSrc * scale; + + sq_getclass( hVM, -2 ); + sq_createinstance( hVM, -1 ); + sq_setinstanceup( hVM, -1, (SQUserPointer)pResult ); + sq_setreleasehook( hVM, -1, &VectorRelease ); + sq_remove( hVM, -2 ); + + return 1; +} + +SQInteger VectorLength( HSQUIRRELVM hVM ) +{ + StackHandler sa(hVM); + Vector *pVector = (Vector *)sa.GetInstanceUp(1,0); + + if ( !pVector ) + { + sq_throwerror( hVM, "null vector" ); + return SQ_ERROR; + } + + float flLength = pVector->Length(); + sa.Return( flLength ); + + return 1; +} + +SQInteger VectorLengthSqr( HSQUIRRELVM hVM ) +{ + StackHandler sa(hVM); + Vector *pVector = (Vector *)sa.GetInstanceUp(1,0); + + if ( !pVector ) + { + sq_throwerror( hVM, "null vector" ); + return SQ_ERROR; + } + + float flLength = pVector->LengthSqr(); + sa.Return( flLength ); + + return 1; +} + +SQInteger VectorLength2D( HSQUIRRELVM hVM ) +{ + StackHandler sa(hVM); + Vector *pVector = (Vector *)sa.GetInstanceUp(1,0); + + if ( !pVector ) + { + sq_throwerror( hVM, "null vector" ); + return SQ_ERROR; + } + + float flLength = pVector->Length2D(); + sa.Return( flLength ); + + return 1; +} + +SQInteger VectorLength2DSqr( HSQUIRRELVM hVM ) +{ + StackHandler sa(hVM); + Vector *pVector = (Vector *)sa.GetInstanceUp(1,0); + + if ( !pVector ) + { + sq_throwerror( hVM, "null vector" ); + return SQ_ERROR; + } + + float flLength = pVector->Length2DSqr(); + sa.Return( flLength ); + + return 1; +} + +SQInteger VectorCross( HSQUIRRELVM hVM ) +{ + StackHandler sa(hVM); + Vector *pVectorSrc = (Vector *)sa.GetInstanceUp(1,0); + Vector *pVectorAdd = (Vector *)sa.GetInstanceUp(2,0); + + if ( !pVectorSrc || !pVectorAdd ) + { + sq_throwerror( hVM, "null vector" ); + return SQ_ERROR; + } + + Vector *pResult = new Vector; + + *pResult = (*pVectorSrc).Cross( *pVectorAdd ); + + sq_getclass( hVM, -1 ); + sq_createinstance( hVM, -1 ); + sq_setinstanceup( hVM, -1, (SQUserPointer)pResult ); + sq_setreleasehook( hVM, -1, &VectorRelease ); + sq_remove( hVM, -2 ); + + return 1; +} + +SQInteger VectorDot( HSQUIRRELVM hVM ) +{ + StackHandler sa(hVM); + Vector *pVectorSrc = (Vector *)sa.GetInstanceUp(1,0); + Vector *pVectorAdd = (Vector *)sa.GetInstanceUp(2,0); + + if ( !pVectorSrc || !pVectorAdd ) + { + sq_throwerror( hVM, "null vector" ); + return SQ_ERROR; + } + + float flResult = (*pVectorSrc).Dot( *pVectorAdd ); + sa.Return( flResult ); + + return 1; +} + +SQInteger VectorNorm( HSQUIRRELVM hVM ) +{ + StackHandler sa(hVM); + Vector *pVector = (Vector *)sa.GetInstanceUp(1,0); + + if ( !pVector ) + { + sq_throwerror( hVM, "null vector" ); + return SQ_ERROR; + } + + float flLength = pVector->NormalizeInPlace(); + sa.Return( flLength ); + + return 1; +} + + +SQRegFunction g_VectorFuncs[] = +{ + { "constructor", VectorConstruct, 0, NULL }, + { "_get", VectorGet, 2, ".." }, + { "_set", VectorSet, 3, "..n" }, + { "_tostring", VectorToString, 0, NULL }, + { "_typeof", VectorTypeOf, 0, NULL }, + { "_nexti", VectorIterate, 0, NULL }, + { "_add", VectorAdd, 2, NULL }, + { "_sub", VectorSubtract, 2, NULL }, + { "_mul", VectorScale, 2, NULL }, + { "ToKVString", VectorToKeyValueString, 0, NULL }, + { "Length", VectorLength, 0, NULL }, + { "LengthSqr", VectorLengthSqr, 0, NULL }, + { "Length2D", VectorLength2D, 0, NULL }, + { "Length2DSqr", VectorLength2DSqr, 0, NULL }, + { "Length2DSqr", VectorLength2DSqr, 0, NULL }, + { "Dot", VectorDot, 2, NULL }, + { "Cross", VectorCross, 2, NULL }, + { "Norm", VectorNorm, 0, NULL }, +}; + + +bool RegisterVector( HSQUIRRELVM hVM ) +{ + int top = sq_gettop( hVM ); + + sq_pushroottable(hVM); + sq_pushstring(hVM,"Vector",-1); + + if (SQ_FAILED(sq_newclass(hVM,0))) + { + sq_settop(hVM,top); + return false; + } + HSQOBJECT hClass; + sq_getstackobj(hVM,-1, &hClass); + sq_settypetag(hVM,-1,TYPETAG_VECTOR); + sq_createslot(hVM,-3); + + sq_pushobject( hVM, hClass ); + for ( int i = 0; i < ARRAYSIZE(g_VectorFuncs); i++ ) + { + sq_pushstring(hVM,g_VectorFuncs[i].name,-1); + sq_newclosure(hVM,g_VectorFuncs[i].f,0); + if ( g_VectorFuncs[i].nparamscheck ) + sq_setparamscheck(hVM,g_VectorFuncs[i].nparamscheck,g_VectorFuncs[i].typemask); + sq_setnativeclosurename(hVM,-1,g_VectorFuncs[i].name); + sq_createslot(hVM,-3); + } + + sq_pop(hVM,1); + + sq_settop( hVM, top ); + return true; +} + +//----------------------------------------------------------------------------- +// Bridge code, some cribbed from SqPlus +//----------------------------------------------------------------------------- + +const HSQOBJECT INVALID_HSQOBJECT = { (SQObjectType)-1, (SQTable *)-1 }; + +inline bool operator==( const HSQOBJECT &lhs, const HSQOBJECT &rhs ) { COMPILE_TIME_ASSERT( sizeof(lhs._unVal) == sizeof(lhs._unVal.pTable) ); return ( lhs._type == rhs._type && lhs._unVal.pTable == rhs._unVal.pTable ); } +inline bool operator!=( const HSQOBJECT &lhs, const HSQOBJECT &rhs ) { return !operator==( lhs, rhs ); } + +class CSquirrelVM : public IScriptVM +{ +public: + CSquirrelVM( HSQUIRRELVM hVM = NULL ) + : m_hVM( hVM ), m_hDbg( NULL ), m_PtrMap( DefLessFunc(void *) ), m_iUniqueIdSerialNumber( 0 ) +#ifndef VSQUIRREL_TEST + , developer( "developer" ) +#else + , developer( "developer", "1" ) +#endif + { + m_hOnCreateScopeFunc = _null_; + m_hOnReleaseScopeFunc = _null_; + m_hClassVector = _null_; + m_ErrorString = _null_; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + virtual bool Init() + { + m_hVM = sq_open(1024); + + m_hVM->_sharedstate->m_pOwnerData = this; + m_hVM->SetQuerySuspendFn( &QueryContinue ); + // Need to make this conditional on convar or commandline [2/11/2008 tom] + //m_hDbg = sq_rdbg_init( m_hVM, 1234, SQTrue); + sq_setprintfunc(m_hVM, &PrintFunc); + sq_pushroottable(m_hVM); + sqstd_register_mathlib(m_hVM); + sqstd_register_stringlib(m_hVM); + sqstd_seterrorhandlers(m_hVM); + sq_pop(m_hVM,1); + if ( IsDebug() || developer.GetInt() > 0 ) + { + sq_enabledebuginfo( m_hVM, SQTrue ); + } + sq_pushroottable( m_hVM); + + sq_pushstring( m_hVM, "developer", -1 ); + sq_newclosure( m_hVM, &GetDeveloper, 0 ); + sq_setnativeclosurename(m_hVM, -1, "developer" ); + sq_createslot( m_hVM, -3 ); + + sq_pushstring( m_hVM, "GetFunctionSignature", -1 ); + sq_newclosure( m_hVM, &GetFunctionSignature, 0 ); + sq_setnativeclosurename(m_hVM, -1, "GetFunctionSignature" ); + sq_createslot( m_hVM, -3 ); + + sq_pop( m_hVM, 1 ); + + m_TypeMap.Init( 256 ); + + RegisterVector( m_hVM ); + + sq_pushroottable(m_hVM ); + sq_pushstring( m_hVM, "Vector", -1 ); + sq_get(m_hVM,-2); //get the function from the root table + sq_getstackobj(m_hVM,-1,&m_hClassVector); + sq_addref(m_hVM,&m_hClassVector); + sq_pop(m_hVM, 2); + + // Initialization scripts & hookup + Run( (const char *)g_Script_init, "init.nut" ); + + m_hOnCreateScopeFunc = LookupObject( "VSquirrel_OnCreateScope" ); + m_hOnReleaseScopeFunc = LookupObject( "VSquirrel_OnReleaseScope" ); + + return true; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + bool Frame( float simTime ) + { + // + // removed garbage collection that was called at least 2 times a frame (60 fps server tick / 30fps game = 2 calls a frame) + // and took 1 ms on PS3 PPU. It's not necessary because our scripts are supposed to never create circular references + // and everything else is handled with ref counting. For the case of bugs creating circular references, the plan is to add + // diagnostics that detects such loops and warns the developer. + // + if ( m_hDbg ) + { + sq_rdbg_update( m_hDbg ); + if ( !m_hDbg->IsConnected() ) + DisconnectDebugger(); + } + return false; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + virtual void Shutdown() + { + if ( m_hVM ) + { + sq_collectgarbage( m_hVM ); + sq_pushnull(m_hVM); + sq_setroottable(m_hVM); + DisconnectDebugger(); + sq_close( m_hVM ); + m_hVM = NULL; + } + m_TypeMap.Purge(); + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + ScriptLanguage_t GetLanguage() + { + return SL_SQUIRREL; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + virtual const char *GetLanguageName() + { + return "Squirrel"; + } + + virtual void AddSearchPath( const char *pszSearchPath ) + { + + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + HSQUIRRELVM GetVM() + { + return m_hVM; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + bool ConnectDebugger() + { + if ( developer.GetInt() > 0 ) + { + if ( !m_hDbg ) + { + m_hDbg = sq_rdbg_init( m_hVM, 1234, SQTrue); + } + + if ( !m_hDbg ) + { + return false; + } + //!! SUSPENDS THE APP UNTIL THE DEBUGGER CLIENT CONNECTS + return SQ_SUCCEEDED(sq_rdbg_waitforconnections(m_hDbg)); + } + return false; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void DisconnectDebugger() + { + if ( m_hDbg ) + { + sq_rdbg_shutdown( m_hDbg ); + m_hDbg = NULL; + } + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + ScriptStatus_t Run( const char *pszScript, bool bWait = true ) + { + Assert( bWait ); + if(SQ_SUCCEEDED(sq_compilebuffer(m_hVM,pszScript,(int)V_strlen(pszScript)*sizeof(SQChar),"unnamed",1))) + { + HSQOBJECT hScript; + sq_getstackobj(m_hVM,-1, &hScript); + sq_addref(m_hVM, &hScript ); + sq_pop(m_hVM,1); + + ScriptStatus_t result = CSquirrelVM::ExecuteFunction( (HSCRIPT)(&hScript), NULL, 0, NULL, NULL, bWait ); + + sq_release( m_hVM, &hScript ); + + return result; + } + return SCRIPT_ERROR; + + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + HSCRIPT CompileScript( const char *pszScript, const char *pszId = NULL ) + { + if ( !pszScript || !*pszScript ) + { + return NULL; + } + + if(SQ_SUCCEEDED(sq_compilebuffer(m_hVM,pszScript,(int)V_strlen(pszScript)*sizeof(SQChar),(pszId) ? pszId : "unnamed",1))) + { + HSQOBJECT *pRet = new HSQOBJECT; + sq_getstackobj(m_hVM,-1,pRet); + sq_addref(m_hVM, pRet); + sq_pop(m_hVM,1); + return (HSCRIPT)pRet; + } + return NULL; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void ReleaseScript( HSCRIPT hScript ) + { + ReleaseScriptObject( hScript ); + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + ScriptStatus_t Run( HSCRIPT hScript, HSCRIPT hScope = NULL, bool bWait = true ) + { + return CSquirrelVM::ExecuteFunction( hScript, NULL, 0, NULL, hScope, bWait ); + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + ScriptStatus_t Run( HSCRIPT hScript, bool bWait ) + { + Assert( bWait ); + return CSquirrelVM::Run( hScript, (HSCRIPT)NULL, bWait ); + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + HSCRIPT CreateScope( const char *pszScope, HSCRIPT hParent = NULL ) + { + if ( !hParent ) + { + hParent = (HSCRIPT)&m_hVM->_roottable; + } + + HSQOBJECT result; + sq_pushobject( m_hVM, m_hOnCreateScopeFunc ); + sq_pushroottable( m_hVM ); + sq_pushstring( m_hVM, pszScope, -1 ); + sq_pushobject( m_hVM, *((HSQOBJECT *)hParent) ); + if ( sq_call( m_hVM, 3, true, SQ_CALL_RAISE_ERROR ) == SQ_OK ) + { + sq_getstackobj(m_hVM,-1,&result); + sq_pop(m_hVM,2); + } + else + { + result = _null_; + sq_pop(m_hVM,1); + } + + if ( sq_isnull( result ) ) + { + return NULL; + } + + sq_addref(m_hVM, &result); + HSQOBJECT *pRet = new HSQOBJECT; + *pRet = result; + return (HSCRIPT)pRet; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void ReleaseScope( HSCRIPT hScript ) + { + HSQOBJECT &o = *((HSQOBJECT *)hScript); + sq_pushobject( m_hVM, m_hOnReleaseScopeFunc ); + sq_pushroottable( m_hVM ); + sq_pushobject(m_hVM, o ); + sq_call( m_hVM, 2, false, SQ_CALL_RAISE_ERROR ); + sq_pop(m_hVM,1); + + ReleaseScriptObject( hScript ); + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + HSQOBJECT LookupObject( const char *pszObject, HSCRIPT hScope = NULL, bool bAddRef = true ) + { + HSQOBJECT result = { OT_NULL, NULL }; + if ( !hScope ) + { + sq_pushroottable( m_hVM ); + } + else + { + if ( hScope == INVALID_HSCRIPT || *((HSQOBJECT *)hScope) == INVALID_HSQOBJECT || !sq_istable( *((HSQOBJECT *)hScope) ) ) + { + return _null_; + } + sq_pushobject( m_hVM, *((HSQOBJECT *)hScope) ); + } + sq_pushstring( m_hVM, pszObject, -1 ); + if ( sq_get( m_hVM, -2 ) == SQ_OK ) + { + sq_getstackobj(m_hVM,-1,&result); + if ( bAddRef ) + sq_addref(m_hVM, &result); + sq_pop(m_hVM,1); + } + sq_pop(m_hVM,1); + return result; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + HSCRIPT LookupFunction( const char *pszFunction, HSCRIPT hScope = NULL ) + { + HSQOBJECT result = LookupObject( pszFunction, hScope ); + if ( !sq_isnull( result ) ) + { + if ( sq_isclosure(result) ) + { + HSQOBJECT *pResult = new HSQOBJECT; + *pResult = result; + return (HSCRIPT)pResult; + } + sq_release( m_hVM, &result ); + } + return NULL; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void ReleaseFunction( HSCRIPT hScript ) + { + ReleaseScriptObject( hScript ); + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + ScriptStatus_t ExecuteFunction( HSCRIPT hFunction, ScriptVariant_t *pArgs, int nArgs, ScriptVariant_t *pReturn, HSCRIPT hScope = NULL, bool bWait = true ) + { + if ( hScope == INVALID_HSCRIPT ) + { + DevWarning( "Invalid scope handed to script VM\n" ); + return SCRIPT_ERROR; + } + if ( m_hDbg ) + { + extern bool g_bSqDbgTerminateScript; + if ( g_bSqDbgTerminateScript ) + { + DisconnectDebugger(); + g_bSqDbgTerminateScript = false; + } + } + + Assert( bWait ); + if ( hFunction ) + { + SQInteger initialTop = m_hVM->_top; + HSQOBJECT &o = *((HSQOBJECT *)hFunction); + Assert( bWait ); + + sq_pushobject( m_hVM, o); + if ( hScope ) + { + if ( hScope == INVALID_HSCRIPT || *((HSQOBJECT *)hScope) == INVALID_HSQOBJECT || !sq_istable( *((HSQOBJECT *)hScope) ) ) + { + sq_pop(m_hVM,1); + return SCRIPT_ERROR; + } + sq_pushobject( m_hVM, *((HSQOBJECT *)hScope) ); + } + else + { + sq_pushroottable( m_hVM ); + } + + for ( int i = 0; i < nArgs; i++ ) + { + PushVariant( pArgs[i], true ); + } + + m_TimeStartExecute = Plat_FloatTime(); + if (SQ_SUCCEEDED(sq_call(m_hVM,1+nArgs, ( pReturn != NULL ),SQ_CALL_RAISE_ERROR))) + { + m_TimeStartExecute = 0.0f; + if ( pReturn ) + { + HSQOBJECT ret; + sq_getstackobj(m_hVM,-1,&ret); + if ( !ConvertToVariant( ret, pReturn ) ) + { + DevMsg( "Script function returned unsupported type\n" ); + } + + sq_pop(m_hVM,2); + } + else + { + sq_pop(m_hVM,1); + } + if ( m_hVM->_top != initialTop ) + { + Warning( "Callstack mismatch in VScript/Squirrel!\n" ); + Assert( m_hVM->_top == initialTop ); + } + if ( !sq_isnull( m_ErrorString ) ) + { + if ( sq_isstring( m_ErrorString ) ) + { + sq_throwerror( m_hVM, m_ErrorString._unVal.pString->_val ); + } + else + { + sq_throwerror( m_hVM, "Internal error" ); + } + m_ErrorString = _null_; + return SCRIPT_ERROR; + } + return SCRIPT_DONE; + } + m_TimeStartExecute = 0.0f; + sq_pop(m_hVM,1); + } + + if ( pReturn ) + { + pReturn->m_type = FIELD_VOID; + } + return SCRIPT_ERROR; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void RegisterFunction( ScriptFunctionBinding_t *pScriptFunction ) + { + sq_pushroottable( m_hVM ); + RegisterFunctionGuts( pScriptFunction ); + sq_pop( m_hVM, 1 ); + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + virtual bool RegisterClass( ScriptClassDesc_t *pClassDesc ) + { + COMPILE_TIME_ASSERT( sizeof(pClassDesc) == sizeof(intptr_t) ); + if ( m_TypeMap.Find( (intptr_t)pClassDesc ) != m_TypeMap.InvalidHandle() ) + { + return true; + } + + sq_pushroottable( m_hVM ); + sq_pushstring( m_hVM, pClassDesc->m_pszScriptName, -1 ); + if ( sq_get( m_hVM, -2 ) == SQ_OK ) + { + sq_pop( m_hVM, 2 ); + return false; + } + sq_pop( m_hVM, 1 ); + + if ( pClassDesc->m_pBaseDesc ) + { + CSquirrelVM::RegisterClass( pClassDesc->m_pBaseDesc ); + } + + int top = sq_gettop(m_hVM); + + HSQOBJECT newClass; + newClass = CreateClass( pClassDesc ); + if ( newClass != INVALID_HSQOBJECT ) + { + sq_pushobject( m_hVM, newClass ); + if ( pClassDesc->m_pfnConstruct ) + { + sq_pushstring( m_hVM, "constructor", -1 ); + void **pUserData = (void **)sq_newuserdata(m_hVM, sizeof(void *)); + *pUserData = pClassDesc; + sq_newclosure( m_hVM, &CallConstructor, 1 ); + sq_createslot( m_hVM, -3 ); + } + + sq_pushstring( m_hVM, "_tostring", -1 ); + sq_newclosure( m_hVM, &InstanceToString, 0 ); + sq_createslot( m_hVM, -3 ); + + sq_pushstring( m_hVM, "IsValid", -1 ); + sq_newclosure( m_hVM, &InstanceIsValid, 0 ); + sq_createslot( m_hVM, -3 ); + + for ( int i = 0; i < pClassDesc->m_FunctionBindings.Count(); i++ ) + { + RegisterFunctionGuts( &pClassDesc->m_FunctionBindings[i], pClassDesc ); + } + sq_pop( m_hVM, 1 ); + // more setup required for inheritance? + } + sq_settop(m_hVM, top); + m_TypeMap.Insert( (intptr_t)pClassDesc, newClass._unVal.pClass ); + return true; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + bool CreateNativeInstance( ScriptClassDesc_t *pDesc, SQUserPointer ud,SQRELEASEHOOK hook ) + { + sq_pushobject( m_hVM, SQObjectPtr(m_TypeMap[m_TypeMap.Find((intptr_t)pDesc)]) ); + if(SQ_FAILED(sq_createinstance(m_hVM,-1))) + { + sq_pop( m_hVM, 1 ); + return false; + } + sq_remove(m_hVM,-2); //removes the class + if(SQ_FAILED(sq_setinstanceup(m_hVM,-1,ud))) + { + return false; + } + sq_setreleasehook(m_hVM,-1,hook); + return TRUE; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + HSCRIPT RegisterInstance( ScriptClassDesc_t *pDesc, void *pInstance ) + { + if ( !CSquirrelVM::RegisterClass( pDesc ) ) + { + return NULL; + } + + InstanceContext_t *pInstanceContext = new InstanceContext_t; + pInstanceContext->pInstance = pInstance; + pInstanceContext->pClassDesc = pDesc; + pInstanceContext->name = _null_; + + if ( !CreateNativeInstance( pDesc, pInstanceContext, &ExternalInstanceReleaseHook ) ) + { + delete pInstanceContext; + return NULL; + } + + HSQOBJECT hObject; + sq_getstackobj(m_hVM,-1,&hObject); + sq_addref( m_hVM, &hObject ); + sq_pop( m_hVM, 1 ); + + HSQOBJECT *pResult = new HSQOBJECT; + *pResult = hObject; + return (HSCRIPT)pResult; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void SetInstanceUniqeId( HSCRIPT hInstance, const char *pszId ) + { + if ( !hInstance ) + { + ExecuteOnce( DevMsg( "NULL instance passed to vscript!\n" ) ); + return; + } + HSQOBJECT *pInstance = (HSQOBJECT *)hInstance; + Assert( pInstance->_type == OT_INSTANCE ); + if ( pInstance->_type == OT_INSTANCE ) + ((InstanceContext_t *)(pInstance->_unVal.pInstance->_userpointer))->name = SQString::Create( _ss(m_hVM), pszId ); + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void RemoveInstance( HSCRIPT hInstance ) + { + if ( !hInstance ) + { + ExecuteOnce( DevMsg( "NULL instance passed to vscript!\n" ) ); + return; + } + HSQOBJECT *pInstance = (HSQOBJECT *)hInstance; + Assert( pInstance->_type == OT_INSTANCE ); + if ( pInstance->_type == OT_INSTANCE ) + ((InstanceContext_t *)(pInstance->_unVal.pInstance->_userpointer))->pInstance = NULL; + ReleaseScriptObject( hInstance ); + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void *GetInstanceValue( HSCRIPT hInstance, ScriptClassDesc_t *pExpectedType ) + { + if ( !hInstance ) + { + ExecuteOnce( DevMsg( "NULL instance passed to vscript!\n" ) ); + return NULL; + } + HSQOBJECT *pInstance = (HSQOBJECT *)hInstance; + if ( pInstance->_type == OT_INSTANCE && pInstance->_unVal.pInstance->_userpointer ) + { + InstanceContext_t *pContext = ((InstanceContext_t *)(pInstance->_unVal.pInstance->_userpointer)); + if ( !pExpectedType || pContext->pClassDesc == pExpectedType || IsClassDerivedFrom( pContext->pClassDesc, pExpectedType ) ) + return pContext->pInstance; + } + return NULL; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + bool IsClassDerivedFrom( const ScriptClassDesc_t *pDerivedClass, const ScriptClassDesc_t *pBaseClass ) + { + const ScriptClassDesc_t* pType = pDerivedClass->m_pBaseDesc; + while ( pType ) + { + if ( pType == pBaseClass ) + return true; + + pType = pType->m_pBaseDesc; + } + + return false; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + bool GenerateUniqueKey( const char *pszRoot, char *pBuf, int nBufSize ) + { + Assert( V_strlen(pszRoot) + 40 + 1 <= nBufSize ); + if ( V_strlen(pszRoot) + 40 + 1 <= nBufSize ) + { + Q_snprintf( pBuf, nBufSize, "%x%x%llx_%s", RandomInt(0, 0xfff), Plat_MSTime(), m_iUniqueIdSerialNumber++, pszRoot ); // random to limit key compare when serial number gets large + return true; + } + Error( "GenerateUniqueKey: buffer too small" ); + if ( nBufSize ) + { + *pBuf = 0; + } + return false; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + virtual bool ValueExists( HSCRIPT hScope, const char *pszKey ) + { + return !sq_isnull( LookupObject( pszKey, hScope, false ) ); + } + + + bool SetValue( HSCRIPT hScope, const char *pszKey, const char *pszValue ) + { + if ( !hScope ) + { + sq_pushroottable( m_hVM ); + } + else + { + if ( hScope == INVALID_HSCRIPT || *((HSQOBJECT *)hScope) == INVALID_HSQOBJECT || !sq_istable( *((HSQOBJECT *)hScope) ) ) + { + return false; + } + sq_pushobject( m_hVM, *((HSQOBJECT *)hScope) ); + } + + sq_pushstring( m_hVM, pszKey, -1 ); + sq_pushstring( m_hVM, pszValue, -1 ); + + sq_createslot( m_hVM, -3 ); + sq_pop( m_hVM, 1 ); + + return true; + } + + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + bool SetValue( HSCRIPT hScope, const char *pszKey, const ScriptVariant_t &value ) + { + if ( !hScope ) + { + sq_pushroottable( m_hVM ); + } + else + { + if ( hScope == INVALID_HSCRIPT || *((HSQOBJECT *)hScope) == INVALID_HSQOBJECT || !sq_istable( *((HSQOBJECT *)hScope) ) ) + { + return false; + } + sq_pushobject( m_hVM, *((HSQOBJECT *)hScope) ); + } + + sq_pushstring( m_hVM, pszKey, -1 ); + if ( value.m_type == FIELD_HSCRIPT && value.m_hScript ) + { + HSQOBJECT hObject = *((HSQOBJECT *)value.m_hScript); + if ( sq_isinstance( hObject ) ) + { + SQInstance *pInstance = hObject._unVal.pInstance; + if ( pInstance->_class->_typetag && pInstance->_class->_typetag != TYPETAG_VECTOR ) + { + InstanceContext_t *pContext = (InstanceContext_t *)pInstance->_userpointer; + if ( sq_isnull( pContext->name ) ) + { + pContext->name = m_hVM->_stack[m_hVM->_top - 1]; + } + } + } + } + PushVariant( value, true ); + sq_createslot( m_hVM, -3 ); + sq_pop(m_hVM,1); + + return true; + } + + + void CreateTable( ScriptVariant_t &Table ) + { + HSQOBJECT hObject; + + sq_newtable( m_hVM ); + sq_getstackobj(m_hVM, -1, &hObject ); + sq_addref( m_hVM, &hObject ); + + ConvertToVariant( hObject, &Table ); + sq_pop( m_hVM, 1 ); + } + + + //------------------------------------------------------------------------------ + // Purpose: returns the number of elements in the table + // Input : hScope - the table + // Output : returns the number of elements in the table + //------------------------------------------------------------------------------ + int GetNumTableEntries( HSCRIPT hScope ) + { + if ( !hScope ) + { + sq_pushroottable( m_hVM ); + } + else + { + if ( hScope == INVALID_HSCRIPT || *((HSQOBJECT *)hScope) == INVALID_HSQOBJECT || !sq_istable( *((HSQOBJECT *)hScope) ) ) + { + return 0; + } + sq_pushobject( m_hVM, *((HSQOBJECT *)hScope) ); + } + + int nCount = sq_getsize( m_hVM, -1 ); + + sq_pop( m_hVM , 1 ); + + return nCount; + } + + + //------------------------------------------------------------------------------ + // Purpose: Gets a key / value pair from the table + // Input : hScope - the table + // nInterator - the current location inside of the table. NOTE this is nota linear representation + // Output : returns the next iterator spot, otherwise -1 if error or end of table + // pKey - the key entry + // pValue - the value entry + //------------------------------------------------------------------------------ + virtual int GetKeyValue( HSCRIPT hScope, int nIterator, ScriptVariant_t *pKey, ScriptVariant_t *pValue ) + { + HSQOBJECT KeyResult = { OT_NULL, NULL }; + HSQOBJECT ValueResult = { OT_NULL, NULL }; + + if ( !hScope ) + { + sq_pushroottable( m_hVM ); + } + else + { + if ( hScope == INVALID_HSCRIPT || *((HSQOBJECT *)hScope) == INVALID_HSQOBJECT || !sq_istable( *((HSQOBJECT *)hScope) ) ) + { + return -1; + } + sq_pushobject( m_hVM, *((HSQOBJECT *)hScope) ); + } + + intp nReturnValue; + + sq_pushinteger(m_hVM, nIterator); + + if ( SQ_SUCCEEDED(sq_next(m_hVM,-2) ) ) + { + sq_getstackobj(m_hVM,-2, &KeyResult ); + sq_getstackobj(m_hVM,-1, &ValueResult ); + sq_addref( m_hVM,&KeyResult ); + sq_addref( m_hVM,&ValueResult ); + + ConvertToVariant( KeyResult, pKey ); + ConvertToVariant( ValueResult, pValue ); + + sq_pop(m_hVM,2); //pops key and val before the nex iteration + + sq_getinteger(m_hVM, -1, &nReturnValue); + } + else + { + nReturnValue = -1; + } + sq_pop( m_hVM, 1 ); //pops the null iterator + sq_pop( m_hVM, 1 ); + + return nReturnValue; + } + + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + bool GetValue( HSCRIPT hScope, const char *pszKey, ScriptVariant_t *pValue ) + { + HSQOBJECT result = LookupObject( pszKey, hScope ); + if ( ConvertToVariant( result, pValue ) && !sq_isnull( result ) ) + { + return true; + } + __Release( result._type, result._unVal ); + return false; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + bool ClearValue( HSCRIPT hScope, const char *pszKey ) + { + if ( !hScope ) + { + sq_pushroottable( m_hVM ); + } + else + { + if ( hScope == INVALID_HSCRIPT || *((HSQOBJECT *)hScope) == INVALID_HSQOBJECT || !sq_istable( *((HSQOBJECT *)hScope) ) ) + { + return false; + } + sq_pushobject( m_hVM, *((HSQOBJECT *)hScope) ); + } + sq_pushstring( m_hVM, pszKey, -1 ); + sq_deleteslot( m_hVM, -2, false ); + sq_pop(m_hVM,1); + return false; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + virtual void ReleaseValue( ScriptVariant_t &value ) + { + if ( value.m_type == FIELD_HSCRIPT ) + { + sq_release( m_hVM, (HSQOBJECT *)value.m_hScript ); + delete ((HSQOBJECT *)value.m_hScript); + } + else + { + value.Free(); + } + value.m_type = FIELD_VOID; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + virtual bool RaiseException( const char *pszExceptionText ) + { + m_ErrorString = SQString::Create( m_hVM->_sharedstate, pszExceptionText ); + return true; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + virtual void DumpState() + { + struct CIterator : public CSQStateIterator + { + CIterator( HSQUIRRELVM hVM ) + { + indent = 0; + m_hVM = hVM; + m_bKey = false; + } + + void Indent() + { + for ( int i = 0; i < indent; i++) + { + Msg( " " ); + } + } + + virtual void PsuedoKey( const char *pszPsuedoKey ) + { + Indent(); + Msg( "%s: ", pszPsuedoKey ); + m_bKey = true; + } + + virtual void Key( SQObjectPtr &key ) + { + Indent(); + SQObjectPtr res; + m_hVM->ToString( key, res ); + Msg( "%s: ", res._unVal.pString->_val ); + m_bKey = true; + } + + virtual void Value( SQObjectPtr &value ) + { + if ( !m_bKey ) + { + Indent(); + } + m_bKey = false; + SQObjectPtr res; + m_hVM->ToString( value, res ); + if ( ISREFCOUNTED(value._type) ) + Msg( "%s [%d]\n", res._unVal.pString->_val, value._unVal.pRefCounted->_uiRef ); + else + Msg( "%s\n", res._unVal.pString->_val ); + } + + virtual bool BeginContained() + { + if ( m_bKey ) + { + Msg( "\n" ); + } + m_bKey = false; + Indent(); + Msg( "{\n" ); + indent++; + return true; + } + + virtual void EndContained() + { + indent--; + Indent(); + Msg( "}\n" ); + } + + int indent; + HSQUIRRELVM m_hVM; + bool m_bKey; + }; + + CIterator iter( m_hVM ); + m_hVM->_sharedstate->Iterate( m_hVM, &iter ); + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + virtual void WriteState( CUtlBuffer *pBuffer) + { +#ifdef VSQUIRREL_DEBUG_SERIALIZATION + Msg( "BEGIN WRITE\n" ); +#endif + m_pBuffer = pBuffer; + sq_collectgarbage( m_hVM ); + + m_pBuffer->PutInt( SAVEVERSION ); + m_pBuffer->PutInt64( (int64)m_iUniqueIdSerialNumber ); + WriteVM( m_hVM ); + + m_pBuffer = NULL; + + SQCollectable *t = m_hVM->_sharedstate->_gc_chain; + while(t) + { + t->UnMark(); + t = t->_next; + } + + m_PtrMap.Purge(); + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + virtual void ReadState( CUtlBuffer *pBuffer ) + { +#ifdef VSQUIRREL_DEBUG_SERIALIZATION +#ifdef VSQUIRREL_DEBUG_SERIALIZATION_HEAPCHK + g_pMemAlloc->CrtCheckMemory(); + int flags = g_pMemAlloc->CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ); + g_pMemAlloc->CrtSetDbgFlag( flags | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_CHECK_CRT_DF ); +#endif + Msg( "BEGIN READ\n" ); +#endif + + if ( pBuffer->GetInt() != SAVEVERSION ) + { + DevMsg( "Incompatible script version\n" ); + return; + } + sq_collectgarbage( m_hVM ); + m_hVM->_sharedstate->_gc_disableDepth++; + m_pBuffer = pBuffer; + uint64 uniqueIdSerialNumber = (uint64)m_pBuffer->GetInt64(); + m_iUniqueIdSerialNumber = max( m_iUniqueIdSerialNumber, uniqueIdSerialNumber ); + Verify( pBuffer->GetInt() == OT_THREAD ); + m_PtrMap.Insert( pBuffer->GetPtr(), m_hVM ); + ReadVM( m_hVM ); + m_pBuffer = NULL; + m_PtrMap.Purge(); + m_hVM->_sharedstate->_gc_disableDepth--; + sq_collectgarbage( m_hVM ); + +#ifdef VSQUIRREL_DEBUG_SERIALIZATION_HEAPCHK + g_pMemAlloc->CrtSetDbgFlag( flags ); +#endif + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + virtual void RemoveOrphanInstances() + { + + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + virtual void SetOutputCallback( ScriptOutputFunc_t pFunc ) + { + + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + virtual void SetErrorCallback( ScriptErrorFunc_t pFunc ) + { + + } + +private: + struct InstanceContext_t + { + void *pInstance; + ScriptClassDesc_t *pClassDesc; + SQObjectPtr name; + }; + + //--------------------------------------------------------- + // Callbacks + //--------------------------------------------------------- + static void PrintFunc(HSQUIRRELVM m_hVM,const SQChar* s,...) + { + char string[2048]; + va_list argptr; + va_start (argptr,s); + Q_vsnprintf (string,sizeof(string),s,argptr); + va_end (argptr); + + Msg( "%s", string ); + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + static SQInteger ReleaseHook( SQUserPointer p, SQInteger size ) + { + InstanceContext_t *pInstanceContext = (InstanceContext_t *)p; + pInstanceContext->pClassDesc->m_pfnDestruct( pInstanceContext->pInstance ); + delete pInstanceContext; + return 0; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + static SQInteger ExternalInstanceReleaseHook( SQUserPointer p, SQInteger size ) + { + InstanceContext_t *pInstanceContext = (InstanceContext_t *)p; + delete pInstanceContext; + return 0; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + static SQInteger GetFunctionSignature( HSQUIRRELVM hVM ) + { + StackHandler sa(hVM); + if ( sa.GetParamCount() != 3 ) + { + return 0; + } + + HSQOBJECT hFunction = sa.GetObjectHandle( 2 ); + if ( !sq_isclosure( hFunction ) ) + { + return 0; + } + + char result[ 512 ] = {0}; + const char *pszName = sa.GetString( 3 ); + SQClosure *pClosure = hFunction._unVal.pClosure; + SQFunctionProto *pProto = pClosure->_function._unVal.pFunctionProto; + + V_strcat_safe( result, + "function " ); + if ( pszName && *pszName ) + { + V_strcat_safe( result, + pszName ); + } + else if ( sq_isstring( pProto->_name ) ) + { + V_strcat_safe( result, + pProto->_name._unVal.pString->_val ); + } + else + { + V_strcat_safe( result, + "" ); + } + V_strcat_safe( result, + "(" ); + + for ( int i = 1; i < pProto->_nparameters; i++ ) + { + if ( i != 1 ) + { + V_strcat_safe( result, + ", " ); + } + if ( sq_isstring( pProto->_parameters[i] ) ) + { + V_strcat_safe( result, + pProto->_parameters[i]._unVal.pString->_val ); + } + else + { + V_strcat_safe( result, + "arg" ); + } + } + V_strcat_safe( result, + ")" ); + + result[ sizeof( result ) - 1 ] = 0; + sa.Return( result ); + + return 1; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + static SQInteger GetDeveloper( HSQUIRRELVM hVM ) + { + StackHandler sa(hVM); + sa.Return( ((CSquirrelVM *)hVM->_sharedstate->m_pOwnerData)->developer.GetInt() ); + return 1; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + static SQInteger CallConstructor( HSQUIRRELVM hVM ) + { + StackHandler sa(hVM); + int nActualParams = sa.GetParamCount(); + ScriptClassDesc_t *pClassDesc = *((ScriptClassDesc_t **)sa.GetUserData( nActualParams )); + InstanceContext_t *pInstanceContext = new InstanceContext_t; + pInstanceContext->pInstance = pClassDesc->m_pfnConstruct(); + pInstanceContext->pClassDesc = pClassDesc; + sq_setinstanceup(hVM, 1, pInstanceContext); + sq_setreleasehook( hVM, 1, &ReleaseHook ); + return 0; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + static SQInteger TranslateCall( HSQUIRRELVM hVM ) + { + StackHandler sa(hVM); + int nActualParams = sa.GetParamCount(); + ScriptFunctionBinding_t *pVMScriptFunction = *((ScriptFunctionBinding_t **)sa.GetUserData( nActualParams )); + int nFormalParams = pVMScriptFunction->m_desc.m_Parameters.Count(); + CUtlVectorFixed params; + ScriptVariant_t returnValue; + bool bCallFree = false; + + params.SetSize( nFormalParams ); + + int i = 0; + + if ( nActualParams ) + { + int iLimit = MIN( nActualParams, nFormalParams ); + ScriptDataType_t *pCurParamType = pVMScriptFunction->m_desc.m_Parameters.Base(); + for ( i = 0; i < iLimit; i++, pCurParamType++ ) + { + switch ( *pCurParamType ) + { + case FIELD_FLOAT: params[i] = sa.GetFloat( i + 2 ); break; + case FIELD_CSTRING: params[i] = sa.GetString( i + 2 ); break; + case FIELD_VECTOR: + { + Vector *pVector = (Vector *)sa.GetInstanceUp( i + 2, TYPETAG_VECTOR ); + if ( pVector ) + { + params[i] = pVector; + break; + } + else + { + sq_throwerror( hVM, "Vector argument expected" ); + return SQ_ERROR; + } + } + case FIELD_INTEGER: params[i] = sa.GetInt( i + 2 ); break; + case FIELD_BOOLEAN: params[i] = sa.GetBool( i + 2 ); break; + case FIELD_CHARACTER: params[i] = sa.GetString( i + 2 )[0]; break; + case FIELD_HSCRIPT: + { + HSQOBJECT object = sa.GetObjectHandle( i+2 ); + if ( object._type == OT_NULL) + { + params[i] = (HSCRIPT)NULL; + } + else + { + HSQOBJECT *pObject = new HSQOBJECT; + *pObject = object; + params[i] = (HSCRIPT)pObject; + params[i].m_flags |= SV_FREE; + bCallFree = true; + } + break; + } + default: break; + } + } + } + +#ifdef _DEBUG + for ( ; i < nFormalParams; i++ ) + { + Assert( params[i].IsNull() ); + } +#endif + + InstanceContext_t *pContext; + void *pObject; + + if ( pVMScriptFunction->m_flags & SF_MEMBER_FUNC ) + { + pContext = (InstanceContext_t *)sa.GetInstanceUp(1,0); + + if ( !pContext ) + { + sq_throwerror( hVM, "Accessed null instance" ); + return SQ_ERROR; + } + + pObject = pContext->pInstance; + + if ( !pObject ) + { + sq_throwerror( hVM, "Accessed null instance" ); + return SQ_ERROR; + } + + if ( pContext->pClassDesc->pHelper ) + { + pObject = pContext->pClassDesc->pHelper->GetProxied( pObject ); + } + + if ( !pObject ) + { + sq_throwerror( hVM, "Accessed null instance" ); + return SQ_ERROR; + } + } + else + { + pObject = NULL; + } + + (*pVMScriptFunction->m_pfnBinding)( pVMScriptFunction->m_pFunction, pObject, params.Base(), params.Count(), ( pVMScriptFunction->m_desc.m_ReturnType != FIELD_VOID ) ? &returnValue : NULL ); + + if ( pVMScriptFunction->m_desc.m_ReturnType != FIELD_VOID ) + { + switch ( returnValue.m_type ) + { + case FIELD_FLOAT: sa.Return( (float)returnValue ); break; + case FIELD_CSTRING: sa.Return( (const char *)returnValue ); break; + case FIELD_VECTOR: + { + sq_pushobject( hVM, ((CSquirrelVM *)hVM->_sharedstate->m_pOwnerData)->m_hClassVector ); + sq_createinstance( hVM, -1 ); + sq_setinstanceup( hVM, -1, (SQUserPointer)returnValue.m_pVector ); + sq_setreleasehook( hVM, -1, &VectorRelease ); + sq_remove( hVM, -2 ); + break; + } + case FIELD_INTEGER: sa.Return( (int)returnValue ); break; + case FIELD_BOOLEAN: sa.Return( (bool)returnValue ); break; + case FIELD_CHARACTER: Assert( 0 ); sq_pushnull( hVM ); break; + case FIELD_HSCRIPT: + { + if ( returnValue.m_hScript ) + { + sq_pushobject( hVM, *((HSQOBJECT *)returnValue.m_hScript) ); + } + else + { + sq_pushnull( hVM ); + } + break; + } + default: sq_pushnull( hVM ); break; + } + } + + if ( bCallFree ) + { + for ( i = 0; i < params.Count(); i++ ) + { + params[i].Free(); + } + } + + if ( !sq_isnull( ((CSquirrelVM *)hVM->_sharedstate->m_pOwnerData)->m_ErrorString ) ) + { + if ( sq_isstring( ((CSquirrelVM *)hVM->_sharedstate->m_pOwnerData)->m_ErrorString ) ) + { + sq_throwerror( hVM, ((CSquirrelVM *)hVM->_sharedstate->m_pOwnerData)->m_ErrorString._unVal.pString->_val ); + } + else + { + sq_throwerror( hVM, "Internal error" ); + } + ((CSquirrelVM *)hVM->_sharedstate->m_pOwnerData)->m_ErrorString = _null_; + return SQ_ERROR; + } + + return ( pVMScriptFunction->m_desc.m_ReturnType != FIELD_VOID ); + } + + //------------------------------------------------------------- + + static int QueryContinue( HSQUIRRELVM hVM ) + { + CSquirrelVM *pVM = ((CSquirrelVM *)hVM->_sharedstate->m_pOwnerData); + if ( !pVM->m_hDbg ) + { + if ( pVM->m_TimeStartExecute != 0.0f && Plat_FloatTime() - pVM->m_TimeStartExecute > 0.03f ) + { + DevMsg( "Script running too long, terminating\n" ); + // @TODO: Mark the offending closure so that it won't be executed again [5/13/2008 tom] + return SQ_QUERY_BREAK; + } + } + return SQ_QUERY_CONTINUE; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + static SQInteger InstanceToString( HSQUIRRELVM hVM ) + { + StackHandler sa(hVM); + InstanceContext_t *pContext = (InstanceContext_t *)sa.GetInstanceUp(1,0); + char szBuf[64]; + + if ( pContext && pContext->pInstance && pContext->pClassDesc->pHelper && pContext->pClassDesc->pHelper->ToString( pContext->pInstance, szBuf, ARRAYSIZE(szBuf) ) ) + { + sa.Return( szBuf ); + } + else + { + HSQOBJECT hInstance = sa.GetObjectHandle( 1 ); + sq_pushstring( hVM, CFmtStr( "(instance : 0x%p)", (void*)_rawval(hInstance) ), -1 ); + } + return 1; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + static SQInteger InstanceIsValid( HSQUIRRELVM hVM ) + { + StackHandler sa(hVM); + InstanceContext_t *pContext = (InstanceContext_t *)sa.GetInstanceUp(1,0); + sq_pushbool( hVM, ( pContext && pContext->pInstance ) ); + return 1; + } + + + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + HSQOBJECT CreateClass( ScriptClassDesc_t *pDesc ) + { + int oldtop = sq_gettop(m_hVM); + sq_pushroottable(m_hVM); + sq_pushstring(m_hVM,pDesc->m_pszScriptName,-1); + if (pDesc->m_pBaseDesc) + { + sq_pushstring(m_hVM,pDesc->m_pBaseDesc->m_pszScriptName,-1); + if (SQ_FAILED(sq_get(m_hVM,-3))) + { // Make sure the base exists if specified by baseName. + sq_settop(m_hVM,oldtop); + return INVALID_HSQOBJECT; + } + } + + if (SQ_FAILED(sq_newclass(m_hVM,pDesc->m_pBaseDesc ? 1 : 0))) + { // Will inherit from base class on stack from sq_get() above. + sq_settop(m_hVM,oldtop); + return INVALID_HSQOBJECT; + } + HSQOBJECT hObject; + sq_getstackobj(m_hVM,-1, &hObject); + sq_addref(m_hVM, &hObject); + sq_settypetag(m_hVM,-1,pDesc); + sq_createslot(m_hVM,-3); + sq_pop(m_hVM,1); + return hObject; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void RegisterFunctionGuts( ScriptFunctionBinding_t *pScriptFunction, ScriptClassDesc_t *pClassDesc = NULL ) + { + char szTypeMask[64]; + + if ( pScriptFunction->m_desc.m_Parameters.Count() > ARRAYSIZE(szTypeMask) - 1 ) + { + AssertMsg1( 0, "Too many agruments for script function %s\n", pScriptFunction->m_desc.m_pszFunction ); + return; + } + + szTypeMask[0] = '.'; + char *pCurrent = &szTypeMask[1]; + for ( int i = 0; i < pScriptFunction->m_desc.m_Parameters.Count(); i++, pCurrent++ ) + { + switch ( pScriptFunction->m_desc.m_Parameters[i] ) + { + case FIELD_CSTRING: + *pCurrent = 's'; + break; + case FIELD_FLOAT: + case FIELD_INTEGER: + *pCurrent = 'n'; + break; + case FIELD_BOOLEAN: + *pCurrent = 'b'; + break; + + case FIELD_VECTOR: + *pCurrent = 'x'; + break; + + case FIELD_HSCRIPT: + *pCurrent = '.'; + break; + + case FIELD_CHARACTER: + default: + *pCurrent = FIELD_VOID; + AssertMsg( 0 , "Not supported" ); + break; + } + } + Assert( pCurrent - szTypeMask < ARRAYSIZE(szTypeMask) - 1 ); + *pCurrent = 0; + sq_pushstring( m_hVM, pScriptFunction->m_desc.m_pszScriptName, -1 ); + ScriptFunctionBinding_t **pVMScriptFunction = (ScriptFunctionBinding_t **)sq_newuserdata(m_hVM, sizeof(ScriptFunctionBinding_t *)); + *pVMScriptFunction = pScriptFunction; + sq_newclosure( m_hVM, &TranslateCall, 1 ); + HSQOBJECT hFunction; + sq_getstackobj( m_hVM, -1, &hFunction ); + sq_setnativeclosurename(m_hVM, -1, pScriptFunction->m_desc.m_pszScriptName ); + sq_setparamscheck( m_hVM, pScriptFunction->m_desc.m_Parameters.Count() + 1, szTypeMask ); + sq_createslot( m_hVM, -3 ); + + if ( developer.GetInt() ) + { + const char *pszHide = SCRIPT_HIDE; + if ( !pScriptFunction->m_desc.m_pszDescription || *pScriptFunction->m_desc.m_pszDescription != *pszHide ) + { + char name[512] = {0}; + char signature[512] = {0}; + + if ( pClassDesc ) + { + V_strcat_safe( name, + pClassDesc->m_pszScriptName ); + V_strcat_safe( name, + "::" ); + } + + V_strcat_safe( name, + pScriptFunction->m_desc.m_pszScriptName ); + + V_strcat_safe( signature, + FieldTypeToString( pScriptFunction->m_desc.m_ReturnType ) ); + V_strcat_safe( signature, + " " ); + V_strcat_safe( signature, + name ); + V_strcat_safe( signature, + "(" ); + for ( int i = 0; i < pScriptFunction->m_desc.m_Parameters.Count(); i++ ) + { + if ( i != 0 ) + { + V_strcat_safe( signature, + ", " ); + } + + V_strcat_safe( signature, + FieldTypeToString( pScriptFunction->m_desc.m_Parameters[i] ) ); + } + V_strcat_safe( signature, + ")" ); + + sq_pushobject( m_hVM, LookupObject( "RegisterFunctionDocumentation", NULL, false ) ); + sq_pushroottable( m_hVM ); + sq_pushobject( m_hVM, hFunction ); + sq_pushstring( m_hVM, name, -1 ); + sq_pushstring( m_hVM, signature, -1 ); + sq_pushstring( m_hVM, pScriptFunction->m_desc.m_pszDescription, -1 ); + sq_call( m_hVM, 5, false, /*false*/ true ); + sq_pop( m_hVM, 1 ); + } + } + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void ReleaseScriptObject( HSCRIPT hScript ) + { + if ( hScript ) + { + HSQOBJECT *pScript = (HSQOBJECT *)hScript; + sq_release( m_hVM, pScript ); + delete pScript; + } + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void PushVariant( const ScriptVariant_t &value, bool bCopy = false ) + { + switch ( value.m_type ) + { + case FIELD_VOID: sq_pushnull( m_hVM ); break; + case FIELD_FLOAT: sq_pushfloat( m_hVM, value ); break; + case FIELD_CSTRING: sq_pushstring( m_hVM, value, strlen( value.m_pszString ) ); break; + case FIELD_VECTOR: + { + // @TODO: should make a pool of these and reuse [4/22/2008 tom] + sq_pushobject( m_hVM, m_hClassVector ); + sq_createinstance( m_hVM, -1 ); + if ( !bCopy ) + { + sq_setinstanceup( m_hVM, -1, (SQUserPointer)value.m_pVector ); + } + else + { + sq_setinstanceup( m_hVM, -1, (SQUserPointer)new Vector( *value.m_pVector ) ); + sq_setreleasehook( m_hVM, -1, &VectorRelease ); + } + sq_remove( m_hVM, -2 ); + break; + } + case FIELD_INTEGER: sq_pushinteger( m_hVM, value ); break; + case FIELD_BOOLEAN: sq_pushbool( m_hVM, value.m_bool ); break; + case FIELD_CHARACTER: { char sz[2]; sz[0] = value.m_char; sz[1] = 0; sq_pushstring( m_hVM, sz, 1 ); break; } + case FIELD_HSCRIPT: if ( value.m_hScript ) sq_pushobject( m_hVM, *((HSQOBJECT *)value.m_hScript) ); else sq_pushnull( m_hVM ); break; + } + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + bool ConvertToVariant( HSQOBJECT object, ScriptVariant_t *pReturn ) + { + switch ( object._type ) + { + case OT_NULL: pReturn->m_type = FIELD_VOID; break; + case OT_INTEGER: *pReturn = object._unVal.nInteger; break; + case OT_FLOAT: *pReturn = object._unVal.fFloat; break; + case OT_BOOL: *pReturn = (object._unVal.nInteger != 0); break; + case OT_STRING: + { + int size = object._unVal.pString->_len + 1; + pReturn->m_type = FIELD_CSTRING; + pReturn->m_pszString = new char[size]; + memcpy( (void *)pReturn->m_pszString, object._unVal.pString->_val, size ); + pReturn->m_flags |= SV_FREE; + } + break; + case OT_INSTANCE: + { + SQUserPointer pVector; + sq_pushobject( m_hVM, object ); + SQRESULT getResult = sq_getinstanceup( m_hVM, -1, &pVector, TYPETAG_VECTOR ); + sq_poptop( m_hVM ); + if ( getResult == SQ_OK ) + { + pReturn->m_type = FIELD_VECTOR; + pReturn->m_pVector = new Vector( *((Vector *)pVector) ); + pReturn->m_flags |= SV_FREE; + break; + } + } + // fall through + default: + { + pReturn->m_type = FIELD_HSCRIPT; + HSQOBJECT *pObject = new HSQOBJECT; + *pObject = object; + pReturn->m_hScript = (HSCRIPT)pObject; + } + } + return true; + } + + //------------------------------------------------------------------------- + // Serialization + //------------------------------------------------------------------------- + enum + { + SAVEVERSION = 2 + }; + + void WriteObject( const SQObjectPtr &object ) + { + switch ( object._type ) + { + case OT_NULL: + m_pBuffer->PutInt( OT_NULL ); + break; + case OT_INTEGER: + m_pBuffer->PutInt( OT_INTEGER ); + m_pBuffer->PutInt( object._unVal.nInteger ); + break; + case OT_FLOAT: + m_pBuffer->PutInt( OT_FLOAT ); + m_pBuffer->PutFloat( object._unVal.fFloat); + break; + case OT_BOOL: + m_pBuffer->PutInt( OT_BOOL ); + m_pBuffer->PutInt( object._unVal.nInteger ); + break; + case OT_STRING: + m_pBuffer->PutInt( OT_STRING ); + m_pBuffer->PutInt( object._unVal.pString->_len ); + m_pBuffer->PutString( object._unVal.pString->_val ); + break; + case OT_TABLE: WriteTable( object._unVal.pTable ); break; + case OT_ARRAY: WriteArray( object._unVal.pArray ); break; + case OT_USERDATA: WriteUserData( object._unVal.pUserData ); break; + case OT_CLOSURE: WriteClosure( object._unVal.pClosure ); break; + case OT_NATIVECLOSURE: WriteNativeClosure( object._unVal.pNativeClosure ); break; + case OT_GENERATOR: WriteGenerator( object._unVal.pGenerator ); break; + case OT_USERPOINTER: WriteUserPointer( object._unVal.pUserPointer ); break; + case OT_THREAD: WriteVM( object._unVal.pThread ); break; + case OT_FUNCPROTO: WriteFuncProto( object._unVal.pFunctionProto ); break; + case OT_CLASS: WriteClass( object._unVal.pClass ); break; + case OT_INSTANCE: WriteInstance( object._unVal.pInstance ); break; + case OT_WEAKREF: WriteWeakRef( object._unVal.pWeakRef ); break; + default: Assert( 0 ); break; + } + +#ifdef VSQUIRREL_DEBUG_SERIALIZATION + SQObjectPtr res; + m_hVM->ToString( object, res ); + Msg( "%d: %s\n", m_pBuffer->TellPut(), res._unVal.pString->_val ); +#endif + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void WriteVM( SQVM *pVM ) + { + unsigned i; + + m_pBuffer->PutInt( OT_THREAD ); + m_pBuffer->PutPtr( pVM ); + + if ( pVM->_uiRef & MARK_FLAG ) + return; + pVM->_uiRef |= MARK_FLAG; + + WriteObject( pVM->_roottable ); + m_pBuffer->PutInt( pVM->_top ); + m_pBuffer->PutInt( pVM->_stackbase ); + m_pBuffer->PutUnsignedInt( pVM->_stack.size() ); + for( i = 0; i < pVM->_stack.size(); i++ ) + { + WriteObject( pVM->_stack[i] ); + } + m_pBuffer->PutUnsignedInt( pVM->_vargsstack.size() ); + for( i = 0; i < pVM->_vargsstack.size(); i++ ) + { + WriteObject( pVM->_vargsstack[i] ); + } + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void WriteArray( SQArray *pArray ) + { + m_pBuffer->PutInt( OT_ARRAY ); + m_pBuffer->PutPtr( pArray ); + + if ( pArray->_uiRef & MARK_FLAG ) + return; + pArray->_uiRef |= MARK_FLAG; + + int len = pArray->_values.size(); + m_pBuffer->PutInt( len ); + for ( int i = 0; i < len; i++ ) + WriteObject( pArray->_values[i] ); + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void WriteTable( SQTable *pTable ) + { + m_pBuffer->PutInt( OT_TABLE ); + m_pBuffer->PutPtr( pTable ); + + if ( pTable->_uiRef & MARK_FLAG ) + return; + pTable->_uiRef |= MARK_FLAG; + + m_pBuffer->PutInt( pTable->_delegate != NULL ); + if ( pTable->_delegate ) + { + WriteObject( pTable->_delegate ); + } + + int len = pTable->_numofnodes; + m_pBuffer->PutInt( len ); + for(int i = 0; i < len; i++) + { + WriteObject( pTable->_nodes[i].key ); + WriteObject( pTable->_nodes[i].val ); + } + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void WriteClass( SQClass *pClass ) + { + m_pBuffer->PutInt( OT_CLASS ); + m_pBuffer->PutPtr( pClass ); + + if ( !pClass || ( pClass->_uiRef & MARK_FLAG ) ) + return; + pClass->_uiRef |= MARK_FLAG; + + bool bIsNative = ( pClass->_typetag != NULL ); + unsigned i; + if ( !bIsNative ) + { + for( i = 0; i < pClass->_methods.size(); i++) + { + if ( sq_isnativeclosure( pClass->_methods[i].val ) ) + { + bIsNative = true; + break; + } + } + } + m_pBuffer->PutInt( bIsNative ); + if ( !bIsNative ) + { + m_pBuffer->PutInt( pClass->_base != NULL ); + if ( pClass->_base ) + { + WriteObject( pClass->_base ); + } + + WriteObject( pClass->_members ); + WriteObject( pClass->_attributes ); + m_pBuffer->PutInt( pClass->_defaultvalues.size() ); + for( i = 0; i< pClass->_defaultvalues.size(); i++) + { + WriteObject(pClass->_defaultvalues[i].val); + WriteObject(pClass->_defaultvalues[i].attrs); + } + m_pBuffer->PutInt( pClass->_methods.size() ); + for( i = 0; i < pClass->_methods.size(); i++) + { + WriteObject(pClass->_methods[i].val); + WriteObject(pClass->_methods[i].attrs); + } + m_pBuffer->PutInt( pClass->_metamethods.size() ); + for( i = 0; i < pClass->_metamethods.size(); i++) + { + WriteObject(pClass->_metamethods[i]); + } + } + else + { + if ( pClass->_typetag ) + { + if ( pClass->_typetag == TYPETAG_VECTOR ) + { + m_pBuffer->PutString( "Vector" ); + } + else + { + ScriptClassDesc_t *pDesc = (ScriptClassDesc_t *)pClass->_typetag; + m_pBuffer->PutString( pDesc->m_pszScriptName ); + } + } + else + { + // Have to grovel for the name + SQObjectPtr key; + if ( FindKeyForObject( m_hVM->_roottable, pClass, key ) ) + { + m_pBuffer->PutString( key._unVal.pString->_val ); + } + else + { + Assert( 0 ); + m_pBuffer->PutString( "" ); + } + } + } + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void WriteInstance( SQInstance *pInstance ) + { + m_pBuffer->PutInt( OT_INSTANCE ); + m_pBuffer->PutPtr( pInstance ); + + if ( pInstance->_uiRef & MARK_FLAG ) + return; + pInstance->_uiRef |= MARK_FLAG; + + WriteObject( pInstance->_class ); + + unsigned nvalues = pInstance->_class->_defaultvalues.size(); + m_pBuffer->PutInt( nvalues ); + for ( unsigned i =0; i< nvalues; i++ ) + { + WriteObject( pInstance->_values[i] ); + } + + m_pBuffer->PutPtr( pInstance->_class->_typetag ); + + if ( pInstance->_class->_typetag ) + { + if ( pInstance->_class->_typetag == TYPETAG_VECTOR ) + { + Vector *pVector = (Vector *)pInstance->_userpointer; + m_pBuffer->PutFloat( pVector->x ); + m_pBuffer->PutFloat( pVector->y ); + m_pBuffer->PutFloat( pVector->z ); + } + else + { + InstanceContext_t *pContext = ((InstanceContext_t *)pInstance->_userpointer); + WriteObject( pContext->name ); + m_pBuffer->PutPtr( pContext->pInstance ); + } + } + else + { + WriteUserPointer( NULL ); + } + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void WriteGenerator( SQGenerator *pGenerator ) + { + ExecuteOnce( Msg( "Save load of generators not well tested. caveat emptor\n" ) ); + WriteObject(pGenerator->_closure); + + m_pBuffer->PutInt( OT_GENERATOR ); + m_pBuffer->PutPtr( pGenerator ); + + if ( pGenerator->_uiRef & MARK_FLAG ) + return; + pGenerator->_uiRef |= MARK_FLAG; + + WriteObject( pGenerator->_closure ); + m_pBuffer->PutInt( pGenerator->_stack.size() ); + for(SQUnsignedInteger i = 0; i < pGenerator->_stack.size(); i++) WriteObject(pGenerator->_stack[i]); + m_pBuffer->PutInt( pGenerator->_vargsstack.size() ); + for(SQUnsignedInteger j = 0; j < pGenerator->_vargsstack.size(); j++) WriteObject(pGenerator->_vargsstack[j]); + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void WriteClosure( SQClosure *pClosure ) + { + m_pBuffer->PutInt( OT_CLOSURE ); + m_pBuffer->PutPtr( pClosure ); + if ( pClosure->_uiRef & MARK_FLAG ) + return; + pClosure->_uiRef |= MARK_FLAG; + + WriteObject( pClosure->_function ); + WriteObject( pClosure->_env ); + + m_pBuffer->PutInt( pClosure->_outervalues.size() ); + for(SQUnsignedInteger i = 0; i < pClosure->_outervalues.size(); i++) WriteObject(pClosure->_outervalues[i]); + m_pBuffer->PutInt( pClosure->_defaultparams.size() ); + for(SQUnsignedInteger i = 0; i < pClosure->_defaultparams.size(); i++) WriteObject(pClosure->_defaultparams[i]); + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void WriteNativeClosure( SQNativeClosure *pNativeClosure ) + { + m_pBuffer->PutInt( OT_NATIVECLOSURE ); + m_pBuffer->PutPtr( pNativeClosure ); + + if ( pNativeClosure->_uiRef & MARK_FLAG ) + return; + pNativeClosure->_uiRef |= MARK_FLAG; + + WriteObject( pNativeClosure->_name ); + return; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void WriteUserData( SQUserData *pUserData ) + { + m_pBuffer->PutInt( OT_USERDATA ); + m_pBuffer->PutPtr( pUserData ); + + if ( pUserData->_uiRef & MARK_FLAG ) + return; + pUserData->_uiRef |= MARK_FLAG; + + // Need to call back or something. Unsure, TBD. [4/3/2008 tom] + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void WriteUserPointer( SQUserPointer pUserPointer ) + { + m_pBuffer->PutInt( OT_USERPOINTER ); + // Need to call back or something. Unsure, TBD. [4/3/2008 tom] + m_pBuffer->PutPtr( pUserPointer ); + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + static SQInteger SqWriteFunc(SQUserPointer up,SQUserPointer data, SQInteger size) + { + CSquirrelVM *pThis = (CSquirrelVM *)up; + pThis->m_pBuffer->Put( data, size ); + return size; + } + + void WriteFuncProto( SQFunctionProto *pFuncProto ) + { + m_pBuffer->PutInt( OT_FUNCPROTO ); + m_pBuffer->PutPtr( pFuncProto ); + + // Using the map to track these as they're not collectables + if ( m_PtrMap.Find( pFuncProto ) != m_PtrMap.InvalidIndex() ) + { + return; + } + m_PtrMap.Insert( pFuncProto, pFuncProto ); + + pFuncProto->Save( m_hVM, this, &SqWriteFunc ); + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void WriteWeakRef( SQWeakRef *pWeakRef ) + { + m_pBuffer->PutInt( OT_WEAKREF ); + WriteObject( pWeakRef->_obj ); + } + + //-------------------------------------------------------- + template + bool BeginRead( T **ppOld, T **ppNew ) + { + *ppOld = (T *)m_pBuffer->GetPtr(); + if ( *ppOld ) + { + int iNew = m_PtrMap.Find( *ppOld ); + if ( iNew != m_PtrMap.InvalidIndex() ) + { + *ppNew = (T*)m_PtrMap[iNew]; + return false; + } + } + *ppNew = NULL; + return true; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void MapPtr( void *pOld, void *pNew ) + { + Assert( m_PtrMap.Find( pOld ) == m_PtrMap.InvalidIndex() ); + m_PtrMap.Insert( pOld, pNew ); + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + bool ReadObject( SQObjectPtr &objectOut, const char *pszName = NULL ) + { + SQObject object; + bool bResult = true; + object._type = (SQObjectType)m_pBuffer->GetInt(); + if ( _RAW_TYPE(object._type) < _RT_TABLE ) + { + switch ( object._type ) + { + case OT_NULL: + object._unVal.pUserPointer = 0; + break; + case OT_INTEGER: + object._unVal.nInteger = m_pBuffer->GetInt(); + break; + case OT_FLOAT: + object._unVal.fFloat = m_pBuffer->GetFloat(); + break; + case OT_BOOL: + object._unVal.nInteger = m_pBuffer->GetInt(); + break; + case OT_STRING: + { + int len = m_pBuffer->GetInt(); + char *pString = (char *)stackalloc( len + 1 ); + m_pBuffer->GetString( pString, len + 1 ); + pString[len] = 0; + object._unVal.pString = SQString::Create( m_hVM->_sharedstate, pString, len ); + break; + } + default: + Assert( 0 ); + break; + } + } + else + { + switch ( object._type ) + { + case OT_TABLE: + { + object._unVal.pTable = ReadTable(); + break; + } + case OT_ARRAY: + { + object._unVal.pArray = ReadArray(); + break; + } + case OT_USERDATA: + { + object._unVal.pUserData = ReadUserData(); + break; + } + case OT_CLOSURE: + { + object._unVal.pClosure = ReadClosure(); + break; + } + case OT_NATIVECLOSURE: + { + object._unVal.pNativeClosure = ReadNativeClosure(); + break; + } + case OT_GENERATOR: + { + object._unVal.pGenerator = ReadGenerator(); + break; + } + case OT_USERPOINTER: + { + object._unVal.pUserPointer = ReadUserPointer(); + break; + } + case OT_THREAD: + { + object._unVal.pThread = ReadVM(); + break; + } + case OT_FUNCPROTO: + { + object._unVal.pFunctionProto = ReadFuncProto(); + break; + } + case OT_CLASS: + { + object._unVal.pClass = ReadClass(); + break; + } + case OT_INSTANCE: + { + object._unVal.pInstance = ReadInstance(); + if ( !object._unVal.pInstance ) + { + // Look for a match in the current root table + HSQOBJECT hExistingObject = LookupObject( pszName, NULL, false ); + if ( sq_isinstance( hExistingObject ) ) + { + object._unVal.pInstance = hExistingObject._unVal.pInstance; + } + } + break; + } + case OT_WEAKREF: + { + object._unVal.pWeakRef = ReadWeakRef(); + break; + } + default: + { + object._unVal.pUserPointer = NULL; + Assert( 0 ); + } + } + if ( !object._unVal.pUserPointer ) + { + DevMsg( "Failed to restore a Squirrel object of type %s\n", SQTypeToString( object._type ) ); + object._type = OT_NULL; + bResult = false; + } + } + +#ifdef VSQUIRREL_DEBUG_SERIALIZATION + lastType = object._type; + SQObjectPtr res; + if ( ISREFCOUNTED(object._type) ) + { + SQ_VALIDATE_REF_COUNT( object._unVal.pRefCounted ); + object._unVal.pRefCounted->_uiRef++; + } + m_hVM->ToString( object, res ); + if ( ISREFCOUNTED(object._type) ) + { + object._unVal.pRefCounted->_uiRef--; + SQ_VALIDATE_REF_COUNT( object._unVal.pRefCounted ); + } + Msg( "%d: %s [%d]\n", m_pBuffer->TellGet(), res._unVal.pString->_val, ( ISREFCOUNTED(object._type) ) ? object._unVal.pRefCounted->_uiRef : -1 ); +#ifdef VSQUIRREL_DEBUG_SERIALIZATION_HEAPCHK + _heapchk(); +#endif +#endif + objectOut = object; + return bResult; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + SQVM *ReadVM() + { + SQVM *pVM = sq_newthread( m_hVM, MIN_STACK_OVERHEAD + 2 ); + m_hVM->Pop(); + return pVM; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + void ReadVM( SQVM *pVM ) + { + unsigned i; + + ReadObject( pVM->_roottable ); + pVM->_top = m_pBuffer->GetInt(); + pVM->_stackbase = m_pBuffer->GetInt(); + unsigned stackSize = m_pBuffer->GetUnsignedInt(); + pVM->_stack.resize( stackSize ); + for( i = 0; i < pVM->_stack.size(); i++ ) + { + ReadObject( pVM->_stack[i] ); + } + stackSize = m_pBuffer->GetUnsignedInt(); + for( i = 0; i < pVM->_vargsstack.size(); i++ ) + { + ReadObject( pVM->_vargsstack[i] ); + } + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + SQTable *ReadTable() + { + SQTable *pOld; + SQTable *pTable; + + if ( !BeginRead( &pOld, &pTable ) ) + { + return pTable; + } + + pTable = SQTable::Create(_ss(m_hVM), 0); + + MapPtr( pOld, pTable ); + + if ( m_pBuffer->GetInt() ) + { + SQObjectPtr delegate; + ReadObject( delegate ); + pTable->SetDelegate( delegate._unVal.pTable ); + } + else + { + pTable->_delegate = NULL; + } + int n = m_pBuffer->GetInt(); + while ( n-- ) + { + SQObjectPtr key, value; + ReadObject( key ); + if ( !ReadObject( value, ( key._type == OT_STRING ) ? key._unVal.pString->_val : NULL ) ) + { + DevMsg( "Failed to read Squirrel table entry %s\n", ( key._type == OT_STRING ) ? key._unVal.pString->_val : SQTypeToString( key._type ) ); + } + if ( key._type != OT_NULL ) + { + pTable->NewSlot( key, value ); + } + } + return pTable; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + SQArray *ReadArray() + { + SQArray *pOld; + SQArray *pArray; + if ( !BeginRead( &pOld, &pArray ) ) + { + return pArray; + } + + pArray = SQArray::Create(_ss(m_hVM), 0); + + MapPtr( pOld, pArray ); + + int n = m_pBuffer->GetInt(); + pArray->Reserve( n ); + + while ( n-- ) + { + SQObjectPtr value; + ReadObject( value ); + pArray->Append( value ); + } + return pArray; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + SQClass *ReadClass() + { + SQClass *pOld; + SQClass *pClass; + if ( !BeginRead( &pOld, &pClass ) ) + { + return pClass; + } + + SQClass *pBase = NULL; + bool bIsNative = !!m_pBuffer->GetInt(); + // If it's not a C++ defined type... + if ( !bIsNative ) + { + if ( m_pBuffer->GetInt() ) + { + SQObjectPtr base; + ReadObject( base ); + pBase = base._unVal.pClass; + } + + SQClass *pClass = SQClass::Create( _ss(m_hVM), pBase ); + MapPtr( pOld, pClass ); + + SQObjectPtr members; + ReadObject( members ); + pClass->_members->Release(); + pClass->_members = members._unVal.pTable; + __ObjAddRef( members._unVal.pTable ); + + ReadObject( pClass->_attributes ); + unsigned i, n; + + n = m_pBuffer->GetUnsignedInt(); + pClass->_defaultvalues.resize( n ); + for ( i = 0; i < n; i++ ) + { + ReadObject(pClass->_defaultvalues[i].val); + ReadObject(pClass->_defaultvalues[i].attrs); + } + + n = m_pBuffer->GetUnsignedInt(); + pClass->_methods.resize( n ); + for ( i = 0; i < n; i++ ) + { + ReadObject(pClass->_methods[i].val); + ReadObject(pClass->_methods[i].attrs); + } + + n = m_pBuffer->GetUnsignedInt(); + pClass->_metamethods.resize( n ); + for ( i = 0; i < n; i++ ) + { + ReadObject(pClass->_metamethods[i]); + } + return pClass; + } + else + { + char *pszName = (char *)stackalloc( 1024 ); + m_pBuffer->GetString( pszName, 1024 ); + pszName[1023] = 0; + + SQObjectPtr value; + if ( m_hVM->_roottable._unVal.pTable->Get( SQString::Create( _ss(m_hVM ), pszName ), value ) && sq_isclass( value ) ) + { + MapPtr( pOld, value._unVal.pClass ); + return value._unVal.pClass; + } + MapPtr( pOld, NULL ); + } + return NULL; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + SQInstance *ReadInstance() + { + SQInstance *pOld; + SQInstance *pInstance; + if ( !BeginRead( &pOld, &pInstance ) ) + { + return pInstance; + } + + SQObjectPtr pClass; + ReadObject( pClass ); + + unsigned i, n; + if ( pClass._unVal.pClass ) + { + pInstance = SQInstance::Create( _ss(m_hVM), pClass._unVal.pClass ); + + n = m_pBuffer->GetUnsignedInt(); + for ( i = 0; i < n; i++ ) + { + ReadObject(pInstance->_values[i]); + } + m_pBuffer->GetPtr(); // ignored in this path + if ( pInstance->_class->_typetag ) + { + if ( pInstance->_class->_typetag == TYPETAG_VECTOR ) + { + Vector *pValue = new Vector; + pValue->x = m_pBuffer->GetFloat(); + pValue->y = m_pBuffer->GetFloat(); + pValue->z = m_pBuffer->GetFloat(); + pInstance->_userpointer = pValue; + } + else + { + InstanceContext_t *pContext = new InstanceContext_t; + pContext->pInstance = NULL; + ReadObject( pContext->name ); + pContext->pClassDesc = (ScriptClassDesc_t *)( pInstance->_class->_typetag ); + void *pOldInstance = m_pBuffer->GetPtr(); + if ( sq_isstring(pContext->name) ) + { + char *pszName = pContext->name._unVal.pString->_val; + if ( pContext->pClassDesc->pHelper ) + { + HSQOBJECT *pInstanceHandle = new HSQOBJECT; + pInstanceHandle->_type = OT_INSTANCE; + pInstanceHandle->_unVal.pInstance = pInstance; + pContext->pInstance = pContext->pClassDesc->pHelper->BindOnRead( (HSCRIPT)pInstanceHandle, pOldInstance, pszName ); + if ( pContext->pInstance ) + { + SQ_VALIDATE_REF_COUNT( pInstance ); + pInstance->_uiRef++; + sq_addref( m_hVM, pInstanceHandle ); + pInstance->_uiRef--; + SQ_VALIDATE_REF_COUNT( pInstance ); + } + else + { + delete pInstanceHandle; + } + } + + if ( !pContext->pInstance ) + { + // Look for a match in the current root table + HSQOBJECT hExistingObject = LookupObject( pszName, NULL, false ); + if ( sq_isinstance(hExistingObject) && hExistingObject._unVal.pInstance->_class == pInstance->_class ) + { + delete pInstance; + return hExistingObject._unVal.pInstance; + } + + pContext->pInstance = NULL; + } + } + pInstance->_userpointer = pContext; + } + } + else + { + Verify( m_pBuffer->GetInt() == OT_USERPOINTER ); + pInstance->_userpointer = ReadUserPointer(); + Assert( pInstance->_userpointer == NULL ); + } + + MapPtr( pOld, pInstance ); + } + else + { + MapPtr( pOld, NULL ); + n = m_pBuffer->GetUnsignedInt(); + for ( i = 0; i < n; i++ ) + { + SQObjectPtr ignored; + ReadObject(ignored); + } + void *pOldTypeTag = m_pBuffer->GetPtr(); // ignored in this path + + if ( pOldTypeTag ) + { + if ( pOldTypeTag == TYPETAG_VECTOR ) + { + m_pBuffer->GetFloat(); + m_pBuffer->GetFloat(); + m_pBuffer->GetFloat(); + } + else + { + SQObjectPtr ignored; + ReadObject( ignored ); + m_pBuffer->GetPtr(); + } + } + else + { + Verify( m_pBuffer->GetInt() == OT_USERPOINTER ); + ReadUserPointer(); + } + pInstance = NULL; + } + return pInstance; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + SQGenerator *ReadGenerator() + { + SQGenerator *pOld; + SQGenerator *pGenerator; + if ( !BeginRead( &pOld, &pGenerator ) ) + { + return pGenerator; + } + + SQObjectPtr closure; + ReadObject( closure ); + + pGenerator = SQGenerator::Create( _ss(m_hVM), closure._unVal.pClosure ); + MapPtr( pOld, pGenerator ); + + unsigned i, n; + n = m_pBuffer->GetUnsignedInt(); + pGenerator->_stack.resize( n ); + for ( i = 0; i < n; i++ ) + { + ReadObject(pGenerator->_stack[i]); + } + n = m_pBuffer->GetUnsignedInt(); + pGenerator->_vargsstack.resize( n ); + for ( i = 0; i < n; i++ ) + { + ReadObject(pGenerator->_vargsstack[i]); + } + return pGenerator; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + SQClosure *ReadClosure() + { + SQClosure *pOld; + SQClosure *pClosure; + if ( !BeginRead( &pOld, &pClosure ) ) + { + return pClosure; + } + + SQObjectPtr proto; + ReadObject( proto ); + pClosure = SQClosure::Create( _ss(m_hVM), proto._unVal.pFunctionProto ); + MapPtr( pOld, pClosure ); + + ReadObject( pClosure->_env ); + + unsigned i, n; + n = m_pBuffer->GetUnsignedInt(); + pClosure->_outervalues.resize( n ); + for ( i = 0; i < n; i++ ) + { + ReadObject(pClosure->_outervalues[i]); + } + + n = m_pBuffer->GetUnsignedInt(); + pClosure->_defaultparams.resize( n ); + for ( i = 0; i < n; i++ ) + { + ReadObject(pClosure->_defaultparams[i]); + } + + return pClosure; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + SQNativeClosure *ReadNativeClosure() + { + SQNativeClosure *pOld; + SQNativeClosure *pClosure; + if ( !BeginRead( &pOld, &pClosure ) ) + { + return pClosure; + } + + SQObjectPtr name; + ReadObject( name ); + SQObjectPtr value; + if ( m_hVM->_roottable._unVal.pTable->Get( name, value ) && sq_isnativeclosure(value) ) + { + MapPtr( pOld, value._unVal.pNativeClosure ); + return value._unVal.pNativeClosure; + } + MapPtr( pOld, NULL ); + return NULL; // @TBD [4/15/2008 tom] + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + SQUserData *ReadUserData() + { + m_pBuffer->GetPtr(); + return NULL; // @TBD [4/15/2008 tom] + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + SQUserPointer *ReadUserPointer() + { + m_pBuffer->GetPtr(); + return NULL; // @TBD [4/15/2008 tom] + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + static SQInteger SqReadFunc(SQUserPointer up,SQUserPointer data, SQInteger size) + { + CSquirrelVM *pThis = (CSquirrelVM *)up; + pThis->m_pBuffer->Get( data, size ); + return size; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + SQFunctionProto *ReadFuncProto() + { + SQFunctionProto *pOld; + SQFunctionProto *pResult; + if ( !BeginRead( &pOld, &pResult ) ) + { + return pResult; + } + + SQObjectPtr result; + SQFunctionProto::Load( m_hVM, this, &SqReadFunc, result ); + pResult = result._unVal.pFunctionProto; + SQ_VALIDATE_REF_COUNT( pResult ); + pResult->_uiRef++; + result.Null(); + pResult->_uiRef--; + SQ_VALIDATE_REF_COUNT( pResult ); + MapPtr( pOld, pResult ); + return pResult; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + SQWeakRef *ReadWeakRef( ) + { + SQObjectPtr obj; + ReadObject( obj ); + if ( !obj._unVal.pRefCounted ) + { + return NULL; + } + + // Need to up ref count if read order has weak ref loading first + Assert( ISREFCOUNTED(obj._type) ); + SQRefCounted *pRefCounted = obj._unVal.pRefCounted; + SQ_VALIDATE_REF_COUNT( pRefCounted ); + pRefCounted->_uiRef++; + + SQWeakRef *pResult = obj._unVal.pRefCounted->GetWeakRef( obj._type ); + + obj.Null(); + pRefCounted->_uiRef--; + SQ_VALIDATE_REF_COUNT( pRefCounted ); + + return pResult; + } + + //------------------------------------------------------------- + // + //------------------------------------------------------------- + bool FindKeyForObject( const SQObjectPtr &table, void *p, SQObjectPtr &key ) + { + SQTable *pTable = table._unVal.pTable; + int len = pTable->_numofnodes; + for(int i = 0; i < len; i++) + { + if ( pTable->_nodes[i].val._unVal.pUserPointer == p ) + { + key = pTable->_nodes[i].key; + return true; + } + if ( sq_istable( pTable->_nodes[i].val ) ) + { + if ( FindKeyForObject( pTable->_nodes[i].val, p, key ) ) + { + return true; + } + } + } + return false; + } + + //------------------------------------------------------------------------- + // + //------------------------------------------------------------------------- + + HSQUIRRELVM m_hVM; + HSQREMOTEDBG m_hDbg; + HSQOBJECT m_hOnCreateScopeFunc; + HSQOBJECT m_hOnReleaseScopeFunc; + HSQOBJECT m_hClassVector; + SQObjectPtr m_ErrorString; + uint64 m_iUniqueIdSerialNumber; + float m_TimeStartExecute; +#ifdef VSQUIRREL_TEST + ConVar developer; +#else + ConVarRef developer; +#endif + + CUtlHashFast m_TypeMap; + friend class CVSquirrelSerializer; + + // Serialization support + CUtlBuffer *m_pBuffer; + CUtlMap m_PtrMap; +}; + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +IScriptVM *ScriptCreateSquirrelVM() +{ + return new CSquirrelVM; +} + +void ScriptDestroySquirrelVM( IScriptVM *pVM ) +{ + CSquirrelVM *pSquirrelVM = assert_cast( pVM ); + delete pSquirrelVM; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +#ifdef VSQUIRREL_TEST + +#include "fasttimer.h" + +CSquirrelVM g_SquirrelVM; +IScriptVM *g_pScriptVM = &g_SquirrelVM; + + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#include +#include "fasttimer.h" + +static void FromScript_AddBehavior( const char *pBehaviorName, HSCRIPT hTable ) +{ + ScriptVariant_t KeyVariant, ValueVariant; + + Msg( "Behavior: %s\n", pBehaviorName ); + + int nInterator = 0; + int index = g_pScriptVM->GetNumTableEntries( hTable ); + for( int i = 0; i < index; i++ ) + { + nInterator = g_pScriptVM->GetKeyValue( hTable, nInterator, &KeyVariant, &ValueVariant ); + + Msg( " %d: %s / %s\n", i, KeyVariant.m_pszString, ValueVariant.m_pszString ); + + g_pScriptVM->ReleaseValue( KeyVariant ); + g_pScriptVM->ReleaseValue( ValueVariant ); + } +} + +static ScriptVariant_t TestReturn( ) +{ + return ScriptVariant_t("test"); +} + +static Vector MyVectorAdd( Vector A, Vector B ) +{ + return A + B; +} + +void TestOutput( const char *pszText ) +{ + Msg( "%s\n", pszText ); +} + +bool TestError( const char *pszText ) +{ + Msg( "%s\n", pszText ); + + return true; +} + + +class CMyClass +{ +public: + bool Foo( int ); + void Bar( HSCRIPT TableA, HSCRIPT TableB ); + float FooBar( int, const char * ); + float OverlyTechnicalName( bool ); +}; + +bool CMyClass::Foo( int test ) +{ + return true; +} + +void CMyClass::Bar( HSCRIPT TableA, HSCRIPT TableB ) +{ + ScriptVariant_t MyValue; + + // g_pScriptVM->CreateTable( MyTable ); + + MyValue = 10; + g_pScriptVM->SetValue( TableA, "1", MyValue ); + MyValue = 20; + g_pScriptVM->SetValue( TableA, "2", MyValue ); + MyValue = 30; + g_pScriptVM->SetValue( TableA, "3", MyValue ); + + MyValue = 100; + g_pScriptVM->SetValue( TableB, "1", MyValue ); + MyValue = 200; + g_pScriptVM->SetValue( TableB, "2", MyValue ); + MyValue = 300; + g_pScriptVM->SetValue( TableB, "3", MyValue ); + + // return MyTable; +} + +float CMyClass::FooBar( int test1, const char *test2 ) +{ + return 2.34f; +} + +float CMyClass::OverlyTechnicalName( bool test ) +{ + return 4.56f; +} + +BEGIN_SCRIPTDESC_ROOT_NAMED( CMyClass , "CMyClass", SCRIPT_SINGLETON "" ) +DEFINE_SCRIPTFUNC( Foo, "" ) +DEFINE_SCRIPTFUNC( Bar, "" ) +DEFINE_SCRIPTFUNC( FooBar, "" ) +DEFINE_SCRIPTFUNC_NAMED( OverlyTechnicalName, "SimpleMemberName", "" ) +END_SCRIPTDESC(); + +class CMyDerivedClass : public CMyClass +{ +public: + float DerivedFunc() const; +}; + +BEGIN_SCRIPTDESC( CMyDerivedClass, CMyClass, SCRIPT_SINGLETON "" ) +DEFINE_SCRIPTFUNC( DerivedFunc, "" ) +END_SCRIPTDESC(); + +float CMyDerivedClass::DerivedFunc() const +{ + return 8.91f; +} + +CMyDerivedClass derivedInstance; + +void AnotherFunction() +{ + // Manual class exposure + g_pScriptVM->RegisterClass( GetScriptDescForClass( CMyClass ) ); + + // Auto registration by instance + g_pScriptVM->RegisterInstance( &derivedInstance, "theInstance" ); +} + +int main( int argc, const char **argv) +{ + if ( argc < 2 ) + { + printf( "No script specified" ); + return 1; + } + g_pScriptVM->Init(); + + g_pScriptVM->SetOutputCallback( TestOutput ); + + AnotherFunction(); + + CCycleCount count; + count.Sample(); + RandomSeed( time( NULL ) ^ count.GetMicroseconds() ); + ScriptRegisterFunction( g_pScriptVM, RandomFloat, "" ); + ScriptRegisterFunction( g_pScriptVM, RandomInt, "" ); + + ScriptRegisterFunction( g_pScriptVM, FromScript_AddBehavior, "" ); + ScriptRegisterFunction( g_pScriptVM, MyVectorAdd, "" ); + ScriptRegisterFunction( g_pScriptVM, TestReturn, "" ); + + if ( argc == 3 && *argv[2] == 'd' ) + { + g_pScriptVM->ConnectDebugger(); + } + + int key; + CScriptScope scope; + scope.Init( "TestScope" ); + do + { + const char *pszScript = argv[1]; + FILE *hFile = fopen( pszScript, "rb" ); + if ( !hFile ) + { + printf( "\"%s\" not found.\n", pszScript ); + return 1; + } + + int nFileLen = _filelength( _fileno( hFile ) ); + char *pBuf = new char[nFileLen + 1]; + fread( pBuf, 1, nFileLen, hFile ); + pBuf[nFileLen] = 0; + fclose( hFile ); + + if (1) + { + printf( "Executing script \"%s\"\n----------------------------------------\n", pszScript ); + HSCRIPT hScript = g_pScriptVM->CompileScript( pBuf, ( strrchr( pszScript, '\\' ) ? strrchr( pszScript, '\\' ) + 1 : pszScript ) ); + if ( hScript ) + { + ScriptVariant_t Table; + + if ( scope.Run( hScript ) != SCRIPT_ERROR ) + { + printf( "----------------------------------------\n" ); + printf("Script complete. Press q to exit, r to reset the scope, m to dump memory usage, enter to run again.\n"); + } + else + { + printf( "----------------------------------------\n" ); + printf("Script execution error. Press q to exit, r to reset the scope, m to dump memory usage, enter to run again.\n"); + } + g_pScriptVM->ReleaseScript( hScript ); + } + else + { + printf( "----------------------------------------\n" ); + printf("Script failed to compile. Press q to exit, r to reset the scope, m to dump memory usage, enter to run again.\n"); + } + } + key = _getch(); // Keypress before exit + if ( key == 'm' ) + { + Msg( "%d\n", g_pMemAlloc->GetSize( NULL ) ); + } + if ( key == 'r' ) + { + scope.Term(); + scope.Init( "TestScope" ); + } + delete pBuf; + } while ( key != 'q' ); + + scope.Term(); + g_pScriptVM->DisconnectDebugger(); + + g_pScriptVM->Shutdown(); + return 0; +} + +#endif diff --git a/vscript/languages/squirrel/vsquirrel/vsquirrel.h b/vscript/languages/squirrel/vsquirrel/vsquirrel.h new file mode 100644 index 00000000..ebcea988 --- /dev/null +++ b/vscript/languages/squirrel/vsquirrel/vsquirrel.h @@ -0,0 +1,17 @@ +//========== Copyright © 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: +// +//============================================================================= + +#ifndef VSQUIRREL_H +#define VSQUIRREL_H + +#if defined( _WIN32 ) +#pragma once +#endif + +IScriptVM *ScriptCreateSquirrelVM(); +void ScriptDestroySquirrelVM( IScriptVM *pVM ); + +#endif // VSQUIRREL_H diff --git a/vscript/languages/squirrel/vsquirrel/vsquirrel.vpc b/vscript/languages/squirrel/vsquirrel/vsquirrel.vpc new file mode 100644 index 00000000..ca3bc609 --- /dev/null +++ b/vscript/languages/squirrel/vsquirrel/vsquirrel.vpc @@ -0,0 +1,180 @@ +//----------------------------------------------------------------------------- +// Project Script +//----------------------------------------------------------------------------- + +$Macro SRCDIR "..\..\..\.." +$Macro OUTBINDIR "." + +$Include "$SRCDIR\vpc_scripts\source_exe_con_win32_base.vpc" + +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE,..\include;..\sqplus" + $PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE;VSQUIRREL_TEST" + } +} + +$Project "vsquirrel" +{ + $Folder "Script Files" + { + $File "init.nut" + { + $Configuration + { + $CustomBuildStep + { + $CommandLine "$SRCDIR\devtools\srcsrv\perl\bin\perl.exe $SRCDIR\devtools\bin\texttoarray.pl $(InputFileName) g_Script_$(InputName)> $(InputName)_nut.h" [$WINDOWS] + $CommandLine "perl $SRCDIR\devtools\bin\texttoarray.pl $(InputFileName) g_Script_$(InputName)> $(InputName)_nut.h" [$POSIX] + $Description "$(InputFileName) produces $(InputName)_nut.h" + $Outputs "$(InputName)_nut.h" + } + } + } + } + + $Folder "Source Files" + { + $File "..\..\..\..\public\vscript\ivscript.h" + $File "..\..\..\..\public\vscript\vscript_templates.h" + $File "vsquirrel.cpp" + { + $Configuration + { + $Compiler + { + // "SQPlus" need exceptions. If commit to squirrel, look into removing that + $AdditionalOptions "/EHa" + } + } + } + } + + $Folder "Squirrel" + { + $Folder "Header Files" + { + $File "..\include\sqdbgserver.h" + $File "..\include\sqrdbg.h" + $File "..\include\sqstdaux.h" + $File "..\include\sqstdblob.h" + $File "..\include\sqstdio.h" + $File "..\include\sqstdmath.h" + $File "..\include\sqstdstring.h" + $File "..\include\sqstdsystem.h" + $File "..\include\squirrel.h " + } + $Folder "squirrel" + { + $Folder "Source Files" + { + $File "..\squirrel\sqapi.cpp" \ + "..\squirrel\sqbaselib.cpp" \ + "..\squirrel\sqclass.cpp" \ + "..\squirrel\sqcompiler.cpp" \ + "..\squirrel\sqdebug.cpp" \ + "..\squirrel\sqfuncstate.cpp" \ + "..\squirrel\sqlexer.cpp" \ + "..\squirrel\sqmem.cpp" \ + "..\squirrel\sqobject.cpp" \ + "..\squirrel\sqstate.cpp" \ + "..\squirrel\sqtable.cpp" \ + "..\squirrel\sqvm.cpp" \ + "..\sqdbg\sqrdbg.cpp" \ + "..\sqdbg\sqdbgserver.cpp" + { + $Configuration + { + $Compiler + { + $WarningLevel "Level 3 (/W3)" + $Detect64bitPortabilityIssues "No" + } + } + } + } + + $Folder "Header Files" + { + $File "..\squirrel\sqarray.h" \ + "..\squirrel\sqclass.h" \ + "..\squirrel\sqclosure.h" \ + "..\squirrel\sqcompiler.h" \ + "..\squirrel\sqfuncproto.h" \ + "..\squirrel\sqfuncstate.h" \ + "..\squirrel\sqlexer.h" \ + "..\squirrel\sqobject.h" \ + "..\squirrel\sqopcodes.h" \ + "..\squirrel\sqpcheader.h" \ + "..\squirrel\sqstate.h" \ + "..\squirrel\sqstring.h" \ + "..\squirrel\sqtable.h" \ + "..\squirrel\squserdata.h" \ + "..\squirrel\squtils.h" \ + "..\squirrel\sqvm.h" + } + } + $Folder "sqstdlib" + { + $Folder "Source Files" + { + $File "..\sqstdlib\sqstdaux.cpp"\ + "..\sqstdlib\sqstdblob.cpp" \ + "..\sqstdlib\sqstdmath.cpp" \ + "..\sqstdlib\sqstdrex.cpp" \ + "..\sqstdlib\sqstdstream.cpp" \ + "..\sqstdlib\sqstdstring.cpp" + { + $Configuration + { + $Compiler + { + $WarningLevel "Level 3 (/W3)" + $Detect64bitPortabilityIssues "No" + } + } + } + } + } + $Folder "sqplus" + { + $Folder "Source Files" + { + $File "..\sqplus\SqPlus.cpp" \ + "..\sqplus\SquirrelBindingsUtils.cpp" \ + "..\sqplus\SquirrelBindingsUtilsWin32.cpp" \ + "..\sqplus\SquirrelObject.cpp" \ + "..\sqplus\SquirrelVM.cpp" + { + $Configuration + { + $Compiler + { + $WarningLevel "Level 3 (/W3)" + $Detect64bitPortabilityIssues "No" + // "SQPlus" need exceptions. If commit to squirrel, look into removing that + $AdditionalOptions "/EHa" + } + } + } + } + $Folder "Header Files" + { + $File "..\sqplus\sqplus.h" \ + "..\sqplus\SqPlusConst.h" \ + "..\sqplus\sqplusWin32.h" \ + "..\sqplus\SquirrelBindingsUtils.h" \ + "..\sqplus\SquirrelBindingsUtilsWin32.h" \ + "..\sqplus\SquirrelObject.h" \ + "..\sqplus\SquirrelVM.h" + } + } + } + $Folder "Link Libraries" + { + $File "$SRCDIR\lib\public\mathlib.lib" + } +} + diff --git a/vscript/vscript.cpp b/vscript/vscript.cpp new file mode 100644 index 00000000..569e5d4b --- /dev/null +++ b/vscript/vscript.cpp @@ -0,0 +1,110 @@ +//========== Copyright � 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: +// +//============================================================================= + +#include "interface.h" +#include "vscript/ivscript.h" +#include "languages/gm/vgm/vgm.h" +#include "languages/squirrel/vsquirrel/vsquirrel.h" +#include "languages/lua/vlua/vlua.h" +#include "languages/python/vpython/vpython.h" +#include "vstdlib/random.h" +#include "tier1/tier1.h" + + +// lwss - HACCCKKKKK for --wrap on fopen() not working with my gcc +FILE *__wrap_fopen(const char *pathname, const char *mode) +{ + return fopen( pathname, mode ); +} +// lwss end +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +class CScriptManager : public CTier1AppSystem +{ +public: + CScriptManager() + { + } + + IScriptVM *CreateVM( ScriptLanguage_t language ) + { + IScriptVM *pVM = NULL; + + if ( language == SL_SQUIRREL ) + { + pVM = ScriptCreateSquirrelVM(); + } +#if !defined( _GAMECONSOLE ) && !defined( LINUX ) + else if ( language == SL_LUA ) + { + pVM = ScriptCreateLuaVM(); + } +#endif +#if VPYTHON_ENABLED + else if ( language == SL_PYTHON ) + { + pVM = ScriptCreatePythonVM(); + } +#endif +#if VGM_ENABLED + else if ( language == SL_GAMEMONKEY ) + { + pVM = ScriptCreateGameMonkeyVM(); + } +#endif + + AssertMsg( pVM, "Unknown script language\n" ); + if ( pVM ) + { + pVM->Init(); + ScriptRegisterFunction( pVM, RandomFloat, "Generate a random floating point number within a range, inclusive" ); + ScriptRegisterFunction( pVM, RandomInt, "Generate a random integer within a range, inclusive" ); + } + return pVM; + } + + void DestroyVM( IScriptVM *p ) + { + if ( p ) + { + p->Shutdown(); + if ( p->GetLanguage() == SL_SQUIRREL ) + { + ScriptDestroySquirrelVM( p ); + } +#if !defined( _GAMECONSOLE ) && !defined( LINUX ) + else if ( p->GetLanguage() == SL_LUA ) + { + ScriptDestroyLuaVM( p ); + } +#endif +#if VPYTHON_ENABLED + else if ( p->GetLanguage() == SL_PYTHON ) + { + ScriptDestroyPythonVM( p ); + } +#endif +#if VGM_ENABLED + else if ( p->GetLanguage() == SL_GAMEMONKEY ) + { + ScriptDestroyGameMonkeyVM( p ); + } +#endif + else + AssertMsg( 0, "Unknown script language\n" ); + } + } +}; + +//----------------------------------------------------------------------------- +// Singleton +//----------------------------------------------------------------------------- +CScriptManager g_ScriptManager; + +EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CScriptManager, IScriptManager, VSCRIPT_INTERFACE_VERSION, g_ScriptManager ); + + diff --git a/vscript/vscript.vpc b/vscript/vscript.vpc new file mode 100644 index 00000000..a7e78e96 --- /dev/null +++ b/vscript/vscript.vpc @@ -0,0 +1,485 @@ +//----------------------------------------------------------------------------- +// VSCRIPT.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$macro SRCDIR ".." +$Macro OUTBINDIR "$SRCDIR\..\game\bin" +$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc" + + +$Configuration +{ + $Compiler [!$PS3] + { + $PreprocessorDefinitions "$BASE;VSCRIPT_DLL_EXPORT;LUA_MOD_CASE_INSENSITIVE" + $PreprocessorDefinitions "$BASE;MSVC" [$WINDOWS||$X360] + $AdditionalIncludeDirectories "$BASE;.\languages\squirrel\include;.\languages\squirrel\sqplus;.\languages\lua\lua-5.1.4\src" [$OSXALL||$POSIX] + + } + + $Compiler [$PS3] + { + $PreprocessorDefinitions "$BASE;VSCRIPT_DLL_EXPORT;LUA_MOD_CASE_INSENSITIVE" + $C++ExceptionsandRTTIUsage "Using Exceptions and RTTI" + } + + $Linker [$OSXALL] + { + $SystemLibraries "iconv" + } + +} + +$Configuration "Release" +{ + $General [!$PS3] + { + $WholeProgramOptimization "Use Link Time Code Generation" [!$PROFILE] + } +} + +$Project "vscript" +{ + $Folder "Source Files" + { + $File "vscript.cpp" + $File ".\languages\gm\vgm\vgm.cpp" + { + $Configuration + { + $Compiler + { + $AdditionalIncludeDirectories "$BASE;.\languages\gm\src\gm;.\languages\gm\src\binds;.\languages\gm\src\platform\win32msvc" + } + $ExcludedFromBuild "Yes" + } + } + $File ".\languages\lua\vlua\vlua.cpp" [!$X360 && !$PS3 && !$LINUX] + { + $Configuration + { + $Compiler + { + $AdditionalIncludeDirectories "$BASE;.\languages\lua\lua-5.1.4\src" + } + } + } + $File ".\languages\squirrel\vsquirrel\vsquirrel.cpp" + { + $Configuration + { + $Compiler + { + $AdditionalIncludeDirectories "$BASE;.\languages\squirrel\include;.\languages\squirrel\sqplus" + } + } + } + + + $Folder "Script Files" + { + $File ".\languages\squirrel\vsquirrel\init.nut" + { + $Configuration + { + $CustomBuildStep + { + $CommandLine "$SRCDIR\devtools\srcsrv\perl\bin\perl.exe $SRCDIR\devtools\bin\texttoarray.pl $(InputPath) g_Script_$(InputName)> $(InputDir)$(InputName)_nut.h" [$WINDOWS] + $CommandLine "perl $SRCDIR\devtools\bin\texttoarray.pl $(InputPath) g_Script_$(InputName)> $(InputDir)$(InputName)_nut.h" [$POSIX] + $Description "$(InputFileName) produces $(InputName)_nut.h" + $Outputs "$(InputDir)$(InputName)_nut.h" + } + } + } + } + } + + $Folder "Header Files" + { + $File ".\languages\gm\vgm\vgm.h" + $File ".\languages\squirrel\vsquirrel\vsquirrel.h" + $File ".\languages\lua\vlua\vlua.h" + } + + $Folder "Interface" + { + $File "$SRCDIR\public\vscript\ivscript.h" + $File "$SRCDIR\public\vscript\vscript_templates.h" + } + + $Folder "GameMonkey" + { + $Folder "gm" + { + $Folder "Source Files" + { + $File ".\languages\gm\src\gm\gmArraySimple.cpp" \ + ".\languages\gm\src\gm\gmByteCode.cpp" \ + ".\languages\gm\src\gm\gmByteCodeGen.cpp" \ + ".\languages\gm\src\gm\gmCodeGen.cpp" \ + ".\languages\gm\src\gm\gmCodeGenHooks.cpp" \ + ".\languages\gm\src\gm\gmCodeTree.cpp" \ + ".\languages\gm\src\gm\gmCrc.cpp" \ + ".\languages\gm\src\gm\gmDebug.cpp" \ + ".\languages\gm\src\gm\gmFunctionObject.cpp" \ + ".\languages\gm\src\gm\gmHash.cpp" \ + ".\languages\gm\src\gm\gmIncGC.cpp" \ + ".\languages\gm\src\gm\gmLibHooks.cpp" \ + ".\languages\gm\src\gm\gmListDouble.cpp" \ + ".\languages\gm\src\gm\gmLog.cpp" \ + ".\languages\gm\src\gm\gmMachine.cpp" \ + ".\languages\gm\src\gm\gmMachineLib.cpp" \ + ".\languages\gm\src\gm\gmMem.cpp" \ + ".\languages\gm\src\gm\gmMemChain.cpp" \ + ".\languages\gm\src\gm\gmMemFixed.cpp" \ + ".\languages\gm\src\gm\gmMemFixedSet.cpp" \ + ".\languages\gm\src\gm\gmOperators.cpp" \ + ".\languages\gm\src\gm\gmParser.cpp" \ + ".\languages\gm\src\gm\gmScanner.cpp" \ + ".\languages\gm\src\gm\gmStream.cpp" \ + ".\languages\gm\src\gm\gmStreamBuffer.cpp" \ + ".\languages\gm\src\gm\gmStringObject.cpp" \ + ".\languages\gm\src\gm\gmTableObject.cpp" \ + ".\languages\gm\src\gm\gmThread.cpp" \ + ".\languages\gm\src\gm\gmUserObject.cpp" \ + ".\languages\gm\src\gm\gmUtil.cpp" \ + ".\languages\gm\src\gm\gmVariable.cpp" + { + $Configuration + { + $Compiler + { + $AdditionalIncludeDirectories "$BASE;.\languages\gm\src\gm;.\languages\gm\src\binds;.\languages\gm\src\platform\win32msvc" + $PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE;VSCRIPT_DLL_EXPORT" + } + $ExcludedFromBuild "Yes" + } + } + } + + $Folder "Header Files" + { + $File ".\languages\gm\src\platform\win32msvc\gmConfig_p.h" \ + ".\languages\gm\src\gm\gmArraySimple.h" \ + ".\languages\gm\src\gm\gmByteCode.h" \ + ".\languages\gm\src\gm\gmByteCodeGen.h" \ + ".\languages\gm\src\gm\gmCodeGen.h" \ + ".\languages\gm\src\gm\gmCodeGenHooks.h" \ + ".\languages\gm\src\gm\gmCodeTree.h" \ + ".\languages\gm\src\gm\gmConfig.h" \ + ".\languages\gm\src\gm\gmCrc.h" \ + ".\languages\gm\src\gm\gmDebug.h" \ + ".\languages\gm\src\gm\gmFunctionObject.h" \ + ".\languages\gm\src\gm\gmHash.h" \ + ".\languages\gm\src\gm\gmIncGC.h" \ + ".\languages\gm\src\gm\gmIterator.h" \ + ".\languages\gm\src\gm\gmLibHooks.h" \ + ".\languages\gm\src\gm\gmListDouble.h" \ + ".\languages\gm\src\gm\gmLog.h" \ + ".\languages\gm\src\gm\gmMachine.h" \ + ".\languages\gm\src\gm\gmMachineLib.h" \ + ".\languages\gm\src\gm\gmMem.h" \ + ".\languages\gm\src\gm\gmMemChain.h" \ + ".\languages\gm\src\gm\gmMemFixed.h" \ + ".\languages\gm\src\gm\gmMemFixedSet.h" \ + ".\languages\gm\src\gm\gmOperators.h" \ + ".\languages\gm\src\gm\gmParser.cpp.h" \ + ".\languages\gm\src\gm\gmScanner.h" \ + ".\languages\gm\src\gm\gmStream.h" \ + ".\languages\gm\src\gm\gmStreamBuffer.h" \ + ".\languages\gm\src\gm\gmStringObject.h" \ + ".\languages\gm\src\gm\gmTableObject.h" \ + ".\languages\gm\src\gm\gmThread.h" \ + ".\languages\gm\src\gm\gmUserObject.h" \ + ".\languages\gm\src\gm\gmUtil.h" \ + ".\languages\gm\src\gm\gmVariable.h" + } + } + + $Folder "binds" + { + $Folder "Source Files" + { + $File ".\languages\gm\src\binds\gmArrayLib.cpp" \ + ".\languages\gm\src\binds\gmCall.cpp" \ + ".\languages\gm\src\binds\gmGCRoot.cpp" \ + ".\languages\gm\src\binds\gmGCRootUtil.cpp" \ + ".\languages\gm\src\binds\gmHelpers.cpp" \ + ".\languages\gm\src\binds\gmMathLib.cpp" \ + ".\languages\gm\src\binds\gmStringLib.cpp" \ + ".\languages\gm\src\binds\gmSystemLib.cpp" \ + ".\languages\gm\src\binds\gmVector3Lib.cpp" + { + $Configuration + { + $Compiler + { + $AdditionalIncludeDirectories "$BASE;.\languages\gm\src\gm;.\languages\gm\src\binds;.\languages\gm\src\platform\win32msvc" + $PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE;VSCRIPT_DLL_EXPORT" + } + $ExcludedFromBuild "Yes" + } + } + + } + $Folder "Header Files" + { + $File ".\languages\gm\src\binds\gmArrayLib.h" \ + ".\languages\gm\src\binds\gmCall.h" \ + ".\languages\gm\src\binds\gmGCRoot.h" \ + ".\languages\gm\src\binds\gmGCRootUtil.h" \ + ".\languages\gm\src\binds\gmHelpers.h" \ + ".\languages\gm\src\binds\gmMathLib.h" \ + ".\languages\gm\src\binds\gmStringLib.h" \ + ".\languages\gm\src\binds\gmSystemLib.h" \ + ".\languages\gm\src\binds\gmVector3Lib.h" + } + } + + } + + $Folder "Squirrel" + { + $Folder "Header Files" + { + $File ".\languages\squirrel\include\sqdbgserver.h" + $File ".\languages\squirrel\include\sqrdbg.h" + $File ".\languages\squirrel\include\sqstdaux.h" + $File ".\languages\squirrel\include\sqstdblob.h" + $File ".\languages\squirrel\include\sqstdio.h" + $File ".\languages\squirrel\include\sqstdmath.h" + $File ".\languages\squirrel\include\sqstdstring.h" + $File ".\languages\squirrel\include\sqstdsystem.h" + $File ".\languages\squirrel\include\squirrel.h" + } + + $Folder "squirrel" + { + $Folder "Source Files" + { + $File ".\languages\squirrel\squirrel\sqapi.cpp" \ + ".\languages\squirrel\squirrel\sqbaselib.cpp" \ + ".\languages\squirrel\squirrel\sqclass.cpp" \ + ".\languages\squirrel\squirrel\sqcompiler.cpp" \ + ".\languages\squirrel\squirrel\sqdebug.cpp" \ + ".\languages\squirrel\squirrel\sqfuncstate.cpp" \ + ".\languages\squirrel\squirrel\sqlexer.cpp" \ + ".\languages\squirrel\squirrel\sqmem.cpp" \ + ".\languages\squirrel\squirrel\sqobject.cpp" \ + ".\languages\squirrel\squirrel\sqstate.cpp" \ + ".\languages\squirrel\squirrel\sqtable.cpp" \ + ".\languages\squirrel\squirrel\sqvm.cpp" \ + ".\languages\squirrel\sqdbg\sqrdbg.cpp" \ + ".\languages\squirrel\sqdbg\sqdbgserver.cpp" + { + $Configuration + { + $Compiler [!$PS3] + { + $WarningLevel "Level 3 (/W3)" +// $Detect64bitPortabilityIssues "No" [$WIN32||$LINUX] + } + + $Compiler +{ + $AdditionalIncludeDirectories "$BASE;.\languages\squirrel\include;.\languages\squirrel\sqplus" + $PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE;VSCRIPT_DLL_EXPORT" + } + } + } + } + + $Folder "Header Files" + { + $File ".\languages\squirrel\squirrel\sqarray.h" \ + ".\languages\squirrel\squirrel\sqclass.h" \ + ".\languages\squirrel\squirrel\sqclosure.h" \ + ".\languages\squirrel\squirrel\sqcompiler.h" \ + ".\languages\squirrel\squirrel\sqfuncproto.h" \ + ".\languages\squirrel\squirrel\sqfuncstate.h" \ + ".\languages\squirrel\squirrel\sqlexer.h" \ + ".\languages\squirrel\squirrel\sqobject.h" \ + ".\languages\squirrel\squirrel\sqopcodes.h" \ + ".\languages\squirrel\squirrel\sqpcheader.h" \ + ".\languages\squirrel\squirrel\sqstate.h" \ + ".\languages\squirrel\squirrel\sqstring.h" \ + ".\languages\squirrel\squirrel\sqtable.h" \ + ".\languages\squirrel\squirrel\squserdata.h" \ + ".\languages\squirrel\squirrel\squtils.h" \ + ".\languages\squirrel\squirrel\sqvm.h" + } + } + $Folder "sqstdlib" + { + $Folder "Source Files" + { + $File ".\languages\squirrel\sqstdlib\sqstdaux.cpp"\ + ".\languages\squirrel\sqstdlib\sqstdblob.cpp" \ + ".\languages\squirrel\sqstdlib\sqstdmath.cpp" \ + ".\languages\squirrel\sqstdlib\sqstdrex.cpp" \ + ".\languages\squirrel\sqstdlib\sqstdstream.cpp" \ + ".\languages\squirrel\sqstdlib\sqstdstring.cpp" + { + $Configuration + { + $Compiler [!$PS3] + { + $WarningLevel "Level 3 (/W3)" +// $Detect64bitPortabilityIssues "No" [$WIN32||$LINUX] + } + + $Compiler + { + $AdditionalIncludeDirectories "$BASE;.\languages\squirrel\include;.\languages\squirrel\sqplus" + $PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE;VSCRIPT_DLL_EXPORT" + } + } + } + } + } + $Folder "sqplus" + { + $Folder "Source Files" + { + $File ".\languages\squirrel\sqplus\SquirrelBindingsUtilsWin32.cpp" [!$PS3&&!$POSIX] + { + $Configuration + { + $Compiler + { + $AdditionalIncludeDirectories "$BASE,.\languages\squirrel3\include" + $WarningLevel "Level 3 (/W3)" +// $Detect64bitPortabilityIssues "No" [$WIN32||$LINUX] + // "SQPlus" need exceptions. If commit to squirrel, look into removing that + $AdditionalOptions "$BASE /EHsc" + $AdditionalIncludeDirectories "$BASE;.\languages\squirrel\include;.\languages\squirrel\sqplus" + $PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE;VSCRIPT_DLL_EXPORT" + } + } + } + + $File ".\languages\squirrel\sqplus\SqPlus.cpp" \ + ".\languages\squirrel\sqplus\SquirrelBindingsUtils.cpp" \ + ".\languages\squirrel\sqplus\SquirrelObject.cpp" \ + ".\languages\squirrel\sqplus\SquirrelVM.cpp" + { + $Configuration + { + $Compiler [!$PS3] + { + $WarningLevel "Level 3 (/W3)" +// $Detect64bitPortabilityIssues "No" [$WIN32||$LINUX] + // "SQPlus" need exceptions. If commit to squirrel, look into removing that + $AdditionalOptions "$BASE /EHsc" + } + + $Compiler + { + $AdditionalIncludeDirectories "$BASE;.\languages\squirrel\include;.\languages\squirrel\sqplus" + $PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE;VSCRIPT_DLL_EXPORT" + } + } + } + } + $Folder "Header Files" + { + $File ".\languages\squirrel\sqplus\sqplus.h" \ + ".\languages\squirrel\sqplus\SqPlusConst.h" \ + ".\languages\squirrel\sqplus\sqplusWin32.h" \ + ".\languages\squirrel\sqplus\SquirrelBindingsUtils.h" \ + ".\languages\squirrel\sqplus\SquirrelBindingsUtilsWin32.h" \ + ".\languages\squirrel\sqplus\SquirrelObject.h" \ + ".\languages\squirrel\sqplus\SquirrelVM.h" + } + } + } + + $Folder "Lua" [ !$X360 && !$PS3 && !$LINUX] + { + $Folder "lua-5.1.4" + { + $Folder "Source Files" + { + $File ".\languages\lua\lua-5.1.4\src\lapi.c" \ + ".\languages\lua\lua-5.1.4\src\lauxlib.c" \ + ".\languages\lua\lua-5.1.4\src\lbaselib.c" \ + ".\languages\lua\lua-5.1.4\src\lcode.c" \ + ".\languages\lua\lua-5.1.4\src\ldblib.c" \ + ".\languages\lua\lua-5.1.4\src\ldebug.c" \ + ".\languages\lua\lua-5.1.4\src\ldo.c" \ + ".\languages\lua\lua-5.1.4\src\ldump.c" \ + ".\languages\lua\lua-5.1.4\src\lfunc.c" \ + ".\languages\lua\lua-5.1.4\src\lgc.c" \ + ".\languages\lua\lua-5.1.4\src\linit.c" \ + ".\languages\lua\lua-5.1.4\src\liolib.c" \ + ".\languages\lua\lua-5.1.4\src\llex.c" \ + ".\languages\lua\lua-5.1.4\src\lmathlib.c" \ + ".\languages\lua\lua-5.1.4\src\lmem.c" \ + ".\languages\lua\lua-5.1.4\src\loadlib.c" \ + ".\languages\lua\lua-5.1.4\src\lobject.c" \ + ".\languages\lua\lua-5.1.4\src\lopcodes.c" \ + ".\languages\lua\lua-5.1.4\src\loslib.c" \ + ".\languages\lua\lua-5.1.4\src\lparser.c" \ + ".\languages\lua\lua-5.1.4\src\lstate.c" \ + ".\languages\lua\lua-5.1.4\src\lstring.c" \ + ".\languages\lua\lua-5.1.4\src\lstrlib.c" \ + ".\languages\lua\lua-5.1.4\src\ltable.c" \ + ".\languages\lua\lua-5.1.4\src\ltablib.c" \ + ".\languages\lua\lua-5.1.4\src\ltm.c" \ + ".\languages\lua\lua-5.1.4\src\lundump.c" \ + ".\languages\lua\lua-5.1.4\src\lvm.c" \ + ".\languages\lua\lua-5.1.4\src\lzio.c" \ + ".\languages\lua\lua-5.1.4\src\print.c" + { + $Configuration + { + $Compiler [!$PS3] + { + $WarningLevel "Level 3 (/W3)" + $Detect64bitPortabilityIssues "No" + $CompileAs "Default" + } + } + } + } + $Folder "Header Files" + { + $File ".\languages\lua\lua-5.1.4\src\lapi.h" \ + ".\languages\lua\lua-5.1.4\src\lauxlib.h" \ + ".\languages\lua\lua-5.1.4\src\lcode.h" \ + ".\languages\lua\lua-5.1.4\src\ldebug.h" \ + ".\languages\lua\lua-5.1.4\src\ldo.h" \ + ".\languages\lua\lua-5.1.4\src\lfunc.h" \ + ".\languages\lua\lua-5.1.4\src\lgc.h" \ + ".\languages\lua\lua-5.1.4\src\llex.h" \ + ".\languages\lua\lua-5.1.4\src\llimits.h" \ + ".\languages\lua\lua-5.1.4\src\lmem.h" \ + ".\languages\lua\lua-5.1.4\src\lobject.h" \ + ".\languages\lua\lua-5.1.4\src\lopcodes.h" \ + ".\languages\lua\lua-5.1.4\src\lparser.h" \ + ".\languages\lua\lua-5.1.4\src\lstate.h" \ + ".\languages\lua\lua-5.1.4\src\lstring.h" \ + ".\languages\lua\lua-5.1.4\src\ltable.h" \ + ".\languages\lua\lua-5.1.4\src\ltm.h" \ + ".\languages\lua\lua-5.1.4\src\lua.h" \ + ".\languages\lua\lua-5.1.4\src\luaconf.h" \ + ".\languages\lua\lua-5.1.4\src\lualib.h" \ + ".\languages\lua\lua-5.1.4\src\lundump.h" \ + ".\languages\lua\lua-5.1.4\src\lvm.h" \ + ".\languages\lua\lua-5.1.4\src\lzio.h" + } + } + $Folder "Support" + { + $File ".\languages\lua\vlua\vec3.cpp" + $File ".\languages\lua\vlua\vec3.h" + } + } + + $Folder "Link Libraries" + { + $Lib mathlib + } +} diff --git a/vscript/vscript_sob.vpc b/vscript/vscript_sob.vpc new file mode 100644 index 00000000..60144100 --- /dev/null +++ b/vscript/vscript_sob.vpc @@ -0,0 +1,460 @@ +//----------------------------------------------------------------------------- +// VSCRIPT.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$macro SRCDIR ".." +$Macro OUTBINDIR "$SRCDIR\..\game\bin" +$macro OUTBINNAME "vscript" + +$include "$SRCDIR\vpc_scripts\source_dll_win32_base.vpc" [$WIN32||$LINUX] +$include "$SRCDIR\vpc_scripts\source_dll_x360_base.vpc" [$X360] + +$Configuration +{ + $Compiler + { + $PreprocessorDefinitions "$BASE;VSCRIPT_DLL_EXPORT;MSVC" + } + + $Linker + { + $AdditionalLibraryDirectories ".\languages\python\python-2.5.1\win32release" + } +} + +$Configuration "Release" +{ + $General + { + $WholeProgramOptimization "Use Link Time Code Generation" [!$PROFILE] + } +} + +$Project "VScript (SOB)" +{ + $Folder "Source Files" + { + $File "vscript.cpp" + $File ".\languages\gm\vgm\vgm.cpp" + { + $Configuration + { + $Compiler + { + $AdditionalIncludeDirectories "$BASE,.\languages\gm\src\gm;.\languages\gm\src\binds;.\languages\gm\src\platform\win32msvc" + } + $ExcludedFromBuild "Yes" + } + } + $File ".\languages\lua\vlua\vlua.cpp" + { + $Configuration + { + $Compiler + { + $AdditionalIncludeDirectories "$BASE,.\languages\lua\lua-5.1.4\src" + } + } + } + $File ".\languages\squirrel\vsquirrel\vsquirrel.cpp" + { + $Configuration + { + $Compiler + { + $AdditionalIncludeDirectories "$BASE,.\languages\squirrel\include;.\languages\squirrel\sqplus" + } + } + } + + $File ".\languages\python\vpython\vpython.cpp" + { + $Configuration + { + $Compiler + { + $AdditionalIncludeDirectories "$BASE,.\languages\python\python-2.5.1\include" + } + } + } + + $Folder "Script Files" + { + $File ".\languages\squirrel\vsquirrel\init.nut" + { + $Configuration + { + $CustomBuildStep + { + $CommandLine "$SRCDIR\devtools\srcsrv\perl\bin\perl.exe $SRCDIR\devtools\bin\texttoarray.pl $(InputPath) g_Script_$(InputName)> $(InputDir)$(InputName)_nut.h" [$WINDOWS] + $CommandLine "perl $SRCDIR\devtools\bin\texttoarray.pl $(InputPath) g_Script_$(InputName)> $(InputDir)$(InputName)_nut.h" [$POSIX] + $Description "$(InputFileName) produces $(InputName)_nut.h" + $Outputs "$(InputDir)$(InputName)_nut.h" + } + } + } + } + } + + $Folder "Header Files" + { + $File ".\languages\gm\vgm\vgm.h" + $File ".\languages\squirrel\vsquirrel\vsquirrel.h" + $File ".\languages\lua\vlua\vlua.h" + $File ".\languages\python\vpython\vpython.h" + } + + $Folder "Interface" + { + $File "$SRCDIR\public\vscript\ivscript.h" + $File "$SRCDIR\public\vscript\vscript_templates.h" + } + + $Folder "GameMonkey" + { + $Folder "gm" + { + $Folder "Source Files" + { + $File ".\languages\gm\src\gm\gmArraySimple.cpp" \ + ".\languages\gm\src\gm\gmByteCode.cpp" \ + ".\languages\gm\src\gm\gmByteCodeGen.cpp" \ + ".\languages\gm\src\gm\gmCodeGen.cpp" \ + ".\languages\gm\src\gm\gmCodeGenHooks.cpp" \ + ".\languages\gm\src\gm\gmCodeTree.cpp" \ + ".\languages\gm\src\gm\gmCrc.cpp" \ + ".\languages\gm\src\gm\gmDebug.cpp" \ + ".\languages\gm\src\gm\gmFunctionObject.cpp" \ + ".\languages\gm\src\gm\gmHash.cpp" \ + ".\languages\gm\src\gm\gmIncGC.cpp" \ + ".\languages\gm\src\gm\gmLibHooks.cpp" \ + ".\languages\gm\src\gm\gmListDouble.cpp" \ + ".\languages\gm\src\gm\gmLog.cpp" \ + ".\languages\gm\src\gm\gmMachine.cpp" \ + ".\languages\gm\src\gm\gmMachineLib.cpp" \ + ".\languages\gm\src\gm\gmMem.cpp" \ + ".\languages\gm\src\gm\gmMemChain.cpp" \ + ".\languages\gm\src\gm\gmMemFixed.cpp" \ + ".\languages\gm\src\gm\gmMemFixedSet.cpp" \ + ".\languages\gm\src\gm\gmOperators.cpp" \ + ".\languages\gm\src\gm\gmParser.cpp" \ + ".\languages\gm\src\gm\gmScanner.cpp" \ + ".\languages\gm\src\gm\gmStream.cpp" \ + ".\languages\gm\src\gm\gmStreamBuffer.cpp" \ + ".\languages\gm\src\gm\gmStringObject.cpp" \ + ".\languages\gm\src\gm\gmTableObject.cpp" \ + ".\languages\gm\src\gm\gmThread.cpp" \ + ".\languages\gm\src\gm\gmUserObject.cpp" \ + ".\languages\gm\src\gm\gmUtil.cpp" \ + ".\languages\gm\src\gm\gmVariable.cpp" + { + $Configuration + { + $Compiler + { + $AdditionalIncludeDirectories "$BASE,.\languages\gm\src\gm;.\languages\gm\src\binds;.\languages\gm\src\platform\win32msvc" + $PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE;VSCRIPT_DLL_EXPORT" + } + $ExcludedFromBuild "Yes" + } + } + } + + $Folder "Header Files" + { + $File ".\languages\gm\src\platform\win32msvc\gmConfig_p.h" \ + ".\languages\gm\src\gm\gmArraySimple.h" \ + ".\languages\gm\src\gm\gmByteCode.h" \ + ".\languages\gm\src\gm\gmByteCodeGen.h" \ + ".\languages\gm\src\gm\gmCodeGen.h" \ + ".\languages\gm\src\gm\gmCodeGenHooks.h" \ + ".\languages\gm\src\gm\gmCodeTree.h" \ + ".\languages\gm\src\gm\gmConfig.h" \ + ".\languages\gm\src\gm\gmCrc.h" \ + ".\languages\gm\src\gm\gmDebug.h" \ + ".\languages\gm\src\gm\gmFunctionObject.h" \ + ".\languages\gm\src\gm\gmHash.h" \ + ".\languages\gm\src\gm\gmIncGC.h" \ + ".\languages\gm\src\gm\gmIterator.h" \ + ".\languages\gm\src\gm\gmLibHooks.h" \ + ".\languages\gm\src\gm\gmListDouble.h" \ + ".\languages\gm\src\gm\gmLog.h" \ + ".\languages\gm\src\gm\gmMachine.h" \ + ".\languages\gm\src\gm\gmMachineLib.h" \ + ".\languages\gm\src\gm\gmMem.h" \ + ".\languages\gm\src\gm\gmMemChain.h" \ + ".\languages\gm\src\gm\gmMemFixed.h" \ + ".\languages\gm\src\gm\gmMemFixedSet.h" \ + ".\languages\gm\src\gm\gmOperators.h" \ + ".\languages\gm\src\gm\gmParser.cpp.h" \ + ".\languages\gm\src\gm\gmScanner.h" \ + ".\languages\gm\src\gm\gmStream.h" \ + ".\languages\gm\src\gm\gmStreamBuffer.h" \ + ".\languages\gm\src\gm\gmStringObject.h" \ + ".\languages\gm\src\gm\gmTableObject.h" \ + ".\languages\gm\src\gm\gmThread.h" \ + ".\languages\gm\src\gm\gmUserObject.h" \ + ".\languages\gm\src\gm\gmUtil.h" \ + ".\languages\gm\src\gm\gmVariable.h" + } + } + + $Folder "binds" + { + $Folder "Source Files" + { + $File ".\languages\gm\src\binds\gmArrayLib.cpp" \ + ".\languages\gm\src\binds\gmCall.cpp" \ + ".\languages\gm\src\binds\gmGCRoot.cpp" \ + ".\languages\gm\src\binds\gmGCRootUtil.cpp" \ + ".\languages\gm\src\binds\gmHelpers.cpp" \ + ".\languages\gm\src\binds\gmMathLib.cpp" \ + ".\languages\gm\src\binds\gmStringLib.cpp" \ + ".\languages\gm\src\binds\gmSystemLib.cpp" \ + ".\languages\gm\src\binds\gmVector3Lib.cpp" + { + $Configuration + { + $Compiler + { + $AdditionalIncludeDirectories "$BASE,.\languages\gm\src\gm;.\languages\gm\src\binds;.\languages\gm\src\platform\win32msvc" + $PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE;VSCRIPT_DLL_EXPORT" + } + $ExcludedFromBuild "Yes" + } + } + + } + $Folder "Header Files" + { + $File ".\languages\gm\src\binds\gmArrayLib.h" \ + ".\languages\gm\src\binds\gmCall.h" \ + ".\languages\gm\src\binds\gmGCRoot.h" \ + ".\languages\gm\src\binds\gmGCRootUtil.h" \ + ".\languages\gm\src\binds\gmHelpers.h" \ + ".\languages\gm\src\binds\gmMathLib.h" \ + ".\languages\gm\src\binds\gmStringLib.h" \ + ".\languages\gm\src\binds\gmSystemLib.h" \ + ".\languages\gm\src\binds\gmVector3Lib.h" + } + } + + } + + $Folder "Squirrel" + { + $Folder "Header Files" + { + $File ".\languages\squirrel\include\sqdbgserver.h" + $File ".\languages\squirrel\include\sqrdbg.h" + $File ".\languages\squirrel\include\sqstdaux.h" + $File ".\languages\squirrel\include\sqstdblob.h" + $File ".\languages\squirrel\include\sqstdio.h" + $File ".\languages\squirrel\include\sqstdmath.h" + $File ".\languages\squirrel\include\sqstdstring.h" + $File ".\languages\squirrel\include\sqstdsystem.h" + $File ".\languages\squirrel\include\squirrel.h" + } + + $Folder "squirrel" + { + $Folder "Source Files" + { + $File ".\languages\squirrel\squirrel\sqapi.cpp" \ + ".\languages\squirrel\squirrel\sqbaselib.cpp" \ + ".\languages\squirrel\squirrel\sqclass.cpp" \ + ".\languages\squirrel\squirrel\sqcompiler.cpp" \ + ".\languages\squirrel\squirrel\sqdebug.cpp" \ + ".\languages\squirrel\squirrel\sqfuncstate.cpp" \ + ".\languages\squirrel\squirrel\sqlexer.cpp" \ + ".\languages\squirrel\squirrel\sqmem.cpp" \ + ".\languages\squirrel\squirrel\sqobject.cpp" \ + ".\languages\squirrel\squirrel\sqstate.cpp" \ + ".\languages\squirrel\squirrel\sqtable.cpp" \ + ".\languages\squirrel\squirrel\sqvm.cpp" \ + ".\languages\squirrel\sqdbg\sqrdbg.cpp" \ + ".\languages\squirrel\sqdbg\sqdbgserver.cpp" + { + $Configuration + { + $Compiler + { + $AdditionalIncludeDirectories "$BASE,.\languages\squirrel\include;.\languages\squirrel\sqplus" + $WarningLevel "Level 3 (/W3)" + $Detect64bitPortabilityIssues "No" + $PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE;VSCRIPT_DLL_EXPORT" + } + } + } + } + + $Folder "Header Files" + { + $File ".\languages\squirrel\squirrel\sqarray.h" \ + ".\languages\squirrel\squirrel\sqclass.h" \ + ".\languages\squirrel\squirrel\sqclosure.h" \ + ".\languages\squirrel\squirrel\sqcompiler.h" \ + ".\languages\squirrel\squirrel\sqfuncproto.h" \ + ".\languages\squirrel\squirrel\sqfuncstate.h" \ + ".\languages\squirrel\squirrel\sqlexer.h" \ + ".\languages\squirrel\squirrel\sqobject.h" \ + ".\languages\squirrel\squirrel\sqopcodes.h" \ + ".\languages\squirrel\squirrel\sqpcheader.h" \ + ".\languages\squirrel\squirrel\sqstate.h" \ + ".\languages\squirrel\squirrel\sqstring.h" \ + ".\languages\squirrel\squirrel\sqtable.h" \ + ".\languages\squirrel\squirrel\squserdata.h" \ + ".\languages\squirrel\squirrel\squtils.h" \ + ".\languages\squirrel\squirrel\sqvm.h" + } + } + $Folder "sqstdlib" + { + $Folder "Source Files" + { + $File ".\languages\squirrel\sqstdlib\sqstdaux.cpp"\ + ".\languages\squirrel\sqstdlib\sqstdblob.cpp" \ + ".\languages\squirrel\sqstdlib\sqstdmath.cpp" \ + ".\languages\squirrel\sqstdlib\sqstdrex.cpp" \ + ".\languages\squirrel\sqstdlib\sqstdstream.cpp" \ + ".\languages\squirrel\sqstdlib\sqstdstring.cpp" + { + $Configuration + { + $Compiler + { + $AdditionalIncludeDirectories "$BASE,.\languages\squirrel\include;.\languages\squirrel\sqplus" + $WarningLevel "Level 3 (/W3)" + $Detect64bitPortabilityIssues "No" + $PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE;VSCRIPT_DLL_EXPORT" + } + } + } + } + } + $Folder "sqplus" + { + $Folder "Source Files" + { + $File ".\languages\squirrel\sqplus\SqPlus.cpp" \ + ".\languages\squirrel\sqplus\SquirrelBindingsUtils.cpp" \ + ".\languages\squirrel\sqplus\SquirrelBindingsUtilsWin32.cpp" \ + ".\languages\squirrel\sqplus\SquirrelObject.cpp" \ + ".\languages\squirrel\sqplus\SquirrelVM.cpp" + { + $Configuration + { + $Compiler + { + $AdditionalIncludeDirectories "$BASE,.\languages\squirrel\include;.\languages\squirrel\sqplus" + $WarningLevel "Level 3 (/W3)" + $Detect64bitPortabilityIssues "No" + // "SQPlus" need exceptions. If commit to squirrel, look into removing that + $AdditionalOptions "/EHa" + $PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE;VSCRIPT_DLL_EXPORT" + } + } + } + } + $Folder "Header Files" + { + $File ".\languages\squirrel\sqplus\sqplus.h" \ + ".\languages\squirrel\sqplus\SqPlusConst.h" \ + ".\languages\squirrel\sqplus\sqplusWin32.h" \ + ".\languages\squirrel\sqplus\SquirrelBindingsUtils.h" \ + ".\languages\squirrel\sqplus\SquirrelBindingsUtilsWin32.h" \ + ".\languages\squirrel\sqplus\SquirrelObject.h" \ + ".\languages\squirrel\sqplus\SquirrelVM.h" + } + } + } + + $Folder "Lua" + { + $Folder "lua-5.1.4" + { + $Folder "Source Files" + { + $File ".\languages\lua\lua-5.1.4\src\lapi.c" \ + ".\languages\lua\lua-5.1.4\src\lauxlib.c" \ + ".\languages\lua\lua-5.1.4\src\lbaselib.c" \ + ".\languages\lua\lua-5.1.4\src\lcode.c" \ + ".\languages\lua\lua-5.1.4\src\ldblib.c" \ + ".\languages\lua\lua-5.1.4\src\ldebug.c" \ + ".\languages\lua\lua-5.1.4\src\ldo.c" \ + ".\languages\lua\lua-5.1.4\src\ldump.c" \ + ".\languages\lua\lua-5.1.4\src\lfunc.c" \ + ".\languages\lua\lua-5.1.4\src\lgc.c" \ + ".\languages\lua\lua-5.1.4\src\linit.c" \ + ".\languages\lua\lua-5.1.4\src\liolib.c" \ + ".\languages\lua\lua-5.1.4\src\llex.c" \ + ".\languages\lua\lua-5.1.4\src\lmathlib.c" \ + ".\languages\lua\lua-5.1.4\src\lmem.c" \ + ".\languages\lua\lua-5.1.4\src\loadlib.c" \ + ".\languages\lua\lua-5.1.4\src\lobject.c" \ + ".\languages\lua\lua-5.1.4\src\lopcodes.c" \ + ".\languages\lua\lua-5.1.4\src\loslib.c" \ + ".\languages\lua\lua-5.1.4\src\lparser.c" \ + ".\languages\lua\lua-5.1.4\src\lstate.c" \ + ".\languages\lua\lua-5.1.4\src\lstring.c" \ + ".\languages\lua\lua-5.1.4\src\lstrlib.c" \ + ".\languages\lua\lua-5.1.4\src\ltable.c" \ + ".\languages\lua\lua-5.1.4\src\ltablib.c" \ + ".\languages\lua\lua-5.1.4\src\ltm.c" \ + ".\languages\lua\lua-5.1.4\src\lundump.c" \ + ".\languages\lua\lua-5.1.4\src\lvm.c" \ + ".\languages\lua\lua-5.1.4\src\lzio.c" \ + ".\languages\lua\lua-5.1.4\src\print.c" + { + $Configuration + { + $Compiler + { + $WarningLevel "Level 3 (/W3)" + $Detect64bitPortabilityIssues "No" + $CompileAs "Default" + } + } + } + } + $Folder "Header Files" + { + $File ".\languages\lua\lua-5.1.4\src\lapi.h" \ + ".\languages\lua\lua-5.1.4\src\lauxlib.h" \ + ".\languages\lua\lua-5.1.4\src\lcode.h" \ + ".\languages\lua\lua-5.1.4\src\ldebug.h" \ + ".\languages\lua\lua-5.1.4\src\ldo.h" \ + ".\languages\lua\lua-5.1.4\src\lfunc.h" \ + ".\languages\lua\lua-5.1.4\src\lgc.h" \ + ".\languages\lua\lua-5.1.4\src\llex.h" \ + ".\languages\lua\lua-5.1.4\src\llimits.h" \ + ".\languages\lua\lua-5.1.4\src\lmem.h" \ + ".\languages\lua\lua-5.1.4\src\lobject.h" \ + ".\languages\lua\lua-5.1.4\src\lopcodes.h" \ + ".\languages\lua\lua-5.1.4\src\lparser.h" \ + ".\languages\lua\lua-5.1.4\src\lstate.h" \ + ".\languages\lua\lua-5.1.4\src\lstring.h" \ + ".\languages\lua\lua-5.1.4\src\ltable.h" \ + ".\languages\lua\lua-5.1.4\src\ltm.h" \ + ".\languages\lua\lua-5.1.4\src\lua.h" \ + ".\languages\lua\lua-5.1.4\src\luaconf.h" \ + ".\languages\lua\lua-5.1.4\src\lualib.h" \ + ".\languages\lua\lua-5.1.4\src\lundump.h" \ + ".\languages\lua\lua-5.1.4\src\lvm.h" \ + ".\languages\lua\lua-5.1.4\src\lzio.h" + } + } + $Folder "Support" + { + $File ".\languages\lua\vlua\vec3.cpp" + $File ".\languages\lua\vlua\vec3.h" + } + } + + $Folder "Link Libraries" + { + $File "$SRCDIR\lib\public\mathlib.lib" + } +} diff --git a/vscript/vsi.nul b/vscript/vsi.nul new file mode 100644 index 00000000..2165fcce --- /dev/null +++ b/vscript/vsi.nul @@ -0,0 +1,2 @@ +SN Visual Studio Integration +IMPORTANT: Do not remove the custom build step for this file diff --git a/vscript/xbox/xbox.def b/vscript/xbox/xbox.def new file mode 100644 index 00000000..56cb8ed6 --- /dev/null +++ b/vscript/xbox/xbox.def @@ -0,0 +1,3 @@ +LIBRARY vscript_360.dll +EXPORTS + CreateInterface @1 \ No newline at end of file diff --git a/wscript b/wscript index d04bc604..998074f1 100644 --- a/wscript +++ b/wscript @@ -39,8 +39,8 @@ projects={ 'engine', 'engine/voice_codecs/minimp3', 'filesystem', - 'game/client', - 'game/server', +# 'game/client', +# 'game/server', 'gameui', 'inputsystem', 'ivp/havana', @@ -162,6 +162,8 @@ def define_platform(conf): conf.env.GL = conf.options.GL and not conf.options.TESTS and not conf.options.DEDICATED conf.env.OPUS = conf.options.OPUS + conf.define('SOURCE_ASW', 1) + if conf.options.DEDICATED: conf.options.SDL = False conf.define('DEDICATED', 1)

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%0Ax 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 LCl`?gBP0GFit-H| literal 0 HcmV?d00001 diff --git a/vscript/languages/gm/doc/GameMonkeyLicense.pdf b/vscript/languages/gm/doc/GameMonkeyLicense.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e7929cde673ef495fc38279a828867a5f4057995 GIT binary patch literal 77591 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∋|<}Y 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 literal 0 HcmV?d00001 diff --git a/vscript/languages/gm/doc/GameMonkeyScriptReference.pdf b/vscript/languages/gm/doc/GameMonkeyScriptReference.pdf new file mode 100644 index 0000000000000000000000000000000000000000..995996a4216289b0dca49fb3807f1f0a4ed1cb39 GIT binary patch literal 221424 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 phbp^gH`|3v|9?5`KobA} literal 0 HcmV?d00001 diff --git a/vscript/languages/gm/doc/ToDoList.txt b/vscript/languages/gm/doc/ToDoList.txt new file mode 100644 index 00000000..a1825a1c --- /dev/null +++ b/vscript/languages/gm/doc/ToDoList.txt @@ -0,0 +1,27 @@ +----------------------------------------------------------- +GameMonkey Script TODO list + +In no particular order unless otherwise specified. No time +frame for changes or features, so effectively a wish list. +----------------------------------------------------------- + +o Fix empty / commented out script from producing parse error. Work around: Add a ';' semicolon to end of source, or ignore known empty scripts. +o Change overide 'this' syntax from this:func() to func() to support member chains eg. a.b.c() +o Put ++, -- operators back, but don't let them be used in conditions for consistency. + + +o Make string hash table resize for efficiency in string intensive applications. +o Make compiler thread safe. Probably by moving to Lemon parser and Flex++. +o Make user type Ids sharable between gmMachine instances so identical registration order is not required. +o Make 64bit compatible. +o Add exception handling like try / catch blocks. +o Possibly move code from gmThread into gmMachine. +o Possibly optimize byte code by moving to register stack machine. +o Possibly allow extra (eg. variable number of) parameters to be passes as a table to script functions. +o Optimize thread code to efficiently handle enormous numbers of threads. +o Expose more to the debugger. +o Eventually remove classic garbage collector, leaving only incremental collector. +o Option for unicode strings. +o Binding to allow user type creation and operator functions from within script. +o Possibly store the 'color' bit and 'persistent' bit flags for GCObjects in the lower, unused part of the list pointer. +o Possibly change the double linked list to a single XOR encoded link. This CPU for memory trade may not be worthwhile. diff --git a/vscript/languages/gm/doc/gmdoc.html b/vscript/languages/gm/doc/gmdoc.html new file mode 100644 index 00000000..a23259de --- /dev/null +++ b/vscript/languages/gm/doc/gmdoc.html @@ -0,0 +1,308 @@ +GM Documentation