diff options
author | Lua Team <team@lua.org> | 2005-11-18 12:00:00 +0000 |
---|---|---|
committer | repogen <> | 2005-11-18 12:00:00 +0000 |
commit | b3196343ba1a5dfe10e68eb9c61dc0ad5bb961a8 (patch) | |
tree | d3efede68270d3986c0f78101e55d17577a62666 | |
parent | bd80c4ee9b6d9464cf9f3ff4ee41890d8b3ca9e6 (diff) | |
download | lua-github-5.1-beta.tar.gz |
Lua 5.1-beta5.1-beta
-rw-r--r-- | HISTORY | 2 | ||||
-rw-r--r-- | INSTALL | 4 | ||||
-rw-r--r-- | MANIFEST | 214 | ||||
-rw-r--r-- | Makefile | 12 | ||||
-rw-r--r-- | README | 2 | ||||
-rw-r--r-- | doc/contents.html | 273 | ||||
-rw-r--r-- | doc/manual.html | 1285 | ||||
-rw-r--r-- | src/lapi.c | 22 | ||||
-rw-r--r-- | src/lauxlib.c | 19 | ||||
-rw-r--r-- | src/lauxlib.h | 3 | ||||
-rw-r--r-- | src/lbaselib.c | 48 | ||||
-rw-r--r-- | src/lcode.c | 279 | ||||
-rw-r--r-- | src/lcode.h | 8 | ||||
-rw-r--r-- | src/ldblib.c | 11 | ||||
-rw-r--r-- | src/ldebug.c | 55 | ||||
-rw-r--r-- | src/ldo.c | 16 | ||||
-rw-r--r-- | src/ldump.c | 53 | ||||
-rw-r--r-- | src/liolib.c | 6 | ||||
-rw-r--r-- | src/llex.c | 40 | ||||
-rw-r--r-- | src/loadlib.c | 25 | ||||
-rw-r--r-- | src/lobject.c | 4 | ||||
-rw-r--r-- | src/lobject.h | 4 | ||||
-rw-r--r-- | src/lopcodes.c | 6 | ||||
-rw-r--r-- | src/lopcodes.h | 10 | ||||
-rw-r--r-- | src/loslib.c | 6 | ||||
-rw-r--r-- | src/lparser.c | 43 | ||||
-rw-r--r-- | src/lparser.h | 8 | ||||
-rw-r--r-- | src/lstate.c | 10 | ||||
-rw-r--r-- | src/lstrlib.c | 133 | ||||
-rw-r--r-- | src/ltable.c | 10 | ||||
-rw-r--r-- | src/ltablib.c | 58 | ||||
-rw-r--r-- | src/lua.c | 186 | ||||
-rw-r--r-- | src/lua.h | 12 | ||||
-rw-r--r-- | src/luac.c | 19 | ||||
-rw-r--r-- | src/luaconf.h | 168 | ||||
-rw-r--r-- | src/lundump.c | 149 | ||||
-rw-r--r-- | src/lundump.h | 34 | ||||
-rw-r--r-- | src/lvm.c | 118 | ||||
-rw-r--r-- | src/print.c | 9 |
39 files changed, 1862 insertions, 1502 deletions
@@ -1,4 +1,4 @@ -This is Lua 5.1 (alpha). +This is Lua 5.1 (beta). * Changes from version 5.0 to 5.1 ------------------------------- @@ -1,10 +1,12 @@ -This is Lua 5.1 (alpha). +This is Lua 5.1 (beta). * Installation ------------ Building Lua on a Unix system should be very easy: simply doing "make" should work. This will build Lua in the src directory. + There are also special make targets for ansi, linux, bsd, mingw. + See below for customization instructions. If you want to install Lua in an official place in your system, then @@ -1,108 +1,108 @@ -MANIFEST contents of Lua 5.1 (alpha) distribution on Fri Sep 9 16:55:12 BRST 2005 -lua-5.1-alpha -lua-5.1-alpha/COPYRIGHT -lua-5.1-alpha/HISTORY -lua-5.1-alpha/INSTALL -lua-5.1-alpha/MANIFEST -lua-5.1-alpha/Makefile -lua-5.1-alpha/README -lua-5.1-alpha/doc -lua-5.1-alpha/doc/contents.html -lua-5.1-alpha/doc/logo.gif -lua-5.1-alpha/doc/lua.1 -lua-5.1-alpha/doc/lua.css -lua-5.1-alpha/doc/lua.html -lua-5.1-alpha/doc/luac.1 -lua-5.1-alpha/doc/luac.html -lua-5.1-alpha/doc/manual.html -lua-5.1-alpha/doc/readme.html -lua-5.1-alpha/etc -lua-5.1-alpha/etc/Makefile -lua-5.1-alpha/etc/README -lua-5.1-alpha/etc/all.c -lua-5.1-alpha/etc/lua.hpp -lua-5.1-alpha/etc/lua.ico -lua-5.1-alpha/etc/lua.pc -lua-5.1-alpha/etc/luavs.bat -lua-5.1-alpha/etc/min.c -lua-5.1-alpha/etc/noparser.c -lua-5.1-alpha/etc/strict.lua -lua-5.1-alpha/src -lua-5.1-alpha/src/Makefile -lua-5.1-alpha/src/lapi.c -lua-5.1-alpha/src/lapi.h -lua-5.1-alpha/src/lauxlib.c -lua-5.1-alpha/src/lauxlib.h -lua-5.1-alpha/src/lbaselib.c -lua-5.1-alpha/src/lcode.c -lua-5.1-alpha/src/lcode.h -lua-5.1-alpha/src/ldblib.c -lua-5.1-alpha/src/ldebug.c -lua-5.1-alpha/src/ldebug.h -lua-5.1-alpha/src/ldo.c -lua-5.1-alpha/src/ldo.h -lua-5.1-alpha/src/ldump.c -lua-5.1-alpha/src/lfunc.c -lua-5.1-alpha/src/lfunc.h -lua-5.1-alpha/src/lgc.c -lua-5.1-alpha/src/lgc.h -lua-5.1-alpha/src/linit.c -lua-5.1-alpha/src/liolib.c -lua-5.1-alpha/src/llex.c -lua-5.1-alpha/src/llex.h -lua-5.1-alpha/src/llimits.h -lua-5.1-alpha/src/lmathlib.c -lua-5.1-alpha/src/lmem.c -lua-5.1-alpha/src/lmem.h -lua-5.1-alpha/src/loadlib.c -lua-5.1-alpha/src/lobject.c -lua-5.1-alpha/src/lobject.h -lua-5.1-alpha/src/lopcodes.c -lua-5.1-alpha/src/lopcodes.h -lua-5.1-alpha/src/loslib.c -lua-5.1-alpha/src/lparser.c -lua-5.1-alpha/src/lparser.h -lua-5.1-alpha/src/lstate.c -lua-5.1-alpha/src/lstate.h -lua-5.1-alpha/src/lstring.c -lua-5.1-alpha/src/lstring.h -lua-5.1-alpha/src/lstrlib.c -lua-5.1-alpha/src/ltable.c -lua-5.1-alpha/src/ltable.h -lua-5.1-alpha/src/ltablib.c -lua-5.1-alpha/src/ltm.c -lua-5.1-alpha/src/ltm.h -lua-5.1-alpha/src/lua.c -lua-5.1-alpha/src/lua.h -lua-5.1-alpha/src/luac.c -lua-5.1-alpha/src/luaconf.h -lua-5.1-alpha/src/lualib.h -lua-5.1-alpha/src/lundump.c -lua-5.1-alpha/src/lundump.h -lua-5.1-alpha/src/lvm.c -lua-5.1-alpha/src/lvm.h -lua-5.1-alpha/src/lzio.c -lua-5.1-alpha/src/lzio.h -lua-5.1-alpha/src/print.c -lua-5.1-alpha/test -lua-5.1-alpha/test/README -lua-5.1-alpha/test/bisect.lua -lua-5.1-alpha/test/cf.lua -lua-5.1-alpha/test/echo.lua -lua-5.1-alpha/test/env.lua -lua-5.1-alpha/test/factorial.lua -lua-5.1-alpha/test/fib.lua -lua-5.1-alpha/test/fibfor.lua -lua-5.1-alpha/test/globals.lua -lua-5.1-alpha/test/hello.lua -lua-5.1-alpha/test/life.lua -lua-5.1-alpha/test/luac.lua -lua-5.1-alpha/test/printf.lua -lua-5.1-alpha/test/readonly.lua -lua-5.1-alpha/test/sieve.lua -lua-5.1-alpha/test/sort.lua -lua-5.1-alpha/test/table.lua -lua-5.1-alpha/test/trace-calls.lua -lua-5.1-alpha/test/trace-globals.lua -lua-5.1-alpha/test/xd.lua +MANIFEST contents of Lua 5.1 (beta) distribution on Fri Nov 18 07:42:23 BRST 2005 +lua-5.1-beta +lua-5.1-beta/COPYRIGHT +lua-5.1-beta/HISTORY +lua-5.1-beta/INSTALL +lua-5.1-beta/MANIFEST +lua-5.1-beta/Makefile +lua-5.1-beta/README +lua-5.1-beta/doc +lua-5.1-beta/doc/contents.html +lua-5.1-beta/doc/logo.gif +lua-5.1-beta/doc/lua.1 +lua-5.1-beta/doc/lua.css +lua-5.1-beta/doc/lua.html +lua-5.1-beta/doc/luac.1 +lua-5.1-beta/doc/luac.html +lua-5.1-beta/doc/manual.html +lua-5.1-beta/doc/readme.html +lua-5.1-beta/etc +lua-5.1-beta/etc/Makefile +lua-5.1-beta/etc/README +lua-5.1-beta/etc/all.c +lua-5.1-beta/etc/lua.hpp +lua-5.1-beta/etc/lua.ico +lua-5.1-beta/etc/lua.pc +lua-5.1-beta/etc/luavs.bat +lua-5.1-beta/etc/min.c +lua-5.1-beta/etc/noparser.c +lua-5.1-beta/etc/strict.lua +lua-5.1-beta/src +lua-5.1-beta/src/Makefile +lua-5.1-beta/src/lapi.c +lua-5.1-beta/src/lapi.h +lua-5.1-beta/src/lauxlib.c +lua-5.1-beta/src/lauxlib.h +lua-5.1-beta/src/lbaselib.c +lua-5.1-beta/src/lcode.c +lua-5.1-beta/src/lcode.h +lua-5.1-beta/src/ldblib.c +lua-5.1-beta/src/ldebug.c +lua-5.1-beta/src/ldebug.h +lua-5.1-beta/src/ldo.c +lua-5.1-beta/src/ldo.h +lua-5.1-beta/src/ldump.c +lua-5.1-beta/src/lfunc.c +lua-5.1-beta/src/lfunc.h +lua-5.1-beta/src/lgc.c +lua-5.1-beta/src/lgc.h +lua-5.1-beta/src/linit.c +lua-5.1-beta/src/liolib.c +lua-5.1-beta/src/llex.c +lua-5.1-beta/src/llex.h +lua-5.1-beta/src/llimits.h +lua-5.1-beta/src/lmathlib.c +lua-5.1-beta/src/lmem.c +lua-5.1-beta/src/lmem.h +lua-5.1-beta/src/loadlib.c +lua-5.1-beta/src/lobject.c +lua-5.1-beta/src/lobject.h +lua-5.1-beta/src/lopcodes.c +lua-5.1-beta/src/lopcodes.h +lua-5.1-beta/src/loslib.c +lua-5.1-beta/src/lparser.c +lua-5.1-beta/src/lparser.h +lua-5.1-beta/src/lstate.c +lua-5.1-beta/src/lstate.h +lua-5.1-beta/src/lstring.c +lua-5.1-beta/src/lstring.h +lua-5.1-beta/src/lstrlib.c +lua-5.1-beta/src/ltable.c +lua-5.1-beta/src/ltable.h +lua-5.1-beta/src/ltablib.c +lua-5.1-beta/src/ltm.c +lua-5.1-beta/src/ltm.h +lua-5.1-beta/src/lua.c +lua-5.1-beta/src/lua.h +lua-5.1-beta/src/luac.c +lua-5.1-beta/src/luaconf.h +lua-5.1-beta/src/lualib.h +lua-5.1-beta/src/lundump.c +lua-5.1-beta/src/lundump.h +lua-5.1-beta/src/lvm.c +lua-5.1-beta/src/lvm.h +lua-5.1-beta/src/lzio.c +lua-5.1-beta/src/lzio.h +lua-5.1-beta/src/print.c +lua-5.1-beta/test +lua-5.1-beta/test/README +lua-5.1-beta/test/bisect.lua +lua-5.1-beta/test/cf.lua +lua-5.1-beta/test/echo.lua +lua-5.1-beta/test/env.lua +lua-5.1-beta/test/factorial.lua +lua-5.1-beta/test/fib.lua +lua-5.1-beta/test/fibfor.lua +lua-5.1-beta/test/globals.lua +lua-5.1-beta/test/hello.lua +lua-5.1-beta/test/life.lua +lua-5.1-beta/test/luac.lua +lua-5.1-beta/test/printf.lua +lua-5.1-beta/test/readonly.lua +lua-5.1-beta/test/sieve.lua +lua-5.1-beta/test/sort.lua +lua-5.1-beta/test/table.lua +lua-5.1-beta/test/trace-calls.lua +lua-5.1-beta/test/trace-globals.lua +lua-5.1-beta/test/xd.lua END OF MANIFEST @@ -55,15 +55,21 @@ ansi: cd src; $(MAKE) MYCFLAGS=-DLUA_ANSI linux: - cd src; $(MAKE) MYCFLAGS=-DLUA_USE_DLOPEN MYLIBS="-Wl,-E -ldl" + cd src; $(MAKE) MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses" + +macosx: + cd src; $(MAKE) MYCFLAGS=-DLUA_USE_MACOSX + +posix: + cd src; $(MAKE) MYCFLAGS=-DLUA_USE_POSIX bsd: - cd src; $(MAKE) MYCFLAGS=-DLUA_USE_DLOPEN MYLIBS="-Wl,-E" + cd src; $(MAKE) MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E" mingw: cd src; $(MAKE) "LUA_A=lua51.dll" "LUA_T=lua.exe" \ "AR=gcc -shared -o" "RANLIB=strip --strip-unneeded" \ - "MYCFLAGS=-DLUA_BUILD_AS_DLL" "MYLIBS=" MYLDFLAGS=-s" lua.exe + "MYCFLAGS=-DLUA_BUILD_AS_DLL" "MYLIBS=" "MYLDFLAGS=-s" lua.exe # echo config parameters echo: @@ -1,4 +1,4 @@ -This is Lua 5.1 (alpha). +This is Lua 5.1 (beta). See HISTORY for a summary of changes since the last released version. * What is Lua? diff --git a/doc/contents.html b/doc/contents.html index 9db0cafa..25dd0c5a 100644 --- a/doc/contents.html +++ b/doc/contents.html @@ -19,6 +19,7 @@ Lua 5.1 Reference Manual <HR> <UL> +<LI><A HREF="#words">Word index</A> <LI><A HREF="manual.html">Top</A> <LI><A HREF="manual.html#1">1 - Introduction</A> <LI><A HREF="manual.html#2">2 - The Language</A> @@ -93,10 +94,280 @@ Lua 5.1 Reference Manual <LI><A HREF="manual.html#BNF">The Complete Syntax of Lua</A> </UL> +<H3><A NAME="words">Word index</A></H3> + +<A HREF="manual.html#pdf-_G">_G</A><BR> +<A HREF="manual.html#pdf-_VERSION">_VERSION</A><BR> +<A HREF="manual.html#pdf-assert">assert</A><BR> +<A HREF="manual.html#pdf-collectgarbage">collectgarbage</A><BR> +<A HREF="manual.html#pdf-coroutine.create">coroutine.create</A><BR> +<A HREF="manual.html#pdf-coroutine.resume">coroutine.resume</A><BR> +<A HREF="manual.html#pdf-coroutine.running">coroutine.running</A><BR> +<A HREF="manual.html#pdf-coroutine.status">coroutine.status</A><BR> +<A HREF="manual.html#pdf-coroutine.wrap">coroutine.wrap</A><BR> +<A HREF="manual.html#pdf-coroutine.yield">coroutine.yield</A><BR> +<A HREF="manual.html#pdf-debug.debug">debug.debug</A><BR> +<A HREF="manual.html#pdf-debug.getfenv">debug.getfenv</A><BR> +<A HREF="manual.html#pdf-debug.gethook">debug.gethook</A><BR> +<A HREF="manual.html#pdf-debug.getinfo">debug.getinfo</A><BR> +<A HREF="manual.html#pdf-debug.getlocal">debug.getlocal</A><BR> +<A HREF="manual.html#pdf-debug.getmetatable">debug.getmetatable</A><BR> +<A HREF="manual.html#pdf-debug.getregistry">debug.getregistry</A><BR> +<A HREF="manual.html#pdf-debug.getupvalue">debug.getupvalue</A><BR> +<A HREF="manual.html#pdf-debug.setfenv">debug.setfenv</A><BR> +<A HREF="manual.html#pdf-debug.sethook">debug.sethook</A><BR> +<A HREF="manual.html#pdf-debug.setlocal">debug.setlocal</A><BR> +<A HREF="manual.html#pdf-debug.setmetatable">debug.setmetatable</A><BR> +<A HREF="manual.html#pdf-debug.setupvalue">debug.setupvalue</A><BR> +<A HREF="manual.html#pdf-debug.traceback">debug.traceback</A><BR> +<A HREF="manual.html#pdf-dofile">dofile</A><BR> +<A HREF="manual.html#pdf-error">error</A><BR> +<A HREF="manual.html#pdf-file:close">file:close</A><BR> +<A HREF="manual.html#pdf-file:flush">file:flush</A><BR> +<A HREF="manual.html#pdf-file:lines">file:lines</A><BR> +<A HREF="manual.html#pdf-file:read">file:read</A><BR> +<A HREF="manual.html#pdf-file:seek">file:seek</A><BR> +<A HREF="manual.html#pdf-file:setvbuf">file:setvbuf</A><BR> +<A HREF="manual.html#pdf-file:write">file:write</A><BR> +<A HREF="manual.html#pdf-getfenv">getfenv</A><BR> +<A HREF="manual.html#pdf-getmetatable">getmetatable</A><BR> +<A HREF="manual.html#pdf-io.close">io.close</A><BR> +<A HREF="manual.html#pdf-io.flush">io.flush</A><BR> +<A HREF="manual.html#pdf-io.input">io.input</A><BR> +<A HREF="manual.html#pdf-io.lines">io.lines</A><BR> +<A HREF="manual.html#pdf-io.open">io.open</A><BR> +<A HREF="manual.html#pdf-io.output">io.output</A><BR> +<A HREF="manual.html#pdf-io.popen">io.popen</A><BR> +<A HREF="manual.html#pdf-io.read">io.read</A><BR> +<A HREF="manual.html#pdf-io.tmpfile">io.tmpfile</A><BR> +<A HREF="manual.html#pdf-io.type">io.type</A><BR> +<A HREF="manual.html#pdf-io.write">io.write</A><BR> +<A HREF="manual.html#pdf-ipairs">ipairs</A><BR> +<A HREF="manual.html#pdf-load">load</A><BR> +<A HREF="manual.html#pdf-loadfile">loadfile</A><BR> +<A HREF="manual.html#pdf-loadstring">loadstring</A><BR> + +<A HREF="manual.html#luaL_Buffer">luaL_Buffer</A><BR> +<A HREF="manual.html#luaL_Reg">luaL_Reg</A><BR> +<A HREF="manual.html#luaL_addchar">luaL_addchar</A><BR> +<A HREF="manual.html#luaL_addlstring">luaL_addlstring</A><BR> +<A HREF="manual.html#luaL_addsize">luaL_addsize</A><BR> +<A HREF="manual.html#luaL_addstring">luaL_addstring</A><BR> +<A HREF="manual.html#luaL_addvalue">luaL_addvalue</A><BR> +<A HREF="manual.html#luaL_argcheck">luaL_argcheck</A><BR> +<A HREF="manual.html#luaL_argerror">luaL_argerror</A><BR> +<A HREF="manual.html#luaL_buffinit">luaL_buffinit</A><BR> +<A HREF="manual.html#luaL_callmeta">luaL_callmeta</A><BR> +<A HREF="manual.html#luaL_checkany">luaL_checkany</A><BR> +<A HREF="manual.html#luaL_checkint">luaL_checkint</A><BR> +<A HREF="manual.html#luaL_checkinteger">luaL_checkinteger</A><BR> +<A HREF="manual.html#luaL_checklong">luaL_checklong</A><BR> +<A HREF="manual.html#luaL_checklstring">luaL_checklstring</A><BR> +<A HREF="manual.html#luaL_checknumber">luaL_checknumber</A><BR> +<A HREF="manual.html#luaL_checkoption">luaL_checkoption</A><BR> +<A HREF="manual.html#luaL_checkstack">luaL_checkstack</A><BR> +<A HREF="manual.html#luaL_checkstring">luaL_checkstring</A><BR> +<A HREF="manual.html#luaL_checktype">luaL_checktype</A><BR> +<A HREF="manual.html#luaL_checkudata">luaL_checkudata</A><BR> +<A HREF="manual.html#luaL_error">luaL_error</A><BR> +<A HREF="manual.html#luaL_getmetafield">luaL_getmetafield</A><BR> +<A HREF="manual.html#luaL_getmetatable">luaL_getmetatable</A><BR> +<A HREF="manual.html#luaL_gsub">luaL_gsub</A><BR> +<A HREF="manual.html#luaL_loadbuffer">luaL_loadbuffer</A><BR> +<A HREF="manual.html#luaL_loadfile">luaL_loadfile</A><BR> +<A HREF="manual.html#luaL_loadstring">luaL_loadstring</A><BR> +<A HREF="manual.html#luaL_newmetatable">luaL_newmetatable</A><BR> +<A HREF="manual.html#luaL_newstate">luaL_newstate</A><BR> +<A HREF="manual.html#luaL_optint">luaL_optint</A><BR> +<A HREF="manual.html#luaL_optinteger">luaL_optinteger</A><BR> +<A HREF="manual.html#luaL_optlong">luaL_optlong</A><BR> +<A HREF="manual.html#luaL_optlstring">luaL_optlstring</A><BR> +<A HREF="manual.html#luaL_optnumber">luaL_optnumber</A><BR> +<A HREF="manual.html#luaL_optstring">luaL_optstring</A><BR> +<A HREF="manual.html#luaL_prepbuffer">luaL_prepbuffer</A><BR> +<A HREF="manual.html#luaL_pushresult">luaL_pushresult</A><BR> +<A HREF="manual.html#luaL_ref">luaL_ref</A><BR> +<A HREF="manual.html#luaL_register">luaL_register</A><BR> +<A HREF="manual.html#luaL_typename">luaL_typename</A><BR> +<A HREF="manual.html#luaL_typerror">luaL_typerror</A><BR> +<A HREF="manual.html#luaL_unref">luaL_unref</A><BR> +<A HREF="manual.html#luaL_where">luaL_where</A><BR> +<A HREF="manual.html#lua_Alloc">lua_Alloc</A><BR> +<A HREF="manual.html#lua_CFunction">lua_CFunction</A><BR> +<A HREF="manual.html#lua_Debug">lua_Debug</A><BR> +<A HREF="manual.html#lua_Hook">lua_Hook</A><BR> +<A HREF="manual.html#lua_Integer">lua_Integer</A><BR> +<A HREF="manual.html#lua_Number">lua_Number</A><BR> +<A HREF="manual.html#lua_Reader">lua_Reader</A><BR> +<A HREF="manual.html#lua_State">lua_State</A><BR> +<A HREF="manual.html#lua_Writer">lua_Writer</A><BR> +<A HREF="manual.html#lua_atpanic">lua_atpanic</A><BR> +<A HREF="manual.html#lua_call">lua_call</A><BR> +<A HREF="manual.html#lua_checkstack">lua_checkstack</A><BR> +<A HREF="manual.html#lua_close">lua_close</A><BR> +<A HREF="manual.html#lua_concat">lua_concat</A><BR> +<A HREF="manual.html#lua_cpcall">lua_cpcall</A><BR> +<A HREF="manual.html#lua_createtable">lua_createtable</A><BR> +<A HREF="manual.html#lua_dump">lua_dump</A><BR> +<A HREF="manual.html#lua_equal">lua_equal</A><BR> +<A HREF="manual.html#lua_error">lua_error</A><BR> +<A HREF="manual.html#lua_gc">lua_gc</A><BR> +<A HREF="manual.html#lua_getallocf">lua_getallocf</A><BR> +<A HREF="manual.html#lua_getfenv">lua_getfenv</A><BR> +<A HREF="manual.html#lua_getfield">lua_getfield</A><BR> +<A HREF="manual.html#lua_gethook">lua_gethook</A><BR> +<A HREF="manual.html#lua_gethookcount">lua_gethookcount</A><BR> +<A HREF="manual.html#lua_gethookmask">lua_gethookmask</A><BR> +<A HREF="manual.html#lua_getinfo">lua_getinfo</A><BR> +<A HREF="manual.html#lua_getlocal">lua_getlocal</A><BR> +<A HREF="manual.html#lua_getmetatable">lua_getmetatable</A><BR> +<A HREF="manual.html#lua_getstack">lua_getstack</A><BR> +<A HREF="manual.html#lua_gettable">lua_gettable</A><BR> +<A HREF="manual.html#lua_gettop">lua_gettop</A><BR> +<A HREF="manual.html#lua_getupvalue">lua_getupvalue</A><BR> +<A HREF="manual.html#lua_insert">lua_insert</A><BR> +<A HREF="manual.html#lua_isboolean">lua_isboolean</A><BR> +<A HREF="manual.html#lua_iscfunction">lua_iscfunction</A><BR> +<A HREF="manual.html#lua_isfunction">lua_isfunction</A><BR> +<A HREF="manual.html#lua_islightuserdata">lua_islightuserdata</A><BR> +<A HREF="manual.html#lua_isnil">lua_isnil</A><BR> +<A HREF="manual.html#lua_isnumber">lua_isnumber</A><BR> +<A HREF="manual.html#lua_isstring">lua_isstring</A><BR> +<A HREF="manual.html#lua_istable">lua_istable</A><BR> +<A HREF="manual.html#lua_isthread">lua_isthread</A><BR> +<A HREF="manual.html#lua_isuserdata">lua_isuserdata</A><BR> +<A HREF="manual.html#lua_lessthan">lua_lessthan</A><BR> +<A HREF="manual.html#lua_load">lua_load</A><BR> +<A HREF="manual.html#lua_newstate">lua_newstate</A><BR> +<A HREF="manual.html#lua_newtable">lua_newtable</A><BR> +<A HREF="manual.html#lua_newthread">lua_newthread</A><BR> +<A HREF="manual.html#lua_newuserdata">lua_newuserdata</A><BR> +<A HREF="manual.html#lua_next">lua_next</A><BR> +<A HREF="manual.html#lua_objlen">lua_objlen</A><BR> +<A HREF="manual.html#lua_pcall">lua_pcall</A><BR> +<A HREF="manual.html#lua_pop">lua_pop</A><BR> +<A HREF="manual.html#lua_pushboolean">lua_pushboolean</A><BR> +<A HREF="manual.html#lua_pushcclosure">lua_pushcclosure</A><BR> +<A HREF="manual.html#lua_pushcfunction">lua_pushcfunction</A><BR> +<A HREF="manual.html#lua_pushfstring">lua_pushfstring</A><BR> +<A HREF="manual.html#lua_pushinteger">lua_pushinteger</A><BR> +<A HREF="manual.html#lua_pushlightuserdata">lua_pushlightuserdata</A><BR> +<A HREF="manual.html#lua_pushlstring">lua_pushlstring</A><BR> +<A HREF="manual.html#lua_pushnil">lua_pushnil</A><BR> +<A HREF="manual.html#lua_pushnumber">lua_pushnumber</A><BR> +<A HREF="manual.html#lua_pushstring">lua_pushstring</A><BR> +<A HREF="manual.html#lua_pushvalue">lua_pushvalue</A><BR> +<A HREF="manual.html#lua_pushvfstring">lua_pushvfstring</A><BR> +<A HREF="manual.html#lua_rawequal">lua_rawequal</A><BR> +<A HREF="manual.html#lua_rawget">lua_rawget</A><BR> +<A HREF="manual.html#lua_rawgeti">lua_rawgeti</A><BR> +<A HREF="manual.html#lua_rawset">lua_rawset</A><BR> +<A HREF="manual.html#lua_rawseti">lua_rawseti</A><BR> +<A HREF="manual.html#lua_remove">lua_remove</A><BR> +<A HREF="manual.html#lua_replace">lua_replace</A><BR> +<A HREF="manual.html#lua_resume">lua_resume</A><BR> +<A HREF="manual.html#lua_setallocf">lua_setallocf</A><BR> +<A HREF="manual.html#lua_setfenv">lua_setfenv</A><BR> +<A HREF="manual.html#lua_setfield">lua_setfield</A><BR> +<A HREF="manual.html#lua_sethook">lua_sethook</A><BR> +<A HREF="manual.html#lua_setlocal">lua_setlocal</A><BR> +<A HREF="manual.html#lua_setmetatable">lua_setmetatable</A><BR> +<A HREF="manual.html#lua_settable">lua_settable</A><BR> +<A HREF="manual.html#lua_settop">lua_settop</A><BR> +<A HREF="manual.html#lua_setupvalue">lua_setupvalue</A><BR> +<A HREF="manual.html#lua_toboolean">lua_toboolean</A><BR> +<A HREF="manual.html#lua_tocfunction">lua_tocfunction</A><BR> +<A HREF="manual.html#lua_tointeger">lua_tointeger</A><BR> +<A HREF="manual.html#lua_tolstring">lua_tolstring</A><BR> +<A HREF="manual.html#lua_tonumber">lua_tonumber</A><BR> +<A HREF="manual.html#lua_topointer">lua_topointer</A><BR> +<A HREF="manual.html#lua_tostring">lua_tostring</A><BR> +<A HREF="manual.html#lua_tothread">lua_tothread</A><BR> +<A HREF="manual.html#lua_touserdata">lua_touserdata</A><BR> +<A HREF="manual.html#lua_type">lua_type</A><BR> +<A HREF="manual.html#lua_xmove">lua_xmove</A><BR> +<A HREF="manual.html#lua_yield">lua_yield</A><BR> + +<A HREF="manual.html#pdf-math.abs">math.abs</A><BR> +<A HREF="manual.html#pdf-math.acos">math.acos</A><BR> +<A HREF="manual.html#pdf-math.asin">math.asin</A><BR> +<A HREF="manual.html#pdf-math.atan">math.atan</A><BR> +<A HREF="manual.html#pdf-math.atan2">math.atan2</A><BR> +<A HREF="manual.html#pdf-math.ceil">math.ceil</A><BR> +<A HREF="manual.html#pdf-math.cos">math.cos</A><BR> +<A HREF="manual.html#pdf-math.cosh">math.cosh</A><BR> +<A HREF="manual.html#pdf-math.def">math.def</A><BR> +<A HREF="manual.html#pdf-math.exp">math.exp</A><BR> +<A HREF="manual.html#pdf-math.floor">math.floor</A><BR> +<A HREF="manual.html#pdf-math.fmod">math.fmod</A><BR> +<A HREF="manual.html#pdf-math.ldexp">math.ldexp</A><BR> +<A HREF="manual.html#pdf-math.log">math.log</A><BR> +<A HREF="manual.html#pdf-math.log10">math.log10</A><BR> +<A HREF="manual.html#pdf-math.pow">math.pow</A><BR> +<A HREF="manual.html#pdf-math.sin">math.sin</A><BR> +<A HREF="manual.html#pdf-math.sinh">math.sinh</A><BR> +<A HREF="manual.html#pdf-math.sqrt">math.sqrt</A><BR> +<A HREF="manual.html#pdf-math.tan">math.tan</A><BR> +<A HREF="manual.html#pdf-math.tanh">math.tanh</A><BR> +<A HREF="manual.html#pdf-module">module</A><BR> +<A HREF="manual.html#pdf-next">next</A><BR> +<A HREF="manual.html#pdf-os.clock">os.clock</A><BR> +<A HREF="manual.html#pdf-os.date">os.date</A><BR> +<A HREF="manual.html#pdf-os.difftime">os.difftime</A><BR> +<A HREF="manual.html#pdf-os.execute">os.execute</A><BR> +<A HREF="manual.html#pdf-os.exit">os.exit</A><BR> +<A HREF="manual.html#pdf-os.getenv">os.getenv</A><BR> +<A HREF="manual.html#pdf-os.remove">os.remove</A><BR> +<A HREF="manual.html#pdf-os.rename">os.rename</A><BR> +<A HREF="manual.html#pdf-os.setlocale">os.setlocale</A><BR> +<A HREF="manual.html#pdf-os.time">os.time</A><BR> +<A HREF="manual.html#pdf-os.tmpname">os.tmpname</A><BR> +<A HREF="manual.html#pdf-package.cpath">package.cpath</A><BR> +<A HREF="manual.html#pdf-package.loaded">package.loaded</A><BR> +<A HREF="manual.html#pdf-package.loadlib">package.loadlib</A><BR> +<A HREF="manual.html#pdf-package.path">package.path</A><BR> +<A HREF="manual.html#pdf-package.preload">package.preload</A><BR> +<A HREF="manual.html#pdf-package.seeall">package.seeall</A><BR> +<A HREF="manual.html#pdf-pairs">pairs</A><BR> +<A HREF="manual.html#pdf-pcall">pcall</A><BR> +<A HREF="manual.html#pdf-print">print</A><BR> +<A HREF="manual.html#pdf-rawequal">rawequal</A><BR> +<A HREF="manual.html#pdf-rawget">rawget</A><BR> +<A HREF="manual.html#pdf-rawset">rawset</A><BR> +<A HREF="manual.html#pdf-require">require</A><BR> +<A HREF="manual.html#pdf-select">select</A><BR> +<A HREF="manual.html#pdf-setfenv">setfenv</A><BR> +<A HREF="manual.html#pdf-setmetatable">setmetatable</A><BR> +<A HREF="manual.html#pdf-string.byte">string.byte</A><BR> +<A HREF="manual.html#pdf-string.char">string.char</A><BR> +<A HREF="manual.html#pdf-string.dump">string.dump</A><BR> +<A HREF="manual.html#pdf-string.find">string.find</A><BR> +<A HREF="manual.html#pdf-string.format">string.format</A><BR> +<A HREF="manual.html#pdf-string.gmatch">string.gmatch</A><BR> +<A HREF="manual.html#pdf-string.gsub">string.gsub</A><BR> +<A HREF="manual.html#pdf-string.len">string.len</A><BR> +<A HREF="manual.html#pdf-string.lower">string.lower</A><BR> +<A HREF="manual.html#pdf-string.match">string.match</A><BR> +<A HREF="manual.html#pdf-string.rep">string.rep</A><BR> +<A HREF="manual.html#pdf-string.reverse">string.reverse</A><BR> +<A HREF="manual.html#pdf-string.sub">string.sub</A><BR> +<A HREF="manual.html#pdf-string.upper">string.upper</A><BR> +<A HREF="manual.html#pdf-table.concat">table.concat</A><BR> +<A HREF="manual.html#pdf-table.insert">table.insert</A><BR> +<A HREF="manual.html#pdf-table.maxn(table)">table.maxn(table)</A><BR> +<A HREF="manual.html#pdf-table.remove">table.remove</A><BR> +<A HREF="manual.html#pdf-table.sort">table.sort</A><BR> +<A HREF="manual.html#pdf-tonumber">tonumber</A><BR> +<A HREF="manual.html#pdf-tostring">tostring</A><BR> +<A HREF="manual.html#pdf-type">type</A><BR> +<A HREF="manual.html#pdf-unpack">unpack</A><BR> +<A HREF="manual.html#pdf-xpcall">xpcall</A><BR> +<P> + <HR> <SMALL> Last update: -Fri Sep 9 14:44:10 BRST 2005 +Tue Nov 1 15:40:46 BRST 2005 </SMALL> </BODY> diff --git a/doc/manual.html b/doc/manual.html index b55232bd..293532f1 100644 --- a/doc/manual.html +++ b/doc/manual.html @@ -1,16 +1,16 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <html> <head> <title>Lua 5.1 Reference Manual</title> -<LINK REL="stylesheet" TYPE="text/css" HREF="lua.css"> +<link rel="stylesheet" href="lua.css"> </head> -<body BGCOLOR="#FFFFFF"> +<body bgcolor="#FFFFFF"> -<hr> +<hr/> <h1> -<a href="http://www.lua.org/home.html"><img src="logo.gif" ALT="[Lua logo]" border=0></a> +<a href="http://www.lua.org/home.html"><img src="logo.gif" alt="[Lua logo]" border="0"/></a> Lua 5.1 Reference Manual </h1> @@ -20,7 +20,7 @@ by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes <a href="http://www.lua.org/copyright.html">Copyright</a> © 2005 Lua.org, PUC-Rio. All rights reserved. </small> -<hr> +<hr/> <p> <p> @@ -28,7 +28,6 @@ by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes -<p> <a name="1"></a><h1>1 - Introduction</h1> <p>Lua is an extension programming language designed to support @@ -68,21 +67,21 @@ which are available at Lua's web site. <ul> <li> R. Ierusalimschy, L. H. de Figueiredo, and W. Celes. -Lua—an extensible extension language. -<em>Software: Practice & Experience</em> <b>26</b>:6 (1996) 635–652. +Lua---an extensible extension language. +<em>Software: Practice & Experience</em> <b>26</b>:6 (1996) 635--652. <li> L. H. de Figueiredo, R. Ierusalimschy, and W. Celes. The design and implementation of a language for extending applications. <em>Proceedings of XXI Brazilian Seminar on Software and Hardware</em> -(1994) 273–283. +(1994) 273--283. <li> L. H. de Figueiredo, R. Ierusalimschy, and W. Celes. Lua: an extensible embedded language. -<em>Dr. Dobb's Journal</em> <b>21</b>:12 (Dec 1996) 26–33. +<em>Dr. Dobb's Journal</em> <b>21</b>:12 (Dec 1996) 26--33. <li> R. Ierusalimschy, L. H. de Figueiredo, and W. Celes. The evolution of an extension language: a history of Lua, -<em>Proceedings of V Brazilian Symposium on Programming Languages</em> (2001) B-14–B-28. +<em>Proceedings of V Brazilian Symposium on Programming Languages</em> (2001) B-14--B-28. </ul> <p>Lua means "moon" in Portuguese and is pronounced LOO-ah. @@ -119,12 +118,12 @@ can be used in an identifier.) <p>The following <em>keywords</em> are reserved and cannot be used as names: -<PRE> +<pre> and break do else elseif end false for function if in local nil not or repeat return then true until while -</PRE> +</pre> <p>Lua is a case-sensitive language: <code>and</code> is a reserved word, but <code>And</code> and <code>AND</code> @@ -134,27 +133,27 @@ uppercase letters (such as <a href="#pdf-_VERSION"><code>_VERSION</code></a>) are reserved for internal variables used by Lua. <p>The following strings denote other tokens: -<PRE> +<pre> + - * / % ^ # == ~= <= >= < > = ( ) { } [ ] ; : , . .. ... -</PRE> +</pre> <p><em>Literal strings</em> can be delimited by matching single or double quotes, and can contain the following C-like escape sequences: <ul> -<li><b><code>\a</code></b> — bell -<li><b><code>\b</code></b> — backspace -<li><b><code>\f</code></b> — form feed -<li><b><code>\n</code></b> — newline -<li><b><code>\r</code></b> — carriage return -<li><b><code>\t</code></b> — horizontal tab -<li><b><code>\v</code></b> — vertical tab -<li><b><code>\\</code></b> — backslash -<li><b><code>\"</code></b> — quotation mark -<li><b><code>\'</code></b> — apostrophe +<li><b><code>\a</code></b> --- bell +<li><b><code>\b</code></b> --- backspace +<li><b><code>\f</code></b> --- form feed +<li><b><code>\n</code></b> --- newline +<li><b><code>\r</code></b> --- carriage return +<li><b><code>\t</code></b> --- horizontal tab +<li><b><code>\v</code></b> --- vertical tab +<li><b><code>\\</code></b> --- backslash +<li><b><code>\"</code></b> --- quotation mark +<li><b><code>\'</code></b> --- apostrophe </ul> Moreover, a `<code>\</code><em>newline</em>´ (that is, a backslash followed by a real newline) @@ -188,7 +187,7 @@ As an example, in a system using ASCII (in which `<code>a</code>´ is coded as 97, newline is coded as 10, and `<code>1</code>´ is coded as 49), the four literals below denote the same string: -<PRE> +<pre> (1) "alo\n123\"" (2) '\97lo\10\04923"' (3) [[alo @@ -196,14 +195,14 @@ the four literals below denote the same string: (4) [==[ alo 123"]==] -</PRE> +</pre> <p><em>Numerical constants</em> may be written with an optional decimal part and an optional decimal exponent. Examples of valid numerical constants are -<PRE> +<pre> 3 3.0 3.1416 314.16e-2 0.31416E1 -</PRE> +</pre> <p><em>Comments</em> start anywhere outside a string with a double hyphen (<code>--</code>). @@ -225,11 +224,11 @@ All values carry their own type. <em>nil</em>, <em>boolean</em>, <em>number</em>, <em>string</em>, <em>function</em>, <em>userdata</em>, <em>thread</em>, and <em>table</em>. -<em>Nil</em> is the type of the value <B>nil</B>, +<em>Nil</em> is the type of the value <b>nil</b>, whose main property is to be different from any other value; usually it represents the absence of a useful value. -<em>Boolean</em> is the type of the values <B>false</B> and <B>true</B>. -In Lua, both <B>nil</B> and <B>false</B> make a condition false; +<em>Boolean</em> is the type of the values <b>false</b> and <b>true</b>. +In Lua, both <b>nil</b> and <b>false</b> make a condition false; any other value makes it true. <em>Number</em> represents real (double-precision floating-point) numbers. (It is easy to build Lua interpreters that use other @@ -266,10 +265,10 @@ and it is used to implement coroutines (see <a href="#coroutine">2.11</a>). <p>The type <em>table</em> implements associative arrays, that is, arrays that can be indexed not only with numbers, -but with any value (except <B>nil</B>). +but with any value (except <b>nil</b>). Moreover, tables can be <em>heterogeneous</em>, -that is, they can contain values of all types (except <B>nil</B>). +that is, they can contain values of all types (except <b>nil</b>). Tables are the sole data structuring mechanism in Lua; they may be used to represent ordinary arrays, symbol tables, sets, records, graphs, trees, etc. @@ -280,7 +279,7 @@ There are several convenient ways to create tables in Lua (see <a href="#tableconstructor">2.5.7</a>). <p>Like indices, -the value of a table field can be of any type (except <B>nil</B>). +the value of a table field can be of any type (except <b>nil</b>). In particular, because functions are first class values, table fields may contain functions. @@ -327,7 +326,7 @@ Local variables are <em>lexically scoped</em>: Local variables can be freely accessed by functions defined inside their scope (see <a href="#visibility">2.6</a>). -<p>Before the first assignment to a variable, its value is <B>nil</B>. +<p>Before the first assignment to a variable, its value is <b>nil</b>. <p>Square brackets are used to index a table: <pre> @@ -370,9 +369,9 @@ through the debug library; (see <a href="#libdebug">5.9</a>).) <p>An access to a global variable <code>x</code> is equivalent to <code>_env.x</code>, which in turn is equivalent to -<PRE> +<pre> gettable_event(_env, "x") -</PRE> +</pre> where <code>_env</code> is the environment of the running function. (See <a href="#metatable">2.8</a> for a complete description of the <code>gettable_event</code> function. @@ -454,7 +453,7 @@ 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 <B>nil</B>'s as needed. +the list is extended with as many <b>nil</b>'s as needed. If the list of expressions ends with a function call, then all values returned by that function call enter in the list of values, before the adjustment @@ -463,17 +462,17 @@ before the adjustment <p>The assignment statement first evaluates all its expressions and only then are the assignments performed. Thus the code -<PRE> +<pre> i = 3 i, a[i] = i+1, 20 -</PRE> +</pre> sets <code>a[3]</code> to 20, without affecting <code>a[4]</code> because the <code>i</code> in <code>a[i]</code> is evaluated (to 3) before it is assigned 4. Similarly, the line -<PRE> +<pre> x, y = y, x -</PRE> +</pre> exchanges the values of <code>x</code> and <code>y</code>. <p>The meaning of assignments to global variables @@ -489,9 +488,9 @@ We use it here only for explanatory purposes.) is equivalent to the assignment <code>_env.x = val</code>, which in turn is equivalent to -<PRE> +<pre> settable_event(_env, "x", val) -</PRE> +</pre> where <code>_env</code> is the environment of the running function. (The <code>_env</code> variable is not defined in Lua. We use it here only for explanatory purposes.) @@ -512,11 +511,11 @@ Lua also has a <b>for</b> statement, in two flavors (see <a href="#for">2.4.5</a <p>The condition expression <em>exp</em> of a control structure may return any value. -Both <B>false</B> and <B>nil</B> are considered false. -All values different from <B>nil</B> and <B>false</B> are considered true +Both <b>false</b> and <b>nil</b> are considered false. +All values different from <b>nil</b> and <b>false</b> are considered true (in particular, the number 0 and the empty string are also true). -<p>In the <b>repeat</b>–<b>until</b> loop, +<p>In the <b>repeat</b>--<b>until</b> loop, the inner block does not end at the <b>until</b> keyword, but only after the condition. That means the condition can refer to local variables @@ -567,11 +566,11 @@ The <em>block</em> is repeated for <em>name</em> starting at the value of the first <em>exp</em>, until it passes the second <em>exp</em> by steps of the third <em>exp</em>. More precisely, a <b>for</b> statement like -<PRE> +<pre> for var = e1, e2, e3 do block end -</PRE> +</pre> is equivalent to the code: -<PRE> +<pre> do local _var, _limit, _step = tonumber(e1), tonumber(e2), tonumber(e3) if not (_var and _limit and _step) then error() end @@ -581,7 +580,7 @@ is equivalent to the code: _var = _var + _step end end -</PRE> +</pre> Note the following: <ul> <li> All three control expressions are evaluated only once, @@ -601,17 +600,17 @@ then assign it to another variable before breaking or exiting the loop. <p>The generic <b>for</b> statement works over functions, called <em>iterators</em>. For each iteration, it calls its iterator function to produce a new value, -stopping when the new value is <B>nil</B>. +stopping when the new value is <b>nil</b>. The generic <b>for</b> loop has the following syntax: <pre> stat ::= <b>for</b> Name {`<b>,</b>´ Name} <b>in</b> explist1 <b>do</b> block <b>end</b> </pre> A <b>for</b> statement like -<PRE> +<pre> for var_1, ..., var_n in explist do block end -</PRE> +</pre> is equivalent to the code: -<PRE> +<pre> do local _f, _s, _var = explist while true do @@ -621,7 +620,7 @@ is equivalent to the code: block end end -</PRE> +</pre> Note the following: <ul> <li> <code>explist</code> is evaluated only once. @@ -654,7 +653,7 @@ The declaration may include an initial assignment: </pre> If present, an initial assignment has the same semantics of a multiple assignment (see <a href="#assignment">2.4.3</a>). -Otherwise, all variables are initialized with <B>nil</B>. +Otherwise, all variables are initialized with <b>nil</b>. <p>A chunk is also a block (see <a href="#chunks">2.4.1</a>), so local variables can be declared in a chunk outside any explicit block. @@ -668,7 +667,7 @@ The scope of such local variables extends until the end of the chunk. The basic expressions in Lua are the following: <pre> exp ::= prefixexp - exp ::= <b>nil</b> | <b>false</b> | <b>true</b> + exp ::= <b>nil</b> | <b>false</b> | <b>true</b> exp ::= Number exp ::= Literal exp ::= function @@ -676,7 +675,7 @@ The basic expressions in Lua are the following: exp ::= `<b>...</b>´ exp ::= exp binop exp exp ::= unop exp - prefixexp ::= var | functioncall | `<b>(</b>´ exp `<b>)</b>´ + prefixexp ::= var | functioncall | `<b>(</b>´ exp `<b>)</b>´ </pre> <p>Numbers and literal strings are explained in <a href="#lexical">2.1</a>; @@ -710,7 +709,7 @@ then no adjustment is made, unless the call is enclosed in parentheses. <p>Here are some examples: -<PRE> +<pre> f() -- adjusted to 0 results g(f(), x) -- f() is adjusted to 1 result g(x, f()) -- g gets x plus all values returned by f() @@ -726,14 +725,14 @@ unless the call is enclosed in parentheses. {f()} -- creates a list with all values returned by f() {...} -- creates a list with all vararg parameters {f(), nil} -- f() is adjusted to 1 result -</PRE> +</pre> <p>An expression enclosed in parentheses always results in only one value. Thus, <code>(f(x,y,z))</code> is always a single value, even if <code>f</code> returns several values. (The value of <code>(f(x,y,z))</code> is the first value returned by <code>f</code> -or <B>nil</B> if <code>f</code> does not return any values.) +or <b>nil</b> if <code>f</code> does not return any values.) <p><a name="arith"></a><a name="2.5.1"></a><h3>2.5.1 - Arithmetic Operators</h3> Lua supports the usual arithmetic operators: @@ -747,21 +746,21 @@ then all operations have the usual meaning. Exponentiation works for any exponent. For instance, <code>x^-0.5</code> computes the inverse of the square root of <code>x</code>. Modulus is defined as -<PRE> +<pre> a % b == a - math.floor(a/b)*b -</PRE> +</pre> That is, it is the remaining of a division that rounds the quotient towards minus infinity. <p><a name="rel-ops"></a><a name="2.5.2"></a><h3>2.5.2 - Relational Operators</h3> The relational operators in Lua are -<PRE> +<pre> == ~= < > <= >= -</PRE> -These operators always result in <B>false</B> or <B>true</B>. +</pre> +These operators always result in <b>false</b> or <b>true</b>. <p>Equality (<code>==</code>) first compares the type of its operands. -If the types are different, then the result is <B>false</B>. +If the types are different, then the result is <b>false</b>. Otherwise, the values of the operands are compared. Numbers and strings are compared in the usual way. Objects (tables, userdata, threads, and functions) @@ -775,7 +774,7 @@ using the "eq" metamethod (see <a href="#metatable">2.8</a>). <p>The conversion rules of <a href="#coercion">2.2.1</a> <em>do not</em> apply to equality comparisons. -Thus, <code>"0"==0</code> evaluates to <B>false</B>, +Thus, <code>"0"==0</code> evaluates to <b>false</b>, and <code>t[0]</code> and <code>t["0"]</code> denote different entries in a table. @@ -792,27 +791,27 @@ metamethod (see <a href="#metatable">2.8</a>). <p><a name="logic"></a><a name="2.5.3"></a><h3>2.5.3 - Logical Operators</h3> The logical operators in Lua are -<PRE> +<pre> and or not -</PRE> +</pre> Like the control structures (see <a href="#control">2.4.4</a>), -all logical operators consider both <B>false</B> and <B>nil</B> as false +all logical operators consider both <b>false</b> and <b>nil</b> as false and anything else as true. -<p>The operator <b>not</b> always returns <B>false</B> or <B>true</B>. +<p>The operator <b>not</b> always returns <b>false</b> or <b>true</b>. <p>The conjunction operator <b>and</b> returns its first argument -if this value is <B>false</B> or <B>nil</B>; +if this value is <b>false</b> or <b>nil</b>; otherwise, <b>and</b> returns its second argument. The disjunction operator <b>or</b> returns its first argument -if this value is different from <B>nil</B> and <B>false</B>; +if this value is different from <b>nil</b> and <b>false</b>; otherwise, <b>or</b> returns its second argument. Both <b>and</b> and <b>or</b> use short-cut evaluation, that is, the second operand is evaluated only if necessary. For example, -<PRE> +<pre> 10 or error() -> 10 nil or "a" -> "a" nil and 10 -> nil @@ -820,7 +819,7 @@ For example, false and nil -> false false or nil -> nil 10 and 20 -> 20 -</PRE> +</pre> <p><a name="concat"></a><a name="2.5.4"></a><h3>2.5.4 - Concatenation</h3> The string concatenation operator in Lua is @@ -837,22 +836,22 @@ The length of a string is its number of bytes character is one byte). The length of a table <code>t</code> is defined to be any integer index <code>n</code> -such that <code>t[n]</code> is not <B>nil</B> and <code>t[n+1]</code> is <B>nil</B>; -moreover, if <code>t[1]</code> is <B>nil</B>, <code>n</code> may be zero. +such that <code>t[n]</code> is not <b>nil</b> and <code>t[n+1]</code> is <b>nil</b>; +moreover, if <code>t[1]</code> is <b>nil</b>, <code>n</code> may be zero. <p>For a regular array, with non-nil values from 1 to a given <code>n</code>, its length is exactly that <code>n</code>, the index of its last value. If the array has "holes" -(that is, <B>nil</B> values between other non-nil values), -then <code>#t</code> may be any of the indices that precede a <B>nil</B> value -(that is, it may consider any such <B>nil</B> value as the end of +(that is, <b>nil</b> values between other non-nil values), +then <code>#t</code> may be any of the indices that precede a <b>nil</b> value +(that is, it may consider any such <b>nil</b> value as the end of the array). <p><a name="2.5.6"></a><h3>2.5.6 - Precedence</h3> Operator precedence in Lua follows the table below, from lower to higher priority: -<PRE> +<pre> or and < > <= >= ~= == @@ -861,7 +860,7 @@ from lower to higher priority: * / % not # - (unary) ^ -</PRE> +</pre> You can use parentheses to change the precedences of an expression. The concatenation (`<code>..</code>´) and exponentiation (`<code>^</code>´) operators are right associative. @@ -876,8 +875,8 @@ The general syntax for constructors is <pre> tableconstructor ::= `<b>{</b>´ [fieldlist] `<b>}</b>´ fieldlist ::= field {fieldsep field} [fieldsep] - field ::= `<b>[</b>´ exp `<b>]</b>´ `<b>=</b>´ exp | Name `<b>=</b>´ exp | exp - fieldsep ::= `<b>,</b>´ | `<b>;</b>´ + field ::= `<b>[</b>´ exp `<b>]</b>´ `<b>=</b>´ exp | Name `<b>=</b>´ exp | exp + fieldsep ::= `<b>,</b>´ | `<b>;</b>´ </pre> <p>Each field of the form <code>[exp1] = exp2</code> adds to the new table an entry @@ -889,11 +888,11 @@ Finally, fields of the form <code>exp</code> are equivalent to starting with 1. Fields in the other formats do not affect this counting. For example, -<PRE> +<pre> a = {[f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45} -</PRE> +</pre> is equivalent to -<PRE> +<pre> do local temp = {} temp[f(1)] = g @@ -905,7 +904,7 @@ is equivalent to temp[4] = 45 -- 4th exp a = temp end -</PRE> +</pre> <p>If the last field in the list has the form <code>exp</code> and the expression is a function call or a vararg expression, @@ -961,10 +960,10 @@ the argument list is a single literal string. you cannot put a line break before the `<code>(</code>´ in a function call. That restriction avoids some ambiguities in the language. If you write -<PRE> +<pre> a = f (g).x(a) -</PRE> +</pre> Lua would read that as <code>a = f(g).x(a)</code>. So, if you want two statements, you must add a semi-colon between them. If you actually want to call <code>f</code>, @@ -985,13 +984,13 @@ where the <b>return</b> has one single function call as argument; this syntax makes the calling function returns exactly the returns of the called function. So, all the following examples are not tail calls: -<PRE> +<pre> 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 -</PRE> +</pre> <p><a name="func-def"></a><a name="2.5.9"></a><h3>2.5.9 - Function Definitions</h3> @@ -1008,29 +1007,29 @@ So, all the following examples are not tail calls: funcname ::= Name {`<b>.</b>´ Name} [`<b>:</b>´ Name] </pre> The statement -<PRE> +<pre> function f () ... end -</PRE> +</pre> translates to -<PRE> +<pre> f = function () ... end -</PRE> +</pre> The statement -<PRE> +<pre> function t.a.b.c.f () ... end -</PRE> +</pre> translates to -<PRE> +<pre> t.a.b.c.f = function () ... end -</PRE> +</pre> The statement -<PRE> +<pre> local function f () ... end -</PRE> +</pre> translates to -<PRE> +<pre> local f; f = function () ... end -</PRE> +</pre> <p>A function definition is an executable expression, whose value has type <em>function</em>. @@ -1047,7 +1046,7 @@ and may have different environment tables. <p>Parameters act as local variables that are initialized with the argument values: <pre> - parlist1 ::= namelist [`<b>,</b>´ `<b>...</b>´] | `<b>...</b>´ + parlist1 ::= namelist [`<b>,</b>´ `<b>...</b>´] | `<b>...</b>´ </pre> When a function is called, the list of arguments is adjusted to @@ -1069,14 +1068,14 @@ then no adjustment is made (unless the call is enclosed in parentheses). <p>As an example, consider the following definitions: -<PRE> +<pre> function f(a, b) end function g(a, b, ...) end function r() return 1,2,3 end -</PRE> +</pre> Then, we have the following mapping from arguments to parameters and to the vararg expression: -<PRE> +<pre> CALL PARAMETERS f(3) a=3, b=nil @@ -1089,7 +1088,7 @@ to the vararg expression: 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 -</PRE> +</pre> <p>Results are returned using the <b>return</b> statement (see <a href="#control">2.4.4</a>). If control reaches the end of a function @@ -1100,13 +1099,13 @@ then the function returns with no results. is used for defining <em>methods</em>, that is, functions that have an implicit extra parameter <code>self</code>. Thus, the statement -<PRE> +<pre> function t.a.b.c:f (...) ... end -</PRE> +</pre> is syntactic sugar for -<PRE> +<pre> t.a.b.c.f = function (self, ...) ... end -</PRE> +</pre> <p><a name="visibility"></a><a name="2.6"></a><h2>2.6 - Visibility Rules</h2> @@ -1116,7 +1115,7 @@ The scope of variables begins at the first statement <em>after</em> their declaration and lasts until the end of the innermost block that includes the declaration. For instance: -<PRE> +<pre> x = 10 -- global variable do -- new block local x = x -- new `x', with value 10 @@ -1129,7 +1128,7 @@ For instance: print(x) --> 11 end print(x) --> 10 (the global one) -</PRE> +</pre> Notice that, in a declaration like <code>local x = x</code>, the new <code>x</code> being declared is not in scope yet, and so the second <code>x</code> refers to the outside variable. @@ -1138,13 +1137,13 @@ and so the second <code>x</code> refers to the outside variable. local variables can be freely accessed by functions defined inside their scope. For instance: -<PRE> +<pre> local counter = 0 function inc (x) counter = counter + x return counter end -</PRE> +</pre> A local variable used by an inner function is called an <em>upvalue</em>, or <em>external local variable</em>, inside the inner function. @@ -1152,14 +1151,14 @@ inside the inner function. <p>Notice that each execution of a <b>local</b> statement defines new local variables. Consider the following example: -<PRE> +<pre> a = {} local x = 20 for i=1,10 do local y = 0 a[i] = function () y=y+1; return x+y end end -</PRE> +</pre> The loop creates ten closures (that is, ten instances of the anonymous function). Each of these closures uses a different <code>y</code> variable, @@ -1243,16 +1242,16 @@ All functions used in these descriptions are described in <a href="#predefined">5.1</a>. In particular, to retrieve the metamethod of a given object, we use the expression -<PRE> +<pre> metatable(obj)[event] -</PRE> +</pre> This should be read as -<PRE> +<pre> rawget(metatable(obj) or {}, event) -</PRE> +</pre> 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 <B>nil</B>). +(it simply results in <b>nil</b>). <p><ul> <li><b>"add":</b> @@ -1263,14 +1262,14 @@ 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. -<PRE> +<pre> function getbinhandler (op1, op2, event) return metatable(op1)[event] or metatable(op2)[event] end -</PRE> +</pre> Using that function, the behavior of the <code>op1 + op2</code> is -<PRE> +<pre> function add_event (op1, op2) local o1, o2 = tonumber(op1), tonumber(op2) if o1 and o2 then -- both operands are numeric? @@ -1285,7 +1284,7 @@ the behavior of the <code>op1 + op2</code> is end end end -</PRE> +</pre> <p><li><b>"sub":</b> the <code>-</code> operation. @@ -1313,7 +1312,7 @@ as the primitive operation. <p><li><b>"unm":</b> the unary <code>-</code> operation. -<PRE> +<pre> function unm_event (op) local o = tonumber(op) if o then -- operand is numeric? @@ -1329,11 +1328,11 @@ the unary <code>-</code> operation. end end end -</PRE> +</pre> <p><li><b>"concat":</b> the <code>..</code> (concatenation) operation. -<PRE> +<pre> function concat_event (op1, op2) if (type(op1) == "string" or type(op1) == "number") and (type(op2) == "string" or type(op2) == "number") then @@ -1347,11 +1346,11 @@ the <code>..</code> (concatenation) operation. end end end -</PRE> +</pre> <p><li><b>"len":</b> the <code>#</code> operation. -<PRE> +<pre> function len_event (op) if type(op) == "string" then return strlen(op) -- primitive string length @@ -1367,7 +1366,7 @@ the <code>#</code> operation. end end end -</PRE> +</pre> See <a href="#len-op">2.5.5</a> for a description of the length of a table. <p><li><b>"eq":</b> @@ -1377,16 +1376,16 @@ 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. -<PRE> +<pre> 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 -</PRE> +</pre> The "eq" event is defined as follows: -<PRE> +<pre> function eq_event (op1, op2) if type(op1) ~= type(op2) then -- different types? return false -- different objects @@ -1402,12 +1401,12 @@ The "eq" event is defined as follows: return false end end -</PRE> +</pre> <code>a ~= b</code> is equivalent to <code>not (a == b)</code>. <p><li><b>"lt":</b> the <code><</code> operation. -<PRE> +<pre> function lt_event (op1, op2) if type(op1) == "number" and type(op2) == "number" then return op1 < op2 -- numeric comparison @@ -1422,12 +1421,12 @@ the <code><</code> operation. end end end -</PRE> +</pre> <code>a > b</code> is equivalent to <code>b < a</code>. <p><li><b>"le":</b> the <code><=</code> operation. -<PRE> +<pre> function le_event (op1, op2) if type(op1) == "number" and type(op2) == "number" then return op1 <= op2 -- numeric comparison @@ -1447,7 +1446,7 @@ the <code><=</code> operation. end end end -</PRE> +</pre> <code>a >= b</code> is equivalent to <code>b <= a</code>. Note that, in the absence of a "le" metamethod, Lua tries the "lt", assuming that <code>a <= b</code> is @@ -1455,7 +1454,7 @@ equivalent to <code>not (b < a)</code>. <p><li><b>"index":</b> The indexing access <code>table[key]</code>. -<PRE> +<pre> function gettable_event (table, key) local h if type(table) == "table" then @@ -1474,11 +1473,11 @@ The indexing access <code>table[key]</code>. else return h[key] -- or repeat operation on it end end -</PRE> +</pre> <p><li><b>"newindex":</b> The indexing assignment <code>table[key] = value</code>. -<PRE> +<pre> function settable_event (table, key, value) local h if type(table) == "table" then @@ -1497,11 +1496,11 @@ The indexing assignment <code>table[key] = value</code>. else h[key] = value -- or repeat operation on it end end -</PRE> +</pre> <p><li><b>"call":</b> called when Lua calls a value. -<PRE> +<pre> function function_event (func, ...) if type(func) == "function" then return func(unpack(arg)) -- primitive call @@ -1514,7 +1513,7 @@ called when Lua calls a value. end end end -</PRE> +</pre> <p></ul> @@ -1612,14 +1611,14 @@ Instead, Lua puts them in a list. After the collection, Lua does the equivalent of the following function for each userdata in that list: -<PRE> +<pre> function gc_event (udata) local h = metatable(udata).__gc if h then h(udata) end end -</PRE> +</pre> <p>At the end of each garbage-collection cycle, the finalizers for userdata are called in <em>reverse</em> @@ -1686,9 +1685,9 @@ it runs until it terminates or <em>yields</em>. 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, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <B>true</B>, +In the first case, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>true</b>, plus any values returned by the coroutine main function. -In case of errors, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <B>false</B> +In case of errors, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>false</b> plus an error message. <p>A coroutine yields by calling <code>coroutine.yield</code>. @@ -1697,7 +1696,7 @@ the corresponding <a href="#pdf-coroutine.resume"><code>coroutine.resume</code>< 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, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> also returns <B>true</B>, +In the case of a yield, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> also returns <b>true</b>, plus any values passed to <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a>. The next time you resume the same coroutine, it continues its execution from the point where it yielded, @@ -1718,7 +1717,7 @@ any error is propagated to the caller. <p>As an example, consider the next code: -<PRE> +<pre> function foo1 (a) print("foo", a) return coroutine.yield(2*a) @@ -1741,9 +1740,9 @@ a, b, c = coroutine.resume(co, "x", "y") print("main", a, b, c) a, b = coroutine.resume(co, "x", "y") print("main", a, b) -</PRE> +</pre> When you run it, it produces the following output: -<PRE> +<pre> co-body 1 10 foo 2 main true 4 @@ -1752,7 +1751,7 @@ main true 11 -9 co-body x y main true 10 end main false cannot resume dead coroutine -</PRE> +</pre> <p> <a name="API"></a><a name="3"></a><h1>3 - The Application Program Interface</h1> @@ -1780,7 +1779,7 @@ in file <code>luaconf.h</code>. <p>Lua uses a <em>virtual stack</em> to pass values to and from C. Each element in this stack represents a Lua value -(<B>nil</B>, number, string, etc.). +(<b>nil</b>, number, string, etc.). <p>Whenever Lua calls C, the called function gets a new stack, which is independent of previous stacks and of stacks of @@ -1828,9 +1827,9 @@ you have set through <a href="#lua_checkstack"><code>lua_checkstack</code></a>. Such indices are called <em>acceptable indices</em>. More formally, we define an <em>acceptable index</em> as follows: -<PRE> +<pre> (index < 0 && abs(index) <= top) || (index > 0 && index <= stackspace) -</PRE> +</pre> Note that 0 is never an acceptable index. <p><a name="pseudo-index"></a><a name="3.3"></a><h2>3.3 - Pseudo-Indices</h2> @@ -1853,9 +1852,9 @@ at pseudo-index <code>LUA_ENVIRONINDEX</code>. <p>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 -<PRE> +<pre> lua_getfield(L, LUA_GLOBALSINDEX, varname); -</PRE> +</pre> <p><a name="c-closure"></a><a name="3.4"></a><h2>3.4 - C Closures</h2> @@ -1918,7 +1917,7 @@ so they never raise an error: alphabetical order. <p><a name="lua_Alloc"></a> -<hr><h3><code>lua_Alloc</code></h3> +<hr/><h3><code>lua_Alloc</code></h3> <pre> typedef void * (*lua_Alloc) (void *ud, void *ptr, @@ -1950,8 +1949,9 @@ the allocator behaves like <code>realloc</code>. Lua assumes that the allocator never fails when <code>osize >= nsize</code>. -<p>A simple implementation for the allocator function could be like this: -<PRE> +<p>A simple implementation for the allocator function +could be like this: +<pre> static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { (void)ud; /* not used */ (void)osize; /* not used */ @@ -1963,10 +1963,10 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { /* ANSI ensures that realloc(NULL, size) == malloc(size) */ return realloc(ptr, nsize); } -</PRE> +</pre> <p><a name="lua_atpanic"></a> -<hr><h3><code>lua_atpanic</code></h3> +<hr/><h3><code>lua_atpanic</code></h3> <pre> lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf); </pre> @@ -1983,7 +1983,7 @@ never returning (e.g., doing a long jump). <p>The panic function can access the error message at the top of the stack. <p><a name="lua_call"></a> -<hr><h3><code>lua_call</code></h3> +<hr/><h3><code>lua_call</code></h3> <pre> void lua_call (lua_State *L, int nargs, int nresults); </pre> @@ -2012,11 +2012,11 @@ so that after the call the last result is on the top. <p>The following example shows how the host program may do the equivalent to this Lua code: -<PRE> +<pre> a = f("how", t.x, 14) -</PRE> +</pre> Here it is in C: -<PRE> +<pre> lua_getfield(L, LUA_GLOBALSINDEX, "t"); /* global `t' (for later use) */ lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* function to be called */ lua_pushstring(L, "how"); /* 1st argument */ @@ -2025,13 +2025,13 @@ Here it is in C: lua_call(L, 3, 1); /* call function with 3 arguments and 1 result */ lua_setfield(L, LUA_GLOBALSINDEX, "a"); /* set global variable `a' */ lua_pop(L, 1); /* remove `t' from the stack */ -</PRE> +</pre> Note that the code above is "balanced": at its end, the stack is back to its original configuration. This is considered good programming practice. <p><a name="lua_CFunction"></a> -<hr><h3><code>lua_CFunction</code></h3> +<hr/><h3><code>lua_CFunction</code></h3> <pre> typedef int (*lua_CFunction) (lua_State *L); </pre> @@ -2056,7 +2056,7 @@ many results. <p>As an example, the following function receives a variable number of numerical arguments and returns their average and sum: -<PRE> +<pre> static int foo (lua_State *L) { int n = lua_gettop(L); /* number of arguments */ lua_Number sum = 0; @@ -2072,10 +2072,10 @@ of numerical arguments and returns their average and sum: lua_pushnumber(L, sum); /* second result */ return 2; /* number of results */ } -</PRE> +</pre> <p><a name="lua_checkstack"></a> -<hr><h3><code>lua_checkstack</code></h3> +<hr/><h3><code>lua_checkstack</code></h3> <pre> int lua_checkstack (lua_State *L, int extra); </pre> @@ -2088,7 +2088,7 @@ if the stack is already larger than the new size, it is left unchanged. <p><a name="lua_close"></a> -<hr><h3><code>lua_close</code></h3> +<hr/><h3><code>lua_close</code></h3> <pre> void lua_close (lua_State *L); </pre> @@ -2105,7 +2105,7 @@ might need to release states as soon as they are not needed, to avoid growing too large. <p><a name="lua_concat"></a> -<hr><h3><code>lua_concat</code></h3> +<hr/><h3><code>lua_concat</code></h3> <pre> void lua_concat (lua_State *L, int n); </pre> @@ -2120,7 +2120,7 @@ Concatenation is done following the usual semantics of Lua (see <a href="#concat">2.5.4</a>). <p><a name="lua_cpcall"></a> -<hr><h3><code>lua_cpcall</code></h3> +<hr/><h3><code>lua_cpcall</code></h3> <pre> int lua_cpcall (lua_State *L, lua_CFunction func, void *ud); </pre> @@ -2136,7 +2136,7 @@ otherwise, it returns zero, and does not change the stack. Any value returned by <code>func</code> is discarded. <p><a name="lua_createtable"></a> -<hr><h3><code>lua_createtable</code></h3> +<hr/><h3><code>lua_createtable</code></h3> <pre> void lua_createtable (lua_State *L, int narr, int nrec); </pre> @@ -2150,7 +2150,7 @@ the table will have. Otherwise you can use the function <a href="#lua_newtable"><code>lua_newtable</code></a>. <p><a name="lua_dump"></a> -<hr><h3><code>lua_dump</code></h3> +<hr/><h3><code>lua_dump</code></h3> <pre> int lua_dump (lua_State *L, lua_Writer writer, void *data); </pre> @@ -2172,7 +2172,7 @@ call to the writer; <p>This function does not pop the function from the stack. <p><a name="lua_equal"></a> -<hr><h3><code>lua_equal</code></h3> +<hr/><h3><code>lua_equal</code></h3> <pre> int lua_equal (lua_State *L, int index1, int index2); </pre> @@ -2180,13 +2180,13 @@ call to the writer; <p>Returns 1 if the two values in acceptable indices <code>index1</code> and <code>index2</code> are equal, -following the semantics of the Lua <code>=</code> operator +following the semantics of the Lua <code>==</code> operator (that is, may call metamethods). Otherwise returns 0. Also returns 0 if any of the indices are non valid. <p><a name="lua_error"></a> -<hr><h3><code>lua_error</code></h3> +<hr/><h3><code>lua_error</code></h3> <pre> int lua_error (lua_State *L); </pre> @@ -2199,7 +2199,7 @@ This function does a long jump, and therefore never returns. <p><a name="lua_gc"></a> -<hr><h3><code>lua_gc</code></h3> +<hr/><h3><code>lua_gc</code></h3> <pre> int lua_gc (lua_State *L, int what, int data); </pre> @@ -2210,12 +2210,15 @@ and therefore never returns. <p>This function performs several tasks, according to the value of the parameter <code>what</code>: <ul> -<li> <code>LUA_GCSTOP</code>— stops the garbage collector. -<li> <code>LUA_GCRESTART</code>— restarts the garbage collector. -<li> <code>LUA_GCCOLLECT</code>— performs a full garbage-collection cycle. -<li> <code>LUA_GCCOUNT</code>— returns the current +<li> <code>LUA_GCSTOP</code>--- stops the garbage collector. +<li> <code>LUA_GCRESTART</code>--- restarts the garbage collector. +<li> <code>LUA_GCCOLLECT</code>--- performs a full garbage-collection cycle. +<li> <code>LUA_GCCOUNT</code>--- returns the current amount of memory (in Kbytes) in use by Lua. -<li> <code>LUA_GCSTEP</code>— performs an incremental step of +<li> <code>LUA_GCCOUNTB</code>--- returns the remainder of +dividing the current amount of bytes of memory in use by Lua +by 1024. +<li> <code>LUA_GCSTEP</code>--- performs an incremental step of garbage collection. The step "size" is controlled by <code>data</code> (larger values mean more steps) in a non-specified way. @@ -2223,16 +2226,18 @@ If you want to control the step size you must tune experimentally the value of <code>data</code>. The function returns 1 if that step finished a garbage-collection cycle. -<li> <code>LUA_GCSETPAUSE</code>— +<li> <code>LUA_GCSETPAUSE</code>--- sets <em><code>data</code>/100</em> as the new value for the <em>pause</em> of the collector (see <a href="#GC">2.10</a>). -<li> <code>LUA_GCSETSTEPMUL</code>— +The function returns the previous value of the pause. +<li> <code>LUA_GCSETSTEPMUL</code>--- sets <em><code>arg</code>/100</em> as the new value for the <em>step multiplier</em> of the collector (see <a href="#GC">2.10</a>). +The function returns the previous value of the step multiplier. </ul> <p><a name="lua_getallocf"></a> -<hr><h3><code>lua_getallocf</code></h3> +<hr/><h3><code>lua_getallocf</code></h3> <pre> lua_Alloc lua_getallocf (lua_State *L, void **ud); </pre> @@ -2243,7 +2248,7 @@ If <code>ud</code> is not <code>NULL</code> Lua stores in <code>*ud</code> the opaque pointer passed to <a href="#lua_newstate"><code>lua_newstate</code></a>. <p><a name="lua_getfenv"></a> -<hr><h3><code>lua_getfenv</code></h3> +<hr/><h3><code>lua_getfenv</code></h3> <pre> void lua_getfenv (lua_State *L, int index); </pre> @@ -2253,7 +2258,7 @@ opaque pointer passed to <a href="#lua_newstate"><code>lua_newstate</code></a>. the value at the given index. <p><a name="lua_getfield"></a> -<hr><h3><code>lua_getfield</code></h3> +<hr/><h3><code>lua_getfield</code></h3> <pre> void lua_getfield (lua_State *L, int index, const char *k); </pre> @@ -2265,7 +2270,7 @@ As in Lua, this function may trigger a metamethod for the "index" event (see <a href="#metatable">2.8</a>). <p><a name="lua_getmetatable"></a> -<hr><h3><code>lua_getmetatable</code></h3> +<hr/><h3><code>lua_getmetatable</code></h3> <pre> int lua_getmetatable (lua_State *L, int index); </pre> @@ -2278,7 +2283,7 @@ or if the value does not have a metatable, returns 0 and pushes nothing on the stack. <p><a name="lua_gettable"></a> -<hr><h3><code>lua_gettable</code></h3> +<hr/><h3><code>lua_gettable</code></h3> <pre> void lua_gettable (lua_State *L, int index); </pre> @@ -2294,7 +2299,7 @@ As in Lua, this function may trigger a metamethod for the "index" event (see <a href="#metatable">2.8</a>). <p><a name="lua_gettop"></a> -<hr><h3><code>lua_gettop</code></h3> +<hr/><h3><code>lua_gettop</code></h3> <pre> int lua_gettop (lua_State *L); </pre> @@ -2306,7 +2311,7 @@ that result is equal to the number of elements in the stack (and so 0 means an empty stack). <p><a name="lua_insert"></a> -<hr><h3><code>lua_insert</code></h3> +<hr/><h3><code>lua_insert</code></h3> <pre> void lua_insert (lua_State *L, int index); </pre> @@ -2318,7 +2323,7 @@ Cannot be called with a pseudo-index, because a pseudo-index is not an actual stack position. <p><a name="lua_Integer"></a> -<hr><h3><code>lua_Integer</code></h3> +<hr/><h3><code>lua_Integer</code></h3> <pre> typedef ptrdiff_t lua_Integer; </pre> @@ -2331,7 +2336,7 @@ which is usually the largest type the machine handles "comfortably". <p><a name="lua_isboolean"></a> -<hr><h3><code>lua_isboolean</code></h3> +<hr/><h3><code>lua_isboolean</code></h3> <pre> int lua_isboolean (lua_State *L, int index); </pre> @@ -2341,7 +2346,7 @@ which is usually the largest type the machine handles and 0 otherwise. <p><a name="lua_iscfunction"></a> -<hr><h3><code>lua_iscfunction</code></h3> +<hr/><h3><code>lua_iscfunction</code></h3> <pre> int lua_iscfunction (lua_State *L, int index); </pre> @@ -2351,7 +2356,7 @@ and 0 otherwise. and 0 otherwise. <p><a name="lua_isfunction"></a> -<hr><h3><code>lua_isfunction</code></h3> +<hr/><h3><code>lua_isfunction</code></h3> <pre> int lua_isfunction (lua_State *L, int index); </pre> @@ -2361,7 +2366,7 @@ and 0 otherwise. (either C or Lua), and 0 otherwise. <p><a name="lua_islightuserdata"></a> -<hr><h3><code>lua_islightuserdata</code></h3> +<hr/><h3><code>lua_islightuserdata</code></h3> <pre> int lua_islightuserdata (lua_State *L, int index); </pre> @@ -2371,17 +2376,17 @@ and 0 otherwise. and 0 otherwise. <p><a name="lua_isnil"></a> -<hr><h3><code>lua_isnil</code></h3> +<hr/><h3><code>lua_isnil</code></h3> <pre> int lua_isnil (lua_State *L, int index); </pre> -<p>Returns 1 if the value at the given acceptable index is <B>nil</B>, +<p>Returns 1 if the value at the given acceptable index is <b>nil</b>, and 0 otherwise. <p><a name="lua_isnumber"></a> -<hr><h3><code>lua_isnumber</code></h3> +<hr/><h3><code>lua_isnumber</code></h3> <pre> int lua_isnumber (lua_State *L, int index); </pre> @@ -2392,7 +2397,7 @@ or a string convertible to a number, and 0 otherwise. <p><a name="lua_isstring"></a> -<hr><h3><code>lua_isstring</code></h3> +<hr/><h3><code>lua_isstring</code></h3> <pre> int lua_isstring (lua_State *L, int index); </pre> @@ -2403,7 +2408,7 @@ or a number (which is always convertible to a string), and 0 otherwise. <p><a name="lua_istable"></a> -<hr><h3><code>lua_istable</code></h3> +<hr/><h3><code>lua_istable</code></h3> <pre> int lua_istable (lua_State *L, int index); </pre> @@ -2413,7 +2418,7 @@ and 0 otherwise. and 0 otherwise. <p><a name="lua_isthread"></a> -<hr><h3><code>lua_isthread</code></h3> +<hr/><h3><code>lua_isthread</code></h3> <pre> int lua_isthread (lua_State *L, int index); </pre> @@ -2423,7 +2428,7 @@ and 0 otherwise. and 0 otherwise. <p><a name="lua_isuserdata"></a> -<hr><h3><code>lua_isuserdata</code></h3> +<hr/><h3><code>lua_isuserdata</code></h3> <pre> int lua_isuserdata (lua_State *L, int index); </pre> @@ -2433,7 +2438,7 @@ and 0 otherwise. (either full or light), and 0 otherwise. <p><a name="lua_lessthan"></a> -<hr><h3><code>lua_lessthan</code></h3> +<hr/><h3><code>lua_lessthan</code></h3> <pre> int lua_lessthan (lua_State *L, int index1, int index2); </pre> @@ -2447,7 +2452,7 @@ Otherwise returns 0. Also returns 0 if any of the indices are non valid. <p><a name="lua_load"></a> -<hr><h3><code>lua_load</code></h3> +<hr/><h3><code>lua_load</code></h3> <pre> int lua_load (lua_State *L, lua_Reader reader, void *data, const char *chunkname); @@ -2462,10 +2467,10 @@ function on top of the stack. Otherwise, it pushes an error message. The return values of <a href="#lua_load"><code>lua_load</code></a> are: <ul> -<li> 0 — no errors; -<li> <code>LUA_ERRSYNTAX</code> — +<li> 0 --- no errors; +<li> <code>LUA_ERRSYNTAX</code> --- syntax error during pre-compilation. -<li> <code>LUA_ERRMEM</code> — +<li> <code>LUA_ERRMEM</code> --- memory allocation error. </ul> @@ -2480,7 +2485,7 @@ The <code>data</code> argument is an opaque value passed to the reader function. It is used for error messages and debug information (see <a href="#debugI">3.8</a>). <p><a name="lua_newstate"></a> -<hr><h3><code>lua_newstate</code></h3> +<hr/><h3><code>lua_newstate</code></h3> <pre> lua_State *lua_newstate (lua_Alloc f, void *ud); </pre> @@ -2495,7 +2500,7 @@ The second argument, <code>ud</code>, is an opaque pointer that Lua simply passes to the allocator in every call. <p><a name="lua_newtable"></a> -<hr><h3><code>lua_newtable</code></h3> +<hr/><h3><code>lua_newtable</code></h3> <pre> void lua_newtable (lua_State *L); </pre> @@ -2505,7 +2510,7 @@ simply passes to the allocator in every call. Equivalent to <code>lua_createtable(L, 0, 0)</code>. <p><a name="lua_newthread"></a> -<hr><h3><code>lua_newthread</code></h3> +<hr/><h3><code>lua_newthread</code></h3> <pre> lua_State *lua_newthread (lua_State *L); </pre> @@ -2522,7 +2527,7 @@ Threads are subject to garbage collection, like any Lua object. <p><a name="lua_newuserdata"></a> -<hr><h3><code>lua_newuserdata</code></h3> +<hr/><h3><code>lua_newuserdata</code></h3> <pre> void *lua_newuserdata (lua_State *L, size_t size); </pre> @@ -2544,7 +2549,7 @@ it calls the userdata's <code>gc</code> metamethod, if any, and then it frees the userdata's corresponding memory. <p><a name="lua_next"></a> -<hr><h3><code>lua_next</code></h3> +<hr/><h3><code>lua_next</code></h3> <pre> int lua_next (lua_State *L, int index); </pre> @@ -2557,7 +2562,7 @@ If there are no more elements, then <a href="#lua_next"><code>lua_next</code></a> returns 0 (and pushes nothing). <p>A typical traversal looks like this: -<PRE> +<pre> /* table is in the stack at index `t' */ lua_pushnil(L); /* first key */ while (lua_next(L, t) != 0) { @@ -2566,7 +2571,7 @@ then <a href="#lua_next"><code>lua_next</code></a> returns 0 (and pushes nothing lua_typename(L, lua_type(L, -2)), lua_typename(L, lua_type(L, -1))); lua_pop(L, 1); /* removes `value'; keeps `key' for next iteration */ } -</PRE> +</pre> <p>While traversing a table, do not call <a href="#lua_tolstring"><code>lua_tolstring</code></a> directly on a key, @@ -2576,7 +2581,7 @@ the value at the given index; this confuses the next call to <a href="#lua_next"><code>lua_next</code></a>. <p><a name="lua_Number"></a> -<hr><h3><code>lua_Number</code></h3> +<hr/><h3><code>lua_Number</code></h3> <pre> typedef double lua_Number; </pre> @@ -2588,7 +2593,7 @@ this confuses the next call to <a href="#lua_next"><code>lua_next</code></a>. Lua to operate with other type for numbers (e.g., float or long). <p><a name="lua_objlen"></a> -<hr><h3><code>lua_objlen</code></h3> +<hr/><h3><code>lua_objlen</code></h3> <pre> size_t lua_objlen (lua_State *L, int index); </pre> @@ -2602,7 +2607,7 @@ for the userdatum. For other values, returns 0. <p><a name="lua_pcall"></a> -<hr><h3><code>lua_pcall</code></h3> +<hr/><h3><code>lua_pcall</code></h3> <pre> lua_pcall (lua_State *L, int nargs, int nresults, int errfunc); </pre> @@ -2640,15 +2645,15 @@ since by then the stack has unwound. or one of the following error codes (defined in <code>lua.h</code>): <ul> -<li> <code>LUA_ERRRUN</code> — a runtime error. -<li> <code>LUA_ERRMEM</code> — memory allocation error. +<li> <code>LUA_ERRRUN</code> --- a runtime error. +<li> <code>LUA_ERRMEM</code> --- memory allocation error. For such errors, Lua does not call the error handler function. -<li> <code>LUA_ERRERR</code> — +<li> <code>LUA_ERRERR</code> --- error while running the error handler function. </ul> <p><a name="lua_pop"></a> -<hr><h3><code>lua_pop</code></h3> +<hr/><h3><code>lua_pop</code></h3> <pre> void lua_pop (lua_State *L, int n); </pre> @@ -2657,7 +2662,7 @@ error while running the error handler function. <p>Pops <code>n</code> elements from the stack. <p><a name="lua_pushboolean"></a> -<hr><h3><code>lua_pushboolean</code></h3> +<hr/><h3><code>lua_pushboolean</code></h3> <pre> void lua_pushboolean (lua_State *L, int b); </pre> @@ -2666,7 +2671,7 @@ error while running the error handler function. <p>Pushes a boolean value with value <code>b</code> onto the stack. <p><a name="lua_pushcclosure"></a> -<hr><h3><code>lua_pushcclosure</code></h3> +<hr/><h3><code>lua_pushcclosure</code></h3> <pre> void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n); </pre> @@ -2688,7 +2693,7 @@ associated with the function. <a href="#lua_pushcclosure"><code>lua_pushcclosure</code></a> also pops these values from the stack. <p><a name="lua_pushcfunction"></a> -<hr><h3><code>lua_pushcfunction</code></h3> +<hr/><h3><code>lua_pushcfunction</code></h3> <pre> void lua_pushcfunction (lua_State *L, lua_CFunction f); </pre> @@ -2698,7 +2703,7 @@ associated with the function. This function is equivalent to <code>lua_pushcclosure(L, f, 0);</code>. <p><a name="lua_pushfstring"></a> -<hr><h3><code>lua_pushfstring</code></h3> +<hr/><h3><code>lua_pushfstring</code></h3> <pre> const char *lua_pushfstring (lua_State *L, const char *fmt, ...); </pre> @@ -2724,7 +2729,7 @@ The conversion specifiers can be simply </ul> <p><a name="lua_pushinteger"></a> -<hr><h3><code>lua_pushinteger</code></h3> +<hr/><h3><code>lua_pushinteger</code></h3> <pre> void lua_pushinteger (lua_State *L, lua_Integer n); </pre> @@ -2733,7 +2738,7 @@ The conversion specifiers can be simply <p>Pushes a number with value <code>n</code> onto the stack. <p><a name="lua_pushlightuserdata"></a> -<hr><h3><code>lua_pushlightuserdata</code></h3> +<hr/><h3><code>lua_pushlightuserdata</code></h3> <pre> void lua_pushlightuserdata (lua_State *L, void *p); </pre> @@ -2750,7 +2755,7 @@ A light userdata is equal to "any" light userdata with the same C address. <p><a name="lua_pushlstring"></a> -<hr><h3><code>lua_pushlstring</code></h3> +<hr/><h3><code>lua_pushlstring</code></h3> <pre> void lua_pushlstring (lua_State *L, const char *s, size_t len); </pre> @@ -2763,7 +2768,7 @@ so the memory at <code>s</code> can be freed or reused immediately after the function returns. <p><a name="lua_pushnil"></a> -<hr><h3><code>lua_pushnil</code></h3> +<hr/><h3><code>lua_pushnil</code></h3> <pre> void lua_pushnil (lua_State *L); </pre> @@ -2772,7 +2777,7 @@ the function returns. <p>Pushes a nil value onto the stack. <p><a name="lua_pushnumber"></a> -<hr><h3><code>lua_pushnumber</code></h3> +<hr/><h3><code>lua_pushnumber</code></h3> <pre> void lua_pushnumber (lua_State *L, lua_Number n); </pre> @@ -2781,7 +2786,7 @@ the function returns. <p>Pushes a number with value <code>n</code> onto the stack. <p><a name="lua_pushstring"></a> -<hr><h3><code>lua_pushstring</code></h3> +<hr/><h3><code>lua_pushstring</code></h3> <pre> void lua_pushstring (lua_State *L, const char *s); </pre> @@ -2794,7 +2799,7 @@ so the memory at <code>s</code> can be freed or reused immediately after the function returns. <p><a name="lua_pushvalue"></a> -<hr><h3><code>lua_pushvalue</code></h3> +<hr/><h3><code>lua_pushvalue</code></h3> <pre> void lua_pushvalue (lua_State *L, int index); </pre> @@ -2804,7 +2809,7 @@ the function returns. onto the stack. <p><a name="lua_pushvfstring"></a> -<hr><h3><code>lua_pushvfstring</code></h3> +<hr/><h3><code>lua_pushvfstring</code></h3> <pre> const char *lua_pushvfstring (lua_State *L, const char *fmt, va_list argp); </pre> @@ -2814,7 +2819,7 @@ onto the stack. instead of a variable number of arguments. <p><a name="lua_rawequal"></a> -<hr><h3><code>lua_rawequal</code></h3> +<hr/><h3><code>lua_rawequal</code></h3> <pre> int lua_rawequal (lua_State *L, int index1, int index2); </pre> @@ -2827,7 +2832,7 @@ Otherwise returns 0. Also returns 0 if any of the indices are non valid. <p><a name="lua_rawget"></a> -<hr><h3><code>lua_rawget</code></h3> +<hr/><h3><code>lua_rawget</code></h3> <pre> void lua_rawget (lua_State *L, int index); </pre> @@ -2837,7 +2842,7 @@ Also returns 0 if any of the indices are non valid. (i.e., without metamethods). <p><a name="lua_rawgeti"></a> -<hr><h3><code>lua_rawgeti</code></h3> +<hr/><h3><code>lua_rawgeti</code></h3> <pre> void lua_rawgeti (lua_State *L, int index, int n); </pre> @@ -2849,7 +2854,7 @@ The access is raw, that is, it does not invoke metamethods. <p><a name="lua_rawset"></a> -<hr><h3><code>lua_rawset</code></h3> +<hr/><h3><code>lua_rawset</code></h3> <pre> void lua_rawset (lua_State *L, int index); </pre> @@ -2859,7 +2864,7 @@ that is, it does not invoke metamethods. (i.e., without metamethods). <p><a name="lua_rawseti"></a> -<hr><h3><code>lua_rawseti</code></h3> +<hr/><h3><code>lua_rawseti</code></h3> <pre> void lua_rawseti (lua_State *L, int index, int n); </pre> @@ -2874,7 +2879,7 @@ The assignment is raw, that is, it does not invoke metamethods. <p><a name="lua_Reader"></a> -<hr><h3><code>lua_Reader</code></h3> +<hr/><h3><code>lua_Reader</code></h3> <pre> typedef const char * (*lua_Reader) (lua_State *L, void *data, size_t *size); @@ -2893,7 +2898,7 @@ To signal the end of the chunk, the reader returns <code>NULL</code>. The reader function may return pieces of any size greater than zero. <p><a name="lua_remove"></a> -<hr><h3><code>lua_remove</code></h3> +<hr/><h3><code>lua_remove</code></h3> <pre> void lua_remove (lua_State *L, int index); </pre> @@ -2905,7 +2910,7 @@ Cannot be called with a pseudo-index, because a pseudo-index is not an actual stack position. <p><a name="lua_replace"></a> -<hr><h3><code>lua_replace</code></h3> +<hr/><h3><code>lua_replace</code></h3> <pre> void lua_replace (lua_State *L, int index); </pre> @@ -2916,7 +2921,7 @@ without shifting any element (therefore replacing the value at the given position). <p><a name="lua_resume"></a> -<hr><h3><code>lua_resume</code></h3> +<hr/><h3><code>lua_resume</code></h3> <pre> int lua_resume (lua_State *L, int narg); </pre> @@ -2932,8 +2937,11 @@ with <code>narg</code> 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 <a href="#lua_yield"><code>lua_yield</code></a>, or all values returned by the body function. -<a href="#lua_resume"><code>lua_resume</code></a> returns 0 if there are no errors running the coroutine, -or an error code (see <a href="#lua_pcall"><code>lua_pcall</code></a>). +<a href="#lua_resume"><code>lua_resume</code></a> returns +<a href="#pdf-LUA_YIELD"><code>LUA_YIELD</code></a> if the coroutine yields, +0 if the coroutine finishes its execution +without errors, +or an error code in case of errors (see <a href="#lua_pcall"><code>lua_pcall</code></a>). In case of errors, the stack is not unwound, so you can use the debug API over it; @@ -2942,8 +2950,18 @@ To restart a coroutine, you put on its stack only the values to be passed as results from <code>yield</code>, and then call <a href="#lua_resume"><code>lua_resume</code></a>. +<p><a name="lua_setallocf"></a> +<hr/><h3><code>lua_setallocf</code></h3> +<pre> + void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); +</pre> + + +<p>Changes the allocator function of a given state to <code>f</code> +with user data <code>ud</code>. + <p><a name="lua_setfenv"></a> -<hr><h3><code>lua_setfenv</code></h3> +<hr/><h3><code>lua_setfenv</code></h3> <pre> int lua_setfenv (lua_State *L, int index); </pre> @@ -2956,7 +2974,7 @@ neither a function nor a thread nor a userdata, <a href="#lua_setfenv"><code>lua_setfenv</code></a> returns 0 (false). <p><a name="lua_setfield"></a> -<hr><h3><code>lua_setfield</code></h3> +<hr/><h3><code>lua_setfield</code></h3> <pre> void lua_setfield (lua_State *L, int index, const char *k); </pre> @@ -2971,7 +2989,7 @@ As in Lua, this function may trigger a metamethod for the "newindex" event (see <a href="#metatable">2.8</a>). <p><a name="lua_setmetatable"></a> -<hr><h3><code>lua_setmetatable</code></h3> +<hr/><h3><code>lua_setmetatable</code></h3> <pre> int lua_setmetatable (lua_State *L, int index); </pre> @@ -2982,7 +3000,7 @@ sets it as the new metatable for the value at the given acceptable index. <p><a name="lua_settable"></a> -<hr><h3><code>lua_settable</code></h3> +<hr/><h3><code>lua_settable</code></h3> <pre> void lua_settable (lua_State *L, int index); </pre> @@ -2998,7 +3016,7 @@ As in Lua, this function may trigger a metamethod for the "newindex" event (see <a href="#metatable">2.8</a>). <p><a name="lua_settop"></a> -<hr><h3><code>lua_settop</code></h3> +<hr/><h3><code>lua_settop</code></h3> <pre> void lua_settop (lua_State *L, int index); </pre> @@ -3007,11 +3025,11 @@ for the "newindex" event (see <a href="#metatable">2.8</a>). <p>Accepts any acceptable index, or 0, and sets the stack top to that index. If the new top is larger than the old one, -then the new elements are filled with <B>nil</B>. +then the new elements are filled with <b>nil</b>. If <code>index</code> is 0, then all stack elements are removed. <p><a name="lua_State"></a> -<hr><h3><code>lua_State</code></h3> +<hr/><h3><code>lua_State</code></h3> <pre> typedef struct lua_State lua_State; </pre> @@ -3027,7 +3045,7 @@ every function in the library, except to <a href="#lua_newstate"><code>lua_newst which creates a Lua state from scratch. <p><a name="lua_toboolean"></a> -<hr><h3><code>lua_toboolean</code></h3> +<hr/><h3><code>lua_toboolean</code></h3> <pre> int lua_toboolean (lua_State *L, int index); </pre> @@ -3037,14 +3055,14 @@ which creates a Lua state from scratch. value ((0 or 1). Like all tests in Lua, <a href="#lua_toboolean"><code>lua_toboolean</code></a> returns 1 for any Lua value -different from <B>false</B> and <B>nil</B>; +different from <b>false</b> and <b>nil</b>; otherwise it returns 0. It also returns 0 when called with a non-valid index. (If you want to accept only real boolean values, use <a href="#lua_isboolean"><code>lua_isboolean</code></a> to test the value's type.) <p><a name="lua_tocfunction"></a> -<hr><h3><code>lua_tocfunction</code></h3> +<hr/><h3><code>lua_tocfunction</code></h3> <pre> lua_CFunction lua_tocfunction (lua_State *L, int index); </pre> @@ -3055,7 +3073,7 @@ That value must be a C function; otherwise, returns <code>NULL</code>. <p><a name="lua_tointeger"></a> -<hr><h3><code>lua_tointeger</code></h3> +<hr/><h3><code>lua_tointeger</code></h3> <pre> lua_Integer lua_tointeger (lua_State *L, int idx); </pre> @@ -3071,7 +3089,7 @@ otherwise, <a href="#lua_tointeger"><code>lua_tointeger</code></a> returns 0. it is truncated in some non-specified way. <p><a name="lua_tolstring"></a> -<hr><h3><code>lua_tolstring</code></h3> +<hr/><h3><code>lua_tolstring</code></h3> <pre> const char *lua_tolstring (lua_State *L, int index, size_t *len); </pre> @@ -3099,7 +3117,7 @@ there is no guarantee that the pointer returned by <a href="#lua_tolstring"><cod will be valid after the corresponding value is removed from the stack. <p><a name="lua_tonumber"></a> -<hr><h3><code>lua_tonumber</code></h3> +<hr/><h3><code>lua_tonumber</code></h3> <pre> lua_Number lua_tonumber (lua_State *L, int index); </pre> @@ -3112,7 +3130,7 @@ The Lua value must be a number or a string convertible to number otherwise, <a href="#lua_tonumber"><code>lua_tonumber</code></a> returns 0. <p><a name="lua_topointer"></a> -<hr><h3><code>lua_topointer</code></h3> +<hr/><h3><code>lua_topointer</code></h3> <pre> const void *lua_topointer (lua_State *L, int index); </pre> @@ -3128,7 +3146,7 @@ There is no direct way to convert the pointer back to its original value. <p>Typically this function is used for debug information. <p><a name="lua_tostring"></a> -<hr><h3><code>lua_tostring</code></h3> +<hr/><h3><code>lua_tostring</code></h3> <pre> const char *lua_tostring (lua_State *L, int index); </pre> @@ -3137,7 +3155,7 @@ There is no direct way to convert the pointer back to its original value. <p>Equivalent to <a href="#lua_tolstring"><code>lua_tolstring</code></a> with <code>len</code> equal to <code>NULL</code>. <p><a name="lua_tothread"></a> -<hr><h3><code>lua_tothread</code></h3> +<hr/><h3><code>lua_tothread</code></h3> <pre> lua_State *lua_tothread (lua_State *L, int index); </pre> @@ -3149,7 +3167,7 @@ This value must be a thread; otherwise, the function returns <code>NULL</code>. <p><a name="lua_touserdata"></a> -<hr><h3><code>lua_touserdata</code></h3> +<hr/><h3><code>lua_touserdata</code></h3> <pre> void *lua_touserdata (lua_State *L, int index); </pre> @@ -3162,7 +3180,7 @@ returns its pointer. Otherwise, returns <code>NULL</code>. <p><a name="lua_type"></a> -<hr><h3><code>lua_type</code></h3> +<hr/><h3><code>lua_type</code></h3> <pre> int lua_type (lua_State *L, int index); </pre> @@ -3184,7 +3202,7 @@ defined in <code>lua.h</code>: <code>LUA_TLIGHTUSERDATA</code>. <p><a name="lua_Writer"></a> -<hr><h3><code>lua_Writer</code></h3> +<hr/><h3><code>lua_Writer</code></h3> <pre> typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); @@ -3205,7 +3223,7 @@ any other value means an error and stops <a href="#lua_dump"><code>lua_dump</cod calling the writer again. <p><a name="lua_xmove"></a> -<hr><h3><code>lua_xmove</code></h3> +<hr/><h3><code>lua_xmove</code></h3> <pre> void lua_xmove (lua_State *from, lua_State *to, int n); </pre> @@ -3217,7 +3235,7 @@ calling the writer again. and pushes them into the stack <code>to</code>. <p><a name="lua_yield"></a> -<hr><h3><code>lua_yield</code></h3> +<hr/><h3><code>lua_yield</code></h3> <pre> int lua_yield (lua_State *L, int nresults); </pre> @@ -3227,9 +3245,9 @@ and pushes them into the stack <code>to</code>. <p>This function can only be called as the return expression of a C function, as follows: -<PRE> +<pre> return lua_yield (L, nresults); -</PRE> +</pre> When a C function calls <a href="#lua_yield"><code>lua_yield</code></a> in that way, the running coroutine suspends its execution, and the call to <a href="#lua_resume"><code>lua_resume</code></a> that started this coroutine returns. @@ -3247,7 +3265,7 @@ kinds of debuggers, profilers, and other tools that need "inside information" from the interpreter. <p><a name="lua_Debug"></a> -<hr><h3><code>lua_Debug</code></h3> +<hr/><h3><code>lua_Debug</code></h3> <pre> typedef struct lua_Debug { int event; @@ -3260,8 +3278,8 @@ that need "inside information" from the interpreter. int linedefined; /* (S) */ int lastlinedefined; /* (S) */ char short_src[LUA_IDSIZE]; /* (S) */ - -<p> /* private part */ + + /* private part */ ... } lua_Debug; @@ -3329,7 +3347,7 @@ The number of upvalues of the function. <p></ul> <p><a name="lua_gethook"></a> -<hr><h3><code>lua_gethook</code></h3> +<hr/><h3><code>lua_gethook</code></h3> <pre> lua_Hook lua_gethook (lua_State *L); </pre> @@ -3338,7 +3356,7 @@ The number of upvalues of the function. <p>Returns the current hook function. <p><a name="lua_gethookcount"></a> -<hr><h3><code>lua_gethookcount</code></h3> +<hr/><h3><code>lua_gethookcount</code></h3> <pre> int lua_gethookcount (lua_State *L); </pre> @@ -3347,7 +3365,7 @@ The number of upvalues of the function. <p>Returns the current hook count. <p><a name="lua_gethookmask"></a> -<hr><h3><code>lua_gethookmask</code></h3> +<hr/><h3><code>lua_gethookmask</code></h3> <pre> int lua_gethookmask (lua_State *L); </pre> @@ -3356,7 +3374,7 @@ The number of upvalues of the function. <p>Returns the current hook mask. <p><a name="lua_getinfo"></a> -<hr><h3><code>lua_getinfo</code></h3> +<hr/><h3><code>lua_getinfo</code></h3> <pre> int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); </pre> @@ -3382,15 +3400,15 @@ you push it onto the stack and start the <code>what</code> string with the character `<code>></code>´. For instance, to know in which line a function <code>f</code> was defined, you can write the following code: -<PRE> +<pre> lua_Debug ar; lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* get global `f' */ lua_getinfo(L, ">S", &ar); printf("%d\n", ar.linedefined); -</PRE> +</pre> <p><a name="lua_getlocal"></a> -<hr><h3><code>lua_getlocal</code></h3> +<hr/><h3><code>lua_getlocal</code></h3> <pre> const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); </pre> @@ -3406,12 +3424,16 @@ until the last active local variable). <a href="#lua_getlocal"><code>lua_getlocal</code></a> pushes the variable's value onto the stack, and returns its name. +<p>Variable names starting with `<code>(</code>´ (open parentheses) +represent internal variables +(loop control variables, temporaries, and C function locals). + <p>Returns <code>NULL</code> (and pushes nothing) when the index is greater than the number of active local variables. <p><a name="lua_getstack"></a> -<hr><h3><code>lua_getstack</code></h3> +<hr/><h3><code>lua_getstack</code></h3> <pre> int lua_getstack (lua_State *L, int level, lua_Debug *ar); </pre> @@ -3429,7 +3451,7 @@ when called with a level greater than the stack depth, it returns 0. <p><a name="lua_getupvalue"></a> -<hr><h3><code>lua_getupvalue</code></h3> +<hr/><h3><code>lua_getupvalue</code></h3> <pre> const char *lua_getupvalue (lua_State *L, int funcindex, int n); </pre> @@ -3452,7 +3474,7 @@ For C functions, this function uses the empty string <code>""</code> as a name for all upvalues. <p><a name="lua_Hook"></a> -<hr><h3><code>lua_Hook</code></h3> +<hr/><h3><code>lua_Hook</code></h3> <pre> typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); </pre> @@ -3480,7 +3502,7 @@ Therefore, if a hook calls back Lua to execute a function or a chunk, that execution occurs without any calls to hooks. <p><a name="lua_sethook"></a> -<hr><h3><code>lua_sethook</code></h3> +<hr/><h3><code>lua_sethook</code></h3> <pre> int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); </pre> @@ -3515,7 +3537,7 @@ or when it jumps back in the code (even to the same line). <p>A hook is disabled by setting <code>mask</code> to zero. <p><a name="lua_setlocal"></a> -<hr><h3><code>lua_setlocal</code></h3> +<hr/><h3><code>lua_setlocal</code></h3> <pre> const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); </pre> @@ -3533,7 +3555,7 @@ when the index is greater than the number of active local variables. <p><a name="lua_setupvalue"></a> -<hr><h3><code>lua_setupvalue</code></h3> +<hr/><h3><code>lua_setupvalue</code></h3> <pre> const char *lua_setupvalue (lua_State *L, int funcindex, int n); </pre> @@ -3582,7 +3604,7 @@ you should not use those functions for other stack values. in alphabetical order. <p><a name="luaL_addchar"></a> -<hr><h3><code>luaL_addchar</code></h3> +<hr/><h3><code>luaL_addchar</code></h3> <pre> void luaL_addchar (luaL_Buffer B, char c); </pre> @@ -3592,7 +3614,7 @@ in alphabetical order. (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). <p><a name="luaL_addlstring"></a> -<hr><h3><code>luaL_addlstring</code></h3> +<hr/><h3><code>luaL_addlstring</code></h3> <pre> void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l); </pre> @@ -3603,7 +3625,7 @@ the buffer <code>B</code> (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). <p><a name="luaL_addsize"></a> -<hr><h3><code>luaL_addsize</code></h3> +<hr/><h3><code>luaL_addsize</code></h3> <pre> void luaL_addsize (luaL_Buffer B, size_t n); </pre> @@ -3614,7 +3636,7 @@ buffer area (see <a href="#luaL_prepbuffer"><code>luaL_prepbuffer</code></a>) to (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). <p><a name="luaL_addstring"></a> -<hr><h3><code>luaL_addstring</code></h3> +<hr/><h3><code>luaL_addstring</code></h3> <pre> void luaL_addstring (luaL_Buffer *B, const char *s); </pre> @@ -3625,7 +3647,7 @@ to the buffer <code>B</code> (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). <p><a name="luaL_addvalue"></a> -<hr><h3><code>luaL_addvalue</code></h3> +<hr/><h3><code>luaL_addvalue</code></h3> <pre> void luaL_addvalue (luaL_Buffer *B); </pre> @@ -3641,7 +3663,7 @@ be called with an extra element on the stack, which is the value to be added to the buffer. <p><a name="luaL_argcheck"></a> -<hr><h3><code>luaL_argcheck</code></h3> +<hr/><h3><code>luaL_argcheck</code></h3> <pre> void luaL_argcheck (lua_State *L, int cond, int numarg, const char *extramsg); @@ -3654,7 +3676,7 @@ If not, raise an error with message where <code>func</code> is retrieved from the call stack. <p><a name="luaL_argerror"></a> -<hr><h3><code>luaL_argerror</code></h3> +<hr/><h3><code>luaL_argerror</code></h3> <pre> int luaL_argerror (lua_State *L, int numarg, const char *extramsg); </pre> @@ -3667,7 +3689,7 @@ where <code>func</code> is retrieved from the call stack. <p>This function never returns. <p><a name="luaL_Buffer"></a> -<hr><h3><code>luaL_Buffer</code></h3> +<hr/><h3><code>luaL_Buffer</code></h3> <pre> typedef struct luaL_Buffer luaL_Buffer; </pre> @@ -3700,7 +3722,7 @@ level when the buffer was initialized, plus the final string on its top. <p><a name="luaL_buffinit"></a> -<hr><h3><code>luaL_buffinit</code></h3> +<hr/><h3><code>luaL_buffinit</code></h3> <pre> void luaL_buffinit (lua_State *L, luaL_Buffer *B); </pre> @@ -3712,7 +3734,7 @@ the buffer must be declared as a variable (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). <p><a name="luaL_callmeta"></a> -<hr><h3><code>luaL_callmeta</code></h3> +<hr/><h3><code>luaL_callmeta</code></h3> <pre> int luaL_callmeta (lua_State *L, int obj, const char *e); </pre> @@ -3729,7 +3751,7 @@ If there is no metatable or no metamethod returns 0 (without pushing any value on the stack). <p><a name="luaL_checkany"></a> -<hr><h3><code>luaL_checkany</code></h3> +<hr/><h3><code>luaL_checkany</code></h3> <pre> void luaL_checkany (lua_State *L, int narg); </pre> @@ -3738,7 +3760,7 @@ If there is no metatable or no metamethod returns 0 <p>Checks whether the function has an argument <code>narg</code>. <p><a name="luaL_checkint"></a> -<hr><h3><code>luaL_checkint</code></h3> +<hr/><h3><code>luaL_checkint</code></h3> <pre> int luaL_checkint (lua_State *L, int narg); </pre> @@ -3748,7 +3770,7 @@ If there is no metatable or no metamethod returns 0 and returns that number casted to an <code>int</code>. <p><a name="luaL_checkinteger"></a> -<hr><h3><code>luaL_checkinteger</code></h3> +<hr/><h3><code>luaL_checkinteger</code></h3> <pre> lua_Integer luaL_checkinteger (lua_State *L, int numArg); </pre> @@ -3758,7 +3780,7 @@ and returns that number casted to an <code>int</code>. and returns that number casted to a <a href="#lua_Integer"><code>lua_Integer</code></a>. <p><a name="luaL_checklong"></a> -<hr><h3><code>luaL_checklong</code></h3> +<hr/><h3><code>luaL_checklong</code></h3> <pre> long luaL_checklong (lua_State *L, int narg); </pre> @@ -3768,7 +3790,7 @@ and returns that number casted to a <a href="#lua_Integer"><code>lua_Integer</co and returns that number casted to a <code>long</code>. <p><a name="luaL_checklstring"></a> -<hr><h3><code>luaL_checklstring</code></h3> +<hr/><h3><code>luaL_checklstring</code></h3> <pre> const char *luaL_checklstring (lua_State *L, int numArg, size_t *l); </pre> @@ -3780,7 +3802,7 @@ if <code>l</code> is not <code>NULL</code> fills the position <code>*l</code> with the string's length. <p><a name="luaL_checknumber"></a> -<hr><h3><code>luaL_checknumber</code></h3> +<hr/><h3><code>luaL_checknumber</code></h3> <pre> lua_Number luaL_checknumber (lua_State *L, int numArg); </pre> @@ -3790,7 +3812,7 @@ with the string's length. and returns that number. <p><a name="luaL_checkoption"></a> -<hr><h3><code>luaL_checkoption</code></h3> +<hr/><h3><code>luaL_checkoption</code></h3> <pre> int luaL_checkoption (lua_State *L, int narg, const char *def, const char *const lst[]); @@ -3802,14 +3824,14 @@ searches for that string into the array <code>lst</code> (which must be NULL-terminated). If <code>def</code> is not <code>NULL</code>, uses <code>def</code> as a default value when -the function has no argument <code>narg</code> or if that argument is <B>nil</B>. +the function has no argument <code>narg</code> or if that argument is <b>nil</b>. <p>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. <p><a name="luaL_checkstack"></a> -<hr><h3><code>luaL_checkstack</code></h3> +<hr/><h3><code>luaL_checkstack</code></h3> <pre> void luaL_checkstack (lua_State *L, int sz, const char *msg); </pre> @@ -3820,7 +3842,7 @@ raising an error if the stack cannot grow to that size. <code>msg</code> is an additional text to go into the error message. <p><a name="luaL_checkstring"></a> -<hr><h3><code>luaL_checkstring</code></h3> +<hr/><h3><code>luaL_checkstring</code></h3> <pre> const char *luaL_checkstring (lua_State *L, int narg); </pre> @@ -3830,7 +3852,7 @@ raising an error if the stack cannot grow to that size. and returns that string. <p><a name="luaL_checktype"></a> -<hr><h3><code>luaL_checktype</code></h3> +<hr/><h3><code>luaL_checktype</code></h3> <pre> void luaL_checktype (lua_State *L, int narg, int t); </pre> @@ -3839,7 +3861,7 @@ and returns that string. <p>Checks whether the function argument <code>narg</code> has type <code>t</code>. <p><a name="luaL_checkudata"></a> -<hr><h3><code>luaL_checkudata</code></h3> +<hr/><h3><code>luaL_checkudata</code></h3> <pre> void *luaL_checkudata (lua_State *L, int ud, const char *tname); </pre> @@ -3849,7 +3871,7 @@ and returns that string. of the type <code>tname</code> (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code></a>). <p><a name="luaL_error"></a> -<hr><h3><code>luaL_error</code></h3> +<hr/><h3><code>luaL_error</code></h3> <pre> int luaL_error (lua_State *L, const char *fmt, ...); </pre> @@ -3866,7 +3888,7 @@ if that information is available. <p>This function never returns. <p><a name="luaL_getmetafield"></a> -<hr><h3><code>luaL_getmetafield</code></h3> +<hr/><h3><code>luaL_getmetafield</code></h3> <pre> int luaL_getmetafield (lua_State *L, int obj, const char *e); </pre> @@ -3879,7 +3901,7 @@ or if the metatable does not have that field, returns 0 (false) and pushes nothing. <p><a name="luaL_getmetatable"></a> -<hr><h3><code>luaL_getmetatable</code></h3> +<hr/><h3><code>luaL_getmetatable</code></h3> <pre> void luaL_getmetatable (lua_State *L, const char *tname); </pre> @@ -3889,7 +3911,7 @@ returns 0 (false) and pushes nothing. in the registry (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code></a>). <p><a name="luaL_gsub"></a> -<hr><h3><code>luaL_gsub</code></h3> +<hr/><h3><code>luaL_gsub</code></h3> <pre> const char *luaL_gsub (lua_State *L, const char *s, const char *p, const char *r); @@ -3901,7 +3923,7 @@ by the string <code>r</code>. Pushes the resulting string on the stack and returns it. <p><a name="luaL_loadbuffer"></a> -<hr><h3><code>luaL_loadbuffer</code></h3> +<hr/><h3><code>luaL_loadbuffer</code></h3> <pre> int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz, const char *name); @@ -3917,7 +3939,7 @@ buffer pointed by <code>buff</code> with size <code>sz</code>. used for debug information and error messages. <p><a name="luaL_loadfile"></a> -<hr><h3><code>luaL_loadfile</code></h3> +<hr/><h3><code>luaL_loadfile</code></h3> <pre> int luaL_loadfile (lua_State *L, const char *filename); </pre> @@ -3933,7 +3955,7 @@ but it has an extra error code <code>LUA_ERRFILE</code> if it cannot open the file. <p><a name="luaL_loadstring"></a> -<hr><h3><code>luaL_loadstring</code></h3> +<hr/><h3><code>luaL_loadstring</code></h3> <pre> int luaL_loadstring (lua_State *L, const char *s); </pre> @@ -3946,7 +3968,7 @@ the zero-terminated string <code>s</code>. <p>This function returns the same results as <a href="#lua_load"><code>lua_load</code></a>. <p><a name="luaL_newmetatable"></a> -<hr><h3><code>luaL_newmetatable</code></h3> +<hr/><h3><code>luaL_newmetatable</code></h3> <pre> int luaL_newmetatable (lua_State *L, const char *tname); </pre> @@ -3963,7 +3985,7 @@ and returns 1. with <code>"tname"</code> in the registry. <p><a name="luaL_newstate"></a> -<hr><h3><code>luaL_newstate</code></h3> +<hr/><h3><code>luaL_newstate</code></h3> <pre> lua_State *luaL_newstate (void); </pre> @@ -3979,7 +4001,7 @@ errors. or <code>NULL</code> if there is a memory allocation error. <p><a name="luaL_optint"></a> -<hr><h3><code>luaL_optint</code></h3> +<hr/><h3><code>luaL_optint</code></h3> <pre> int luaL_optint (lua_State *L, int narg, int d); </pre> @@ -3987,12 +4009,12 @@ or <code>NULL</code> if there is a memory allocation error. <p>If the function argument <code>narg</code> is a number, returns that number casted to an <code>int</code>. -If that argument is absent or is <B>nil</B>, +If that argument is absent or is <b>nil</b>, returns <code>d</code>. Otherwise, raise an error. <p><a name="luaL_optinteger"></a> -<hr><h3><code>luaL_optinteger</code></h3> +<hr/><h3><code>luaL_optinteger</code></h3> <pre> lua_Integer luaL_optinteger (lua_State *L, int nArg, lua_Integer d); </pre> @@ -4000,12 +4022,12 @@ Otherwise, raise an error. <p>If the function argument <code>narg</code> is a number, returns that number casted to a <a href="#lua_Integer"><code>lua_Integer</code></a>. -If that argument is absent or is <B>nil</B>, +If that argument is absent or is <b>nil</b>, returns <code>d</code>. Otherwise, raise an error. <p><a name="luaL_optlong"></a> -<hr><h3><code>luaL_optlong</code></h3> +<hr/><h3><code>luaL_optlong</code></h3> <pre> long luaL_optlong (lua_State *L, int narg, long d); </pre> @@ -4013,12 +4035,12 @@ Otherwise, raise an error. <p>If the function argument <code>narg</code> is a number, returns that number casted to a <code>long</code>. -If that argument is absent or is <B>nil</B>, +If that argument is absent or is <b>nil</b>, returns <code>d</code>. Otherwise, raise an error. <p><a name="luaL_optlstring"></a> -<hr><h3><code>luaL_optlstring</code></h3> +<hr/><h3><code>luaL_optlstring</code></h3> <pre> const char *luaL_optlstring (lua_State *L, int numArg, const char *d, size_t *l); @@ -4027,7 +4049,7 @@ Otherwise, raise an error. <p>If the function argument <code>narg</code> is a string, returns that string. -If that argument is absent or is <B>nil</B>, +If that argument is absent or is <b>nil</b>, returns <code>d</code>. Otherwise, raise an error. @@ -4035,7 +4057,7 @@ Otherwise, raise an error. with the results's length. <p><a name="luaL_optnumber"></a> -<hr><h3><code>luaL_optnumber</code></h3> +<hr/><h3><code>luaL_optnumber</code></h3> <pre> lua_Number luaL_optnumber (lua_State *L, int nArg, lua_Number d); </pre> @@ -4043,12 +4065,12 @@ with the results's length. <p>If the function argument <code>narg</code> is a number, returns that number. -If that argument is absent or is <B>nil</B>, +If that argument is absent or is <b>nil</b>, returns <code>d</code>. Otherwise, raise an error. <p><a name="luaL_optstring"></a> -<hr><h3><code>luaL_optstring</code></h3> +<hr/><h3><code>luaL_optstring</code></h3> <pre> const char *luaL_optstring (lua_State *L, int narg, const char *d); </pre> @@ -4056,12 +4078,12 @@ Otherwise, raise an error. <p>If the function argument <code>narg</code> is a string, returns that string. -If that argument is absent or is <B>nil</B>, +If that argument is absent or is <b>nil</b>, returns <code>d</code>. Otherwise, raise an error. <p><a name="luaL_prepbuffer"></a> -<hr><h3><code>luaL_prepbuffer</code></h3> +<hr/><h3><code>luaL_prepbuffer</code></h3> <pre> char *luaL_prepbuffer (luaL_Buffer *B); </pre> @@ -4075,7 +4097,7 @@ After copying the string into that space you must call it to the buffer. <p><a name="luaL_pushresult"></a> -<hr><h3><code>luaL_pushresult</code></h3> +<hr/><h3><code>luaL_pushresult</code></h3> <pre> void luaL_pushresult (luaL_Buffer *B); </pre> @@ -4085,7 +4107,7 @@ it to the buffer. the top of the stack. <p><a name="luaL_ref"></a> -<hr><h3><code>luaL_ref</code></h3> +<hr/><h3><code>luaL_ref</code></h3> <pre> int luaL_ref (lua_State *L, int t); </pre> @@ -4102,13 +4124,13 @@ You can retrieve an object referred by reference <code>r</code> calling <code>lua_rawgeti(L, t, r)</code>. Function <a href="#luaL_unref"><code>luaL_unref</code></a> frees a reference and its associated object. -<p>Whenever the object at the top of the stack is <B>nil</B>, +<p>Whenever the object at the top of the stack is <b>nil</b>, <a href="#luaL_ref"><code>luaL_ref</code></a> returns the same reference <code>LUA_REFNIL</code>. The constant <code>LUA_NOREF</code> is garanteed to be different from any reference returned by <a href="#luaL_ref"><code>luaL_ref</code></a>. <p><a name="luaL_Reg"></a> -<hr><h3><code>luaL_Reg</code></h3> +<hr/><h3><code>luaL_Reg</code></h3> <pre> typedef struct luaL_Reg { const char *name; @@ -4126,7 +4148,7 @@ Any array of <a href="#luaL_Reg"><code>luaL_Reg</code></a> must end with an sent wherein both <code>name</code> and <code>func</code> are <code>NULL</code>. <p><a name="luaL_register"></a> -<hr><h3><code>luaL_register</code></h3> +<hr/><h3><code>luaL_register</code></h3> <pre> void luaL_register (lua_State *L, const char *libname, const luaL_Reg *l); @@ -4152,7 +4174,7 @@ reuses that table instead of creating a new one. on the top of the stack. <p><a name="luaL_typename"></a> -<hr><h3><code>luaL_typename</code></h3> +<hr/><h3><code>luaL_typename</code></h3> <pre> const char *luaL_typename (lua_State *L, int idx); </pre> @@ -4161,22 +4183,22 @@ on the top of the stack. <p>Returns the name of the type of the value at index <code>idx</code>. <p><a name="luaL_typerror"></a> -<hr><h3><code>luaL_typerror</code></h3> +<hr/><h3><code>luaL_typerror</code></h3> <pre> int luaL_typerror (lua_State *L, int narg, const char *tname); </pre> <p>Generates an error with a message like -<PRE> +<pre> <location>: bad argument <narg> to <function> (<tname> expected, got <realt>) -</PRE> +</pre> where <code><location></code> is produced by <a href="#luaL_where"><code>luaL_where</code></a>, <code><function></code> is the name of the current function, and <code><realt></code> is the type name of the actual argument. <p><a name="luaL_unref"></a> -<hr><h3><code>luaL_unref</code></h3> +<hr/><h3><code>luaL_unref</code></h3> <pre> void luaL_unref (lua_State *L, int t, int ref); </pre> @@ -4192,7 +4214,7 @@ The reference <code>ref</code> is also freed to be used again. <a href="#luaL_unref"><code>luaL_unref</code></a> does nothing. <p><a name="luaL_where"></a> -<hr><h3><code>luaL_where</code></h3> +<hr/><h3><code>luaL_where</code></h3> <pre> void luaL_where (lua_State *L, int lvl); </pre> @@ -4255,14 +4277,14 @@ If you do not include this library in your application, you should check carefully whether you need to provide some alternative implementation for some of its facilities. -<p><a name="pdf-assert"></a><hr><h3><code>assert (v [, message])</code></h3> +<p><a name="pdf-assert"></a><hr/><h3><code>assert (v [, message])</code></h3> Issues an error when -the value of its argument <code>v</code> is <B>nil</B> or <B>false</B>; +the value of its argument <code>v</code> is <b>nil</b> or <b>false</b>; otherwise, returns all its arguments. <code>message</code> is an error message; when absent, it defaults to "assertion failed!" -<p><a name="pdf-collectgarbage"></a><hr><h3><code>collectgarbage (opt [, arg])</code></h3> +<p><a name="pdf-collectgarbage"></a><hr/><h3><code>collectgarbage (opt [, arg])</code></h3> <p>This function is a generic interface to the garbage collector. It performs different functions according to its first argument, <code>opt</code>: @@ -4276,6 +4298,7 @@ The step "size" is controlled by <code>arg</code> (larger values mean more steps) in a non-specified way. If you want to control the step size you must tune experimentally the value of <code>arg</code>. +Returns <b>true</b> if that step finished a collection cycle. <li><b>"steppause"</b> sets <em><code>arg</code>/100</em> as the new value for the <em>pause</em> of the collector (see <a href="#GC">2.10</a>). @@ -4284,7 +4307,7 @@ sets <em><code>arg</code>/100</em> as the new value for the <em>step multiplier< the collector (see <a href="#GC">2.10</a>). </ul> -<p><a name="pdf-dofile"></a><hr><h3><code>dofile (filename)</code></h3> +<p><a name="pdf-dofile"></a><hr/><h3><code>dofile (filename)</code></h3> Opens the named file and executes its contents as a Lua chunk. When called without arguments, <a href="#pdf-dofile"><code>dofile</code></a> executes the contents of the standard input (<code>stdin</code>). @@ -4292,7 +4315,7 @@ Returns any value returned by the chunk. In case of errors, <a href="#pdf-dofile"><code>dofile</code></a> propagates the error to its caller (that is, it does not run in protected mode). -<p><a name="pdf-error"></a><hr><h3><code>error (message [, level])</code></h3> +<p><a name="pdf-error"></a><hr/><h3><code>error (message [, level])</code></h3> Terminates the last protected function called and returns <code>message</code> as the error message. Function <a href="#pdf-error"><code>error</code></a> never returns. @@ -4307,14 +4330,14 @@ that called <a href="#pdf-error"><code>error</code></a> was called; and so on. Passing a level 0 avoids the addition of error position information to the message. -<p><a name="pdf-_G"></a><hr><h3><code>_G</code></h3> +<p><a name="pdf-_G"></a><hr/><h3><code>_G</code></h3> A global variable (not a function) that holds the global environment (that is, <code>_G._G = _G</code>). Lua itself does not use this variable; changing its value does not affect any environment. (Use <a href="#pdf-setfenv"><code>setfenv</code></a> to change environments.) -<p><a name="pdf-getfenv"></a><hr><h3><code>getfenv (f)</code></h3> +<p><a name="pdf-getfenv"></a><hr/><h3><code>getfenv (f)</code></h3> Returns the current environment in use by the function. <code>f</code> can be a Lua function or a number, which specifies the function at that stack level: @@ -4324,73 +4347,73 @@ or if <code>f</code> is 0, <a href="#pdf-getfenv"><code>getfenv</code></a> returns the global environment. The default for <code>f</code> is 1. -<p><a name="pdf-getmetatable"></a><hr><h3><code>getmetatable (object)</code></h3> +<p><a name="pdf-getmetatable"></a><hr/><h3><code>getmetatable (object)</code></h3> -<p>If <code>object</code> does not have a metatable, returns <B>nil</B>. +<p>If <code>object</code> does not have a metatable, returns <b>nil</b>. Otherwise, if the object's metatable has a <code>"__metatable"</code> field, returns the associated value. Otherwise, returns the metatable of the given object. -<p><a name="pdf-ipairs"></a><hr><h3><code>ipairs (t)</code></h3> +<p><a name="pdf-ipairs"></a><hr/><h3><code>ipairs (t)</code></h3> <p>Returns an iterator function, the table <code>t</code>, and 0, so that the construction -<PRE> +<pre> for i,v in ipairs(t) do ... end -</PRE> +</pre> will iterate over the pairs (<code>1,t[1]</code>), (<code>2,t[2]</code>), ..., up to the first integer key with a nil value in the table. -<p><a name="pdf-load"></a><hr><h3><code>load (func [, chunkname])</code></h3> +<p><a name="pdf-load"></a><hr/><h3><code>load (func [, chunkname])</code></h3> <p>Loads a chunk using function <code>func</code> to get its pieces. Each call to <code>func</code> must return a string that concatenates with previous results. -A return of <B>nil</B> (or no value) signals the end of the chunk. +A return of <b>nil</b> (or no value) signals the end of the chunk. <p>If there are no errors, returns the compiled chunk as a function; -otherwise, returns <B>nil</B> plus the error message. +otherwise, returns <b>nil</b> plus the error message. The environment of the returned function is the global environment. <p><code>chunkname</code> is used as the chunk name for error messages and debug information. -<p><a name="pdf-loadfile"></a><hr><h3><code>loadfile (filename)</code></h3> +<p><a name="pdf-loadfile"></a><hr/><h3><code>loadfile (filename)</code></h3> <p>Similar to <a href="#pdf-load"><code>load</code></a>, but gets the chunk from file <code>filename</code>. -<p><a name="pdf-loadstring"></a><hr><h3><code>loadstring (string [, chunkname])</code></h3> +<p><a name="pdf-loadstring"></a><hr/><h3><code>loadstring (string [, chunkname])</code></h3> <p>Similar to <a href="#pdf-load"><code>load</code></a>, but gets the chunk from the given string. <p>To load and run a given string, use the idiom -<PRE> +<pre> assert(loadstring(s))() -</PRE> +</pre> -<p><a name="pdf-next"></a><hr><h3><code>next (table [, index])</code></h3> +<p><a name="pdf-next"></a><hr/><h3><code>next (table [, index])</code></h3> <p>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. <a href="#pdf-next"><code>next</code></a> returns the next index of the table and the value associated with the index. -When called with <B>nil</B> as its second argument, +When called with <b>nil</b> as its second argument, <a href="#pdf-next"><code>next</code></a> returns the first index of the table and its associated value. When called with the last index, -or with <B>nil</B> in an empty table, -<a href="#pdf-next"><code>next</code></a> returns <B>nil</B>. -If the second argument is absent, then it is interpreted as <B>nil</B>. +or with <b>nil</b> in an empty table, +<a href="#pdf-next"><code>next</code></a> returns <b>nil</b>. +If the second argument is absent, then it is interpreted as <b>nil</b>. <p>Lua has no declaration of fields; There is no difference between a -field not present in a table or a field with value <B>nil</B>. -Therefore, <a href="#pdf-next"><code>next</code></a> only considers fields with non-<B>nil</B> values. +field not present in a table or a field with value <b>nil</b>. +Therefore, <a href="#pdf-next"><code>next</code></a> only considers fields with non-<b>nil</b> values. The order in which the indices are enumerated is not specified, <em>even for numeric indices</em>. (To traverse a table in numeric order, @@ -4400,16 +4423,16 @@ use a numerical <b>for</b> or the <a href="#pdf-ipairs"><code>ipairs</code></a> during the traversal, you assign any value to a non-existent field in the table. -<p><a name="pdf-pairs"></a><hr><h3><code>pairs (t)</code></h3> +<p><a name="pdf-pairs"></a><hr/><h3><code>pairs (t)</code></h3> -<p>Returns the <a href="#pdf-next"><code>next</code></a> function and the table <code>t</code> (plus a <B>nil</B>), +<p>Returns the <a href="#pdf-next"><code>next</code></a> function and the table <code>t</code> (plus a <b>nil</b>), so that the construction -<PRE> +<pre> for k,v in pairs(t) do ... end -</PRE> -will iterate over all key–value pairs of table <code>t</code>. +</pre> +will iterate over all key--value pairs of table <code>t</code>. -<p><a name="pdf-pcall"></a><hr><h3><code>pcall (f, arg1, arg2, ...)</code></h3> +<p><a name="pdf-pcall"></a><hr/><h3><code>pcall (f, arg1, arg2, ...)</code></h3> <p>Calls function <code>f</code> with the given arguments in protected mode. @@ -4420,9 +4443,9 @@ Its first result is the status code (a boolean), which is true if the call succeeds without errors. In such case, <a href="#pdf-pcall"><code>pcall</code></a> also returns all results from the call, after this first result. -In case of any error, <a href="#pdf-pcall"><code>pcall</code></a> returns <B>false</B> plus the error message. +In case of any error, <a href="#pdf-pcall"><code>pcall</code></a> returns <b>false</b> plus the error message. -<p><a name="pdf-print"></a><hr><h3><code>print (e1, e2, ...)</code></h3> +<p><a name="pdf-print"></a><hr/><h3><code>print (e1, e2, ...)</code></h3> Receives any number of arguments, and prints their values in <code>stdout</code>, using the <a href="#pdf-tostring"><code>tostring</code></a> function to convert them to strings. @@ -4431,32 +4454,32 @@ but only as a quick way to show a value, typically for debugging. For formatted output, use <code>format</code> (see <a href="#format">5.4</a>). -<p><a name="pdf-rawequal"></a><hr><h3><code>rawequal (v1, v2)</code></h3> +<p><a name="pdf-rawequal"></a><hr/><h3><code>rawequal (v1, v2)</code></h3> Checks whether <code>v1</code> is equal to <code>v2</code>, without invoking any metamethod. Returns a boolean. -<p><a name="pdf-rawget"></a><hr><h3><code>rawget (table, index)</code></h3> +<p><a name="pdf-rawget"></a><hr/><h3><code>rawget (table, index)</code></h3> Gets the real value of <code>table[index]</code>, without invoking any metamethod. <code>table</code> must be a table; -<code>index</code> is any value different from <B>nil</B>. +<code>index</code> is any value different from <b>nil</b>. -<p><a name="pdf-rawset"></a><hr><h3><code>rawset (table, index, value)</code></h3> +<p><a name="pdf-rawset"></a><hr/><h3><code>rawset (table, index, value)</code></h3> Sets the real value of <code>table[index]</code> to <code>value</code>, without invoking any metamethod. <code>table</code> must be a table, -<code>index</code> is any value different from <B>nil</B>, +<code>index</code> is any value different from <b>nil</b>, and <code>value</code> is any Lua value. -<p><a name="pdf-select"></a><hr><h3><code>select (index, ...)</code></h3> +<p><a name="pdf-select"></a><hr/><h3><code>select (index, ...)</code></h3> <p>If <code>index</code> is a number, returns all argument after argument number <code>index</code>. Otherwise, <code>index</code> must be the string <code>"#"</code>, and <code>select</code> returns the total number of extra arguments it received. -<p><a name="setfenv"></a><a name="pdf-setfenv"></a><hr><h3><code>setfenv (f, table)</code></h3> +<p><a name="setfenv"></a><a name="pdf-setfenv"></a><hr/><h3><code>setfenv (f, table)</code></h3> <p>Sets the environment to be used by the given function. <code>f</code> can be a Lua function or a number, @@ -4468,22 +4491,22 @@ Level 1 is the function calling <a href="#pdf-setfenv"><code>setfenv</code></a>. the environment of the running thread. In this case, <a href="#pdf-setfenv"><code>setfenv</code></a> returns no values. -<p><a name="pdf-setmetatable"></a><hr><h3><code>setmetatable (table, metatable)</code></h3> +<p><a name="pdf-setmetatable"></a><hr/><h3><code>setmetatable (table, metatable)</code></h3> <p>Sets the metatable for the given table. (You cannot change the metatable of other types from Lua.) -If <code>metatable</code> is <B>nil</B>, +If <code>metatable</code> is <b>nil</b>, removes the metatable of the given table. If the original metatable has a <code>"__metatable"</code> field, raises an error. <p>This function returns <code>table</code>. -<p><a name="pdf-tonumber"></a><hr><h3><code>tonumber (e [, base])</code></h3> +<p><a name="pdf-tonumber"></a><hr/><h3><code>tonumber (e [, base])</code></h3> Tries to convert its argument to a number. If the argument is already a number or a string convertible to a number, then <a href="#pdf-tonumber"><code>tonumber</code></a> returns that number; -otherwise, it returns <B>nil</B>. +otherwise, it returns <b>nil</b>. <p>An optional argument specifies the base to interpret the numeral. The base may be any integer between 2 and 36, inclusive. @@ -4494,7 +4517,7 @@ In base 10 (the default), the number may have a decimal part, as well as an optional exponent part (see <a href="#coercion">2.2.1</a>). In other bases, only unsigned integers are accepted. -<p><a name="pdf-tostring"></a><hr><h3><code>tostring (e)</code></h3> +<p><a name="pdf-tostring"></a><hr/><h3><code>tostring (e)</code></h3> Receives an argument of any type and converts it to a string in a reasonable format. For complete control of how numbers are converted, @@ -4505,10 +4528,10 @@ use <a href="#pdf-string.format"><code>string.format</code></a> (see <a href="#f with <code>e</code> as argument, and uses the result of the call as its result. -<p><a name="pdf-type"></a><hr><h3><code>type (v)</code></h3> +<p><a name="pdf-type"></a><hr/><h3><code>type (v)</code></h3> Returns the type of its only argument, coded as a string. The possible results of this function are -<code>"nil"</code> (a string, not the value <B>nil</B>), +<code>"nil"</code> (a string, not the value <b>nil</b>), <code>"number"</code>, <code>"string"</code>, <code>"boolean</code>, @@ -4517,23 +4540,23 @@ The possible results of this function are <code>"thread"</code>, and <code>"userdata"</code>. -<p><a name="pdf-unpack"></a><hr><h3><code>unpack (list [, i [, j]])</code></h3> +<p><a name="pdf-unpack"></a><hr/><h3><code>unpack (list [, i [, j]])</code></h3> Returns the elements from the given list. This function is equivalent to -<PRE> +<pre> return list[i], list[i+1], ..., list[j] -</PRE> +</pre> except that the above code can be written only for a fixed number of elements. By default, <code>i</code> is 1 and <code>j</code> is the length of the list, as defined by the length operator. -<p><a name="pdf-_VERSION"></a><hr><h3><code>_VERSION</code></h3> +<p><a name="pdf-_VERSION"></a><hr/><h3><code>_VERSION</code></h3> A global variable (not a function) that holds a string containing the current interpreter version. The current contents of this variable is <code>"Lua 5.1"</code>. -<p><a name="pdf-xpcall"></a><hr><h3><code>xpcall (f, err)</code></h3> +<p><a name="pdf-xpcall"></a><hr/><h3><code>xpcall (f, err)</code></h3> <p>This function is similar to <a href="#pdf-pcall"><code>pcall</code></a>, except that you can set a new error handler. @@ -4557,14 +4580,14 @@ In case of any error, the basic library and come inside the table <code>coroutine</code>. See <a href="#coroutine">2.11</a> for a general description of coroutines. -<p><a name="pdf-coroutine.create"></a><hr><h3><code>coroutine.create (f)</code></h3> +<p><a name="pdf-coroutine.create"></a><hr/><h3><code>coroutine.create (f)</code></h3> <p>Creates a new coroutine, with body <code>f</code>. <code>f</code> must be a Lua function. Returns this new coroutine, an object with type <code>"thread"</code>. -<p><a name="pdf-coroutine.resume"></a><hr><h3><code>coroutine.resume (co, val1, ...)</code></h3> +<p><a name="pdf-coroutine.resume"></a><hr/><h3><code>coroutine.resume (co, val1, ...)</code></h3> <p>Starts or continues the execution of coroutine <code>co</code>. The first time you resume a coroutine, @@ -4575,18 +4598,18 @@ If the coroutine has yielded, the arguments <code>val1</code>, ... go as the results from the yield. <p>If the coroutine runs without any errors, -<code>resume</code> returns <B>true</B> plus any values passed to <code>yield</code> +<code>resume</code> returns <b>true</b> plus any values passed to <code>yield</code> (if the coroutine yields) or any values returned by the body function (if the coroutine terminates). If there is any error, -<code>resume</code> returns <B>false</B> plus the error message. +<code>resume</code> returns <b>false</b> plus the error message. -<p><a name="pdf-coroutine.running"></a><hr><h3><code>coroutine.running ()</code></h3> +<p><a name="pdf-coroutine.running"></a><hr/><h3><code>coroutine.running ()</code></h3> <p>Returns the running coroutine, -or <B>nil</B> when called by the main thread. +or <b>nil</b> when called by the main thread. -<p><a name="pdf-coroutine.status"></a><hr><h3><code>coroutine.status (co)</code></h3> +<p><a name="pdf-coroutine.status"></a><hr/><h3><code>coroutine.status (co)</code></h3> <p>Returns the status of coroutine <code>co</code>, as a string: <code>"running"</code>, @@ -4598,7 +4621,7 @@ or if it has not started running yet; and <code>"dead"</code> if the coroutine has finished its body function, or if it has stopped with an error. -<p><a name="pdf-coroutine.wrap"></a><hr><h3><code>coroutine.wrap (f)</code></h3> +<p><a name="pdf-coroutine.wrap"></a><hr/><h3><code>coroutine.wrap (f)</code></h3> <p>Creates a new coroutine, with body <code>f</code>. <code>f</code> must be a Lua function. @@ -4609,7 +4632,7 @@ Returns the same values returned by <code>resume</code>, except the first boolean. In case of error, propagates the error. -<p><a name="pdf-coroutine.yield"></a><hr><h3><code>coroutine.yield (val1, ...)</code></h3> +<p><a name="pdf-coroutine.yield"></a><hr/><h3><code>coroutine.yield (val1, ...)</code></h3> <p>Suspends the execution of the calling coroutine. The coroutine cannot be running neither a C function, @@ -4624,7 +4647,7 @@ It exports two of its functions directly in the global environment: <a href="#pdf-require"><code>require</code></a> and <a href="#pdf-module"><code>module</code></a>. Everything else is exported in a table <code>package</code>. -<p><a name="pdf-module"></a><hr><h3><code>module (name [, ...])</code></h3> +<p><a name="pdf-module"></a><hr/><h3><code>module (name [, ...])</code></h3> <p>Creates a module. If there is a table in <code>package.loaded[name]</code>, @@ -4654,7 +4677,7 @@ field <code>b</code> of global <code>a</code>. the module name, where each option is a function to be applied over the module. -<p><a name="pdf-require"></a><hr><h3><code>require (modname)</code></h3> +<p><a name="pdf-require"></a><hr/><h3><code>require (modname)</code></h3> <p>Loads the given module. The function starts by looking into the table <code>package.loaded</code> @@ -4682,9 +4705,9 @@ be used as the loader. The name of that C function is the string <code>"luaopen_"</code> concatenated with a copy of the module name wherein each dot is replaced by an underscore. -Moreover, if the module name has a colon, -its prefix up to (and including) the first colon is removed. -For instance, if the module name is <code>a.v1:b.c</code>, +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 <code>a.v1-b.c</code>, the function name will be <code>luaopen_b_c</code>. <p>If <a href="#pdf-require"><code>require</code></a> finds neither a Lua library nor a @@ -4715,7 +4738,7 @@ final value of <code>package.loaded[modname]</code>. or if it cannot find any loader for that module, then <a href="#pdf-require"><code>require</code></a> signals an error. -<p><a name="pdf-package.cpath"></a><hr><h3><code>package.cpath</code></h3> +<p><a name="pdf-package.cpath"></a><hr/><h3><code>package.cpath</code></h3> <p>The path used by <a href="#pdf-require"><code>require</code></a> to search for a C loader. @@ -4724,7 +4747,7 @@ it initializes the Lua path <a href="#pdf-package.path"><code>package.path</code using the environment variable <code>LUA_CPATH</code> (plus another compiled-defined default path). -<p><a name="pdf-package.loaded"></a><hr><h3><code>package.loaded</code></h3> +<p><a name="pdf-package.loaded"></a><hr/><h3><code>package.loaded</code></h3> <p>A table used by <a href="#pdf-require"><code>require</code></a> to control which modules are already loaded. @@ -4732,7 +4755,7 @@ When you require a module <code>modname</code> and <code>package.loaded[modname]</code> is not false, <a href="#pdf-require"><code>require</code></a> simply returns the value stored there. -<p><a name="pdf-package.loadlib"></a><hr><h3><code>package.loadlib (libname, funcname)</code></h3> +<p><a name="pdf-package.loadlib"></a><hr/><h3><code>package.loadlib (libname, funcname)</code></h3> <p>Links the program with the dynamic C library <code>libname</code>. Inside this library, looks for a function <code>funcname</code> @@ -4746,7 +4769,7 @@ As such, it is only available on some platforms (Windows, Linux, Solaris, BSD, plus other Unix systems that support the <code>dlfcn</code> standard). -<p><a name="pdf-package.path"></a><hr><h3><code>package.path</code></h3> +<p><a name="pdf-package.path"></a><hr/><h3><code>package.path</code></h3> <p>The path used by <a href="#pdf-require"><code>require</code></a> to search for a Lua loader. @@ -4764,20 +4787,20 @@ which is <code>modname</code> with each dot replaced by a "directory separator" (such as <code>"/"</code> in Unix); then it will try to load the resulting file name. So, for instance, if the Lua path is -<PRE> +<pre> "./?.lua;./?.lc;/usr/local/?/init.lua" -</PRE> +</pre> the search for a Lua loader for module <code>mod</code> will try to load the files <code>./mod.lua</code>, <code>./mod.lc</code>, and <code>/usr/local/mod/init.lua</code>, in that order. -<p><a name="pdf-package.preload"></a><hr><h3><code>package.preload</code></h3> +<p><a name="pdf-package.preload"></a><hr/><h3><code>package.preload</code></h3> <p>A table to store loaders for specific modules (see <a href="#pdf-require"><code>require</code></a>). -<p><a name="pdf-package.seeall"></a><hr><h3><code>package.seeall (module)</code></h3> +<p><a name="pdf-package.seeall"></a><hr/><h3><code>package.seeall (module)</code></h3> <p>Sets a metatable for <code>module</code> with its <code>__index</code> field refering to the global environment, @@ -4803,7 +4826,7 @@ Therefore, you can use the string function is object-oriented style. For instance, <code>string.byte(s, i)</code> can be written as <code>s:byte(i)</code>. -<p><a name="pdf-string.byte"></a><hr><h3><code>string.byte (s [, i [, j]])</code></h3> +<p><a name="pdf-string.byte"></a><hr/><h3><code>string.byte (s [, i [, j]])</code></h3> Returns the internal numerical codes of the characters <code>s[i]</code>, <code>s[i+1]</code>, ..., <code>s[j]</code>. The default value for <code>i</code> is 1; @@ -4811,7 +4834,7 @@ the default value for <code>j</code> is <code>i</code>. <p>Note that numerical codes are not necessarily portable across platforms. -<p><a name="pdf-string.char"></a><hr><h3><code>string.char (i1, i2, ...)</code></h3> +<p><a name="pdf-string.char"></a><hr/><h3><code>string.char (i1, i2, ...)</code></h3> Receives 0 or more integers. Returns a string with length equal to the number of arguments, in which each character has the internal numerical code equal @@ -4819,29 +4842,34 @@ to its correspondent argument. <p>Note that numerical codes are not necessarily portable across platforms. -<p><a name="pdf-string.dump"></a><hr><h3><code>string.dump (function)</code></h3> +<p><a name="pdf-string.dump"></a><hr/><h3><code>string.dump (function)</code></h3> <p>Returns a binary representation of the given function, so that a later <a href="#pdf-loadstring"><code>loadstring</code></a> on that string returns a copy of the function. <code>function</code> must be a Lua function. -<p><a name="pdf-string.find"></a><hr><h3><code>string.find (s, pattern [, init [, plain]])</code></h3> +<p><a name="pdf-string.find"></a><hr/><h3><code>string.find (s, pattern [, init [, plain]])</code></h3> Looks for the first <em>match</em> of <code>pattern</code> in the string <code>s</code>. If it finds one, then <code>find</code> returns the indices of <code>s</code> where this occurrence starts and ends; -otherwise, it returns <B>nil</B>. +otherwise, it returns <b>nil</b>. A third, optional numerical argument <code>init</code> specifies where to start the search; its default value is 1 and may be negative. -A value of <B>true</B> as a fourth, optional argument <code>plain</code> +A value of <b>true</b> as a fourth, optional argument <code>plain</code> turns off the pattern matching facilities, so the function does a plain "find substring" operation, with no characters in <code>pattern</code> being considered "magic". Note that if <code>plain</code> is given, then <code>init</code> must be given too. -<p><a name="format"></a><a name="pdf-string.format"></a><hr><h3><code>string.format (formatstring, e1, e2, ...)</code></h3> +<p>If the pattern has captures, +then in a successful match +the captured values are also returned, +after the two indices. + +<p><a name="format"></a><a name="pdf-string.format"></a><hr/><h3><code>string.format (formatstring, e1, e2, ...)</code></h3> 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 <code>printf</code> family of @@ -4856,14 +4884,14 @@ The string is written between double quotes, and all double quotes, newlines, and backslashes in the string are correctly escaped when written. For instance, the call -<PRE> +<pre> string.format('%q', 'a string with "quotes" and \n new line') -</PRE> +</pre> will produce the string: -<PRE> +<pre> "a string with \"quotes\" and \ new line" -</PRE> +</pre> <p>The options <code>c</code>, <code>d</code>, <code>E</code>, <code>e</code>, <code>f</code>, <code>g</code>, <code>G</code>, <code>i</code>, <code>o</code>, <code>u</code>, <code>X</code>, and <code>x</code> all @@ -4873,7 +4901,7 @@ whereas <code>q</code> and <code>s</code> expect a string. <p>This function does not accept string values containing embedded zeros. -<p><a name="pdf-string.gmatch"></a><hr><h3><code>string.gmatch (s, pat)</code></h3> +<p><a name="pdf-string.gmatch"></a><hr/><h3><code>string.gmatch (s, pat)</code></h3> Returns an iterator function that, each time it is called, returns the next captures from pattern <code>pat</code> over string <code>s</code>. @@ -4882,25 +4910,25 @@ returns the next captures from pattern <code>pat</code> over string <code>s</cod then the whole match is produced in each call. <p>As an example, the following loop -<PRE> +<pre> s = "hello world from Lua" for w in string.gmatch(s, "%a+") do print(w) end -</PRE> +</pre> will iterate over all the words from string <code>s</code>, printing one per line. The next example collects all pairs <code>key=value</code> from the given string into a table: -<PRE> +<pre> t = {} s = "from=world, to=Lua" for k, v in string.gmatch(s, "(%w+)=(%w+)") do t[k] = v end -</PRE> +</pre> -<p><a name="pdf-string.gsub"></a><hr><h3><code>string.gsub (s, pat, repl [, n])</code></h3> +<p><a name="pdf-string.gsub"></a><hr/><h3><code>string.gsub (s, pat, repl [, n])</code></h3> Returns a copy of <code>s</code> in which all occurrences of the pattern <code>pat</code> have been replaced by a replacement string specified by <code>repl</code>. @@ -4920,9 +4948,16 @@ 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 this function is a string, +If <code>repl</code> is a table, then this table is queried with the +value of the first capture or of the whole match, +if the pattern specifies no captures. +In both cases, +if the value returned by the function or resulted by the query +is a string, then it is used as the replacement string; -otherwise, the replacement string is the empty string. +otherwise, if it is <b>false</b> or <b>nil</b>, +then there is no replacement +(that is, the original match is kept in the string). <p>The optional last parameter <code>n</code> limits the maximum number of substitutions to occur. @@ -4930,7 +4965,7 @@ For instance, when <code>n</code> is 1 only the first occurrence of <code>pat</code> is replaced. <p>Here are some examples: -<PRE> +<pre> x = string.gsub("hello world", "(%w+)", "%1 %1") --> x="hello hello world world" @@ -4949,44 +4984,42 @@ For instance, when <code>n</code> is 1 only the first occurrence of --> x="4+5 = 9" local t = {name="lua", version="5.0"} - x = string.gsub("$name_$version.tar.gz", "%$(%w+)", function (v) - return t[v] - end) + x = string.gsub("$name_$version.tar.gz", "%$(%w+)", t) --> x="lua_5.0.tar.gz" -</PRE> +</pre> -<p><a name="pdf-string.len"></a><hr><h3><code>string.len (s)</code></h3> +<p><a name="pdf-string.len"></a><hr/><h3><code>string.len (s)</code></h3> Receives a string and returns its length. The empty string <code>""</code> has length 0. Embedded zeros are counted, so <code>"a\000bc\000"</code> has length 5. -<p><a name="pdf-string.lower"></a><hr><h3><code>string.lower (s)</code></h3> +<p><a name="pdf-string.lower"></a><hr/><h3><code>string.lower (s)</code></h3> Receives a string and returns a copy of that string with all uppercase letters changed to lowercase. All other characters are left unchanged. The definition of what is an uppercase letter depends on the current locale. -<p><a name="pdf-string.match"></a><hr><h3><code>string.match (s, pattern [, init])</code></h3> +<p><a name="pdf-string.match"></a><hr/><h3><code>string.match (s, pattern [, init])</code></h3> Looks for the first <em>match</em> of <code>pattern</code> in the string <code>s</code>. If it finds one, then <code>match</code> returns the captures from the pattern; -otherwise it returns <B>nil</B>. +otherwise it returns <b>nil</b>. If <code>pattern</code> specifies no captures, then the whole match is returned. A third, optional numerical argument <code>init</code> specifies where to start the search; its default value is 1 and may be negative. -<p><a name="pdf-string.rep"></a><hr><h3><code>string.rep (s, n)</code></h3> +<p><a name="pdf-string.rep"></a><hr/><h3><code>string.rep (s, n)</code></h3> Returns a string that is the concatenation of <code>n</code> copies of the string <code>s</code>. -<p><a name="pdf-string.reverse"></a><hr><h3><code>string.reverse (s)</code></h3> +<p><a name="pdf-string.reverse"></a><hr/><h3><code>string.reverse (s)</code></h3> Returns a string that is the string <code>s</code> reversed. -<p><a name="pdf-string.sub"></a><hr><h3><code>string.sub (s, i [, j])</code></h3> +<p><a name="pdf-string.sub"></a><hr/><h3><code>string.sub (s, i [, j])</code></h3> Returns the substring of <code>s</code> that starts at <code>i</code> and continues until <code>j</code>; <code>i</code> and <code>j</code> may be negative. @@ -4998,7 +5031,7 @@ with length <code>j</code>, and <code>string.sub(s, -i)</code> returns a suffix of <code>s</code> with length <code>i</code>. -<p><a name="pdf-string.upper"></a><hr><h3><code>string.upper (s)</code></h3> +<p><a name="pdf-string.upper"></a><hr/><h3><code>string.upper (s)</code></h3> Receives a string and returns a copy of that string with all lowercase letters changed to uppercase. All other characters are left unchanged. @@ -5012,26 +5045,26 @@ The following combinations are allowed in describing a character class: <ul> <li><b><em>x</em></b> (where <em>x</em> is not one of the magic characters <code>^$()%.[]*+-?</code>) -— represents the character <em>x</em> itself. -<li><b><code>.</code></b> — (a dot) represents all characters. -<li><b><code>%a</code></b> — represents all letters. -<li><b><code>%c</code></b> — represents all control characters. -<li><b><code>%d</code></b> — represents all digits. -<li><b><code>%l</code></b> — represents all lowercase letters. -<li><b><code>%p</code></b> — represents all punctuation characters. -<li><b><code>%s</code></b> — represents all space characters. -<li><b><code>%u</code></b> — represents all uppercase letters. -<li><b><code>%w</code></b> — represents all alphanumeric characters. -<li><b><code>%x</code></b> — represents all hexadecimal digits. -<li><b><code>%z</code></b> — represents the character with representation 0. -<li><b><code>%<em>x</em></code></b> (where <em>x</em> is any non-alphanumeric character) — +--- represents the character <em>x</em> itself. +<li><b><code>.</code></b> --- (a dot) represents all characters. +<li><b><code>%a</code></b> --- represents all letters. +<li><b><code>%c</code></b> --- represents all control characters. +<li><b><code>%d</code></b> --- represents all digits. +<li><b><code>%l</code></b> --- represents all lowercase letters. +<li><b><code>%p</code></b> --- represents all punctuation characters. +<li><b><code>%s</code></b> --- represents all space characters. +<li><b><code>%u</code></b> --- represents all uppercase letters. +<li><b><code>%w</code></b> --- represents all alphanumeric characters. +<li><b><code>%x</code></b> --- represents all hexadecimal digits. +<li><b><code>%z</code></b> --- represents the character with representation 0. +<li><b><code>%<em>x</em></code></b> (where <em>x</em> is any non-alphanumeric character) --- represents the character <em>x</em>. This is the standard way to escape the magic characters. Any punctuation character (even the non magic) can be preceded by a `<code>%</code>´ when used to represent itself in a pattern. -<p><li><b><code>[<em>set</em>]</code></b> — +<p><li><b><code>[<em>set</em>]</code></b> --- represents the class which is the union of all characters in <em>set</em>. A range of characters may be specified by @@ -5049,7 +5082,7 @@ the lowercase letters plus the `<code>-</code>´ character. Therefore, patterns like <code>[%a-z]</code> or <code>[a-%%]</code> have no meaning. -<p><li><b><code>[^<em>set</em>]</code></b> — +<p><li><b><code>[^<em>set</em>]</code></b> --- represents the complement of <em>set</em>, where <em>set</em> is interpreted as above. </ul> @@ -5135,30 +5168,14 @@ represents an array or a list. For those functions, when we talk about "the length" of a table we mean the result of the length operator. -<p><a name="pdf-table.concat"></a><hr><h3><code>table.concat (table [, sep [, i [, j]]])</code></h3> +<p><a name="pdf-table.concat"></a><hr/><h3><code>table.concat (table [, sep [, i [, j]]])</code></h3> Returns <code>table[i]..sep..table[i+1] ... sep..table[j]</code>. The default value for <code>sep</code> is the empty string, the default for <code>i</code> is 1, and the default for <code>j</code> is the length of the table. If <code>i</code> is greater than <code>j</code>, returns the empty string. -<p><a name="pdf-table.sort"></a><hr><h3><code>table.sort (table [, comp])</code></h3> -Sorts table elements in a given order, <em>in-place</em>, -from <code>table[1]</code> to <code>table[n]</code>, -where <code>n</code> is the length of the table. -If <code>comp</code> 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 <code>not comp(a[i+1],a[i])</code> will be true after the sort). -If <code>comp</code> is not given, -then the standard Lua operator <code><</code> is used instead. - -<p>The sort algorithm is not stable, -that is, elements considered equal by the given order -may have their relative positions changed by the sort. - -<p><a name="pdf-table.insert"></a><hr><h3><code>table.insert (table, [pos,] value)</code></h3> +<p><a name="pdf-table.insert"></a><hr/><h3><code>table.insert (table, [pos,] value)</code></h3> <p>Inserts element <code>value</code> at position <code>pos</code> in <code>table</code>, shifting up other elements to open space, if necessary. @@ -5167,7 +5184,12 @@ where <code>n</code> is the length of the table (see <a href="#len-op">2.5.5</a> so that a call <code>table.insert(t,x)</code> inserts <code>x</code> at the end of table <code>t</code>. -<p><a name="pdf-table.remove"></a><hr><h3><code>table.remove (table [, pos])</code></h3> +<p><a name="pdf-table.maxn(table)"></a><hr/><h3><code>table.maxn(table)</code></h3> + +<p>Returns the largest positive numerical index of the given table, +or zero if the table has no positive numerical indices. + +<p><a name="pdf-table.remove"></a><hr/><h3><code>table.remove (table [, pos])</code></h3> <p>Removes from <code>table</code> the element at position <code>pos</code>, shifting down other elements to close the space, if necessary. @@ -5177,26 +5199,42 @@ where <code>n</code> is the length of the table, so that a call <code>table.remove(t)</code> removes the last element of table <code>t</code>. +<p><a name="pdf-table.sort"></a><hr/><h3><code>table.sort (table [, comp])</code></h3> +Sorts table elements in a given order, <em>in-place</em>, +from <code>table[1]</code> to <code>table[n]</code>, +where <code>n</code> is the length of the table. +If <code>comp</code> 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 <code>not comp(a[i+1],a[i])</code> will be true after the sort). +If <code>comp</code> is not given, +then the standard Lua operator <code><</code> is used instead. + +<p>The sort algorithm is not stable, +that is, elements considered equal by the given order +may have their relative positions changed by the sort. + <p><a name="mathlib"></a><a name="5.6"></a><h2>5.6 - Mathematical Functions</h2> <p>This library is an interface to the standard C math library. It provides all its functions inside the table <code>math</code>. The library provides the following functions: - - - - - - - -<PRE> +<a name="pdf-math.abs"></a><a name="pdf-math.acos"></a><a name="pdf-math.asin"></a><a name="pdf-math.atan"></a> +<a name="pdf-math.atan2"></a><a name="pdf-math.ceil"></a><a name="pdf-math.cos"></a><a name="pdf-math.cosh"></a> +<a name="pdf-math.def"></a><a name="pdf-math.exp"></a> +<a name="pdf-math.floor"></a><a name="pdf-math.log"></a><a name="pdf-math.log10"></a> +<a name="pdf-math.fmod"></a><a name="pdf-math.pow"></a><a name="pdf-math.sin"></a> +<a name="pdf-math.sqrt"></a><a name="pdf-math.tan"></a><a name="pdf-math.ldexp"></a> +<a name="pdf-math.sinh"></a><a name="pdf-math.tanh"></a> +<pre> math.abs math.acos math.asin math.atan math.atan2 math.ceil math.cosh math.cos math.deg math.exp math.floor math.fmod math.frexp math.ldexp math.log math.log10 math.max math.min math.modf math.pow math.rad math.random math.randomseed math.sin math.sinh math.sqrt math.tan math.tanh -</PRE> +</pre> plus a variable <code>math.pi</code> and a variable <code>math.huge</code>, with the value <code>HUGE_VAL</code>. @@ -5255,20 +5293,20 @@ three predefined file descriptors with their usual meanings from C: <code>io.stdin</code>, <code>io.stdout</code>, and <code>io.stderr</code>. <p>Unless otherwise stated, -all I/O functions return <B>nil</B> on failure +all I/O functions return <b>nil</b> on failure (plus an error message as a second result) -and some value different from <B>nil</B> on success. +and some value different from <b>nil</b> on success. -<p><a name="pdf-io.close"></a><hr><h3><code>io.close ([file])</code></h3> +<p><a name="pdf-io.close"></a><hr/><h3><code>io.close ([file])</code></h3> <p>Equivalent to <code>file:close()</code>. Without a <code>file</code>, closes the default output file. -<p><a name="pdf-io.flush"></a><hr><h3><code>io.flush ()</code></h3> +<p><a name="pdf-io.flush"></a><hr/><h3><code>io.flush ()</code></h3> <p>Equivalent to <code>file:flush</code> over the default output file. -<p><a name="pdf-io.input"></a><hr><h3><code>io.input ([file])</code></h3> +<p><a name="pdf-io.input"></a><hr/><h3><code>io.input ([file])</code></h3> <p>When called with a file name, it opens the named file (in text mode), and sets its handle as the default input file. @@ -5280,31 +5318,31 @@ it returns the current default input file. <p>In case of errors this function raises the error, instead of returning an error code. -<p><a name="pdf-io.lines"></a><hr><h3><code>io.lines ([filename])</code></h3> +<p><a name="pdf-io.lines"></a><hr/><h3><code>io.lines ([filename])</code></h3> <p>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 -<PRE> +<pre> for line in io.lines(filename) do ... end -</PRE> +</pre> will iterate over all lines of the file. When the iterator function detects the end of file, -it returns <B>nil</B> (to finish the loop) and automatically closes the file. +it returns <b>nil</b> (to finish the loop) and automatically closes the file. <p>The call <code>io.lines()</code> (without a file name) is equivalent to <code>io.input():lines()</code>, that is, it iterates over the lines of the default input file. In that case it does not close the file when the loop ends. -<p><a name="pdf-io.open"></a><hr><h3><code>io.open (filename [, mode])</code></h3> +<p><a name="pdf-io.open"></a><hr/><h3><code>io.open (filename [, mode])</code></h3> <p>This function opens a file, in the mode specified in the string <code>mode</code>. It returns a new file handle, -or, in case of errors, <B>nil</B> plus an error message. +or, in case of errors, <b>nil</b> plus an error message. <p>The <code>mode</code> string can be any of the following: <ul> @@ -5321,11 +5359,11 @@ 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 <code>fopen</code>. -<p><a name="pdf-io.output"></a><hr><h3><code>io.output ([file])</code></h3> +<p><a name="pdf-io.output"></a><hr/><h3><code>io.output ([file])</code></h3> <p>Similar to <a href="#pdf-io.input"><code>io.input</code></a>, but operates over the default output file. -<p><a name="pdf-io.popen"></a><hr><h3><code>io.popen ([prog [, mode]])</code></h3> +<p><a name="pdf-io.popen"></a><hr/><h3><code>io.popen ([prog [, mode]])</code></h3> <p>Starts program <code>prog</code> in a separated process and returns a file handle that you can use to read data from that program @@ -5336,57 +5374,57 @@ or to write data to that program <p>This function is system dependent and is not available in all platforms. -<p><a name="pdf-io.read"></a><hr><h3><code>io.read (format1, ...)</code></h3> +<p><a name="pdf-io.read"></a><hr/><h3><code>io.read (format1, ...)</code></h3> <p>Equivalent to <code>io.input():read</code>. -<p><a name="pdf-io.tmpfile"></a><hr><h3><code>io.tmpfile ()</code></h3> +<p><a name="pdf-io.tmpfile"></a><hr/><h3><code>io.tmpfile ()</code></h3> <p>Returns a handle for a temporary file. This file is open in update mode and it is automatically removed when the program ends. -<p><a name="pdf-io.type"></a><hr><h3><code>io.type (obj)</code></h3> +<p><a name="pdf-io.type"></a><hr/><h3><code>io.type (obj)</code></h3> <p>Checks whether <code>obj</code> is a valid file handle. Returns the string <code>"file"</code> if <code>obj</code> is an open file handle, <code>"closed file"</code> if <code>obj</code> is a closed file handle, -and <B>nil</B> if <code>obj</code> is not a file handle. +and <b>nil</b> if <code>obj</code> is not a file handle. -<p><a name="pdf-io.write"></a><hr><h3><code>io.write (value1, ...)</code></h3> +<p><a name="pdf-io.write"></a><hr/><h3><code>io.write (value1, ...)</code></h3> <p>Equivalent to <code>io.output():write</code>. -<p><a name="pdf-file:close"></a><hr><h3><code>file:close ()</code></h3> +<p><a name="pdf-file:close"></a><hr/><h3><code>file:close ()</code></h3> <p>Closes <code>file</code>. Note that files are automatically closed when garbage collected, but that takes an unpredictable time to happen. -<p><a name="flush"></a><a name="pdf-file:flush"></a><hr><h3><code>file:flush ()</code></h3> +<p><a name="flush"></a><a name="pdf-file:flush"></a><hr/><h3><code>file:flush ()</code></h3> <p>Saves any written data to <code>file</code>. -<p><a name="pdf-file:lines"></a><hr><h3><code>file:lines ()</code></h3> +<p><a name="pdf-file:lines"></a><hr/><h3><code>file:lines ()</code></h3> <p>Returns an iterator function that, each time it is called, returns a new line from the file. Therefore, the construction -<PRE> +<pre> for line in file:lines() do ... end -</PRE> +</pre> will iterate over all lines of the file. (Unlike <a href="#pdf-io.lines"><code>io.lines</code></a>, this function does not close the file when the loop ends.) -<p><a name="pdf-file:read"></a><hr><h3><code>file:read (format1, ...)</code></h3> +<p><a name="pdf-file:read"></a><hr/><h3><code>file:read (format1, ...)</code></h3> <p>Reads the file <code>file</code>, 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 <B>nil</B> if it cannot read data with the specified format. +or <b>nil</b> 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). @@ -5398,16 +5436,16 @@ this is the only format that returns a number instead of a string. <li><b>"*a"</b> reads the whole file, starting at the current position. On end of file, it returns the empty string. <li><b>"*l"</b> reads the next line (skipping the end of line), -returning <B>nil</B> on end of file. +returning <b>nil</b> on end of file. This is the default format. <li><b><em>number</em></b> reads a string with up to that number of characters, -returning <B>nil</B> on end of file. +returning <b>nil</b> on end of file. If number is zero, it reads nothing and returns an empty string, -or <B>nil</B> on end of file. +or <b>nil</b> on end of file. </ul> -<p><a name="pdf-file:seek"></a><hr><h3><code>file:seek ([whence] [, offset])</code></h3> +<p><a name="pdf-file:seek"></a><hr/><h3><code>file:seek ([whence] [, offset])</code></h3> <p>Sets and gets the file position, measured from the beginning of the file, @@ -5420,7 +5458,7 @@ specified by the string <code>whence</code>, as follows: </ul> In case of success, function <code>seek</code> returns the final file position, measured in bytes from the beginning of the file. -If this function fails, it returns <B>nil</B>, +If this function fails, it returns <b>nil</b>, plus a string describing the error. <p>The default value for <code>whence</code> is <code>"cur"</code>, @@ -5432,7 +5470,7 @@ beginning of the file (and returns 0); and the call <code>file:seek("end")</code> sets the position to the end of the file, and returns its size. -<p><a name="pdf-file:setvbuf"></a><hr><h3><code>file:setvbuf (mode [, size])</code></h3> +<p><a name="pdf-file:setvbuf"></a><hr/><h3><code>file:setvbuf (mode [, size])</code></h3> <p>Sets the buffering mode for an output file. There are three available modes: @@ -5448,7 +5486,7 @@ For the last two cases, <code>sizes</code> specifies the size of the buffer, in bytes. The default is an appropriate size. -<p><a name="pdf-file:write"></a><hr><h3><code>file:write (value1, ...)</code></h3> +<p><a name="pdf-file:write"></a><hr/><h3><code>file:write (value1, ...)</code></h3> <p>Writes the value of each of its arguments to the filehandle <code>file</code>. @@ -5460,12 +5498,12 @@ use <a href="#pdf-tostring"><code>tostring</code></a> or <a href="#pdf-string.fo <p>This library is implemented through table <code>os</code>. -<p><a name="pdf-os.clock"></a><hr><h3><code>os.clock ()</code></h3> +<p><a name="pdf-os.clock"></a><hr/><h3><code>os.clock ()</code></h3> <p>Returns an approximation of the amount of CPU time used by the program, in seconds. -<p><a name="pdf-os.date"></a><hr><h3><code>os.date ([format [, time]])</code></h3> +<p><a name="pdf-os.date"></a><hr/><h3><code>os.date ([format [, time]])</code></h3> <p>Returns a string or a table containing date and time, formatted according to the given string <code>format</code>. @@ -5495,43 +5533,43 @@ formatted according to the same rules as the C function <code>strftime</code>. the host system and on the current locale (that is, <code>os.date()</code> is equivalent to <code>os.date("%c")</code>). -<p><a name="pdf-os.difftime"></a><hr><h3><code>os.difftime (t2, t1)</code></h3> +<p><a name="pdf-os.difftime"></a><hr/><h3><code>os.difftime (t2, t1)</code></h3> <p>Returns the number of seconds from time <code>t1</code> to time <code>t2</code>. In Posix, Windows, and some other systems, this value is exactly <code>t2</code><em>-</em><code>t1</code>. -<p><a name="pdf-os.execute"></a><hr><h3><code>os.execute (command)</code></h3> +<p><a name="pdf-os.execute"></a><hr/><h3><code>os.execute (command)</code></h3> <p>This function is equivalent to the C function <code>system</code>. It passes <code>command</code> to be executed by an operating system shell. It returns a status code, which is system-dependent. -<p><a name="pdf-os.exit"></a><hr><h3><code>os.exit ([code])</code></h3> +<p><a name="pdf-os.exit"></a><hr/><h3><code>os.exit ([code])</code></h3> <p>Calls the C function <code>exit</code>, with an optional <code>code</code>, to terminate the host program. The default value for <code>code</code> is the success code. -<p><a name="pdf-os.getenv"></a><hr><h3><code>os.getenv (varname)</code></h3> +<p><a name="pdf-os.getenv"></a><hr/><h3><code>os.getenv (varname)</code></h3> <p>Returns the value of the process environment variable <code>varname</code>, -or <B>nil</B> if the variable is not defined. +or <b>nil</b> if the variable is not defined. -<p><a name="pdf-os.remove"></a><hr><h3><code>os.remove (filename)</code></h3> +<p><a name="pdf-os.remove"></a><hr/><h3><code>os.remove (filename)</code></h3> <p>Deletes the file with the given name. -If this function fails, it returns <B>nil</B>, +If this function fails, it returns <b>nil</b>, plus a string describing the error. -<p><a name="pdf-os.rename"></a><hr><h3><code>os.rename (oldname, newname)</code></h3> +<p><a name="pdf-os.rename"></a><hr/><h3><code>os.rename (oldname, newname)</code></h3> <p>Renames file named <code>oldname</code> to <code>newname</code>. -If this function fails, it returns <B>nil</B>, +If this function fails, it returns <b>nil</b>, plus a string describing the error. -<p><a name="pdf-os.setlocale"></a><hr><h3><code>os.setlocale (locale [, category])</code></h3> +<p><a name="pdf-os.setlocale"></a><hr/><h3><code>os.setlocale (locale [, category])</code></h3> <p>Sets the current locale of the program. <code>locale</code> is a string specifying a locale; @@ -5540,9 +5578,9 @@ plus a string describing the error. <code>"monetary"</code>, <code>"numeric"</code>, or <code>"time"</code>; the default category is <code>"all"</code>. The function returns the name of the new locale, -or <B>nil</B> if the request cannot be honored. +or <b>nil</b> if the request cannot be honored. -<p><a name="pdf-os.time"></a><hr><h3><code>os.time ([table])</code></h3> +<p><a name="pdf-os.time"></a><hr/><h3><code>os.time ([table])</code></h3> <p>Returns the current time when called without arguments, or a time representing the date and time specified by the given table. @@ -5557,7 +5595,7 @@ In other systems, the meaning is not specified, and the number returned by <code>time</code> can be used only as an argument to <code>date</code> and <code>difftime</code>. -<p><a name="pdf-os.tmpname"></a><hr><h3><code>os.tmpname ()</code></h3> +<p><a name="pdf-os.tmpname"></a><hr/><h3><code>os.tmpname ()</code></h3> <p>Returns a string with a file name that can be used for a temporary file. @@ -5583,7 +5621,7 @@ and therefore can compromise some otherwise secure code. <p>All functions in this library are provided inside a <code>debug</code> table. -<p><a name="pdf-debug.debug"></a><hr><h3><code>debug.debug ()</code></h3> +<p><a name="pdf-debug.debug"></a><hr/><h3><code>debug.debug ()</code></h3> <p>Enters an interactive mode with the user, running each string that the user enters. @@ -5596,17 +5634,17 @@ so that the caller continues its execution. <p>Note that commands for <a href="#pdf-debug.debug"><code>debug.debug</code></a> are not lexically nested with any function, so they have no direct access to local variables. -<p><a name="pdf-debug.getfenv"></a><hr><h3><code>debug.getfenv (o)</code></h3> +<p><a name="pdf-debug.getfenv"></a><hr/><h3><code>debug.getfenv (o)</code></h3> Returns the environment of object <code>o</code>. -<p><a name="pdf-debug.gethook"></a><hr><h3><code>debug.gethook ()</code></h3> +<p><a name="pdf-debug.gethook"></a><hr/><h3><code>debug.gethook ()</code></h3> <p>Returns the current hook settings, as three values: the current hook function, the current hook mask, and the current hook count (as set by the <a href="#pdf-debug.sethook"><code>debug.sethook</code></a> function). -<p><a name="pdf-debug.getinfo"></a><hr><h3><code>debug.getinfo (function [, what])</code></h3> +<p><a name="pdf-debug.getinfo"></a><hr/><h3><code>debug.getinfo (function [, what])</code></h3> <p>This function returns a table with information about a function. You can give the function directly, @@ -5616,7 +5654,7 @@ Level 0 is the current function (<code>getinfo</code> itself); level 1 is the function that called <code>getinfo</code>; and so on. If <code>function</code> is a number larger than the number of active functions, -then <code>getinfo</code> returns <B>nil</B>. +then <code>getinfo</code> returns <b>nil</b>. <p>The returned table contains all the fields returned by <a href="#lua_getinfo"><code>lua_getinfo</code></a>, with the string <code>what</code> describing which fields to fill in. @@ -5630,33 +5668,41 @@ the name of the current function, if a reasonable name can be found, and <code>debug.getinfo(print)</code> returns a table with all available information about the <a href="#pdf-print"><code>print</code></a> function. -<p><a name="pdf-debug.getlocal"></a><hr><h3><code>debug.getlocal (level, local)</code></h3> +<p><a name="pdf-debug.getlocal"></a><hr/><h3><code>debug.getlocal (level, local)</code></h3> <p>This function returns the name and the value of the local variable with index <code>local</code> of the function at level <code>level</code> of the stack. (The first parameter or local variable has index 1, and so on, until the last active local variable.) -The function returns <B>nil</B> if there is no local +The function returns <b>nil</b> if there is no local variable with the given index, and raises an error when called with a <code>level</code> out of range. (You can call <a href="#pdf-debug.getinfo"><code>debug.getinfo</code></a> to check whether the level is valid.) -<p><a name="pdf-debug.getmetatable"></a><hr><h3><code>debug.getmetatable (object)</code></h3> +<p>Variable names starting with `<code>(</code>´ (open parentheses) +represent internal variables +(loop control variables, temporaries, and C function locals). -<p>If <code>object</code> does not have a metatable, returns <B>nil</B>. +<p><a name="pdf-debug.getmetatable"></a><hr/><h3><code>debug.getmetatable (object)</code></h3> + +<p>If <code>object</code> does not have a metatable, returns <b>nil</b>. Otherwise, returns the metatable of the given object. -<p><a name="pdf-debug.getupvalue"></a><hr><h3><code>debug.getupvalue (func, up)</code></h3> +<p><a name="pdf-debug.getregistry"></a><hr/><h3><code>debug.getregistry ()</code></h3> + +<p>Returns the registry table (see <a href="#registry">3.5</a>). + +<p><a name="pdf-debug.getupvalue"></a><hr/><h3><code>debug.getupvalue (func, up)</code></h3> <p>This function returns the name and the value of the upvalue with index <code>up</code> of the function <code>func</code>. -The function returns <B>nil</B> if there is no upvalue with the given index. +The function returns <b>nil</b> if there is no upvalue with the given index. -<p><a name="pdf-debug.setfenv"></a><hr><h3><code>debug.setfenv (o, table)</code></h3> +<p><a name="pdf-debug.setfenv"></a><hr/><h3><code>debug.setfenv (o, table)</code></h3> <p>Sets the environment of the given object. -<p><a name="pdf-debug.sethook"></a><hr><h3><code>debug.sethook (hook, mask [, count])</code></h3> +<p><a name="pdf-debug.sethook"></a><hr/><h3><code>debug.sethook (hook, mask [, count])</code></h3> <p>Sets the given function as a hook. The string <code>mask</code> and the number <code>count</code> describe @@ -5689,29 +5735,29 @@ unless the event is <code>"tail return"</code>. In this case, Lua is only simulating the return, and a call to <code>getinfo</code> will return invalid data. -<p><a name="pdf-debug.setlocal"></a><hr><h3><code>debug.setlocal (level, local, value)</code></h3> +<p><a name="pdf-debug.setlocal"></a><hr/><h3><code>debug.setlocal (level, local, value)</code></h3> <p>This function assigns the value <code>value</code> to the local variable with index <code>local</code> of the function at level <code>level</code> of the stack. -The function returns <B>nil</B> if there is no local +The function returns <b>nil</b> if there is no local variable with the given index, and raises an error when called with a <code>level</code> out of range. (You can call <code>getinfo</code> to check whether the level is valid.) Otherwise, it returns the name of the local variable. -<p><a name="pdf-debug.setmetatable"></a><hr><h3><code>debug.setmetatable (o, metatable)</code></h3> +<p><a name="pdf-debug.setmetatable"></a><hr/><h3><code>debug.setmetatable (o, metatable)</code></h3> <p>Sets the metatable for the given object. -<p><a name="pdf-debug.setupvalue"></a><hr><h3><code>debug.setupvalue (func, up, value)</code></h3> +<p><a name="pdf-debug.setupvalue"></a><hr/><h3><code>debug.setupvalue (func, up, value)</code></h3> <p>This function assigns the value <code>value</code> to the upvalue with index <code>up</code> of the function <code>func</code>. -The function returns <B>nil</B> if there is no upvalue +The function returns <b>nil</b> if there is no upvalue with the given index. Otherwise, it returns the name of the upvalue. -<p><a name="pdf-debug.traceback"></a><hr><h3><code>debug.traceback ([message])</code></h3> +<p><a name="pdf-debug.traceback"></a><hr/><h3><code>debug.traceback ([message])</code></h3> <p>Returns a string with a traceback of the call stack. An optional <code>message</code> string is appended @@ -5731,17 +5777,17 @@ is provided with the standard distribution. The stand-alone interpreter includes all standard libraries plus the reflexive debug interface. Its usage is: -<PRE> +<pre> lua [options] [script [args]] -</PRE> +</pre> The options are: <ul> -<li><b><code>-</code> </b> executes <code>stdin</code> as a file; <li><b><code>-e</code> <em>stat</em></b> executes string <em>stat</em>; <li><b><code>-l</code> <em>mod</em></b> "requires" <em>mod</em>; <li><b><code>-i</code></b> enters interactive mode after running <em>script</em>; <li><b><code>-v</code></b> prints version information; -<li><b><code>--</code></b> stop handling options. +<li><b><code>--</code></b> stops handling options; +<li><b><code>-</code> </b> executes <code>stdin</code> as a file and stops handling options. </ul> After handling its options, <code>lua</code> runs the given <em>script</em>, passing to it the given <em>args</em>. @@ -5757,9 +5803,9 @@ Otherwise, lua executes the string itself. <p>All options are handled in order, except <code>-i</code>. For instance, an invocation like -<PRE> +<pre> $ lua -e'a=1' -e 'print(a)' script.lua -</PRE> +</pre> will first set <code>a</code> to 1, then print <code>a</code>, and finally run the file <code>script.lua</code>. (Here <code>$</code> is the shell prompt. Your prompt may be different.) @@ -5774,15 +5820,15 @@ Any arguments before the script name (that is, the interpreter name plus the options) go to negative indices. For instance, in the call -<PRE> +<pre> $ lua -la.lua b.lua t1 t2 -</PRE> +</pre> the interpreter first runs the file <code>a.lua</code>, then creates a table -<PRE> +<pre> arg = { [-2] = "lua", [-1] = "-la.lua", [0] = "b.lua", [1] = "t1", [2] = "t2" } -</PRE> +</pre> and finally runs the file <code>b.lua</code>. The script is called with <code>arg[1]</code>, <code>arg[2]</code>, ... as arguments; @@ -5795,9 +5841,9 @@ the interpreter waits for its completion. <p>If the global variable <code>_PROMPT</code> is defined as a string, then its value is used as the prompt. Therefore, the prompt can be changed directly on the command line: -<PRE> +<pre> $ lua -e"_PROMPT='myprompt> '" -i -</PRE> +</pre> (the outer pair of quotes is for the shell, the inner is for Lua), or in any Lua programs by assigning to <code>_PROMPT</code>. @@ -5811,19 +5857,19 @@ the first line of a chunk if it starts with <code>#</code>. Therefore, Lua scripts can be made into executable programs by using <code>chmod +x</code> and the <code>#!</code> form, as in -<PRE> +<pre> #!/usr/local/bin/lua -</PRE> +</pre> (Of course, the location of the Lua interpreter may be different in your machine. If <code>lua</code> is in your <code>PATH</code>, then -<PRE> +<pre> #!/usr/bin/env lua -</PRE> +</pre> is a more portable solution.) -<p><hr> +<p><hr/> <p><h1>Incompatibilities with Previous Version</h1> @@ -5867,6 +5913,13 @@ Function <code>string.gfind</code> was renamed <a href="#pdf-string.gmatch"><cod (Option <code>LUA_COMPAT_GFIND</code>) <p><li> +When <a href="#pdf-string.gsub"><code>string.gsub</code></a> is called with a function as its +third argument, +whenever that function returns <b>nil</b> or <b>false</b> the +replacement string is the whole match, +instead of the empty string. + +<p><li> Function <code>table.setn</code> was deprecated. Function <code>table.getn</code> corresponds to the new length operator (<code>#</code>); @@ -5924,48 +5977,66 @@ Function <code>luaL_openlib</code> was replaced by <a href="#luaL_register"><cod <p><pre> -<p> chunk ::= {stat [`<b>;</b>´]} + chunk ::= {stat [`<b>;</b>´]} [laststat[`<b>;</b>´]] + + block ::= chunk -<p> block ::= chunk + stat ::= varlist1 `<b>=</b>´ explist1 | + functioncall | + <b>do</b> block <b>end</b> | + <b>while</b> exp <b>do</b> block <b>end</b> | + <b>repeat</b> block <b>until</b> exp | + <b>if</b> exp <b>then</b> block {<b>elseif</b> exp <b>then</b> block} [<b>else</b> block] <b>end</b> | + <b>for</b> Name `<b>=</b>´ exp `<b>,</b>´ exp [`<b>,</b>´ exp] <b>do</b> block <b>end</b> | + <b>for</b> namelist <b>in</b> explist1 <b>do</b> block <b>end</b> | + <b>function</b> funcname funcbody | + <b>local</b> <b>function</b> Name funcbody | + <b>local</b> namelist [init] -<p> stat ::= varlist1 `<b>=</b>´ explist1 | functioncall | <b>do</b> block <b>end</b> | <b>while</b> exp <b>do</b> block <b>end</b> | <b>repeat</b> block <b>until</b> exp | <b>if</b> exp <b>then</b> block {<b>elseif</b> exp <b>then</b> block} [<b>else</b> block] <b>end</b> | <b>return</b> [explist1] | <b>break</b> | <b>for</b> Name `<b>=</b>´ exp `<b>,</b>´ exp [`<b>,</b>´ exp] <b>do</b> block <b>end</b> | <b>for</b> namelist <b>in</b> explist1 <b>do</b> block <b>end</b> | <b>function</b> funcname funcbody | <b>local</b> <b>function</b> Name funcbody | <b>local</b> namelist [init] + laststat ::= <b>return</b> [explist1] | <b>break</b> -<p> funcname ::= Name {`<b>.</b>´ Name} [`<b>:</b>´ Name] + funcname ::= Name {`<b>.</b>´ Name} [`<b>:</b>´ Name] + + varlist1 ::= var {`<b>,</b>´ var} -<p> varlist1 ::= var {`<b>,</b>´ var} + var ::= Name | prefixexp `<b>[</b>´ exp `<b>]</b>´ | prefixexp `<b>.</b>´ Name -<p> var ::= Name | prefixexp `<b>[</b>´ exp `<b>]</b>´ | prefixexp `<b>.</b>´ Name + namelist ::= Name {`<b>,</b>´ Name} -<p> namelist ::= Name {`<b>,</b>´ Name} + init ::= `<b>=</b>´ explist1 -<p> init ::= `<b>=</b>´ explist1 + explist1 ::= {exp `<b>,</b>´} exp -<p> explist1 ::= {exp `<b>,</b>´} exp + exp ::= <b>nil</b> | <b>false</b> | <b>true</b> | Number | Literal | `<b>...</b>´ | + function | prefixexp | tableconstructor | exp binop exp | unop exp -<p> exp ::= <b>nil</b> | <b>false</b> | <b>true</b> | Number | Literal | `<b>...</b>´ | function | prefixexp | tableconstructor | exp binop exp | unop exp + prefixexp ::= var | functioncall | `<b>(</b>´ exp `<b>)</b>´ -<p> prefixexp ::= var | functioncall | `<b>(</b>´ exp `<b>)</b>´ + functioncall ::= prefixexp args | prefixexp `<b>:</b>´ Name args -<p> functioncall ::= prefixexp args | prefixexp `<b>:</b>´ Name args + args ::= `<b>(</b>´ [explist1] `<b>)</b>´ | tableconstructor | Literal -<p> args ::= `<b>(</b>´ [explist1] `<b>)</b>´ | tableconstructor | Literal + function ::= <b>function</b> funcbody -<p> function ::= <b>function</b> funcbody + funcbody ::= `<b>(</b>´ [parlist1] `<b>)</b>´ block <b>end</b> -<p> funcbody ::= `<b>(</b>´ [parlist1] `<b>)</b>´ block <b>end</b> + parlist1 ::= namelist [`<b>,</b>´ `<b>...</b>´] | `<b>...</b>´ -<p> parlist1 ::= namelist [`<b>,</b>´ `<b>...</b>´] | `<b>...</b>´ + tableconstructor ::= `<b>{</b>´ [fieldlist] `<b>}</b>´ -<p> tableconstructor ::= `<b>{</b>´ [fieldlist] `<b>}</b>´ fieldlist ::= field {fieldsep field} [fieldsep] - field ::= `<b>[</b>´ exp `<b>]</b>´ `<b>=</b>´ exp | name `<b>=</b>´ exp | exp - fieldsep ::= `<b>,</b>´ | `<b>;</b>´ -<p> binop ::= `<b>+</b>´ | `<b>-</b>´ | `<b>*</b>´ | `<b>/</b>´ | `<b>^</b>´ | `<b>%</b>´ | `<b>..</b>´ | `<b><</b>´ | `<b><=</b>´ | `<b>></b>´ | `<b>>=</b>´ | `<b>==</b>´ | `<b>~=</b>´ | <b>and</b> | <b>or</b> + field ::= `<b>[</b>´ exp `<b>]</b>´ `<b>=</b>´ exp | name `<b>=</b>´ exp | exp -<p> unop ::= `<b>-</b>´ | <b>not</b> | `<b>#</b>´ + fieldsep ::= `<b>,</b>´ | `<b>;</b>´ -<p></pre> + binop ::= `<b>+</b>´ | `<b>-</b>´ | `<b>*</b>´ | `<b>/</b>´ | `<b>^</b>´ | `<b>%</b>´ | `<b>..</b>´ | + `<b><</b>´ | `<b><=</b>´ | `<b>></b>´ | `<b>>=</b>´ | `<b>==</b>´ | `<b>~=</b>´ | + <b>and</b> | <b>or</b> + + unop ::= `<b>-</b>´ | <b>not</b> | `<b>#</b>´ + +</pre> <p> @@ -5974,7 +6045,7 @@ Function <code>luaL_openlib</code> was replaced by <a href="#luaL_register"><cod <HR> <SMALL> Last update: -Wed Sep 7 13:53:49 BRT 2005 +Tue Nov 1 15:20:21 BRST 2005 </SMALL> </body></html> @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 2.48 2005/09/01 17:42:22 roberto Exp $ +** $Id: lapi.c,v 2.51 2005/10/20 11:35:50 roberto Exp $ ** Lua API ** See Copyright Notice in lua.h */ @@ -141,7 +141,7 @@ LUA_API lua_State *lua_newthread (lua_State *L) { setthvalue(L, L->top, L1); api_incr_top(L); lua_unlock(L); - luai_userstateopen(L1); + luai_userstatethread(L, L1); return L1; } @@ -913,6 +913,10 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { 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) @@ -992,8 +996,20 @@ LUA_API void lua_concat (lua_State *L, int n) { LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { + lua_Alloc f; + lua_lock(L); if (ud) *ud = G(L)->ud; - return G(L)->frealloc; + 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); } diff --git a/src/lauxlib.c b/src/lauxlib.c index b643d6c3..04620979 100644 --- a/src/lauxlib.c +++ b/src/lauxlib.c @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.c,v 1.152 2005/09/06 17:20:11 roberto Exp $ +** $Id: lauxlib.c,v 1.156 2005/10/21 13:47:42 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -176,8 +176,7 @@ LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) { LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { - if (lua_isnoneornil(L, narg)) return def; - else return luaL_checknumber(L, narg); + return luaL_opt(L, luaL_checknumber, narg, def); } @@ -190,16 +189,16 @@ LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg, - lua_Integer def) { - if (lua_isnoneornil(L, narg)) return def; - else return luaL_checkinteger(L, 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_getfield(L, -1, event); + lua_pushstring(L, event); + lua_rawget(L, -2); if (lua_isnil(L, -1)) { lua_pop(L, 2); /* remove metatable and metafield */ return 0; @@ -231,7 +230,7 @@ LUALIB_API void luaI_openlib (lua_State *L, const char *libname, const luaL_Reg *l, int nup) { if (libname) { /* check whether lib already exists */ - lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED"); lua_getfield(L, -1, libname); /* get _LOADED[libname] */ if (!lua_istable(L, -1)) { /* not found? */ lua_pop(L, 1); /* remove previous result */ @@ -305,7 +304,7 @@ LUALIB_API int luaL_getn (lua_State *L, int t) { if ((n = checkint(L, 2)) >= 0) return n; lua_getfield(L, t, "n"); /* else try t.n */ if ((n = checkint(L, 1)) >= 0) return n; - return lua_objlen(L, t); + return (int)lua_objlen(L, t); } #endif @@ -470,7 +469,7 @@ LUALIB_API int luaL_ref (lua_State *L, int t) { lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ } else { /* no free elements */ - ref = lua_objlen(L, t); + ref = (int)lua_objlen(L, t); ref++; /* create new reference */ } lua_rawseti(L, t, ref); diff --git a/src/lauxlib.h b/src/lauxlib.h index aa07cb2b..ee503cc8 100644 --- a/src/lauxlib.h +++ b/src/lauxlib.h @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.h,v 1.85 2005/09/06 17:19:51 roberto Exp $ +** $Id: lauxlib.h,v 1.86 2005/10/21 13:47:42 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -114,6 +114,7 @@ LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, #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))) /* ** {====================================================== diff --git a/src/lbaselib.c b/src/lbaselib.c index fb21da4b..7d8724a5 100644 --- a/src/lbaselib.c +++ b/src/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.182 2005/08/26 17:36:32 roberto Exp $ +** $Id: lbaselib.c,v 1.186 2005/10/21 13:47:42 roberto Exp $ ** Basic library ** See Copyright Notice in lua.h */ @@ -196,9 +196,23 @@ static int luaB_collectgarbage (lua_State *L) { 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_optinteger(L, 2, 0); - lua_pushinteger(L, lua_gc(L, optsnum[o], ex)); - return 1; + 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, ((lua_Number)res*1024 + b)/1000); + return 1; + } + case LUA_GCSTEP: { + lua_pushboolean(L, res); + return 1; + } + default: { + lua_pushnumber(L, res); + return 1; + } + } } @@ -326,12 +340,10 @@ static int luaB_assert (lua_State *L) { static int luaB_unpack (lua_State *L) { - int i = luaL_optint(L, 2, 1); - int e = luaL_optint(L, 3, -1); - int n; + int i, e, n; luaL_checktype(L, 1, LUA_TTABLE); - if (e == -1) - e = luaL_getn(L, 1); + i = luaL_optint(L, 2, 1); + e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1)); n = e - i + 1; /* number of elements */ if (n <= 0) return 0; /* empty range */ luaL_checkstack(L, n, "table too big to unpack"); @@ -349,8 +361,9 @@ static int luaB_select (lua_State *L) { } else { int i = luaL_checkint(L, 1); - if (i <= 0) i = 1; - else if (i >= n) i = n; + 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; } } @@ -560,7 +573,7 @@ static int luaB_costatus (lua_State *L) { lua_pushliteral(L, "dead"); else lua_pushliteral(L, "suspended"); /* initial state */ - break; + break; } default: /* some error occured */ lua_pushliteral(L, "dead"); @@ -601,8 +614,11 @@ static void auxopen (lua_State *L, const char *name, static void base_open (lua_State *L) { + /* set global _G */ lua_pushvalue(L, LUA_GLOBALSINDEX); - luaL_register(L, NULL, base_funcs); /* open lib into global table */ + 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 */ @@ -616,12 +632,6 @@ static void base_open (lua_State *L) { lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ lua_pushcclosure(L, luaB_newproxy, 1); lua_setglobal(L, "newproxy"); /* set global `newproxy' */ - /* create register._LOADED to track loaded modules */ - lua_newtable(L); - lua_setfield(L, LUA_REGISTRYINDEX, "_LOADED"); - /* set global _G */ - lua_pushvalue(L, LUA_GLOBALSINDEX); - lua_setglobal(L, "_G"); } diff --git a/src/lcode.c b/src/lcode.c index 04838f33..ecda5cbf 100644 --- a/src/lcode.c +++ b/src/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 2.16 2005/08/29 20:49:21 roberto Exp $ +** $Id: lcode.c,v 2.22 2005/11/16 11:55:27 roberto Exp $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -27,16 +27,24 @@ #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? */ - GET_OPCODE(*(previous = &fs->f->code[fs->pc-1])) == 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; + if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ + if (fs->pc == 0) /* function start? */ + return; /* positions are already clean */ + if (GET_OPCODE(*(previous = &fs->f->code[fs->pc-1])) == 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 */ @@ -115,20 +123,22 @@ static int need_value (FuncState *fs, int list) { } -static void patchtestreg (Instruction *i, int reg) { - if (reg != NO_REG) +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; change TESTSET to TEST */ + 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)) { - Instruction *i = getjumpcontrol(fs, list); - if (GET_OPCODE(*i) == OP_TESTSET) - patchtestreg(i, NO_REG); - } + for (; list != NO_JUMP; list = getjump(fs, list)) + patchtestreg(fs, list, NO_REG); } @@ -136,11 +146,8 @@ static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, int dtarget) { while (list != NO_JUMP) { int next = getjump(fs, list); - Instruction *i = getjumpcontrol(fs, list); - if (GET_OPCODE(*i) == OP_TESTSET) { - patchtestreg(i, reg); + if (patchtestreg(fs, list, reg)) fixjump(fs, list, vtarget); - } else fixjump(fs, list, dtarget); /* jump to default target */ list = next; @@ -210,7 +217,7 @@ static void freereg (FuncState *fs, int reg) { static void freeexp (FuncState *fs, expdesc *e) { if (e->k == VNONRELOC) - freereg(fs, e->info); + freereg(fs, e->u.s.info); } @@ -280,7 +287,7 @@ void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { void luaK_setoneret (FuncState *fs, expdesc *e) { if (e->k == VCALL) { /* expression is an open function call? */ e->k = VNONRELOC; - e->info = GETARG_A(getcode(fs, e)); + e->u.s.info = GETARG_A(getcode(fs, e)); } else if (e->k == VVARARG) { SETARG_B(getcode(fs, e), 2); @@ -296,19 +303,19 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) { break; } case VUPVAL: { - e->info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->info, 0); + e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0); e->k = VRELOCABLE; break; } case VGLOBAL: { - e->info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->info); + e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info); e->k = VRELOCABLE; break; } case VINDEXED: { - freereg(fs, e->aux); - freereg(fs, e->info); - e->info = luaK_codeABC(fs, OP_GETTABLE, 0, e->info, e->aux); + 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; } @@ -340,7 +347,11 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) { break; } case VK: { - luaK_codeABx(fs, OP_LOADK, reg, e->info); + 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: { @@ -349,8 +360,8 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) { break; } case VNONRELOC: { - if (reg != e->info) - luaK_codeABC(fs, OP_MOVE, reg, e->info, 0); + if (reg != e->u.s.info) + luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0); break; } default: { @@ -358,7 +369,7 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) { return; /* nothing to do... */ } } - e->info = reg; + e->u.s.info = reg; e->k = VNONRELOC; } @@ -374,15 +385,13 @@ static void discharge2anyreg (FuncState *fs, expdesc *e) { static void exp2reg (FuncState *fs, expdesc *e, int reg) { discharge2reg(fs, e, reg); if (e->k == VJMP) - luaK_concat(fs, &e->t, e->info); /* put this jump in `t' list */ + 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 = NO_JUMP; /* first jump (over LOAD ops.) */ - if (e->k != VJMP) - fj = luaK_jump(fs); + 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); @@ -392,7 +401,7 @@ static void exp2reg (FuncState *fs, expdesc *e, int reg) { patchlistaux(fs, e->t, final, reg, p_t); } e->f = e->t = NO_JUMP; - e->info = reg; + e->u.s.info = reg; e->k = VNONRELOC; } @@ -408,14 +417,14 @@ void luaK_exp2nextreg (FuncState *fs, expdesc *e) { int luaK_exp2anyreg (FuncState *fs, expdesc *e) { luaK_dischargevars(fs, e); if (e->k == VNONRELOC) { - if (!hasjumps(e)) return e->info; /* exp is already in a register */ - if (e->info >= fs->nactvar) { /* reg. is not a local? */ - exp2reg(fs, e, e->info); /* put value on it */ - return e->info; + 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->info; + return e->u.s.info; } @@ -430,19 +439,22 @@ void luaK_exp2val (FuncState *fs, expdesc *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->info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE)); + 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->info); + return RKASK(e->u.s.info); } else break; } case VK: { - if (e->info <= MAXINDEXRK) /* constant fit in argC? */ - return RKASK(e->info); + if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */ + return RKASK(e->u.s.info); else break; } default: break; @@ -456,22 +468,22 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { switch (var->k) { case VLOCAL: { freeexp(fs, ex); - exp2reg(fs, ex, var->info); + exp2reg(fs, ex, var->u.s.info); return; } case VUPVAL: { int e = luaK_exp2anyreg(fs, ex); - luaK_codeABC(fs, OP_SETUPVAL, e, var->info, 0); + 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->info); + 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->info, var->aux, e); + luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e); break; } default: { @@ -489,15 +501,15 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { freeexp(fs, e); func = fs->freereg; luaK_reserveregs(fs, 2); - luaK_codeABC(fs, OP_SELF, func, e->info, luaK_exp2RK(fs, key)); + luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key)); freeexp(fs, key); - e->info = func; + e->u.s.info = func; e->k = VNONRELOC; } static void invertjump (FuncState *fs, expdesc *e) { - Instruction *pc = getjumpcontrol(fs, e->info); + 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))); @@ -515,7 +527,7 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) { } discharge2anyreg(fs, e); freeexp(fs, e); - return condjump(fs, OP_TESTSET, NO_REG, e->info, cond); + return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond); } @@ -523,7 +535,7 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) { int pc; /* pc of last jump */ luaK_dischargevars(fs, e); switch (e->k) { - case VK: case VTRUE: { + case VK: case VKNUM: case VTRUE: { pc = NO_JUMP; /* always true; do nothing */ break; } @@ -533,7 +545,7 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) { } case VJMP: { invertjump(fs, e); - pc = e->info; + pc = e->u.s.info; break; } default: { @@ -547,7 +559,7 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) { } -void luaK_goiffalse (FuncState *fs, expdesc *e) { +static void luaK_goiffalse (FuncState *fs, expdesc *e) { int pc; /* pc of last jump */ luaK_dischargevars(fs, e); switch (e->k) { @@ -560,7 +572,7 @@ void luaK_goiffalse (FuncState *fs, expdesc *e) { break; } case VJMP: { - pc = e->info; + pc = e->u.s.info; break; } default: { @@ -581,7 +593,7 @@ static void codenot (FuncState *fs, expdesc *e) { e->k = VTRUE; break; } - case VK: case VTRUE: { + case VK: case VKNUM: case VTRUE: { e->k = VFALSE; break; } @@ -593,7 +605,7 @@ static void codenot (FuncState *fs, expdesc *e) { case VNONRELOC: { discharge2anyreg(fs, e); freeexp(fs, e); - e->info = luaK_codeABC(fs, OP_NOT, 0, e->info, 0); + e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0); e->k = VRELOCABLE; break; } @@ -610,34 +622,81 @@ static void codenot (FuncState *fs, expdesc *e) { void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { - t->aux = luaK_exp2RK(fs, 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 (r != 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 o1 = luaK_exp2RK(fs, e1); + int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0; + 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: { - luaK_exp2val(fs, e); - if (e->k == VK && ttisnumber(&fs->f->k[e->info])) - e->info = luaK_numberK(fs, luai_numunm(L, nvalue(&fs->f->k[e->info]))); - else { - luaK_exp2anyreg(fs, e); - freeexp(fs, e); - e->info = luaK_codeABC(fs, OP_UNM, 0, e->info, 0); - e->k = VRELOCABLE; - } - break; - } - case OPR_NOT: { - codenot(fs, e); + if (e->k == VK) + 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); - freeexp(fs, e); - e->info = luaK_codeABC(fs, OP_LEN, 0, e->info, 0); - e->k = VRELOCABLE; + luaK_exp2anyreg(fs, e); /* cannot operate on constants */ + codearith(fs, OP_LEN, e, &e2); break; } default: lua_assert(0); @@ -660,74 +719,58 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { break; } default: { - luaK_exp2RK(fs, v); + if (!isnumeral(v)) luaK_exp2RK(fs, v); break; } } } -static void codebinop (FuncState *fs, expdesc *res, BinOpr op, - int o1, int o2) { - if (op <= OPR_POW) { /* arithmetic operator? */ - OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD); /* ORDER OP */ - res->info = luaK_codeABC(fs, opc, 0, o1, o2); - res->k = VRELOCABLE; - } - else { /* test operator */ - static const OpCode ops[] = {OP_EQ, OP_EQ, OP_LT, OP_LE, OP_LT, OP_LE}; - int cond = 1; - if (op >= OPR_GT) { /* `>' or `>='? */ - int temp; /* exchange args and replace by `<' or `<=' */ - temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ - } - else if (op == OPR_NE) cond = 0; - res->info = condjump(fs, ops[op - OPR_NE], cond, o1, o2); - res->k = VJMP; - } -} - - 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, &e1->f, e2->f); - e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->t = e2->t; + e1->k = e2->k; e1->u.s.info = e2->u.s.info; + e1->u.s.aux = e2->u.s.aux; e1->t = e2->t; break; } case OPR_OR: { lua_assert(e1->f == NO_JUMP); /* list must be closed */ luaK_dischargevars(fs, e2); luaK_concat(fs, &e1->t, e2->t); - e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->f = e2->f; + e1->k = e2->k; e1->u.s.info = e2->u.s.info; + e1->u.s.aux = e2->u.s.aux; e1->f = e2->f; break; } case OPR_CONCAT: { luaK_exp2val(fs, e2); if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { - lua_assert(e1->info == GETARG_B(getcode(fs, e2))-1); + lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1); freeexp(fs, e1); - SETARG_B(getcode(fs, e2), e1->info); - e1->k = e2->k; e1->info = e2->info; + SETARG_B(getcode(fs, e2), e1->u.s.info); + e1->k = e2->k; e1->u.s.info = e2->u.s.info; } else { - luaK_exp2nextreg(fs, e2); - freeexp(fs, e2); - freeexp(fs, e1); - e1->info = luaK_codeABC(fs, OP_CONCAT, 0, e1->info, e2->info); - e1->k = VRELOCABLE; + luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ + codearith(fs, OP_CONCAT, e1, e2); } break; } - default: { - int o1 = luaK_exp2RK(fs, e1); - int o2 = luaK_exp2RK(fs, e2); - freeexp(fs, e2); - freeexp(fs, e1); - codebinop(fs, e1, op, o1, o2); - } + 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); } } @@ -737,7 +780,7 @@ void luaK_fixline (FuncState *fs, int line) { } -int luaK_code (FuncState *fs, Instruction i, int 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 */ diff --git a/src/lcode.h b/src/lcode.h index ed1a95bc..b5668f22 100644 --- a/src/lcode.h +++ b/src/lcode.h @@ -1,5 +1,5 @@ /* -** $Id: lcode.h,v 1.45 2005/08/29 20:49:21 roberto Exp $ +** $Id: lcode.h,v 1.47 2005/11/08 19:44:31 roberto Exp $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -24,7 +24,7 @@ ** grep "ORDER OPR" if you change these enums */ typedef enum BinOpr { - OPR_ADD, OPR_SUB, OPR_MULT, OPR_DIV, OPR_MOD, OPR_POW, + 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, @@ -37,13 +37,12 @@ typedef enum BinOpr { typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; -#define getcode(fs,e) ((fs)->f->code[(e)->info]) +#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_code (FuncState *fs, Instruction i, int line); 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); @@ -60,7 +59,6 @@ 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_goiffalse (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); diff --git a/src/ldblib.c b/src/ldblib.c index e7458634..5da6e1da 100644 --- a/src/ldblib.c +++ b/src/ldblib.c @@ -1,5 +1,5 @@ /* -** $Id: ldblib.c,v 1.101 2005/08/26 17:36:32 roberto Exp $ +** $Id: ldblib.c,v 1.103 2005/11/01 16:08:32 roberto Exp $ ** Interface from Lua to its debug API ** See Copyright Notice in lua.h */ @@ -19,6 +19,12 @@ +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)) { @@ -319,7 +325,7 @@ static int db_errorfb (lua_State *L) { lua_State *L1 = getthread(L, &arg); lua_Debug ar; if (lua_isnumber(L, arg+2)) { - level = lua_tointeger(L, arg+2); + level = (int)lua_tointeger(L, arg+2); lua_pop(L, 1); } else @@ -371,6 +377,7 @@ static const luaL_Reg dblib[] = { {"gethook", db_gethook}, {"getinfo", db_getinfo}, {"getlocal", db_getlocal}, + {"getregistry", db_getregistry}, {"getmetatable", db_getmetatable}, {"getupvalue", db_getupvalue}, {"setfenv", db_setfenv}, diff --git a/src/ldebug.c b/src/ldebug.c index 11166c0a..5fb11ce1 100644 --- a/src/ldebug.c +++ b/src/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 2.26 2005/08/04 13:37:38 roberto Exp $ +** $Id: ldebug.c,v 2.28 2005/11/01 16:08:52 roberto Exp $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -109,40 +109,39 @@ static Proto *getluaproto (CallInfo *ci) { } -LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { +static const char *findlocal (lua_State *L, CallInfo *ci, int n) { const char *name; - CallInfo *ci; - Proto *fp; - lua_lock(L); - name = NULL; - ci = L->base_ci + ar->i_ci; - fp = getluaproto(ci); - if (fp) { /* is a Lua function? */ - name = luaF_getlocalname(fp, n, currentpc(L, ci)); - if (name) - luaA_pushobject(L, ci->base+(n-1)); /* push value */ + 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) { - const char *name; - CallInfo *ci; - Proto *fp; + CallInfo *ci = L->base_ci + ar->i_ci; + const char *name = findlocal(L, ci, n); lua_lock(L); - name = NULL; - ci = L->base_ci + ar->i_ci; - fp = getluaproto(ci); - L->top--; /* pop new value */ - if (fp) { /* is a Lua function? */ - name = luaF_getlocalname(fp, n, currentpc(L, ci)); - if (!name || name[0] == '(') /* `(' starts private locals */ - name = NULL; - else - setobjs2s(L, ci->base+(n-1), L->top); - } + if (name) + setobjs2s(L, ci->base + (n - 1), L->top - 1); + L->top--; /* pop value */ lua_unlock(L); return name; } @@ -321,7 +320,7 @@ static Instruction symbexec (const Proto *pt, int lastpc, int reg) { last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ check(precheck(pt)); for (pc = 0; pc < lastpc; pc++) { - const Instruction i = pt->code[pc]; + Instruction i = pt->code[pc]; OpCode op = GET_OPCODE(i); int a = GETARG_A(i); int b = 0; @@ -348,7 +347,7 @@ static Instruction symbexec (const Proto *pt, int lastpc, int reg) { check(0 <= dest && dest < pt->sizecode); if (dest > 0) { /* cannot jump to a setlist count */ - const Instruction d = pt->code[dest-1]; + Instruction d = pt->code[dest-1]; check(!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)); } } @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 2.33 2005/09/09 18:16:28 roberto Exp $ +** $Id: ldo.c,v 2.36 2005/10/23 17:52:42 roberto Exp $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -276,8 +276,11 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { Proto *p = cl->p; luaD_checkstack(L, p->maxstacksize); func = restorestack(L, funcr); - if (!p->is_vararg) /* no varargs? */ + 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); @@ -316,14 +319,12 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { lua_unlock(L); n = (*curr_func(L)->c.f)(L); /* do the actual call */ lua_lock(L); - if (n >= 0) { /* no yielding? */ + if (n < 0) /* yielding? */ + return PCRYIELD; + else { luaD_poscall(L, L->top - n); return PCRC; } - else { - ci->nresults = nresults; - return PCRYIELD; - } } } @@ -428,6 +429,7 @@ LUA_API int lua_resume (lua_State *L, int nargs) { if (status != 0) { /* error? */ L->status = cast(lu_byte, status); /* mark thread as `dead' */ luaD_seterrorobj(L, status, L->top); + L->ci->top = L->top; } else status = L->status; diff --git a/src/ldump.c b/src/ldump.c index e580047b..73463410 100644 --- a/src/ldump.c +++ b/src/ldump.c @@ -1,6 +1,6 @@ /* -** $Id: ldump.c,v 1.12 2005/06/08 14:40:44 lhf Exp $ -** save pre-compiled Lua chunks +** $Id: ldump.c,v 1.14 2005/11/11 14:03:13 lhf Exp $ +** save precompiled Lua chunks ** See Copyright Notice in lua.h */ @@ -12,7 +12,6 @@ #include "lua.h" #include "lobject.h" -#include "lopcodes.h" #include "lstate.h" #include "lundump.h" @@ -24,11 +23,8 @@ typedef struct { int status; } DumpState; -#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) -#define DumpLines(f,D) DumpVector(f->lineinfo,f->sizelineinfo,sizeof(int),D) -#define DumpLiteral(s,D) DumpBlock("" s,(sizeof(s))-1,D) -#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) #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) { @@ -77,24 +73,7 @@ static void DumpString(const TString* s, DumpState* D) } } -static void DumpLocals(const Proto* f, DumpState* D) -{ - int i,n=f->sizelocvars; - DumpInt(n,D); - for (i=0; i<n; i++) - { - DumpString(f->locvars[i].varname,D); - DumpInt(f->locvars[i].startpc,D); - DumpInt(f->locvars[i].endpc,D); - } -} - -static void DumpUpvalues(const Proto* f, DumpState* D) -{ - int i,n=f->sizeupvalues; - DumpInt(n,D); - for (i=0; i<n; i++) DumpString(f->upvalues[i],D); -} +#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) static void DumpFunction(const Proto* f, const TString* p, DumpState* D); @@ -129,6 +108,24 @@ static void DumpConstants(const Proto* f, DumpState* D) for (i=0; i<n; i++) DumpFunction(f->p[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; i<n; i++) + { + DumpString(f->locvars[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; i<n; i++) DumpString(f->upvalues[i],D); +} + static void DumpFunction(const Proto* f, const TString* p, DumpState* D) { DumpString((f->source==p) ? NULL : f->source,D); @@ -138,11 +135,9 @@ static void DumpFunction(const Proto* f, const TString* p, DumpState* D) DumpChar(f->numparams,D); DumpChar(f->is_vararg,D); DumpChar(f->maxstacksize,D); - if (D->strip) DumpInt(0,D); else DumpLines(f,D); - if (D->strip) DumpInt(0,D); else DumpLocals(f,D); - if (D->strip) DumpInt(0,D); else DumpUpvalues(f,D); - DumpConstants(f,D); DumpCode(f,D); + DumpConstants(f,D); + DumpDebug(f,D); } static void DumpHeader(DumpState* D) diff --git a/src/liolib.c b/src/liolib.c index a7f8743f..cc493aff 100644 --- a/src/liolib.c +++ b/src/liolib.c @@ -1,5 +1,5 @@ /* -** $Id: liolib.c,v 2.67 2005/08/26 17:36:32 roberto Exp $ +** $Id: liolib.c,v 2.69 2005/10/19 13:05:11 roberto Exp $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ @@ -424,7 +424,7 @@ static int f_seek (lua_State *L) { static const char *const modenames[] = {"set", "cur", "end", NULL}; FILE *f = tofile(L); int op = luaL_checkoption(L, 2, "cur", modenames); - lua_Integer offset = luaL_optinteger(L, 3, 0); + long offset = luaL_optlong(L, 3, 0); op = fseek(f, offset, mode[op]); if (op) return pushresult(L, 0, NULL); /* error */ @@ -440,7 +440,7 @@ static int f_setvbuf (lua_State *L) { 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, BUFSIZ); + lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); int res = setvbuf(f, NULL, mode[op], sz); return pushresult(L, res == 0, NULL); } @@ -1,5 +1,5 @@ /* -** $Id: llex.c,v 2.12 2005/05/17 19:49:15 roberto Exp $ +** $Id: llex.c,v 2.13 2005/11/08 19:45:14 roberto Exp $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ @@ -155,28 +155,23 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { +static int check_next (LexState *ls, const char *set) { + if (!strchr(set, ls->current)) + return 0; + save_and_next(ls); + return 1; +} + + /* LUA_NUMBER */ static void read_numeral (LexState *ls, SemInfo *seminfo) { - while (isdigit(ls->current)) { + lua_assert(isdigit(ls->current)); + do { save_and_next(ls); - } - if (ls->current == '.') { - save_and_next(ls); - if (ls->current == '.') { - save_and_next(ls); - luaX_lexerror(ls, - "ambiguous syntax (decimal point x string concatenation)", - TK_NUMBER); - } - } - while (isdigit(ls->current)) { - save_and_next(ls); - } - if (ls->current == 'e' || ls->current == 'E') { - save_and_next(ls); /* read `E' */ - if (ls->current == '+' || ls->current == '-') - save_and_next(ls); /* optional exponent sign */ + } while (isdigit(ls->current) || ls->current == '.'); + if (check_next(ls, "Ee")) { /* `E'? */ + check_next(ls, "+-"); /* optional exponent sign */ while (isdigit(ls->current)) { save_and_next(ls); } @@ -375,12 +370,9 @@ int luaX_lex (LexState *ls, SemInfo *seminfo) { } case '.': { save_and_next(ls); - if (ls->current == '.') { - next(ls); - if (ls->current == '.') { - next(ls); + if (check_next(ls, ".")) { + if (check_next(ls, ".")) return TK_DOTS; /* ... */ - } else return TK_CONCAT; /* .. */ } else if (!isdigit(ls->current)) return '.'; diff --git a/src/loadlib.c b/src/loadlib.c index 767fdb8e..9f992086 100644 --- a/src/loadlib.c +++ b/src/loadlib.c @@ -1,5 +1,5 @@ /* -** $Id: loadlib.c,v 1.44 2005/09/06 17:20:25 roberto Exp $ +** $Id: loadlib.c,v 1.48 2005/10/17 18:01:51 roberto Exp $ ** Dynamic library loader for Lua ** See Copyright Notice in lua.h ** @@ -97,16 +97,18 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { #undef setprogdir -void setprogdir (lua_State *L) { +static void setprogdir (lua_State *L) { char buff[MAX_PATH + 1]; char *lb; DWORD nsize = sizeof(buff)/sizeof(char); DWORD n = GetModuleFileName(NULL, buff, nsize); if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) luaL_error(L, "unable to get ModuleFileName"); - *lb = '\0'; - luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff); - lua_remove(L, -2); /* remove original string */ + else { + *lb = '\0'; + luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff); + lua_remove(L, -2); /* remove original string */ + } } @@ -440,7 +442,8 @@ static int loader_preload (lua_State *L) { } -static const int sentinel = 0; +static const int sentinel_ = 0; +#define sentinel ((void *)&sentinel_) static int ll_require (lua_State *L) { @@ -450,7 +453,7 @@ static int ll_require (lua_State *L) { 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 */ + 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 */ } @@ -467,14 +470,14 @@ static int ll_require (lua_State *L) { if (lua_isnil(L, -1)) lua_pop(L, 1); /* did not found module */ else break; /* module loaded successfully */ } - lua_pushlightuserdata(L, (void *)&sentinel); + 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? */ + 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 */ @@ -624,8 +627,6 @@ LUALIB_API int luaopen_package (lua_State *L) { lua_setfield(L, LUA_GLOBALSINDEX, "loadlib"); #endif lua_pushvalue(L, -1); - lua_setfield(L, LUA_REGISTRYINDEX, "_PACKAGE"); - lua_pushvalue(L, -1); lua_replace(L, LUA_ENVIRONINDEX); /* create `loaders' table */ lua_newtable(L); @@ -642,7 +643,7 @@ LUALIB_API int luaopen_package (lua_State *L) { LUA_EXECDIR "\n" LUA_IGMARK); lua_setfield(L, -2, "config"); /* set field `loaded' */ - lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED"); lua_setfield(L, -2, "loaded"); /* set field `preload' */ lua_newtable(L); diff --git a/src/lobject.c b/src/lobject.c index 9aa9760f..3974c683 100644 --- a/src/lobject.c +++ b/src/lobject.c @@ -1,5 +1,5 @@ /* -** $Id: lobject.c,v 2.18 2005/08/01 04:22:23 roberto Exp $ +** $Id: lobject.c,v 2.19 2005/10/24 17:37:52 roberto Exp $ ** Some generic functions over Lua objects ** See Copyright Notice in lua.h */ @@ -75,7 +75,7 @@ int luaO_rawequalObj (const TValue *t1, const TValue *t2) { case LUA_TNIL: return 1; case LUA_TNUMBER: - return luai_numeq(L, nvalue(t1), nvalue(t2)); + return luai_numeq(nvalue(t1), nvalue(t2)); case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ case LUA_TLIGHTUSERDATA: diff --git a/src/lobject.h b/src/lobject.h index 1709fa3c..1416e360 100644 --- a/src/lobject.h +++ b/src/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 2.17 2005/06/13 14:19:00 roberto Exp $ +** $Id: lobject.h,v 2.18 2005/10/24 17:37:33 roberto Exp $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -353,7 +353,7 @@ typedef struct Table { ** `module' operation for hashing (size is always a power of 2) */ #define lmod(s,size) \ - check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1)))) + (check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1))))) #define twoto(x) (1<<(x)) diff --git a/src/lopcodes.c b/src/lopcodes.c index 5e3bc5f7..bf9cd522 100644 --- a/src/lopcodes.c +++ b/src/lopcodes.c @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.c,v 1.35 2005/08/29 20:49:21 roberto Exp $ +** $Id: lopcodes.c,v 1.37 2005/11/08 19:45:36 roberto Exp $ ** See Copyright Notice in lua.h */ @@ -7,9 +7,7 @@ #define lopcodes_c #define LUA_CORE -#include "lua.h" -#include "lobject.h" #include "lopcodes.h" @@ -88,7 +86,7 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = { ,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, 0, OpArgR, OpArgU, iABC) /* OP_TEST */ + ,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 */ diff --git a/src/lopcodes.h b/src/lopcodes.h index b08b6798..88e7e65c 100644 --- a/src/lopcodes.h +++ b/src/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.122 2005/08/29 20:49:21 roberto Exp $ +** $Id: lopcodes.h,v 1.123 2005/10/23 17:37:55 roberto Exp $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -193,12 +193,12 @@ 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+1) then pc+=sBx */ +OP_FORLOOP,/* A sBx R(A)+=R(A+2); + if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/ OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */ -OP_TFORLOOP,/* A C R(A+2), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); - if R(A+2) ~= nil then pc++ */ - +OP_TFORLOOP,/* A C R(A+3), ... ,R(A+3+C) := R(A)(R(A+1), R(A+2)); + if R(A+3) ~= nil then { pc++; R(A+2)=R(A+3); } */ OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */ OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/ diff --git a/src/loslib.c b/src/loslib.c index 4cee7ba5..01458b90 100644 --- a/src/loslib.c +++ b/src/loslib.c @@ -1,5 +1,5 @@ /* -** $Id: loslib.c,v 1.13 2005/09/09 18:22:46 roberto Exp $ +** $Id: loslib.c,v 1.14 2005/10/21 13:47:42 roberto Exp $ ** Standard Operating System library ** See Copyright Notice in lua.h */ @@ -125,8 +125,8 @@ static int getfield (lua_State *L, const char *key, int d) { static int io_date (lua_State *L) { const char *s = luaL_optstring(L, 1, "%c"); - lua_Number n = luaL_optnumber(L, 2, -1); - time_t t = (n == -1) ? time(NULL) : (time_t)n; + time_t t = lua_isnoneornil(L, 2) ? time(NULL) : + (time_t)luaL_checknumber(L, 2); struct tm *stm; if (*s == '!') { /* UTC? */ stm = gmtime(&t); diff --git a/src/lparser.c b/src/lparser.c index 91dc4fff..dd4715d0 100644 --- a/src/lparser.c +++ b/src/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 2.35 2005/08/29 20:49:21 roberto Exp $ +** $Id: lparser.c,v 2.38 2005/10/24 17:38:47 roberto Exp $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -144,7 +144,7 @@ static TString *str_checkname (LexState *ls) { static void init_exp (expdesc *e, expkind k, int i) { e->f = e->t = NO_JUMP; e->k = k; - e->info = i; + e->u.s.info = i; } @@ -184,7 +184,7 @@ static void new_localvar (LexState *ls, TString *name, int n) { static void adjustlocalvars (LexState *ls, int nvars) { FuncState *fs = ls->fs; - fs->nactvar += nvars; + fs->nactvar = cast(lu_byte, fs->nactvar + nvars); for (; nvars; nvars--) { getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc; } @@ -203,7 +203,7 @@ static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { Proto *f = fs->f; int oldsize = f->sizeupvalues; for (i=0; i<f->nups; i++) { - if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info) { + if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) { lua_assert(f->upvalues[i] == name); return i; } @@ -217,7 +217,7 @@ static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { luaC_objbarrier(fs->L, f, name); lua_assert(v->k == VLOCAL || v->k == VUPVAL); fs->upvalues[f->nups].k = cast(lu_byte, v->k); - fs->upvalues[f->nups].info = cast(lu_byte, v->info); + fs->upvalues[f->nups].info = cast(lu_byte, v->u.s.info); return f->nups++; } @@ -255,7 +255,7 @@ static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { else { /* not found at current level; try upper one */ if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL) return VGLOBAL; - var->info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */ + var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */ var->k = VUPVAL; /* upvalue in this level */ return VUPVAL; } @@ -267,7 +267,7 @@ static void singlevar (LexState *ls, expdesc *var) { TString *varname = str_checkname(ls); FuncState *fs = ls->fs; if (singlevaraux(fs, varname, var, 1) == VGLOBAL) - var->info = luaK_stringK(fs, varname); /* info points to global name */ + var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */ } @@ -351,7 +351,7 @@ static void open_func (LexState *ls, FuncState *fs) { fs->L = L; ls->fs = fs; fs->pc = 0; - fs->lasttarget = 0; + fs->lasttarget = -1; fs->jpc = NO_JUMP; fs->freereg = 0; fs->nk = 0; @@ -472,8 +472,8 @@ static void recfield (LexState *ls, struct ConsControl *cc) { checknext(ls, '='); luaK_exp2RK(fs, &key); expr(ls, &val); - luaK_codeABC(fs, OP_SETTABLE, cc->t->info, luaK_exp2RK(fs, &key), - luaK_exp2RK(fs, &val)); + luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, luaK_exp2RK(fs, &key), + luaK_exp2RK(fs, &val)); fs->freereg = reg; /* free registers */ } @@ -483,7 +483,7 @@ static void closelistfield (FuncState *fs, struct ConsControl *cc) { luaK_exp2nextreg(fs, &cc->v); cc->v.k = VVOID; if (cc->tostore == LFIELDS_PER_FLUSH) { - luaK_setlist(fs, cc->t->info, cc->na, cc->tostore); /* flush */ + luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */ cc->tostore = 0; /* no more items pending */ } } @@ -493,13 +493,13 @@ 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->info, cc->na, LUA_MULTRET); + 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->info, cc->na, cc->tostore); + luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); } } @@ -657,7 +657,7 @@ static void funcargs (LexState *ls, expdesc *f) { } } lua_assert(f->k == VNONRELOC); - base = f->info; /* base register for call */ + base = f->u.s.info; /* base register for call */ if (hasmultret(args.k)) nparams = LUA_MULTRET; /* open call */ else { @@ -746,7 +746,8 @@ static void simpleexp (LexState *ls, expdesc *v) { constructor | FUNCTION body | primaryexp */ switch (ls->t.token) { case TK_NUMBER: { - init_exp(v, VK, luaK_numberK(ls->fs, ls->t.seminfo.r)); + init_exp(v, VKNUM, 0); + v->u.nval = ls->t.seminfo.r; break; } case TK_STRING: { @@ -805,7 +806,7 @@ static BinOpr getbinopr (int op) { switch (op) { case '+': return OPR_ADD; case '-': return OPR_SUB; - case '*': return OPR_MULT; + case '*': return OPR_MUL; case '/': return OPR_DIV; case '%': return OPR_MOD; case '^': return OPR_POW; @@ -927,18 +928,18 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { int conflict = 0; for (; lh; lh = lh->prev) { if (lh->v.k == VINDEXED) { - if (lh->v.info == v->info) { /* conflict? */ + if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ conflict = 1; - lh->v.info = extra; /* previous assignment will use safe copy */ + lh->v.u.s.info = extra; /* previous assignment will use safe copy */ } - if (lh->v.aux == v->info) { /* conflict? */ + if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */ conflict = 1; - lh->v.aux = extra; /* previous assignment will use safe copy */ + lh->v.u.s.aux = extra; /* previous assignment will use safe copy */ } } } if (conflict) { - luaK_codeABC(fs, OP_MOVE, fs->freereg, v->info, 0); /* make copy */ + luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */ luaK_reserveregs(fs, 1); } } diff --git a/src/lparser.h b/src/lparser.h index d8542f9c..d5e6e81d 100644 --- a/src/lparser.h +++ b/src/lparser.h @@ -1,5 +1,5 @@ /* -** $Id: lparser.h,v 1.55 2005/04/25 19:24:10 roberto Exp $ +** $Id: lparser.h,v 1.56 2005/10/03 14:02:40 roberto Exp $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -23,6 +23,7 @@ typedef enum { 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' */ @@ -36,7 +37,10 @@ typedef enum { typedef struct expdesc { expkind k; - int info, aux; + 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; diff --git a/src/lstate.c b/src/lstate.c index 2a4ace12..77e93fbd 100644 --- a/src/lstate.c +++ b/src/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 2.33 2005/08/25 15:39:16 roberto Exp $ +** $Id: lstate.c,v 2.35 2005/10/06 20:46:25 roberto Exp $ ** Global State ** See Copyright Notice in lua.h */ @@ -71,8 +71,8 @@ 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, 20)); /* table of globals */ - sethvalue(L, registry(L), luaH_new(L, 6, 20)); /* registry */ + sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */ + sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */ luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ luaT_init(L); luaX_init(L); @@ -134,6 +134,7 @@ lua_State *luaE_newthread (lua_State *L) { 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)); } @@ -196,8 +197,9 @@ static void callallgcTM (lua_State *L, void *ud) { LUA_API void lua_close (lua_State *L) { - lua_lock(L); L = G(L)->mainthread; /* only the main thread can be closed */ + luai_userstateclose(L); + 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 */ diff --git a/src/lstrlib.c b/src/lstrlib.c index 4cf5836a..25258bfe 100644 --- a/src/lstrlib.c +++ b/src/lstrlib.c @@ -1,5 +1,5 @@ /* -** $Id: lstrlib.c,v 1.123 2005/08/26 17:36:32 roberto Exp $ +** $Id: lstrlib.c,v 1.127 2005/10/26 13:28:19 roberto Exp $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ @@ -111,7 +111,9 @@ static int str_byte (lua_State *L) { if (posi <= 0) posi = 1; if ((size_t)pose > l) pose = l; if (posi > pose) return 0; /* empty interval; return no values */ - n = pose - posi + 1; + 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<n; i++) lua_pushinteger(L, uchar(s[posi+i-1])); @@ -460,28 +462,32 @@ static const char *lmemfind (const char *s1, size_t l1, } -static void push_onecapture (MatchState *ms, int i) { - 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 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; - luaL_checkstack(ms->L, ms->level, "too many captures"); - if (ms->level == 0 && s) { /* no explicit captures? */ - lua_pushlstring(ms->L, s, e-s); /* return whole match */ - return 1; - } - else { /* return all captures */ - for (i=0; i<ms->level; i++) - push_onecapture(ms, i); - return ms->level; /* number of strings pushed */ - } + 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 */ } @@ -516,12 +522,7 @@ static int str_find_aux (lua_State *L, int find) { if (find) { lua_pushinteger(L, s1-s+1); /* start */ lua_pushinteger(L, res-s); /* end */ -#if defined(LUA_COMPAT_FIND) return push_captures(&ms, NULL, 0) + 2; -#else - return 2; -#endif - } else return push_captures(&ms, s1, res); @@ -585,42 +586,61 @@ static int gfind_nodef (lua_State *L) { } -static void add_s (MatchState *ms, luaL_Buffer *b, - const char *s, const char *e) { - lua_State *L = ms->L; - if (lua_isstring(L, 3)) { - size_t l; - const char *news = lua_tolstring(L, 3, &l); - size_t i; - for (i=0; i<l; i++) { - if (news[i] != L_ESC) +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 { - i++; /* skip ESC */ - if (!isdigit(uchar(news[i]))) - luaL_addchar(b, news[i]); - else { - if (news[i] == '0') - lua_pushlstring(L, s, e - s); /* add whole match */ - else { - int level = check_capture(ms, news[i]); - push_onecapture(ms, level); - } - luaL_addvalue(b); /* add capture to accumulated result */ - } + push_onecapture(ms, news[i] - '1', s, e); + luaL_addvalue(b); /* add capture to accumulated result */ } } } - else { /* is a function */ - int n; - lua_pushvalue(L, 3); - n = push_captures(ms, s, e); - lua_call(L, n, 1); - if (lua_isstring(L, -1)) - luaL_addvalue(b); /* add return to accumulated result */ - else - lua_pop(L, 1); /* function result is not a string: pop it */ +} + + +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; + } + default: { + luaL_argerror(L, 3, "string/function/table expected"); + return; + } + } + 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 */ } @@ -633,9 +653,6 @@ static int str_gsub (lua_State *L) { int n = 0; MatchState ms; luaL_Buffer b; - luaL_argcheck(L, - lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)), - 3, "string or function expected"); luaL_buffinit(L, &b); ms.L = L; ms.src_init = src; @@ -646,7 +663,7 @@ static int str_gsub (lua_State *L) { e = match(&ms, src, p); if (e) { n++; - add_s(&ms, &b, src, e); + add_value(&ms, &b, src, e); } if (e && e>src) /* non empty match? */ src = e; /* skip it */ diff --git a/src/ltable.c b/src/ltable.c index 979cc5ca..5d4a828a 100644 --- a/src/ltable.c +++ b/src/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 2.26 2005/07/11 14:01:37 roberto Exp $ +** $Id: ltable.c,v 2.27 2005/10/24 17:37:52 roberto Exp $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -120,7 +120,7 @@ static int arrayindex (const TValue *key) { lua_Number n = nvalue(key); int k; lua_number2int(k, n); - if (luai_numeq(L, cast(lua_Number, k), nvalue(key))) + if (luai_numeq(cast(lua_Number, k), nvalue(key))) return k; } return -1; /* `key' did not match some condition */ @@ -437,7 +437,7 @@ const TValue *luaH_getnum (Table *t, int key) { lua_Number nk = cast(lua_Number, key); Node *n = hashnum(t, nk); do { /* check whether `key' is somewhere in the chain */ - if (ttisnumber(gkey(n)) && luai_numeq(L, nvalue(gkey(n)), nk)) + if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) return gval(n); /* that's it */ else n = gnext(n); } while (n); @@ -471,7 +471,7 @@ const TValue *luaH_get (Table *t, const TValue *key) { int k; lua_Number n = nvalue(key); lua_number2int(k, n); - if (luai_numeq(L, cast(lua_Number, k), nvalue(key))) /* index is int? */ + if (luai_numeq(cast(lua_Number, k), nvalue(key))) /* index is int? */ return luaH_getnum(t, k); /* use specialized version */ /* else go through */ } @@ -495,7 +495,7 @@ TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { return cast(TValue *, p); else { if (ttisnil(key)) luaG_runerror(L, "table index is nil"); - else if (ttisnumber(key) && !luai_numeq(L, nvalue(key), nvalue(key))) + else if (ttisnumber(key) && !luai_numeq(nvalue(key), nvalue(key))) luaG_runerror(L, "table index is NaN"); return newkey(L, t, key); } diff --git a/src/ltablib.c b/src/ltablib.c index 348b6ed5..453b23b3 100644 --- a/src/ltablib.c +++ b/src/ltablib.c @@ -1,5 +1,5 @@ /* -** $Id: ltablib.c,v 1.35 2005/08/26 17:36:32 roberto Exp $ +** $Id: ltablib.c,v 1.38 2005/10/23 17:38:15 roberto Exp $ ** Library for Table Manipulation ** See Copyright Notice in lua.h */ @@ -40,9 +40,7 @@ static int foreach (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); luaL_checktype(L, 2, LUA_TFUNCTION); lua_pushnil(L); /* first key */ - for (;;) { - if (lua_next(L, 1) == 0) - return 0; + while (lua_next(L, 1)) { lua_pushvalue(L, 2); /* function */ lua_pushvalue(L, -3); /* key */ lua_pushvalue(L, -3); /* value */ @@ -51,6 +49,23 @@ static int foreach (lua_State *L) { 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; } @@ -75,16 +90,23 @@ static int setn (lua_State *L) { static int tinsert (lua_State *L) { int e = aux_getn(L, 1) + 1; /* first empty element */ int pos; /* where to insert new element */ - if (lua_isnone(L, 3)) /* called with only 2 arguments */ - pos = e; /* insert new element at the end */ - else { - int i; - pos = luaL_checkint(L, 2); /* 2nd argument is the position */ - if (pos > e) e = pos; /* `grow' array if necessary */ - lua_settop(L, 3); /* function may be called with more than 3 args */ - 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] */ + 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 */ @@ -112,12 +134,11 @@ static int tremove (lua_State *L) { static int tconcat (lua_State *L) { luaL_Buffer b; size_t lsep; + int i, last; const char *sep = luaL_optlstring(L, 2, "", &lsep); - int i = luaL_optint(L, 3, 1); - int last = luaL_optint(L, 4, -2); luaL_checktype(L, 1, LUA_TTABLE); - if (last == -2) - last = luaL_getn(L, 1); + i = luaL_optint(L, 3, 1); + last = luaL_opt(L, luaL_checkint, 4, luaL_getn(L, 1)); luaL_buffinit(L, &b); for (; i <= last; i++) { lua_rawgeti(L, 1, i); @@ -241,6 +262,7 @@ static const luaL_Reg tab_funcs[] = { {"foreach", foreach}, {"foreachi", foreachi}, {"getn", getn}, + {"maxn", maxn}, {"insert", tinsert}, {"remove", tremove}, {"setn", setn}, @@ -1,5 +1,5 @@ /* -** $Id: lua.c,v 1.150 2005/09/06 17:19:33 roberto Exp $ +** $Id: lua.c,v 1.154 2005/10/24 17:38:47 roberto Exp $ ** Lua stand-alone interpreter ** See Copyright Notice in lua.h */ @@ -43,12 +43,13 @@ static void print_usage (void) { fprintf(stderr, "usage: %s [options] [script [args]].\n" "Available options are:\n" - " - execute stdin as a file\n" " -e stat execute string " LUA_QL("stat") "\n" - " -i enter interactive mode after executing " LUA_QL("script") "\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" , + " -- stop handling options\n" + " - execute stdin and stop handling options\n" + , progname); fflush(stderr); } @@ -99,6 +100,8 @@ static int docall (lua_State *L, int narg, int clear) { 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; } @@ -108,9 +111,12 @@ static void print_version (void) { } -static int getargs (lua_State *L, int argc, char **argv, int n) { - int narg = argc - (n + 1); /* number of arguments to the script */ +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]); @@ -229,86 +235,71 @@ static void dotty (lua_State *L) { } -#define clearinteractive(i) (*i &= 2) +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); +} -static int handle_argv (lua_State *L, int argc, char **argv, int *interactive) { - if (argv[1] == NULL) { /* no arguments? */ - *interactive = 0; - if (lua_stdin_is_tty()) - dotty(L); - else - dofile(L, NULL); /* executes stdin as a file */ - } - else { /* other arguments; loop over them */ - int i; - for (i = 1; argv[i] != NULL; i++) { - if (argv[i][0] != '-') break; /* not an option? */ - switch (argv[i][1]) { /* option */ - case '-': { /* `--' */ - if (argv[i][2] != '\0') { - print_usage(); - return 1; - } - i++; /* skip this argument */ - goto endloop; /* stop handling arguments */ - } - case '\0': { - clearinteractive(interactive); - dofile(L, NULL); /* executes stdin as a file */ - break; - } - case 'i': { - *interactive = 2; /* force interactive mode after arguments */ - break; - } - case 'v': { - clearinteractive(interactive); - print_version(); - break; - } - case 'e': { - const char *chunk = argv[i] + 2; - clearinteractive(interactive); - if (*chunk == '\0') chunk = argv[++i]; - if (chunk == NULL) { - print_usage(); - return 1; - } - if (dostring(L, chunk, "=(command line)") != 0) - return 1; - break; - } - case 'l': { - const char *filename = argv[i] + 2; - if (*filename == '\0') filename = argv[++i]; - if (filename == NULL) { - print_usage(); - return 1; - } - if (dolibrary(L, filename)) - return 1; /* stop if file fails */ - break; + +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 '-': return (argv[i+1] != NULL ? i+1 : 0); + case '\0': return i; + case 'i': *pi = 1; break; + case 'v': *pv = 1; break; + case 'e': *pe = 1; /* go through */ + case 'l': + if (argv[i][2] == '\0') { + i++; + if (argv[i] == NULL) return -1; } - default: { - clearinteractive(interactive); - print_usage(); + 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; } - } endloop: - if (argv[i] != NULL) { - int status; - const char *filename = argv[i]; - int narg = getargs(L, argc, argv, i); /* collect arguments */ - lua_setglobal(L, "arg"); - clearinteractive(interactive); - status = luaL_loadfile(L, filename); - lua_insert(L, -(narg+1)); - if (status == 0) - status = docall(L, narg, 0); - else - lua_pop(L, narg); - return report(L, status); + 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; @@ -334,17 +325,32 @@ struct Smain { static int pmain (lua_State *L) { struct Smain *s = (struct Smain *)lua_touserdata(L, 1); - int status; - int interactive = 1; - if (s->argv[0] && s->argv[0][0]) progname = s->argv[0]; + 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]; luaL_openlibs(L); /* open libraries */ - status = handle_luainit(L); - if (status == 0) { - status = handle_argv(L, s->argc, s->argv, &interactive); - if (status == 0 && interactive) dotty(L); + 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()) dotty(L); + else dofile(L, NULL); /* executes stdin as a file */ } - s->status = status; return 0; } @@ -1,5 +1,5 @@ /* -** $Id: lua.h,v 1.212 2005/08/25 20:02:08 roberto Exp $ +** $Id: lua.h,v 1.214 2005/10/20 11:35:50 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 @@ -16,7 +16,7 @@ #include "luaconf.h" -#define LUA_VERSION "Lua 5.1 (alpha)" +#define LUA_VERSION "Lua 5.1 (beta)" #define LUA_VERSION_NUM 501 #define LUA_COPYRIGHT "Copyright (C) 1994-2005 Lua.org, PUC-Rio" #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" @@ -221,9 +221,10 @@ LUA_API int (lua_status) (lua_State *L); #define LUA_GCRESTART 1 #define LUA_GCCOLLECT 2 #define LUA_GCCOUNT 3 -#define LUA_GCSTEP 4 -#define LUA_GCSETPAUSE 5 -#define LUA_GCSETSTEPMUL 6 +#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); @@ -239,6 +240,7 @@ 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); @@ -1,5 +1,5 @@ /* -** $Id: luac.c,v 1.51 2005/06/02 13:39:23 lhf Exp $ +** $Id: luac.c,v 1.52 2005/11/11 14:03:13 lhf Exp $ ** Lua compiler (saves bytecodes to files; also list bytecodes) ** See Copyright Notice in lua.h */ @@ -23,13 +23,8 @@ #include "lstring.h" #include "lundump.h" -#ifndef PROGNAME #define PROGNAME "luac" /* default program name */ -#endif - -#ifndef OUTPUT -#define OUTPUT "luac.out" /* default output file */ -#endif +#define OUTPUT PROGNAME ".out" /* default output file */ static int listing=0; /* list bytecodes? */ static int dumping=1; /* dump bytecodes? */ @@ -152,15 +147,15 @@ static int writer(lua_State* L, const void* p, size_t size, void* u) } struct Smain { - int argc; - char **argv; + int argc; + char** argv; }; -static int pmain(lua_State *L) +static int pmain(lua_State* L) { - struct Smain *s = (struct Smain *)lua_touserdata(L, 1); + struct Smain* s = (struct Smain*)lua_touserdata(L, 1); int argc=s->argc; - char **argv=s->argv; + char** argv=s->argv; Proto* f; int i; if (!lua_checkstack(L,argc)) fatal("too many input files"); diff --git a/src/luaconf.h b/src/luaconf.h index d6d4a2a7..ea685a2d 100644 --- a/src/luaconf.h +++ b/src/luaconf.h @@ -1,5 +1,5 @@ /* -** $Id: luaconf.h,v 1.65 2005/09/09 18:24:42 roberto Exp $ +** $Id: luaconf.h,v 1.74 2005/11/16 16:24:28 roberto Exp $ ** Configuration file for Lua ** See Copyright Notice in lua.h */ @@ -19,8 +19,6 @@ */ - - /* @@ LUA_ANSI controls the use of non-ansi features. ** CHANGE it (define it) if you want Lua to avoid the use of any @@ -30,6 +28,31 @@ #define LUA_ANSI #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_DEFAULT is the default path that Lua uses to look for @@ -92,7 +115,7 @@ #define LUA_PATHSEP ";" #define LUA_PATH_MARK "?" #define LUA_EXECDIR "!" -#define LUA_IGMARK ":" +#define LUA_IGMARK "-" /* @@ -141,10 +164,12 @@ #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 @@ -189,7 +214,7 @@ ** CHANGE it if you have a better definition for non-POSIX/non-Windows ** systems. */ -#if !defined(LUA_ANSI) && defined(_POSIX_C_SOURCE) +#if defined(LUA_USE_ISATTY) #include <unistd.h> #define lua_stdin_is_tty() isatty(0) #elif !defined(LUA_ANSI) && defined(_WIN32) @@ -239,17 +264,17 @@ #include <stdio.h> #include <readline/readline.h> #include <readline/history.h> -#define lua_readline(L,b,p) (((b)=readline(p)) != NULL) +#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) free(b) +#define lua_freeline(L,b) ((void)L, free(b)) #else #define lua_readline(L,b,p) \ - (fputs(p, stdout), fflush(stdout), /* show prompt */ \ + ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ -#define lua_saveline(L,idx) ((void)0) -#define lua_freeline(L,b) ((void)0) +#define lua_saveline(L,idx) { (void)L; (void)idx; } +#define lua_freeline(L,b) { (void)L; (void)b; } #endif #endif @@ -316,20 +341,12 @@ #define LUA_COMPAT_LSTR 1 /* -@@ LUA_COMPAT_FIND controls compatibility with old 'string.find' behavior. -** CHANGE it to undefined as soon as your programs use 'string.find' only -** to find patterns. -*/ -#define LUA_COMPAT_FIND - -/* @@ 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. @@ -349,10 +366,10 @@ */ #if defined(LUA_USE_APICHECK) #include <assert.h> -#define luai_apicheck(L,o) assert(o) +#define luai_apicheck(L,o) { (void)L; assert(o); } #else /* (By default lua_assert is empty, so luai_apicheck is also empty.) */ -#define luai_apicheck(L,o) lua_assert(o) +#define luai_apicheck(L,o) { (void)L; lua_assert(o); } #endif @@ -464,31 +481,6 @@ -/* -@@ 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_ANSI) && !defined(__SSE2__) && \ - (defined(__i386) || defined (_M_IX86)) -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) - -/* 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 - - /* ** {================================================================== @@ -525,16 +517,44 @@ union luai_Cast { double l_d; long l_l; }; /* @@ The luai_num* macros define the primitive operations over numbers. */ -#define luai_numadd(L,a,b) ((a)+(b)) -#define luai_numsub(L,a,b) ((a)-(b)) -#define luai_nummul(L,a,b) ((a)*(b)) -#define luai_numdiv(L,a,b) ((a)/(b)) -#define luai_nummod(L,a,b) ((a) - floor((a)/(b))*(b)) -#define luai_numpow(L,a,b) pow(a,b) -#define luai_numunm(L,a) (-(a)) -#define luai_numeq(L,a,b) ((a)==(b)) -#define luai_numlt(L,a,b) ((a)<(b)) -#define luai_numle(L,a,b) ((a)<=(b)) +#if defined(LUA_CORE) +#include <math.h> +#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)) +#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_ANSI) && !defined(__SSE2__) && \ + (defined(__i386) || defined (_M_IX86) || defined(__i386__)) +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) + +/* 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 /* }================================================================== */ @@ -597,7 +617,7 @@ union luai_Cast { double l_d; long l_l; }; */ #if defined(loslib_c) || defined(luaall_c) -#if !defined(LUA_ANSI) && defined(_POSIX_C_SOURCE) +#if defined(LUA_USE_MKSTEMP) #include <unistd.h> #define LUA_TMPNAMBUFSIZE 32 #define lua_tmpnam(b,e) { \ @@ -605,6 +625,7 @@ union luai_Cast { double l_d; long l_l; }; 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); } @@ -618,21 +639,21 @@ union luai_Cast { double l_d; long l_l; }; @* the file streams. ** CHANGE it if you have a way to implement it in your system. */ -#if !defined(LUA_ANSI) && defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 2 +#if defined(LUA_USE_POPEN) -#define lua_popen(L,c,m) popen(c,m) -#define lua_pclose(L,file) (pclose(file) != -1) +#define lua_popen(L,c,m) ((void)L, popen(c,m)) +#define lua_pclose(L,file) ((void)L, (pclose(file) != -1)) #elif !defined(LUA_ANSI) && defined(_WIN32) -#define lua_popen(L,c,m) _popen(c,m) -#define lua_pclose(L,file) (_pclose(file) != -1) +#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)c, (void)m, luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) -#define lua_pclose(L,file) ((void)file, 0) +#define lua_pclose(L,file) ((void)L, (void)file, 0) #endif @@ -647,16 +668,15 @@ union luai_Cast { double l_d; long l_l; }; ** 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 (or just remove these definitions). +** options. +** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD. */ -#if !defined(LUA_ANSI) -#if defined(_WIN32) -#define LUA_DL_DLL -#elif defined(__APPLE__) && defined(__MACH__) -#define LUA_DL_DYLD -#elif defined(LUA_USE_DLOPEN) +#if defined(LUA_USE_DLOPEN) #define LUA_DL_DLOPEN #endif + +#if !defined(LUA_ANSI) && defined(_WIN32) +#define LUA_DL_DLL #endif @@ -674,10 +694,12 @@ union luai_Cast { double l_d; long l_l; }; ** 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)0) -#define luai_userstatefree(L) ((void)0) -#define luai_userstateresume(L,n) ((void)0) -#define luai_userstateyield(L,n) ((void)0) +#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) diff --git a/src/lundump.c b/src/lundump.c index 726d021d..60a0eeed 100644 --- a/src/lundump.c +++ b/src/lundump.c @@ -1,6 +1,6 @@ /* -** $Id: lundump.c,v 1.58 2005/09/02 01:54:47 lhf Exp $ -** load pre-compiled Lua chunks +** $Id: lundump.c,v 1.59 2005/11/11 14:03:13 lhf Exp $ +** load precompiled Lua chunks ** See Copyright Notice in lua.h */ @@ -15,42 +15,34 @@ #include "ldo.h" #include "lfunc.h" #include "lmem.h" -#include "lopcodes.h" +#include "lobject.h" #include "lstring.h" #include "lundump.h" #include "lzio.h" -#ifdef LUAC_TRUST_BINARIES -#define IF(c,s) -#else -#define IF(c,s) if (c) error(S,s) -#endif - typedef struct { lua_State* L; ZIO* Z; Mbuffer* b; const char* name; -#ifdef LUAC_SWAP_ON_LOAD - int swap; -#endif } LoadState; -#ifdef LUAC_SWAP_ON_LOAD -static void LoadMem (LoadState* S, void* b, int n, size_t size); +#ifdef LUAC_TRUST_BINARIES +#define IF(c,s) #else -#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) -#endif - -#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) +#define IF(c,s) if (c) error(S,s) static void error(LoadState* S, const char* why) { - luaO_pushfstring(S->L,"%s: %s",S->name,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) { @@ -102,39 +94,6 @@ static void LoadCode(LoadState* S, Proto* f) LoadVector(S,f->code,n,sizeof(Instruction)); } -static void LoadLocals(LoadState* S, Proto* f) -{ - int i,n; - n=LoadInt(S); - f->locvars=luaM_newvector(S->L,n,LocVar); - f->sizelocvars=n; - for (i=0; i<n; i++) f->locvars[i].varname=NULL; - for (i=0; i<n; i++) - { - f->locvars[i].varname=LoadString(S); - f->locvars[i].startpc=LoadInt(S); - f->locvars[i].endpc=LoadInt(S); - } -} - -static void LoadLines(LoadState* S, Proto* f) -{ - int n=LoadInt(S); - f->lineinfo=luaM_newvector(S->L,n,int); - f->sizelineinfo=n; - LoadVector(S,f->lineinfo,n,sizeof(int)); -} - -static void LoadUpvalues(LoadState* S, Proto* f) -{ - int i,n; - n=LoadInt(S); - f->upvalues=luaM_newvector(S->L,n,TString*); - f->sizeupvalues=n; - for (i=0; i<n; i++) f->upvalues[i]=NULL; - for (i=0; i<n; i++) f->upvalues[i]=LoadString(S); -} - static Proto* LoadFunction(LoadState* S, TString* p); static void LoadConstants(LoadState* S, Proto* f) @@ -174,6 +133,30 @@ static void LoadConstants(LoadState* S, Proto* f) for (i=0; i<n; i++) f->p[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; i<n; i++) f->locvars[i].varname=NULL; + for (i=0; i<n; i++) + { + f->locvars[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; i<n; i++) f->upvalues[i]=NULL; + for (i=0; i<n; i++) f->upvalues[i]=LoadString(S); +} + static Proto* LoadFunction(LoadState* S, TString* p) { Proto* f=luaF_newproto(S->L); @@ -185,11 +168,9 @@ static Proto* LoadFunction(LoadState* S, TString* p) f->numparams=LoadByte(S); f->is_vararg=LoadByte(S); f->maxstacksize=LoadByte(S); - LoadLines(S,f); - LoadLocals(S,f); - LoadUpvalues(S,f); - LoadConstants(S,f); LoadCode(S,f); + LoadConstants(S,f); + LoadDebug(S,f); IF (!luaG_checkcode(f), "bad code"); S->L->top--; return f; @@ -201,9 +182,6 @@ static void LoadHeader(LoadState* S) char s[LUAC_HEADERSIZE]; luaU_header(h); LoadBlock(S,s,LUAC_HEADERSIZE); -#ifdef LUAC_SWAP_ON_LOAD - S->swap=(s[6]!=h[6]); s[6]=h[6]; -#endif IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header"); } @@ -236,55 +214,10 @@ void luaU_header (char* h) h+=sizeof(LUA_SIGNATURE)-1; *h++=(char)LUAC_VERSION; *h++=(char)LUAC_FORMAT; - *h++=(char)*(char*)&x; + *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); -} - -#ifdef LUAC_SWAP_ON_LOAD -static void LoadMem (LoadState* S, void* b, int n, size_t size) -{ - LoadBlock(S,b,n*size); - if (S->swap) - { - char* p=(char*) b; - char c; - switch (size) - { - case 1: - break; - case 2: - while (n--) - { - c=p[0]; p[0]=p[1]; p[1]=c; - p+=2; - } - break; - case 4: - while (n--) - { - c=p[0]; p[0]=p[3]; p[3]=c; - c=p[1]; p[1]=p[2]; p[2]=c; - p+=4; - } - break; - case 8: - while (n--) - { - c=p[0]; p[0]=p[7]; p[7]=c; - c=p[1]; p[1]=p[6]; p[6]=c; - c=p[2]; p[2]=p[5]; p[5]=c; - c=p[3]; p[3]=p[4]; p[4]=c; - p+=8; - } - break; - default: - IF(1, "bad size"); - break; - } - } + *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ } -#endif diff --git a/src/lundump.h b/src/lundump.h index 5de3c46e..58cca5d1 100644 --- a/src/lundump.h +++ b/src/lundump.h @@ -1,6 +1,6 @@ /* -** $Id: lundump.h,v 1.38 2005/09/02 01:54:47 lhf Exp $ -** load pre-compiled Lua chunks +** $Id: lundump.h,v 1.40 2005/11/11 14:03:13 lhf Exp $ +** load precompiled Lua chunks ** See Copyright Notice in lua.h */ @@ -10,12 +10,6 @@ #include "lobject.h" #include "lzio.h" -/* make it work with Lua 5.0 */ -#ifndef LUA_VERSION_NUM -#define LUAI_FUNC -#define lua_Writer lua_Chunkwriter -#endif - /* load one chunk; from lundump.c */ LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); @@ -25,8 +19,10 @@ 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 @@ -37,26 +33,4 @@ LUAI_FUNC void luaU_print (const Proto* f, int full); /* size of header of binary files */ #define LUAC_HEADERSIZE 12 -/* make it work with Lua 5.0 */ -#ifndef LUA_VERSION_NUM -#define LUA_SIGNATURE "\033Lua" -#define TValue TObject -#define rawtsvalue tsvalue -#define linedefined lineDefined -#define lastlinedefined lineDefined -#define setptvalue2s(L,t,f) -#undef setsvalue2n -#define setsvalue2n(L,x,y) setsvalue(x,y) -#define LUA_QL(x) "'" x "'" -#define LUA_QS LUA_QL("%s") -#undef LUAC_VERSION -#define LUAC_VERSION 0x50 -#ifdef lapi_c -#define luaU_dump(L,f,w,d) (luaU_dump)(L,f,w,d,0) -#endif -#ifdef ldo_c -#define luaU_undump(L,z,b) (luaU_undump)(L,z,b,z->name) -#endif -#endif - #endif @@ -1,11 +1,10 @@ /* -** $Id: lvm.c,v 2.55 2005/09/09 18:23:35 roberto Exp $ +** $Id: lvm.c,v 2.59 2005/11/01 16:08:45 roberto Exp $ ** Lua virtual machine ** See Copyright Notice in lua.h */ -#include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -66,7 +65,6 @@ static void traceexec (lua_State *L, const Instruction *pc) { if (L->hookcount == 0) { resethookcount(L); luaD_callhook(L, LUA_HOOKCOUNT, -1); - return; } } if (mask & LUA_MASKLINE) { @@ -226,7 +224,7 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { if (ttype(l) != ttype(r)) return luaG_ordererror(L, l, r); else if (ttisnumber(l)) - return luai_numlt(L, nvalue(l), nvalue(r)); + 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) @@ -240,7 +238,7 @@ static int lessequal (lua_State *L, const TValue *l, const TValue *r) { if (ttype(l) != ttype(r)) return luaG_ordererror(L, l, r); else if (ttisnumber(l)) - return luai_numle(L, nvalue(l), nvalue(r)); + 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' */ @@ -256,7 +254,7 @@ int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { lua_assert(ttype(t1) == ttype(t2)); switch (ttype(t1)) { case LUA_TNIL: return 1; - case LUA_TNUMBER: return luai_numeq(L, nvalue(t1), nvalue(t2)); + 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: { @@ -319,13 +317,13 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb, (c = luaV_tonumber(rc, &tempc)) != NULL) { lua_Number nb = nvalue(b), nc = nvalue(c); switch (op) { - case TM_ADD: setnvalue(ra, luai_numadd(L, nb, nc)); break; - case TM_SUB: setnvalue(ra, luai_numsub(L, nb, nc)); break; - case TM_MUL: setnvalue(ra, luai_nummul(L, nb, nc)); break; - case TM_DIV: setnvalue(ra, luai_numdiv(L, nb, nc)); break; - case TM_MOD: setnvalue(ra, luai_nummod(L, nb, nc)); break; - case TM_POW: setnvalue(ra, luai_numpow(L, nb, nc)); break; - case TM_UNM: setnvalue(ra, luai_numunm(L, nb)); break; + 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; } } @@ -358,6 +356,19 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb, #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; @@ -455,76 +466,34 @@ void luaV_execute (lua_State *L, int nexeccalls) { continue; } case OP_ADD: { - TValue *rb = RKB(i); - TValue *rc = RKC(i); - if (ttisnumber(rb) && ttisnumber(rc)) { - lua_Number nb = nvalue(rb), nc = nvalue(rc); - setnvalue(ra, luai_numadd(L, nb, nc)); - } - else - Protect(Arith(L, ra, rb, rc, TM_ADD)); + arith_op(luai_numadd, TM_ADD); continue; } case OP_SUB: { - TValue *rb = RKB(i); - TValue *rc = RKC(i); - if (ttisnumber(rb) && ttisnumber(rc)) { - lua_Number nb = nvalue(rb), nc = nvalue(rc); - setnvalue(ra, luai_numsub(L, nb, nc)); - } - else - Protect(Arith(L, ra, rb, rc, TM_SUB)); + arith_op(luai_numsub, TM_SUB); continue; } case OP_MUL: { - TValue *rb = RKB(i); - TValue *rc = RKC(i); - if (ttisnumber(rb) && ttisnumber(rc)) { - lua_Number nb = nvalue(rb), nc = nvalue(rc); - setnvalue(ra, luai_nummul(L, nb, nc)); - } - else - Protect(Arith(L, ra, rb, rc, TM_MUL)); + arith_op(luai_nummul, TM_MUL); continue; } case OP_DIV: { - TValue *rb = RKB(i); - TValue *rc = RKC(i); - if (ttisnumber(rb) && ttisnumber(rc)) { - lua_Number nb = nvalue(rb), nc = nvalue(rc); - setnvalue(ra, luai_numdiv(L, nb, nc)); - } - else - Protect(Arith(L, ra, rb, rc, TM_DIV)); + arith_op(luai_numdiv, TM_DIV); continue; } case OP_MOD: { - TValue *rb = RKB(i); - TValue *rc = RKC(i); - if (ttisnumber(rb) && ttisnumber(rc)) { - lua_Number nb = nvalue(rb), nc = nvalue(rc); - setnvalue(ra, luai_nummod(L, nb, nc)); - } - else - Protect(Arith(L, ra, rb, rc, TM_MOD)); + arith_op(luai_nummod, TM_MOD); continue; } case OP_POW: { - TValue *rb = RKB(i); - TValue *rc = RKC(i); - if (ttisnumber(rb) && ttisnumber(rc)) { - lua_Number nb = nvalue(rb), nc = nvalue(rc); - setnvalue(ra, luai_numpow(L, nb, nc)); - } - else - Protect(Arith(L, ra, rb, rc, TM_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(L, nb)); + setnvalue(ra, luai_numunm(nb)); } else { Protect(Arith(L, ra, rb, rb, TM_UNM)); @@ -594,18 +563,18 @@ void luaV_execute (lua_State *L, int nexeccalls) { continue; } case OP_TEST: { - if (l_isfalse(ra) == GETARG_C(i)) pc++; - else - dojump(L, pc, GETARG_sBx(*pc) + 1); + 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)) pc++; - else { + if (l_isfalse(rb) != GETARG_C(i)) { setobjs2s(L, ra, rb); - dojump(L, pc, GETARG_sBx(*pc) + 1); + dojump(L, pc, GETARG_sBx(*pc)); } + pc++; continue; } case OP_CALL: { @@ -678,9 +647,9 @@ void luaV_execute (lua_State *L, int nexeccalls) { } case OP_FORLOOP: { lua_Number step = nvalue(ra+2); - lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */ + lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */ lua_Number limit = nvalue(ra+1); - if (step > 0 ? luai_numle(L, idx, limit) : luai_numle(L, limit, idx)) { + if (step > 0 ? 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 */ @@ -698,7 +667,7 @@ void luaV_execute (lua_State *L, int nexeccalls) { 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(L, nvalue(ra), nvalue(pstep))); + setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep))); dojump(L, pc, GETARG_sBx(i)); continue; } @@ -711,12 +680,11 @@ void luaV_execute (lua_State *L, int nexeccalls) { 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)) /* break loop? */ - pc++; /* skip jump (break loop) */ - else { + if (!ttisnil(cb)) { /* continue loop? */ setobjs2s(L, cb-1, cb); /* save control variable */ - dojump(L, pc, GETARG_sBx(*pc) + 1); /* jump back */ + dojump(L, pc, GETARG_sBx(*pc)); /* jump back */ } + pc++; continue; } case OP_SETLIST: { diff --git a/src/print.c b/src/print.c index 8090a2d5..cfecba96 100644 --- a/src/print.c +++ b/src/print.c @@ -1,5 +1,5 @@ /* -** $Id: print.c,v 1.52 2005/06/08 14:40:44 lhf Exp $ +** $Id: print.c,v 1.53 2005/11/11 14:03:13 lhf Exp $ ** print bytecodes ** See Copyright Notice in lua.h */ @@ -7,6 +7,7 @@ #include <ctype.h> #include <stdio.h> +#define luac_c #define LUA_CORE #include "ldebug.h" @@ -14,6 +15,8 @@ #include "lopcodes.h" #include "lundump.h" +#define PrintFunction luaU_print + #define Sizeof(x) ((int)sizeof(x)) #define VOID(p) ((const void*)(p)) @@ -203,7 +206,7 @@ static void PrintUpvalues(const Proto* f) } } -void luaU_print(const Proto* f, int full) +void PrintFunction(const Proto* f, int full) { int i,n=f->sizep; PrintHeader(f); @@ -214,5 +217,5 @@ void luaU_print(const Proto* f, int full) PrintLocals(f); PrintUpvalues(f); } - for (i=0; i<n; i++) luaU_print(f->p[i],full); + for (i=0; i<n; i++) PrintFunction(f->p[i],full); } |